This document inventories how @coreai-ds/react-components differs from using Fluent UI v9 directly, organized by component or component family.
For more details, see the storybook for each component
Global platform behavior
Files: src/theme.ts, src/CoreAIFluentProvider.tsx, src/styleHooks.ts, src/index.ts, src/globalStyles.ts, src/FluentThemeModeContext.tsx
- CoreAI theme tokens differ from stock Fluent (brand ramp, light/dark token overrides, Aptos fonts, plus CoreAI interactive background tokens).
- Azure theme (
azureLightTheme/azureDarkTheme) uses the Azure/Coherence brand ramp with CoreAI's shared neutral palette, fonts, and interactive tokens. - Dark theme custom interactive tokens were increased for stronger feedback (
colorInteractiveBackgroundHover,colorInteractiveBackgroundSelected). CoreAIFluentProviderwrapsFluentProvider, defaultsthemetocoreaiLightTheme, and pre-wirescustomStyleHooks_unstable.- Component defaults are runtime-gated via
withComponentDefaults(defaulttrue). - Provider descendants receive responsive letter spacing based on their computed font size, with a
0.01emminimum at18pxand above. - Global scrollbar styling is applied by default through provider root classes.
- Barrel exports re-export Fluent, then shadow selected exports with CoreAI wrappers/extensions.
Button family (Button, CompoundButton, MenuButton, SplitButton, ToggleButton)
Files: src/componentDefaults.ts, src/components/Button.styles.ts, src/styleHooks.ts
- Default
shape="circular"for all listed Button-family wrappers. - Style-hook override sets default min-width to
40px(instead of Fluent96px) for non-icon-only variants.
SwatchPicker
Files: src/componentDefaults.ts
- Default
shape="rounded".
Card
Files: src/componentDefaults.ts, src/components/Card.styles.ts
- Default
appearance="filled-alternative". - Adds a
floatingActionPositionprop (rightdefault, plusleft) that repositions the.fui-Card__floatingActionslot. - Style-hook overrides card surface behavior (shadow/pseudo-border reset, size-based radii, interactive/selected/disabled styling, CoreAI appearance treatment).
- Cards rendered with an anchor root suppress the native link underline.
- Interactive cards preserve custom colors on nested
Textcomponents instead of forcingcurrentColor. appearance="subtle"interactive/selectable hover usescolorNeutralBackground3Hoverinstead of Fluent's defaultcolorSubtleBackgroundHover, to match side nav hover weight.
Input-family default appearance wrappers
Files: src/components/Select.ts, src/components/Textarea.ts, src/components/SearchBox.ts, src/components/SpinButton.ts, src/components/TagPicker.ts
- Default
appearance="filled-darker"for:Select,Textarea,SearchBox,SpinButton,TagPicker.
Input, Combobox, Dropdown (inline-label extensions)
Files: src/components/Input.tsx, src/components/Combobox.tsx, src/components/Dropdown.tsx, src/components/inlineLabelProps.ts, src/styleHooks.ts
- Add inline-label model (
labelrendered inside control surface). - Add
dynamicWidth(type-limited to cases wherelabelis provided). - Add
truncateTextOverflow. - Add value-aware inline label colon behavior (
Label:) via style hooks. - Add disabled-state inline-label color dimming to match Fluent disabled foreground.
- Expose stable inline-label class names:
fui-Input__label,fui-Combobox__label,fui-Dropdown__label. - Wrapper-level default
appearance="filled-darker"for these three controls.
Input specifics
Files: src/components/Input.tsx
- In
readOnlymode, auto-injectsCopyButtonintocontentAfterwhen caller does not providecontentAfter.
DropdownButton
Files: src/components/DropdownButton.tsx
- Specialized wrapper around CoreAI
Dropdownwith button-style trigger behavior. - Requires inline
label. - Uses Fluent Button styling pipeline (
useButtonStyles_unstable) and supports Button-style trigger props (appearance,shape,size,disabled). - Current appearance set aligns to Button appearances (
secondary,primary,outline,subtle,transparent) with default behavior matchingsecondary.
LinkButton
Files: src/components/LinkButton.tsx
- New component, no stock Fluent equivalent — CoreAI
Buttonrendered with a native<a>root. - Supports the complete Button content and visual API, including
icon,iconPosition,appearance,shape,size,disabled, anddisabledFocusable, plus native anchor attributes and anHTMLAnchorElementref. - Accepts an anchor-compatible component through
asfor framework router integration. - Adds Link's
externalbehavior: appends an external-link icon and defaultstarget="_blank"andrel="noopener noreferrer", while preserving explicit overrides. - Fluent's supported anchor-root Button behavior strips
href, setsaria-disabled, and suppresses click/keyboard activation fordisabledanddisabledFocusable;disabledFocusableremains in the tab order. - Does not provide a loading state: links navigate to resources rather than representing pending actions. Use a button for operations that need loading feedback.
DateTimePicker
Files: src/components/DateTimePicker.tsx, src/components/dateTimePickerValue.ts, src/index.ts
- New component, no direct stock Fluent equivalent — a thin wrapper around
Inputthat restrictstypeto HTML's native temporal input types (date[default],time,datetime-local,month,week), rendering the browser's own picker UI instead of a custom popup calendar/dropdown list. - Replaces the compat
DatePicker/TimePicker/Calendar(see below) as the supported date/time-picking component;@fluentui/react-datepicker-compat/react-timepicker-compat/react-calendar-compatare no longer barrel-exported. value/defaultValue/min/maxareDateobjects (not strings);onChangereports(event, { value: Date | null }).onValidationResult(event, { error })mirrors the compatDatePicker's callback of the same name, derived from the native input'sValidityState.clearableadds an "x" button: clears to empty if nodefaultValue, otherwise resets todefaultValue.
Avatar
Files: src/components/Avatar.tsx, src/index.ts
- Adds CoreAI-only
color="neutral-alt"option. - Applies the background override to the
fui-Avatar__initials/fui-Avatar__iconslot:color="neutral"usescolorNeutralBackground4,color="neutral-alt"usescolorNeutralBackground1. neutral-altmaps internally to Fluentneutral; defaultscolortoneutral.
TabList
Files: src/components/TabList.tsx
- Adds CoreAI-only
appearance="elevated"option. - Maps internally to Fluent
filled-circularplus elevated container styling. - Tabs rendered with an anchor root suppress the native link underline.
MessageBar
Files: src/components/MessageBar.tsx, src/index.ts
- Adds CoreAI-only
intent="brand"option styled with the brand token ramp:colorBrandBackground2surface,colorBrandStroke2border, andcolorBrandForeground1icon. brandmaps internally to Fluentinfo(preserving the default icon and polite aria-live announcement) with the brand styling layered on viaclassName.- Other intents (
info,warning,error,success) behave identically to Fluent.
Divider
Files: src/components/Divider.tsx, src/index.ts
Dividerexport is replaced with a simplified styled<hr>implementation.- New implementation removes the
childrenandalignContentprops. It has no content or label - It's just a line. - Stock Fluent divider remains available as
DividerLabeled.
Nav family (deprecated primitives)
Files: src/components/Nav.deprecated.ts, src/index.ts
- Fluent's low-level
Navprimitives are re-exported under their original names and flagged@deprecated; the CoreAINavtemplate is the supported navigation surface. - Deprecated components:
Nav,NavCategory,NavCategoryItem,NavDivider,NavDrawer,NavDrawerBody,NavDrawerFooter,NavDrawerHeader,NavItem,NavSectionHeader,NavSubItem,NavSubItemGroup,AppItem,AppItemStatic,Hamburger,SplitNavItem. - Related Nav types remain available under their original names (
NavProps,NavItemValue,NavDensity,OnNavItemSelectData, and exported context-value types) and are not marked deprecated. - These names are also explicitly root-exported from
src/index.tsso deprecation metadata is preserved at the package surface.
Link
Files: src/components/Link.tsx, src/index.ts
- Adds an
externalprop. Whentrue, renders an inline open-in-new icon (bundleIcon(OpenFilled, OpenRegular)) immediately after the link text, defaultstargetto_blankandreltonoopener noreferrer, and allows either default to be overridden explicitly. The icon fills on:hover/:focus-visibleand is decorative (aria-hidden). - Without
external(default), behaves identically to Fluent'sLink.
Text
Files: src/components/Text.tsx, src/index.ts
- Adds a
foregroundprop (1 | 2 | 3 | 4 | 'disabled') mapping to thecolorNeutralForeground1–colorNeutralForeground4andcolorNeutralForegroundDisabledtokens;1is highest-emphasis,4is lowest. - Adds an
uppercaseboolean that appliestext-transform: uppercasewith letter-spacing tracking. - Adds a
presetprop (TextPreset:heading1–heading4,heading5/bodyStrong,body,heading6/bodySStrong,bodyS,bodyXSStrong,bodyXS) that suppliessize/weightdefaults in place of Fluent's fixed typography-ramp presets; explicitsize/weightprops still overridepreset. - Resets browser default margins to
0when rendered as semantic elements such as headings and paragraphs. - Unset color, font family, font size, line height, and font weight inherit from the CSS parent, so nested
Textchanges only the properties explicitly supplied.
Text presets (deprecated)
Files: src/components/Text.deprecated.ts, src/index.ts
- Fluent's fixed typography-ramp
Textpresets are re-exported as-is and flagged@deprecated; the CoreAITextcomponent'ssize/weightprops (or the newpresetprop above) are the supported alternative. - Deprecated components:
Body1,Body1Strong,Body1Stronger,Body2,Caption1,Caption1Strong,Caption1Stronger,Caption2,Caption2Strong,Display,LargeTitle,Subtitle1,Subtitle2,Subtitle2Stronger,Title1,Title2,Title3. - The shared
TextPresetPropstype is re-exported but NOT deprecated.
InfoButton
Files: src/components/InfoButton.tsx, src/index.ts
- Adds wrapped
InfoButtonto the barrel. - Requires accessible name via
aria-labeloraria-labelledby. - When
infois primitive text/number, mirrors that content into the popover surfacearia-labelfor better screen-reader announcement.
Accordion
Files: src/components/Accordion.styles.ts, src/contexts/styleHooks.ts
- Style-hook override for header button layout and interaction styling (grid layouts for icon/expand-icon arrangements, a vertically centered non-stretching expand icon, and hover/pressed visuals).
AccordionHeaderbutton padding andAccordionPanelmargin are reset to0so accordion content aligns with surrounding content.
Tag family (Tag, InteractionTagPrimary, InteractionTagSecondary)
Files: src/components/Tag.styles.ts, src/styleHooks.ts
- Style-hook override trims
primaryTextbottom padding to0. InteractionTagSecondarygets border/spacing adjustments (except outline appearance).
Overlay family (Dialog, Popover, Tooltip, Menu)
Files: src/components/Overlay.styles.ts, src/components/Dialog.styles.ts, src/styleHooks.ts
- Shared overlay border/beak styling across floating surfaces.
- Dialog-specific spacing/body/content slot styling layered on top.
Table/DataGrid family
Files: src/components/Table.styles.ts, src/components/DataGrid.tsx, src/components/DataGridHeaderCell.tsx, src/components/DataGridCell.tsx, src/styleHooks.ts
- Slot-level style-hook overrides for border model, header/body separators, row/cell styling, selection-cell behavior, and DataGrid parity.
DataGriddefaultsselectionAppearanceto"neutral"instead of Fluent's"brand"; passselectionAppearance="brand"to opt into the Fluent default.DataGridis a non-stock wrapper adding an opt-incolumnFlexOptionsfeature: CSS-only per-column flexbox/truncation overrides, keyed bycolumnId, applied automatically by the accompanyingDataGridHeaderCell/DataGridCellwrappers.
Non-stock components: CopyButton, CodeBlock, Markdown
Files: src/components/CopyButton.tsx, src/components/CodeBlock.tsx, src/components/Markdown.tsx
CopyButton: copy action preset with copied-state icon/tooltip feedback.CodeBlock: syntax highlighting + copy button + theme-mode-aware VS palettes; supports fixed-height scrolling, arbitrary header and footer content withdividedandsubtleappearances, header/footer class overrides, andfallbackContentfor loading or empty states whencodeis empty or omitted.Markdown: Markdown + GFM + math rendering with Fluent-themed output andCodeBlockintegration; external links use CoreAILinkand open in a new tab by default.
Storybook/runtime integration
Files: apps/storybook/.storybook/main.ts, apps/storybook/scripts/patch-fluent-stories.mjs
- Canonical Fluent story imports are rewritten to
@coreai-ds/react-components, so stories render with CoreAI wrappers by default. - Selected canonical story re-exports are patched out to prevent duplicate story IDs where CoreAI forks exist.
What remains stock Fluent
- Any export not explicitly shadowed/added in
src/index.tsstays stock Fluent. withComponentDefaults={false}disables wrapped default-prop behavior globally.