@bug-on/m3-expressive 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.css CHANGED
@@ -1,8 +1,13 @@
1
1
  /* @bug-on/m3-tokens — MD3 System Color Tokens */
2
- /* MD3 System Color Tokens — Light Theme (Baseline Scheme)
2
+ /* MD3 Expressive System Color Tokens — Light Theme (Baseline Scheme)
3
3
  *
4
+ * Spec: Material 3 Expressive 2025 (SpecVersion '2025')
4
5
  * Mapping: PaletteTokens → ColorLightTokens → CSS variable
5
6
  * Reference: ColorLightTokens.kt, ColorDarkTokens.kt, PaletteTokens.kt
7
+ *
8
+ * Static fallback for SSR / no-JS environments.
9
+ * At runtime, MD3ThemeProvider overrides all --md-sys-color-* via
10
+ * element.style.setProperty() using the dynamic color engine (theme-utils.ts).
6
11
  */
7
12
  :root {
8
13
  /* ── Primary ─────────────────────────────────────────────────────────── */
package/dist/index.d.mts CHANGED
@@ -1,9 +1,10 @@
1
- export { Icon, IconProps, MD3ColorScheme, MD3ThemeProvider, MD3ThemeProviderProps, MaterialSymbolsPreconnect, Ripple, RippleOrigin, RippleProps, ThemeMode, UseRippleStateOptions, applyTheme, cn, generateM3Theme, resolveMode, useDOMRipple, useMediaQuery, useRipple, useRippleState, useTheme, useThemeMode } from './core.mjs';
1
+ import { S as SchemeVariant, C as ContrastLevel, M as MD3ColorScheme } from './core-D4048_K5.mjs';
2
+ export { G as GenerateM3ThemeOptions, I as Icon, a as IconProps, b as MD3ThemeProvider, c as MD3ThemeProviderProps, d as MaterialSymbolsPreconnect, R as Ripple, e as RippleOrigin, f as RippleProps, T as ThemeMode, U as UseRippleStateOptions, g as applyTheme, h as cn, i as generateM3Theme, r as resolveMode, u as useDOMRipple, j as useMediaQuery, k as useRipple, l as useRippleState, m as useTheme, n as useThemeMode } from './core-D4048_K5.mjs';
2
3
  export { ANGLE_EPSILON, CornerFeature, CornerRounding, Cubic, CubicPair, DISTANCE_EPSILON, DoubleMapper, EdgeFeature, FLOAT_PI, Feature, MD3CornerRadius, MD3CornerRadiusToken, MD3ShapeName, MD3Shapes, MeasuredCubic, MeasuredFeature, MeasuredPolygon, Morph, MorphTrigger, MutableCubic, Point, PointTransformer, RoundedPolygon, ShapeIcon, ShapeIconProps, ShapeMedia, ShapeMediaProps, ShapeMediaServer, ShapeMorphOptions, ShapeRef, ShapeSvg, ShapeSvgProps, UNROUNDED, UseShapeMorphResult, addPoints, circle, clockwise, convex, cornerFeature, cornerRounding, createDoubleMapper, directionVector, distance, distanceSquared, dividePoint, dotProduct, edgeFeature, featureMapper, getDirection, getDistance, getDistanceSquared, interpolate, interpolatePath, lerpPoint, pill, pillStar, point, positiveModulo, radialToCartesian, rectangle, rotate90, scalePoint, square, star, subtractPoints, toClipPath, toSvgPath, transformFeature, transformPoint, useShapeMorph } from './shapes.mjs';
3
- export { M as MD3ColorStyle, a as MD3Shape, b as MD3Size, P as PolymorphicProps, c as PolymorphicRef } from './md3-DFhj-NZj.mjs';
4
+ export { M as MD3ColorStyle, a as MD3Shape, b as MD3Size, P as PolymorphicProps, c as PolymorphicRef } from './md3-Dty-Qcad.mjs';
4
5
  export { APP_BAR_BOTTOM_SPRING, APP_BAR_COLORS, APP_BAR_COLOR_TRANSITION, APP_BAR_ENTER_ALWAYS_SPRING, APP_BAR_TITLE_FADE, AppBarColors, AppBarColumn, AppBarColumnProps, AppBarItem, AppBarItemType, AppBarMenuState, AppBarOverflowIndicator, AppBarOverflowIndicatorProps, AppBarRow, AppBarRowProps, AppBarScrollBehavior, AppBarTokens, BaseAppBarProps, BottomAppBar, BottomAppBarProps, BottomDockedToolbar, BottomDockedToolbarProps, CHECK_ICON_VARIANTS, ContextMenu, ContextMenuContent, ContextMenuContentProps, ContextMenuProps, ContextMenuTrigger, ContextMenuTriggerProps, DIVIDER_COLOR, DIVIDER_PADDING, DockedToolbar, DockedToolbarProps, FAST_EFFECTS_TRANSITION, FAST_SPATIAL_SPRING, FlexibleAppBarProps, FloatingToolbarColors, FloatingToolbarProps, FloatingToolbarScrollBehavior, FloatingToolbarWithFabProps, GROUP_SHAPES, HorizontalFloatingToolbar, HorizontalFloatingToolbarWithFab, ITEM_SHAPE_CLASSES, LargeFlexibleAppBar, MENU_CHECK_ICON_SIZE, MENU_CONTAINER_VARIANTS, MENU_GROUP_GAP, MENU_ICON_SIZE, MENU_ITEM_MIN_HEIGHT, MENU_MAX_WIDTH, MENU_MIN_WIDTH, MediumFlexibleAppBar, Menu, MenuColorVariant, MenuContent, MenuContentProps, MenuDivider, MenuDividerProps, MenuGroup, MenuGroupPosition, MenuGroupProps, MenuItem, MenuItemPosition, MenuItemProps, MenuPrimitive, MenuProps, MenuProvider, MenuTrigger, MenuTriggerProps, MenuVariant, NavigationBar, NavigationBarItem, NavigationBarItemLayout, NavigationBarItemProps, NavigationBarProps, NavigationBarVariant, NavigationRail, NavigationRailItem, NavigationRailItemProps, NavigationRailLabelVisibility, NavigationRailProps, NavigationRailVariant, SEARCH_BAR_EXPAND_SPRING, SEARCH_COLORS, SEARCH_DOCKED_REVEAL_SPRING, SEARCH_FULLSCREEN_SPRING, SEARCH_TYPOGRAPHY, SEARCH_VIEW_SPRING, STANDARD_COLORS, SUBMENU_CONTAINER_VARIANTS, Search, SearchAppBar, SearchAppBarProps, SearchBar, SearchBarVariant, SearchProps, SearchStyleType, SearchTokens, SearchVariant, SearchView, SearchViewContainer, SearchViewDocked, SearchViewFullScreen, SearchViewProps, SmallAppBar, SmallAppBarProps, SubMenu, SubMenuProps, Tab, TabProps, Tabs, TabsColors, TabsContent, TabsContentProps, TabsList, TabsListProps, TabsProps, TabsTokens, TabsVariant, TitleAlignment, ToolbarDivider, ToolbarDividerProps, ToolbarDividerTokens, ToolbarIconButton, ToolbarIconButtonProps, ToolbarIconButtonSize, ToolbarIconButtonTokens, ToolbarIconButtonVariant, UseAppBarScrollReturn, UseFloatingToolbarScrollBehaviorOptions, VIBRANT_COLORS, VerticalFloatingToolbar, VerticalFloatingToolbarWithFab, VerticalMenu, VerticalMenuContent, VerticalMenuContentProps, VerticalMenuDivider, VerticalMenuDividerProps, VerticalMenuGroup, VerticalMenuGroupProps, VerticalMenuProps, VerticalMenuSeparatorStyle, appBarTypography, standardFloatingToolbarColors, useAppBarScroll, useFloatingToolbarScrollBehavior, useMenuContext, useSearchKeyboard, vibrantFloatingToolbarColors } from './navigation.mjs';
5
6
  export { Badge, BadgeProps, BadgedBox, BadgedBoxProps, CaretConfig, CircularProgressProps, LinearProgressProps, LoadingIndicator, LoadingIndicatorProps, PlainTooltip, PlainTooltipProps, ProgressIndicator, ProgressIndicatorProps, RichTooltip, RichTooltipProps, Snackbar, SnackbarData, SnackbarDuration, SnackbarHost, SnackbarHostProps, SnackbarProps, SnackbarProvider, SnackbarResult, SnackbarVisuals, TooltipBox, TooltipBoxProps, TooltipCaretShape, TooltipPlacement, TooltipState, TooltipStateConfig, TooltipTokens, TooltipTrigger, UseSnackbarStateReturn, useSnackbar, useSnackbarState, useTooltipPosition, useTooltipState } from './feedback.mjs';
6
- export { B as BUTTON_COLOR_TOKENS, a as BUTTON_SIZE_TOKENS, b as BaseButtonProps, c as Button, d as ButtonGroup, e as ButtonGroupOrientation, f as ButtonGroupProps, g as ButtonGroupVariant, h as ButtonProps, E as ElevatedSplitButtonLeading, i as ElevatedSplitButtonTrailing, j as ElevatedSplitButtonTrailingUncheckable, k as ExtendedFAB, l as ExtendedFABProps, F as FAB, m as FABMenu, n as FABMenuItem, o as FABMenuItemData, p as FABMenuItemProps, q as FABMenuProps, r as FABPosition, s as FABPositionProps, t as FABProps, u as FilledSplitButtonLeading, v as FilledSplitButtonTrailing, w as FilledSplitButtonTrailingUncheckable, O as OutlinedSplitButtonLeading, x as OutlinedSplitButtonTrailing, y as OutlinedSplitButtonTrailingUncheckable, S as SplitButtonLayout, z as SplitButtonLayoutProps, A as SplitButtonLeading, C as SplitButtonLeadingProps, D as SplitButtonSize, G as SplitButtonTrailing, H as SplitButtonTrailingProps, I as SplitButtonTrailingUncheckable, J as SplitButtonTrailingUncheckableProps, K as SplitButtonVariant, T as ToggleFAB, L as ToggleFABProps, M as TonalSplitButtonLeading, N as TonalSplitButtonTrailing, P as TonalSplitButtonTrailingUncheckable } from './split-button-trailing-uncheckable-BRPuTqi1.mjs';
7
+ export { B as BUTTON_COLOR_TOKENS, a as BUTTON_SIZE_TOKENS, b as BaseButtonProps, c as Button, d as ButtonGroup, e as ButtonGroupOrientation, f as ButtonGroupProps, g as ButtonGroupVariant, h as ButtonProps, E as ElevatedSplitButtonLeading, i as ElevatedSplitButtonTrailing, j as ElevatedSplitButtonTrailingUncheckable, k as ExtendedFAB, l as ExtendedFABProps, F as FAB, m as FABMenu, n as FABMenuItem, o as FABMenuItemData, p as FABMenuItemProps, q as FABMenuProps, r as FABPosition, s as FABPositionProps, t as FABProps, u as FilledSplitButtonLeading, v as FilledSplitButtonTrailing, w as FilledSplitButtonTrailingUncheckable, O as OutlinedSplitButtonLeading, x as OutlinedSplitButtonTrailing, y as OutlinedSplitButtonTrailingUncheckable, S as SplitButtonLayout, z as SplitButtonLayoutProps, A as SplitButtonLeading, C as SplitButtonLeadingProps, D as SplitButtonSize, G as SplitButtonTrailing, H as SplitButtonTrailingProps, I as SplitButtonTrailingUncheckable, J as SplitButtonTrailingUncheckableProps, K as SplitButtonVariant, T as ToggleFAB, L as ToggleFABProps, M as TonalSplitButtonLeading, N as TonalSplitButtonTrailing, P as TonalSplitButtonTrailingUncheckable } from './split-button-trailing-uncheckable-D_PLPb-u.mjs';
7
8
  export { B as BaseIconButtonProps, I as IconButton, a as IconButtonProps } from './icon-button-D-gs0gfj.mjs';
8
9
  export { Card, CardProps, CodeBlock, CodeBlockProps, Divider, DividerProps, LIST_TOKENS, List, ListContext, ListDivider, ListDividerProps, ListItem, ListItemLeadingType, ListItemProps, ListItemTrailingType, ListProps, ListSelectionMode, ListStyle, ListVariant, TableOfContents, TableOfContentsProps, Text, TextProps, ToCItem, TypeScaleTokens, TypeScaleTokensType, buildWavePath, getExpressiveShape, getListItemHeight, shouldTopAlign, useListContext } from './layout.mjs';
9
10
  export { C as Checkbox, a as CheckboxProps, b as CheckboxState, c as Chip, d as ChipProps, R as RadioButton, e as RadioButtonColors, f as RadioButtonProps, g as RadioGroup, h as RadioGroupProps, i as RangeSlider, j as RangeSliderProps, S as Slider, k as SliderColors, l as SliderOrientation, m as SliderProps, n as SliderTokens, o as SliderTrackSize, p as SliderVariant, q as Switch, r as SwitchColors, s as SwitchProps, t as SwitchTokens, T as TextField, u as TextFieldHandle, v as TextFieldInputType, w as TextFieldProps, x as TextFieldTrailingIconMode, y as TextFieldVariant, z as TriStateCheckbox, A as TriStateCheckboxProps } from './text-field-eAIpz9z1.mjs';
@@ -22,3 +23,64 @@ import 'class-variance-authority/types';
22
23
  import 'class-variance-authority';
23
24
  import '@radix-ui/react-dialog';
24
25
  import '@radix-ui/react-scroll-area';
26
+
27
+ interface CreateMd3ThemeOptions {
28
+ /** Seed color in hex format, e.g. `"#6750A4"`. */
29
+ seedColor: string;
30
+ /** Whether to generate a dark scheme. Defaults to `false`. */
31
+ isDark?: boolean;
32
+ /**
33
+ * Color scheme variant. Defaults to `"expressive"` (MD3 Expressive 2025).
34
+ * @see SchemeVariant
35
+ */
36
+ variant?: SchemeVariant;
37
+ /**
38
+ * Contrast adjustment. Defaults to `0` (standard).
39
+ * - `0` — Standard
40
+ * - `0.5` — Medium contrast
41
+ * - `1` — Maximum contrast (WCAG AAA)
42
+ */
43
+ contrastLevel?: ContrastLevel;
44
+ }
45
+ interface Md3ThemeResult {
46
+ /**
47
+ * Flat map of CSS custom properties that can be injected into a style block.
48
+ * Keys use `--md-sys-color-*` naming.
49
+ *
50
+ * @example
51
+ * Object.entries(cssVariables).forEach(([k, v]) => {
52
+ * document.documentElement.style.setProperty(k, v);
53
+ * });
54
+ */
55
+ cssVariables: Record<string, string>;
56
+ /** Fully-typed color scheme object with camelCase role names. */
57
+ colorScheme: MD3ColorScheme;
58
+ }
59
+ /**
60
+ * High-level one-call API to generate a Material 3 Expressive theme.
61
+ *
62
+ * Returns both a CSS variable map (for injection into the DOM or SSR style tags)
63
+ * and a typed `MD3ColorScheme` object for use in TypeScript.
64
+ *
65
+ * Uses **SpecVersion 2025** and **Variant.EXPRESSIVE** by default, aligning with
66
+ * the MD3 Expressive 2025 color specification.
67
+ *
68
+ * @example
69
+ * const { cssVariables } = createMd3ExpressiveTheme({ seedColor: "#6750A4" });
70
+ * // Inject at runtime:
71
+ * for (const [k, v] of Object.entries(cssVariables)) {
72
+ * document.documentElement.style.setProperty(k, v);
73
+ * }
74
+ *
75
+ * @example
76
+ * // High-contrast dark scheme with tonal_spot variant
77
+ * const theme = createMd3ExpressiveTheme({
78
+ * seedColor: "#00639B",
79
+ * isDark: true,
80
+ * variant: "tonal_spot",
81
+ * contrastLevel: 1,
82
+ * });
83
+ */
84
+ declare function createMd3ExpressiveTheme(options: CreateMd3ThemeOptions): Md3ThemeResult;
85
+
86
+ export { ContrastLevel, type CreateMd3ThemeOptions, MD3ColorScheme, type Md3ThemeResult, SchemeVariant, createMd3ExpressiveTheme };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- export { Icon, IconProps, MD3ColorScheme, MD3ThemeProvider, MD3ThemeProviderProps, MaterialSymbolsPreconnect, Ripple, RippleOrigin, RippleProps, ThemeMode, UseRippleStateOptions, applyTheme, cn, generateM3Theme, resolveMode, useDOMRipple, useMediaQuery, useRipple, useRippleState, useTheme, useThemeMode } from './core.js';
1
+ import { S as SchemeVariant, C as ContrastLevel, M as MD3ColorScheme } from './core-Bc5Wj_pc.js';
2
+ export { G as GenerateM3ThemeOptions, I as Icon, a as IconProps, b as MD3ThemeProvider, c as MD3ThemeProviderProps, d as MaterialSymbolsPreconnect, R as Ripple, e as RippleOrigin, f as RippleProps, T as ThemeMode, U as UseRippleStateOptions, g as applyTheme, h as cn, i as generateM3Theme, r as resolveMode, u as useDOMRipple, j as useMediaQuery, k as useRipple, l as useRippleState, m as useTheme, n as useThemeMode } from './core-Bc5Wj_pc.js';
2
3
  export { ANGLE_EPSILON, CornerFeature, CornerRounding, Cubic, CubicPair, DISTANCE_EPSILON, DoubleMapper, EdgeFeature, FLOAT_PI, Feature, MD3CornerRadius, MD3CornerRadiusToken, MD3ShapeName, MD3Shapes, MeasuredCubic, MeasuredFeature, MeasuredPolygon, Morph, MorphTrigger, MutableCubic, Point, PointTransformer, RoundedPolygon, ShapeIcon, ShapeIconProps, ShapeMedia, ShapeMediaProps, ShapeMediaServer, ShapeMorphOptions, ShapeRef, ShapeSvg, ShapeSvgProps, UNROUNDED, UseShapeMorphResult, addPoints, circle, clockwise, convex, cornerFeature, cornerRounding, createDoubleMapper, directionVector, distance, distanceSquared, dividePoint, dotProduct, edgeFeature, featureMapper, getDirection, getDistance, getDistanceSquared, interpolate, interpolatePath, lerpPoint, pill, pillStar, point, positiveModulo, radialToCartesian, rectangle, rotate90, scalePoint, square, star, subtractPoints, toClipPath, toSvgPath, transformFeature, transformPoint, useShapeMorph } from './shapes.js';
3
- export { M as MD3ColorStyle, a as MD3Shape, b as MD3Size, P as PolymorphicProps, c as PolymorphicRef } from './md3-DFhj-NZj.js';
4
+ export { M as MD3ColorStyle, a as MD3Shape, b as MD3Size, P as PolymorphicProps, c as PolymorphicRef } from './md3-Dty-Qcad.js';
4
5
  export { APP_BAR_BOTTOM_SPRING, APP_BAR_COLORS, APP_BAR_COLOR_TRANSITION, APP_BAR_ENTER_ALWAYS_SPRING, APP_BAR_TITLE_FADE, AppBarColors, AppBarColumn, AppBarColumnProps, AppBarItem, AppBarItemType, AppBarMenuState, AppBarOverflowIndicator, AppBarOverflowIndicatorProps, AppBarRow, AppBarRowProps, AppBarScrollBehavior, AppBarTokens, BaseAppBarProps, BottomAppBar, BottomAppBarProps, BottomDockedToolbar, BottomDockedToolbarProps, CHECK_ICON_VARIANTS, ContextMenu, ContextMenuContent, ContextMenuContentProps, ContextMenuProps, ContextMenuTrigger, ContextMenuTriggerProps, DIVIDER_COLOR, DIVIDER_PADDING, DockedToolbar, DockedToolbarProps, FAST_EFFECTS_TRANSITION, FAST_SPATIAL_SPRING, FlexibleAppBarProps, FloatingToolbarColors, FloatingToolbarProps, FloatingToolbarScrollBehavior, FloatingToolbarWithFabProps, GROUP_SHAPES, HorizontalFloatingToolbar, HorizontalFloatingToolbarWithFab, ITEM_SHAPE_CLASSES, LargeFlexibleAppBar, MENU_CHECK_ICON_SIZE, MENU_CONTAINER_VARIANTS, MENU_GROUP_GAP, MENU_ICON_SIZE, MENU_ITEM_MIN_HEIGHT, MENU_MAX_WIDTH, MENU_MIN_WIDTH, MediumFlexibleAppBar, Menu, MenuColorVariant, MenuContent, MenuContentProps, MenuDivider, MenuDividerProps, MenuGroup, MenuGroupPosition, MenuGroupProps, MenuItem, MenuItemPosition, MenuItemProps, MenuPrimitive, MenuProps, MenuProvider, MenuTrigger, MenuTriggerProps, MenuVariant, NavigationBar, NavigationBarItem, NavigationBarItemLayout, NavigationBarItemProps, NavigationBarProps, NavigationBarVariant, NavigationRail, NavigationRailItem, NavigationRailItemProps, NavigationRailLabelVisibility, NavigationRailProps, NavigationRailVariant, SEARCH_BAR_EXPAND_SPRING, SEARCH_COLORS, SEARCH_DOCKED_REVEAL_SPRING, SEARCH_FULLSCREEN_SPRING, SEARCH_TYPOGRAPHY, SEARCH_VIEW_SPRING, STANDARD_COLORS, SUBMENU_CONTAINER_VARIANTS, Search, SearchAppBar, SearchAppBarProps, SearchBar, SearchBarVariant, SearchProps, SearchStyleType, SearchTokens, SearchVariant, SearchView, SearchViewContainer, SearchViewDocked, SearchViewFullScreen, SearchViewProps, SmallAppBar, SmallAppBarProps, SubMenu, SubMenuProps, Tab, TabProps, Tabs, TabsColors, TabsContent, TabsContentProps, TabsList, TabsListProps, TabsProps, TabsTokens, TabsVariant, TitleAlignment, ToolbarDivider, ToolbarDividerProps, ToolbarDividerTokens, ToolbarIconButton, ToolbarIconButtonProps, ToolbarIconButtonSize, ToolbarIconButtonTokens, ToolbarIconButtonVariant, UseAppBarScrollReturn, UseFloatingToolbarScrollBehaviorOptions, VIBRANT_COLORS, VerticalFloatingToolbar, VerticalFloatingToolbarWithFab, VerticalMenu, VerticalMenuContent, VerticalMenuContentProps, VerticalMenuDivider, VerticalMenuDividerProps, VerticalMenuGroup, VerticalMenuGroupProps, VerticalMenuProps, VerticalMenuSeparatorStyle, appBarTypography, standardFloatingToolbarColors, useAppBarScroll, useFloatingToolbarScrollBehavior, useMenuContext, useSearchKeyboard, vibrantFloatingToolbarColors } from './navigation.js';
5
6
  export { Badge, BadgeProps, BadgedBox, BadgedBoxProps, CaretConfig, CircularProgressProps, LinearProgressProps, LoadingIndicator, LoadingIndicatorProps, PlainTooltip, PlainTooltipProps, ProgressIndicator, ProgressIndicatorProps, RichTooltip, RichTooltipProps, Snackbar, SnackbarData, SnackbarDuration, SnackbarHost, SnackbarHostProps, SnackbarProps, SnackbarProvider, SnackbarResult, SnackbarVisuals, TooltipBox, TooltipBoxProps, TooltipCaretShape, TooltipPlacement, TooltipState, TooltipStateConfig, TooltipTokens, TooltipTrigger, UseSnackbarStateReturn, useSnackbar, useSnackbarState, useTooltipPosition, useTooltipState } from './feedback.js';
6
- export { B as BUTTON_COLOR_TOKENS, a as BUTTON_SIZE_TOKENS, b as BaseButtonProps, c as Button, d as ButtonGroup, e as ButtonGroupOrientation, f as ButtonGroupProps, g as ButtonGroupVariant, h as ButtonProps, E as ElevatedSplitButtonLeading, i as ElevatedSplitButtonTrailing, j as ElevatedSplitButtonTrailingUncheckable, k as ExtendedFAB, l as ExtendedFABProps, F as FAB, m as FABMenu, n as FABMenuItem, o as FABMenuItemData, p as FABMenuItemProps, q as FABMenuProps, r as FABPosition, s as FABPositionProps, t as FABProps, u as FilledSplitButtonLeading, v as FilledSplitButtonTrailing, w as FilledSplitButtonTrailingUncheckable, O as OutlinedSplitButtonLeading, x as OutlinedSplitButtonTrailing, y as OutlinedSplitButtonTrailingUncheckable, S as SplitButtonLayout, z as SplitButtonLayoutProps, A as SplitButtonLeading, C as SplitButtonLeadingProps, D as SplitButtonSize, G as SplitButtonTrailing, H as SplitButtonTrailingProps, I as SplitButtonTrailingUncheckable, J as SplitButtonTrailingUncheckableProps, K as SplitButtonVariant, T as ToggleFAB, L as ToggleFABProps, M as TonalSplitButtonLeading, N as TonalSplitButtonTrailing, P as TonalSplitButtonTrailingUncheckable } from './split-button-trailing-uncheckable-CjOFCoyW.js';
7
+ export { B as BUTTON_COLOR_TOKENS, a as BUTTON_SIZE_TOKENS, b as BaseButtonProps, c as Button, d as ButtonGroup, e as ButtonGroupOrientation, f as ButtonGroupProps, g as ButtonGroupVariant, h as ButtonProps, E as ElevatedSplitButtonLeading, i as ElevatedSplitButtonTrailing, j as ElevatedSplitButtonTrailingUncheckable, k as ExtendedFAB, l as ExtendedFABProps, F as FAB, m as FABMenu, n as FABMenuItem, o as FABMenuItemData, p as FABMenuItemProps, q as FABMenuProps, r as FABPosition, s as FABPositionProps, t as FABProps, u as FilledSplitButtonLeading, v as FilledSplitButtonTrailing, w as FilledSplitButtonTrailingUncheckable, O as OutlinedSplitButtonLeading, x as OutlinedSplitButtonTrailing, y as OutlinedSplitButtonTrailingUncheckable, S as SplitButtonLayout, z as SplitButtonLayoutProps, A as SplitButtonLeading, C as SplitButtonLeadingProps, D as SplitButtonSize, G as SplitButtonTrailing, H as SplitButtonTrailingProps, I as SplitButtonTrailingUncheckable, J as SplitButtonTrailingUncheckableProps, K as SplitButtonVariant, T as ToggleFAB, L as ToggleFABProps, M as TonalSplitButtonLeading, N as TonalSplitButtonTrailing, P as TonalSplitButtonTrailingUncheckable } from './split-button-trailing-uncheckable-BkPbiBo3.js';
7
8
  export { B as BaseIconButtonProps, I as IconButton, a as IconButtonProps } from './icon-button-D-gs0gfj.js';
8
9
  export { Card, CardProps, CodeBlock, CodeBlockProps, Divider, DividerProps, LIST_TOKENS, List, ListContext, ListDivider, ListDividerProps, ListItem, ListItemLeadingType, ListItemProps, ListItemTrailingType, ListProps, ListSelectionMode, ListStyle, ListVariant, TableOfContents, TableOfContentsProps, Text, TextProps, ToCItem, TypeScaleTokens, TypeScaleTokensType, buildWavePath, getExpressiveShape, getListItemHeight, shouldTopAlign, useListContext } from './layout.js';
9
10
  export { C as Checkbox, a as CheckboxProps, b as CheckboxState, c as Chip, d as ChipProps, R as RadioButton, e as RadioButtonColors, f as RadioButtonProps, g as RadioGroup, h as RadioGroupProps, i as RangeSlider, j as RangeSliderProps, S as Slider, k as SliderColors, l as SliderOrientation, m as SliderProps, n as SliderTokens, o as SliderTrackSize, p as SliderVariant, q as Switch, r as SwitchColors, s as SwitchProps, t as SwitchTokens, T as TextField, u as TextFieldHandle, v as TextFieldInputType, w as TextFieldProps, x as TextFieldTrailingIconMode, y as TextFieldVariant, z as TriStateCheckbox, A as TriStateCheckboxProps } from './text-field-eAIpz9z1.js';
@@ -22,3 +23,64 @@ import 'class-variance-authority/types';
22
23
  import 'class-variance-authority';
23
24
  import '@radix-ui/react-dialog';
24
25
  import '@radix-ui/react-scroll-area';
26
+
27
+ interface CreateMd3ThemeOptions {
28
+ /** Seed color in hex format, e.g. `"#6750A4"`. */
29
+ seedColor: string;
30
+ /** Whether to generate a dark scheme. Defaults to `false`. */
31
+ isDark?: boolean;
32
+ /**
33
+ * Color scheme variant. Defaults to `"expressive"` (MD3 Expressive 2025).
34
+ * @see SchemeVariant
35
+ */
36
+ variant?: SchemeVariant;
37
+ /**
38
+ * Contrast adjustment. Defaults to `0` (standard).
39
+ * - `0` — Standard
40
+ * - `0.5` — Medium contrast
41
+ * - `1` — Maximum contrast (WCAG AAA)
42
+ */
43
+ contrastLevel?: ContrastLevel;
44
+ }
45
+ interface Md3ThemeResult {
46
+ /**
47
+ * Flat map of CSS custom properties that can be injected into a style block.
48
+ * Keys use `--md-sys-color-*` naming.
49
+ *
50
+ * @example
51
+ * Object.entries(cssVariables).forEach(([k, v]) => {
52
+ * document.documentElement.style.setProperty(k, v);
53
+ * });
54
+ */
55
+ cssVariables: Record<string, string>;
56
+ /** Fully-typed color scheme object with camelCase role names. */
57
+ colorScheme: MD3ColorScheme;
58
+ }
59
+ /**
60
+ * High-level one-call API to generate a Material 3 Expressive theme.
61
+ *
62
+ * Returns both a CSS variable map (for injection into the DOM or SSR style tags)
63
+ * and a typed `MD3ColorScheme` object for use in TypeScript.
64
+ *
65
+ * Uses **SpecVersion 2025** and **Variant.EXPRESSIVE** by default, aligning with
66
+ * the MD3 Expressive 2025 color specification.
67
+ *
68
+ * @example
69
+ * const { cssVariables } = createMd3ExpressiveTheme({ seedColor: "#6750A4" });
70
+ * // Inject at runtime:
71
+ * for (const [k, v] of Object.entries(cssVariables)) {
72
+ * document.documentElement.style.setProperty(k, v);
73
+ * }
74
+ *
75
+ * @example
76
+ * // High-contrast dark scheme with tonal_spot variant
77
+ * const theme = createMd3ExpressiveTheme({
78
+ * seedColor: "#00639B",
79
+ * isDark: true,
80
+ * variant: "tonal_spot",
81
+ * contrastLevel: 1,
82
+ * });
83
+ */
84
+ declare function createMd3ExpressiveTheme(options: CreateMd3ThemeOptions): Md3ThemeResult;
85
+
86
+ export { ContrastLevel, type CreateMd3ThemeOptions, MD3ColorScheme, type Md3ThemeResult, SchemeVariant, createMd3ExpressiveTheme };
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
  'use strict';
3
3
 
4
4
  var React59 = require('react');
5
- var jsxRuntime = require('react/jsx-runtime');
6
5
  var materialColorUtilities = require('@material/material-color-utilities');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
7
  var clsx = require('clsx');
8
8
  var tailwindMerge = require('tailwind-merge');
9
9
  var RxContextMenu = require('@radix-ui/react-context-menu');
@@ -143,6 +143,143 @@ function useRipple(options = {}) {
143
143
  );
144
144
  return { rippleRef: ref, onPointerDown };
145
145
  }
146
+ function resolveMode(mode) {
147
+ if (mode !== "system") return mode;
148
+ if (typeof window === "undefined") return "light";
149
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
150
+ }
151
+ function createDynamicScheme(sourceColorHex, isDark, variant = "expressive", contrastLevel = 0) {
152
+ const hct = materialColorUtilities.Hct.fromInt(argbFromHex(sourceColorHex));
153
+ const spec = "2025";
154
+ switch (variant) {
155
+ case "tonal_spot":
156
+ return new materialColorUtilities.SchemeTonalSpot(hct, isDark, contrastLevel, spec);
157
+ case "vibrant":
158
+ return new materialColorUtilities.SchemeVibrant(hct, isDark, contrastLevel, spec);
159
+ case "fidelity":
160
+ return new materialColorUtilities.SchemeFidelity(hct, isDark, contrastLevel, spec);
161
+ case "content":
162
+ return new materialColorUtilities.SchemeContent(hct, isDark, contrastLevel, spec);
163
+ case "monochrome":
164
+ return new materialColorUtilities.SchemeMonochrome(hct, isDark, contrastLevel, spec);
165
+ case "neutral":
166
+ return new materialColorUtilities.SchemeNeutral(hct, isDark, contrastLevel, spec);
167
+ default:
168
+ return new materialColorUtilities.SchemeExpressive(hct, isDark, contrastLevel, spec);
169
+ }
170
+ }
171
+ function argbFromHex(hex) {
172
+ const sanitized = hex.replace(/^#/, "");
173
+ const r = Number.parseInt(sanitized.substring(0, 2), 16);
174
+ const g = Number.parseInt(sanitized.substring(2, 4), 16);
175
+ const b = Number.parseInt(sanitized.substring(4, 6), 16);
176
+ return (4278190080 | r << 16 | g << 8 | b) >>> 0;
177
+ }
178
+ function generateM3Theme(sourceColorHex, mode = "light", options = {}) {
179
+ const { variant = "expressive", contrastLevel = 0 } = options;
180
+ const isDark = mode === "dark";
181
+ const scheme = createDynamicScheme(
182
+ sourceColorHex,
183
+ isDark,
184
+ variant,
185
+ contrastLevel
186
+ );
187
+ const hex = (argb) => materialColorUtilities.hexFromArgb(argb);
188
+ return {
189
+ // Primary
190
+ primary: hex(scheme.primary),
191
+ onPrimary: hex(scheme.onPrimary),
192
+ primaryContainer: hex(scheme.primaryContainer),
193
+ onPrimaryContainer: hex(scheme.onPrimaryContainer),
194
+ inversePrimary: hex(scheme.inversePrimary),
195
+ primaryFixed: hex(scheme.primaryFixed),
196
+ primaryFixedDim: hex(scheme.primaryFixedDim),
197
+ onPrimaryFixed: hex(scheme.onPrimaryFixed),
198
+ onPrimaryFixedVariant: hex(scheme.onPrimaryFixedVariant),
199
+ primaryDim: hex(scheme.primaryDim),
200
+ // Secondary
201
+ secondary: hex(scheme.secondary),
202
+ onSecondary: hex(scheme.onSecondary),
203
+ secondaryContainer: hex(scheme.secondaryContainer),
204
+ onSecondaryContainer: hex(scheme.onSecondaryContainer),
205
+ secondaryFixed: hex(scheme.secondaryFixed),
206
+ secondaryFixedDim: hex(scheme.secondaryFixedDim),
207
+ onSecondaryFixed: hex(scheme.onSecondaryFixed),
208
+ onSecondaryFixedVariant: hex(scheme.onSecondaryFixedVariant),
209
+ secondaryDim: hex(scheme.secondaryDim),
210
+ // Tertiary
211
+ tertiary: hex(scheme.tertiary),
212
+ onTertiary: hex(scheme.onTertiary),
213
+ tertiaryContainer: hex(scheme.tertiaryContainer),
214
+ onTertiaryContainer: hex(scheme.onTertiaryContainer),
215
+ tertiaryFixed: hex(scheme.tertiaryFixed),
216
+ tertiaryFixedDim: hex(scheme.tertiaryFixedDim),
217
+ onTertiaryFixed: hex(scheme.onTertiaryFixed),
218
+ onTertiaryFixedVariant: hex(scheme.onTertiaryFixedVariant),
219
+ tertiaryDim: hex(scheme.tertiaryDim),
220
+ // Error
221
+ error: hex(scheme.error),
222
+ onError: hex(scheme.onError),
223
+ errorContainer: hex(scheme.errorContainer),
224
+ onErrorContainer: hex(scheme.onErrorContainer),
225
+ // Surface
226
+ surface: hex(scheme.surface),
227
+ onSurface: hex(scheme.onSurface),
228
+ surfaceVariant: hex(scheme.surfaceVariant),
229
+ onSurfaceVariant: hex(scheme.onSurfaceVariant),
230
+ surfaceTint: hex(scheme.surfaceTint),
231
+ surfaceDim: hex(scheme.surfaceDim),
232
+ surfaceBright: hex(scheme.surfaceBright),
233
+ surfaceContainerLowest: hex(scheme.surfaceContainerLowest),
234
+ surfaceContainerLow: hex(scheme.surfaceContainerLow),
235
+ surfaceContainer: hex(scheme.surfaceContainer),
236
+ surfaceContainerHigh: hex(scheme.surfaceContainerHigh),
237
+ surfaceContainerHighest: hex(scheme.surfaceContainerHighest),
238
+ // Inverse
239
+ inverseSurface: hex(scheme.inverseSurface),
240
+ inverseOnSurface: hex(scheme.inverseOnSurface),
241
+ // Background
242
+ background: hex(scheme.background),
243
+ onBackground: hex(scheme.onBackground),
244
+ // Outline
245
+ outline: hex(scheme.outline),
246
+ outlineVariant: hex(scheme.outlineVariant),
247
+ // Utility
248
+ shadow: hex(scheme.shadow),
249
+ scrim: hex(scheme.scrim)
250
+ };
251
+ }
252
+ function applyTheme(sourceColorHex, mode = "light", root = document.documentElement, options = {}) {
253
+ const resolved = resolveMode(mode);
254
+ const colors = generateM3Theme(sourceColorHex, resolved, options);
255
+ for (const [key, value] of Object.entries(colors)) {
256
+ const kebabKey = key.replace(/[A-Z]/g, (m67) => `-${m67.toLowerCase()}`);
257
+ root.style.setProperty(`--md-sys-color-${kebabKey}`, value);
258
+ root.style.setProperty(`--color-m3-${kebabKey}`, value);
259
+ }
260
+ root.setAttribute("data-theme", resolved);
261
+ }
262
+
263
+ // src/lib/create-theme.ts
264
+ function createMd3ExpressiveTheme(options) {
265
+ const { seedColor, isDark = false, variant, contrastLevel } = options;
266
+ const themeOptions = { variant, contrastLevel };
267
+ const colorScheme = generateM3Theme(
268
+ seedColor,
269
+ isDark ? "dark" : "light",
270
+ themeOptions
271
+ );
272
+ const cssVariables = schemeToCssVariables(colorScheme);
273
+ return { cssVariables, colorScheme };
274
+ }
275
+ function schemeToCssVariables(scheme) {
276
+ const result = {};
277
+ for (const [key, value] of Object.entries(scheme)) {
278
+ const kebabKey = key.replace(/[A-Z]/g, (m67) => `-${m67.toLowerCase()}`);
279
+ result[`--md-sys-color-${kebabKey}`] = value;
280
+ }
281
+ return result;
282
+ }
146
283
  function MaterialSymbolsPreconnect({
147
284
  variants = ["outlined"]
148
285
  }) {
@@ -182,78 +319,6 @@ function MaterialSymbolsPreconnect({
182
319
  )
183
320
  ] });
184
321
  }
185
- function resolveMode(mode) {
186
- if (mode !== "system") return mode;
187
- if (typeof window === "undefined") return "light";
188
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
189
- }
190
- function generateM3Theme(sourceColorHex, mode = "light") {
191
- const sourceColor = materialColorUtilities.argbFromHex(sourceColorHex);
192
- const theme = materialColorUtilities.themeFromSourceColor(sourceColor);
193
- const scheme = mode === "light" ? theme.schemes.light : theme.schemes.dark;
194
- const palettes = theme.palettes;
195
- const tone = (palette, t) => materialColorUtilities.hexFromArgb(palette.tone(t));
196
- return {
197
- primary: materialColorUtilities.hexFromArgb(scheme.primary),
198
- onPrimary: materialColorUtilities.hexFromArgb(scheme.onPrimary),
199
- primaryContainer: materialColorUtilities.hexFromArgb(scheme.primaryContainer),
200
- onPrimaryContainer: materialColorUtilities.hexFromArgb(scheme.onPrimaryContainer),
201
- inversePrimary: materialColorUtilities.hexFromArgb(scheme.inversePrimary),
202
- primaryFixed: tone(palettes.primary, 90),
203
- primaryFixedDim: tone(palettes.primary, 80),
204
- onPrimaryFixed: tone(palettes.primary, 10),
205
- onPrimaryFixedVariant: tone(palettes.primary, 30),
206
- secondary: materialColorUtilities.hexFromArgb(scheme.secondary),
207
- onSecondary: materialColorUtilities.hexFromArgb(scheme.onSecondary),
208
- secondaryContainer: materialColorUtilities.hexFromArgb(scheme.secondaryContainer),
209
- onSecondaryContainer: materialColorUtilities.hexFromArgb(scheme.onSecondaryContainer),
210
- secondaryFixed: tone(palettes.secondary, 90),
211
- secondaryFixedDim: tone(palettes.secondary, 80),
212
- onSecondaryFixed: tone(palettes.secondary, 10),
213
- onSecondaryFixedVariant: tone(palettes.secondary, 30),
214
- tertiary: materialColorUtilities.hexFromArgb(scheme.tertiary),
215
- onTertiary: materialColorUtilities.hexFromArgb(scheme.onTertiary),
216
- tertiaryContainer: materialColorUtilities.hexFromArgb(scheme.tertiaryContainer),
217
- onTertiaryContainer: materialColorUtilities.hexFromArgb(scheme.onTertiaryContainer),
218
- tertiaryFixed: tone(palettes.tertiary, 90),
219
- tertiaryFixedDim: tone(palettes.tertiary, 80),
220
- onTertiaryFixed: tone(palettes.tertiary, 10),
221
- onTertiaryFixedVariant: tone(palettes.tertiary, 30),
222
- error: materialColorUtilities.hexFromArgb(scheme.error),
223
- onError: materialColorUtilities.hexFromArgb(scheme.onError),
224
- errorContainer: materialColorUtilities.hexFromArgb(scheme.errorContainer),
225
- onErrorContainer: materialColorUtilities.hexFromArgb(scheme.onErrorContainer),
226
- surface: materialColorUtilities.hexFromArgb(scheme.surface),
227
- onSurface: materialColorUtilities.hexFromArgb(scheme.onSurface),
228
- surfaceVariant: materialColorUtilities.hexFromArgb(scheme.surfaceVariant),
229
- onSurfaceVariant: materialColorUtilities.hexFromArgb(scheme.onSurfaceVariant),
230
- surfaceTint: materialColorUtilities.hexFromArgb(scheme.primary),
231
- // Surface container roles from neutral palette tones
232
- surfaceContainerLowest: mode === "light" ? tone(palettes.neutral, 100) : tone(palettes.neutral, 4),
233
- surfaceContainerLow: mode === "light" ? tone(palettes.neutral, 96) : tone(palettes.neutral, 10),
234
- surfaceContainer: mode === "light" ? tone(palettes.neutral, 94) : tone(palettes.neutral, 12),
235
- surfaceContainerHigh: mode === "light" ? tone(palettes.neutral, 92) : tone(palettes.neutral, 17),
236
- surfaceContainerHighest: mode === "light" ? tone(palettes.neutral, 90) : tone(palettes.neutral, 22),
237
- inverseSurface: materialColorUtilities.hexFromArgb(scheme.inverseSurface),
238
- inverseOnSurface: materialColorUtilities.hexFromArgb(scheme.inverseOnSurface),
239
- background: materialColorUtilities.hexFromArgb(scheme.background),
240
- onBackground: materialColorUtilities.hexFromArgb(scheme.onBackground),
241
- outline: materialColorUtilities.hexFromArgb(scheme.outline),
242
- outlineVariant: materialColorUtilities.hexFromArgb(scheme.outlineVariant),
243
- shadow: materialColorUtilities.hexFromArgb(scheme.shadow),
244
- scrim: materialColorUtilities.hexFromArgb(scheme.scrim)
245
- };
246
- }
247
- function applyTheme(sourceColorHex, mode = "light", root = document.documentElement) {
248
- const resolved = resolveMode(mode);
249
- const colors = generateM3Theme(sourceColorHex, resolved);
250
- for (const [key, value] of Object.entries(colors)) {
251
- const kebabKey = key.replace(/[A-Z]/g, (m67) => `-${m67.toLowerCase()}`);
252
- root.style.setProperty(`--md-sys-color-${kebabKey}`, value);
253
- root.style.setProperty(`--color-m3-${kebabKey}`, value);
254
- }
255
- root.setAttribute("data-theme", resolved);
256
- }
257
322
  function cn(...inputs) {
258
323
  return tailwindMerge.twMerge(clsx.clsx(inputs));
259
324
  }
