Skip to content

feat(react-headless-components-preview): add drawer components#36043

Merged
dmytrokirpa merged 12 commits intomasterfrom
headless-drawer-components
Apr 30, 2026
Merged

feat(react-headless-components-preview): add drawer components#36043
dmytrokirpa merged 12 commits intomasterfrom
headless-drawer-components

Conversation

@dmytrokirpa
Copy link
Copy Markdown
Contributor

@dmytrokirpa dmytrokirpa commented Apr 25, 2026

This PR adds new Drawer components to the @fluentui/react-headless-components-preview package, providing a headless implementation for drawers including overlay and inline variants. It introduces the main Drawer component along with supporting subcomponents, updates the package's API and dependencies, and adds comprehensive tests and Cypress integration tests to ensure correct behavior and accessibility.

Preview:

https://fluentuipr.z22.web.core.windows.net/pull/36043/public-docsite-v9-headless/storybook/index.html?path=/docs/headless-components-drawer--docs

Demo:

Screen.Recording.2026-04-29.at.22.11.52.mov

@dmytrokirpa dmytrokirpa requested a review from a team as a code owner April 25, 2026 07:57
@dmytrokirpa dmytrokirpa marked this pull request as draft April 25, 2026 07:58
@github-actions
Copy link
Copy Markdown

Pull request demo site: URL

@dmytrokirpa dmytrokirpa self-assigned this Apr 27, 2026
@dmytrokirpa dmytrokirpa changed the base branch from drawer-base-hooks to master April 28, 2026 13:04
@dmytrokirpa dmytrokirpa force-pushed the headless-drawer-components branch from f67aaa8 to feab03f Compare April 28, 2026 13:06
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-headless-components-preview
react-headless-components-preview: entire library
85.341 kB
25.007 kB
90.526 kB
26.248 kB
5.185 kB
1.241 kB

🤖 This report was generated against f4ba0c3cbba6b1b985f3824e839d3bf93027987a

@dmytrokirpa dmytrokirpa force-pushed the headless-drawer-components branch from feab03f to a7821bb Compare April 29, 2026 17:35
@dmytrokirpa dmytrokirpa force-pushed the headless-drawer-components branch from a7821bb to 03aedb1 Compare April 29, 2026 19:50
@dmytrokirpa dmytrokirpa added Component: Drawer The Fluent v9 Drawer component Headless labels Apr 29, 2026
@dmytrokirpa dmytrokirpa marked this pull request as ready for review April 29, 2026 20:20
dmytrokirpa and others added 2 commits April 30, 2026 00:13
Co-authored-by: Copilot <copilot@github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new headless Drawer API surface to @fluentui/react-headless-components-preview, including overlay (native <dialog>-based) and inline variants, along with Storybook docs and test coverage.

Changes:

  • Added Drawer, OverlayDrawer, InlineDrawer and related subcomponents (Header/Body/Footer/Title/Navigation) with a new drawer export entrypoint.
  • Introduced Storybook stories + docs markdown for the new Drawer components.
  • Added unit tests and Cypress coverage for behavior and accessibility-related semantics.

Reviewed changes

