Skip to content

feat(react-headless-components-preview): add Card component#36005

Open
dmytrokirpa wants to merge 4 commits intomicrosoft:masterfrom
dmytrokirpa:feat/headless-components-preview-card
Open

feat(react-headless-components-preview): add Card component#36005
dmytrokirpa wants to merge 4 commits intomicrosoft:masterfrom
dmytrokirpa:feat/headless-components-preview-card

Conversation

@dmytrokirpa
Copy link
Copy Markdown
Contributor

Summary

Adds a headless Card with CardHeader, CardFooter, and CardPreview subcomponents that wrap the base hooks from @fluentui/react-card.

Depends on

⚠️ Until the prerequisite PR merges, the diff here also includes its commit. Please review that PR first. After it merges, this branch will be rebased to drop the duplicate commit.

Behavior

  • ✅ Selection works end-to-end: selected / defaultSelected / onSelectionChange, the auto-rendered checkbox slot (or floatingAction), aria-labelledby wiring from CardHeader, click & Enter-key toggling, and disabled short-circuiting.
  • focusMode is intentionally omitted from CardProps (Omit<CardBaseProps, 'focusMode'>). Tabster groupper-style Tab-trap semantics (limited / limited-trap-focus / unlimited) cannot be expressed with the WICG focusgroup polyfill the headless package relies on. Consumers can implement equivalent behavior on top of the rendered DOM if needed.

Storybook examples

  • Default — Card composition with header, preview, body, and footer.
  • Selectable — controlled selection driven by the auto-rendered checkbox slot.
  • Disabled — disabled selectable card showing aria-disabled handling and short-circuited toggling.

Verification

  • yarn nx build react-headless-components-preview succeeds (api.md regenerated).
  • yarn nx run react-headless-components-preview:test --testPathPatterns Card — 16/16 pass (isConformant + default render snapshot).

Move @fluentui/react-tabster usage out of useCardBase_unstable and
useCardSelectable into useCard_unstable. The base hooks no longer
manage focusable-group attributes or the focus-aware selection
restriction predicate.

useCardSelectable now reads an optional shouldRestrictTriggerAction
predicate from CardBaseProps; useCard_unstable provides one based on
useFocusFinders + useFocusWithin to preserve existing behavior. This
lets headless component packages consume the base hooks without
pulling in @fluentui/react-tabster.
Adds a headless Card with CardHeader, CardFooter, and CardPreview
subcomponents that wrap the base hooks from @fluentui/react-card.

Selection works (selected, defaultSelected, onSelectionChange,
auto-rendered checkbox / floatingAction slots, click and Enter
toggling, disabled handling). focusMode is intentionally omitted
from CardProps because tabster groupper-style Tab-trap semantics
cannot be expressed with the WICG focusgroup polyfill the headless
package relies on.

Includes Default, Selectable, and Disabled Storybook examples.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 19, 2026

📊 Bundle size report

Package & Exports Baseline (minified/GZIP) PR Change
react-card
Card - All
105.24 kB
29.479 kB
105.231 kB
29.543 kB
-9 B
64 B
react-card
Card
97.858 kB
27.587 kB
97.849 kB
27.634 kB
-9 B
47 B
react-components
react-components: entire library
1.3 MB
325.038 kB
1.3 MB
325.085 kB
-22 B
47 B
react-headless-components-preview
react-headless-components-preview: entire library
70.65 kB
20.862 kB
76.011 kB
22.312 kB
5.361 kB
1.45 kB
Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-card
CardFooter
12.792 kB
5.12 kB
react-card
CardHeader
15.321 kB
5.98 kB
react-card
CardPreview
12.872 kB
5.255 kB
react-components
react-components: Button, FluentProvider & webLightTheme
70.415 kB
19.963 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
237.205 kB
68.894 kB
react-components
react-components: FluentProvider & webLightTheme
43.63 kB
14.026 kB
react-portal-compat
PortalCompatProvider
8.386 kB
2.624 kB
react-timepicker-compat
TimePicker
108.995 kB
36.042 kB
🤖 This report was generated against 70972f1b1169ae00247b080202ce05581c2dd62f

@github-actions
Copy link
Copy Markdown

Pull request demo site: URL

@dmytrokirpa dmytrokirpa marked this pull request as draft April 19, 2026 13:34
@@ -0,0 +1,7 @@
{
Copy link
Copy Markdown

@github-actions github-actions Bot Apr 19, 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/Charts-DonutChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Charts-DonutChart.Dynamic.default.chromium.png 5581 Changed
vr-tests-react-components/Menu 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu.Nested Submenus Small Viewport Flipped.nested menu.chromium.png 122 Changed
vr-tests-react-components/Menu Converged - submenuIndicator slotted content 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default - RTL.submenus open.chromium.png 404 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 878 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 623 Changed
vr-tests-react-components/ProgressBar converged 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - Dark Mode.default.chromium.png 51 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - High Contrast.default.chromium.png 60 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness.default.chromium.png 61 Changed
vr-tests-react-components/TagPicker 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - High Contrast.disabled input hover.chromium.png 1319 Changed

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

@dmytrokirpa dmytrokirpa marked this pull request as ready for review April 22, 2026 14:15
@dmytrokirpa dmytrokirpa requested a review from mainframev April 22, 2026 14:15
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