@@ -6584,6 +6649,35 @@ var BUTTON_COLOR_TOKENS = {
6584
6649
  default: "bg-transparent text-m3-primary",
6585
6650
  selected: "bg-transparent text-m3-primary",
6586
6651
  unselected: "bg-transparent text-m3-primary"
6652
+ },
6653
+ // ── MD3 Expressive accent variants ──────────────────────────────────────
6654
+ /**
6655
+ * High-chroma tertiary tone. Use for hero CTAs and expressive moments where
6656
+ * a distinct accent beyond primary is needed (e.g., hero chip, highlight fab).
6657
+ */
6658
+ tertiary: {
6659
+ default: "bg-m3-tertiary text-m3-on-tertiary",
6660
+ selected: "bg-m3-tertiary text-m3-on-tertiary",
6661
+ unselected: "bg-m3-tertiary-container text-m3-on-tertiary-container"
6662
+ },
6663
+ /**
6664
+ * Brand-stable primary fixed. Hue stays consistent across light and dark modes.
6665
+ * Ideal for badges, pill chips, and elements that must carry the brand color
6666
+ * regardless of the active theme.
6667
+ */
6668
+ "primary-fixed": {
6669
+ default: "bg-m3-primary-fixed text-m3-on-primary-fixed",
6670
+ selected: "bg-m3-primary-fixed text-m3-on-primary-fixed",
6671
+ unselected: "bg-m3-primary-fixed text-m3-on-primary-fixed-variant"
6672
+ },
6673
+ /**
6674
+ * Brand-stable tertiary fixed. Use for special-state indicators, achievement
6675
+ * badges, or accent pills that need a fixed tertiary hue across themes.
6676
+ */
6677
+ "tertiary-fixed": {
6678
+ default: "bg-m3-tertiary-fixed text-m3-on-tertiary-fixed",
6679
+ selected: "bg-m3-tertiary-fixed text-m3-on-tertiary-fixed",
6680
+ unselected: "bg-m3-tertiary-fixed text-m3-on-tertiary-fixed-variant"
6587
6681
  }
6588
6682
  };
6589
6683
  var MOTION_PROP_KEYS = [
@@ -6955,7 +7049,7 @@ var PILL_BORDER_RADIUS = 9999;
6955
7049
  var MIN_FLEX_GROW = 0.01;
6956
7050
  var PADDING_EXPAND_MULTIPLIER = 4;
6957
7051
  var CHECK_ICON_SIZE = 24;
6958
- var CHECK_ICON = /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", size: CHECK_ICON_SIZE, weight: 700 });
7052
+ var CHECK_ICON = /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "check", variant: "rounded", size: CHECK_ICON_SIZE, weight: 700 });
6959
7053
  var CHECK_ICON_GAP_MAP = {
6960
7054
  xs: 6,
6961
7055
  sm: 8,
@@ -22339,6 +22433,8 @@ function MD3ThemeProvider({
22339
22433
  sourceColor: initialSourceColor = "#6750A4",
22340
22434
  defaultMode = "light",
22341
22435
  persistToLocalStorage = false,
22436
+ variant = "expressive",
22437
+ contrastLevel = 0,
22342
22438
  typography: typographyProp,
22343
22439
  fontFamily,
22344
22440
  fontVariationAxes,
@@ -22347,6 +22443,17 @@ function MD3ThemeProvider({
22347
22443
  const [sourceColor, setSourceColor] = React59.useState(initialSourceColor);
22348
22444
  const [mode, setMode] = React59.useState(defaultMode);
22349
22445
  const [isHydrated, setIsHydrated] = React59.useState(!persistToLocalStorage);
22446
+ const [systemMode, setSystemMode] = React59.useState("light");
22447
+ React59.useEffect(() => {
22448
+ if (typeof window === "undefined") return;
22449
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
22450
+ const updateSystemMode = () => {
22451
+ setSystemMode(mediaQuery.matches ? "dark" : "light");
22452
+ };
22453
+ updateSystemMode();
22454
+ mediaQuery.addEventListener("change", updateSystemMode);
22455
+ return () => mediaQuery.removeEventListener("change", updateSystemMode);
22456
+ }, []);
22350
22457
  React59.useEffect(() => {
22351
22458
  if (!persistToLocalStorage) return;
22352
22459
  const savedColor = localStorage.getItem(STORAGE_KEY_COLOR);
@@ -22358,25 +22465,37 @@ function MD3ThemeProvider({
22358
22465
  setMode(savedMode);
22359
22466
  setIsHydrated(true);
22360
22467
  }, [persistToLocalStorage]);
22468
+ const effectiveMode = mode === "system" ? systemMode : mode;
22361
22469
  React59.useEffect(() => {
22362
22470
  if (!isHydrated) return;
22363
- applyTheme(sourceColor, mode);
22471
+ applyTheme(sourceColor, effectiveMode, document.documentElement, {
22472
+ variant,
22473
+ contrastLevel
22474
+ });
22364
22475
  if (persistToLocalStorage) {
22365
22476
  localStorage.setItem(STORAGE_KEY_COLOR, sourceColor);
22366
22477
  localStorage.setItem(STORAGE_KEY_MODE, mode);
22367
22478
  }
22368
- }, [sourceColor, mode, persistToLocalStorage, isHydrated]);
22369
- React59.useEffect(() => {
22370
- if (mode !== "system" || typeof window === "undefined") return;
22371
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
22372
- const handleChange = () => applyTheme(sourceColor, "system");
22373
- mediaQuery.addEventListener("change", handleChange);
22374
- return () => mediaQuery.removeEventListener("change", handleChange);
22375
- }, [mode, sourceColor]);
22376
- const effectiveMode = resolveMode(mode);
22479
+ }, [
22480
+ sourceColor,
22481
+ mode,
22482
+ effectiveMode,
22483
+ persistToLocalStorage,
22484
+ isHydrated,
22485
+ variant,
22486
+ contrastLevel
22487
+ ]);
22377
22488
  const themeValue = React59.useMemo(
22378
- () => ({ sourceColor, setSourceColor, mode, setMode, effectiveMode }),
22379
- [sourceColor, mode, effectiveMode]
22489
+ () => ({
22490
+ sourceColor,
22491
+ setSourceColor,
22492
+ mode,
22493
+ setMode,
22494
+ effectiveMode,
22495
+ variant,
22496
+ contrastLevel
22497
+ }),
22498
+ [sourceColor, mode, effectiveMode, variant, contrastLevel]
22380
22499
  );
22381
22500
  const typographyValue = React59.useMemo(() => {
22382
22501
  if (typographyProp) return typographyProp;
@@ -23912,6 +24031,7 @@ exports.convex = convex;
23912
24031
  exports.cornerFeature = cornerFeature;
23913
24032
  exports.cornerRounding = cornerRounding;
23914
24033
  exports.createDoubleMapper = createDoubleMapper;
24034
+ exports.createMd3ExpressiveTheme = createMd3ExpressiveTheme;
23915
24035
  exports.directionVector = directionVector;
23916
24036
  exports.distance = distance;
23917
24037
  exports.distanceSquared = distanceSquared;