Skip to content

feat(field-set): add Field Set component#14866

Draft
brendan-vincent-rice wants to merge 25 commits into
devfrom
brendan-vincent-rice/12450-field-set-component
Draft

feat(field-set): add Field Set component#14866
brendan-vincent-rice wants to merge 25 commits into
devfrom
brendan-vincent-rice/12450-field-set-component

Conversation

@brendan-vincent-rice

Copy link
Copy Markdown
Member

Related Issue: #12450

Summary

This PR adds the new Field Set component, which can used to group Input and Label components into groups.

The component includes:

  • Slots for the <legend> text and form controls.
  • CSS variables to override the default <legend> text color and space between slotted elements.
  • scale and disabled props, which override individual settings of slotted components.
  • props for layout (vertical, horizontal, grid) and columns (when setting layout='grid').
  • props for equalizing the widths of "prefix" and "suffix" elements for improved vertical alignment.

@brendan-vincent-rice brendan-vincent-rice self-assigned this Jul 22, 2026
@brendan-vincent-rice brendan-vincent-rice added the pr ready for visual snapshots Adding this label will run visual snapshot testing. label Jul 22, 2026
@github-actions github-actions Bot added the enhancement Issues tied to a new feature or request. label Jul 22, 2026
<div class={CSS.suffix} ref={this.suffixRef}>
{this.suffixText}
</div>
);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The Input is owning its prefix/suffix sizing details rather than the Field Set inspecting its slotted children shadow DOMs.

layout: "vertical" | "horizontal" | "grid";
columns?: 1 | 2 | 3 | 4 | 5 | 6;
prefixAutoWidth: boolean;
suffixAutoWidth: boolean;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

When toggling the "suffixAutoWidth" in Storybook, the "centimeters" suffix appears to shift to the left a bit. This is because the "suffix" element renders at 94.16px by default. When the "suffixAutoWidth" toggle is used and the alignment math kicks in, it increases to a whole number (95px).

Screen.Recording.2026-07-22.at.4.01.21.PM.mov
Image

:host([columns="#{$i}"]) {
--calcite-internal-field-set-columns: #{$i};
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The for loop saves us from being more verbose:

:host([columns="1"]) {
  --calcite-internal-field-set-columns: 1;
}

:host([columns="2"]) {
  --calcite-internal-field-set-columns: 2;
}

:host([columns="3"]) {
  --calcite-internal-field-set-columns: 3;
}

:host([columns="4"]) {
  --calcite-internal-field-set-columns: 4;
}

:host([columns="5"]) {
  --calcite-internal-field-set-columns: 5;
}

:host([columns="6"]) {
  --calcite-internal-field-set-columns: 6;
}

display: grid;
place-content: stretch;
grid-template-columns: repeat(
var(--calcite-field-set-columns, var(--calcite-internal-field-set-columns, 2)),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The component currently defaults to two columns when using layout='grid'.

font-weight: var(--calcite-font-weight-medium);
color: var(--calcite-field-set-legend-text-color, var(--calcite-color-text-1));
min-block-size: var(--calcite-space-3xl);
float: inline-start; // TODO: this is a hack; consider using <div> instead of <legend>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Using float: inline-start or float: left saves us from needing to use a <div> instead of a <legend> or wrapping the <legend> in a <div>.

<legend> elements are intrinsic <fieldset> children and don't respond to parent display: flex declarations, flex-direction or gap properties without the float "workaround." As I type, I'm leaning toward simply wrapping the <legend> in <div> 😄

Image

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new calcite-field-set component to group form controls (notably calcite-input and calcite-label) with configurable layout, scale/disabled propagation, spacing customization, and optional prefix/suffix width coordination across inputs.

Changes:

  • Introduces the new calcite-field-set component (TSX + styles + resources) with layout, columns, scale, disabled, and affix auto-width props.
  • Updates calcite-input to measure its prefix/suffix rendered widths and expose them via internal host CSS custom properties for parent coordination.
  • Adds Storybook stories and E2E/browser tests covering structure, styling, propagation, and affix width behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/components/src/components/label/label.tsx Minor formatting adjustment in label private-methods region.
packages/components/src/components/input/input.tsx Adds internal measurement of prefix/suffix widths and stores them on host CSS custom properties.
packages/components/src/components/input/input.browser.e2e.tsx Adds browser tests validating internal affix width CSS properties are set/cleared.
packages/components/src/components/field-set/resources.ts Adds Field Set CSS class name constants.
packages/components/src/components/field-set/field-set.tsx Implements calcite-field-set behavior: layout, scale/disabled propagation, and affix width coordination.
packages/components/src/components/field-set/field-set.stories.ts Adds Storybook stories demonstrating layouts, scales, spacing, legend styling, and affix auto-width.
packages/components/src/components/field-set/field-set.scss Adds Field Set styling, layout variants, spacing variables, and columns handling.
packages/components/src/components/field-set/field-set.e2e.ts Adds basic E2E coverage for structure and horizontal layout class.
packages/components/src/components/field-set/field-set.browser.e2e.tsx Adds browser tests for hidden/renders, layout, propagation, styling, and affix width coordination.

Comment thread packages/components/src/components/field-set/field-set.scss Outdated
Comment thread packages/components/src/components/field-set/field-set.tsx Outdated
Comment thread packages/components/src/components/field-set/field-set.tsx Outdated
Comment thread packages/components/src/components/field-set/field-set.stories.ts Outdated
brendan-vincent-rice and others added 2 commits July 23, 2026 09:09
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@brendan-vincent-rice brendan-vincent-rice added pr ready for visual snapshots Adding this label will run visual snapshot testing. and removed pr ready for visual snapshots Adding this label will run visual snapshot testing. labels Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Issues tied to a new feature or request. pr ready for visual snapshots Adding this label will run visual snapshot testing.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants