Skip to content

feat(react-field): add useFieldBase_unstable hook#35827

Draft
dmytrokirpa wants to merge 4 commits intomasterfrom
feat/react-field-base-hooks
Draft

feat(react-field): add useFieldBase_unstable hook#35827
dmytrokirpa wants to merge 4 commits intomasterfrom
feat/react-field-base-hooks

Conversation

@dmytrokirpa
Copy link
Contributor

Summary

This PR adds a base state hook for the Field component as part of the experimental base hooks initiative.

What was implemented

  • useFieldBase_unstable — base hook for Field component
    • Props type: FieldBaseProps (omits orientation, size)
    • State type: FieldBaseState (omits orientation, size)
    • Handles:
      • validationState defaulting ('error' when validationMessage is set, 'none' otherwise)
      • role="alert" on validationMessage for error and warning states
      • ID generation (useId) for form control association (generatedControlId)
      • Label slot with htmlFor, id, required props
      • ValidationMessage slot with id and role
      • Hint slot with id
      • ValidationMessageIcon slot with appropriate icon (ErrorCircle12Filled, Warning12Filled, CheckmarkCircle12Filled, or none)
      • Slot structure (root, label, validationMessage, validationMessageIcon, hint)

Note on size

The size prop controls the label's size. In useField_unstable, after calling useFieldBase_unstable, the size value is merged into the label slot's props. orientation is added directly to the returned state object.

Exports

All new types and hooks are exported from the package index.ts. They are NOT exported from @fluentui/react-components.

Test plan

  • TypeScript compilation passes (npx tsc --noEmit on the package)
  • Existing Field rendering unchanged
  • Validation states (error, warning, success) still render correct icons and ARIA attributes
  • Label correctly associates with the control via htmlFor
  • New base hook can be used independently without design props

🤖 Generated with Claude Code

@dmytrokirpa dmytrokirpa changed the base branch from experimental/component-base-hooks to master March 5, 2026 09:54
dmytrokirpa and others added 2 commits March 5, 2026 12:12
Implements base state hook for Field component as part of the experimental base hooks initiative.
The base hook extracts pure component logic while omitting design props (orientation, size).

- FieldBaseProps: omits orientation, size
- FieldBaseState: omits orientation, size
- useFieldBase_unstable: handles
  - validationState with role="alert" for error/warning messages
  - ID generation (baseId, generatedControlId) for form control association
  - label slot with htmlFor, id, required
  - validationMessage slot with id, role
  - hint slot with id
  - validationMessageIcon slot with appropriate icon based on validationState
  - slot structure (root, label, validationMessage, validationMessageIcon, hint)

useField_unstable now calls useFieldBase_unstable and adds orientation, size design props.
The size prop is merged into the label slot's props.
All new types and hooks exported from package index.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dmytrokirpa dmytrokirpa force-pushed the feat/react-field-base-hooks branch from 013b527 to 6a809a3 Compare March 5, 2026 11:13
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-components
react-components: entire library
1.292 MB
323.107 kB
1.292 MB
323.16 kB
88 B
53 B
react-field
Field
21.925 kB
8.257 kB
22.013 kB
8.282 kB
88 B
25 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-checkbox
Checkbox
33.522 kB
11.407 kB
react-combobox
Combobox (including child components)
105.208 kB
34.168 kB
react-combobox
Dropdown (including child components)
105.832 kB
34.1 kB
react-components
react-components: Button, FluentProvider & webLightTheme
70.397 kB
19.96 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
236.537 kB
68.697 kB
react-components
react-components: FluentProvider & webLightTheme
43.612 kB
14.022 kB
react-datepicker-compat
DatePicker Compat
225.061 kB
63.608 kB
react-input
Input
26.246 kB
8.688 kB
react-list
List
87.11 kB
25.762 kB
react-list
ListItem
110.695 kB
32.627 kB
react-portal-compat
PortalCompatProvider
8.386 kB
2.624 kB
react-progress
ProgressBar
15.7 kB
6.214 kB
react-radio
Radio
30.905 kB
9.611 kB
react-radio
RadioGroup
13.994 kB
5.688 kB
react-select
Select
26.085 kB
9.437 kB
react-slider
Slider
36.322 kB
12.065 kB
react-spinbutton
SpinButton
33.637 kB
11.067 kB
react-swatch-picker
@fluentui/react-swatch-picker - package
104.305 kB
29.944 kB
react-switch
Switch
36.105 kB
11.011 kB
react-table
DataGrid
159.313 kB
44.939 kB
react-table
Table (Primitives only)
40.997 kB
13.172 kB
react-table
Table as DataGrid
130.528 kB
35.943 kB
react-table
Table (Selection only)
68.916 kB
19.309 kB
react-table
Table (Sort only)
67.559 kB
18.924 kB
react-tag-picker
@fluentui/react-tag-picker - package
186.596 kB
55.849 kB
react-textarea
Textarea
24.628 kB
8.954 kB
react-timepicker-compat
TimePicker
108.174 kB
35.695 kB
react-tree
FlatTree
147.635 kB
42.134 kB
react-tree
PersonaFlatTree
149.463 kB
42.517 kB
react-tree
PersonaTree
145.523 kB
41.338 kB
react-tree
Tree
143.701 kB
40.972 kB
🤖 This report was generated against ace36179073ac4600a3635304a0941bd7dcda21d

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Pull request demo site: URL

@@ -0,0 +1,7 @@
{
Copy link

@github-actions github-actions bot Mar 5, 2026

Choose a reason for hiding this comment

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

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/CalendarCompat 4 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/CalendarCompat.multiDayView - High Contrast.default.chromium.png 1236 Changed
vr-tests-react-components/CalendarCompat.multiDayView - Dark Mode.default.chromium.png 1107 Changed
vr-tests-react-components/CalendarCompat.multiDayView.default.chromium.png 495 Changed
vr-tests-react-components/CalendarCompat.multiDayView.default.chromium_1.png 403 Changed
vr-tests-react-components/Charts-DonutChart 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Charts-DonutChart.Dynamic.default.chromium.png 5581 Changed
vr-tests-react-components/Charts-DonutChart.Dynamic - RTL.default.chromium.png 5570 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 609 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 507 Changed
vr-tests-react-components/Skeleton converged 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Skeleton converged.Opaque Skeleton with circle - High Contrast.default.chromium.png 1 Changed
vr-tests-react-components/TagPicker 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - Dark Mode.disabled input hover.chromium.png 658 Changed
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png 635 Changed

There were 3 duplicate changes discarded. Check the build logs for more information.

dmytrokirpa and others added 2 commits March 5, 2026 13:21
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant