@windmorph/react 0.2.2 → 0.2.4
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/components/autocomplete/Autocomplete.d.ts +4 -1
- package/dist/components/autocomplete/Autocomplete.js +3 -5
- package/dist/components/autocomplete/Autocomplete.js.map +1 -1
- package/dist/components/badge/Badge.d.ts +5 -2
- package/dist/components/badge/Badge.js +7 -3
- package/dist/components/badge/Badge.js.map +1 -1
- package/dist/components/button/Button.d.ts +4 -2
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/button/ButtonContext.d.ts +1 -1
- package/dist/components/button/button-pending.js +2 -4
- package/dist/components/button/button-pending.js.map +1 -1
- package/dist/{composites → components}/button-group/ButtonGroup.d.ts +4 -4
- package/dist/{composites → components}/button-group/ButtonGroup.js +9 -7
- package/dist/components/button-group/ButtonGroup.js.map +1 -0
- package/dist/{composites → components}/button-group/button-group-styles.d.ts +1 -1
- package/dist/{composites → components}/button-group/button-group-styles.js +1 -1
- package/dist/{composites → components}/button-group/button-group-styles.js.map +1 -1
- package/dist/{composites → components}/button-group/lazy-overflow-menu.js +2 -2
- package/dist/components/button-group/lazy-overflow-menu.js.map +1 -0
- package/dist/{composites → components}/button-group/overflow-menu-list.js +2 -2
- package/dist/components/button-group/overflow-menu-list.js.map +1 -0
- package/dist/{composites → components}/button-group/use-overflow.js +1 -1
- package/dist/{composites → components}/button-group/use-overflow.js.map +1 -1
- package/dist/{composites → components}/button-group/use-press-expansion.js +1 -1
- package/dist/{composites → components}/button-group/use-press-expansion.js.map +1 -1
- package/dist/components/carousel/Carousel.d.ts +4 -1
- package/dist/components/carousel/Carousel.js +2 -4
- package/dist/components/carousel/Carousel.js.map +1 -1
- package/dist/components/checkbox/checkbox-styles.d.ts +3 -3
- package/dist/components/chip/Chip.d.ts +8 -2
- package/dist/components/chip/Chip.js +3 -8
- package/dist/components/chip/Chip.js.map +1 -1
- package/dist/components/chip/chip-tokens.d.ts +4 -4
- package/dist/components/date-picker/DateField.d.ts +4 -1
- package/dist/components/date-picker/DateField.js +3 -1
- package/dist/components/date-picker/DateField.js.map +1 -1
- package/dist/components/date-picker/DatePicker.d.ts +4 -1
- package/dist/components/date-picker/DatePicker.js +5 -2
- package/dist/components/date-picker/DatePicker.js.map +1 -1
- package/dist/components/date-picker/PickerDialog.d.ts +4 -1
- package/dist/components/date-picker/PickerDialog.js +3 -1
- package/dist/components/date-picker/PickerDialog.js.map +1 -1
- package/dist/components/date-picker/date-picker-styles.d.ts +12 -12
- package/dist/components/date-picker/date-picker-tokens.d.ts +1 -1
- package/dist/components/dialog/Dialog.d.ts +5 -2
- package/dist/components/dialog/Dialog.js +4 -2
- package/dist/components/dialog/Dialog.js.map +1 -1
- package/dist/components/dialog/dialog-tokens.d.ts +1 -1
- package/dist/components/fab-menu/FabMenu.js +2 -2
- package/dist/components/fab-menu/FabMenu.js.map +1 -1
- package/dist/components/icon-button/IconButton.d.ts +4 -2
- package/dist/components/icon-button/IconButton.js.map +1 -1
- package/dist/components/labels/LabelsProvider.d.ts +35 -0
- package/dist/components/labels/LabelsProvider.js +47 -0
- package/dist/components/labels/LabelsProvider.js.map +1 -0
- package/dist/components/labels/use-labels.d.ts +16 -0
- package/dist/components/labels/use-labels.js +42 -0
- package/dist/components/labels/use-labels.js.map +1 -0
- package/dist/components/menu/Menu.d.ts +17 -1
- package/dist/components/menu/Menu.js +21 -11
- package/dist/components/menu/Menu.js.map +1 -1
- package/dist/components/menu/menu-styles.js +12 -12
- package/dist/components/menu/menu-styles.js.map +1 -1
- package/dist/components/menu/menu-tokens.d.ts +1 -1
- package/dist/components/menu/menu-tokens.js.map +1 -1
- package/dist/components/navigation/NavItem.d.ts +1 -1
- package/dist/components/navigation/NavItem.js +9 -6
- package/dist/components/navigation/NavItem.js.map +1 -1
- package/dist/components/navigation/navigation-styles.js +1 -1
- package/dist/components/navigation/navigation-styles.js.map +1 -1
- package/dist/components/pull-to-refresh/PullToRefresh.d.ts +1 -1
- package/dist/components/pull-to-refresh/PullToRefresh.js +2 -4
- package/dist/components/pull-to-refresh/PullToRefresh.js.map +1 -1
- package/dist/components/search/SearchField.d.ts +4 -1
- package/dist/components/search/SearchField.js +2 -4
- package/dist/components/search/SearchField.js.map +1 -1
- package/dist/components/search/search-styles.js +2 -2
- package/dist/components/search/search-styles.js.map +1 -1
- package/dist/components/select/Select.d.ts +4 -1
- package/dist/components/select/Select.js +2 -4
- package/dist/components/select/Select.js.map +1 -1
- package/dist/components/sheet/BottomSheet.d.ts +4 -1
- package/dist/components/sheet/BottomSheet.js +2 -4
- package/dist/components/sheet/BottomSheet.js.map +1 -1
- package/dist/components/sheet/SideSheet.d.ts +4 -1
- package/dist/components/sheet/SideSheet.js +2 -4
- package/dist/components/sheet/SideSheet.js.map +1 -1
- package/dist/components/slider/Slider.d.ts +4 -1
- package/dist/components/slider/Slider.js +7 -5
- package/dist/components/slider/Slider.js.map +1 -1
- package/dist/components/snackbar/Snackbar.d.ts +8 -2
- package/dist/components/snackbar/Snackbar.js +2 -4
- package/dist/components/snackbar/Snackbar.js.map +1 -1
- package/dist/components/snackbar/snackbar-tokens.d.ts +1 -1
- package/dist/components/split-button/SplitButton.d.ts +4 -1
- package/dist/components/split-button/SplitButton.js +4 -2
- package/dist/components/split-button/SplitButton.js.map +1 -1
- package/dist/components/switch/switch-styles.d.ts +3 -3
- package/dist/components/text-field/TextField.d.ts +4 -1
- package/dist/components/text-field/TextField.js +2 -4
- package/dist/components/text-field/TextField.js.map +1 -1
- package/dist/components/text-field/text-field-styles.js +2 -2
- package/dist/components/text-field/text-field-styles.js.map +1 -1
- package/dist/components/time-picker/TimeField.d.ts +24 -2
- package/dist/components/time-picker/TimeField.js +40 -12
- package/dist/components/time-picker/TimeField.js.map +1 -1
- package/dist/components/time-picker/TimeFieldList.js +95 -0
- package/dist/components/time-picker/TimeFieldList.js.map +1 -0
- package/dist/components/time-picker/TimePicker.d.ts +9 -5
- package/dist/components/time-picker/TimePicker.js +5 -2
- package/dist/components/time-picker/TimePicker.js.map +1 -1
- package/dist/components/time-picker/time-list.js +33 -0
- package/dist/components/time-picker/time-list.js.map +1 -0
- package/dist/components/tooltip/Tooltip.d.ts +1 -1
- package/dist/components/tooltip/tooltip-tokens.d.ts +1 -1
- package/dist/index.d.ts +40 -38
- package/dist/index.js +4 -3
- package/dist/primitives/use-m3-interaction.js +10 -6
- package/dist/primitives/use-m3-interaction.js.map +1 -1
- package/dist/primitives.d.ts +7 -4
- package/dist/primitives.js +4 -1
- package/dist/styles/utilities.css +22 -15
- package/dist/styles.compiled.css +1 -1
- package/dist/utils/use-scroll-keys.d.ts +29 -0
- package/dist/utils/use-scroll-keys.js +66 -0
- package/dist/utils/use-scroll-keys.js.map +1 -0
- package/dist/utils/use-scroll-restoration.d.ts +43 -0
- package/dist/utils/use-scroll-restoration.js +173 -0
- package/dist/utils/use-scroll-restoration.js.map +1 -0
- package/dist/windmorph-labels.d.ts +101 -0
- package/package.json +1 -1
- package/dist/composites/button-group/ButtonGroup.js.map +0 -1
- package/dist/composites/button-group/lazy-overflow-menu.js.map +0 -1
- package/dist/composites/button-group/overflow-menu-list.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { cn, twMergeConfig } from "./utils/cn.js";
|
|
|
14
14
|
import { ThemeScope } from "./theme/ThemeScope.js";
|
|
15
15
|
import { ThemeScript, getThemeScriptSource } from "./theme/ThemeScript.js";
|
|
16
16
|
import { createTheme } from "./theme/create-theme.js";
|
|
17
|
+
import { LabelsProvider } from "./components/labels/LabelsProvider.js";
|
|
17
18
|
import { getM3Spring } from "./motion/get-m3-spring.js";
|
|
18
19
|
import { useM3Spring } from "./motion/use-m3-spring.js";
|
|
19
20
|
import { tv } from "./utils/tv.js";
|
|
@@ -28,9 +29,9 @@ import { TooltipTrigger } from "./components/tooltip/tooltip-trigger.js";
|
|
|
28
29
|
import { iconButtonStyles } from "./components/icon-button/icon-button-styles.js";
|
|
29
30
|
import { IconButton } from "./components/icon-button/IconButton.js";
|
|
30
31
|
import { iconButtonTokenSet } from "./components/icon-button/icon-button-tokens.js";
|
|
31
|
-
import { buttonGroupStyles } from "./
|
|
32
|
+
import { buttonGroupStyles } from "./components/button-group/button-group-styles.js";
|
|
32
33
|
import { ContextMenuTrigger, MenuTrigger } from "./components/menu/menu-trigger.js";
|
|
33
|
-
import { ButtonGroup } from "./
|
|
34
|
+
import { ButtonGroup } from "./components/button-group/ButtonGroup.js";
|
|
34
35
|
import { extendedFabStyles, fabStyles } from "./components/fab/fab-styles.js";
|
|
35
36
|
import { ExtendedFab, Fab } from "./components/fab/Fab.js";
|
|
36
37
|
import { extendedFabTokenSet, fabTokenSet } from "./components/fab/fab-tokens.js";
|
|
@@ -136,4 +137,4 @@ import { TimePicker, TimePickerModeToggle, useTimePickerRoom } from "./component
|
|
|
136
137
|
import { TimeField } from "./components/time-picker/TimeField.js";
|
|
137
138
|
import { timePickerTokenSet } from "./components/time-picker/time-picker-tokens.js";
|
|
138
139
|
import { Time, parseTime } from "@internationalized/date";
|
|
139
|
-
export { AssistChip, Autocomplete, AutocompleteItem, AutocompleteSection, BREAKPOINTS, BREAKPOINT_NAMES, BUILT_IN_THEMES, BUILT_IN_THEME_NAMES, Badge, BadgedBox, BottomSheet, Button, ButtonContext, ButtonGroup, COLOR_MODES, COLOR_ROLES, CONTRAST_LEVELS, CONTRAST_LEVEL_NAMES, CORNERS, CORNER_NAMES, CUSTOM_COLORS, CUSTOM_COLOR_ROLES, Card, Carousel, Checkbox, ChipSet, CircularProgressIndicator, ContextMenuTrigger, DEFAULT_CUSTOM_COLORS, DEFAULT_DENSITY, DEFAULT_MOTION_SCHEME, DEFAULT_STORAGE_KEY, DEFAULT_THEME, DEFAULT_THEME_STATE, DENSITIES, DateField, DatePicker, DateRangePicker, Dialog, DialogActions, DialogContent, DialogHeader, DialogTitle, DialogTrigger, Divider, DockedToolbar, ELEVATION_LEVELS, ELEVATION_LEVEL_NAMES, ExtendedFab, FOCUS_INDICATOR, Fab, FabMenu, FabMenuItem, FilterChip, FloatingToolbar, IconButton, InputChip, LEGACY_DURATIONS, LEGACY_EASINGS, LabeledDivider, LinearProgressIndicator, List, ListItem, ListItemAvatar, ListItemImage, ListItemVideo, ListSection, LoadingIndicator, MOTION_SCHEMES, Menu, MenuGroup, MenuItem, MenuTrigger, NavigationBar, NavigationBarItem, NavigationRail, NavigationRailItem, OptionPopover, PALETTE_NAMES, PickerDialog, PullToRefresh, Radio, RadioGroup, RangeSlider, RichTooltip, RichTooltipTrigger, SCHEME_VARIANTS, SHADOW_AMBIENT_OPACITY, SHADOW_KEY_OPACITY, SPRINGS, SPRING_FAMILIES, SPRING_SPEEDS, SPRING_TOKEN_NAMES, STATE_OPACITIES, SearchAppBar, SearchBar, SearchField, Select, SelectItem, SelectSection, SheetTrigger, SideSheet, Slider, Snackbar, SnackbarHost, SnackbarHostState, SplitButton, SubmenuTrigger, SuggestionChip, Switch, TYPEFACES, TYPE_ROLES, TYPE_SCALE, Tab, Tabs, TextField, ThemeProvider, ThemeScope, ThemeScript, Time, TimeField, TimePicker, TimePickerModeToggle, ToggleGroupStateContext, ToolbarFab, Tooltip, TooltipPlacementContext, TooltipTrigger, TopAppBar, Z_INDEX, appBarTokenSet, assistChipTokenSet, badgeStyles, badgeTokenSet, badgedBoxStyles, bottomSheetStyles, bottomSheetTokenSet, buttonGroupStyles, buttonStyles, buttonTokenSet, buttonVariantClasses, cardStyles, cardTokenSet, carouselStyles, carouselTokenSet, checkboxStyles, checkboxTokenSet, chipSetStyles, chipStyles, circularProgressStyles, cn, color, colorAt, componentTokenList, componentTokensCss, corner, createTheme, datePickerStyles, datePickerTokenSet, defineComponentTokens, densityAttribute, dialogStyles, dialogTokenSet, dividerStyles, dividerTokenSet, dockedDatePickerStyles, dockedToolbarStyles, dockedToolbarTokenSet, elevation, extendedFabStyles, extendedFabTokenSet, fabMenuStyles, fabMenuTokenSet, fabStyles, fabTokenSet, filterChipTokenSet, floatingToolbarStyles, floatingToolbarTokenSet, getM3Spring, getThemeScriptSource, iconButtonStyles, iconButtonTokenSet, inputChipTokenSet, isComponentTokenSet, isDensity, labeledDividerStyles, linearProgressStyles, listMediaStyles, listStyles, listTokenSet, loadingIndicatorStyles, loadingIndicatorTokenSet, matchesSearch, menuStyles, menuTokenSet, navBarTokenSet, navItemStyles, navRailTokenSet, navigationBarStyles, navigationRailStyles, normalizeSearch, parseThemeState, parseTime, pickerDialogStyles, plainTooltipTokenSet, progressIndicatorTokenSet, pullToRefreshStyles, px, radioGroupStyles, radioStyles, radioTokenSet, richTooltipStyles, richTooltipTokenSet, searchAppBarStyles, searchBarStyles, searchBarTokenSet, searchFieldStyles, searchViewTokenSet, serializeThemeState, sideSheetStyles, sideSheetTokenSet, sliderStyles, sliderTokenSet, snackbarHostStyles, snackbarStyles, snackbarTokenSet, splitButtonStyles, splitButtonTokenSet, spring, springPosition, springSettleDuration, springToLinearEasing, suggestionChipTokenSet, switchStyles, switchTokenSet, tabsStyles, tabsTokenSet, textFieldStyles, textFieldTokenSet, themeAttributes, timePickerStyles, timePickerTokenSet, toMotionSpring, toolbarFabStyles, toolbarFabTokenSet, tooltipStyles, topAppBarStyles, tv, twMergeConfig, typeTokens, typescale, useM3Spring, useNavigationRail, useSnackbarHostState, useTheme, useThemeScope, useTimePickerRoom, useToolbarScrollExit, useToolbarScrollExpansion };
|
|
140
|
+
export { AssistChip, Autocomplete, AutocompleteItem, AutocompleteSection, BREAKPOINTS, BREAKPOINT_NAMES, BUILT_IN_THEMES, BUILT_IN_THEME_NAMES, Badge, BadgedBox, BottomSheet, Button, ButtonContext, ButtonGroup, COLOR_MODES, COLOR_ROLES, CONTRAST_LEVELS, CONTRAST_LEVEL_NAMES, CORNERS, CORNER_NAMES, CUSTOM_COLORS, CUSTOM_COLOR_ROLES, Card, Carousel, Checkbox, ChipSet, CircularProgressIndicator, ContextMenuTrigger, DEFAULT_CUSTOM_COLORS, DEFAULT_DENSITY, DEFAULT_MOTION_SCHEME, DEFAULT_STORAGE_KEY, DEFAULT_THEME, DEFAULT_THEME_STATE, DENSITIES, DateField, DatePicker, DateRangePicker, Dialog, DialogActions, DialogContent, DialogHeader, DialogTitle, DialogTrigger, Divider, DockedToolbar, ELEVATION_LEVELS, ELEVATION_LEVEL_NAMES, ExtendedFab, FOCUS_INDICATOR, Fab, FabMenu, FabMenuItem, FilterChip, FloatingToolbar, IconButton, InputChip, LEGACY_DURATIONS, LEGACY_EASINGS, LabeledDivider, LabelsProvider, LinearProgressIndicator, List, ListItem, ListItemAvatar, ListItemImage, ListItemVideo, ListSection, LoadingIndicator, MOTION_SCHEMES, Menu, MenuGroup, MenuItem, MenuTrigger, NavigationBar, NavigationBarItem, NavigationRail, NavigationRailItem, OptionPopover, PALETTE_NAMES, PickerDialog, PullToRefresh, Radio, RadioGroup, RangeSlider, RichTooltip, RichTooltipTrigger, SCHEME_VARIANTS, SHADOW_AMBIENT_OPACITY, SHADOW_KEY_OPACITY, SPRINGS, SPRING_FAMILIES, SPRING_SPEEDS, SPRING_TOKEN_NAMES, STATE_OPACITIES, SearchAppBar, SearchBar, SearchField, Select, SelectItem, SelectSection, SheetTrigger, SideSheet, Slider, Snackbar, SnackbarHost, SnackbarHostState, SplitButton, SubmenuTrigger, SuggestionChip, Switch, TYPEFACES, TYPE_ROLES, TYPE_SCALE, Tab, Tabs, TextField, ThemeProvider, ThemeScope, ThemeScript, Time, TimeField, TimePicker, TimePickerModeToggle, ToggleGroupStateContext, ToolbarFab, Tooltip, TooltipPlacementContext, TooltipTrigger, TopAppBar, Z_INDEX, appBarTokenSet, assistChipTokenSet, badgeStyles, badgeTokenSet, badgedBoxStyles, bottomSheetStyles, bottomSheetTokenSet, buttonGroupStyles, buttonStyles, buttonTokenSet, buttonVariantClasses, cardStyles, cardTokenSet, carouselStyles, carouselTokenSet, checkboxStyles, checkboxTokenSet, chipSetStyles, chipStyles, circularProgressStyles, cn, color, colorAt, componentTokenList, componentTokensCss, corner, createTheme, datePickerStyles, datePickerTokenSet, defineComponentTokens, densityAttribute, dialogStyles, dialogTokenSet, dividerStyles, dividerTokenSet, dockedDatePickerStyles, dockedToolbarStyles, dockedToolbarTokenSet, elevation, extendedFabStyles, extendedFabTokenSet, fabMenuStyles, fabMenuTokenSet, fabStyles, fabTokenSet, filterChipTokenSet, floatingToolbarStyles, floatingToolbarTokenSet, getM3Spring, getThemeScriptSource, iconButtonStyles, iconButtonTokenSet, inputChipTokenSet, isComponentTokenSet, isDensity, labeledDividerStyles, linearProgressStyles, listMediaStyles, listStyles, listTokenSet, loadingIndicatorStyles, loadingIndicatorTokenSet, matchesSearch, menuStyles, menuTokenSet, navBarTokenSet, navItemStyles, navRailTokenSet, navigationBarStyles, navigationRailStyles, normalizeSearch, parseThemeState, parseTime, pickerDialogStyles, plainTooltipTokenSet, progressIndicatorTokenSet, pullToRefreshStyles, px, radioGroupStyles, radioStyles, radioTokenSet, richTooltipStyles, richTooltipTokenSet, searchAppBarStyles, searchBarStyles, searchBarTokenSet, searchFieldStyles, searchViewTokenSet, serializeThemeState, sideSheetStyles, sideSheetTokenSet, sliderStyles, sliderTokenSet, snackbarHostStyles, snackbarStyles, snackbarTokenSet, splitButtonStyles, splitButtonTokenSet, spring, springPosition, springSettleDuration, springToLinearEasing, suggestionChipTokenSet, switchStyles, switchTokenSet, tabsStyles, tabsTokenSet, textFieldStyles, textFieldTokenSet, themeAttributes, timePickerStyles, timePickerTokenSet, toMotionSpring, toolbarFabStyles, toolbarFabTokenSet, tooltipStyles, topAppBarStyles, tv, twMergeConfig, typeTokens, typescale, useM3Spring, useNavigationRail, useSnackbarHostState, useTheme, useThemeScope, useTimePickerRoom, useToolbarScrollExit, useToolbarScrollExpansion };
|
|
@@ -15,18 +15,22 @@ const RIPPLE_START = {
|
|
|
15
15
|
* one is still growing or fading. The ripple's animated properties are pinned to their start
|
|
16
16
|
* values with their transitions off and flushed to style, then released: they transition
|
|
17
17
|
* from this press's start to whatever the state layer's rules say (growing if
|
|
18
|
-
* `data-rippling` is on, or once it turns on).
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* `data-rippling` is on, or once it turns on). They're pinned with no duration or delay, not by
|
|
19
|
+
* leaving them out of `transition-property`: a running transition whose property drops out of
|
|
20
|
+
* the list is cancelled and jumps to its end, as did a corner morph on a quick second press
|
|
21
|
+
* and a width an app animates through `className` (2026-11-10). A running transition keeps its
|
|
22
|
+
* own timing when the durations change, so nothing else is touched.
|
|
21
23
|
*/
|
|
22
24
|
function restartRipple(element) {
|
|
23
25
|
const { style } = element;
|
|
24
|
-
const
|
|
25
|
-
style.
|
|
26
|
+
const { transitionDuration, transitionDelay } = style;
|
|
27
|
+
style.transitionDuration = "0s";
|
|
28
|
+
style.transitionDelay = "0s";
|
|
26
29
|
for (const [name, value] of Object.entries(RIPPLE_START)) style.setProperty(name, value);
|
|
27
30
|
getComputedStyle(element).getPropertyValue("--m3-ripple-x");
|
|
28
31
|
for (const name of Object.keys(RIPPLE_START)) style.removeProperty(name);
|
|
29
|
-
style.
|
|
32
|
+
style.transitionDuration = transitionDuration;
|
|
33
|
+
style.transitionDelay = transitionDelay;
|
|
30
34
|
}
|
|
31
35
|
/**
|
|
32
36
|
* Positions a new ripple at the press point (Compose `RippleAnimation`): it grows from 30%
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-m3-interaction.js","names":[],"sources":["../../src/primitives/use-m3-interaction.ts"],"sourcesContent":["'use client';\n\nimport { mergeProps, useFocusRing, useHover, usePress, type PressEvents } from 'react-aria';\nimport {\n useEffect,\n useState,\n type DOMAttributes,\n type KeyboardEvent,\n type PointerEvent,\n type RefObject,\n} from 'react';\n\nexport interface M3InteractionOptions extends PressEvents {\n isDisabled?: boolean;\n isSelected?: boolean;\n isDragged?: boolean;\n /**\n * Pressed state from another React Aria hook (e.g. `useButton`). When provided,\n * this hook does not attach its own press handling.\n */\n isPressed?: boolean;\n /** Treat focus inside the element as focus on the element (e.g. text fields). */\n within?: boolean;\n /** Whether the element is a text input; focus is then always visible. */\n isTextInput?: boolean;\n autoFocus?: boolean;\n}\n\nexport interface M3InteractionState {\n isHovered: boolean;\n isPressed: boolean;\n isFocused: boolean;\n isFocusVisible: boolean;\n}\n\n/** `data-*` attributes read by the `state-layer` and `focus-ring` utilities. */\nexport interface M3InteractionDataAttributes {\n 'data-hovered'?: true;\n 'data-pressed'?: true;\n /** The ripple is showing: from press start until release, but at least 225ms. */\n 'data-rippling'?: true;\n 'data-focused'?: true;\n 'data-focus-visible'?: true;\n 'data-disabled'?: true;\n 'data-selected'?: true;\n 'data-dragged'?: true;\n}\n\nexport interface M3InteractionResult {\n /** Event handlers to spread on the interactive element. */\n interactionProps: DOMAttributes<HTMLElement>;\n dataAttributes: M3InteractionDataAttributes;\n state: M3InteractionState;\n}\n\nconst flag = (value: boolean | undefined): true | undefined => (value ? true : undefined);\n\n/** Compose `RippleAnimation`: the radius grows (and the centre travels) over 225ms. */\nexport const RIPPLE_GROW_MS = 225;\n\n/** The ripple's animated properties, pinned at the start of a new ripple. */\nconst RIPPLE_START = {\n '--m3-ripple-opacity': '0',\n '--m3-ripple-radius': 'var(--m3-ripple-start, 0px)',\n '--m3-ripple-x': 'var(--m3-ripple-origin-x, 50%)',\n '--m3-ripple-y': 'var(--m3-ripple-origin-y, 50%)',\n} as const;\n\n/**\n * Starts a fresh ripple on `element`, as Compose does for every press, even while the last\n * one is still growing or fading. The ripple's animated properties are pinned to their start\n * values with their transitions off and flushed to style, then released: they transition\n * from this press's start to whatever the state layer's rules say (growing if\n * `data-rippling` is on, or once it turns on). Only the ripple's transitions are switched\n * off: the component's own (`--m3-transition-property`, such as a running corner morph) keep\n * running, so a quick second press doesn't make the corners jump.\n */\nexport function restartRipple(element: HTMLElement) {\n const { style } = element;\n const transitionProperty = style.transitionProperty;\n style.transitionProperty = 'var(--m3-transition-property, --m3-none)';\n for (const [name, value] of Object.entries(RIPPLE_START)) style.setProperty(name, value);\n getComputedStyle(element).getPropertyValue('--m3-ripple-x');\n for (const name of Object.keys(RIPPLE_START)) style.removeProperty(name);\n style.transitionProperty = transitionProperty;\n}\n\n/**\n * Positions a new ripple at the press point (Compose `RippleAnimation`): it grows from 30%\n * of the element's longer side to half its diagonal plus 10px while its centre moves to the\n * middle. Without a point (a key press) it starts in the middle. For a state layer on a\n * child of the pressed element (a navigation item's pill), pass that child.\n */\nexport function setRippleOrigin(element: HTMLElement, clientX?: number, clientY?: number) {\n const rect = element.getBoundingClientRect();\n const x = clientX === undefined ? rect.width / 2 : clientX - rect.left;\n const y = clientY === undefined ? rect.height / 2 : clientY - rect.top;\n const { style } = element;\n style.setProperty('--m3-ripple-origin-x', `${x}px`);\n style.setProperty('--m3-ripple-origin-y', `${y}px`);\n style.setProperty('--m3-ripple-center-x', `${rect.width / 2}px`);\n style.setProperty('--m3-ripple-center-y', `${rect.height / 2}px`);\n style.setProperty('--m3-ripple-start', `${Math.max(rect.width, rect.height) * 0.3}px`);\n style.setProperty(\n '--m3-ripple-size',\n `${Math.ceil(Math.hypot(rect.width, rect.height) / 2 + 10)}px`,\n );\n restartRipple(element);\n}\n\n/**\n * Flags a press that starts while the element's corner morph is still running\n * (`data-rapid-press`). M3's buttons note that the web can use \"a modified motion curve to\n * avoid resonant effects from overlapping animations\": the `container-motion` utility then\n * morphs on the fast effects spring, which doesn't overshoot, instead of the fast spatial\n * one. The attribute is set on the element directly, before React renders the press, so\n * the morph that press starts already uses the modified curve. Call it before anything\n * that resets the element's transitions (such as `restartRipple`).\n */\nexport function markRapidPress(element: HTMLElement) {\n const morphing =\n typeof element.getAnimations === 'function' &&\n element\n .getAnimations()\n .some(\n (animation) =>\n animation instanceof CSSTransition &&\n animation.transitionProperty.endsWith('radius') &&\n animation.playState === 'running',\n );\n element.toggleAttribute('data-rapid-press', morphing);\n}\n\n/**\n * Whether a ripple should be showing. Compose always finishes a ripple's 225ms growth\n * before fading it out, so a quick tap still reaches the edges: this stays true from press\n * start until release, but for at least 225ms.\n */\nexport function useRippleHold(isPressed: boolean): boolean {\n const [wasPressed, setWasPressed] = useState(isPressed);\n const [held, setHeld] = useState(false);\n const [presses, setPresses] = useState(0);\n // Adjust state while rendering when a press starts (no effect, no extra paint).\n if (isPressed !== wasPressed) {\n setWasPressed(isPressed);\n if (isPressed) {\n setHeld(true);\n setPresses((n) => n + 1);\n }\n }\n useEffect(() => {\n if (!held) return;\n const timer = setTimeout(() => setHeld(false), RIPPLE_GROW_MS);\n return () => clearTimeout(timer);\n }, [held, presses]);\n return isPressed || held;\n}\n\n/**\n * M3 interaction states for any element: hover, press, focus-visible, selected,\n * dragged and disabled, exposed as `data-*` attributes, plus the ripple origin.\n * Pair with the `state-layer` and `focus-ring` utilities, which paint the state\n * layer and ripple as background layers on the element itself (no child nodes).\n */\nexport function useM3Interaction(\n options: M3InteractionOptions,\n ref: RefObject<HTMLElement | null>,\n): M3InteractionResult {\n const {\n isDisabled,\n isSelected,\n isDragged,\n within,\n isTextInput,\n autoFocus,\n onPress,\n onPressStart,\n onPressEnd,\n onPressChange,\n onPressUp,\n onClick,\n } = options;\n const hasExternalPress = options.isPressed !== undefined;\n\n // Only `usePress`'s own options: it spreads any others onto the props it returns, so this\n // hook's options (`isDragged`, `within` …) would reach the DOM as unknown attributes.\n const { pressProps, isPressed: isOwnPressed } = usePress({\n onPress,\n onPressStart,\n onPressEnd,\n onPressChange,\n onPressUp,\n onClick,\n ref,\n isDisabled: isDisabled || hasExternalPress,\n });\n const { hoverProps, isHovered } = useHover({ isDisabled });\n const { focusProps, isFocused, isFocusVisible } = useFocusRing({\n within,\n isTextInput,\n autoFocus,\n });\n\n const isPressed = hasExternalPress ? Boolean(options.isPressed) : isOwnPressed;\n const isRippling = useRippleHold(isPressed && !isDisabled);\n\n const rippleProps: DOMAttributes<HTMLElement> = {\n onPointerDown: (event: PointerEvent<HTMLElement>) => {\n if (!isDisabled && event.button === 0) {\n markRapidPress(event.currentTarget);\n setRippleOrigin(event.currentTarget, event.clientX, event.clientY);\n }\n },\n onKeyDown: (event: KeyboardEvent<HTMLElement>) => {\n if (!isDisabled && (event.key === 'Enter' || event.key === ' ')) {\n markRapidPress(event.currentTarget);\n setRippleOrigin(event.currentTarget);\n }\n },\n };\n\n return {\n interactionProps: mergeProps(\n hasExternalPress ? {} : pressProps,\n hoverProps,\n focusProps,\n rippleProps,\n ),\n dataAttributes: {\n 'data-hovered': flag(isHovered && !isDisabled),\n 'data-pressed': flag(isPressed && !isDisabled),\n 'data-rippling': flag(isRippling),\n 'data-focused': flag(isFocused),\n 'data-focus-visible': flag(isFocusVisible),\n 'data-disabled': flag(isDisabled),\n 'data-selected': flag(isSelected),\n 'data-dragged': flag(isDragged),\n },\n state: { isHovered, isPressed, isFocused, isFocusVisible },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-m3-interaction.js","names":[],"sources":["../../src/primitives/use-m3-interaction.ts"],"sourcesContent":["'use client';\n\nimport { mergeProps, useFocusRing, useHover, usePress, type PressEvents } from 'react-aria';\nimport {\n useEffect,\n useState,\n type DOMAttributes,\n type KeyboardEvent,\n type PointerEvent,\n type RefObject,\n} from 'react';\n\nexport interface M3InteractionOptions extends PressEvents {\n isDisabled?: boolean;\n isSelected?: boolean;\n isDragged?: boolean;\n /**\n * Pressed state from another React Aria hook (e.g. `useButton`). When provided,\n * this hook does not attach its own press handling.\n */\n isPressed?: boolean;\n /** Treat focus inside the element as focus on the element (e.g. text fields). */\n within?: boolean;\n /** Whether the element is a text input; focus is then always visible. */\n isTextInput?: boolean;\n autoFocus?: boolean;\n}\n\nexport interface M3InteractionState {\n isHovered: boolean;\n isPressed: boolean;\n isFocused: boolean;\n isFocusVisible: boolean;\n}\n\n/** `data-*` attributes read by the `state-layer` and `focus-ring` utilities. */\nexport interface M3InteractionDataAttributes {\n 'data-hovered'?: true;\n 'data-pressed'?: true;\n /** The ripple is showing: from press start until release, but at least 225ms. */\n 'data-rippling'?: true;\n 'data-focused'?: true;\n 'data-focus-visible'?: true;\n 'data-disabled'?: true;\n 'data-selected'?: true;\n 'data-dragged'?: true;\n}\n\nexport interface M3InteractionResult {\n /** Event handlers to spread on the interactive element. */\n interactionProps: DOMAttributes<HTMLElement>;\n dataAttributes: M3InteractionDataAttributes;\n state: M3InteractionState;\n}\n\nconst flag = (value: boolean | undefined): true | undefined => (value ? true : undefined);\n\n/** Compose `RippleAnimation`: the radius grows (and the centre travels) over 225ms. */\nexport const RIPPLE_GROW_MS = 225;\n\n/** The ripple's animated properties, pinned at the start of a new ripple. */\nconst RIPPLE_START = {\n '--m3-ripple-opacity': '0',\n '--m3-ripple-radius': 'var(--m3-ripple-start, 0px)',\n '--m3-ripple-x': 'var(--m3-ripple-origin-x, 50%)',\n '--m3-ripple-y': 'var(--m3-ripple-origin-y, 50%)',\n} as const;\n\n/**\n * Starts a fresh ripple on `element`, as Compose does for every press, even while the last\n * one is still growing or fading. The ripple's animated properties are pinned to their start\n * values with their transitions off and flushed to style, then released: they transition\n * from this press's start to whatever the state layer's rules say (growing if\n * `data-rippling` is on, or once it turns on). They're pinned with no duration or delay, not by\n * leaving them out of `transition-property`: a running transition whose property drops out of\n * the list is cancelled and jumps to its end, as did a corner morph on a quick second press\n * and a width an app animates through `className` (2026-11-10). A running transition keeps its\n * own timing when the durations change, so nothing else is touched.\n */\nexport function restartRipple(element: HTMLElement) {\n const { style } = element;\n const { transitionDuration, transitionDelay } = style;\n style.transitionDuration = '0s';\n style.transitionDelay = '0s';\n for (const [name, value] of Object.entries(RIPPLE_START)) style.setProperty(name, value);\n getComputedStyle(element).getPropertyValue('--m3-ripple-x');\n for (const name of Object.keys(RIPPLE_START)) style.removeProperty(name);\n style.transitionDuration = transitionDuration;\n style.transitionDelay = transitionDelay;\n}\n\n/**\n * Positions a new ripple at the press point (Compose `RippleAnimation`): it grows from 30%\n * of the element's longer side to half its diagonal plus 10px while its centre moves to the\n * middle. Without a point (a key press) it starts in the middle. For a state layer on a\n * child of the pressed element (a navigation item's pill), pass that child.\n */\nexport function setRippleOrigin(element: HTMLElement, clientX?: number, clientY?: number) {\n const rect = element.getBoundingClientRect();\n const x = clientX === undefined ? rect.width / 2 : clientX - rect.left;\n const y = clientY === undefined ? rect.height / 2 : clientY - rect.top;\n const { style } = element;\n style.setProperty('--m3-ripple-origin-x', `${x}px`);\n style.setProperty('--m3-ripple-origin-y', `${y}px`);\n style.setProperty('--m3-ripple-center-x', `${rect.width / 2}px`);\n style.setProperty('--m3-ripple-center-y', `${rect.height / 2}px`);\n style.setProperty('--m3-ripple-start', `${Math.max(rect.width, rect.height) * 0.3}px`);\n style.setProperty(\n '--m3-ripple-size',\n `${Math.ceil(Math.hypot(rect.width, rect.height) / 2 + 10)}px`,\n );\n restartRipple(element);\n}\n\n/**\n * Flags a press that starts while the element's corner morph is still running\n * (`data-rapid-press`). M3's buttons note that the web can use \"a modified motion curve to\n * avoid resonant effects from overlapping animations\": the `container-motion` utility then\n * morphs on the fast effects spring, which doesn't overshoot, instead of the fast spatial\n * one. The attribute is set on the element directly, before React renders the press, so\n * the morph that press starts already uses the modified curve. Call it before anything\n * that resets the element's transitions (such as `restartRipple`).\n */\nexport function markRapidPress(element: HTMLElement) {\n const morphing =\n typeof element.getAnimations === 'function' &&\n element\n .getAnimations()\n .some(\n (animation) =>\n animation instanceof CSSTransition &&\n animation.transitionProperty.endsWith('radius') &&\n animation.playState === 'running',\n );\n element.toggleAttribute('data-rapid-press', morphing);\n}\n\n/**\n * Whether a ripple should be showing. Compose always finishes a ripple's 225ms growth\n * before fading it out, so a quick tap still reaches the edges: this stays true from press\n * start until release, but for at least 225ms.\n */\nexport function useRippleHold(isPressed: boolean): boolean {\n const [wasPressed, setWasPressed] = useState(isPressed);\n const [held, setHeld] = useState(false);\n const [presses, setPresses] = useState(0);\n // Adjust state while rendering when a press starts (no effect, no extra paint).\n if (isPressed !== wasPressed) {\n setWasPressed(isPressed);\n if (isPressed) {\n setHeld(true);\n setPresses((n) => n + 1);\n }\n }\n useEffect(() => {\n if (!held) return;\n const timer = setTimeout(() => setHeld(false), RIPPLE_GROW_MS);\n return () => clearTimeout(timer);\n }, [held, presses]);\n return isPressed || held;\n}\n\n/**\n * M3 interaction states for any element: hover, press, focus-visible, selected,\n * dragged and disabled, exposed as `data-*` attributes, plus the ripple origin.\n * Pair with the `state-layer` and `focus-ring` utilities, which paint the state\n * layer and ripple as background layers on the element itself (no child nodes).\n */\nexport function useM3Interaction(\n options: M3InteractionOptions,\n ref: RefObject<HTMLElement | null>,\n): M3InteractionResult {\n const {\n isDisabled,\n isSelected,\n isDragged,\n within,\n isTextInput,\n autoFocus,\n onPress,\n onPressStart,\n onPressEnd,\n onPressChange,\n onPressUp,\n onClick,\n } = options;\n const hasExternalPress = options.isPressed !== undefined;\n\n // Only `usePress`'s own options: it spreads any others onto the props it returns, so this\n // hook's options (`isDragged`, `within` …) would reach the DOM as unknown attributes.\n const { pressProps, isPressed: isOwnPressed } = usePress({\n onPress,\n onPressStart,\n onPressEnd,\n onPressChange,\n onPressUp,\n onClick,\n ref,\n isDisabled: isDisabled || hasExternalPress,\n });\n const { hoverProps, isHovered } = useHover({ isDisabled });\n const { focusProps, isFocused, isFocusVisible } = useFocusRing({\n within,\n isTextInput,\n autoFocus,\n });\n\n const isPressed = hasExternalPress ? Boolean(options.isPressed) : isOwnPressed;\n const isRippling = useRippleHold(isPressed && !isDisabled);\n\n const rippleProps: DOMAttributes<HTMLElement> = {\n onPointerDown: (event: PointerEvent<HTMLElement>) => {\n if (!isDisabled && event.button === 0) {\n markRapidPress(event.currentTarget);\n setRippleOrigin(event.currentTarget, event.clientX, event.clientY);\n }\n },\n onKeyDown: (event: KeyboardEvent<HTMLElement>) => {\n if (!isDisabled && (event.key === 'Enter' || event.key === ' ')) {\n markRapidPress(event.currentTarget);\n setRippleOrigin(event.currentTarget);\n }\n },\n };\n\n return {\n interactionProps: mergeProps(\n hasExternalPress ? {} : pressProps,\n hoverProps,\n focusProps,\n rippleProps,\n ),\n dataAttributes: {\n 'data-hovered': flag(isHovered && !isDisabled),\n 'data-pressed': flag(isPressed && !isDisabled),\n 'data-rippling': flag(isRippling),\n 'data-focused': flag(isFocused),\n 'data-focus-visible': flag(isFocusVisible),\n 'data-disabled': flag(isDisabled),\n 'data-selected': flag(isSelected),\n 'data-dragged': flag(isDragged),\n },\n state: { isHovered, isPressed, isFocused, isFocusVisible },\n };\n}\n"],"mappings":"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"}
|
package/dist/primitives.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ThemeScopeContext } from "./theme/context.js";
|
|
2
|
+
import { DescriptionAria, RootDOMProps, SplitRootProps, SplitRootPropsOptions, WidgetAria, WrapperRootDOMProps, pickDescriptionAria, pickWidgetAria, splitRootProps } from "./utils/root-props.js";
|
|
3
|
+
import { ButtonBase, ButtonBaseActionProps, ButtonBaseDivActionProps, ButtonBaseLinkProps, ButtonBasePendingProps, ButtonBaseProps, ButtonBaseRenderState, ButtonBaseToggleProps } from "./primitives/ButtonBase.js";
|
|
4
|
+
import { closedByOverlayOptions } from "./utils/closed-by.js";
|
|
2
5
|
import { getM3Spring } from "./motion/get-m3-spring.js";
|
|
3
6
|
import { useM3Spring } from "./motion/use-m3-spring.js";
|
|
4
|
-
import { ButtonBase, ButtonBaseActionProps, ButtonBaseDivActionProps, ButtonBaseLinkProps, ButtonBasePendingProps, ButtonBaseProps, ButtonBaseRenderState, ButtonBaseToggleProps } from "./primitives/ButtonBase.js";
|
|
5
|
-
import { DescriptionAria, RootDOMProps, SplitRootProps, SplitRootPropsOptions, WidgetAria, WrapperRootDOMProps, pickDescriptionAria, pickWidgetAria, splitRootProps } from "./utils/root-props.js";
|
|
6
7
|
import { CornerRounding } from "./shapes/corner-rounding.js";
|
|
7
8
|
import { PointTransformer } from "./shapes/point.js";
|
|
8
9
|
import { Cubic } from "./shapes/cubic.js";
|
|
@@ -13,7 +14,6 @@ import { MaterialShapes } from "./shapes/material-shapes.js";
|
|
|
13
14
|
import { Morph } from "./shapes/morph.js";
|
|
14
15
|
import { M3MorphOptions, MorphShape, getMorph, morphPathAt } from "./primitives/morph-path.js";
|
|
15
16
|
import { SelectionControl, SelectionControlClassNames, SelectionControlProps } from "./primitives/SelectionControl.js";
|
|
16
|
-
import { closedByOverlayOptions } from "./utils/closed-by.js";
|
|
17
17
|
import { M3InteractionDataAttributes, M3InteractionOptions, M3InteractionResult, M3InteractionState, useM3Interaction } from "./primitives/use-m3-interaction.js";
|
|
18
18
|
import { Surface, SurfaceProps, SurfaceVariants, surfaceStyles } from "./primitives/Surface.js";
|
|
19
19
|
import { Overlay, OverlayProps } from "./primitives/Overlay.js";
|
|
@@ -29,6 +29,9 @@ import { DomDirectionLocale, DomDirectionLocaleProps } from "./primitives/DomDir
|
|
|
29
29
|
import { localeWithDirection } from "./primitives/locale-with-direction.js";
|
|
30
30
|
import { useM3Morph } from "./primitives/use-m3-morph.js";
|
|
31
31
|
import { KeepPressedInPlaceResult, useKeepPressedInPlace } from "./utils/keep-pressed-in-place.js";
|
|
32
|
+
import { ScrollKeysResult, useScrollKeys } from "./utils/use-scroll-keys.js";
|
|
33
|
+
import { ScrollRestorationOptions, useScrollRestoration } from "./utils/use-scroll-restoration.js";
|
|
34
|
+
import { LabelsKey, LabelsOf, useLabels } from "./components/labels/use-labels.js";
|
|
32
35
|
import { mergeDataTokens } from "./utils/merge-data-tokens.js";
|
|
33
36
|
import { splitDataAttributes } from "./utils/split-data-attributes.js";
|
|
34
37
|
import { generateSchemeColors } from "./theme/scheme.js";
|
|
@@ -36,4 +39,4 @@ import { materialShapeMask } from "./shapes/mask.js";
|
|
|
36
39
|
import { materialShapePaths } from "./shapes/generated/material-shape-path-record.js";
|
|
37
40
|
import { MorphPathOptions, PathOptions, cubicsToPath, morphToPath, polygonToPath } from "./shapes/path.js";
|
|
38
41
|
import { circle, pill, pillStar, rectangle, star } from "./shapes/shapes.js";
|
|
39
|
-
export { ButtonBase, type ButtonBaseActionProps, type ButtonBaseDivActionProps, type ButtonBaseLinkProps, type ButtonBasePendingProps, type ButtonBaseProps, type ButtonBaseRenderState, type ButtonBaseToggleProps, CharacterCounter, type CharacterCounterProps, CornerRounding, Cubic, type DescriptionAria, DomDirectionLocale, type DomDirectionLocaleProps, ErrorText, type ErrorTextProps, FieldErrorIcon, type FieldErrorIconProps, FieldLabel, type FieldLabelProps, type KeepPressedInPlaceResult, type M3InteractionDataAttributes, type M3InteractionOptions, type M3InteractionResult, type M3InteractionState, type M3MorphOptions, MaterialShapeName, type MaterialShapePath, MaterialShapes, Morph, type MorphPathOptions, type MorphShape, Overlay, type OverlayProps, type PathOptions, type PointTransformer, type RootDOMProps, RoundedPolygon, SelectionControl, type SelectionControlClassNames, type SelectionControlProps, type SplitRootProps, type SplitRootPropsOptions, SupportingText, type SupportingTextProps, Surface, type SurfaceProps, type SurfaceVariants, ThemeScopeContext, TouchTarget, type TouchTargetProps, TriggerContext, type TriggerContextValue, type WidgetAria, type WrapperRootDOMProps, archShape, arrowShape, boomShape, bunShape, burstShape, circle, circleShape, clamShellShape, closedByOverlayOptions, clover4LeafShape, clover8LeafShape, cookie12SidedShape, cookie4SidedShape, cookie6SidedShape, cookie7SidedShape, cookie9SidedShape, cubicsToPath, diamondShape, fanShape, flowerShape, gemShape, generateSchemeColors, getM3Spring, getMorph, ghostishShape, heartShape, localeWithDirection, materialShapeMask, materialShapeNames, materialShapePaths, mergeDataTokens, morphPathAt, morphToPath, ovalShape, pentagonShape, pickDescriptionAria, pickWidgetAria, pill, pillShape, pillStar, pixelCircleShape, pixelTriangleShape, polygonToPath, puffyDiamondShape, puffyShape, rectangle, selectionControlStyles, semiCircleShape, slantedShape, softBoomShape, softBurstShape, splitDataAttributes, splitRootProps, springProgressWithVelocity, springWithVelocityToLinearEasing, squareShape, star, sunnyShape, surfaceStyles, toAriaPlacement, triangleShape, useKeepPressedInPlace, useM3Interaction, useM3Morph, useM3Spring, usePresence, useRevealEntering, useTriggerProps, verySunnyShape };
|
|
42
|
+
export { ButtonBase, type ButtonBaseActionProps, type ButtonBaseDivActionProps, type ButtonBaseLinkProps, type ButtonBasePendingProps, type ButtonBaseProps, type ButtonBaseRenderState, type ButtonBaseToggleProps, CharacterCounter, type CharacterCounterProps, CornerRounding, Cubic, type DescriptionAria, DomDirectionLocale, type DomDirectionLocaleProps, ErrorText, type ErrorTextProps, FieldErrorIcon, type FieldErrorIconProps, FieldLabel, type FieldLabelProps, type KeepPressedInPlaceResult, type LabelsKey, type LabelsOf, type M3InteractionDataAttributes, type M3InteractionOptions, type M3InteractionResult, type M3InteractionState, type M3MorphOptions, MaterialShapeName, type MaterialShapePath, MaterialShapes, Morph, type MorphPathOptions, type MorphShape, Overlay, type OverlayProps, type PathOptions, type PointTransformer, type RootDOMProps, RoundedPolygon, type ScrollKeysResult, type ScrollRestorationOptions, SelectionControl, type SelectionControlClassNames, type SelectionControlProps, type SplitRootProps, type SplitRootPropsOptions, SupportingText, type SupportingTextProps, Surface, type SurfaceProps, type SurfaceVariants, ThemeScopeContext, TouchTarget, type TouchTargetProps, TriggerContext, type TriggerContextValue, type WidgetAria, type WrapperRootDOMProps, archShape, arrowShape, boomShape, bunShape, burstShape, circle, circleShape, clamShellShape, closedByOverlayOptions, clover4LeafShape, clover8LeafShape, cookie12SidedShape, cookie4SidedShape, cookie6SidedShape, cookie7SidedShape, cookie9SidedShape, cubicsToPath, diamondShape, fanShape, flowerShape, gemShape, generateSchemeColors, getM3Spring, getMorph, ghostishShape, heartShape, localeWithDirection, materialShapeMask, materialShapeNames, materialShapePaths, mergeDataTokens, morphPathAt, morphToPath, ovalShape, pentagonShape, pickDescriptionAria, pickWidgetAria, pill, pillShape, pillStar, pixelCircleShape, pixelTriangleShape, polygonToPath, puffyDiamondShape, puffyShape, rectangle, selectionControlStyles, semiCircleShape, slantedShape, softBoomShape, softBurstShape, splitDataAttributes, splitRootProps, springProgressWithVelocity, springWithVelocityToLinearEasing, squareShape, star, sunnyShape, surfaceStyles, toAriaPlacement, triangleShape, useKeepPressedInPlace, useLabels, useM3Interaction, useM3Morph, useM3Spring, usePresence, useRevealEntering, useScrollKeys, useScrollRestoration, useTriggerProps, verySunnyShape };
|
package/dist/primitives.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ThemeScopeContext } from "./theme/context.js";
|
|
2
2
|
import { generateSchemeColors } from "./theme/scheme.js";
|
|
3
|
+
import { useLabels } from "./components/labels/use-labels.js";
|
|
3
4
|
import { getM3Spring } from "./motion/get-m3-spring.js";
|
|
4
5
|
import { useM3Spring } from "./motion/use-m3-spring.js";
|
|
5
6
|
import { TriggerContext, useTriggerProps } from "./primitives/TriggerContext.js";
|
|
@@ -30,8 +31,10 @@ import { useKeepPressedInPlace } from "./utils/keep-pressed-in-place.js";
|
|
|
30
31
|
import { springProgressWithVelocity, springWithVelocityToLinearEasing } from "./tokens/spring-velocity.js";
|
|
31
32
|
import { Surface, surfaceStyles } from "./primitives/Surface.js";
|
|
32
33
|
import { useM3Morph } from "./primitives/use-m3-morph.js";
|
|
34
|
+
import { useScrollKeys } from "./utils/use-scroll-keys.js";
|
|
35
|
+
import { useScrollRestoration } from "./utils/use-scroll-restoration.js";
|
|
33
36
|
import { splitDataAttributes } from "./utils/split-data-attributes.js";
|
|
34
37
|
import { materialShapeMask } from "./shapes/mask.js";
|
|
35
38
|
import { archShape, arrowShape, boomShape, bunShape, burstShape, circleShape, clamShellShape, clover4LeafShape, clover8LeafShape, cookie12SidedShape, cookie4SidedShape, cookie6SidedShape, cookie7SidedShape, cookie9SidedShape, diamondShape, fanShape, flowerShape, gemShape, ghostishShape, heartShape, materialShapeNames, ovalShape, pentagonShape, pillShape, pixelCircleShape, pixelTriangleShape, puffyDiamondShape, puffyShape, semiCircleShape, slantedShape, softBoomShape, softBurstShape, squareShape, sunnyShape, triangleShape, verySunnyShape } from "./shapes/generated/material-shape-paths.js";
|
|
36
39
|
import { materialShapePaths } from "./shapes/generated/material-shape-path-record.js";
|
|
37
|
-
export { ButtonBase, CharacterCounter, CornerRounding, Cubic, DomDirectionLocale, ErrorText, FieldErrorIcon, FieldLabel, MaterialShapes, Morph, Overlay, RoundedPolygon, SelectionControl, SupportingText, Surface, ThemeScopeContext, TouchTarget, TriggerContext, archShape, arrowShape, boomShape, bunShape, burstShape, circle, circleShape, clamShellShape, closedByOverlayOptions, clover4LeafShape, clover8LeafShape, cookie12SidedShape, cookie4SidedShape, cookie6SidedShape, cookie7SidedShape, cookie9SidedShape, cubicsToPath, diamondShape, fanShape, flowerShape, gemShape, generateSchemeColors, getM3Spring, getMorph, ghostishShape, heartShape, localeWithDirection, materialShapeMask, materialShapeNames, materialShapePaths, mergeDataTokens, morphPathAt, morphToPath, ovalShape, pentagonShape, pickDescriptionAria, pickWidgetAria, pill, pillShape, pillStar, pixelCircleShape, pixelTriangleShape, polygonToPath, puffyDiamondShape, puffyShape, rectangle, selectionControlStyles, semiCircleShape, slantedShape, softBoomShape, softBurstShape, splitDataAttributes, splitRootProps, springProgressWithVelocity, springWithVelocityToLinearEasing, squareShape, star, sunnyShape, surfaceStyles, toAriaPlacement, triangleShape, useKeepPressedInPlace, useM3Interaction, useM3Morph, useM3Spring, usePresence, useRevealEntering, useTriggerProps, verySunnyShape };
|
|
40
|
+
export { ButtonBase, CharacterCounter, CornerRounding, Cubic, DomDirectionLocale, ErrorText, FieldErrorIcon, FieldLabel, MaterialShapes, Morph, Overlay, RoundedPolygon, SelectionControl, SupportingText, Surface, ThemeScopeContext, TouchTarget, TriggerContext, archShape, arrowShape, boomShape, bunShape, burstShape, circle, circleShape, clamShellShape, closedByOverlayOptions, clover4LeafShape, clover8LeafShape, cookie12SidedShape, cookie4SidedShape, cookie6SidedShape, cookie7SidedShape, cookie9SidedShape, cubicsToPath, diamondShape, fanShape, flowerShape, gemShape, generateSchemeColors, getM3Spring, getMorph, ghostishShape, heartShape, localeWithDirection, materialShapeMask, materialShapeNames, materialShapePaths, mergeDataTokens, morphPathAt, morphToPath, ovalShape, pentagonShape, pickDescriptionAria, pickWidgetAria, pill, pillShape, pillStar, pixelCircleShape, pixelTriangleShape, polygonToPath, puffyDiamondShape, puffyShape, rectangle, selectionControlStyles, semiCircleShape, slantedShape, softBoomShape, softBurstShape, splitDataAttributes, splitRootProps, springProgressWithVelocity, springWithVelocityToLinearEasing, squareShape, star, sunnyShape, surfaceStyles, toAriaPlacement, triangleShape, useKeepPressedInPlace, useLabels, useM3Interaction, useM3Morph, useM3Spring, usePresence, useRevealEntering, useScrollKeys, useScrollRestoration, useTriggerProps, verySunnyShape };
|
|
@@ -147,18 +147,30 @@
|
|
|
147
147
|
transparent
|
|
148
148
|
)
|
|
149
149
|
);
|
|
150
|
-
/*
|
|
150
|
+
/*
|
|
151
|
+
* After the ripple: fade it out, then reset its radius and centre once it is invisible. The
|
|
152
|
+
* states below change only these variables, never the transition itself, so an app's own
|
|
153
|
+
* transition through `className` (one class, which wins over this one at rest) keeps its
|
|
154
|
+
* timing while the element is pressed too (2026-11-10).
|
|
155
|
+
*/
|
|
156
|
+
--m3-ripple-fade-duration: 150ms;
|
|
157
|
+
--m3-ripple-grow-duration: 0s;
|
|
158
|
+
--m3-ripple-grow-delay: 150ms;
|
|
159
|
+
--m3-ripple-grow-easing: linear;
|
|
151
160
|
/* Components append their own transitions through the --m3-transition-* lists. */
|
|
152
161
|
transition-property:
|
|
153
162
|
--m3-state-opacity, --m3-ripple-opacity, --m3-ripple-radius, --m3-ripple-x, --m3-ripple-y,
|
|
154
163
|
var(--m3-transition-property, --m3-none);
|
|
155
164
|
transition-duration:
|
|
156
|
-
var(--md-sys-motion-spring-effects-fast-duration),
|
|
165
|
+
var(--md-sys-motion-spring-effects-fast-duration), var(--m3-ripple-fade-duration),
|
|
166
|
+
var(--m3-ripple-grow-duration), var(--m3-ripple-grow-duration), var(--m3-ripple-grow-duration),
|
|
157
167
|
var(--m3-transition-duration, 0s);
|
|
158
|
-
transition-delay:
|
|
168
|
+
transition-delay:
|
|
169
|
+
0s, 0s, var(--m3-ripple-grow-delay), var(--m3-ripple-grow-delay), var(--m3-ripple-grow-delay),
|
|
170
|
+
var(--m3-transition-delay, 0s);
|
|
159
171
|
transition-timing-function:
|
|
160
|
-
var(--md-sys-motion-spring-effects-fast-easing), linear,
|
|
161
|
-
var(--m3-transition-easing, linear);
|
|
172
|
+
var(--md-sys-motion-spring-effects-fast-easing), linear, var(--m3-ripple-grow-easing), linear,
|
|
173
|
+
linear, var(--m3-transition-easing, linear);
|
|
162
174
|
|
|
163
175
|
&[data-hovered] {
|
|
164
176
|
--m3-state-opacity: var(--md-sys-state-hover-state-layer-opacity);
|
|
@@ -181,13 +193,10 @@
|
|
|
181
193
|
--m3-ripple-radius: var(--m3-ripple-size, 0px);
|
|
182
194
|
--m3-ripple-x: var(--m3-ripple-center-x, 50%);
|
|
183
195
|
--m3-ripple-y: var(--m3-ripple-center-y, 50%);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
transition-timing-function:
|
|
189
|
-
var(--md-sys-motion-spring-effects-fast-easing), linear, cubic-bezier(0.4, 0, 0.2, 1), linear,
|
|
190
|
-
linear, var(--m3-transition-easing, linear);
|
|
196
|
+
--m3-ripple-fade-duration: 75ms;
|
|
197
|
+
--m3-ripple-grow-duration: 225ms;
|
|
198
|
+
--m3-ripple-grow-delay: 0s;
|
|
199
|
+
--m3-ripple-grow-easing: cubic-bezier(0.4, 0, 0.2, 1);
|
|
191
200
|
}
|
|
192
201
|
&[data-disabled] {
|
|
193
202
|
--m3-state-opacity: 0;
|
|
@@ -197,9 +206,7 @@
|
|
|
197
206
|
/* Reduced motion: the ripple appears at full size where it ends, with no growth or travel. */
|
|
198
207
|
@media (prefers-reduced-motion: reduce) {
|
|
199
208
|
&[data-rippling] {
|
|
200
|
-
|
|
201
|
-
var(--md-sys-motion-spring-effects-fast-duration), 75ms, 0s, 0s, 0s,
|
|
202
|
-
var(--m3-transition-duration, 0s);
|
|
209
|
+
--m3-ripple-grow-duration: 0s;
|
|
203
210
|
}
|
|
204
211
|
}
|
|
205
212
|
}
|