Skip to content

Align fieldset to architecture goals#192

Open
lifeiscontent wants to merge 3 commits into
mainfrom
align/fieldset
Open

Align fieldset to architecture goals#192
lifeiscontent wants to merge 3 commits into
mainfrom
align/fieldset

Conversation

@lifeiscontent

Copy link
Copy Markdown
Collaborator

Closes #129

What the designer said

From the issue, the designer marked these as always the same (bake in):

  • Legend/header position — always at top of the group
  • Legend font style — consistent weight and size
  • Internal spacing between child fields — fixed vertical gap
  • Grouping semantics — <fieldset> / <legend> element pair
  • Disabled state cascades to all contained fields

And these as depends (adjustable) — should be exposed as props:

  • Legend text
  • Contained fields (any combination)
  • Disabled state of the whole group
  • Border visibility (bordered vs borderless grouping) ← was missing
  • Description text below the legend ← no part existed for this

Changes

packages/propel/src/ui/fieldset/variants.ts

  • Added a bordered variant to fieldsetVariants (true adds rounded-md border-sm border-subtle p-4; false adds nothing). No defaultVariants — callers must be explicit.
  • Added fieldsetDescriptionVariants cva for the new description part.

packages/propel/src/ui/fieldset/fieldset.tsx

  • Fieldset now requires a bordered prop (passed through to fieldsetVariants).

packages/propel/src/ui/fieldset/fieldset-description.tsx (new)

  • FieldsetDescription renders a <p> styled with fieldsetDescriptionVariants. Uses no Base UI wrapper — there is no Fieldset.Description in Base UI; the field-tier FieldDescription is context-bound to <Field> and does not apply here.

packages/propel/src/ui/fieldset/index.tsx

  • Exports the new FieldsetDescription part.

packages/propel/src/components/fieldset/fieldset.tsx

  • Adds an optional description prop; renders FieldsetDescription when provided.
  • Doc comment updated to mention bordered.

packages/propel/src/components/fieldset/index.tsx

  • Re-exports FieldsetDescription and its type so consumers can import from one place.

Stories — both tiers updated:

  • All Fieldset usages now pass bordered explicitly.
  • New Bordered story showing a bordered group with a description.

Callers fixed (components/field/):

  • CheckboxGroupField and RadioGroupField both render the ui-tier Fieldset directly; both now pass bordered={false} (semantic grouping, no visible frame).

Notes

  • FieldsetLegend keeps its magnitude prop. The spec says "consistent weight/size" for the legend font style — that is already true (every magnitude step uses the same font-medium text-primary base; only the size token changes). Removing magnitude would break CheckboxGroupField and RadioGroupField where the legend must match the group's control size.
  • Needs design approval before merge (@bhaveshraja).

@github-actions

Copy link
Copy Markdown

📚 Storybook preview: https://pr-192-propel-storybook.vamsi-906.workers.dev

Add `bordered` variant to `fieldsetVariants` (required, no default) for the
border-visibility axis the designer flagged as adjustable. Add a
`FieldsetDescription` ui part with its own cva variant — description text is
also listed as adjustable and the ui tier had no part for it. Wire both into
the components-tier `Fieldset` convenience component and update all stories.
Fix `CheckboxGroupField` and `RadioGroupField` (the two callers that render
the ui-tier `Fieldset` directly) to pass `bordered={false}`.

Closes #129
The fieldset alignment PR made `bordered` a required prop (no defaultVariants).
The three Fieldset usages in radio.stories.tsx were missing it, breaking the
whole-package type-check. These groups are inline (no border), so bordered=false.
The fieldset's body — the stack of contained fields with the consistent
vertical gap the design spec calls always-the-same — was being done by
ad-hoc wrapper divs in stories and consumers rather than an anatomy part.
Extract it into a single-element FieldsetBody part with its gap baked into
cva, export it, and compose it in the components-tier Fieldset and both
stories (registered in subcomponents). Radio stories that render the
fieldset as a RadioGroup keep the group's own density as the body spacing,
so they compose the ui-tier Fieldset + FieldsetLegend directly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fieldset: what should always look the same, and what should be adjustable?

1 participant