Copilot reviewed 51 out of 51 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/react-components/react-headless-components-preview/stories/src/Drawer/index.stories.tsx Registers Drawer stories + docs description for Storybook.
packages/react-components/react-headless-components-preview/stories/src/Drawer/InlineDrawer.stories.tsx Adds an inline drawer example story.
packages/react-components/react-headless-components-preview/stories/src/Drawer/DrawerDescription.md Adds docs blurb for Drawer.
packages/react-components/react-headless-components-preview/stories/src/Drawer/DefaultDrawer.stories.tsx Adds an overlay drawer example story.
packages/react-components/react-headless-components-preview/library/src/drawer.ts Adds public exports for the new drawer entrypoint.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/useDrawer.ts Implements Drawer wrapper that selects inline vs overlay variant.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/renderDrawer.tsx Renders the selected Drawer variant.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/index.ts Barrel exports for Drawer + subcomponents.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/OverlayDrawer/useOverlayDrawer.ts Creates state for native-dialog-based overlay drawer.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/OverlayDrawer/renderOverlayDrawer.tsx Reuses @fluentui/react-drawer overlay render helper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/OverlayDrawer/index.ts Barrel exports for OverlayDrawer.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/OverlayDrawer/OverlayDrawer.types.ts Defines headless overlay drawer types (Dialog-composed).
packages/react-components/react-headless-components-preview/library/src/components/Drawer/OverlayDrawer/OverlayDrawer.tsx OverlayDrawer component wiring hook + render.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/InlineDrawer/useInlineDrawer.ts Creates state for inline drawer (currently based on react-drawer base hook).
packages/react-components/react-headless-components-preview/library/src/components/Drawer/InlineDrawer/renderInlineDrawer.tsx Reuses @fluentui/react-drawer inline render helper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/InlineDrawer/index.ts Barrel exports for InlineDrawer.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/InlineDrawer/InlineDrawer.types.ts Defines headless inline drawer types + added data attrs.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/InlineDrawer/InlineDrawer.tsx InlineDrawer component wiring hook + render.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderTitle/useDrawerHeaderTitle.ts Adapts DrawerHeaderTitle heading id to headless Dialog context.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderTitle/renderDrawerHeaderTitle.ts Reuses @fluentui/react-drawer title render helper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderTitle/index.ts Barrel exports for DrawerHeaderTitle.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderTitle/DrawerHeaderTitle.types.ts Type re-exports for DrawerHeaderTitle.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderTitle/DrawerHeaderTitle.tsx DrawerHeaderTitle component wiring hook + render.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderNavigation/useDrawerHeaderNavigation.ts Reuses @fluentui/react-drawer navigation hook.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderNavigation/renderDrawerHeaderNavigation.ts Reuses @fluentui/react-drawer navigation render helper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderNavigation/index.ts Barrel exports for DrawerHeaderNavigation.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderNavigation/DrawerHeaderNavigation.types.ts Type re-exports for DrawerHeaderNavigation.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeaderNavigation/DrawerHeaderNavigation.tsx DrawerHeaderNavigation component wiring hook + render.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeader/useDrawerHeader.ts Reuses @fluentui/react-drawer header hook + adds data attr.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeader/renderDrawerHeader.ts Reuses @fluentui/react-drawer header render helper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeader/index.ts Barrel exports for DrawerHeader.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeader/DrawerHeader.types.ts Type re-exports for DrawerHeader + added data attr.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerHeader/DrawerHeader.tsx DrawerHeader component wiring hook + render.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerFooter/useDrawerFooter.ts Reuses @fluentui/react-drawer footer hook + adds data attr.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerFooter/renderDrawerFooter.ts Reuses @fluentui/react-drawer footer render helper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerFooter/index.ts Barrel exports for DrawerFooter.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerFooter/DrawerFooter.types.ts Type re-exports for DrawerFooter + added data attr.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerFooter/DrawerFooter.tsx DrawerFooter component wiring hook + render.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerBody/useDrawerBody.ts Reuses @fluentui/react-drawer body hook.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerBody/renderDrawerBody.ts Reuses @fluentui/react-drawer body render helper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerBody/index.ts Barrel exports for DrawerBody.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerBody/DrawerBody.types.ts Type re-exports for DrawerBody.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/DrawerBody/DrawerBody.tsx DrawerBody component wiring hook + render.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/Drawer.types.ts Defines public DrawerProps / DrawerState.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/Drawer.tsx Implements Drawer component wrapper.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/Drawer.test.tsx Adds unit tests for Drawer variants and Dialog naming.
packages/react-components/react-headless-components-preview/library/src/components/Drawer/Drawer.cy.tsx Adds Cypress coverage for core scenarios + a11y semantics.
packages/react-components/react-headless-components-preview/library/package.json Adds dependency + export map for ./drawer.
packages/react-components/react-headless-components-preview/library/etc/drawer.api.md Adds API extractor report for new entrypoint.
packages/react-components/react-headless-components-preview/library/bundle-size/AllComponents.fixture.js Includes drawer entrypoint (and card) in bundle-size fixture.
change/@fluentui-react-headless-components-preview-338990b0-7296-45e7-9d92-2664aa67375c.json Beachball change file for the new feature.

