Skip to content

feat(react-checkbox): add useCheckboxBase_unstable hook#35826

Draft
dmytrokirpa wants to merge 3 commits intomasterfrom
feat/react-checkbox-base-hooks
Draft

feat(react-checkbox): add useCheckboxBase_unstable hook#35826
dmytrokirpa wants to merge 3 commits intomasterfrom
feat/react-checkbox-base-hooks

Conversation

@dmytrokirpa
Copy link
Contributor

Summary

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

What was implemented

  • useCheckboxBase_unstable — base hook for Checkbox component
    • Props type: CheckboxBaseProps (omits shape, size)
    • State type: CheckboxBaseState (omits shape, size)
    • Handles:
      • Controlled/uncontrolled checked state (useControllableState) supporting tri-state (true, false, 'mixed')
      • onChange callback with correct { checked: val } data
      • Native props partitioning (getPartitionedNativeProps)
      • Focus management via useFocusWithin
      • Input ref management (useMergedRefs) for setting indeterminate prop
      • indeterminate layout effect (useIsomorphicLayoutEffect)
      • ARIA attributes on input (type, checked, id)
      • Label slot with htmlFor, disabled, required props
      • Default checkmark icon (uses medium/square defaults)
      • Slot structure (root, input, indicator, label)

Note on icon selection

The base hook uses medium-size square/checkmark icons by default. useCheckbox_unstable overrides the indicator children with the appropriate size+shape-specific icon based on the size and shape design props.

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 Checkbox rendering unchanged (checked, unchecked, mixed states)
  • Large size and circular shape still render correct icons
  • New base hook can be used independently without design props

🤖 Generated with Claude Code

dmytrokirpa and others added 2 commits March 5, 2026 12:11
Implements base state hook for Checkbox component as part of the experimental base hooks initiative.
The base hook extracts pure component logic while omitting design props (shape, size).

- CheckboxBaseProps: omits shape, size
- CheckboxBaseState: omits shape, size
- useCheckboxBase_unstable: handles checked/indeterminate state (controlled/uncontrolled),
  onChange callback, ARIA attributes, focus management (useFocusWithin), input ref management,
  indeterminate layout effect, label slot with htmlFor, slot structure

useCheckbox_unstable now calls useCheckboxBase_unstable and adds shape+size-specific checkmark icons.
All new types and hooks exported from package index.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dmytrokirpa dmytrokirpa changed the base branch from experimental/component-base-hooks to master March 5, 2026 11:12
@dmytrokirpa dmytrokirpa force-pushed the feat/react-checkbox-base-hooks branch from 350df88 to e1eb221 Compare March 5, 2026 11:12
@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 - Dark Mode.default.chromium.png 1107 Changed
vr-tests-react-components/CalendarCompat.multiDayView - High Contrast.default.chromium.png 1236 Changed
vr-tests-react-components/CalendarCompat.multiDayView - RTL.default.chromium.png 495 Changed
vr-tests-react-components/CalendarCompat.multiDayView.default.chromium_1.png 403 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 611 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 193 Changed
vr-tests-react-components/TagPicker 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png 635 Changed
vr-tests-react-components/TagPicker.disabled.disabled input hover.chromium.png 677 Changed

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

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 5, 2026

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-checkbox
Checkbox
33.522 kB
11.407 kB
33.691 kB
11.447 kB
169 B
40 B
react-components
react-components: entire library
1.292 MB
323.107 kB
1.292 MB
323.153 kB
173 B
46 B
react-list
ListItem
110.695 kB
32.627 kB
110.864 kB
32.665 kB
169 B
38 B
react-table
DataGrid
159.313 kB
44.939 kB
159.492 kB
44.989 kB
179 B
50 B
react-table
Table as DataGrid
130.528 kB
35.943 kB
130.709 kB
35.973 kB
181 B
30 B
react-table
Table (Selection only)
68.916 kB
19.309 kB
69.095 kB
19.362 kB
179 B
53 B
react-table
Table (Sort only)
67.559 kB
18.924 kB
67.738 kB
18.974 kB
179 B
50 B
react-tree
FlatTree
147.635 kB
42.134 kB
147.808 kB
42.158 kB
173 B
24 B
react-tree
PersonaFlatTree
149.463 kB
42.517 kB
149.634 kB
42.551 kB
171 B
34 B
react-tree
PersonaTree
145.523 kB
41.338 kB
145.696 kB
41.381 kB
173 B
43 B
react-tree
Tree
143.701 kB
40.972 kB
143.874 kB
41.016 kB
173 B
44 B
Unchanged fixtures
Package & Exports Size (minified/GZIP)
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-list
List
87.11 kB
25.762 kB
react-portal-compat
PortalCompatProvider
8.386 kB
2.624 kB
react-table
Table (Primitives only)
40.997 kB
13.172 kB
react-timepicker-compat
TimePicker
108.174 kB
35.695 kB
🤖 This report was generated against ace36179073ac4600a3635304a0941bd7dcda21d

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