RFC: Headless Components (@fluentui/react-headless-components)#35984
RFC: Headless Components (@fluentui/react-headless-components)#35984dmytrokirpa wants to merge 4 commits intomicrosoft:masterfrom
Conversation
Proposes `@fluentui/react-headless` — unstyled components built from base state hooks and render functions, with stable `data-*` attributes as the CSS-targeting contract for component state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📊 Bundle size report✅ No changes found |
|
Pull request demo site: URL |
7d11b15 to
4e58ed7
Compare
| Headless components include: | ||
|
|
||
| - behavior and ARIA from base hooks | ||
| - existing slot API |
There was a problem hiding this comment.
we should highlight info about default slots ( no icons etc )
| Ship headless components from `@fluentui/react-headless-components`. | ||
|
|
||
| ```tsx | ||
| import { Button, Checkbox } from '@fluentui/react-headless-components'; |
There was a problem hiding this comment.
should highlight the export maps api only
| ``` | ||
|
|
||
| This abstraction preserves the existing base architecture but removes repetitive wiring from app | ||
| code. Note: headless components wrap existing hooks — they introduce no new behavior or |
There was a problem hiding this comment.
lets improve the structure
| code. Note: headless components wrap existing hooks — they introduce no new behavior or | |
| code. | |
| > **💁♂️ Note:** headless components wrap existing hooks — they introduce no new behavior or |
|
|
||
| ### State To `data-*` Mapping (Primary Contract) | ||
|
|
||
| Headless state hooks map internal state to stable `data-*` attributes. Components then render |
There was a problem hiding this comment.
might be good to note that this pattern is also used for icons headless
| - no design-state attributes (no appearance/size/shape) | ||
| - removal/rename is breaking (major) | ||
| - adding a new attribute is non-breaking for CSS selectors; it may affect snapshot tests, which is acceptable | ||
| - data attributes must be documented on the components documentation page (Storybook docsite) |
There was a problem hiding this comment.
it would be actually good to have these as part of State type, then this will be part of .d.ts -> easy agent metadata extraction / SB table enablement
| Use headless when teams need Fluent behavior with non-Fluent visuals. | ||
| Use styled components when teams want Fluent visuals with branding tweaks. |
There was a problem hiding this comment.
this probably doesn't have to be part of this RFC, as the goal is clearly set above
- Clarify slot API: root slot only by default; optional slots (icon, avatar, indicator) require explicit props - Remove redundant use-case guidance (already covered by Goal section) - Add note that only the export-map root is a supported import surface - Reformat composition-model note as a blockquote - Note that icon-state data attributes follow the same data-* pattern - Require data attributes to be typed on the State type for .d.ts / Storybook props-table / agent metadata extraction Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
||
| **[Radix UI](https://www.radix-ui.com/)** uses a single `data-state` attribute per component with semantic string values (`data-state="open"` / `"closed"` on Dialog, `data-state="checked"` / `"unchecked"` on Checkbox). Additional attributes like `data-disabled` and `data-highlighted` cover contextual state. | ||
|
|
||
| **[React Aria Components](https://react-spectrum.adobe.com/react-aria/react-aria-components.html)** (Adobe) emits granular per-property `data-*` attributes (`data-hovered`, `data-pressed`, `data-focused`, `data-focus-visible`, `data-disabled`, `data-selected`, `data-orientation`, etc.). It also supports render props as an alternative — consumers can pass a function to `className` or `style` that receives the full component state object. |
There was a problem hiding this comment.
Do you need so many examples of data-attributes? Probably 3 would be enough before "etc"
Summary
Proposes
@fluentui/react-headless— a package of unstyled components built from base state hooks and render functions, with stabledata-*attributes as the CSS-targeting contract for component state.This is the next layer above the Base State Hooks RFC.
What's in this RFC
@fluentui/react-headlessas a single import surface re-exporting base hooks from individual packagesdata-*attribute schema on root slots, emitted by both headless and styled variantsRelated