Comment thread packages/react-components/react-headless-components-preview/library/package.json Outdated
@dmytrokirpa
Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

…er components

- Update @fluentui/react-drawer dep version to ^9.12.0
- Fix className strings with extra single quotes in stories
- Change unmountOnClose default to true in useOverlayDrawer
- Fix InlineDrawer renderInlineDrawer to handle unmountOnClose properly
- Add guard for empty dialogTitleId in useDrawerHeaderTitle
- Change DrawerProps to proper discriminated union
- Exclude type prop from spread in useDrawer"

Agent-Logs-Url: https://github.com/microsoft/fluentui/sessions/823f5537-f61d-425d-b274-f2dff491d2ca

Co-authored-by: dmytrokirpa <1492102+dmytrokirpa@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 30, 2026

@copilot apply changes based on the comments in this thread

Applied all changes from the review thread in commit e83ef2f:

  1. package.json: Updated @fluentui/react-drawer to ^9.12.0
  2. DefaultDrawer.stories.tsx / InlineDrawer.stories.tsx: Fixed className strings — removed wrapping single quotes inside template literals so Tailwind classes resolve correctly
  3. useOverlayDrawer.ts: Changed unmountOnClose default to true (aligns with @fluentui/react-drawer defaults and tests)
  4. renderInlineDrawer.tsx: Replaced the cast of renderInlineDrawer_unstable with a custom render that returns null when unmountOnClose=true and open=false, properly handling the unmount behavior
  5. useDrawerHeaderTitle.ts: Added a guard to only set id on the heading when dialogTitleId is non-empty — prevents id="" on headings in inline drawer contexts
  6. Drawer.types.ts: Changed DrawerProps to a proper discriminated union keyed by type, preventing overlay-only props from being passed with type="inline" and vice versa
  7. useDrawer.ts: Destructures type before spreading props to prevent forwarding it as an unknown prop to the underlying InlineDrawer/OverlayDrawer components

@dmytrokirpa dmytrokirpa requested a review from Hotell April 30, 2026 12:59
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 30, 2026

@dmytrokirpa I've opened a new pull request, #36083, to work on those changes. Once the pull request is ready, I'll request review from you.

…fixture, add DrawerHeaderTitle test

- Remove Card import from AllComponents.fixture.js (belongs in separate PR)
- Add unit test to verify DrawerHeaderTitle heading does not get id="" when outside Dialog context

Co-authored-by: dmytrokirpa <1492102+dmytrokirpa@users.noreply.github.com>
…nent type re-exports

Use direct re-exports instead of import-alias-then-re-export pattern in:
- DrawerBody.types.ts
- DrawerHeaderNavigation.types.ts
- DrawerHeaderTitle.types.ts
- DrawerFooter.types.ts (Slots/Props direct, State keeps extension)
- DrawerHeader.types.ts (Slots/Props direct, State keeps extension)
- InlineDrawer.types.ts (Slots/Props direct, State keeps extension)

Agent-Logs-Url: https://github.com/microsoft/fluentui/sessions/ffc48e67-9724-4369-9889-3fd8627c2426

Co-authored-by: dmytrokirpa <1492102+dmytrokirpa@users.noreply.github.com>
@dmytrokirpa dmytrokirpa enabled auto-merge (squash) April 30, 2026 16:19
@dmytrokirpa dmytrokirpa merged commit c7766b6 into master Apr 30, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants