Skip to content

docs: new form system#109861

Open
TkDodo wants to merge 19 commits intomasterfrom
tkdodo/ref/form-docs
Open

docs: new form system#109861
TkDodo wants to merge 19 commits intomasterfrom
tkdodo/ref/form-docs

Conversation

@TkDodo
Copy link
Collaborator

@TkDodo TkDodo commented Mar 4, 2026

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Mar 4, 2026
@TkDodo TkDodo marked this pull request as ready for review March 4, 2026 10:26
@TkDodo TkDodo requested review from a team as code owners March 4, 2026 10:26
Copy link
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

!config.components.includes(lowerName) &&
!subgroupComponents.has(lowerName) &&
!folderNode.children[name]
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort overrides intended component ordering in subgroups

Medium Severity

The buildComponentTree function carefully adds top-level components in config.components order (e.g., form, fields, autosavefield), but sortTreeRecursively later re-sorts all children with folders before files, then alphabetically. This causes the _subgroup_Primitives folder to appear before the main form documentation entries, and the remaining items to be alphabetized (autosavefield, fields, form) rather than following the configured display order. The explicit ordering from config.components is effectively discarded.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The side-effect of this is that the in-page navigation no longer matches the sidebar

Image

Copy link
Member

@natemoo-re natemoo-re left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs look great, very happy with this overall! Just a few comments/questions.

<form.AppField name="color">
{field => (
<field.Layout.Row label="Terms of Service:">
<field.Layout.Row label="Brand Color:">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we drop the : labels? Don't want to give Claude incorrect patterns.

Suggested change
<field.Layout.Row label="Brand Color:">
<field.Layout.Row label="Brand Color">

title: CompactSelect
description: A versatile dropdown select component for non-form contexts, supporting sections, search, multi-select, custom triggers, and performance optimizations.
category: forms
category: buttons
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand wanting to separate these from the primitives connected to a <Form>, but I'm not sure if button is the right category?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, do you have an alternative grouping idea? compactSelect gets triggered by a button, and we never use it in a form, so it can’t even be used as a formField. segmentedControl is really just buttons with multiple states.

how about “controls” ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The __stories__ pattern is nice! We currently have static/app/stories/playground but colocation makes more sense (short of fixing the issue with prettier)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it already exists somewhere that’s why knip categorizes it correctly:

sentry/knip.config.ts

Lines 62 to 64 in 1448df5

// helper files for stories - it's fine that they are only used in tests
'!static/app/**/__stories__/*.{js,ts,tsx}!',
'!static/app/stories/**/*.{js,ts,tsx}!',


## Select

Single-value select dropdown.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to mention that this uses react-select? Just to avoid confusion among our many implementations.

<form.AppField
name="secret"
validators={{
onDynamic: z.string().min(1, 'Secret is required'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to link to https://tanstack.com/form/latest/docs/framework/react/guides/dynamic-validation here—onDynamic is likely a new concept for most people

Comment on lines +263 to +264
> [!TIP]
> Prefer using a string for `disabled` so users understand why the field is not editable.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should ideally only document the good pattern :)


// String — disabled with a reason shown as tooltip
<field.Input
disabled="This feature requires a Business plan"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing t() wrapper

<form
data-test-id={form.formId}
id={form.formId}
style={{width: '100%'}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also want flexGrow: 1 here?

!config.components.includes(lowerName) &&
!subgroupComponents.has(lowerName) &&
!folderNode.children[name]
) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The side-effect of this is that the in-page navigation no longer matches the sidebar

Image

Comment on lines -84 to -86
"@tanstack/react-devtools": "^0.9.3",
"@tanstack/react-form": "^1.28.0",
"@tanstack/react-form-devtools": "^0.2.13",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I’ll make a new PR to add tanstack devtools and also integrate the query one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants