Skip to content

Conversation

@dmytrokirpa
Copy link
Contributor

@dmytrokirpa dmytrokirpa commented Dec 3, 2025

Problem

Some of our partners have specific design and technical needs—their designs don't use the Fluent 2 design system, and technically, they prefer to avoid Griffel and fluent tokens.

Solution

TLDR

To address this, we're looking at offering headless or unstyled v9 components. These would provide our components without built-in styles, including only slot classes and state modifier classes (similar to BEM).

Details

The main idea is explained in #35464. We plan to create .headless.ts style hooks that add static classes to component slots based on their state. Consumers would need to adjust their bundler resolution to use these headless files when they're available. This method lets us make the change without affecting current functionality. We're already using a similar approach for "raw/unprocessed" styles: https://storybooks.fluentui.dev/react/?path=/docs/concepts-developer-unprocessed-styles--docs

How to use it

  1. Configure a bundler's (Vite/Webpack/etc) resolution to prefer .headless.js files when they are available
  2. Instead of regular FluentProvider use ThemelessFluentProvider from contrib as we don't want to use Griffel providers.
  3. use Button/SpinButton/MenuButton/SplitButton or Divider, as these are the only headless components atm
import { ThemelessFluentProvider } from '@fluentui-contrib/react-themeless-provider';

<ThemelessFluentProvider>
  <Button appearance="primary">Button</Button>
<ThemelessFluentProvider>

You can now apply your own styles using custom style hooks supported in headless components, or use any CSS method you prefer to style headless components.

Bundle size comparison

It’s not really a fair comparison since we’re looking at styled vs unstyled components. But like the problem statement says, our partners aren’t interested in using our default styles or Griffel, so they don’t want to deal with the extra bundle or runtime costs for stuff they won’t actually use.

Default

Screenshot 2025-11-14 at 12 48 22
Headless/Unstyled
Screenshot 2025-11-14 at 12 50 20

@github-actions
Copy link

github-actions bot commented Dec 3, 2025

📊 Bundle size report

✅ No changes found

@github-actions
Copy link

github-actions bot commented Dec 3, 2025

Pull request demo site: URL

@dmytrokirpa dmytrokirpa changed the title Headless components feat(react-button,react-divider): headless style hooks for buttons and divider components Dec 3, 2025
@dmytrokirpa dmytrokirpa enabled auto-merge (squash) December 4, 2025 16:54
@dmytrokirpa dmytrokirpa merged commit a9c009e into master Dec 5, 2025
15 checks passed
@dmytrokirpa dmytrokirpa deleted the headless-components branch December 5, 2025 13:54
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.

5 participants