@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chip.js","names":[],"sources":["../../../src/components/chip/Chip.tsx"],"sourcesContent":["'use client';\n\nimport {\n useContext,\n useId,\n type CSSProperties,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { VisuallyHidden } from 'react-aria';\nimport { useToggleState } from 'react-stately';\nimport {\n ButtonBase,\n ToggleGroupStateContext,\n type ButtonBaseActionProps,\n type ButtonBaseLinkProps,\n type ButtonBaseToggleProps,\n} from '../../primitives/ButtonBase';\nimport { TouchTarget } from '../../primitives/TouchTarget';\nimport { densityAttribute, type Density } from '../../tokens/density';\nimport { cn } from '../../utils/cn';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport { chipStyles, type ChipOutline } from './chip-styles';\n\n/** Material Symbols \"check\" and \"close\" (Apache-2.0). */\nfunction CheckIcon() {\n return (\n <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\">\n <path d=\"M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z\" />\n </svg>\n );\n}\n\nfunction CloseIcon() {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\n <path d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n );\n}\n\nexport interface ChipClassNames {\n /** The chip's container, merged with `className`. */\n root?: string;\n /** The row holding the leading icon, label and trailing icon. */\n content?: string;\n /** The leading icon or avatar slot. */\n leading?: string;\n /** The label text. */\n label?: string;\n /** The trailing icon slot. */\n trailing?: string;\n}\n\nexport interface ChipLabels {\n /** First word of the remove button's name, which ends with the label. @default \"Remove\" */\n remove: string;\n /**\n * Announces a selected `InputChip` that has no `onPress` (with one, its action carries\n * `aria-pressed`): the remove button's description, or hidden text on a static chip.\n * @default \"Selected\"\n */\n selected: string;\n}\n\nconst DEFAULT_LABELS: ChipLabels = { remove: 'Remove', selected: 'Selected' };\n\ninterface ChipCommonProps {\n /** The label. */\n children: ReactNode;\n /** Icon before the label (18px). Hidden from assistive tech. */\n leadingIcon?: ReactElement;\n /**\n * The flat chip's border: `outline-variant`, or `strong` (`outline`) for 3:1 contrast\n * where nothing else shows the chip is interactive. @default \"standard\"\n */\n outline?: ChipOutline;\n /**\n * Web density, `0` to `-3`: each step takes 4px off the chip's height (32px at 0, 24px at -2\n * and -3); its touch target stays 48px. Left out, the chip takes the density of the nearest\n * `ChipSet`, `ThemeProvider` or `ThemeScope`. M3 asks for density to be the reader's choice\n * rather than a default, so prefer setting it there, from a setting.\n * @default 0\n */\n density?: Density;\n /** Classes for each part, by slot. */\n classNames?: ChipClassNames;\n}\n\ntype Styles = ReturnType<typeof chipStyles>;\n\nfunction ChipContent({\n styles,\n classNames,\n leading,\n children,\n trailing,\n labelId,\n}: {\n styles: Styles;\n classNames?: ChipClassNames;\n leading?: ReactNode;\n children: ReactNode;\n trailing?: ReactNode;\n labelId?: string;\n}) {\n return (\n <span className={styles.content({ class: classNames?.content })}>\n <TouchTarget />\n {leading}\n <span id={labelId} className={styles.label({ class: classNames?.label })}>\n {children}\n </span>\n {trailing}\n </span>\n );\n}\n\n/**\n * The component tokens' hooks (chip-tokens.ts): each kind's set, followed by any set the app\n * passed on the same element (`props`), and whether the chip is elevated, which picks its\n * elevated container token; and the chip's own density, if set.\n */\nconst tokenAttributes = (\n kind: 'assist' | 'suggestion' | 'filter' | 'input',\n elevated: boolean | undefined,\n density: Density | undefined,\n props?: object,\n) => ({\n 'data-tokens': mergeDataTokens(`md-comp-${kind}-chip`, props),\n 'data-elevated': elevated || undefined,\n ...densityAttribute(density),\n});\n\nconst leadingIconOf = (styles: Styles, icon: ReactElement | undefined, className?: string) =>\n icon && (\n <span aria-hidden=\"true\" data-slot=\"leading\" className={styles.leading({ class: className })}>\n {icon}\n </span>\n );\n\nconst trailingIconOf = (styles: Styles, icon: ReactElement | undefined, className?: string) =>\n icon && (\n <span aria-hidden=\"true\" className={styles.trailing({ class: className })}>\n {icon}\n </span>\n );\n\n/** Backspace or Delete on a removable chip removes it (M3 chips, keyboard navigation). */\nconst removeKeys =\n (onRemove: (() => void) | undefined, disabled: boolean | undefined) =>\n (event: KeyboardEvent<HTMLElement>) => {\n if (onRemove && !disabled && (event.key === 'Backspace' || event.key === 'Delete')) {\n event.preventDefault();\n onRemove();\n }\n };\n\n/** The remove button: named \"Remove\" + the chip's label, with a 48px target. */\nfunction RemoveButton({\n styles,\n className,\n labelId,\n labels,\n onRemove,\n disabled,\n describedBy,\n}: {\n styles: Styles;\n className?: string;\n labelId: string;\n labels?: Partial<ChipLabels>;\n onRemove: () => void;\n disabled?: boolean;\n /** An element describing the chip's state (a selected input chip without an action). */\n describedBy?: string;\n}) {\n const removeId = useId();\n const { remove } = { ...DEFAULT_LABELS, ...labels };\n return (\n <ButtonBase\n disabled={disabled}\n onPress={onRemove}\n onKeyDown={removeKeys(onRemove, disabled)}\n aria-labelledby={`${removeId} ${labelId}`}\n aria-describedby={describedBy}\n data-chip-remove=\"\"\n className={styles.remove({ class: className })}\n >\n <TouchTarget />\n <span id={removeId} hidden>\n {remove}\n </span>\n <CloseIcon />\n </ButtonBase>\n );\n}\n\n/* ------------------------------------------------------------------ Assist */\n\ninterface AssistChipOwnProps extends ChipCommonProps {\n /** `surface-container-low` at level 1 instead of an outline. @default false */\n elevated?: boolean;\n}\n\ntype OmitChip<T> = Omit<T, keyof AssistChipOwnProps | 'toggle'>;\n\nexport type AssistChipProps = AssistChipOwnProps &\n (OmitChip<ButtonBaseActionProps> | OmitChip<ButtonBaseLinkProps>);\n\n/**\n * M3 assist chip: a smart or automated action that can span apps, such as opening a calendar\n * event. A button, or a link with `href`. Assist chips have no trailing icon.\n *\n * @example\n * <AssistChip leadingIcon={<EventIcon />} onPress={addToCalendar}>Add to calendar</AssistChip>\n */\nexport function AssistChip({\n children,\n leadingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n ...base\n}: AssistChipProps) {\n const styles = chipStyles({\n kind: 'assist',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n });\n return (\n <ButtonBase\n {...(base as ButtonBaseActionProps)}\n {...tokenAttributes('assist', elevated, density, base)}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n leading={leadingIconOf(styles, leadingIcon, classNames?.leading)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n );\n}\n\n/* -------------------------------------------------------------- Suggestion */\n\ninterface SuggestionChipOwnProps extends ChipCommonProps {\n /** `surface-container-low` at level 1 instead of an outline. @default false */\n elevated?: boolean;\n}\n\nexport type SuggestionChipProps = SuggestionChipOwnProps &\n Omit<ButtonBaseActionProps, keyof SuggestionChipOwnProps | 'toggle'>;\n\n/**\n * M3 suggestion chip: a dynamically generated suggestion, such as a reply. Use an icon\n * sparingly.\n *\n * @example\n * <SuggestionChip onPress={() => reply('Sounds good')}>Sounds good</SuggestionChip>\n */\nexport function SuggestionChip({\n children,\n leadingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n ...base\n}: SuggestionChipProps) {\n const styles = chipStyles({\n kind: 'suggestion',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n });\n return (\n <ButtonBase\n {...base}\n {...tokenAttributes('suggestion', elevated, density, base)}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n leading={leadingIconOf(styles, leadingIcon, classNames?.leading)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n );\n}\n\n/* ------------------------------------------------------------------ Filter */\n\nexport interface FilterChipClassNames extends ChipClassNames {\n /** The toggle of a chip with a remove button. */\n primary?: string;\n /** The remove button after the label. */\n remove?: string;\n}\n\ninterface FilterChipOwnProps extends Omit<ChipCommonProps, 'classNames'> {\n /**\n * Icon after the label, e.g. a dropdown arrow when the chip opens a menu. Hidden from\n * assistive tech; the whole chip is the control. Not with `onRemove`.\n */\n trailingIcon?: ReactElement;\n /**\n * Adds a remove button after the label, a second focus stop named \"Remove\" + the label\n * (M3: for medium and expanded windows). Backspace or Delete on the chip also calls it.\n */\n onRemove?: () => void;\n /** Words the chip announces, with English defaults. */\n labels?: Partial<ChipLabels>;\n /** `surface-container-low` at level 1 instead of an outline. @default false */\n elevated?: boolean;\n /** Classes for each part, by slot. */\n classNames?: FilterChipClassNames;\n}\n\nexport type FilterChipProps = FilterChipOwnProps &\n Omit<ButtonBaseToggleProps, keyof FilterChipOwnProps | 'toggle'>;\n\n/**\n * M3 filter chip: a toggle (`aria-pressed`, or a radio in a single-select `ChipSet`) for\n * filtering content. Without a `leadingIcon` a check grows in when selected. Controlled\n * with `selected` / `onSelectedChange`, uncontrolled with `defaultSelected`, or through a\n * `ChipSet`'s selection with a `value`.\n *\n * @example\n * <FilterChip selected={vegan} onSelectedChange={setVegan}>Vegan</FilterChip>\n */\nexport function FilterChip(props: FilterChipProps) {\n const { onRemove } = props;\n return onRemove ? (\n <RemovableFilterChip {...props} onRemove={onRemove} />\n ) : (\n <SimpleFilterChip {...props} />\n );\n}\n\nfunction filterLeading(styles: Styles, leadingIcon: ReactElement | undefined, className?: string) {\n if (leadingIcon) return leadingIconOf(styles, leadingIcon, className);\n return (\n <span aria-hidden=\"true\" className={styles.check()}>\n <span className={styles.checkInner()}>\n <span className={styles.checkIcon({ class: className })}>\n <CheckIcon />\n </span>\n </span>\n </span>\n );\n}\n\nfunction SimpleFilterChip({\n children,\n leadingIcon,\n trailingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n onRemove: _onRemove,\n labels: _labels,\n ...base\n}: FilterChipProps) {\n const styles = chipStyles({\n kind: 'filter',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n trailing: Boolean(trailingIcon),\n });\n return (\n <ButtonBase\n {...base}\n {...tokenAttributes('filter', elevated, density, base)}\n toggle\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n leading={filterLeading(styles, leadingIcon, classNames?.leading)}\n trailing={trailingIconOf(styles, trailingIcon, classNames?.trailing)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n );\n}\n\n/** A filter chip with a remove button: a container of the toggle and the remove button. */\nfunction RemovableFilterChip({\n children,\n leadingIcon,\n trailingIcon: _trailingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n style,\n onRemove,\n labels,\n selected,\n defaultSelected,\n onSelectedChange,\n value,\n disabled,\n onKeyDown,\n ...base\n}: FilterChipProps & { onRemove: () => void }) {\n const labelId = useId();\n const groupState = useContext(ToggleGroupStateContext);\n const inGroup = groupState != null && value !== undefined;\n const ownState = useToggleState({\n isSelected: selected,\n defaultSelected,\n onChange: onSelectedChange,\n });\n const isSelected = inGroup ? groupState.selectedKeys.has(value) : ownState.isSelected;\n const isDisabled = Boolean(disabled || (inGroup && groupState.isDisabled));\n const styles = chipStyles({\n kind: 'filter',\n split: 'two',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n trailing: true,\n });\n const toggleProps = inGroup\n ? { value }\n : { value, selected: ownState.isSelected, onSelectedChange: ownState.setSelected };\n return (\n <div\n {...tokenAttributes('filter', elevated, density)}\n data-selected={isSelected || undefined}\n data-disabled={isDisabled || undefined}\n style={style}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ButtonBase\n {...base}\n {...toggleProps}\n toggle\n disabled={disabled}\n onKeyDown={(event) => {\n removeKeys(onRemove, isDisabled)(event);\n onKeyDown?.(event);\n }}\n data-chip-primary=\"\"\n className={styles.primary({ class: classNames?.primary })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n labelId={labelId}\n leading={filterLeading(styles, leadingIcon, classNames?.leading)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n <RemoveButton\n styles={styles}\n className={classNames?.remove}\n labelId={labelId}\n labels={labels}\n onRemove={onRemove}\n disabled={isDisabled}\n />\n </div>\n );\n}\n\n/* ------------------------------------------------------------------- Input */\n\nexport interface InputChipClassNames extends ChipClassNames {\n /** The chip's action (a button with `onPress`), or its label part. */\n primary?: string;\n /** The avatar image before the label. */\n avatar?: string;\n /** The remove button after the label. */\n remove?: string;\n}\n\ninterface InputChipOwnProps {\n /** The label. */\n children: ReactNode;\n /** Icon before the label (18px). Hidden from assistive tech. */\n leadingIcon?: ReactElement;\n /** A 24px image before the label, with 12px corners (takes precedence over `leadingIcon`). */\n avatar?: ReactElement;\n /** Shows the chip as selected (`aria-pressed` on its action). */\n selected?: boolean;\n /** The chip's action, e.g. editing the entry. Makes the chip's label part a button. */\n onPress?: ButtonBaseActionProps['onPress'];\n /** Shows a remove button; also called on Backspace or Delete. */\n onRemove?: () => void;\n /** Words the chip announces, with English defaults. */\n labels?: Partial<ChipLabels>;\n /** The flat chip's border. @default \"standard\" */\n outline?: ChipOutline;\n /**\n * Web density, `0` to `-3`: each step takes 4px off the chip's height (32px at 0, 24px at -2\n * and -3); its touch target stays 48px. Left out, the chip takes the density of the nearest\n * `ChipSet`, `ThemeProvider` or `ThemeScope`. M3 asks for density to be the reader's choice\n * rather than a default, so prefer setting it there, from a setting.\n * @default 0\n */\n density?: Density;\n /** Disables the chip's action and its remove button. @default false */\n disabled?: boolean;\n /** Classes for each part, by slot. */\n classNames?: InputChipClassNames;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n}\n\nexport type InputChipProps = InputChipOwnProps &\n Omit<React.ComponentPropsWithRef<'div'>, keyof InputChipOwnProps>;\n\n/**\n * M3 input chip: a discrete piece of information the user entered, such as a recipient.\n * M3 expects input chips to be removable: give it `onRemove` unless the entry is fixed.\n *\n * With `onPress` and `onRemove`, the chip's action and its remove button are two focus\n * stops. With only `onRemove`, the chip is one focus stop (the remove button, named\n * \"Remove\" + the label), as M3 asks. Backspace or Delete on the chip removes it. A chip\n * with a remove button is at least 88px wide, so the button's 48px target never covers\n * the label.\n *\n * @example\n * <InputChip avatar={<img src={photo} alt=\"\" />} onRemove={() => remove(id)}>\n * Alex\n * </InputChip>\n */\nexport function InputChip({\n children,\n leadingIcon,\n avatar,\n selected,\n onPress,\n onRemove,\n labels,\n outline,\n density,\n disabled,\n classNames,\n className,\n ...rest\n}: InputChipProps) {\n const labelId = useId();\n const selectedId = useId();\n const split = onRemove ? (onPress ? 'two' : 'removeOnly') : 'none';\n // Without an action there's no `aria-pressed` to carry the selection, so it's said in words\n // (WCAG 1.3.1): the remove button's description, or hidden text on a static chip.\n const announceSelected = Boolean(selected) && !onPress;\n const selectedWord = { ...DEFAULT_LABELS, ...labels }.selected;\n const styles = chipStyles({\n kind: 'input',\n split,\n outline,\n leading: avatar ? 'avatar' : leadingIcon ? 'icon' : 'none',\n trailing: Boolean(onRemove),\n });\n const leading = avatar ? (\n <span\n aria-hidden=\"true\"\n data-slot=\"leading\"\n className={styles.leading({ class: classNames?.leading })}\n >\n <span className={styles.avatar({ class: classNames?.avatar })}>{avatar}</span>\n </span>\n ) : (\n leadingIconOf(styles, leadingIcon, classNames?.leading)\n );\n const content = (\n <ChipContent styles={styles} classNames={classNames} leading={leading} labelId={labelId}>\n {children}\n </ChipContent>\n );\n\n return (\n <div\n {...rest}\n {...tokenAttributes('input', undefined, density, rest)}\n data-selected={selected || undefined}\n data-disabled={disabled || undefined}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n {onPress ? (\n <ButtonBase\n disabled={disabled}\n onPress={onPress}\n onKeyDown={removeKeys(onRemove, disabled)}\n aria-pressed={selected}\n data-chip-primary=\"\"\n className={styles.primary({ class: classNames?.primary })}\n >\n {content}\n </ButtonBase>\n ) : (\n <span data-chip-primary=\"\" className={styles.primary({ class: classNames?.primary })}>\n {content}\n {announceSelected &&\n (onRemove ? (\n <span id={selectedId} hidden>\n {selectedWord}\n </span>\n ) : (\n <VisuallyHidden>{`, ${selectedWord}`}</VisuallyHidden>\n ))}\n </span>\n )}\n {onRemove && (\n <RemoveButton\n styles={styles}\n className={classNames?.remove}\n labelId={labelId}\n labels={labels}\n onRemove={onRemove}\n disabled={disabled}\n describedBy={announceSelected ? selectedId : undefined}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Chip.js","names":[],"sources":["../../../src/components/chip/Chip.tsx"],"sourcesContent":["'use client';\n\nimport {\n useContext,\n useId,\n type CSSProperties,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { VisuallyHidden } from 'react-aria';\nimport { useToggleState } from 'react-stately';\nimport { useLabels } from '../labels/use-labels';\nimport {\n ButtonBase,\n ToggleGroupStateContext,\n type ButtonBaseActionProps,\n type ButtonBaseLinkProps,\n type ButtonBaseToggleProps,\n} from '../../primitives/ButtonBase';\nimport { TouchTarget } from '../../primitives/TouchTarget';\nimport { densityAttribute, type Density } from '../../tokens/density';\nimport { cn } from '../../utils/cn';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport { chipStyles, type ChipOutline } from './chip-styles';\n\n/** Material Symbols \"check\" and \"close\" (Apache-2.0). */\nfunction CheckIcon() {\n return (\n <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\">\n <path d=\"M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z\" />\n </svg>\n );\n}\n\nfunction CloseIcon() {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\n <path d=\"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z\" />\n </svg>\n );\n}\n\nexport interface ChipClassNames {\n /** The chip's container, merged with `className`. */\n root?: string;\n /** The row holding the leading icon, label and trailing icon. */\n content?: string;\n /** The leading icon or avatar slot. */\n leading?: string;\n /** The label text. */\n label?: string;\n /** The trailing icon slot. */\n trailing?: string;\n}\n\nexport interface ChipLabels {\n /** First word of the remove button's name, which ends with the label. @default \"Remove\" */\n remove: string;\n /**\n * Announces a selected `InputChip` that has no `onPress` (with one, its action carries\n * `aria-pressed`): the remove button's description, or hidden text on a static chip.\n * @default \"Selected\"\n */\n selected: string;\n}\n\nconst DEFAULT_LABELS: ChipLabels = { remove: 'Remove', selected: 'Selected' };\n\ninterface ChipCommonProps {\n /** The label. */\n children: ReactNode;\n /** Icon before the label (18px). Hidden from assistive tech. */\n leadingIcon?: ReactElement;\n /**\n * The flat chip's border: `outline-variant`, or `strong` (`outline`) for 3:1 contrast\n * where nothing else shows the chip is interactive. @default \"standard\"\n */\n outline?: ChipOutline;\n /**\n * Web density, `0` to `-3`: each step takes 4px off the chip's height (32px at 0, 24px at -2\n * and -3); its touch target stays 48px. Left out, the chip takes the density of the nearest\n * `ChipSet`, `ThemeProvider` or `ThemeScope`. M3 asks for density to be the reader's choice\n * rather than a default, so prefer setting it there, from a setting.\n * @default 0\n */\n density?: Density;\n /** Classes for each part, by slot. */\n classNames?: ChipClassNames;\n}\n\ntype Styles = ReturnType<typeof chipStyles>;\n\nfunction ChipContent({\n styles,\n classNames,\n leading,\n children,\n trailing,\n labelId,\n}: {\n styles: Styles;\n classNames?: ChipClassNames;\n leading?: ReactNode;\n children: ReactNode;\n trailing?: ReactNode;\n labelId?: string;\n}) {\n return (\n <span className={styles.content({ class: classNames?.content })}>\n <TouchTarget />\n {leading}\n <span id={labelId} className={styles.label({ class: classNames?.label })}>\n {children}\n </span>\n {trailing}\n </span>\n );\n}\n\n/**\n * The component tokens' hooks (chip-tokens.ts): each kind's set, followed by any set the app\n * passed on the same element (`props`), and whether the chip is elevated, which picks its\n * elevated container token; and the chip's own density, if set.\n */\nconst tokenAttributes = (\n kind: 'assist' | 'suggestion' | 'filter' | 'input',\n elevated: boolean | undefined,\n density: Density | undefined,\n props?: object,\n) => ({\n 'data-tokens': mergeDataTokens(`md-comp-${kind}-chip`, props),\n 'data-elevated': elevated || undefined,\n ...densityAttribute(density),\n});\n\nconst leadingIconOf = (styles: Styles, icon: ReactElement | undefined, className?: string) =>\n icon && (\n <span aria-hidden=\"true\" data-slot=\"leading\" className={styles.leading({ class: className })}>\n {icon}\n </span>\n );\n\nconst trailingIconOf = (styles: Styles, icon: ReactElement | undefined, className?: string) =>\n icon && (\n <span aria-hidden=\"true\" className={styles.trailing({ class: className })}>\n {icon}\n </span>\n );\n\n/** Backspace or Delete on a removable chip removes it (M3 chips, keyboard navigation). */\nconst removeKeys =\n (onRemove: (() => void) | undefined, disabled: boolean | undefined) =>\n (event: KeyboardEvent<HTMLElement>) => {\n if (onRemove && !disabled && (event.key === 'Backspace' || event.key === 'Delete')) {\n event.preventDefault();\n onRemove();\n }\n };\n\n/** The remove button: named \"Remove\" + the chip's label, with a 48px target. */\nfunction RemoveButton({\n styles,\n className,\n labelId,\n labels,\n onRemove,\n disabled,\n describedBy,\n}: {\n styles: Styles;\n className?: string;\n labelId: string;\n labels?: Partial<ChipLabels>;\n onRemove: () => void;\n disabled?: boolean;\n /** An element describing the chip's state (a selected input chip without an action). */\n describedBy?: string;\n}) {\n const removeId = useId();\n const { remove } = useLabels('Chip', DEFAULT_LABELS, labels);\n return (\n <ButtonBase\n disabled={disabled}\n onPress={onRemove}\n onKeyDown={removeKeys(onRemove, disabled)}\n aria-labelledby={`${removeId} ${labelId}`}\n aria-describedby={describedBy}\n data-chip-remove=\"\"\n className={styles.remove({ class: className })}\n >\n <TouchTarget />\n <span id={removeId} hidden>\n {remove}\n </span>\n <CloseIcon />\n </ButtonBase>\n );\n}\n\n/* ------------------------------------------------------------------ Assist */\n\ninterface AssistChipOwnProps extends ChipCommonProps {\n /** `surface-container-low` at level 1 instead of an outline. @default false */\n elevated?: boolean;\n}\n\ntype OmitChip<T> = Omit<T, keyof AssistChipOwnProps | 'toggle'>;\n\nexport type AssistChipProps = AssistChipOwnProps &\n (OmitChip<ButtonBaseActionProps> | OmitChip<ButtonBaseLinkProps>);\n\n/**\n * M3 assist chip: a smart or automated action that can span apps, such as opening a calendar\n * event. A button, or a link with `href`. Assist chips have no trailing icon.\n *\n * @example\n * <AssistChip leadingIcon={<EventIcon />} onPress={addToCalendar}>Add to calendar</AssistChip>\n */\nexport function AssistChip({\n children,\n leadingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n ...base\n}: AssistChipProps) {\n const styles = chipStyles({\n kind: 'assist',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n });\n return (\n <ButtonBase\n {...(base as ButtonBaseActionProps)}\n {...tokenAttributes('assist', elevated, density, base)}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n leading={leadingIconOf(styles, leadingIcon, classNames?.leading)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n );\n}\n\n/* -------------------------------------------------------------- Suggestion */\n\ninterface SuggestionChipOwnProps extends ChipCommonProps {\n /** `surface-container-low` at level 1 instead of an outline. @default false */\n elevated?: boolean;\n}\n\nexport type SuggestionChipProps = SuggestionChipOwnProps &\n Omit<ButtonBaseActionProps, keyof SuggestionChipOwnProps | 'toggle'>;\n\n/**\n * M3 suggestion chip: a dynamically generated suggestion, such as a reply. Use an icon\n * sparingly.\n *\n * @example\n * <SuggestionChip onPress={() => reply('Sounds good')}>Sounds good</SuggestionChip>\n */\nexport function SuggestionChip({\n children,\n leadingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n ...base\n}: SuggestionChipProps) {\n const styles = chipStyles({\n kind: 'suggestion',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n });\n return (\n <ButtonBase\n {...base}\n {...tokenAttributes('suggestion', elevated, density, base)}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n leading={leadingIconOf(styles, leadingIcon, classNames?.leading)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n );\n}\n\n/* ------------------------------------------------------------------ Filter */\n\nexport interface FilterChipClassNames extends ChipClassNames {\n /** The toggle of a chip with a remove button. */\n primary?: string;\n /** The remove button after the label. */\n remove?: string;\n}\n\ninterface FilterChipOwnProps extends Omit<ChipCommonProps, 'classNames'> {\n /**\n * Icon after the label, e.g. a dropdown arrow when the chip opens a menu. Hidden from\n * assistive tech; the whole chip is the control. Not with `onRemove`.\n */\n trailingIcon?: ReactElement;\n /**\n * Adds a remove button after the label, a second focus stop named \"Remove\" + the label\n * (M3: for medium and expanded windows). Backspace or Delete on the chip also calls it.\n */\n onRemove?: () => void;\n /**\n * Words the chip announces, with English defaults. A {@link LabelsProvider} sets them for the\n * whole app.\n */\n labels?: Partial<ChipLabels>;\n /** `surface-container-low` at level 1 instead of an outline. @default false */\n elevated?: boolean;\n /** Classes for each part, by slot. */\n classNames?: FilterChipClassNames;\n}\n\nexport type FilterChipProps = FilterChipOwnProps &\n Omit<ButtonBaseToggleProps, keyof FilterChipOwnProps | 'toggle'>;\n\n/**\n * M3 filter chip: a toggle (`aria-pressed`, or a radio in a single-select `ChipSet`) for\n * filtering content. Without a `leadingIcon` a check grows in when selected. Controlled\n * with `selected` / `onSelectedChange`, uncontrolled with `defaultSelected`, or through a\n * `ChipSet`'s selection with a `value`.\n *\n * @example\n * <FilterChip selected={vegan} onSelectedChange={setVegan}>Vegan</FilterChip>\n */\nexport function FilterChip(props: FilterChipProps) {\n const { onRemove } = props;\n return onRemove ? (\n <RemovableFilterChip {...props} onRemove={onRemove} />\n ) : (\n <SimpleFilterChip {...props} />\n );\n}\n\nfunction filterLeading(styles: Styles, leadingIcon: ReactElement | undefined, className?: string) {\n if (leadingIcon) return leadingIconOf(styles, leadingIcon, className);\n return (\n <span aria-hidden=\"true\" className={styles.check()}>\n <span className={styles.checkInner()}>\n <span className={styles.checkIcon({ class: className })}>\n <CheckIcon />\n </span>\n </span>\n </span>\n );\n}\n\nfunction SimpleFilterChip({\n children,\n leadingIcon,\n trailingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n onRemove: _onRemove,\n labels: _labels,\n ...base\n}: FilterChipProps) {\n const styles = chipStyles({\n kind: 'filter',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n trailing: Boolean(trailingIcon),\n });\n return (\n <ButtonBase\n {...base}\n {...tokenAttributes('filter', elevated, density, base)}\n toggle\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n leading={filterLeading(styles, leadingIcon, classNames?.leading)}\n trailing={trailingIconOf(styles, trailingIcon, classNames?.trailing)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n );\n}\n\n/** A filter chip with a remove button: a container of the toggle and the remove button. */\nfunction RemovableFilterChip({\n children,\n leadingIcon,\n trailingIcon: _trailingIcon,\n elevated,\n outline,\n density,\n classNames,\n className,\n style,\n onRemove,\n labels,\n selected,\n defaultSelected,\n onSelectedChange,\n value,\n disabled,\n onKeyDown,\n ...base\n}: FilterChipProps & { onRemove: () => void }) {\n const labelId = useId();\n const groupState = useContext(ToggleGroupStateContext);\n const inGroup = groupState != null && value !== undefined;\n const ownState = useToggleState({\n isSelected: selected,\n defaultSelected,\n onChange: onSelectedChange,\n });\n const isSelected = inGroup ? groupState.selectedKeys.has(value) : ownState.isSelected;\n const isDisabled = Boolean(disabled || (inGroup && groupState.isDisabled));\n const styles = chipStyles({\n kind: 'filter',\n split: 'two',\n elevated,\n outline,\n leading: leadingIcon ? 'icon' : 'none',\n trailing: true,\n });\n const toggleProps = inGroup\n ? { value }\n : { value, selected: ownState.isSelected, onSelectedChange: ownState.setSelected };\n return (\n <div\n {...tokenAttributes('filter', elevated, density)}\n data-selected={isSelected || undefined}\n data-disabled={isDisabled || undefined}\n style={style}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n <ButtonBase\n {...base}\n {...toggleProps}\n toggle\n disabled={disabled}\n onKeyDown={(event) => {\n removeKeys(onRemove, isDisabled)(event);\n onKeyDown?.(event);\n }}\n data-chip-primary=\"\"\n className={styles.primary({ class: classNames?.primary })}\n >\n <ChipContent\n styles={styles}\n classNames={classNames}\n labelId={labelId}\n leading={filterLeading(styles, leadingIcon, classNames?.leading)}\n >\n {children}\n </ChipContent>\n </ButtonBase>\n <RemoveButton\n styles={styles}\n className={classNames?.remove}\n labelId={labelId}\n labels={labels}\n onRemove={onRemove}\n disabled={isDisabled}\n />\n </div>\n );\n}\n\n/* ------------------------------------------------------------------- Input */\n\nexport interface InputChipClassNames extends ChipClassNames {\n /** The chip's action (a button with `onPress`), or its label part. */\n primary?: string;\n /** The avatar image before the label. */\n avatar?: string;\n /** The remove button after the label. */\n remove?: string;\n}\n\ninterface InputChipOwnProps {\n /** The label. */\n children: ReactNode;\n /** Icon before the label (18px). Hidden from assistive tech. */\n leadingIcon?: ReactElement;\n /** A 24px image before the label, with 12px corners (takes precedence over `leadingIcon`). */\n avatar?: ReactElement;\n /** Shows the chip as selected (`aria-pressed` on its action). */\n selected?: boolean;\n /** The chip's action, e.g. editing the entry. Makes the chip's label part a button. */\n onPress?: ButtonBaseActionProps['onPress'];\n /** Shows a remove button; also called on Backspace or Delete. */\n onRemove?: () => void;\n /**\n * Words the chip announces, with English defaults. A {@link LabelsProvider} sets them for the\n * whole app.\n */\n labels?: Partial<ChipLabels>;\n /** The flat chip's border. @default \"standard\" */\n outline?: ChipOutline;\n /**\n * Web density, `0` to `-3`: each step takes 4px off the chip's height (32px at 0, 24px at -2\n * and -3); its touch target stays 48px. Left out, the chip takes the density of the nearest\n * `ChipSet`, `ThemeProvider` or `ThemeScope`. M3 asks for density to be the reader's choice\n * rather than a default, so prefer setting it there, from a setting.\n * @default 0\n */\n density?: Density;\n /** Disables the chip's action and its remove button. @default false */\n disabled?: boolean;\n /** Classes for each part, by slot. */\n classNames?: InputChipClassNames;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n}\n\nexport type InputChipProps = InputChipOwnProps &\n Omit<React.ComponentPropsWithRef<'div'>, keyof InputChipOwnProps>;\n\n/**\n * M3 input chip: a discrete piece of information the user entered, such as a recipient.\n * M3 expects input chips to be removable: give it `onRemove` unless the entry is fixed.\n *\n * With `onPress` and `onRemove`, the chip's action and its remove button are two focus\n * stops. With only `onRemove`, the chip is one focus stop (the remove button, named\n * \"Remove\" + the label), as M3 asks. Backspace or Delete on the chip removes it. A chip\n * with a remove button is at least 88px wide, so the button's 48px target never covers\n * the label.\n *\n * @example\n * <InputChip avatar={<img src={photo} alt=\"\" />} onRemove={() => remove(id)}>\n * Alex\n * </InputChip>\n */\nexport function InputChip({\n children,\n leadingIcon,\n avatar,\n selected,\n onPress,\n onRemove,\n labels,\n outline,\n density,\n disabled,\n classNames,\n className,\n ...rest\n}: InputChipProps) {\n const labelId = useId();\n const selectedId = useId();\n const split = onRemove ? (onPress ? 'two' : 'removeOnly') : 'none';\n // Without an action there's no `aria-pressed` to carry the selection, so it's said in words\n // (WCAG 1.3.1): the remove button's description, or hidden text on a static chip.\n const announceSelected = Boolean(selected) && !onPress;\n const selectedWord = useLabels('Chip', DEFAULT_LABELS, labels).selected;\n const styles = chipStyles({\n kind: 'input',\n split,\n outline,\n leading: avatar ? 'avatar' : leadingIcon ? 'icon' : 'none',\n trailing: Boolean(onRemove),\n });\n const leading = avatar ? (\n <span\n aria-hidden=\"true\"\n data-slot=\"leading\"\n className={styles.leading({ class: classNames?.leading })}\n >\n <span className={styles.avatar({ class: classNames?.avatar })}>{avatar}</span>\n </span>\n ) : (\n leadingIconOf(styles, leadingIcon, classNames?.leading)\n );\n const content = (\n <ChipContent styles={styles} classNames={classNames} leading={leading} labelId={labelId}>\n {children}\n </ChipContent>\n );\n\n return (\n <div\n {...rest}\n {...tokenAttributes('input', undefined, density, rest)}\n data-selected={selected || undefined}\n data-disabled={disabled || undefined}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n {onPress ? (\n <ButtonBase\n disabled={disabled}\n onPress={onPress}\n onKeyDown={removeKeys(onRemove, disabled)}\n aria-pressed={selected}\n data-chip-primary=\"\"\n className={styles.primary({ class: classNames?.primary })}\n >\n {content}\n </ButtonBase>\n ) : (\n <span data-chip-primary=\"\" className={styles.primary({ class: classNames?.primary })}>\n {content}\n {announceSelected &&\n (onRemove ? (\n <span id={selectedId} hidden>\n {selectedWord}\n </span>\n ) : (\n <VisuallyHidden>{`, ${selectedWord}`}</VisuallyHidden>\n ))}\n </span>\n )}\n {onRemove && (\n <RemoveButton\n styles={styles}\n className={classNames?.remove}\n labelId={labelId}\n labels={labels}\n onRemove={onRemove}\n disabled={disabled}\n describedBy={announceSelected ? selectedId : undefined}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -2,12 +2,12 @@ import { ComponentTokenSet } from "../../tokens/component.js";
|
|
|
2
2
|
import "../../index.js";
|
|
3
3
|
//#region src/components/chip/chip-tokens.d.ts
|
|
4
4
|
/** The tokens of {@link AssistChip}: `--md-comp-assist-chip-*`. */
|
|
5
|
-
export declare const assistChipTokenSet: ComponentTokenSet<"
|
|
5
|
+
export declare const assistChipTokenSet: ComponentTokenSet<"label-text-color" | "container-shape" | "with-icon-icon-color" | "flat-outline-color" | "elevated-container-color">;
|
|
6
6
|
/** The tokens of {@link SuggestionChip}: `--md-comp-suggestion-chip-*`. */
|
|
7
|
-
export declare const suggestionChipTokenSet: ComponentTokenSet<"
|
|
7
|
+
export declare const suggestionChipTokenSet: ComponentTokenSet<"label-text-color" | "container-shape" | "flat-outline-color" | "elevated-container-color" | "with-leading-icon-leading-icon-color">;
|
|
8
8
|
/** The tokens of {@link FilterChip}: `--md-comp-filter-chip-*`. */
|
|
9
|
-
export declare const filterChipTokenSet: ComponentTokenSet<"
|
|
9
|
+
export declare const filterChipTokenSet: ComponentTokenSet<"selected-label-text-color" | "unselected-label-text-color" | "container-shape" | "with-leading-icon-unselected-leading-icon-color" | "flat-unselected-outline-color" | "flat-selected-container-color" | "elevated-unselected-container-color">;
|
|
10
10
|
/** The tokens of {@link InputChip}: `--md-comp-input-chip-*`. */
|
|
11
|
-
export declare const inputChipTokenSet: ComponentTokenSet<"
|
|
11
|
+
export declare const inputChipTokenSet: ComponentTokenSet<"selected-container-color" | "selected-label-text-color" | "unselected-label-text-color" | "container-shape" | "unselected-outline-color">;
|
|
12
12
|
//#endregion
|
|
13
13
|
//# sourceMappingURL=chip-tokens.d.ts.map
|
|
@@ -128,7 +128,10 @@ export interface DateFieldProps extends WrapperRootDOMProps {
|
|
|
128
128
|
* @default 0
|
|
129
129
|
*/
|
|
130
130
|
density?: Density;
|
|
131
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Words the field and its calendar show and announce, with English defaults.
|
|
133
|
+
* A {@link LabelsProvider} sets them for the whole app.
|
|
134
|
+
*/
|
|
132
135
|
labels?: Partial<DateFieldLabels>;
|
|
133
136
|
/** The text field's root. */
|
|
134
137
|
ref?: Ref<HTMLDivElement>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { NO_DEFAULT_LABELS, useLabels } from "../labels/use-labels.js";
|
|
3
4
|
import { onDemand, usePreloadOnIntent } from "../../utils/load-on-demand.js";
|
|
4
5
|
import { Button } from "../button/Button.js";
|
|
5
6
|
import { TooltipTrigger } from "../tooltip/tooltip-trigger.js";
|
|
@@ -45,7 +46,8 @@ function DateField(props) {
|
|
|
45
46
|
directionRef
|
|
46
47
|
}) });
|
|
47
48
|
}
|
|
48
|
-
function DateFieldInner({ label, value: valueProp, defaultValue, onChange, min, max, isDateUnavailable, yearRange = [1900, 2100], open, defaultOpen, onOpenChange, supportingText, invalid: invalidProp, errorMessage, required: requiredProp, disabled, readOnly: readOnlyProp, "aria-describedby": describedBy, "aria-details": details, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, "aria-readonly": ariaReadonly, name, id, calendarIcon, density, labels
|
|
49
|
+
function DateFieldInner({ label, value: valueProp, defaultValue, onChange, min, max, isDateUnavailable, yearRange = [1900, 2100], open, defaultOpen, onOpenChange, supportingText, invalid: invalidProp, errorMessage, required: requiredProp, disabled, readOnly: readOnlyProp, "aria-describedby": describedBy, "aria-details": details, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, "aria-readonly": ariaReadonly, name, id, calendarIcon, density, labels: labelsProp, ref, inputRef, className, style, classNames, directionRef, ...rest }) {
|
|
50
|
+
const labels = useLabels(["DatePicker", "DateField"], NO_DEFAULT_LABELS, labelsProp);
|
|
49
51
|
const { root, rest: aria } = splitRootProps(rest, { wrapper: true });
|
|
50
52
|
const invalid = invalidProp ?? ariaFlag(ariaInvalid);
|
|
51
53
|
const required = requiredProp ?? ariaFlag(ariaRequired);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateField.js","names":[],"sources":["../../../src/components/date-picker/DateField.tsx"],"sourcesContent":["'use client';\n\nimport {\n createCalendar,\n getLocalTimeZone,\n toCalendarDate,\n type CalendarDate,\n type DateValue,\n} from '@internationalized/date';\nimport {\n useRef,\n useState,\n type AriaAttributes,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { useCalendar, useDateFormatter, useDialog, useLocale } from 'react-aria';\nimport { useCalendarState, useOverlayTriggerState } from 'react-stately';\nimport { useControlledState } from 'react-stately/useControlledState';\nimport { DomDirectionLocale } from '../../primitives/DomDirectionLocale';\nimport { cn } from '../../utils/cn';\nimport {\n ariaFlag,\n pickDescriptionAria,\n splitRootProps,\n type WrapperRootDOMProps,\n} from '../../utils/root-props';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport type { Density } from '../../tokens/density';\nimport { OptionPopover } from '../select/option-list';\nimport type { TextFieldClassNames } from '../text-field/TextField';\nimport { LazyTooltip } from '../tooltip/lazy-tooltip';\nimport { onDemand, usePreloadOnIntent } from '../../utils/load-on-demand';\nimport { TooltipTrigger } from '../tooltip/tooltip-trigger';\nimport { CalendarGrid } from './CalendarGrid';\nimport { ChoiceButton, ShortcutIconButton, useMonthSwipe, usePickerKeys } from './calendar-parts';\nimport { DateInput, type DateInputLabels } from './DateInput';\nimport type { CompactDateDialogProps } from './CompactDateDialog';\nimport { COMPACT_WINDOW, useMediaQuery } from './use-media-query';\nimport { datePickerStyles, dockedDatePickerStyles } from './date-picker-styles';\nimport {\n ArrowDropDownIcon,\n CalendarIcon,\n CheckIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from './picker-icons';\n\n/** Words of a {@link DateField}, for localisation. */\nexport interface DateFieldLabels extends DateInputLabels {\n /** The calendar icon button. @default \"Open calendar\" */\n openCalendar: string;\n /** Name of the dropdown calendar. @default \"Choose a date\" */\n calendar: string;\n /** The previous month button. @default \"Previous month\" */\n previousMonth: string;\n /** The next month button. @default \"Next month\" */\n nextMonth: string;\n /** Tooltip of the previous month button. @default \"Previous month (Page Up)\" */\n previousMonthTooltip: string;\n /** Tooltip of the next month button. @default \"Next month (Page Down)\" */\n nextMonthTooltip: string;\n /** The previous year button. @default \"Previous year\" */\n previousYear: string;\n /** The next year button. @default \"Next year\" */\n nextYear: string;\n /** Tooltip of the previous year button. @default \"Previous year (Shift+Page Up)\" */\n previousYearTooltip: string;\n /** Tooltip of the next year button. @default \"Next year (Shift+Page Down)\" */\n nextYearTooltip: string;\n /** Added to the month menu button's name. @default \"Choose a month\" */\n chooseMonth: string;\n /** Added to the year menu button's name. @default \"Choose a year\" */\n chooseYear: string;\n /** Tooltip of the month menu button. @default \"Choose a month (Shift+M)\" */\n monthMenuTooltip: string;\n /** Tooltip of the year menu button. @default \"Choose a year (Shift+Y)\" */\n yearMenuTooltip: string;\n /** Name of the month list. @default \"Month\" */\n monthList: string;\n /** Name of the year list. @default \"Year\" */\n yearList: string;\n /** The calendar's dismissing action. @default \"Cancel\" */\n cancel: string;\n /** The calendar's confirming action. @default \"OK\" */\n ok: string;\n}\n\nexport interface DateFieldClassNames extends Omit<\n TextFieldClassNames,\n 'leadingIcon' | 'prefix' | 'suffix' | 'counter'\n> {\n /** The text field's root; `className` goes here too. */\n root?: string;\n /** The `<input>`. */\n input?: string;\n /**\n * The calendar's panel: the dropdown panel, or on compact windows the full-screen\n * dialog's surface.\n */\n calendar?: string;\n /**\n * The calendar's month and year menu buttons (on compact windows, the modal picker's one\n * month and year button).\n */\n menuButton?: string;\n /** The calendar's weekday names. */\n weekday?: string;\n /** Each day of the calendar. */\n day?: string;\n /** Each month or year in the calendar's month and year lists. */\n item?: string;\n}\n\nexport interface DateFieldProps extends WrapperRootDOMProps {\n /** The field's label, e.g. \"Date of birth\". */\n label: ReactNode;\n /** The date (controlled); `null` for none. */\n value?: CalendarDate | null;\n /** Initial date when uncontrolled. @default null */\n defaultValue?: CalendarDate | null;\n /** A date was typed and committed, or picked and confirmed; `null` when cleared. */\n onChange?: (value: CalendarDate | null) => void;\n /** Earliest date allowed; earlier days are disabled. */\n min?: DateValue;\n /** Latest date allowed; later days are disabled. */\n max?: DateValue;\n /** Returns `true` for a day that can't be picked (it shows disabled). */\n isDateUnavailable?: (date: DateValue) => boolean;\n /** First and last years of the year menu; years outside min / max are disabled. @default [1900, 2100] */\n yearRange?: [number, number];\n /** Whether the dropdown calendar is open (controlled). */\n open?: boolean;\n /** Whether the dropdown calendar starts open when uncontrolled. @default false */\n defaultOpen?: boolean;\n /** Called when the dropdown calendar opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Helper text below the field. @default the locale's format, such as \"MM/DD/YYYY\" in en-US */\n supportingText?: ReactNode;\n /** Marks the field invalid, with `errorMessage` below it. */\n invalid?: boolean;\n /** Error text shown below the field while it's invalid, in place of `supportingText`. */\n errorMessage?: ReactNode;\n /** The field must have a date. @default false */\n required?: boolean;\n /** The field and its calendar button can't be used. @default false */\n disabled?: boolean;\n /** The date can be read and focused but not changed. @default false */\n readOnly?: boolean;\n /**\n * More description for the `<input>`, after the supporting or error text: the ids of\n * elements such as a hint that the date must come after another field's.\n */\n 'aria-describedby'?: string;\n /** The id of an element with more details about the `<input>`. */\n 'aria-details'?: string;\n /** Read as `invalid` when that's left out, for a form library that sets the attribute. */\n 'aria-invalid'?: AriaAttributes['aria-invalid'];\n /** Read as `required` when that's left out, for a form library that sets the attribute. */\n 'aria-required'?: AriaAttributes['aria-required'];\n /** Read as `readOnly` when that's left out, for a form library that sets the attribute. */\n 'aria-readonly'?: AriaAttributes['aria-readonly'];\n /** Form field name; the input submits the typed text. */\n name?: string;\n /** The `<input>`'s id, for a `<label for>` or an error summary's link. */\n id?: string;\n /** Icon of the button that opens the calendar. */\n calendarIcon?: ReactElement;\n /**\n * Web density of the typed field, `0` to `-3`: each step takes 4px off it (56px at 0, 44px\n * at -3). The calendar keeps its size: M3 doesn't make date pickers denser, since their 48px\n * day targets are part of their accessibility. Left out, the field takes the density of the\n * nearest `ThemeProvider` or `ThemeScope`.\n * @default 0\n */\n density?: Density;\n /** Words the field and its calendar show and announce, with English defaults. */\n labels?: Partial<DateFieldLabels>;\n /** The text field's root. */\n ref?: Ref<HTMLDivElement>;\n /** The `<input>`. */\n inputRef?: Ref<HTMLInputElement>;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n /** Classes for each part, by slot. */\n classNames?: DateFieldClassNames;\n /** `data-*` attributes go to the root. */\n [data: `data-${string}`]: string | number | boolean | undefined;\n}\n\n/**\n * The full-screen modal picker a {@link DateField} opens on compact windows, loaded with\n * `import()`: a field on a wider window never needs it.\n */\nconst compactDialog = onDemand<CompactDateDialogProps>(() =>\n import('./CompactDateDialog').then((module) => module.CompactDateDialog),\n);\n\n/**\n * M3 docked date picker: an outlined date field you can type in (no input mask; the\n * locale's format as helper text), whose calendar button opens a calendar just below it\n * with month and year menus, previous / next month and year buttons, the days of the\n * months around the shown one, and Cancel / OK. On compact windows (below 600px) the\n * button opens the modal {@link DatePicker} in a full-screen {@link PickerDialog} instead,\n * as M3 recommends there: the 360px docked calendar doesn't fit a phone. That picker's\n * code loads on demand, only on a compact window: when the browser is next idle, or as soon\n * as the pointer or focus reaches the field, so it's in before the first press.\n *\n * @example\n * <DateField label=\"Date\" value={date} onChange={setDate} />\n */\nexport function DateField(props: DateFieldProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <DateFieldInner {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\nfunction DateFieldInner({\n label,\n value: valueProp,\n defaultValue,\n onChange,\n min,\n max,\n isDateUnavailable,\n yearRange = [1900, 2100],\n open,\n defaultOpen,\n onOpenChange,\n supportingText,\n invalid: invalidProp,\n errorMessage,\n required: requiredProp,\n disabled,\n readOnly: readOnlyProp,\n 'aria-describedby': describedBy,\n 'aria-details': details,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-readonly': ariaReadonly,\n name,\n id,\n calendarIcon,\n density,\n labels = {},\n ref,\n inputRef,\n className,\n style,\n classNames,\n directionRef,\n ...rest\n}: DateFieldProps & { directionRef: (element: HTMLElement | null) => void }) {\n const { root, rest: aria } = splitRootProps(rest, { wrapper: true });\n const invalid = invalidProp ?? ariaFlag(ariaInvalid);\n const required = requiredProp ?? ariaFlag(ariaRequired);\n const readOnly = readOnlyProp ?? ariaFlag(ariaReadonly);\n // The text field splits them again: the description reaches its `<input>`, after its own.\n const data = {\n ...root,\n ...pickDescriptionAria(aria),\n ...(describedBy !== undefined && { 'aria-describedby': describedBy }),\n ...(details !== undefined && { 'aria-details': details }),\n };\n const [value, setValue] = useControlledState(valueProp, defaultValue ?? null, onChange);\n const overlay = useOverlayTriggerState({ isOpen: open, defaultOpen, onOpenChange });\n const fieldRef = useRef<HTMLDivElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n // M3: \"On compact breakpoints … a full-screen modal date picker is recommended\". Below\n // 600px the docked calendar's header was cut off and its day targets overlapped.\n const compact = useMediaQuery(COMPACT_WINDOW);\n usePreloadOnIntent(fieldRef, compactDialog.preload, compact);\n // Mounted from the first open on, so it can play its exit; the module is usually in by\n // then, and if not it opens as it arrives, taking focus as it would have.\n const [compactOpened, setCompactOpened] = useState(compact && overlay.isOpen);\n if (compact && overlay.isOpen && !compactOpened) setCompactOpened(true);\n const {\n root: rootClassName,\n calendar,\n menuButton,\n weekday,\n day,\n item,\n ...fieldClassNames\n } = classNames ?? {};\n return (\n <>\n <DateInput\n ref={(element) => {\n fieldRef.current = element;\n directionRef(element);\n if (typeof ref === 'function') ref(element);\n else if (ref) ref.current = element;\n }}\n inputRef={inputRef}\n label={label}\n value={value}\n onCommit={setValue}\n min={min}\n max={max}\n isDateUnavailable={isDateUnavailable}\n labels={labels}\n supportingText={supportingText}\n invalid={invalid}\n errorMessage={errorMessage}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n name={name}\n id={id}\n style={style}\n data={data}\n className={cn(rootClassName, className)}\n classNames={fieldClassNames}\n density={density}\n trailingIcon={\n <IconButton\n variant=\"standard\"\n icon={calendarIcon ?? <CalendarIcon />}\n aria-label={labels.openCalendar ?? 'Open calendar'}\n aria-haspopup=\"dialog\"\n aria-expanded={overlay.isOpen}\n disabled={disabled || readOnly}\n onPress={overlay.open}\n />\n }\n />\n {compact ? (\n compactOpened && (\n <compactDialog.Component\n open={overlay.isOpen}\n onOpenChange={overlay.setOpen}\n value={value}\n onCommit={setValue}\n min={min}\n max={max}\n isDateUnavailable={isDateUnavailable}\n yearRange={yearRange}\n labels={labels}\n classNames={{ calendar, menuButton, weekday, day, item }}\n />\n )\n ) : (\n <OptionPopover state={overlay} triggerRef={fieldRef} popoverRef={popoverRef}>\n <DockedCalendar\n value={value}\n onCommit={(date) => {\n setValue(date);\n overlay.close();\n }}\n onCancel={overlay.close}\n min={min}\n max={max}\n isDateUnavailable={isDateUnavailable}\n yearRange={yearRange}\n labels={labels}\n className={calendar}\n classNames={{ menuButton, weekday, day, item }}\n />\n </OptionPopover>\n )}\n </>\n );\n}\n\ntype View = 'days' | 'months' | 'years';\n\n/** The dropdown calendar of a {@link DateField}. */\nfunction DockedCalendar({\n value,\n onCommit,\n onCancel,\n min: minValue,\n max: maxValue,\n isDateUnavailable,\n yearRange,\n labels,\n className,\n classNames,\n}: {\n value: CalendarDate | null;\n onCommit: (date: CalendarDate | null) => void;\n onCancel: () => void;\n min: DateValue | undefined;\n max: DateValue | undefined;\n isDateUnavailable: ((date: DateValue) => boolean) | undefined;\n yearRange: [number, number];\n labels: Partial<DateFieldLabels>;\n className: string | undefined;\n classNames: Pick<DateFieldClassNames, 'menuButton' | 'weekday' | 'day' | 'item'>;\n}) {\n const { locale } = useLocale();\n const [draft, setDraft] = useState(value);\n const state = useCalendarState({\n value: draft,\n onChange: (date) => setDraft(date as CalendarDate),\n minValue,\n maxValue,\n isDateUnavailable,\n autoFocus: true,\n locale,\n createCalendar,\n });\n const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar({}, state);\n const panelRef = useRef<HTMLDivElement>(null);\n const { dialogProps } = useDialog({ 'aria-label': labels.calendar ?? 'Choose a date' }, panelRef);\n const [view, setView] = useState<View>('days');\n const [focusList, setFocusList] = useState(false);\n const monthRef = useRef<HTMLButtonElement>(null);\n const yearRef = useRef<HTMLButtonElement>(null);\n const styles = dockedDatePickerStyles();\n const grid = datePickerStyles({ docked: true });\n const { swipeProps, slideKey, slideDirection } = useMonthSwipe(state);\n const shortMonth = useDateFormatter({ month: 'short' });\n const longMonth = useDateFormatter({ month: 'long' });\n const yearFormat = useDateFormatter({ year: 'numeric' });\n const shown = state.focusedDate;\n const at = (date: CalendarDate) => date.toDate(getLocalTimeZone());\n const min = minValue ? toCalendarDate(minValue) : undefined;\n const max = maxValue ? toCalendarDate(maxValue) : undefined;\n const firstYear = Math.max(yearRange[0], min?.year ?? -Infinity);\n const lastYear = Math.min(yearRange[1], max?.year ?? Infinity);\n\n const openList = (next: View, byKeyboard: boolean) => {\n setFocusList(byKeyboard);\n setView(view === next ? 'days' : next);\n };\n const pick = (date: CalendarDate, menu: View) => {\n state.setFocusedDate(date);\n setView('days');\n (menu === 'months' ? monthRef : yearRef).current?.focus();\n };\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: () => onCommit(state.focusedDate),\n onMonthMenu: () => openList('months', true),\n onYearMenu: () => openList('years', true),\n });\n const monthOutside = (month: number) => {\n const date = shown.set({ month, day: 1 });\n const last = date.add({ months: 1 }).subtract({ days: 1 });\n return (\n (max !== undefined && date.compare(max) > 0) || (min !== undefined && last.compare(min) < 0)\n );\n };\n\n return (\n <div\n {...dialogProps}\n ref={panelRef}\n onKeyDownCapture={onKeyDownCapture}\n data-view={view}\n className={styles.panel({ class: className })}\n >\n <div {...calendarProps} className={styles.calendar()}>\n <div className={styles.header()}>\n <div className={styles.group()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousMonth ?? 'Previous month'}\n tooltip={labels.previousMonthTooltip ?? 'Previous month (Page Up)'}\n onPress={prevButtonProps.onPress as () => void}\n disabled={view !== 'days' || prevButtonProps.isDisabled}\n />\n <MenuButton\n buttonRef={monthRef}\n label={`${longMonth.format(at(shown))}, ${labels.chooseMonth ?? 'Choose a month'}`}\n tooltip={labels.monthMenuTooltip ?? 'Choose a month (Shift+M)'}\n open={view === 'months'}\n disabled={view === 'years'}\n styles={styles}\n className={classNames.menuButton}\n onPress={() => openList('months', false)}\n >\n {shortMonth.format(at(shown))}\n </MenuButton>\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextMonth ?? 'Next month'}\n tooltip={labels.nextMonthTooltip ?? 'Next month (Page Down)'}\n onPress={nextButtonProps.onPress as () => void}\n disabled={view !== 'days' || nextButtonProps.isDisabled}\n />\n </div>\n <div className={styles.group()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousYear ?? 'Previous year'}\n tooltip={labels.previousYearTooltip ?? 'Previous year (Shift+Page Up)'}\n onPress={() => state.setFocusedDate(shown.subtract({ years: 1 }))}\n disabled={view !== 'days' || shown.year <= firstYear}\n />\n <MenuButton\n buttonRef={yearRef}\n label={`${yearFormat.format(at(shown))}, ${labels.chooseYear ?? 'Choose a year'}`}\n tooltip={labels.yearMenuTooltip ?? 'Choose a year (Shift+Y)'}\n open={view === 'years'}\n disabled={view === 'months'}\n styles={styles}\n className={classNames.menuButton}\n onPress={() => openList('years', false)}\n >\n {yearFormat.format(at(shown))}\n </MenuButton>\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextYear ?? 'Next year'}\n tooltip={labels.nextYearTooltip ?? 'Next year (Shift+Page Down)'}\n onPress={() => state.setFocusedDate(shown.add({ years: 1 }))}\n disabled={view !== 'days' || shown.year >= lastYear}\n />\n </div>\n </div>\n {view === 'days' && (\n <div {...swipeProps} className={grid.swipe({ class: styles.view() })}>\n <div key={slideKey} data-direction={slideDirection} className={grid.slide()}>\n <CalendarGrid state={state} styles={grid} classNames={classNames} />\n </div>\n </div>\n )}\n {view === 'months' && (\n <ChoiceList label={labels.monthList ?? 'Month'} autoFocus={focusList} styles={styles}>\n {Array.from({ length: 12 }, (_, i) => i + 1).map((month) => (\n <ChoiceButton\n key={month}\n selected={month === shown.month}\n disabled={monthOutside(month)}\n steps={LIST_STEPS}\n className={styles.item({ class: classNames.item })}\n onPick={() => pick(shown.set({ month }), 'months')}\n >\n <Check selected={month === shown.month} styles={styles} />\n {longMonth.format(at(shown.set({ month, day: 1 })))}\n </ChoiceButton>\n ))}\n </ChoiceList>\n )}\n {view === 'years' && (\n <ChoiceList label={labels.yearList ?? 'Year'} autoFocus={focusList} styles={styles}>\n {Array.from(\n { length: yearRange[1] - yearRange[0] + 1 },\n (_, i) => yearRange[0] + i,\n ).map((year) => (\n <ChoiceButton\n key={year}\n selected={year === shown.year}\n disabled={year < firstYear || year > lastYear}\n steps={LIST_STEPS}\n className={styles.item({ class: classNames.item })}\n onPick={() => pick(shown.set({ year }), 'years')}\n >\n <Check selected={year === shown.year} styles={styles} />\n {year}\n </ChoiceButton>\n ))}\n </ChoiceList>\n )}\n </div>\n <div className={styles.actions()}>\n <Button variant=\"text\" onPress={onCancel}>\n {labels.cancel ?? 'Cancel'}\n </Button>\n <Button variant=\"text\" onPress={() => onCommit(draft)}>\n {labels.ok ?? 'OK'}\n </Button>\n </div>\n </div>\n );\n}\n\n/** One option per row. */\nconst LIST_STEPS = { ArrowUp: -1, ArrowDown: 1 };\n\nfunction MenuButton({\n buttonRef,\n label,\n tooltip,\n open,\n disabled,\n styles,\n className,\n onPress,\n children,\n}: {\n buttonRef: Ref<HTMLButtonElement>;\n label: string;\n tooltip: string;\n open: boolean;\n disabled: boolean;\n styles: ReturnType<typeof dockedDatePickerStyles>;\n className: string | undefined;\n onPress: () => void;\n children: string;\n}) {\n return (\n <TooltipTrigger>\n <Button\n ref={buttonRef}\n variant=\"text\"\n aria-label={label}\n aria-expanded={open}\n // M3 menus: while its list is open the button looks the same, plus a pressed state.\n data-menu-open={open || undefined}\n disabled={disabled}\n onPress={onPress}\n className={styles.menuButton({ class: className })}\n >\n {/* The drop-down arrow trails the label here, which Button's one leading icon can't do. */}\n <span className=\"inline-flex items-center gap-[8px]\">\n {children}\n <span aria-hidden=\"true\" className=\"inline-flex size-[20px] items-center justify-center\">\n <span data-open={open || undefined} className={styles.menuIcon()}>\n <ArrowDropDownIcon />\n </span>\n </span>\n </span>\n </Button>\n <LazyTooltip>{tooltip}</LazyTooltip>\n </TooltipTrigger>\n );\n}\n\nfunction ChoiceList({\n label,\n autoFocus,\n styles,\n children,\n}: {\n label: string;\n autoFocus: boolean;\n styles: ReturnType<typeof dockedDatePickerStyles>;\n children: ReactNode;\n}) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={label}\n className={styles.list()}\n ref={(element) => {\n const selected = element?.querySelector<HTMLElement>('[aria-checked=\"true\"]');\n selected?.scrollIntoView?.({ block: 'center' });\n if (autoFocus) selected?.focus({ preventScroll: true });\n }}\n >\n {children}\n </div>\n );\n}\n\nfunction Check({\n selected,\n styles,\n}: {\n selected: boolean;\n styles: ReturnType<typeof dockedDatePickerStyles>;\n}) {\n return <span className={styles.check()}>{selected && <CheckIcon />}</span>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateField.js","names":[],"sources":["../../../src/components/date-picker/DateField.tsx"],"sourcesContent":["'use client';\n\nimport {\n createCalendar,\n getLocalTimeZone,\n toCalendarDate,\n type CalendarDate,\n type DateValue,\n} from '@internationalized/date';\nimport {\n useRef,\n useState,\n type AriaAttributes,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { useCalendar, useDateFormatter, useDialog, useLocale } from 'react-aria';\nimport { useCalendarState, useOverlayTriggerState } from 'react-stately';\nimport { useControlledState } from 'react-stately/useControlledState';\nimport { NO_DEFAULT_LABELS, useLabels } from '../labels/use-labels';\nimport { DomDirectionLocale } from '../../primitives/DomDirectionLocale';\nimport { cn } from '../../utils/cn';\nimport {\n ariaFlag,\n pickDescriptionAria,\n splitRootProps,\n type WrapperRootDOMProps,\n} from '../../utils/root-props';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport type { Density } from '../../tokens/density';\nimport { OptionPopover } from '../select/option-list';\nimport type { TextFieldClassNames } from '../text-field/TextField';\nimport { LazyTooltip } from '../tooltip/lazy-tooltip';\nimport { onDemand, usePreloadOnIntent } from '../../utils/load-on-demand';\nimport { TooltipTrigger } from '../tooltip/tooltip-trigger';\nimport { CalendarGrid } from './CalendarGrid';\nimport { ChoiceButton, ShortcutIconButton, useMonthSwipe, usePickerKeys } from './calendar-parts';\nimport { DateInput, type DateInputLabels } from './DateInput';\nimport type { CompactDateDialogProps } from './CompactDateDialog';\nimport { COMPACT_WINDOW, useMediaQuery } from './use-media-query';\nimport { datePickerStyles, dockedDatePickerStyles } from './date-picker-styles';\nimport {\n ArrowDropDownIcon,\n CalendarIcon,\n CheckIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from './picker-icons';\n\n/** Words of a {@link DateField}, for localisation. */\nexport interface DateFieldLabels extends DateInputLabels {\n /** The calendar icon button. @default \"Open calendar\" */\n openCalendar: string;\n /** Name of the dropdown calendar. @default \"Choose a date\" */\n calendar: string;\n /** The previous month button. @default \"Previous month\" */\n previousMonth: string;\n /** The next month button. @default \"Next month\" */\n nextMonth: string;\n /** Tooltip of the previous month button. @default \"Previous month (Page Up)\" */\n previousMonthTooltip: string;\n /** Tooltip of the next month button. @default \"Next month (Page Down)\" */\n nextMonthTooltip: string;\n /** The previous year button. @default \"Previous year\" */\n previousYear: string;\n /** The next year button. @default \"Next year\" */\n nextYear: string;\n /** Tooltip of the previous year button. @default \"Previous year (Shift+Page Up)\" */\n previousYearTooltip: string;\n /** Tooltip of the next year button. @default \"Next year (Shift+Page Down)\" */\n nextYearTooltip: string;\n /** Added to the month menu button's name. @default \"Choose a month\" */\n chooseMonth: string;\n /** Added to the year menu button's name. @default \"Choose a year\" */\n chooseYear: string;\n /** Tooltip of the month menu button. @default \"Choose a month (Shift+M)\" */\n monthMenuTooltip: string;\n /** Tooltip of the year menu button. @default \"Choose a year (Shift+Y)\" */\n yearMenuTooltip: string;\n /** Name of the month list. @default \"Month\" */\n monthList: string;\n /** Name of the year list. @default \"Year\" */\n yearList: string;\n /** The calendar's dismissing action. @default \"Cancel\" */\n cancel: string;\n /** The calendar's confirming action. @default \"OK\" */\n ok: string;\n}\n\nexport interface DateFieldClassNames extends Omit<\n TextFieldClassNames,\n 'leadingIcon' | 'prefix' | 'suffix' | 'counter'\n> {\n /** The text field's root; `className` goes here too. */\n root?: string;\n /** The `<input>`. */\n input?: string;\n /**\n * The calendar's panel: the dropdown panel, or on compact windows the full-screen\n * dialog's surface.\n */\n calendar?: string;\n /**\n * The calendar's month and year menu buttons (on compact windows, the modal picker's one\n * month and year button).\n */\n menuButton?: string;\n /** The calendar's weekday names. */\n weekday?: string;\n /** Each day of the calendar. */\n day?: string;\n /** Each month or year in the calendar's month and year lists. */\n item?: string;\n}\n\nexport interface DateFieldProps extends WrapperRootDOMProps {\n /** The field's label, e.g. \"Date of birth\". */\n label: ReactNode;\n /** The date (controlled); `null` for none. */\n value?: CalendarDate | null;\n /** Initial date when uncontrolled. @default null */\n defaultValue?: CalendarDate | null;\n /** A date was typed and committed, or picked and confirmed; `null` when cleared. */\n onChange?: (value: CalendarDate | null) => void;\n /** Earliest date allowed; earlier days are disabled. */\n min?: DateValue;\n /** Latest date allowed; later days are disabled. */\n max?: DateValue;\n /** Returns `true` for a day that can't be picked (it shows disabled). */\n isDateUnavailable?: (date: DateValue) => boolean;\n /** First and last years of the year menu; years outside min / max are disabled. @default [1900, 2100] */\n yearRange?: [number, number];\n /** Whether the dropdown calendar is open (controlled). */\n open?: boolean;\n /** Whether the dropdown calendar starts open when uncontrolled. @default false */\n defaultOpen?: boolean;\n /** Called when the dropdown calendar opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Helper text below the field. @default the locale's format, such as \"MM/DD/YYYY\" in en-US */\n supportingText?: ReactNode;\n /** Marks the field invalid, with `errorMessage` below it. */\n invalid?: boolean;\n /** Error text shown below the field while it's invalid, in place of `supportingText`. */\n errorMessage?: ReactNode;\n /** The field must have a date. @default false */\n required?: boolean;\n /** The field and its calendar button can't be used. @default false */\n disabled?: boolean;\n /** The date can be read and focused but not changed. @default false */\n readOnly?: boolean;\n /**\n * More description for the `<input>`, after the supporting or error text: the ids of\n * elements such as a hint that the date must come after another field's.\n */\n 'aria-describedby'?: string;\n /** The id of an element with more details about the `<input>`. */\n 'aria-details'?: string;\n /** Read as `invalid` when that's left out, for a form library that sets the attribute. */\n 'aria-invalid'?: AriaAttributes['aria-invalid'];\n /** Read as `required` when that's left out, for a form library that sets the attribute. */\n 'aria-required'?: AriaAttributes['aria-required'];\n /** Read as `readOnly` when that's left out, for a form library that sets the attribute. */\n 'aria-readonly'?: AriaAttributes['aria-readonly'];\n /** Form field name; the input submits the typed text. */\n name?: string;\n /** The `<input>`'s id, for a `<label for>` or an error summary's link. */\n id?: string;\n /** Icon of the button that opens the calendar. */\n calendarIcon?: ReactElement;\n /**\n * Web density of the typed field, `0` to `-3`: each step takes 4px off it (56px at 0, 44px\n * at -3). The calendar keeps its size: M3 doesn't make date pickers denser, since their 48px\n * day targets are part of their accessibility. Left out, the field takes the density of the\n * nearest `ThemeProvider` or `ThemeScope`.\n * @default 0\n */\n density?: Density;\n /**\n * Words the field and its calendar show and announce, with English defaults.\n * A {@link LabelsProvider} sets them for the whole app.\n */\n labels?: Partial<DateFieldLabels>;\n /** The text field's root. */\n ref?: Ref<HTMLDivElement>;\n /** The `<input>`. */\n inputRef?: Ref<HTMLInputElement>;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n /** Classes for each part, by slot. */\n classNames?: DateFieldClassNames;\n /** `data-*` attributes go to the root. */\n [data: `data-${string}`]: string | number | boolean | undefined;\n}\n\n/**\n * The full-screen modal picker a {@link DateField} opens on compact windows, loaded with\n * `import()`: a field on a wider window never needs it.\n */\nconst compactDialog = onDemand<CompactDateDialogProps>(() =>\n import('./CompactDateDialog').then((module) => module.CompactDateDialog),\n);\n\n/**\n * M3 docked date picker: an outlined date field you can type in (no input mask; the\n * locale's format as helper text), whose calendar button opens a calendar just below it\n * with month and year menus, previous / next month and year buttons, the days of the\n * months around the shown one, and Cancel / OK. On compact windows (below 600px) the\n * button opens the modal {@link DatePicker} in a full-screen {@link PickerDialog} instead,\n * as M3 recommends there: the 360px docked calendar doesn't fit a phone. That picker's\n * code loads on demand, only on a compact window: when the browser is next idle, or as soon\n * as the pointer or focus reaches the field, so it's in before the first press.\n *\n * @example\n * <DateField label=\"Date\" value={date} onChange={setDate} />\n */\nexport function DateField(props: DateFieldProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <DateFieldInner {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\nfunction DateFieldInner({\n label,\n value: valueProp,\n defaultValue,\n onChange,\n min,\n max,\n isDateUnavailable,\n yearRange = [1900, 2100],\n open,\n defaultOpen,\n onOpenChange,\n supportingText,\n invalid: invalidProp,\n errorMessage,\n required: requiredProp,\n disabled,\n readOnly: readOnlyProp,\n 'aria-describedby': describedBy,\n 'aria-details': details,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-readonly': ariaReadonly,\n name,\n id,\n calendarIcon,\n density,\n labels: labelsProp,\n ref,\n inputRef,\n className,\n style,\n classNames,\n directionRef,\n ...rest\n}: DateFieldProps & { directionRef: (element: HTMLElement | null) => void }) {\n // The modal picker a compact window shows is a `DatePicker`, so its words apply here too.\n const labels = useLabels(['DatePicker', 'DateField'], NO_DEFAULT_LABELS, labelsProp);\n const { root, rest: aria } = splitRootProps(rest, { wrapper: true });\n const invalid = invalidProp ?? ariaFlag(ariaInvalid);\n const required = requiredProp ?? ariaFlag(ariaRequired);\n const readOnly = readOnlyProp ?? ariaFlag(ariaReadonly);\n // The text field splits them again: the description reaches its `<input>`, after its own.\n const data = {\n ...root,\n ...pickDescriptionAria(aria),\n ...(describedBy !== undefined && { 'aria-describedby': describedBy }),\n ...(details !== undefined && { 'aria-details': details }),\n };\n const [value, setValue] = useControlledState(valueProp, defaultValue ?? null, onChange);\n const overlay = useOverlayTriggerState({ isOpen: open, defaultOpen, onOpenChange });\n const fieldRef = useRef<HTMLDivElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n // M3: \"On compact breakpoints … a full-screen modal date picker is recommended\". Below\n // 600px the docked calendar's header was cut off and its day targets overlapped.\n const compact = useMediaQuery(COMPACT_WINDOW);\n usePreloadOnIntent(fieldRef, compactDialog.preload, compact);\n // Mounted from the first open on, so it can play its exit; the module is usually in by\n // then, and if not it opens as it arrives, taking focus as it would have.\n const [compactOpened, setCompactOpened] = useState(compact && overlay.isOpen);\n if (compact && overlay.isOpen && !compactOpened) setCompactOpened(true);\n const {\n root: rootClassName,\n calendar,\n menuButton,\n weekday,\n day,\n item,\n ...fieldClassNames\n } = classNames ?? {};\n return (\n <>\n <DateInput\n ref={(element) => {\n fieldRef.current = element;\n directionRef(element);\n if (typeof ref === 'function') ref(element);\n else if (ref) ref.current = element;\n }}\n inputRef={inputRef}\n label={label}\n value={value}\n onCommit={setValue}\n min={min}\n max={max}\n isDateUnavailable={isDateUnavailable}\n labels={labels}\n supportingText={supportingText}\n invalid={invalid}\n errorMessage={errorMessage}\n required={required}\n disabled={disabled}\n readOnly={readOnly}\n name={name}\n id={id}\n style={style}\n data={data}\n className={cn(rootClassName, className)}\n classNames={fieldClassNames}\n density={density}\n trailingIcon={\n <IconButton\n variant=\"standard\"\n icon={calendarIcon ?? <CalendarIcon />}\n aria-label={labels.openCalendar ?? 'Open calendar'}\n aria-haspopup=\"dialog\"\n aria-expanded={overlay.isOpen}\n disabled={disabled || readOnly}\n onPress={overlay.open}\n />\n }\n />\n {compact ? (\n compactOpened && (\n <compactDialog.Component\n open={overlay.isOpen}\n onOpenChange={overlay.setOpen}\n value={value}\n onCommit={setValue}\n min={min}\n max={max}\n isDateUnavailable={isDateUnavailable}\n yearRange={yearRange}\n labels={labels}\n classNames={{ calendar, menuButton, weekday, day, item }}\n />\n )\n ) : (\n <OptionPopover state={overlay} triggerRef={fieldRef} popoverRef={popoverRef}>\n <DockedCalendar\n value={value}\n onCommit={(date) => {\n setValue(date);\n overlay.close();\n }}\n onCancel={overlay.close}\n min={min}\n max={max}\n isDateUnavailable={isDateUnavailable}\n yearRange={yearRange}\n labels={labels}\n className={calendar}\n classNames={{ menuButton, weekday, day, item }}\n />\n </OptionPopover>\n )}\n </>\n );\n}\n\ntype View = 'days' | 'months' | 'years';\n\n/** The dropdown calendar of a {@link DateField}. */\nfunction DockedCalendar({\n value,\n onCommit,\n onCancel,\n min: minValue,\n max: maxValue,\n isDateUnavailable,\n yearRange,\n labels,\n className,\n classNames,\n}: {\n value: CalendarDate | null;\n onCommit: (date: CalendarDate | null) => void;\n onCancel: () => void;\n min: DateValue | undefined;\n max: DateValue | undefined;\n isDateUnavailable: ((date: DateValue) => boolean) | undefined;\n yearRange: [number, number];\n labels: Partial<DateFieldLabels>;\n className: string | undefined;\n classNames: Pick<DateFieldClassNames, 'menuButton' | 'weekday' | 'day' | 'item'>;\n}) {\n const { locale } = useLocale();\n const [draft, setDraft] = useState(value);\n const state = useCalendarState({\n value: draft,\n onChange: (date) => setDraft(date as CalendarDate),\n minValue,\n maxValue,\n isDateUnavailable,\n autoFocus: true,\n locale,\n createCalendar,\n });\n const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar({}, state);\n const panelRef = useRef<HTMLDivElement>(null);\n const { dialogProps } = useDialog({ 'aria-label': labels.calendar ?? 'Choose a date' }, panelRef);\n const [view, setView] = useState<View>('days');\n const [focusList, setFocusList] = useState(false);\n const monthRef = useRef<HTMLButtonElement>(null);\n const yearRef = useRef<HTMLButtonElement>(null);\n const styles = dockedDatePickerStyles();\n const grid = datePickerStyles({ docked: true });\n const { swipeProps, slideKey, slideDirection } = useMonthSwipe(state);\n const shortMonth = useDateFormatter({ month: 'short' });\n const longMonth = useDateFormatter({ month: 'long' });\n const yearFormat = useDateFormatter({ year: 'numeric' });\n const shown = state.focusedDate;\n const at = (date: CalendarDate) => date.toDate(getLocalTimeZone());\n const min = minValue ? toCalendarDate(minValue) : undefined;\n const max = maxValue ? toCalendarDate(maxValue) : undefined;\n const firstYear = Math.max(yearRange[0], min?.year ?? -Infinity);\n const lastYear = Math.min(yearRange[1], max?.year ?? Infinity);\n\n const openList = (next: View, byKeyboard: boolean) => {\n setFocusList(byKeyboard);\n setView(view === next ? 'days' : next);\n };\n const pick = (date: CalendarDate, menu: View) => {\n state.setFocusedDate(date);\n setView('days');\n (menu === 'months' ? monthRef : yearRef).current?.focus();\n };\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: () => onCommit(state.focusedDate),\n onMonthMenu: () => openList('months', true),\n onYearMenu: () => openList('years', true),\n });\n const monthOutside = (month: number) => {\n const date = shown.set({ month, day: 1 });\n const last = date.add({ months: 1 }).subtract({ days: 1 });\n return (\n (max !== undefined && date.compare(max) > 0) || (min !== undefined && last.compare(min) < 0)\n );\n };\n\n return (\n <div\n {...dialogProps}\n ref={panelRef}\n onKeyDownCapture={onKeyDownCapture}\n data-view={view}\n className={styles.panel({ class: className })}\n >\n <div {...calendarProps} className={styles.calendar()}>\n <div className={styles.header()}>\n <div className={styles.group()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousMonth ?? 'Previous month'}\n tooltip={labels.previousMonthTooltip ?? 'Previous month (Page Up)'}\n onPress={prevButtonProps.onPress as () => void}\n disabled={view !== 'days' || prevButtonProps.isDisabled}\n />\n <MenuButton\n buttonRef={monthRef}\n label={`${longMonth.format(at(shown))}, ${labels.chooseMonth ?? 'Choose a month'}`}\n tooltip={labels.monthMenuTooltip ?? 'Choose a month (Shift+M)'}\n open={view === 'months'}\n disabled={view === 'years'}\n styles={styles}\n className={classNames.menuButton}\n onPress={() => openList('months', false)}\n >\n {shortMonth.format(at(shown))}\n </MenuButton>\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextMonth ?? 'Next month'}\n tooltip={labels.nextMonthTooltip ?? 'Next month (Page Down)'}\n onPress={nextButtonProps.onPress as () => void}\n disabled={view !== 'days' || nextButtonProps.isDisabled}\n />\n </div>\n <div className={styles.group()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousYear ?? 'Previous year'}\n tooltip={labels.previousYearTooltip ?? 'Previous year (Shift+Page Up)'}\n onPress={() => state.setFocusedDate(shown.subtract({ years: 1 }))}\n disabled={view !== 'days' || shown.year <= firstYear}\n />\n <MenuButton\n buttonRef={yearRef}\n label={`${yearFormat.format(at(shown))}, ${labels.chooseYear ?? 'Choose a year'}`}\n tooltip={labels.yearMenuTooltip ?? 'Choose a year (Shift+Y)'}\n open={view === 'years'}\n disabled={view === 'months'}\n styles={styles}\n className={classNames.menuButton}\n onPress={() => openList('years', false)}\n >\n {yearFormat.format(at(shown))}\n </MenuButton>\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextYear ?? 'Next year'}\n tooltip={labels.nextYearTooltip ?? 'Next year (Shift+Page Down)'}\n onPress={() => state.setFocusedDate(shown.add({ years: 1 }))}\n disabled={view !== 'days' || shown.year >= lastYear}\n />\n </div>\n </div>\n {view === 'days' && (\n <div {...swipeProps} className={grid.swipe({ class: styles.view() })}>\n <div key={slideKey} data-direction={slideDirection} className={grid.slide()}>\n <CalendarGrid state={state} styles={grid} classNames={classNames} />\n </div>\n </div>\n )}\n {view === 'months' && (\n <ChoiceList label={labels.monthList ?? 'Month'} autoFocus={focusList} styles={styles}>\n {Array.from({ length: 12 }, (_, i) => i + 1).map((month) => (\n <ChoiceButton\n key={month}\n selected={month === shown.month}\n disabled={monthOutside(month)}\n steps={LIST_STEPS}\n className={styles.item({ class: classNames.item })}\n onPick={() => pick(shown.set({ month }), 'months')}\n >\n <Check selected={month === shown.month} styles={styles} />\n {longMonth.format(at(shown.set({ month, day: 1 })))}\n </ChoiceButton>\n ))}\n </ChoiceList>\n )}\n {view === 'years' && (\n <ChoiceList label={labels.yearList ?? 'Year'} autoFocus={focusList} styles={styles}>\n {Array.from(\n { length: yearRange[1] - yearRange[0] + 1 },\n (_, i) => yearRange[0] + i,\n ).map((year) => (\n <ChoiceButton\n key={year}\n selected={year === shown.year}\n disabled={year < firstYear || year > lastYear}\n steps={LIST_STEPS}\n className={styles.item({ class: classNames.item })}\n onPick={() => pick(shown.set({ year }), 'years')}\n >\n <Check selected={year === shown.year} styles={styles} />\n {year}\n </ChoiceButton>\n ))}\n </ChoiceList>\n )}\n </div>\n <div className={styles.actions()}>\n <Button variant=\"text\" onPress={onCancel}>\n {labels.cancel ?? 'Cancel'}\n </Button>\n <Button variant=\"text\" onPress={() => onCommit(draft)}>\n {labels.ok ?? 'OK'}\n </Button>\n </div>\n </div>\n );\n}\n\n/** One option per row. */\nconst LIST_STEPS = { ArrowUp: -1, ArrowDown: 1 };\n\nfunction MenuButton({\n buttonRef,\n label,\n tooltip,\n open,\n disabled,\n styles,\n className,\n onPress,\n children,\n}: {\n buttonRef: Ref<HTMLButtonElement>;\n label: string;\n tooltip: string;\n open: boolean;\n disabled: boolean;\n styles: ReturnType<typeof dockedDatePickerStyles>;\n className: string | undefined;\n onPress: () => void;\n children: string;\n}) {\n return (\n <TooltipTrigger>\n <Button\n ref={buttonRef}\n variant=\"text\"\n aria-label={label}\n aria-expanded={open}\n // M3 menus: while its list is open the button looks the same, plus a pressed state.\n data-menu-open={open || undefined}\n disabled={disabled}\n onPress={onPress}\n className={styles.menuButton({ class: className })}\n >\n {/* The drop-down arrow trails the label here, which Button's one leading icon can't do. */}\n <span className=\"inline-flex items-center gap-[8px]\">\n {children}\n <span aria-hidden=\"true\" className=\"inline-flex size-[20px] items-center justify-center\">\n <span data-open={open || undefined} className={styles.menuIcon()}>\n <ArrowDropDownIcon />\n </span>\n </span>\n </span>\n </Button>\n <LazyTooltip>{tooltip}</LazyTooltip>\n </TooltipTrigger>\n );\n}\n\nfunction ChoiceList({\n label,\n autoFocus,\n styles,\n children,\n}: {\n label: string;\n autoFocus: boolean;\n styles: ReturnType<typeof dockedDatePickerStyles>;\n children: ReactNode;\n}) {\n return (\n <div\n role=\"radiogroup\"\n aria-label={label}\n className={styles.list()}\n ref={(element) => {\n const selected = element?.querySelector<HTMLElement>('[aria-checked=\"true\"]');\n selected?.scrollIntoView?.({ block: 'center' });\n if (autoFocus) selected?.focus({ preventScroll: true });\n }}\n >\n {children}\n </div>\n );\n}\n\nfunction Check({\n selected,\n styles,\n}: {\n selected: boolean;\n styles: ReturnType<typeof dockedDatePickerStyles>;\n}) {\n return <span className={styles.check()}>{selected && <CheckIcon />}</span>;\n}\n"],"mappings":"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"}
|
|
@@ -92,7 +92,10 @@ interface DatePickerCommonProps extends Omit<WrapperRootDOMProps, DescriptionAri
|
|
|
92
92
|
* `min` / `max` are shown disabled. @default [1900, 2100]
|
|
93
93
|
*/
|
|
94
94
|
yearRange?: [number, number];
|
|
95
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* Words the picker shows and announces, with English defaults. A {@link LabelsProvider} sets them
|
|
97
|
+
* for the whole app.
|
|
98
|
+
*/
|
|
96
99
|
labels?: Partial<DatePickerLabels>;
|
|
97
100
|
/**
|
|
98
101
|
* Web density of the input mode's text fields, `0` to `-3`: each step takes 4px off them
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { NO_DEFAULT_LABELS, useLabels } from "../labels/use-labels.js";
|
|
3
4
|
import { mergeDataTokens } from "../../utils/merge-data-tokens.js";
|
|
4
5
|
import { usePresence } from "../../primitives/use-presence.js";
|
|
5
6
|
import { Button } from "../button/Button.js";
|
|
@@ -65,10 +66,11 @@ function SingleDatePicker(props) {
|
|
|
65
66
|
createCalendar
|
|
66
67
|
});
|
|
67
68
|
const formatter = useDateFormatter({ dateStyle: "medium" });
|
|
68
|
-
const labels = props.labels
|
|
69
|
+
const labels = useLabels("DatePicker", NO_DEFAULT_LABELS, props.labels);
|
|
69
70
|
const headline = value ? formatter.format(value.toDate(getLocalTimeZone())) : labels.noSelection ?? "Selected date";
|
|
70
71
|
return /* @__PURE__ */ jsx(PickerFrame, {
|
|
71
72
|
...props,
|
|
73
|
+
labels,
|
|
72
74
|
range: false,
|
|
73
75
|
state,
|
|
74
76
|
headline,
|
|
@@ -110,7 +112,7 @@ function RangeDatePicker({ monthLayout = "scroll", ...props }) {
|
|
|
110
112
|
month: "short",
|
|
111
113
|
day: "numeric"
|
|
112
114
|
});
|
|
113
|
-
const labels = props.labels
|
|
115
|
+
const labels = useLabels("DatePicker", NO_DEFAULT_LABELS, props.labels);
|
|
114
116
|
const format = (date) => formatter.format(date.toDate(getLocalTimeZone()));
|
|
115
117
|
const anchor = state.anchorDate;
|
|
116
118
|
const headline = anchor ? `${format(anchor)} – ${labels.endDateLabel ?? "End date"}` : value ? `${format(value.start)} – ${format(value.end)}` : labels.noSelection ?? "Start date – End date";
|
|
@@ -124,6 +126,7 @@ function RangeDatePicker({ monthLayout = "scroll", ...props }) {
|
|
|
124
126
|
};
|
|
125
127
|
return /* @__PURE__ */ jsx(PickerFrame, {
|
|
126
128
|
...props,
|
|
129
|
+
labels,
|
|
127
130
|
range: true,
|
|
128
131
|
scroll,
|
|
129
132
|
state,
|