@med-o/ui 0.1.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/button/Button.tsx","../src/progress/Progress.tsx","../src/utils/cx.ts","../src/icon-button/IconButton.tsx","../src/tooltip/Tooltip.tsx","../src/text-field/TextField.tsx","../src/field/Field.tsx","../src/checkbox/Checkbox.tsx","../src/radio/Radio.tsx","../src/switch/Switch.tsx","../src/badge/Badge.tsx","../src/tag/Tag.tsx","../src/avatar/Avatar.tsx","../src/toggle-button/ToggleButton.tsx","../src/listbox/ListBox.tsx","../src/utils/highlight.tsx","../src/select/Select.tsx","../src/bottom-sheet/BottomSheet.tsx","../src/utils/useFitCount.ts","../src/utils/useMediaQuery.ts","../src/menu/Menu.tsx","../src/dialog/Dialog.tsx","../src/combobox/Combobox.tsx","../src/toast/Toast.tsx","../src/tabs/Tabs.tsx","../src/popover/Popover.tsx","../src/link/Link.tsx","../src/navigation/Navigation.tsx","../src/drawer/Drawer.tsx","../src/list/List.tsx","../src/list-view/ListView.tsx","../src/bulk-action-bar/BulkActionBar.tsx","../src/empty-state/EmptyState.tsx","../src/pagination/Pagination.tsx","../src/search/SearchField.tsx","../src/search/SearchResult.tsx","../src/search/QuickSearch.tsx","../src/breadcrumbs/Breadcrumbs.tsx","../src/accordion/Accordion.tsx","../src/slider/Slider.tsx","../src/number-field/NumberField.tsx","../src/alert/Alert.tsx","../src/card/Card.tsx","../src/table/Table.tsx","../src/table/ColumnsMenu.tsx","../src/upload/Upload.tsx","../src/date-time/Calendar.tsx","../src/date-time/DateField.tsx","../src/date-time/DatePicker.tsx","../src/index.ts","../src/media/Image.tsx","../src/media/EmbedConsent.tsx"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport { Button as AriaButton, type ButtonProps as AriaButtonProps } from 'react-aria-components';\nimport { Spinner } from '../progress/Progress';\nimport { cx } from '../utils/cx';\nimport './button.css';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'text' | 'ghost-danger';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps extends Omit<AriaButtonProps, 'children' | 'className' | 'style'> {\n /** Visual weight. One primary button per area. */\n variant?: ButtonVariant;\n /** sm 32 px · md 40 px · lg 48 px (touch). */\n size?: ButtonSize;\n /** Icon before the label (decorative, hidden from screen readers). */\n startIcon?: ReactNode;\n /** Icon after the label (decorative, hidden from screen readers). */\n endIcon?: ReactNode;\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Button – triggers an action. Built on React Aria: consistent press,\n * hover and focus behaviour on mouse, touch, keyboard and screen readers.\n * Use onPress instead of onClick and isDisabled instead of disabled.\n * While saving, set isPending and change the label („Saving…“): the button keeps its look and size.\n */\nexport function Button({ variant = 'primary', size = 'md', startIcon, endIcon, className, children, ...props }: ButtonProps) {\n // isPending: React Aria keeps focus and announces the pending state; a spinner replaces the start icon.\n const icon = props.isPending ? <Spinner decorative /> : startIcon;\n return (\n <AriaButton {...props} className={cx('medo-button', `medo-button--${variant}`, `medo-button--${size}`, className)}>\n {icon && (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-button__label\">{children}</span>\n {endIcon && (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {endIcon}\n </span>\n )}\n </AriaButton>\n );\n}\n\nexport interface ButtonGroupProps {\n /** footer: right, primary last · header: right, next to a title · content: left, primary first. */\n context?: 'footer' | 'header' | 'content';\n /** Buttons in reading order (footer: Cancel, Save · content: Get started, Learn more). */\n children: ReactNode;\n /** Footer only: a destructive action, placed on the far left and separated. */\n destructive?: ReactNode;\n /** Name of the group for screen readers, when it is not obvious from the context. */\n 'aria-label'?: string;\n className?: string;\n}\n\n/** Button group – spacing, alignment and mobile stacking for related buttons. */\nexport function ButtonGroup({ context = 'footer', children, destructive, className, ...props }: ButtonGroupProps) {\n return (\n <div\n role={props['aria-label'] ? 'group' : undefined}\n aria-label={props['aria-label']}\n className={cx('medo-button-group', `medo-button-group--${context}`, className)}\n >\n {destructive && context === 'footer' && <div className=\"medo-button-group__destructive\">{destructive}</div>}\n {children}\n </div>\n );\n}\n","import { useId, type CSSProperties, type ReactNode } from 'react';\nimport { Label, ProgressBar as AriaProgressBar, type ProgressBarProps as AriaProgressBarProps } from 'react-aria-components';\nimport { cx } from '../utils/cx';\nimport './progress.css';\n\n/* ---------- Spinner ---------- */\n\nexport interface SpinnerProps {\n /** sm 16 · md 20 · lg 24 · xl 40 px. */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /** current = text colour of the parent (default, fits every button) · brand · neutral · on-brand. */\n tone?: 'current' | 'brand' | 'neutral' | 'on-brand';\n /** Name for screen readers. */\n 'aria-label'?: string;\n /** Inside a control that already says what happens („Saving…“): hide the spinner from screen readers. */\n decorative?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SpinnerGraphic = () => (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <circle className=\"medo-spinner__track\" cx=\"12\" cy=\"12\" r=\"10\" />\n <circle className=\"medo-spinner__arc\" cx=\"12\" cy=\"12\" r=\"10\" pathLength={100} />\n </svg>\n);\n\n/** Spinner – short wait of unknown length. */\nexport function Spinner({ size = 'md', tone = 'current', decorative, className, style, ...props }: SpinnerProps) {\n const classes = cx('medo-spinner', `medo-spinner--${size}`, tone !== 'current' && `medo-spinner--${tone}`, className);\n if (decorative) {\n return (\n <span className={classes} style={style} aria-hidden=\"true\">\n <SpinnerGraphic />\n </span>\n );\n }\n return (\n <AriaProgressBar isIndeterminate aria-label={props['aria-label'] ?? 'Loading'} className={classes} style={style}>\n <SpinnerGraphic />\n </AriaProgressBar>\n );\n}\n\n/* ---------- Progress bar ---------- */\n\nexport interface ProgressBarProps extends Omit<AriaProgressBarProps, 'children' | 'className' | 'style'> {\n /** Visible label („Uploading 3 files“). Without it, set aria-label. */\n label?: ReactNode;\n /** Helper below the bar: files, time left, or what to do after an error. */\n description?: ReactNode;\n /** md 8 px in content · sm 4 px in dense rows (file list). */\n size?: 'sm' | 'md';\n /** success when done, error when it failed. Announced politely. */\n status?: 'default' | 'success' | 'error';\n /** Show the value („64 %“) next to the label. Hidden when indeterminate. */\n showValue?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Progress bar – measurable or long work. Built on React Aria ProgressBar:\n * role progressbar with value and value text. Use `valueLabel` for words („64 %, 2 of 3 files“).\n */\nexport function ProgressBar({\n label,\n description,\n size = 'md',\n status = 'default',\n showValue = true,\n className,\n style,\n ...props\n}: ProgressBarProps) {\n const descriptionId = useId();\n return (\n <AriaProgressBar\n {...props}\n aria-describedby={description ? descriptionId : undefined}\n className={cx(\n 'medo-progress',\n `medo-progress--${size}`,\n status !== 'default' && `medo-progress--${status}`,\n props.isIndeterminate && 'medo-progress--indeterminate',\n className,\n )}\n style={style}\n >\n {({ percentage, valueText, isIndeterminate }) => (\n <>\n {(label || (showValue && !isIndeterminate)) && (\n <div className=\"medo-progress__header\">\n {label && <Label className=\"medo-progress__label\">{label}</Label>}\n {showValue && !isIndeterminate && <span className=\"medo-progress__value\">{valueText}</span>}\n </div>\n )}\n <div className=\"medo-progress__track\">\n <div className=\"medo-progress__fill\" style={isIndeterminate ? undefined : { inlineSize: `${percentage}%` }} />\n </div>\n {description && (\n // Live only for the final state, so regular updates („12 s left“) do not chatter.\n <span id={descriptionId} className=\"medo-progress__description\" aria-live={status === 'default' ? undefined : 'polite'}>\n {description}\n </span>\n )}\n </>\n )}\n </AriaProgressBar>\n );\n}\n\n/* ---------- Skeleton ---------- */\n\nexport interface SkeletonProps {\n /** text: 12 px line · circle: avatar · rect: image or card. */\n shape?: 'text' | 'circle' | 'rect';\n /** Number of text lines; the last one is shorter. */\n lines?: number;\n /** Any CSS length, e.g. \"60%\", 160. Match the real content. */\n width?: CSSProperties['inlineSize'];\n height?: CSSProperties['blockSize'];\n className?: string;\n}\n\n/**\n * Skeleton – placeholder in the shape of the content.\n * Hidden from screen readers; mark the loading region with aria-busy=\"true\".\n */\nexport function Skeleton({ shape = 'text', lines = 1, width, height, className }: SkeletonProps) {\n const style: CSSProperties = { inlineSize: width, blockSize: height };\n const one = (key?: number) => (\n <span key={key} className={cx('medo-skeleton', `medo-skeleton--${shape}`, className)} style={style} aria-hidden=\"true\" />\n );\n if (shape !== 'text' || lines <= 1) return one();\n return (\n <span className=\"medo-skeleton-lines\" aria-hidden=\"true\">\n {Array.from({ length: lines }, (_, i) => one(i))}\n </span>\n );\n}\n","/** Joins class names and drops empty values. */\nexport const cx = (...classes: Array<string | false | null | undefined>) => classes.filter(Boolean).join(' ');\n","import type { CSSProperties, ReactNode } from 'react';\nimport { Button as AriaButton, type ButtonProps as AriaButtonProps } from 'react-aria-components';\nimport { Spinner } from '../progress/Progress';\nimport { Tooltip, TooltipTrigger, formatShortcut, resolveShortcut } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport '../button/button.css';\n\nexport interface IconButtonProps extends Omit<AriaButtonProps, 'children' | 'className' | 'style'> {\n /** Required: describes the action („Delete file“), because there is no visible label. */\n 'aria-label': string;\n icon: ReactNode;\n /**\n * ghost (default for toolbars) · secondary · primary · danger.\n * On images and video: media – round overlay/media fill for busy images ·\n * media-ghost – no fill, on a gradient bar (video controls).\n */\n variant?: 'ghost' | 'secondary' | 'primary' | 'danger' | 'media' | 'media-ghost';\n /** sm 32 · md 40 · lg 48 px with 16 / 20 / 24 px icons. Media variants: sm 28 with a 44 px hit area. */\n size?: 'sm' | 'md' | 'lg';\n /**\n * Tooltip text. Default: the aria-label, so sighted users see the same name.\n * Pass false to turn it off (e.g. when a visible label is next to the button).\n */\n tooltip?: ReactNode | false;\n /** Keyboard shortcut in aria-keyshortcuts syntax (e.g. „Control+C“). Exposed to screen readers and shown in the tooltip. */\n shortcut?: string;\n /** Visible form of the shortcut. Default: „Control+C“ → „Ctrl C“, „Meta+C“ → „⌘ C“. */\n shortcutLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Square icon-only action. Shares the Button styles. Shows its label as a tooltip. */\nexport function IconButton({ icon, variant = 'ghost', size = 'md', tooltip, shortcut, shortcutLabel, className, ...props }: IconButtonProps) {\n const button = (\n <AriaButton\n {...props}\n aria-keyshortcuts={shortcut && resolveShortcut(shortcut)}\n className={cx('medo-button', 'medo-button--icon-only', `medo-button--${variant}`, `medo-button--${size}`, className)}\n >\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {props.isPending ? <Spinner decorative /> : icon}\n </span>\n </AriaButton>\n );\n\n if (tooltip === false) return button;\n return (\n <TooltipTrigger>\n {button}\n <Tooltip shortcut={shortcutLabel ?? (shortcut && formatShortcut(shortcut))}>{tooltip ?? props['aria-label']}</Tooltip>\n </TooltipTrigger>\n );\n}\n","import { useContext, type ReactNode } from 'react';\nimport {\n Link as AriaLink,\n Tooltip as AriaTooltip,\n TooltipTrigger as AriaTooltipTrigger,\n TooltipTriggerStateContext,\n type LinkProps as AriaLinkProps,\n type TooltipProps as AriaTooltipProps,\n type TooltipTriggerComponentProps,\n} from 'react-aria-components';\nimport { cx } from '../utils/cx';\nimport './tooltip.css';\n\n/**\n * Wraps a focusable trigger (e.g. Button, IconButton) and its Tooltip.\n * Timing: 500 ms delay on hover, 100 ms close delay, instant on keyboard focus.\n * React Aria handles warm-up between neighbours, Escape and touch (no tooltip on touch).\n */\nexport function TooltipTrigger({ delay = 500, closeDelay = 100, ...props }: TooltipTriggerComponentProps) {\n return <AriaTooltipTrigger delay={delay} closeDelay={closeDelay} {...props} />;\n}\n\nexport interface TooltipProps extends Omit<AriaTooltipProps, 'children' | 'className'> {\n /** A few words, at most one sentence. No links or buttons. */\n children: ReactNode;\n /** Keyboard shortcut, shown dimmed after the text (e.g. „⌘C“). */\n shortcut?: string;\n className?: string;\n}\n\nconst KEY_LABELS: Record<string, string> = { Control: 'Ctrl', Meta: '⌘', Shift: '⇧', Alt: 'Alt' };\n\n/** True on macOS and iOS: „Mod“ means ⌘ there, Ctrl everywhere else. */\nconst isApple = () => typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent);\n\n/** „Mod+D“ → „Meta+D“ on Apple devices, „Control+D“ elsewhere (aria-keyshortcuts syntax). */\nexport const resolveShortcut = (keys: string) => keys.replace(/\\bMod\\b/g, isApple() ? 'Meta' : 'Control');\n\n/** Visible form of an aria-keyshortcuts value: „Control+C“ → „Ctrl C“, „Meta+C“ → „⌘ C“, „Mod+C“ → per platform. */\nexport const formatShortcut = (keys: string) =>\n resolveShortcut(keys)\n .split('+')\n .map((k) => KEY_LABELS[k] ?? k)\n .join(' ');\n\n/** Tooltip – short label on hover or focus. Top, 8 px offset, flips if needed. */\nexport function Tooltip({ children, shortcut, placement = 'top', offset = 8, className, ...props }: TooltipProps) {\n return (\n <AriaTooltip {...props} placement={placement} offset={offset} className={cx('medo-tooltip', className)}>\n <span>{children}</span>\n {shortcut && <kbd className=\"medo-tooltip__shortcut\">{shortcut}</kbd>}\n </AriaTooltip>\n );\n}\n\n/**\n * Link as a tooltip trigger. React Aria's Link takes focus but not hover from a TooltipTrigger –\n * this opens the tooltip on hover too. Internal (Navigation rail, Breadcrumbs), not exported from the package.\n */\nexport function TooltipLink(props: AriaLinkProps) {\n const tooltip = useContext(TooltipTriggerStateContext);\n return <AriaLink {...props} onHoverStart={() => tooltip?.open()} onHoverEnd={() => tooltip?.close()} />;\n}\n","import { useEffect, useState, type FormEvent, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Input as AriaInput,\n TextArea as AriaTextArea,\n TextField as AriaTextField,\n type ButtonProps as AriaButtonProps,\n type TextFieldProps as AriaTextFieldProps,\n} from 'react-aria-components';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { cx } from '../utils/cx';\nimport './input.css';\n\nexport type InputSize = 'sm' | 'md' | 'lg';\n\nexport interface TextFieldProps extends Omit<AriaTextFieldProps, 'children' | 'className' | 'style'> {\n /** Visible label. Always set one – a placeholder is no label. */\n label: ReactNode;\n /** Helper text below the field. Replaced by the error message when invalid. */\n description?: ReactNode;\n /** Error text shown when the field is invalid (isInvalid or failed validation). */\n errorMessage?: ReactNode;\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. Use lg on mobile and touch. Textareas: md or lg. */\n size?: InputSize;\n /** Decorative icon before the text (hidden from screen readers). */\n leadingIcon?: ReactNode;\n /** Trailing action, e.g. `<InputAction aria-label=\"Show password\" />`. */\n trailing?: ReactNode;\n /** Multi-line text (Textarea): min 3 rows, grows up to 8 rows. */\n multiline?: boolean;\n /** Soft limit: typing beyond is allowed, the counter turns red. Validate on submit. */\n characterLimit?: number;\n className?: string;\n}\n\n/** Text input with label, helper and error text (Field + Input / Textarea). */\nexport function TextField({\n label,\n description,\n errorMessage,\n placeholder,\n size = 'md',\n leadingIcon,\n trailing,\n multiline,\n characterLimit,\n className,\n onChange,\n ...props\n}: TextFieldProps) {\n const [length, setLength] = useState((props.value ?? props.defaultValue ?? '').length);\n const count = props.value !== undefined ? props.value.length : length;\n\n return (\n <AriaTextField\n {...props}\n className={cx('medo-field', className)}\n onChange={(value) => {\n setLength(value.length);\n onChange?.(value);\n }}\n >\n <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>\n {multiline ? (\n <AriaTextArea className={cx('medo-textarea', `medo-textarea--${size === 'lg' ? 'lg' : 'md'}`)} placeholder={placeholder} onInput={clearErrorWhenValid} />\n ) : (\n <div className={cx('medo-input', `medo-input--${size}`)}>\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n <AriaInput className=\"medo-input__control\" placeholder={placeholder} onInput={clearErrorWhenValid} />\n {trailing}\n </div>\n )}\n <FieldFooter description={description} errorMessage={errorMessage}>\n {characterLimit !== undefined && <CharacterCount count={count} limit={characterLimit} />}\n </FieldFooter>\n </AriaTextField>\n );\n}\n\n/**\n * „Reward early, punish late“: an error disappears as soon as the input is valid while typing –\n * new errors still only appear on blur or submit. React Aria commits validation on the native\n * change event (blur), so a valid input dispatches it early. Without this the error text vanished\n * on the next mousedown, the layout shifted and the click on e.g. „Save“ missed its target.\n * Checked after the render, when React Aria has updated custom validity (validate functions).\n */\nfunction clearErrorWhenValid(e: FormEvent<HTMLInputElement | HTMLTextAreaElement>) {\n const el = e.currentTarget;\n requestAnimationFrame(() => {\n if (el.validity.valid && el.closest('[data-invalid]')) el.dispatchEvent(new Event('change'));\n });\n}\n\n/** Visible counter plus a calm, delayed announcement for screen readers (pattern of GOV.UK). */\nfunction CharacterCount({ count, limit }: { count: number; limit: number }) {\n const over = count - limit;\n const text = over > 0 ? `${over} too many` : `${count} / ${limit}`;\n const [announcement, setAnnouncement] = useState('');\n\n useEffect(() => {\n const id = setTimeout(\n () => setAnnouncement(over > 0 ? `${over} characters too many` : `${limit - count} characters left`),\n 1000,\n );\n return () => clearTimeout(id);\n }, [count, limit, over]);\n\n return (\n <>\n <span className=\"medo-field__counter\" data-over={over > 0 || undefined} aria-hidden=\"true\">\n {text}\n </span>\n <span className=\"medo-visually-hidden\" aria-live=\"polite\">\n {announcement}\n </span>\n </>\n );\n}\n\nexport interface InputActionProps extends Omit<AriaButtonProps, 'className' | 'children'> {\n /** Required: icon-only buttons need an accessible name. */\n 'aria-label': string;\n icon: ReactNode;\n}\n\n/** Icon button inside an input, e.g. clear or show password. */\nexport function InputAction({ icon, ...props }: InputActionProps) {\n return (\n <AriaButton {...props} className=\"medo-input__action\">\n {icon}\n </AriaButton>\n );\n}\n","import type { ReactNode } from 'react';\nimport { FieldError, Label, Text, type ValidationResult } from 'react-aria-components';\nimport { CircleAlert } from 'lucide-react';\nimport '../utils/utilities.css';\nimport './field.css';\n\n/** Label with the visual required marker. The field itself is announced as required. */\nexport function FieldLabel({ children, isRequired }: { children: ReactNode; isRequired?: boolean }) {\n return (\n <Label className=\"medo-field__label\">\n {children}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </Label>\n );\n}\n\n/** Helper text and error message. The error replaces the helper text when the field is invalid. */\nexport function FieldFooter({\n description,\n errorMessage,\n children,\n}: {\n description?: ReactNode;\n /** A function gets the validation details (rangeUnderflow, badInput …) to name the rule. */\n errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);\n children?: ReactNode;\n}) {\n return (\n <div className=\"medo-field__footer\">\n {description && (\n <Text slot=\"description\" className=\"medo-field__description\">\n {description}\n </Text>\n )}\n <FieldError className=\"medo-field__error\">\n {(validation) => (\n <>\n <CircleAlert aria-hidden=\"true\" />\n <span>{(typeof errorMessage === 'function' ? errorMessage(validation) : errorMessage) || validation.validationErrors.join(' ')}</span>\n </>\n )}\n </FieldError>\n {children}\n </div>\n );\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport {\n CheckboxButton,\n CheckboxField,\n CheckboxGroup as AriaCheckboxGroup,\n Text,\n type CheckboxFieldProps,\n type CheckboxGroupProps as AriaCheckboxGroupProps,\n} from 'react-aria-components';\nimport { Check, Minus } from 'lucide-react';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { cx } from '../utils/cx';\nimport './choice.css';\n\nexport type ChoiceSize = 'md' | 'lg';\nexport const ChoiceSizeContext = createContext<ChoiceSize>('md');\n\nexport interface CheckboxProps extends Omit<CheckboxFieldProps, 'children' | 'className' | 'style'> {\n /** Label. Clicking it toggles the checkbox. */\n children?: ReactNode;\n /** Second line below the label. */\n description?: ReactNode;\n /** md (16 px box, 14 px text) · lg (20 px box, 16 px text, mobile). Inherits from a group. */\n size?: ChoiceSize;\n className?: string;\n}\n\n/** Checkbox – on its own or inside a CheckboxGroup. */\nexport function Checkbox({ children, description, size, className, ...props }: CheckboxProps) {\n const groupSize = useContext(ChoiceSizeContext);\n return (\n <CheckboxField {...props} className={cx('medo-choice', 'medo-checkbox', `medo-choice--${size ?? groupSize}`, className)}>\n <CheckboxButton className=\"medo-choice__button\">\n {({ isSelected, isIndeterminate }) => (\n <>\n <span className=\"medo-choice__control\" aria-hidden=\"true\">\n {isIndeterminate ? <Minus /> : isSelected ? <Check /> : null}\n </span>\n {children && <span className=\"medo-choice__label\">{children}</span>}\n </>\n )}\n </CheckboxButton>\n {description && (\n <Text slot=\"description\" className=\"medo-choice__description\">\n {description}\n </Text>\n )}\n </CheckboxField>\n );\n}\n\nexport interface CheckboxGroupProps extends Omit<AriaCheckboxGroupProps, 'children' | 'className' | 'style'> {\n /** Group label (rendered like a legend). Without it set `aria-label` – only where the context names the group (e.g. an Accordion title). */\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n size?: ChoiceSize;\n /** vertical (default) or horizontal for 2–3 short options. */\n orientation?: 'vertical' | 'horizontal';\n children: ReactNode;\n className?: string;\n}\n\n/** Several checkboxes with one label, helper and error text. */\nexport function CheckboxGroup({ label, description, errorMessage, size = 'md', orientation = 'vertical', children, className, ...props }: CheckboxGroupProps) {\n return (\n <AriaCheckboxGroup {...props} className={cx('medo-field', 'medo-field--group', className)} data-orientation={orientation}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <ChoiceSizeContext.Provider value={size}>\n <div className=\"medo-field__options\">{children}</div>\n </ChoiceSizeContext.Provider>\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaCheckboxGroup>\n );\n}\n","import { useContext, type ReactNode } from 'react';\nimport { RadioButton, RadioField, RadioGroup as AriaRadioGroup, Text, type RadioFieldProps, type RadioGroupProps as AriaRadioGroupProps } from 'react-aria-components';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ChoiceSizeContext, type ChoiceSize } from '../checkbox/Checkbox';\nimport { cx } from '../utils/cx';\nimport '../checkbox/choice.css';\n\nexport interface RadioProps extends Omit<RadioFieldProps, 'children' | 'className' | 'style'> {\n children?: ReactNode;\n description?: ReactNode;\n size?: ChoiceSize;\n className?: string;\n}\n\n/** One option of a RadioGroup. */\nexport function Radio({ children, description, size, className, ...props }: RadioProps) {\n const groupSize = useContext(ChoiceSizeContext);\n return (\n <RadioField {...props} className={cx('medo-choice', 'medo-radio', `medo-choice--${size ?? groupSize}`, className)}>\n <RadioButton className=\"medo-choice__button\">\n <span className=\"medo-choice__control\" aria-hidden=\"true\" />\n {children && <span className=\"medo-choice__label\">{children}</span>}\n </RadioButton>\n {description && (\n <Text slot=\"description\" className=\"medo-choice__description\">\n {description}\n </Text>\n )}\n </RadioField>\n );\n}\n\nexport interface RadioGroupProps extends Omit<AriaRadioGroupProps, 'children' | 'className' | 'style'> {\n /** Group label (rendered like a legend). Without it set `aria-label` – only where the context names the group (e.g. an Accordion title). */\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n size?: ChoiceSize;\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Pick exactly one of 2–4 visible options (5 or more: use a Select).\n * Arrow keys move and select; a choice cannot be removed again.\n */\nexport function RadioGroup({ label, description, errorMessage, size = 'md', children, className, ...props }: RadioGroupProps) {\n return (\n <AriaRadioGroup {...props} className={cx('medo-field', 'medo-field--group', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <ChoiceSizeContext.Provider value={size}>\n <div className=\"medo-field__options\">{children}</div>\n </ChoiceSizeContext.Provider>\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaRadioGroup>\n );\n}\n","import type { ReactNode } from 'react';\nimport { SwitchButton, SwitchField, Text, type SwitchFieldProps } from 'react-aria-components';\nimport { Check, LoaderCircle, X } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport './switch.css';\n\nexport interface SwitchProps extends Omit<SwitchFieldProps, 'children' | 'className' | 'style'> {\n /** Label. Describes the setting, never the state („Notifications“, not „On“). */\n children: ReactNode;\n description?: ReactNode;\n /** md (36 × 20) · lg (44 × 24, mobile). */\n size?: 'md' | 'lg';\n /** start: label first, switch at the end (settings lists). end: switch first (forms). */\n labelPosition?: 'start' | 'end';\n /** While the change is being saved. The switch cannot be toggled meanwhile. */\n isLoading?: boolean;\n className?: string;\n}\n\n/** Switch – on / off with immediate effect. */\nexport function Switch({\n children,\n description,\n size = 'md',\n labelPosition = 'end',\n isLoading,\n isReadOnly,\n className,\n ...props\n}: SwitchProps) {\n return (\n <SwitchField\n {...props}\n isReadOnly={isReadOnly || isLoading}\n aria-busy={isLoading || undefined}\n className={cx('medo-switch', `medo-switch--${size}`, `medo-switch--label-${labelPosition}`, className)}\n >\n <SwitchButton className=\"medo-switch__button\">\n {({ isSelected }) => (\n <>\n <span className=\"medo-switch__track\" aria-hidden=\"true\">\n <span className=\"medo-switch__thumb\">\n {isLoading ? <LoaderCircle className=\"medo-switch__spinner\" /> : isSelected ? <Check /> : <X />}\n </span>\n </span>\n <span className=\"medo-switch__label\">{children}</span>\n </>\n )}\n </SwitchButton>\n {description && (\n <Text slot=\"description\" className=\"medo-switch__description\">\n {description}\n </Text>\n )}\n </SwitchField>\n );\n}\n","import type { HTMLAttributes, ReactNode } from 'react';\nimport { cx } from '../utils/cx';\nimport '../utils/utilities.css';\nimport './badge.css';\n\nexport type BadgeTone = 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n /** Meaning: success, warning, danger, info. Brand for „New“, neutral for everything else. */\n tone?: BadgeTone;\n /** sm 20 px · md 24 px. */\n size?: 'sm' | 'md';\n /** Leading dot in the text colour, so the status does not rely on colour alone. */\n dot?: boolean;\n /** Leading icon (12 px, decorative). Ignored when `dot` is set. */\n icon?: ReactNode;\n /** 1–2 words, sentence case. */\n children: ReactNode;\n}\n\n/**\n * Badge – short, non-interactive status label.\n * Plain text: never clickable. For a badge that changes live, pass role=\"status\".\n */\nexport function Badge({ tone = 'neutral', size = 'md', dot, icon, className, children, ...props }: BadgeProps) {\n return (\n <span {...props} className={cx('medo-badge', `medo-badge--${tone}`, `medo-badge--${size}`, className)}>\n {dot ? (\n <span className=\"medo-badge__dot\" aria-hidden=\"true\" />\n ) : (\n icon && (\n <span className=\"medo-badge__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )\n )}\n {children}\n </span>\n );\n}\n\nexport interface BadgeCountProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n count: number;\n /** Above this number the badge shows „99+“. */\n max?: number;\n tone?: 'danger' | 'brand' | 'neutral';\n /** sm 16 px · md 20 px. */\n size?: 'sm' | 'md';\n /**\n * Text for screen readers, e.g. „3 unread messages“.\n * Without it the number is hidden: then the parent names it („Notifications, 3 unread“).\n */\n label?: string;\n}\n\n/** Count for notifications. Hidden at 0. */\nexport function BadgeCount({ count, max = 99, tone = 'danger', size = 'md', label, className, ...props }: BadgeCountProps) {\n if (count <= 0) return null;\n const text = count > max ? `${max}+` : String(count);\n return (\n <span\n {...props}\n aria-hidden={label ? undefined : true}\n className={cx('medo-badge-count', `medo-badge-count--${tone}`, `medo-badge-count--${size}`, className)}\n >\n <span aria-hidden={label ? true : undefined}>{text}</span>\n {label && <span className=\"medo-visually-hidden\">{label}</span>}\n </span>\n );\n}\n\nexport interface BadgeDotProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n tone?: BadgeTone;\n /** Text for screen readers („Unread“, „Online“). Without it the dot is decorative. */\n label?: string;\n}\n\n/** Dot for unread or presence. Always pair it with text or a label. */\nexport function BadgeDot({ tone = 'neutral', label, className, ...props }: BadgeDotProps) {\n return (\n <span\n {...props}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={cx('medo-badge-dot', `medo-badge-dot--${tone}`, className)}\n />\n );\n}\n","import { createContext, useContext, useRef, useState, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Tag as AriaTag,\n TagGroup as AriaTagGroup,\n TagList,\n Text,\n type Key,\n type TagGroupProps as AriaTagGroupProps,\n type TagListProps,\n type TagProps as AriaTagProps,\n} from 'react-aria-components';\nimport { Check, X } from 'lucide-react';\nimport { FieldLabel } from '../field/Field';\nimport { cx } from '../utils/cx';\nimport './tag.css';\n\ntype TagSize = 'sm' | 'md';\nconst TagSizeContext = createContext<TagSize>('md');\n\nexport interface TagGroupProps<T> extends Omit<AriaTagGroupProps, 'children' | 'className' | 'style'> {\n /** Visible label. Without it, set aria-label. */\n label?: ReactNode;\n /** Helper text below the tags. */\n description?: ReactNode;\n /** sm 24 px · md 32 px. Follows the field size (Select sm/md → sm, lg/mobile → md). */\n size?: TagSize;\n /** Tags, or a render function together with `items`. */\n children: TagListProps<T>['children'];\n items?: Iterable<T>;\n /** Shown when there are no tags. */\n renderEmptyState?: () => ReactNode;\n /** Text announced after a removal. Default: „{label} removed“. */\n removedMessage?: (labels: string[]) => string;\n className?: string;\n}\n\n/**\n * Tag group – a labelled list of tags. Built on React Aria TagGroup:\n * arrow keys move between tags, Backspace/Delete removes, Space/Enter toggles a filter.\n *\n * Two roles, never mixed in one group:\n * - removable values: pass `onRemove`\n * - filters: pass `selectionMode=\"multiple\"` (or \"single\"). Click again to deselect.\n */\nexport function TagGroup<T extends object>({\n label,\n description,\n size = 'md',\n children,\n items,\n renderEmptyState,\n onRemove,\n removedMessage = (labels) => `${labels.join(', ')} removed`,\n className,\n ...props\n}: TagGroupProps<T>) {\n const ref = useRef<HTMLDivElement>(null);\n const [announcement, setAnnouncement] = useState('');\n\n // Removals are announced politely, so screen reader users know it worked.\n const handleRemove =\n onRemove &&\n ((keys: Set<Key>) => {\n const labels = [...keys].map(\n (key) => ref.current?.querySelector(`[data-key=\"${CSS.escape(String(key))}\"] .medo-tag__label`)?.textContent ?? String(key),\n );\n onRemove(keys);\n setAnnouncement(removedMessage(labels));\n });\n\n return (\n <AriaTagGroup {...props} ref={ref} onRemove={handleRemove} className={cx('medo-field', 'medo-field--group', className)}>\n {label && <FieldLabel>{label}</FieldLabel>}\n <TagSizeContext.Provider value={size}>\n <TagList items={items} renderEmptyState={renderEmptyState} className=\"medo-tag-list\">\n {children}\n </TagList>\n </TagSizeContext.Provider>\n {description && (\n <div className=\"medo-field__footer\">\n <Text slot=\"description\" className=\"medo-field__description\">\n {description}\n </Text>\n </div>\n )}\n <span className=\"medo-visually-hidden\" aria-live=\"polite\">\n {announcement}\n </span>\n </AriaTagGroup>\n );\n}\n\nexport interface TagProps extends Omit<AriaTagProps, 'children' | 'className'> {\n /** Short label; long text is truncated at 200 px. */\n children: ReactNode;\n /** Leading icon (decorative). A selected filter shows a check instead. */\n icon?: ReactNode;\n className?: string;\n}\n\n/** A single tag inside a TagGroup. */\nexport function Tag({ children, icon, textValue, className, ...props }: TagProps) {\n const size = useContext(TagSizeContext);\n return (\n <AriaTag\n {...props}\n textValue={textValue ?? (typeof children === 'string' ? children : undefined)}\n className={({ selectionMode }) =>\n cx('medo-tag', `medo-tag--${size}`, selectionMode !== 'none' && 'medo-tag--selectable', className)\n }\n >\n {({ allowsRemoving, isSelected, selectionMode }) => (\n <>\n {selectionMode !== 'none' && isSelected ? (\n <span className=\"medo-tag__icon\" aria-hidden=\"true\">\n <Check />\n </span>\n ) : (\n icon && (\n <span className=\"medo-tag__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )\n )}\n <span className=\"medo-tag__label\">{children}</span>\n {allowsRemoving && (\n <AriaButton slot=\"remove\" className=\"medo-tag__remove\">\n <X aria-hidden=\"true\" />\n </AriaButton>\n )}\n </>\n )}\n </AriaTag>\n );\n}\n","import {\n Children,\n cloneElement,\n createContext,\n isValidElement,\n useContext,\n useEffect,\n useState,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { Button as AriaButton } from 'react-aria-components';\nimport { Building2, User } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport './avatar.css';\n\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\nexport type AvatarStatus = 'online' | 'away' | 'busy' | 'offline';\n\nconst TONES = ['blue', 'violet', 'pink', 'amber', 'green', 'teal'] as const;\n/** Size for avatars inside a group or a list row (internal, set by the container). */\nexport const AvatarSizeContext = createContext<AvatarSize | undefined>(undefined);\n\n/** Same input, same tone: a small string hash modulo 6. */\nfunction toneFor(key: string) {\n let hash = 0;\n for (const char of key) hash = (hash * 31 + char.codePointAt(0)!) | 0;\n return TONES[Math.abs(hash) % TONES.length];\n}\n\n/** First letters of first and last name; one word: first two letters. */\nexport function initialsOf(name: string) {\n const words = name.trim().split(/\\s+/).filter(Boolean);\n if (words.length === 0) return '';\n if (words.length === 1) return Array.from(words[0]).slice(0, 2).join('').toUpperCase();\n return (Array.from(words[0])[0] + Array.from(words[words.length - 1])[0]).toUpperCase();\n}\n\nconst STATUS_TEXT: Record<AvatarStatus, string> = { online: 'online', away: 'away', busy: 'busy', offline: 'offline' };\n\nexport interface AvatarProps {\n /** Person or organization name. Used for alt text, initials and (without `colorKey`) the tone. */\n name?: string;\n /** Photo URL. Falls back to initials if it is missing or fails to load. */\n src?: string;\n /** xs 20 · sm 24 · md 32 · lg 40 · xl 56 · 2xl 80 px. */\n size?: AvatarSize;\n /** circle = person · square = organization, team, workspace. */\n shape?: 'circle' | 'square';\n /** Stable id (user id) for the initials colour, so it survives name changes. */\n colorKey?: string;\n /** Presence dot. Also added to the accessible name („Lea M., online“). */\n status?: AvatarStatus;\n /** Words for the status in the accessible name. */\n statusLabels?: Partial<Record<AvatarStatus, string>>;\n /** Next to a visible name the avatar is decorative and hidden from screen readers. */\n decorative?: boolean;\n /** Accessible name when the name is unknown (guest, deleted account). */\n unknownLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Avatar – picture of a person or organization with fallback image → initials → icon. */\nexport function Avatar({\n name,\n src,\n size,\n shape = 'circle',\n colorKey,\n status,\n statusLabels,\n decorative,\n unknownLabel,\n className,\n style,\n}: AvatarProps) {\n const groupSize = useContext(AvatarSizeContext);\n const finalSize = size ?? groupSize ?? 'md';\n const [failed, setFailed] = useState(false);\n useEffect(() => setFailed(false), [src]);\n\n const initials = name ? initialsOf(name) : '';\n const showImage = Boolean(src) && !failed;\n const tone = initials ? toneFor(colorKey ?? name!) : 'neutral';\n const statusText = status ? (statusLabels?.[status] ?? STATUS_TEXT[status]) : undefined;\n const fallbackName = unknownLabel ?? (shape === 'square' ? 'Unknown organization' : 'Unknown person');\n const label = [name || fallbackName, statusText].filter(Boolean).join(', ');\n\n return (\n <span\n role={decorative ? undefined : 'img'}\n aria-label={decorative ? undefined : label}\n aria-hidden={decorative || undefined}\n className={cx(\n 'medo-avatar',\n `medo-avatar--${finalSize}`,\n `medo-avatar--${shape}`,\n `medo-avatar--${tone}`,\n showImage && 'medo-avatar--has-image',\n className,\n )}\n style={style}\n >\n {initials ? (\n <span className=\"medo-avatar__initials\" aria-hidden=\"true\">\n {initials}\n </span>\n ) : (\n <span className=\"medo-avatar__icon\" aria-hidden=\"true\">\n {shape === 'square' ? <Building2 /> : <User />}\n </span>\n )}\n {showImage && <img className=\"medo-avatar__image\" src={src} alt=\"\" onError={() => setFailed(true)} />}\n {status && <span className={cx('medo-avatar__status', `medo-avatar__status--${status}`)} aria-hidden=\"true\" />}\n </span>\n );\n}\n\nexport interface AvatarGroupProps {\n /** Avatars, most relevant first (owner, you). */\n children: ReactNode;\n /** Visible avatars before „+N“. */\n max?: number;\n /** xs · sm · md · lg. */\n size?: Exclude<AvatarSize, 'xl' | '2xl'>;\n /** Name of the group, e.g. „Assignees“. */\n 'aria-label': string;\n /** Opens the full list (e.g. a popover). Without it „+N“ is plain text. */\n onMorePress?: () => void;\n /** Accessible name of „+N“. Default: „N more“. */\n moreLabel?: (count: number) => string;\n className?: string;\n}\n\n/** Overlapping avatars, max 4 + „+N“. */\nexport function AvatarGroup({\n children,\n max = 4,\n size = 'md',\n onMorePress,\n moreLabel = (n) => `${n} more`,\n className,\n ...props\n}: AvatarGroupProps) {\n const items = Children.toArray(children);\n const visible = items.slice(0, max);\n const hidden = items.length - visible.length;\n const moreClass = cx('medo-avatar', `medo-avatar--${size}`, 'medo-avatar--circle', 'medo-avatar--neutral', 'medo-avatar--more');\n\n return (\n <div role=\"group\" aria-label={props['aria-label']} className={cx('medo-avatar-group', `medo-avatar-group--${size}`, className)}>\n <AvatarSizeContext.Provider value={size}>\n {visible.map((child, i) =>\n // The first avatar sits on top.\n isValidElement<AvatarProps>(child)\n ? cloneElement(child as ReactElement<AvatarProps>, { style: { ...child.props.style, zIndex: visible.length - i } })\n : child,\n )}\n </AvatarSizeContext.Provider>\n {hidden > 0 &&\n (onMorePress ? (\n <AriaButton className={moreClass} onPress={onMorePress} aria-label={moreLabel(hidden)}>\n +{hidden}\n </AriaButton>\n ) : (\n <span className={moreClass} role=\"img\" aria-label={moreLabel(hidden)}>\n +{hidden}\n </span>\n ))}\n </div>\n );\n}\n","import { createContext, useContext, useEffect, useRef, type CSSProperties, type ReactNode } from 'react';\nimport {\n SelectionIndicator,\n Separator,\n ToggleButton as AriaToggleButton,\n ToggleButtonGroup as AriaToggleButtonGroup,\n Toolbar as AriaToolbar,\n type ToggleButtonGroupProps as AriaToggleButtonGroupProps,\n type ToggleButtonProps as AriaToggleButtonProps,\n type ToolbarProps as AriaToolbarProps,\n} from 'react-aria-components';\nimport { Tooltip, TooltipTrigger, formatShortcut, resolveShortcut } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport '../button/button.css';\nimport './toggle-button.css';\n\ntype ToggleSize = 'sm' | 'md' | 'lg';\n\n/** Item size set by a group (segmented items are one size smaller than the group). */\nconst ToggleSizeContext = createContext<ToggleSize | null>(null);\n/** Segmented groups show a sliding indicator (iOS segmented control). */\nconst SegmentedContext = createContext(false);\n\nexport interface ToggleButtonProps extends Omit<AriaToggleButtonProps, 'children' | 'className' | 'style'> {\n /** Visible label. It never changes with the state („Bold“ stays „Bold“). Leave out for icon only. */\n children?: ReactNode;\n /** Leading icon; alone it makes an icon-only toggle (then aria-label is required). */\n icon?: ReactNode;\n /** sm 32 · md 40 · lg 48 px, like Button. Inside a group the group sets it. */\n size?: ToggleSize;\n /** Icon only: tooltip text. Default: the aria-label. false turns it off. */\n tooltip?: ReactNode | false;\n /** Keyboard shortcut in aria-keyshortcuts syntax (e.g. „Control+B“), shown in the tooltip. */\n shortcut?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Toggle Button – a button that stays pressed.\n * Built on React Aria ToggleButton: announced as pressed / not pressed (aria-pressed).\n * For an immediate, local effect (bold, mute, favourite). Saved settings use Switch, navigation uses Tabs.\n */\nexport function ToggleButton({ children, icon, size, tooltip, shortcut, className, ...props }: ToggleButtonProps) {\n const groupSize = useContext(ToggleSizeContext);\n const segmented = useContext(SegmentedContext);\n const s = groupSize ?? size ?? 'md';\n const iconOnly = !children;\n const button = (\n <AriaToggleButton\n {...props}\n aria-keyshortcuts={shortcut && resolveShortcut(shortcut)}\n className={cx('medo-button', `medo-button--${s}`, iconOnly && 'medo-button--icon-only', 'medo-toggle', className)}\n >\n {/* Segmented: the selected fill is an indicator that slides from the previous item (React Aria SelectionIndicator). */}\n {segmented && <SelectionIndicator className=\"medo-toggle__indicator\" />}\n {icon && (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n {children}\n </AriaToggleButton>\n );\n\n if (!iconOnly || tooltip === false) return button;\n return (\n <TooltipTrigger>\n {button}\n <Tooltip shortcut={shortcut && formatShortcut(shortcut)}>{tooltip ?? props['aria-label']}</Tooltip>\n </TooltipTrigger>\n );\n}\n\nexport interface ToggleButtonGroupProps extends Omit<AriaToggleButtonGroupProps, 'children' | 'className' | 'style'> {\n /**\n * segmented: switch between 2–5 views, exactly one on, shared container.\n * toolbar: formatting options, any combination (or selectionMode=\"single\", e.g. text alignment), no container.\n */\n variant?: 'segmented' | 'toolbar';\n /** Height of the group: md 40 · lg 48 (segmented items are one size smaller). */\n size?: 'md' | 'lg';\n /** Segmented only: full width, items share the space (mobile). */\n fullWidth?: boolean;\n /** Required when there is no visible label: names the group („View“). */\n 'aria-label'?: string;\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Toggle button group. Built on React Aria ToggleButtonGroup:\n * Tab enters once on the selected item, arrow keys move between items.\n */\nexport function ToggleButtonGroup({\n variant = 'segmented',\n size = 'md',\n fullWidth,\n selectionMode,\n disallowEmptySelection,\n children,\n className,\n ...props\n}: ToggleButtonGroupProps) {\n const segmented = variant === 'segmented';\n /*\n * Workaround for React Aria: inside a Toolbar a multi-select group switches to role=\"group\" after\n * mounting but keeps aria-orientation, which ARIA does not allow on a group (axe: aria-allowed-attr).\n * React re-sets the attribute only when its value changes, so removing it once per change is enough.\n */\n const ref = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const fix = () => {\n if (el.getAttribute('role') === 'group' && el.hasAttribute('aria-orientation')) el.removeAttribute('aria-orientation');\n };\n fix();\n const observer = new MutationObserver(fix);\n observer.observe(el, { attributes: true, attributeFilter: ['role', 'aria-orientation'] });\n return () => observer.disconnect();\n }, []);\n const itemSize: ToggleSize = segmented ? (size === 'lg' ? 'md' : 'sm') : size;\n return (\n <AriaToggleButtonGroup\n {...props}\n ref={ref}\n selectionMode={segmented ? 'single' : (selectionMode ?? 'multiple')}\n disallowEmptySelection={segmented || disallowEmptySelection}\n className={cx('medo-toggle-group', `medo-toggle-group--${variant}`, `medo-toggle-group--${size}`, segmented && fullWidth && 'medo-toggle-group--full', className)}\n >\n <SegmentedContext.Provider value={segmented}>\n <ToggleSizeContext.Provider value={itemSize}>{children}</ToggleSizeContext.Provider>\n </SegmentedContext.Provider>\n </AriaToggleButtonGroup>\n );\n}\n\nexport interface ToolbarProps extends Omit<AriaToolbarProps, 'className' | 'style'> {\n /** Required: names the toolbar („Text formatting“). */\n 'aria-label': string;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Toolbar – several toggle groups (and buttons) in one row.\n * Built on React Aria Toolbar: one Tab stop for the whole toolbar, arrow keys move across all groups.\n */\nexport function Toolbar({ className, ...props }: ToolbarProps) {\n return <AriaToolbar {...props} className={cx('medo-toolbar', className)} />;\n}\n\n/** Divider between groups in a Toolbar (1 px border/default, 24 px high). */\nexport function ToolbarSeparator() {\n return <Separator orientation=\"vertical\" className=\"medo-toolbar__separator\" />;\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport {\n Collection,\n ComboBoxStateContext,\n Header,\n ListBox as AriaListBox,\n ListBoxItem,\n ListBoxSection as AriaListBoxSection,\n Text,\n type ListBoxItemProps,\n type ListBoxProps as AriaListBoxProps,\n} from 'react-aria-components';\nimport { Check } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport { Highlight as SharedHighlight } from '../utils/highlight';\nimport '../checkbox/choice.css';\nimport './listbox.css';\n\nexport type ListBoxSize = 'md' | 'lg';\n\nconst ListBoxSizeContext = createContext<ListBoxSize>('md');\n\nexport interface ListBoxProps<T> extends Omit<AriaListBoxProps<T>, 'className' | 'style'> {\n /** md on desktop · lg on mobile and in the Bottom Sheet. */\n size?: ListBoxSize;\n className?: string;\n}\n\n/**\n * Listbox – the list behind Select, Combobox and Bottom Sheet.\n * Built on React Aria ListBox: arrow keys, type-ahead, Home/End; sections and separators.\n */\nexport function ListBox<T extends object>({ size = 'md', className, ...props }: ListBoxProps<T>) {\n return (\n <ListBoxSizeContext.Provider value={size}>\n <AriaListBox {...props} className={cx('medo-listbox', `medo-listbox--${size}`, className)} />\n </ListBoxSizeContext.Provider>\n );\n}\n\nexport interface OptionProps extends Omit<ListBoxItemProps, 'children' | 'className' | 'style'> {\n /** Label. Long labels wrap; keep them short and put details into the description. */\n children: ReactNode;\n /** Second line in text/secondary. */\n description?: ReactNode;\n /** Decorative leading icon. */\n icon?: ReactNode;\n}\n\n/** Option – one row in a Listbox. Single: check on the right. Multi: checkbox on the left. */\nexport function Option({ children, description, icon, textValue, ...props }: OptionProps) {\n const size = useContext(ListBoxSizeContext);\n return (\n <ListBoxItem {...props} textValue={textValue ?? (typeof children === 'string' ? children : undefined)} className=\"medo-option\">\n {({ isSelected, selectionMode }) => (\n <>\n {selectionMode === 'multiple' && (\n <span\n className={cx('medo-choice', 'medo-checkbox', `medo-choice--${size}`, 'medo-option__checkbox')}\n data-selected={isSelected || undefined}\n aria-hidden=\"true\"\n >\n <span className=\"medo-choice__control\">{isSelected && <Check />}</span>\n </span>\n )}\n {icon && (\n <span className=\"medo-option__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-option__content\">\n <Text slot=\"label\" className=\"medo-option__label\">\n <Highlight>{children}</Highlight>\n </Text>\n {description && (\n <Text slot=\"description\" className=\"medo-option__description\">\n {description}\n </Text>\n )}\n </span>\n {selectionMode !== 'multiple' && isSelected && (\n <span className=\"medo-option__check\" aria-hidden=\"true\">\n <Check />\n </span>\n )}\n </>\n )}\n </ListBoxItem>\n );\n}\n\nexport interface ListBoxSectionProps<T> {\n /** Group heading (overline). Use headings only with two or more groups. Without a title, set aria-label. */\n title?: ReactNode;\n 'aria-label'?: string;\n children: ReactNode | ((item: T) => ReactNode);\n items?: Iterable<T>;\n id?: string;\n}\n\n/**\n * A group of options with a heading (announced as the name of the group).\n * Groups are divided by a line automatically (a separator element is not allowed inside a listbox).\n */\nexport function ListBoxSection<T extends object>({ title, children, items, id, ...props }: ListBoxSectionProps<T>) {\n return (\n <AriaListBoxSection id={id} aria-label={props['aria-label']} className=\"medo-listbox__section\">\n {title && <Header className=\"medo-listbox__header\">{title}</Header>}\n {typeof children === 'function' ? <Collection items={items}>{children}</Collection> : children}\n </AriaListBoxSection>\n );\n}\n\n/** Message row for empty and loading states – never an empty popup. Announced as status. */\nexport function ListBoxMessage({ children }: { children: ReactNode }) {\n return (\n <div className=\"medo-listbox__message\" role=\"status\">\n {children}\n </div>\n );\n}\n\n/* ---------- Match highlight (Combobox) ---------- */\n\n/** Search text to highlight, for lists filtered outside a ComboBox (e.g. the search in a Bottom Sheet, Quick search). */\nexport const OptionHighlightContext = createContext<string | null>(null);\n\n/**\n * Inside a Combobox: shows the typed text in bold within the option label (contains match,\n * case and accent insensitive, „mul“ → „Müller“). Visual only; screen readers read plain text.\n */\nfunction Highlight({ children }: { children: ReactNode }) {\n const combo = useContext(ComboBoxStateContext);\n const external = useContext(OptionHighlightContext);\n let query = (external ?? combo?.inputValue ?? '').trim();\n // The input shows the chosen value (single): nothing to highlight then.\n if (combo?.selectedItems.some((item) => item?.textValue === query)) query = '';\n if (!query || typeof children !== 'string') return <>{children}</>;\n return <SharedHighlight text={children} query={query} as=\"span\" className=\"medo-option__match\" />;\n}\n","import type { ReactNode } from 'react';\n\nconst plain = (text: string) =>\n text\n .normalize('NFD')\n .replace(/\\p{Diacritic}/gu, '')\n .toLocaleLowerCase();\n\n/**\n * Splits a text into parts that match the query and parts that don't – contains match, case and\n * accent insensitive („mul“ → „Müller“). Indices stay in the original text. `all`: every match, else the first.\n */\nexport function matchParts(text: string, query: string, all = false): { text: string; match: boolean }[] {\n const q = plain(query.trim());\n if (!q) return [{ text, match: false }];\n // Map every character of the text to its plain form, so indices stay in the original text.\n const chars = [...text];\n const map: number[] = [];\n let flat = '';\n chars.forEach((char, i) => {\n const p = plain(char);\n flat += p;\n for (let k = 0; k < p.length; k++) map.push(i);\n });\n const parts: { text: string; match: boolean }[] = [];\n let last = 0;\n let from = 0;\n while (from <= flat.length - q.length) {\n const at = flat.indexOf(q, from);\n if (at < 0) break;\n const start = map[at];\n const end = map[at + q.length - 1] + 1;\n if (start > last) parts.push({ text: chars.slice(last, start).join(''), match: false });\n parts.push({ text: chars.slice(start, end).join(''), match: true });\n last = end;\n from = at + q.length;\n if (!all) break;\n }\n if (last < chars.length) parts.push({ text: chars.slice(last).join(''), match: false });\n return parts;\n}\n\n/** Shows the matching parts of a text in bold (`className` on each match). Visual only; screen readers read plain text. */\nexport function Highlight({\n text,\n query,\n all = false,\n as: Tag = 'mark',\n className,\n}: {\n text: string;\n query?: string;\n all?: boolean;\n as?: 'mark' | 'span';\n className?: string;\n}): ReactNode {\n if (!query?.trim()) return text;\n return matchParts(text, query, all).map((part, i) =>\n part.match ? (\n <Tag key={i} className={className}>\n {part.text}\n </Tag>\n ) : (\n part.text\n ),\n );\n}\n","import { useContext, useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Popover,\n Select as AriaSelect,\n SelectStateContext,\n SelectValue,\n type Key,\n type SelectProps as AriaSelectProps,\n} from 'react-aria-components';\nimport { ChevronDown, X } from 'lucide-react';\nimport { BottomSheetPopover } from '../bottom-sheet/BottomSheet';\nimport { Button } from '../button/Button';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox } from '../listbox/ListBox';\nimport { InputAction, type InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { useFitCount } from '../utils/useFitCount';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\n\ntype SelectMode = 'single' | 'multiple';\ntype ValueOf<M extends SelectMode> = M extends 'multiple' ? Key[] : Key | null;\n\n/** Where the options open. auto: popover on desktop; below 640 px native picker (single) or Bottom Sheet (multi). */\nexport type SelectOverlay = 'auto' | 'popover' | 'sheet' | 'native';\nimport '../text-field/input.css';\nimport '../tag/tag.css';\nimport './select.css';\n\nexport interface SelectProps<T extends object, M extends SelectMode = 'single'> extends Omit<AriaSelectProps<T, M>, 'children' | 'className' | 'style' | 'placeholder'> {\n /** Visible label. Without it set `aria-label` – only where the context names the field (filter bars, toolbars). */\n label?: ReactNode;\n /** Helper text below the field. Replaced by the error message when invalid. */\n description?: ReactNode;\n /** Error text shown when the field is invalid. Validate on submit or blur, not while open. */\n errorMessage?: ReactNode;\n /** A hint like „Select…“. Never required information. */\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. lg on mobile (opens the lg list). */\n size?: InputSize;\n /** Decorative icon before the value. */\n leadingIcon?: ReactNode;\n /** Single only: shows a clear button for optional fields. Multi always has clear-all. */\n clearable?: boolean;\n /** Value can be read and copied but not changed. Not the same as disabled. */\n isReadOnly?: boolean;\n /** Options as data; then pass a render function as children. */\n items?: Iterable<T>;\n /** Option and ListBoxSection elements, or a render function with items. */\n children: ReactNode | ((item: T) => ReactNode);\n /** auto (default) · popover · sheet (Bottom Sheet) · native (system picker, single only). */\n overlay?: SelectOverlay;\n /**\n * Multi: what happens with the selection. live (forms): it is the value, nothing else happens.\n * onClose (filters, reloads): `onApply` runs once when the list closes – any way – and only if the selection changed.\n */\n commit?: 'live' | 'onClose';\n /** commit=\"onClose\": apply the selection (load results, write the URL …). */\n onApply?: (value: ValueOf<M>) => void;\n /** commit=\"onClose\": label of the primary sheet button, ideally with the live result count („Show 128 results“). */\n resultLabel?: (value: ValueOf<M>) => ReactNode;\n className?: string;\n}\n\n/**\n * Select – choose one or several values from a list.\n * Built on React Aria Select with a hidden native select: forms, autofill and validation keep working.\n * 2–4 options: Radio. 5–10: Select. More, or users know what to type: Combobox.\n */\nexport function Select<T extends object, M extends SelectMode = 'single'>({\n label,\n description,\n errorMessage,\n placeholder = 'Select…',\n size = 'md',\n leadingIcon,\n clearable,\n isReadOnly,\n items,\n children,\n overlay = 'auto',\n commit = 'live',\n onApply,\n resultLabel = () => 'Show results',\n className,\n selectionMode,\n ...props\n}: SelectProps<T, M>) {\n const multiple = selectionMode === 'multiple';\n const mobile = useMediaQuery(MOBILE_QUERY);\n const mode = overlay === 'auto' ? (mobile ? (multiple ? 'sheet' : 'native') : 'popover') : overlay === 'native' && multiple ? 'sheet' : overlay;\n const [hasValue, setHasValue] = useState(false);\n /* The popover aligns to the whole field (border incl.), not only the inner trigger button. */\n const fieldRef = useRef<HTMLDivElement>(null);\n return (\n <AriaSelect<T, M>\n {...props}\n selectionMode={selectionMode}\n placeholder={placeholder}\n /* Read-only: never opens. */\n isOpen={isReadOnly ? false : props.isOpen}\n data-readonly={isReadOnly || undefined}\n className={cx(\n 'medo-field',\n 'medo-select',\n multiple && hasValue && 'medo-select--tags',\n (multiple || clearable) && hasValue && !isReadOnly && !props.isDisabled && 'medo-select--clearable',\n className,\n )}\n >\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <div ref={fieldRef} className={cx('medo-input', `medo-input--${size}`, 'medo-select__field')}>\n <ReadOnlyKeys isReadOnly={isReadOnly}>\n {/* With the native picker the invisible <select> on top takes focus and taps; the button only shows the value. */}\n <AriaButton className=\"medo-select__trigger\" excludeFromTabOrder={mode === 'native'} aria-hidden={mode === 'native' || undefined}>\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n <SelectValue<T> className=\"medo-select__value\">\n {/* The field shows only the label of the option – no description or option icon (one line, ellipsis). */}\n {({ defaultChildren, isPlaceholder, selectedText }) => (\n <>\n {isPlaceholder ? defaultChildren : multiple ? <SelectedTags size={size} /> : selectedText}\n {isReadOnly && <span className=\"medo-visually-hidden\">, read only</span>}\n </>\n )}\n </SelectValue>\n {!isReadOnly && (\n <span className=\"medo-select__chevron\" aria-hidden=\"true\">\n <ChevronDown />\n </span>\n )}\n </AriaButton>\n </ReadOnlyKeys>\n {mode === 'native' && !isReadOnly && <NativePicker label={label ?? props['aria-label']} placeholder={placeholder} isRequired={props.isRequired} />}\n <ClearButton enabled={(multiple || !!clearable) && !isReadOnly && !props.isDisabled} onHasValue={setHasValue} />\n </div>\n <FieldFooter description={description} errorMessage={errorMessage} />\n {commit === 'onClose' && onApply && <ApplyOnClose onApply={onApply as (value: Key[] | Key | null) => void} />}\n {mode === 'sheet' ? (\n <BottomSheetPopover\n title={label ?? props['aria-label']}\n footer={multiple ? <SheetFooter commit={commit} resultLabel={resultLabel as (value: Key[] | Key | null) => ReactNode} /> : undefined}\n >\n <ListBox<T> size=\"lg\" items={items}>\n {children}\n </ListBox>\n </BottomSheetPopover>\n ) : (\n <Popover triggerRef={fieldRef} offset={4} className=\"medo-listbox-popover\">\n <ListBox<T> size={size === 'lg' ? 'lg' : 'md'} items={items}>\n {children}\n </ListBox>\n </Popover>\n )}\n </AriaSelect>\n );\n}\n\n/** Read-only: blocks type-to-select and arrow keys on the trigger; Tab still moves on. */\nfunction ReadOnlyKeys({ isReadOnly, children }: { isReadOnly?: boolean; children: ReactNode }) {\n if (!isReadOnly) return <>{children}</>;\n const block = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') e.stopPropagation();\n };\n return (\n <div style={{ display: 'contents' }} onKeyDownCapture={block}>\n {children}\n </div>\n );\n}\n\n/** Clear (single, optional) or clear-all (multi). Next to the trigger, never inside it. */\nfunction ClearButton({ enabled, onHasValue }: { enabled: boolean; onHasValue: (v: boolean) => void }) {\n const state = useContext(SelectStateContext);\n const hasValue = !!state && (Array.isArray(state.value) ? state.value.length > 0 : state.value != null);\n useLayoutEffect(() => onHasValue(hasValue), [hasValue, onHasValue]);\n const ref = useRef<HTMLSpanElement>(null);\n if (!enabled || !hasValue || !state) return null;\n return (\n <span className=\"medo-select__clear\" ref={ref}>\n <InputAction\n // slot={null}: opts out of the Select's trigger context, so this stays its own button.\n slot={null}\n aria-label={Array.isArray(state.value) ? 'Clear all' : 'Clear selection'}\n icon={<X />}\n onPress={() => {\n state.setValue(Array.isArray(state.value) ? [] : null);\n // The clear button disappears: move focus back to the trigger.\n (ref.current?.parentElement?.querySelector('.medo-select__trigger') as HTMLElement | null)?.focus();\n }}\n />\n </span>\n );\n}\n\n/** Selected values as tags in one line; what does not fit becomes „+N“. Screen readers get the full list. */\nfunction SelectedTags({ size }: { size: InputSize }) {\n const state = useContext(SelectStateContext);\n const labels = state?.selectedItems.map((item) => item.textValue) ?? [];\n const key = labels.join('\\u0000');\n const rowRef = useRef<HTMLSpanElement>(null);\n const measureRef = useRef<HTMLSpanElement>(null);\n const visible = useFitCount(rowRef, measureRef, key, labels.length);\n const tagClass = cx('medo-tag', size === 'lg' ? 'medo-tag--md' : 'medo-tag--sm');\n\n const hidden = labels.length - visible;\n return (\n <span className=\"medo-select__tags\" ref={rowRef}>\n <span className=\"medo-visually-hidden\">{labels.join(', ')}</span>\n <span className=\"medo-select__measure\" ref={measureRef} aria-hidden=\"true\">\n {labels.map((label, i) => (\n <span key={i} className={tagClass}>\n {label}\n </span>\n ))}\n <span className={tagClass}>+{labels.length}</span>\n </span>\n {labels.slice(0, visible).map((label, i) => (\n <span key={i} className={tagClass} aria-hidden=\"true\">\n <span className=\"medo-select__tag-label\">{label}</span>\n </span>\n ))}\n {hidden > 0 && (\n <span className={tagClass} aria-hidden=\"true\">\n +{hidden}\n </span>\n )}\n </span>\n );\n}\n\n/**\n * Mobile, single: an invisible native <select> over the field opens the system picker.\n * The options come from the Select's collection; the change goes into the same state.\n */\nfunction NativePicker({ label, placeholder, isRequired }: { label: ReactNode; placeholder: string; isRequired?: boolean }) {\n const state = useContext(SelectStateContext);\n if (!state) return null;\n const keys = new Map<string, Key>();\n const option = (key: Key) => {\n const node = state.collection.getItem(key);\n if (!node || node.type !== 'item') return null;\n keys.set(String(key), key);\n return (\n <option key={String(key)} value={String(key)} disabled={state.selectionManager.isDisabled(key)}>\n {node.textValue}\n </option>\n );\n };\n const value = state.value == null || Array.isArray(state.value) ? '' : String(state.value);\n return (\n <select\n className=\"medo-select__native\"\n aria-label={typeof label === 'string' ? label : undefined}\n required={isRequired}\n value={value}\n onChange={(e) => state.setValue(e.target.value === '' ? null : (keys.get(e.target.value) ?? e.target.value))}\n >\n <option value=\"\" disabled={isRequired}>\n {placeholder}\n </option>\n {[...state.collection].map((node) =>\n node.type === 'section' ? (\n <optgroup key={String(node.key)} label={node.textValue || node['aria-label'] || ''}>\n {[...state.collection.getChildren!(node.key)].map((child) => option(child.key))}\n </optgroup>\n ) : (\n option(node.key)\n ),\n )}\n </select>\n );\n}\n\n/** Sheet footer for multi: live → „3 selected“ + Done · onClose → result button + Reset below (thumb reach). */\nfunction SheetFooter({ commit, resultLabel }: { commit: 'live' | 'onClose'; resultLabel: (value: Key[] | Key | null) => ReactNode }) {\n const state = useContext(SelectStateContext);\n if (!state) return null;\n const count = Array.isArray(state.value) ? state.value.length : state.value == null ? 0 : 1;\n return commit === 'onClose' ? (\n <>\n <Button size=\"lg\" onPress={() => state.close()}>\n {resultLabel(state.value as Key[])}\n </Button>\n <Button size=\"lg\" variant=\"secondary\" onPress={() => state.setValue([])} isDisabled={count === 0}>\n Reset\n </Button>\n </>\n ) : (\n <>\n <p className=\"medo-sheet__count\" aria-live=\"polite\">\n {count} selected\n </p>\n <Button size=\"lg\" onPress={() => state.close()}>\n Done\n </Button>\n </>\n );\n}\n\n/** commit=\"onClose\": calls onApply once when the list closes (any way), if the selection changed while open. */\nfunction ApplyOnClose({ onApply }: { onApply: (value: Key[] | Key | null) => void }) {\n const state = useContext(SelectStateContext);\n const opened = useRef<string | null>(null);\n const isOpen = !!state?.isOpen;\n useEffect(() => {\n if (!state) return;\n const snapshot = JSON.stringify(state.value);\n if (isOpen) opened.current = snapshot;\n else if (opened.current !== null) {\n if (opened.current !== snapshot) onApply(state.value as Key[]);\n opened.current = null;\n }\n // Only the open/close transition matters.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n return null;\n}\n","import { useContext, useId, useRef, type PointerEvent, type ReactNode } from 'react';\nimport { Dialog, Heading, Modal, ModalOverlay, OverlayTriggerStateContext, Popover, type ModalOverlayProps } from 'react-aria-components';\nimport { ChevronLeft, X } from 'lucide-react';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport './bottom-sheet.css';\n\nexport interface BottomSheetProps extends Omit<ModalOverlayProps, 'children' | 'className' | 'style'> {\n /** Required: names the dialog (for a Select sheet: the field label). */\n title: ReactNode;\n /** Content; scrolls when taller than the sheet. */\n children: ReactNode;\n /** Sticky footer, e.g. a full-width primary action. A function gets `close`. */\n footer?: ReactNode | ((close: () => void) => ReactNode);\n /** content: height of the content, max 90 % · full: fixed 90 % (with search, so it does not jump). */\n height?: 'content' | 'full';\n /** Accessible name of the close button. */\n closeLabel?: string;\n /** Shows a back button before the title (second view, e.g. a submenu). */\n onBack?: () => void;\n /** Accessible name of the back button. */\n backLabel?: string;\n className?: string;\n}\n\n/** Share of the sheet height (or a fast flick) that closes it when swiped down. */\nconst CLOSE_DISTANCE = 0.25;\nconst CLOSE_VELOCITY = 0.5; // px per ms\n\n/**\n * Bottom Sheet – a modal layer from the bottom on small screens.\n * Built on React Aria ModalOverlay + Modal + Dialog: focus stays inside and returns to the trigger,\n * page scroll is locked, Esc and a tap on the scrim close it. Swipe down on the handle or header closes it,\n * the close button is the non-drag alternative (WCAG 2.5.7). Use inside a DialogTrigger or with isOpen.\n */\nexport function BottomSheet({\n title,\n children,\n footer,\n height = 'content',\n closeLabel = 'Close',\n onBack,\n backLabel = 'Back',\n isDismissable = true,\n className,\n ...props\n}: BottomSheetProps) {\n return (\n <ModalOverlay {...props} isDismissable={isDismissable} className=\"medo-sheet-overlay\">\n <Modal className={cx('medo-sheet', height === 'full' && 'medo-sheet--full', className)}>\n <Dialog className=\"medo-sheet__dialog\">\n {({ close }) => (\n <>\n <SwipeArea onClose={close}>\n <span className=\"medo-sheet__handle\" aria-hidden=\"true\" />\n <div className=\"medo-sheet__header\">\n {onBack && (\n <IconButton variant=\"ghost\" size=\"lg\" icon={<ChevronLeft />} aria-label={backLabel} tooltip={false} onPress={onBack} />\n )}\n <Heading slot=\"title\" className=\"medo-sheet__title\">\n {title}\n </Heading>\n <IconButton variant=\"ghost\" size=\"lg\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />\n </div>\n </SwipeArea>\n <div className=\"medo-sheet__content\">{children}</div>\n {footer && <div className=\"medo-sheet__footer\">{typeof footer === 'function' ? footer(close) : footer}</div>}\n </>\n )}\n </Dialog>\n </Modal>\n </ModalOverlay>\n );\n}\n\n/** Handle and header: drag down to close (touch, pen or mouse). Buttons inside keep working. */\nfunction SwipeArea({ onClose, children }: { onClose: () => void; children: ReactNode }) {\n const drag = useRef<{ y: number; t: number; sheet: HTMLElement } | null>(null);\n\n const onPointerDown = (e: PointerEvent<HTMLDivElement>) => {\n if ((e.target as HTMLElement).closest('button')) return;\n const sheet = e.currentTarget.closest<HTMLElement>('.medo-sheet');\n if (!sheet) return;\n drag.current = { y: e.clientY, t: e.timeStamp, sheet };\n e.currentTarget.setPointerCapture(e.pointerId);\n sheet.setAttribute('data-dragging', '');\n };\n\n const onPointerMove = (e: PointerEvent<HTMLDivElement>) => {\n if (!drag.current) return;\n const dy = Math.max(0, e.clientY - drag.current.y);\n drag.current.sheet.style.transform = `translateY(${dy}px)`;\n };\n\n const end = (e: PointerEvent<HTMLDivElement>) => {\n const d = drag.current;\n if (!d) return;\n drag.current = null;\n const dy = Math.max(0, e.clientY - d.y);\n const velocity = dy / Math.max(1, e.timeStamp - d.t);\n d.sheet.removeAttribute('data-dragging');\n d.sheet.style.transform = '';\n if (dy > d.sheet.offsetHeight * CLOSE_DISTANCE || (velocity > CLOSE_VELOCITY && dy > 24)) onClose();\n };\n\n return (\n <div className=\"medo-sheet__grab\" onPointerDown={onPointerDown} onPointerMove={onPointerMove} onPointerUp={end} onPointerCancel={end}>\n {children}\n </div>\n );\n}\n\n/**\n * Bottom Sheet as the popover of a Select. React Aria builds the Select's list\n * from its Popover even while closed – a Modal would hide the options from it – so the sheet is a\n * full-screen popover here: same look, same closing (swipe, scrim, Esc, close button), focus stays inside.\n */\nexport function BottomSheetPopover({\n title,\n children,\n footer,\n height = 'content',\n closeLabel = 'Close',\n}: Pick<BottomSheetProps, 'title' | 'children' | 'footer' | 'height' | 'closeLabel'>) {\n return (\n <Popover className=\"medo-sheet-overlay medo-sheet-overlay--popover\" offset={0} containerPadding={0}>\n <SheetPopoverBody title={title} footer={footer} height={height} closeLabel={closeLabel}>\n {children}\n </SheetPopoverBody>\n </Popover>\n );\n}\n\nfunction SheetPopoverBody({ title, children, footer, height, closeLabel }: Omit<BottomSheetProps, 'isDismissable' | 'className'>) {\n const state = useContext(OverlayTriggerStateContext);\n const titleId = useId();\n const close = () => state?.close();\n return (\n // A tap on the scrim (outside the sheet) closes it.\n <div className=\"medo-sheet-scrim\" onClick={(e) => e.target === e.currentTarget && close()}>\n <section className={cx('medo-sheet', height === 'full' && 'medo-sheet--full')} aria-labelledby={titleId}>\n <SwipeArea onClose={close}>\n <span className=\"medo-sheet__handle\" aria-hidden=\"true\" />\n <div className=\"medo-sheet__header\">\n <h2 id={titleId} className=\"medo-sheet__title\">\n {title}\n </h2>\n <IconButton slot={null} variant=\"ghost\" size=\"lg\" icon={<X />} aria-label={closeLabel ?? 'Close'} tooltip={false} onPress={close} />\n </div>\n </SwipeArea>\n <div className=\"medo-sheet__content\">{children}</div>\n {footer && <div className=\"medo-sheet__footer\">{typeof footer === 'function' ? footer(close) : footer}</div>}\n </section>\n </div>\n );\n}\n","import { useLayoutEffect, useState, type RefObject } from 'react';\n\n/**\n * How many items of a one-line row fit, keeping room for a „+N“ item (Select and Combobox tags).\n *\n * The caller renders a hidden measure row (same gap as the visible row): one child per item and,\n * as the last child, a „+N“ probe. `reserve` keeps extra space free, e.g. for a text input.\n * At least one item stays visible (it may truncate).\n */\nexport function useFitCount(\n rowRef: RefObject<HTMLElement | null>,\n measureRef: RefObject<HTMLElement | null>,\n key: string,\n total: number,\n reserve = 0,\n) {\n const [visible, setVisible] = useState(total);\n\n useLayoutEffect(() => {\n const row = rowRef.current;\n const measure = measureRef.current;\n if (!row || !measure) return;\n const fit = () => {\n const items = [...measure.children] as HTMLElement[];\n const plus = items.pop();\n const gap = parseFloat(getComputedStyle(measure).columnGap) || 0;\n const avail = row.clientWidth - reserve;\n let used = 0;\n let count = 0;\n for (let i = 0; i < items.length; i++) {\n const width = items[i].offsetWidth + (i ? gap : 0);\n const plusRoom = i < items.length - 1 ? gap + (plus?.offsetWidth ?? 0) : 0;\n if (used + width + plusRoom > avail) break;\n used += width;\n count = i + 1;\n }\n setVisible(Math.min(total, Math.max(1, count)));\n };\n fit();\n const observer = new ResizeObserver(fit);\n observer.observe(row);\n return () => observer.disconnect();\n }, [rowRef, measureRef, key, total, reserve]);\n\n return Math.min(visible, total);\n}\n","import { useSyncExternalStore } from 'react';\n\n/** Below breakpoint/sm (640 px): mobile behaviour for Select, Combobox and Bottom Sheet. */\nexport const MOBILE_QUERY = '(max-width: 639.98px)';\n\n/** True while the media query matches. SSR-safe (false on the server). */\nexport function useMediaQuery(query: string) {\n return useSyncExternalStore(\n (onChange) => {\n const list = window.matchMedia(query);\n list.addEventListener('change', onChange);\n return () => list.removeEventListener('change', onChange);\n },\n () => window.matchMedia(query).matches,\n () => false,\n );\n}\n","import { createContext, useContext, useState, type ReactNode } from 'react';\nimport {\n Header,\n Keyboard,\n Menu as AriaMenu,\n MenuItem as AriaMenuItem,\n MenuSection as AriaMenuSection,\n MenuTrigger as AriaMenuTrigger,\n Popover,\n SubmenuTrigger,\n Text,\n type MenuItemProps as AriaMenuItemProps,\n type MenuProps as AriaMenuProps,\n type MenuTriggerProps as AriaMenuTriggerProps,\n} from 'react-aria-components';\nimport { ChevronRight, Ellipsis } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { IconButton } from '../icon-button/IconButton';\nimport { formatShortcut } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport '../listbox/listbox.css';\nimport './menu.css';\n\ntype MenuSize = 'md' | 'lg';\n\n/** md: desktop popover · lg: mobile sheet (no shortcuts); push opens a submenu as second view in the sheet. */\ninterface MenuMode {\n size: MenuSize;\n push?: (title: ReactNode, children: ReactNode) => void;\n}\nconst MenuModeContext = createContext<MenuMode>({ size: 'md' });\n\nexport interface MenuTriggerProps extends Omit<AriaMenuTriggerProps, 'children'> {\n /** The trigger (default: an ellipsis Icon Button) and the Menu. Without a trigger, pass `label`. */\n children: ReactNode;\n}\n\n/** Opens a Menu from a trigger (React Aria MenuTrigger). Focus returns to the trigger. */\nexport function MenuTrigger(props: MenuTriggerProps) {\n return <AriaMenuTrigger {...props} />;\n}\n\n/**\n * Default trigger: ghost Icon Button with an ellipsis. The name includes the object\n * („More actions for Q3-Report.pdf“); it looks pressed while the menu is open.\n */\nexport function MenuButton({ 'aria-label': label, size = 'md' }: { 'aria-label': string; size?: 'sm' | 'md' | 'lg' }) {\n return <IconButton variant=\"ghost\" size={size} icon={<Ellipsis />} aria-label={label} />;\n}\n\nexport interface MenuProps<T> extends Omit<AriaMenuProps<T>, 'className' | 'style'> {\n /** Mobile sheet title: the object the actions apply to („Q3-Report.pdf“). */\n title?: ReactNode;\n /** auto: popover on desktop, Bottom Sheet below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n className?: string;\n}\n\n/**\n * Menu – a list of actions. Built on React Aria Menu: arrow keys, Enter runs the item,\n * Esc closes, type to jump, Home/End. Every item has an icon, labels start with a verb; danger items last.\n * Not for values (Select) or site navigation (disclosure pattern).\n */\nexport function Menu<T extends object>({ title, overlay = 'auto', className, ...props }: MenuProps<T>) {\n const mobile = useMediaQuery(MOBILE_QUERY);\n const sheet = overlay === 'sheet' || (overlay === 'auto' && mobile);\n if (sheet) return <SheetMenu title={title} className={className} {...props} />;\n return (\n <Popover placement=\"bottom end\" offset={4} className=\"medo-menu-popover\">\n <MenuModeContext.Provider value={{ size: 'md' }}>\n <AriaMenu {...props} className={cx('medo-menu', 'medo-menu--md', className)} />\n </MenuModeContext.Provider>\n </Popover>\n );\n}\n\n/** Mobile: Bottom Sheet with lg items; a submenu replaces the list as a second view with a back button. */\nfunction SheetMenu<T extends object>({ title, className, ...props }: Omit<MenuProps<T>, 'overlay'>) {\n const [view, setView] = useState<{ title: ReactNode; children: ReactNode } | null>(null);\n return (\n <BottomSheet\n title={view ? view.title : (title ?? props['aria-label'])}\n onBack={view ? () => setView(null) : undefined}\n onOpenChange={(open) => !open && setView(null)}\n >\n <MenuModeContext.Provider value={{ size: 'lg', push: (t, c) => setView({ title: t, children: c }) }}>\n {view ? (\n <AriaMenu key=\"sub\" aria-label={typeof view.title === 'string' ? view.title : undefined} autoFocus=\"first\" className={cx('medo-menu', 'medo-menu--lg', className)}>\n {view.children}\n </AriaMenu>\n ) : (\n <AriaMenu {...props} key=\"main\" className={cx('medo-menu', 'medo-menu--lg', className)} />\n )}\n </MenuModeContext.Provider>\n </BottomSheet>\n );\n}\n\nexport interface MenuItemProps extends Omit<AriaMenuItemProps, 'children' | 'className' | 'style'> {\n /** Label, starting with a verb („Duplicate“). „…“ only when a dialog or second step follows. */\n children: string;\n /** Required: shows the action. Decorative for screen readers – the label carries the meaning. */\n icon: ReactNode;\n /** Keyboard shortcut in aria-keyshortcuts syntax; „Mod“ = ⌘ on Apple, Ctrl elsewhere. Desktop only. It must also work without the menu. */\n shortcut?: string;\n /** Destructive action: red, last in its own group. Irreversible actions open a confirmation dialog. */\n variant?: 'default' | 'danger';\n}\n\n/** One action in a Menu. */\nexport function MenuItem({ children, icon, shortcut, variant = 'default', textValue, ...props }: MenuItemProps) {\n const { size } = useContext(MenuModeContext);\n return (\n <AriaMenuItem\n {...props}\n textValue={textValue ?? children}\n className={cx('medo-menu-item', variant === 'danger' && 'medo-menu-item--danger')}\n >\n {({ hasSubmenu }) => (\n <>\n <span className=\"medo-menu-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <Text slot=\"label\" className=\"medo-menu-item__label\">\n {children}\n </Text>\n {/* Keyboard is linked to the item (aria-describedby), so screen readers hear the shortcut. */}\n {shortcut && size === 'md' && <Keyboard className=\"medo-menu-item__shortcut\">{formatShortcut(shortcut)}</Keyboard>}\n {hasSubmenu && (\n <span className=\"medo-menu-item__chevron\" aria-hidden=\"true\">\n <ChevronRight />\n </span>\n )}\n </>\n )}\n </AriaMenuItem>\n );\n}\n\nexport interface SubmenuProps {\n /** Label of the parent item. */\n label: string;\n icon: ReactNode;\n /** The submenu's items (one level only). */\n children: ReactNode;\n isDisabled?: boolean;\n}\n\n/** Submenu (one level). Desktop: opens to the side. Mobile: second view in the sheet with a back button. */\nexport function Submenu({ label, icon, children, isDisabled }: SubmenuProps) {\n const { size, push } = useContext(MenuModeContext);\n if (push) {\n return (\n <AriaMenuItem\n textValue={label}\n isDisabled={isDisabled}\n shouldCloseOnSelect={false}\n onAction={() => push(label, children)}\n className=\"medo-menu-item\"\n >\n <span className=\"medo-menu-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <Text slot=\"label\" className=\"medo-menu-item__label\">\n {label}\n </Text>\n <span className=\"medo-menu-item__chevron\" aria-hidden=\"true\">\n <ChevronRight />\n </span>\n </AriaMenuItem>\n );\n }\n return (\n <SubmenuTrigger>\n <MenuItem icon={icon} isDisabled={isDisabled}>\n {label}\n </MenuItem>\n {/* Side placement, first item level with the parent item (popover padding + border). */}\n <Popover placement=\"end top\" offset={4} crossOffset={-5} className=\"medo-menu-popover\">\n <AriaMenu aria-label={label} className={cx('medo-menu', `medo-menu--${size}`)}>\n {children}\n </AriaMenu>\n </Popover>\n </SubmenuTrigger>\n );\n}\n\nexport interface MenuSectionProps {\n /** Optional overline heading. Without a title the group is only divided by a line; then set aria-label if it helps. */\n title?: ReactNode;\n 'aria-label'?: string;\n children: ReactNode;\n}\n\n/** A group of related actions. Groups are divided by a line; the danger group comes last. */\nexport function MenuSection({ title, children, ...props }: MenuSectionProps) {\n return (\n <AriaMenuSection aria-label={props['aria-label']} className=\"medo-menu__section\">\n {title && <Header className=\"medo-listbox__header\">{title}</Header>}\n {children}\n </AriaMenuSection>\n );\n}\n","import { useContext, useEffect, useId, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { Dialog as AriaDialog, DialogContext, Heading, Modal, ModalOverlay, OverlayTriggerStateContext, Provider } from 'react-aria-components';\nimport { CircleAlert, Info, TriangleAlert, X } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button, ButtonGroup, type ButtonSize } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport './dialog.css';\n\n/** Opens a Dialog or Alert dialog from a trigger (React Aria DialogTrigger). Focus returns to the trigger. */\nexport { DialogTrigger } from 'react-aria-components';\n\n/* ---------- Shared ---------- */\n\nexport interface DialogAction {\n /** Verb that says what happens („Send invite“, „Delete“). Never „OK“, „Yes“ or „Confirm“. */\n label: string;\n /**\n * Runs on press, then the dialog closes. Return a promise to show the pending state until it\n * resolves; when it rejects, the dialog stays open (show the error inside the dialog).\n */\n onAction?: () => void | Promise<unknown>;\n /** Id of a form in the dialog: the button submits it. The form's onSubmit saves and calls `close`. */\n form?: string;\n /** Dialog only: danger for a destructive main action. */\n variant?: 'primary' | 'danger';\n isDisabled?: boolean;\n /** Controlled pending state (e.g. while a submitted form saves). */\n isPending?: boolean;\n}\n\ninterface OpenProps {\n /** Controlled open state. Inside a DialogTrigger the trigger controls it. */\n isOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n}\n\n/** Open state from props, else from the surrounding DialogTrigger. */\nfunction useOpenState({ isOpen, onOpenChange }: OpenProps) {\n const trigger = useContext(OverlayTriggerStateContext);\n const open = isOpen ?? trigger?.isOpen ?? false;\n const setOpen = (next: boolean) => {\n onOpenChange?.(next);\n if (isOpen === undefined) trigger?.setOpen(next);\n };\n return [open, setOpen] as const;\n}\n\n/** Main action button: runs the action and closes; a promise shows the pending state. Shared with Popover (internal, not exported from the package). */\nexport function ActionButton({ action, close, size, variant }: { action: DialogAction; close: () => void; size: ButtonSize; variant: 'primary' | 'danger' }) {\n const [pending, setPending] = useState(false);\n const run = async () => {\n const result = action.onAction?.();\n if (!(result instanceof Promise)) return close();\n setPending(true);\n try {\n await result;\n close();\n } finally {\n setPending(false);\n }\n };\n return (\n <Button\n variant={action.variant ?? variant}\n size={size}\n type={action.form ? 'submit' : 'button'}\n form={action.form}\n isDisabled={action.isDisabled}\n isPending={action.isPending || pending}\n onPress={action.form ? undefined : run}\n >\n {action.label}\n </Button>\n );\n}\n\n/** A nested modal must not inherit the outer dialog's trigger, ids or state. */\nfunction Nested({ children }: { children: ReactNode }) {\n return (\n <Provider\n values={[\n [DialogContext, null],\n [OverlayTriggerStateContext, null],\n ]}\n >\n {children}\n </Provider>\n );\n}\n\n/* ---------- Dialog ---------- */\n\nexport interface DirtyGuardProps extends OpenProps {\n isDirty?: boolean;\n discardText?: Partial<DialogDiscardText>;\n}\n\n/**\n * Open state with the „Discard changes?“ guard (protects unsaved input). Every way of closing\n * (X, Cancel, Esc, swipe) goes through onOpenChange; with unsaved input it asks first.\n * Render `confirmDiscard` inside the dialog. Shared with Drawer (internal).\n */\nexport function useDirtyGuard({ isDirty = false, discardText, ...openProps }: DirtyGuardProps) {\n const [open, setOpen] = useOpenState(openProps);\n const [confirm, setConfirm] = useState(false);\n const onOpenChange = (next: boolean) => {\n if (next || !isDirty) setOpen(next);\n else setConfirm(true);\n };\n const discard = { ...DISCARD, ...discardText };\n const confirmDiscard = (\n <Nested>\n <AlertDialog\n tone=\"warning\"\n isOpen={confirm}\n onOpenChange={setConfirm}\n title={discard.title}\n actionLabel={discard.actionLabel}\n cancelLabel={discard.cancelLabel}\n onAction={() => setOpen(false)}\n >\n {discard.description}\n </AlertDialog>\n </Nested>\n );\n /** Deliberate close after saving – does not ask. */\n const forceClose = () => setOpen(false);\n return { open, onOpenChange, confirmDiscard, forceClose };\n}\n\nexport interface DialogDiscardText {\n title: string;\n description: string;\n actionLabel: string;\n cancelLabel: string;\n}\n\nexport interface DialogProps extends OpenProps {\n /** Required. Names the task („Invite member“). Screen readers announce it when the dialog opens. */\n title: ReactNode;\n /** One or two sentences under the title. */\n description?: ReactNode;\n /** Content or form. A function gets `close`: closes without asking – call it after saving (X, Cancel and Esc still ask when isDirty). */\n children?: ReactNode | ((close: () => void) => ReactNode);\n /** sm 400 (one or two fields) · md 560 · lg 720 (tables, two-column forms). */\n size?: 'sm' | 'md' | 'lg';\n /** Main action at the end of the footer, next to Cancel. On mobile fullscreen it moves to the header. Without it, no footer. */\n primaryAction?: DialogAction;\n cancelLabel?: string;\n /** Accessible name of the X (and the label of the mobile close button without a main action). */\n closeLabel?: string;\n /** Shows the X in the header. */\n showClose?: boolean;\n /**\n * Unsaved input. While true, a click on the scrim no longer closes, and X, Esc and Cancel\n * first ask „Discard changes?“ (Alert dialog).\n */\n isDirty?: boolean;\n /** Text of the „Discard changes?“ Alert dialog. */\n discardText?: Partial<DialogDiscardText>;\n /** auto: dialog on desktop, `mobile` below 640 px · dialog · fullscreen · sheet. */\n overlay?: 'auto' | 'dialog' | 'fullscreen' | 'sheet';\n /** Pattern below 640 px: fullscreen for forms (keyboard needs space), sheet for short content. */\n mobile?: 'fullscreen' | 'sheet';\n className?: string;\n}\n\nconst DISCARD: DialogDiscardText = {\n title: 'Discard changes?',\n description: 'Your changes will be lost.',\n actionLabel: 'Discard',\n cancelLabel: 'Keep editing',\n};\n\n/**\n * Dialog – a modal window for a focused task. Built on React Aria ModalOverlay,\n * Modal and Dialog: role dialog with aria-modal, the title names it, focus starts in the first field,\n * stays inside and returns to the trigger; the page behind does not scroll. Use inside a DialogTrigger or with isOpen.\n */\nexport function Dialog({\n title,\n description,\n children,\n size = 'md',\n primaryAction,\n cancelLabel = 'Cancel',\n closeLabel = 'Close',\n showClose = true,\n isDirty = false,\n discardText,\n overlay = 'auto',\n mobile = 'fullscreen',\n className,\n ...openProps\n}: DialogProps) {\n const { open, onOpenChange, confirmDiscard, forceClose } = useDirtyGuard({ isDirty, discardText, ...openProps });\n const isMobile = useMediaQuery(MOBILE_QUERY);\n const layout = overlay === 'auto' ? (isMobile ? mobile : 'dialog') : overlay;\n const content = (close: () => void) => (typeof children === 'function' ? children(close) : children);\n\n if (layout === 'sheet') {\n return (\n <BottomSheet\n title={title}\n closeLabel={closeLabel}\n isOpen={open}\n onOpenChange={onOpenChange}\n isDismissable={!isDirty}\n className={className}\n footer={\n primaryAction &&\n ((close) => (\n <ButtonGroup>\n <Button variant=\"secondary\" size=\"lg\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={forceClose} size=\"lg\" variant=\"primary\" />\n </ButtonGroup>\n ))\n }\n >\n <SheetContent description={description}>{content(forceClose)}</SheetContent>\n {confirmDiscard}\n </BottomSheet>\n );\n }\n\n const fullscreen = layout === 'fullscreen';\n return (\n <ModalOverlay\n isOpen={open}\n onOpenChange={onOpenChange}\n isDismissable={!isDirty}\n className={cx('medo-dialog-overlay', fullscreen && 'medo-dialog-overlay--fullscreen')}\n >\n <Modal className={cx('medo-dialog', fullscreen ? 'medo-dialog--fullscreen' : `medo-dialog--${size}`, className)}>\n <DialogFrame\n title={title}\n description={description}\n fullscreen={fullscreen}\n primaryAction={primaryAction}\n cancelLabel={cancelLabel}\n closeLabel={closeLabel}\n showClose={showClose}\n nested={confirmDiscard}\n forceClose={forceClose}\n >\n {content}\n </DialogFrame>\n </Modal>\n </ModalOverlay>\n );\n}\n\ninterface FrameProps extends Pick<DialogProps, 'title' | 'description' | 'primaryAction' | 'showClose'> {\n fullscreen: boolean;\n cancelLabel: string;\n closeLabel: string;\n /** Rendered inside the dialog (focus scope): the „Discard changes?“ Alert dialog. */\n nested: ReactNode;\n /** Closes without asking: the main action and the content's `close` (after saving). */\n forceClose: () => void;\n children: (close: () => void) => ReactNode;\n}\n\n/** Header, scrolling body and footer of the centered and the fullscreen dialog. */\nfunction DialogFrame({ title, description, fullscreen, primaryAction, cancelLabel, closeLabel, showClose, nested, forceClose, children }: FrameProps) {\n const descriptionId = useId();\n const ref = useRef<HTMLElement>(null);\n const [scrolls, setScrolls] = useState(false);\n useInitialFocus(ref);\n\n return (\n <AriaDialog ref={ref} className=\"medo-dialog__dialog\" aria-describedby={description ? descriptionId : undefined} data-scrolled={scrolls || undefined}>\n {({ close }) =>\n fullscreen ? (\n <>\n {/* Mobile: Cancel left, title centered, main action right – always visible above the keyboard. */}\n <div className=\"medo-dialog__bar\">\n <Button variant=\"ghost\" size=\"md\" onPress={close}>\n {primaryAction ? cancelLabel : closeLabel}\n </Button>\n <Heading slot=\"title\" className=\"medo-dialog__bar-title\">\n {title}\n </Heading>\n {primaryAction ? <ActionButton action={primaryAction} close={forceClose} size=\"md\" variant=\"primary\" /> : <span />}\n </div>\n <DialogBody onScrollsChange={setScrolls}>\n {description && (\n <p id={descriptionId} className=\"medo-dialog__description\">\n {description}\n </p>\n )}\n {children(forceClose)}\n </DialogBody>\n {nested}\n </>\n ) : (\n <>\n <div className=\"medo-dialog__header\">\n <div className=\"medo-dialog__heading\">\n <Heading slot=\"title\" className=\"medo-dialog__title\">\n {title}\n </Heading>\n {description && (\n <p id={descriptionId} className=\"medo-dialog__description\">\n {description}\n </p>\n )}\n </div>\n {showClose && <IconButton variant=\"ghost\" size=\"sm\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />}\n </div>\n <DialogBody onScrollsChange={setScrolls}>{children(forceClose)}</DialogBody>\n {primaryAction && (\n <div className=\"medo-dialog__footer\">\n <ButtonGroup>\n <Button variant=\"secondary\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={forceClose} size=\"md\" variant=\"primary\" />\n </ButtonGroup>\n </div>\n )}\n {nested}\n </>\n )\n }\n </AriaDialog>\n );\n}\n\n/** Only the body scrolls. While it does, it is focusable (keyboard scrolling) and header and footer get dividers. */\nfunction DialogBody({ children, onScrollsChange }: { children: ReactNode; onScrollsChange: (scrolls: boolean) => void }) {\n const ref = useRef<HTMLDivElement>(null);\n const [scrolls, setScrolls] = useState(false);\n useLayoutEffect(() => {\n const body = ref.current;\n if (!body) return;\n const check = () => setScrolls(body.scrollHeight > body.clientHeight + 1);\n const observer = new ResizeObserver(check);\n observer.observe(body);\n if (body.firstElementChild) observer.observe(body.firstElementChild);\n check();\n return () => observer.disconnect();\n }, []);\n useEffect(() => onScrollsChange(scrolls), [scrolls, onScrollsChange]);\n return (\n <div ref={ref} className=\"medo-dialog__body\" tabIndex={scrolls ? 0 : undefined}>\n <div className=\"medo-dialog__body-inner\">{children}</div>\n </div>\n );\n}\n\n/** Bottom Sheet content: description and the dialog content with the sheet's padding. */\nfunction SheetContent({ description, children }: { description: ReactNode; children: ReactNode }) {\n return (\n <div className=\"medo-dialog__sheet-body\">\n {description && <p className=\"medo-dialog__description\">{description}</p>}\n {children}\n </div>\n );\n}\n\n/** Focus starts in the first field, else on the first button. */\nconst FIELDS = 'input, textarea, select, [role=\"combobox\"], button[aria-haspopup=\"listbox\"]';\nexport function useInitialFocus(ref: React.RefObject<HTMLElement | null>) {\n useEffect(() => {\n const root = ref.current;\n if (!root) return;\n const usable = (el: HTMLElement) => el.tabIndex >= 0 && !el.closest('[aria-hidden=\"true\"], [inert]') && !el.matches(':disabled');\n const field = [...root.querySelectorAll<HTMLElement>(FIELDS)].find(usable);\n (field ?? [...root.querySelectorAll<HTMLElement>('button')].find(usable))?.focus();\n }, [ref]);\n}\n\n/* ---------- Alert dialog ---------- */\n\nexport type AlertDialogTone = 'danger' | 'warning' | 'info';\n\n/** Same icons as the Alert: danger = circle-alert, warning = triangle-alert, info = info. */\nconst TONE_ICONS: Record<AlertDialogTone, typeof Info> = {\n danger: CircleAlert,\n warning: TriangleAlert,\n info: Info,\n};\n\nexport interface AlertDialogProps extends OpenProps {\n /** danger: irreversible or destructive · warning: risk of data loss · info: must be acknowledged. */\n tone?: AlertDialogTone;\n /** Required. A question („Delete Q3-Report.pdf?“). */\n title: ReactNode;\n /** The consequence („This cannot be undone.“). */\n children?: ReactNode;\n /** Verb of the action („Delete“). Danger tone: danger button, else primary. */\n actionLabel: string;\n /** Runs, then the dialog closes. A promise shows the pending state until it resolves. */\n onAction?: () => void | Promise<unknown>;\n cancelLabel?: string;\n className?: string;\n}\n\n/**\n * Alert dialog – a decision that needs an answer before the user can go on.\n * role alertdialog, no X, a click on the scrim never closes, Esc = Cancel. Focus starts on Cancel,\n * so an accidental Enter never deletes. Below 640 px: icon on top, buttons stacked (lg).\n */\nexport function AlertDialog({ tone = 'danger', title, children, actionLabel, onAction, cancelLabel = 'Cancel', className, ...openProps }: AlertDialogProps) {\n const [open, setOpen] = useOpenState(openProps);\n const isMobile = useMediaQuery(MOBILE_QUERY);\n const descriptionId = useId();\n const Icon = TONE_ICONS[tone];\n const size: ButtonSize = isMobile ? 'lg' : 'md';\n return (\n <ModalOverlay isOpen={open} onOpenChange={setOpen} isDismissable={false} className=\"medo-dialog-overlay\">\n <Modal className={cx('medo-dialog', 'medo-alert-dialog', `medo-alert-dialog--${tone}`, className)}>\n <AriaDialog role=\"alertdialog\" aria-describedby={children ? descriptionId : undefined} className=\"medo-dialog__dialog\">\n {({ close }) => (\n <>\n <div className=\"medo-alert-dialog__content\">\n <span className=\"medo-alert-dialog__icon\" aria-hidden=\"true\">\n <Icon />\n </span>\n <div className=\"medo-alert-dialog__text\">\n <Heading slot=\"title\" className=\"medo-alert-dialog__title\">\n {title}\n </Heading>\n {children && (\n <div id={descriptionId} className=\"medo-alert-dialog__description\">\n {children}\n </div>\n )}\n </div>\n </div>\n <ButtonGroup>\n <Button variant=\"secondary\" size={size} autoFocus onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={{ label: actionLabel, onAction }} close={close} size={size} variant={tone === 'danger' ? 'danger' : 'primary'} />\n </ButtonGroup>\n </>\n )}\n </AriaDialog>\n </Modal>\n </ModalOverlay>\n );\n}\n","import { useContext, useEffect, useId, useRef, useState, type KeyboardEvent, type MouseEvent, type ReactNode } from 'react';\nimport {\n Autocomplete,\n Button as AriaButton,\n Collection,\n CollectionBuilder,\n ComboBox as AriaComboBox,\n ComboBoxStateContext,\n Group,\n Input,\n Popover,\n TextField as AriaTextField,\n useFilter,\n type ComboBoxProps as AriaComboBoxProps,\n type Key,\n type Selection,\n} from 'react-aria-components';\nimport { ChevronDown, CircleAlert, Plus, Search, X } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button } from '../button/Button';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox, ListBoxMessage, ListBoxSection, OptionHighlightContext, Option } from '../listbox/ListBox';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { Tag, TagGroup } from '../tag/Tag';\nimport { InputAction, type InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { useFitCount } from '../utils/useFitCount';\nimport '../text-field/input.css';\nimport '../tag/tag.css';\nimport '../select/select.css';\nimport '../bottom-sheet/bottom-sheet.css';\nimport './combobox.css';\n\ntype ComboMode = 'single' | 'multiple';\ntype Value = Key | null | Key[];\n\n/** Key of the „Add …“ row. Never stored as a value. */\nconst CREATE_KEY = '__medo_create__';\n\nexport interface ComboboxProps<T extends object, M extends ComboMode = 'single'>\n extends Omit<AriaComboBoxProps<T, M>, 'children' | 'className' | 'style' | 'placeholder' | 'menuTrigger'> {\n /** Visible label. Always set one. */\n label: ReactNode;\n /** Helper text below the field. Replaced by the error message when invalid. */\n description?: ReactNode;\n /** Error text shown when the field is invalid. */\n errorMessage?: ReactNode;\n /** A hint like „Search…“. */\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. lg on mobile. */\n size?: InputSize;\n /** Decorative icon before the text, e.g. a search icon. */\n leadingIcon?: ReactNode;\n /** Server search: shows a loading row (previous results stay) and marks the list busy. */\n isLoading?: boolean;\n /** Empty list text. Default: „No results for „…““. */\n noResultsMessage?: (inputValue: string) => ReactNode;\n /** Multi only: shows an „Add …“ row for text without an exact match. Return the key of the new item to select it. */\n onCreate?: (text: string) => Key | void;\n /** Option and ListBoxSection elements, or a render function with items / defaultItems. */\n children: ReactNode | ((item: T) => ReactNode);\n /** auto (default): popover on desktop, Bottom Sheet with search below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n /** Multi in the sheet: live (forms, footer „Done“) · onClose (filters: onApply once when the sheet closes, if changed). */\n commit?: 'live' | 'onClose';\n /** commit=\"onClose\": apply the selection (load results, write the URL …). */\n onApply?: (value: Key[]) => void;\n /** commit=\"onClose\": label of the primary sheet button, ideally with the live result count. */\n resultLabel?: (value: Key[]) => ReactNode;\n className?: string;\n}\n\n/**\n * Combobox – a Select you can type into; typing filters the list.\n * Built on React Aria ComboBox: opens on typing, arrow down or the chevron – never on focus.\n * Contains-match, case and accent insensitive; the first match is highlighted, Enter picks it.\n * Leaving without a selection restores the last valid value.\n * Local data: `defaultItems` (filtered here). Server data: `items` + `inputValue` / `onInputChange` + `isLoading`.\n */\nexport function Combobox<T extends object, M extends ComboMode = 'single'>({\n label,\n description,\n errorMessage,\n placeholder = 'Search…',\n size = 'md',\n leadingIcon,\n isLoading,\n noResultsMessage = (text) => (text ? `No results for „${text}“` : 'No results'),\n onCreate,\n children,\n overlay = 'auto',\n commit = 'live',\n onApply,\n resultLabel = () => 'Show results',\n className,\n selectionMode,\n value: valueProp,\n defaultValue,\n onChange,\n onInputChange,\n ...props\n}: ComboboxProps<T, M>) {\n const multiple = selectionMode === 'multiple';\n const groupRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const entryRef = useRef<HTMLSpanElement>(null);\n const textRef = useRef('');\n const [text, setText] = useState('');\n const [exact, setExact] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n\n // Own value state, so the „Add …“ row can be intercepted before it becomes a value.\n const [inner, setInner] = useState<Value>((defaultValue as Value) ?? (multiple ? [] : null));\n const value = (valueProp !== undefined ? valueProp : inner) as Value;\n const setValue = (next: Value) => {\n if (valueProp === undefined) setInner(next);\n (onChange as ((v: Value) => void) | undefined)?.(next);\n };\n\n const handleChange = (next: Value) => {\n if (Array.isArray(next) && next.includes(CREATE_KEY)) {\n const rest = next.filter((k) => k !== CREATE_KEY);\n const created = onCreate?.(textRef.current.trim());\n setValue(created != null ? [...rest, created] : rest);\n return;\n }\n setValue(next);\n };\n\n const mobile = useMediaQuery(MOBILE_QUERY);\n if (overlay === 'sheet' || (overlay === 'auto' && mobile)) {\n return (\n <ComboboxSheet<T>\n {...{\n label,\n description,\n errorMessage,\n placeholder,\n size,\n leadingIcon,\n isLoading,\n noResultsMessage,\n onCreate,\n children,\n className,\n }}\n multiple={multiple}\n value={value}\n onValueChange={handleChange}\n textRef={textRef}\n items={props.items}\n defaultItems={props.defaultItems}\n inputValue={props.inputValue}\n onInputChange={onInputChange}\n isDisabled={props.isDisabled}\n isReadOnly={props.isReadOnly}\n isInvalid={props.isInvalid}\n isRequired={props.isRequired}\n name={props.name}\n commit={commit}\n onApply={onApply}\n resultLabel={resultLabel}\n />\n );\n }\n\n // Click on the free space of the field puts the caret into the input.\n const focusInput = (e: MouseEvent) => {\n if (e.target === e.currentTarget) {\n e.preventDefault();\n inputRef.current?.focus();\n }\n };\n\n return (\n <AriaComboBox<T, M>\n {...(props as AriaComboBoxProps<T, M>)}\n selectionMode={selectionMode}\n value={value as never}\n onChange={handleChange as never}\n onInputChange={(text) => {\n textRef.current = text;\n setText(text.trim());\n onInputChange?.(text);\n }}\n menuTrigger=\"input\"\n allowsEmptyCollection\n className={cx('medo-field', 'medo-combobox', className)}\n >\n <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>\n <Group ref={groupRef} className={cx('medo-input', `medo-input--${size}`, 'medo-combobox__field')} onMouseDown={focusInput}>\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n {multiple ? (\n /* Tags and input share one line; the tags get what is left after 4 rem for typing. */\n <span className=\"medo-combobox__entry\" ref={entryRef}>\n <SelectedTags entryRef={entryRef} size={size} label={label} isDisabled={props.isDisabled} isReadOnly={props.isReadOnly} />\n <ComboInput ref={inputRef} placeholder={placeholder} multiple onRemoved={setAnnouncement} />\n </span>\n ) : (\n <ComboInput ref={inputRef} placeholder={placeholder} multiple={false} onRemoved={setAnnouncement} />\n )}\n <ClearButton inputRef={inputRef} isDisabled={props.isDisabled || props.isReadOnly} />\n {!props.isReadOnly && (\n <AriaButton className=\"medo-input__action medo-combobox__toggle\">\n <ChevronDown aria-hidden=\"true\" />\n </AriaButton>\n )}\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage} />\n <span className=\"medo-visually-hidden\" aria-live=\"polite\">\n {announcement}\n </span>\n <Popover offset={4} className=\"medo-listbox-popover\">\n <ComboList<T>\n size={size}\n items={props.items ?? props.defaultItems}\n isLoading={isLoading}\n noResultsMessage={noResultsMessage}\n creatable={multiple && !!onCreate}\n text={text}\n exact={exact}\n onExactChange={setExact}\n >\n {children}\n </ComboList>\n </Popover>\n </AriaComboBox>\n );\n}\n\n/** Text input. Multi: Backspace in the empty input removes the last value. */\nfunction ComboInput({\n ref,\n placeholder,\n multiple,\n onRemoved,\n}: {\n ref: React.Ref<HTMLInputElement>;\n placeholder: string;\n multiple: boolean;\n onRemoved: (message: string) => void;\n}) {\n const state = useContext(ComboBoxStateContext);\n const values = Array.isArray(state?.value) ? state.value : [];\n const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (!multiple || !state || e.key !== 'Backspace' || state.inputValue !== '' || values.length === 0) return;\n const last = state.selectedItems.at(-1);\n state.setValue(values.slice(0, -1));\n if (last) onRemoved(`${last.textValue} removed`);\n };\n return (\n <Input\n ref={ref}\n className=\"medo-input__control medo-combobox__input\"\n // Multi with values: the placeholder would compete with the tags.\n placeholder={multiple && values.length > 0 ? undefined : placeholder}\n onKeyDown={onKeyDown}\n />\n );\n}\n\n/** Clears text and value. Visible with text or a value. Beside the toggle, never inside another button. */\nfunction ClearButton({ inputRef, isDisabled }: { inputRef: React.RefObject<HTMLInputElement | null>; isDisabled?: boolean }) {\n const state = useContext(ComboBoxStateContext);\n if (!state || isDisabled) return null;\n const hasValue = Array.isArray(state.value) ? state.value.length > 0 : state.value != null;\n if (!hasValue && !state.inputValue) return null;\n return (\n <InputAction\n // slot={null}: not the ComboBox's own toggle button.\n slot={null}\n excludeFromTabOrder\n aria-label={Array.isArray(state.value) ? 'Clear all' : 'Clear'}\n icon={<X />}\n onPress={() => {\n state.setValue(Array.isArray(state.value) ? [] : null);\n state.setInputValue('');\n inputRef.current?.focus();\n }}\n />\n );\n}\n\n/** Multi: chosen values as removable tags in one line, the rest as „+N“; the caret sits after them. */\nfunction SelectedTags({\n entryRef,\n size,\n label,\n isDisabled,\n isReadOnly,\n}: {\n entryRef: React.RefObject<HTMLSpanElement | null>;\n size: InputSize;\n label: ReactNode;\n isDisabled?: boolean;\n isReadOnly?: boolean;\n}) {\n const state = useContext(ComboBoxStateContext);\n const items = (state?.selectedItems ?? []).filter(Boolean);\n const values = Array.isArray(state?.value) ? state.value : [];\n const key = items.map((item) => item.key).join('\\u0000');\n const measureRef = useRef<HTMLSpanElement>(null);\n // Keeps room for the text input (4 rem + gap) next to the tags.\n const visible = useFitCount(entryRef, measureRef, key, items.length, 68);\n if (!state || items.length === 0) return null;\n const tagSize = size === 'lg' ? 'md' : 'sm';\n const hidden = items.length - visible;\n const name = typeof label === 'string' ? label : 'Selected';\n\n return (\n <span className=\"medo-combobox__tags-row\">\n <span className={cx('medo-combobox__measure')} ref={measureRef} aria-hidden=\"true\">\n {items.map((item) => (\n <span key={item.key} className={cx('medo-tag', `medo-tag--${tagSize}`)} data-allows-removing=\"\">\n <span className=\"medo-tag__label\">{item.textValue}</span>\n <span className=\"medo-tag__remove\" />\n </span>\n ))}\n <span className={cx('medo-tag', `medo-tag--${tagSize}`)}>+{items.length}</span>\n </span>\n <TagGroup\n aria-label={`${name}: selected`}\n size={tagSize}\n className=\"medo-combobox__tags\"\n items={items.slice(0, visible)}\n disabledKeys={isDisabled ? items.map((item) => item.key) : undefined}\n onRemove={isReadOnly ? undefined : (keys) => state.setValue(values.filter((k) => !keys.has(k)))}\n >\n {(item) => <Tag id={item.key}>{item.textValue}</Tag>}\n </TagGroup>\n {hidden > 0 && (\n <span className={cx('medo-tag', `medo-tag--${tagSize}`, 'medo-combobox__more')}>\n +{hidden}\n <span className=\"medo-visually-hidden\"> more selected</span>\n </span>\n )}\n </span>\n );\n}\n\n/**\n * The list: options, optional „Add …“ row, empty message and loading row.\n * Note: React Aria builds the collection from these children before the ComboBox state exists,\n * so everything inside the ListBox depends on props (`text`, `exact`), never on the state.\n */\nfunction ComboList<T extends object>({\n size,\n items,\n isLoading,\n noResultsMessage,\n creatable,\n text,\n exact,\n onExactChange,\n children,\n}: {\n size: InputSize;\n items?: Iterable<T>;\n isLoading?: boolean;\n noResultsMessage: (inputValue: string) => ReactNode;\n creatable: boolean;\n text: string;\n exact: boolean;\n onExactChange: (exact: boolean) => void;\n children: ReactNode | ((item: T) => ReactNode);\n}) {\n const state = useContext(ComboBoxStateContext);\n const nodes = state ? [...state.collection].filter((node) => node.key !== CREATE_KEY) : [];\n const hasItems = nodes.length > 0;\n const exactNow = nodes.some((node) => node.textValue.toLocaleLowerCase() === text.toLocaleLowerCase());\n useEffect(() => {\n if (state && exactNow !== exact) onExactChange(exactNow);\n });\n\n // „First match ready“: while typing, the first enabled option is highlighted, so Enter picks it.\n const typing = !!state?.isOpen && text !== '';\n useEffect(() => {\n if (!state || !typing) return;\n // After React Aria's own update (it resets the focused option on every input change).\n const frame = requestAnimationFrame(() => {\n const manager = state.selectionManager;\n let key = state.collection.getFirstKey();\n while (key != null) {\n const node = state.collection.getItem(key);\n if (node?.type === 'item' && !manager.isDisabled(key)) break;\n key = state.collection.getKeyAfter(key);\n }\n if (key == null) return;\n manager.setFocused(true);\n if (manager.focusedKey !== key) manager.setFocusedKey(key);\n });\n return () => cancelAnimationFrame(frame);\n // Re-run when the filter result changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [typing, text, state?.collection]);\n\n return (\n <>\n <ListBox<T>\n size={size === 'lg' ? 'lg' : 'md'}\n renderEmptyState={() => <ListBoxMessage>{isLoading ? 'Loading…' : noResultsMessage(text)}</ListBoxMessage>}\n >\n {typeof children === 'function' ? <Collection items={items}>{children}</Collection> : children}\n {creatable && text && !exact && (\n <ListBoxSection aria-label=\"Create\">\n <Option id={CREATE_KEY} icon={<Plus />} textValue={text}>\n {`Add „${text}“`}\n </Option>\n </ListBoxSection>\n )}\n </ListBox>\n {/* Server search: previous results stay, the loading row sits below them. */}\n {isLoading && hasItems && <ListBoxMessage>Loading…</ListBoxMessage>}\n </>\n );\n}\n\n/* ---------- Mobile: Bottom Sheet with search ---------- */\n\ninterface ComboboxSheetProps<T> {\n label: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n placeholder: string;\n size: InputSize;\n leadingIcon?: ReactNode;\n isLoading?: boolean;\n noResultsMessage: (inputValue: string) => ReactNode;\n onCreate?: (text: string) => Key | void;\n children: ReactNode | ((item: T) => ReactNode);\n className?: string;\n multiple: boolean;\n value: Value;\n onValueChange: (value: Value) => void;\n textRef: React.RefObject<string>;\n items?: Iterable<T>;\n defaultItems?: Iterable<T>;\n inputValue?: string;\n onInputChange?: (value: string) => void;\n isDisabled?: boolean;\n isReadOnly?: boolean;\n isInvalid?: boolean;\n isRequired?: boolean;\n name?: string;\n commit: 'live' | 'onClose';\n onApply?: (value: Key[]) => void;\n resultLabel: (value: Key[]) => ReactNode;\n}\n\n/**\n * Below 640 px the field becomes a button that opens a Bottom Sheet: search on top (fixed 90 % height,\n * so it does not jump with the keyboard), options lg, single closes on tap, multi with Done or result button.\n */\nfunction ComboboxSheet<T extends object>({\n label,\n description,\n errorMessage,\n placeholder,\n size,\n leadingIcon,\n isLoading,\n noResultsMessage,\n onCreate,\n children,\n className,\n multiple,\n value,\n onValueChange,\n textRef,\n items,\n defaultItems,\n inputValue,\n onInputChange,\n isDisabled,\n isReadOnly,\n isInvalid,\n isRequired,\n name,\n commit,\n onApply,\n resultLabel,\n}: ComboboxSheetProps<T>) {\n const id = useId();\n const [isOpen, setOpen] = useState(false);\n const [ownSearch, setOwnSearch] = useState('');\n const search = inputValue ?? ownSearch;\n const setSearch = (text: string) => {\n textRef.current = text;\n if (inputValue === undefined) setOwnSearch(text);\n onInputChange?.(text);\n };\n const { contains } = useFilter({ sensitivity: 'base' });\n const list = items ?? defaultItems;\n const keys = Array.isArray(value) ? value : value == null ? [] : [value];\n const opened = useRef<string | null>(null);\n\n const query = search.trim();\n const content = typeof children === 'function' ? <Collection items={list}>{children}</Collection> : children;\n\n const open = (next: boolean) => {\n if (next) {\n setSearch('');\n opened.current = JSON.stringify(keys);\n } else if (commit === 'onClose' && multiple && opened.current !== null && opened.current !== JSON.stringify(keys)) {\n onApply?.(keys);\n }\n if (!next) opened.current = null;\n setOpen(next);\n };\n\n const onSelectionChange = (selection: Selection) => {\n const next = selection === 'all' ? [] : [...selection];\n if (multiple) {\n onValueChange(next);\n } else {\n // Tapping the chosen option again deselects it in the list: keep the value, just close (single closes on tap).\n onValueChange(next[0] ?? value);\n open(false);\n }\n };\n\n const descId = description ? `${id}-desc` : undefined;\n const errId = isInvalid && errorMessage ? `${id}-err` : undefined;\n\n // The field shows the labels of the chosen values: React Aria builds the collection from the options\n // without rendering them, the same way the Select gets its labels.\n return (\n <CollectionBuilder content={content}>\n {(collection) => {\n const nodes = [...collection.getKeys()].map((key) => collection.getItem(key)).filter((node) => node?.type === 'item');\n const text = keys.map((key) => collection.getItem(key)?.textValue ?? String(key));\n const exact = nodes.some((node) => node!.textValue.toLocaleLowerCase() === query.toLocaleLowerCase());\n return (\n <div\n className={cx('medo-field', 'medo-combobox', 'medo-select', multiple && keys.length > 0 && 'medo-select--tags', className)}\n data-invalid={isInvalid || undefined}\n data-disabled={isDisabled || undefined}\n data-readonly={isReadOnly || undefined}\n data-open={isOpen || undefined}\n >\n <span className=\"medo-field__label\" id={`${id}-label`}>\n {label}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n <div className={cx('medo-input', `medo-input--${size}`, 'medo-select__field')}>\n <AriaButton\n className=\"medo-select__trigger\"\n isDisabled={isDisabled}\n aria-haspopup=\"dialog\"\n aria-labelledby={`${id}-label ${id}-value`}\n aria-describedby={[errId ?? descId].filter(Boolean).join(' ') || undefined}\n onPress={() => !isReadOnly && open(true)}\n >\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n <span className=\"medo-select__value\" id={`${id}-value`} data-placeholder={keys.length === 0 || undefined}>\n {keys.length === 0 ? placeholder : multiple ? <DisplayTags labels={text} size={size} /> : text[0]}\n {isReadOnly && <span className=\"medo-visually-hidden\">, read only</span>}\n </span>\n {!isReadOnly && (\n <span className=\"medo-select__chevron\" aria-hidden=\"true\">\n <ChevronDown />\n </span>\n )}\n </AriaButton>\n </div>\n <div className=\"medo-field__footer\">\n {isInvalid && errorMessage ? (\n <span className=\"medo-field__error\" id={errId}>\n <CircleAlert aria-hidden=\"true\" />\n <span>{errorMessage}</span>\n </span>\n ) : (\n description && (\n <span className=\"medo-field__description\" id={descId}>\n {description}\n </span>\n )\n )}\n </div>\n {name && keys.map((key) => <input key={String(key)} type=\"hidden\" name={name} value={String(key)} />)}\n\n <BottomSheet\n title={label}\n height=\"full\"\n isOpen={isOpen}\n onOpenChange={open}\n footer={\n multiple\n ? commit === 'onClose'\n ? (close) => (\n <>\n <Button size=\"lg\" onPress={close}>\n {resultLabel(keys)}\n </Button>\n <Button size=\"lg\" variant=\"secondary\" onPress={() => onValueChange([])} isDisabled={keys.length === 0}>\n Reset\n </Button>\n </>\n )\n : (close) => (\n <>\n <p className=\"medo-sheet__count\" aria-live=\"polite\">\n {keys.length} selected\n </p>\n <Button size=\"lg\" onPress={close}>\n Done\n </Button>\n </>\n )\n : undefined\n }\n >\n <Autocomplete inputValue={search} onInputChange={setSearch} filter={items ? undefined : contains}>\n <div className=\"medo-sheet__search\">\n <AriaTextField aria-label=\"Search\" autoFocus className=\"medo-input medo-input--lg\">\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n <Search />\n </span>\n <Input className=\"medo-input__control\" placeholder={placeholder} />\n </AriaTextField>\n </div>\n <OptionHighlightContext.Provider value={query}>\n <ListBox<T>\n size=\"lg\"\n aria-labelledby={`${id}-label`}\n selectionMode={multiple ? 'multiple' : 'single'}\n selectedKeys={keys}\n onSelectionChange={onSelectionChange}\n renderEmptyState={() => <ListBoxMessage>{isLoading ? 'Loading…' : noResultsMessage(query)}</ListBoxMessage>}\n >\n {content}\n {multiple && onCreate && query && !exact && (\n <ListBoxSection aria-label=\"Create\">\n <Option id={CREATE_KEY} icon={<Plus />} textValue={query}>\n {`Add „${query}“`}\n </Option>\n </ListBoxSection>\n )}\n </ListBox>\n </OptionHighlightContext.Provider>\n {isLoading && list && [...list].length > 0 && <ListBoxMessage>Loading…</ListBoxMessage>}\n </Autocomplete>\n </BottomSheet>\n </div>\n );\n }}\n </CollectionBuilder>\n );\n}\n\n/** Chosen values as display-only tags in one line (inside the trigger button: no remove buttons). */\nfunction DisplayTags({ labels, size }: { labels: string[]; size: InputSize }) {\n const rowRef = useRef<HTMLSpanElement>(null);\n const measureRef = useRef<HTMLSpanElement>(null);\n const visible = useFitCount(rowRef, measureRef, labels.join('\\u0000'), labels.length);\n const tagClass = cx('medo-tag', size === 'lg' ? 'medo-tag--md' : 'medo-tag--sm');\n return (\n <span className=\"medo-select__tags\" ref={rowRef}>\n <span className=\"medo-visually-hidden\">{labels.join(', ')}</span>\n <span className=\"medo-select__measure\" ref={measureRef} aria-hidden=\"true\">\n {labels.map((l, i) => (\n <span key={i} className={tagClass}>\n {l}\n </span>\n ))}\n <span className={tagClass}>+{labels.length}</span>\n </span>\n {labels.slice(0, visible).map((l, i) => (\n <span key={i} className={tagClass} aria-hidden=\"true\">\n <span className=\"medo-select__tag-label\">{l}</span>\n </span>\n ))}\n {labels.length > visible && (\n <span className={tagClass} aria-hidden=\"true\">\n +{labels.length - visible}\n </span>\n )}\n </span>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { flushSync } from 'react-dom';\nimport {\n Button,\n Text,\n UNSTABLE_Toast as AriaToast,\n UNSTABLE_ToastContent as AriaToastContent,\n UNSTABLE_ToastQueue as ToastQueue,\n UNSTABLE_ToastRegion as AriaToastRegion,\n} from 'react-aria-components';\nimport { X } from 'lucide-react';\nimport './toast.css';\n\n/*\n * React Aria's Toast is still marked UNSTABLE. Only this file imports it, so an API change\n * in React Aria stays here – apps use `ToastRegion` and `toast()`.\n */\n\nexport interface ToastAction {\n /** „Undo“, „View“ or „Retry“. It must also be reachable elsewhere in the app. */\n label: string;\n onAction: () => void;\n}\n\nexport interface ToastOptions {\n /** Max one action. Pressing it runs the action and closes the toast. */\n action?: ToastAction;\n /** Errors („Could not save“): stays until closed. Otherwise 5 s, with an action 8 s. */\n persistent?: boolean;\n /** Called when the toast closes (timeout, close button, Esc or action). */\n onClose?: () => void;\n}\n\ninterface ToastContent {\n message: string;\n action?: ToastAction;\n}\n\n/** Timing: message only 5 s, with action 8 s, errors without timeout. */\nconst TIMEOUT = 5000;\nconst TIMEOUT_ACTION = 8000;\nconst MAX_VISIBLE = 3;\n\n/** The app-wide queue: max 3 visible, newest first. Changes run in a View Transition where supported. */\nconst queue = new ToastQueue<ToastContent>({\n maxVisibleToasts: MAX_VISIBLE,\n wrapUpdate(fn) {\n if (typeof document !== 'undefined' && 'startViewTransition' in document) {\n document.startViewTransition(() => flushSync(fn));\n } else {\n fn();\n }\n },\n});\n\n/**\n * Shows a toast: short, temporary feedback after an action.\n * Write the result, not the process („Q3-Report.pdf deleted“), one line, max about 50 characters.\n * Returns the key for `toast.close(key)`. The same message is never shown twice at once.\n */\nexport function toast(message: string, { action, persistent = false, onClose }: ToastOptions = {}): string {\n const same = queue.visibleToasts.find((t) => t.content.message === message);\n if (same) return same.key;\n // Max 3 – the oldest leaves first (React Aria would hold it back and show it again later).\n const visible = queue.visibleToasts;\n if (visible.length >= MAX_VISIBLE) queue.close(visible[visible.length - 1].key);\n return queue.add({ message, action }, { timeout: persistent ? undefined : action ? TIMEOUT_ACTION : TIMEOUT, onClose });\n}\n\n/** Closes a toast by its key. */\ntoast.close = (key: string) => queue.close(key);\n/** Closes all toasts (e.g. on sign-out). */\ntoast.clear = () => queue.clear();\n\nlet regionMounted = false;\n\n/** Esc closes the focused toast (React Aria's Toast has no key handling of its own). React 19 ref cleanup removes the listener. */\nfunction closeOnEscape(el: HTMLElement | null, key: string) {\n if (!el) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n e.stopPropagation();\n queue.close(key);\n };\n el.addEventListener('keydown', onKeyDown);\n return () => el.removeEventListener('keydown', onKeyDown);\n}\n\nexport interface ToastRegionProps {\n /** Accessible name of the landmark. Default: „Notifications“ (localized by React Aria). */\n 'aria-label'?: string;\n /** Accessible name of the close buttons. Default: „Close“ (localized by React Aria). */\n closeLabel?: string;\n}\n\n/**\n * The place where toasts appear – render it once at the root of the app.\n * A landmark: F6 moves focus into it, new toasts are announced. Desktop bottom right,\n * mobile full width (set `--medo-toast-offset` to the height of a bottom navigation).\n * Hover, focus and a hidden window pause the timers (WCAG 2.2.1).\n */\nexport function ToastRegion({ closeLabel, ...props }: ToastRegionProps) {\n // One region per page: a second one (e.g. several Storybook stories) stays empty instead of duplicating toasts.\n const [active, setActive] = useState(false);\n useEffect(() => {\n if (regionMounted) return;\n regionMounted = true;\n setActive(true);\n // Do not lose messages in a background tab.\n const onVisibility = () => (document.hidden ? queue.pauseAll() : queue.resumeAll());\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n regionMounted = false;\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, []);\n if (!active) return null;\n\n return (\n <AriaToastRegion {...props} queue={queue} className=\"medo-toast-region\">\n {({ toast: t }) => (\n <AriaToast\n toast={t}\n className=\"medo-toast\"\n style={{ viewTransitionName: t.key }}\n ref={(el) => closeOnEscape(el, t.key)}\n >\n <AriaToastContent className=\"medo-toast__content\">\n <Text slot=\"title\" className=\"medo-toast__message\">\n {t.content.message}\n </Text>\n </AriaToastContent>\n {t.content.action && (\n <Button\n className=\"medo-toast__button medo-toast__action\"\n onPress={() => {\n t.content.action?.onAction();\n queue.close(t.key);\n }}\n >\n {t.content.action.label}\n </Button>\n )}\n <Button slot=\"close\" aria-label={closeLabel} className=\"medo-toast__button medo-toast__close\">\n <X aria-hidden=\"true\" />\n </Button>\n </AriaToast>\n )}\n </AriaToastRegion>\n );\n}\n","import { useLayoutEffect, useRef, type ReactNode } from 'react';\nimport {\n SelectionIndicator,\n Tab as AriaTab,\n TabList as AriaTabList,\n TabPanel as AriaTabPanel,\n Tabs as AriaTabs,\n type TabListProps as AriaTabListProps,\n type TabPanelProps as AriaTabPanelProps,\n type TabProps as AriaTabProps,\n type TabsProps as AriaTabsProps,\n} from 'react-aria-components';\nimport { BadgeCount } from '../badge/Badge';\nimport { cx } from '../utils/cx';\nimport './tabs.css';\n\nexport interface TabsProps extends Omit<AriaTabsProps, 'className' | 'style' | 'orientation'> {\n /** md: tab 32 / track 40 · lg: 40 / 48. Below 640 px tabs are always lg. */\n size?: 'md' | 'lg';\n /** The tabs share the full width. Below 640 px automatic: up to 3 tabs fill, more scroll. */\n fullWidth?: boolean;\n className?: string;\n}\n\n/**\n * Tabs – switch between views of the same context, one panel visible at a time.\n * Built on React Aria Tabs: tablist / tab / tabpanel, only the selected tab is in the Tab order,\n * ← → move and select, Home / End. `keyboardActivation=\"manual\"` for slow panels (select with Enter).\n * Keep the selected tab in the URL with `selectedKey` + `onSelectionChange`.\n */\nexport function Tabs({ size = 'md', fullWidth = false, className, ...props }: TabsProps) {\n return <AriaTabs {...props} className={cx('medo-tabs', `medo-tabs--${size}`, fullWidth && 'medo-tabs--full', className)} />;\n}\n\nexport interface TabListProps<T> extends Omit<AriaTabListProps<T>, 'className' | 'style'> {\n /** Names the tabs when there is no visible heading („Project“). */\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * The track with the tabs. 2 to 6 tabs. Scrolls horizontally when it does not fit\n * (with a fade at the edge that still has tabs) – tabs never wrap.\n */\nexport function TabList<T extends object>({ className, ...props }: TabListProps<T>) {\n const ref = useRef<HTMLDivElement>(null);\n useScrollEdges(ref);\n return <AriaTabList {...props} ref={ref} className={cx('medo-tabs__list', className)} />;\n}\n\nexport interface TabProps extends Omit<AriaTabProps, 'className' | 'style' | 'children'> {\n /** Required. 1–2 words, a noun („Activity“). */\n children: string;\n /** Optional, then on all tabs. Decorative – the label carries the meaning. */\n icon?: ReactNode;\n /** Items waiting in the tab (Badge count, neutral). Hidden at 0. */\n count?: number;\n /** Screen-reader text of the count („3 new“). Without it the number is read as part of the name. */\n countLabel?: string;\n}\n\n/** One tab. The selected tab is a raised thumb that slides to the new tab with a snappy spring (no slide with reduced motion). */\nexport function Tab({ children, icon, count, countLabel, ...props }: TabProps) {\n return (\n <AriaTab {...props} className=\"medo-tab\">\n <SelectionIndicator className=\"medo-tab__thumb\" ref={revealInList} />\n {icon && (\n <span className=\"medo-tab__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-tab__label\">{children}</span>\n {count !== undefined && <BadgeCount count={count} tone=\"neutral\" size=\"sm\" label={countLabel ?? String(count)} />}\n </AriaTab>\n );\n}\n\nexport interface TabPanelProps extends Omit<AriaTabPanelProps, 'className' | 'style' | 'shouldForceMount'> {\n /**\n * Keeps the panel (hidden) while another tab is selected, so input is never lost.\n * Set false for heavy panels (large tables, charts) to unmount them.\n */\n keepMounted?: boolean;\n className?: string;\n}\n\n/** The content of one tab, directly below the tab list. It is focusable when nothing inside is. */\nexport function TabPanel({ keepMounted = true, className, ...props }: TabPanelProps) {\n return <AriaTabPanel {...props} shouldForceMount={keepMounted} className={cx('medo-tabs__panel', className)} />;\n}\n\n/** The thumb mounts in the selected tab: scroll that tab fully into the track (without moving the page). */\nfunction revealInList(thumb: HTMLDivElement | null) {\n const tab = thumb?.parentElement;\n const list = tab?.parentElement;\n if (!tab || !list || list.scrollWidth <= list.clientWidth) return;\n const start = tab.offsetLeft - list.offsetLeft;\n const end = start + tab.offsetWidth;\n if (start < list.scrollLeft) list.scrollTo({ left: start - 32 });\n else if (end > list.scrollLeft + list.clientWidth) list.scrollTo({ left: end - list.clientWidth + 32 });\n}\n\n/** Marks the edges that still have hidden tabs (data-scroll-start / data-scroll-end) for the fade. */\nfunction useScrollEdges(ref: React.RefObject<HTMLDivElement | null>) {\n useLayoutEffect(() => {\n const list = ref.current;\n if (!list) return;\n const update = () => {\n const max = list.scrollWidth - list.clientWidth;\n const start = Math.abs(list.scrollLeft); // RTL scrolls negative\n list.toggleAttribute('data-scroll-start', max > 1 && start > 1);\n list.toggleAttribute('data-scroll-end', max > 1 && start < max - 1);\n };\n update();\n list.addEventListener('scroll', update, { passive: true });\n const observer = new ResizeObserver(update);\n observer.observe(list);\n return () => {\n list.removeEventListener('scroll', update);\n observer.disconnect();\n };\n }, [ref]);\n}\n","import { useContext, useRef, type ReactNode } from 'react';\nimport {\n Dialog as AriaDialog,\n DialogTrigger,\n Heading,\n OverlayTriggerStateContext,\n Popover as AriaPopover,\n type PopoverProps as AriaPopoverProps,\n} from 'react-aria-components';\nimport { Info, X } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button, ButtonGroup } from '../button/Button';\nimport { ActionButton, useInitialFocus, type DialogAction } from '../dialog/Dialog';\nimport { IconButton } from '../icon-button/IconButton';\nimport { Link } from '../link/Link';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport './popover.css';\n\n/** Opens a Popover from a trigger on click (React Aria DialogTrigger). The trigger is pressed and aria-expanded while open. */\nexport const PopoverTrigger = DialogTrigger;\n\nexport interface PopoverProps {\n /** Header with title and close button. Use it when the content needs a title or holds a form. */\n title?: ReactNode;\n /** Required without a title: names the popover. */\n 'aria-label'?: string;\n /** Interactive content. A function gets `close`. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** sm 240 · md 320 · lg 400 · auto: hugs content without padding (e.g. a calendar). */\n size?: 'sm' | 'md' | 'lg' | 'auto';\n /** Footer, only when changes must be confirmed – otherwise apply them live. Cancel + main action (Button sm). */\n primaryAction?: DialogAction;\n cancelLabel?: string;\n /** Accessible name of the close button. */\n closeLabel?: string;\n /** auto: popover on desktop, Bottom Sheet below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n /** Default bottom start; flips when there is no space. */\n placement?: AriaPopoverProps['placement'];\n className?: string;\n}\n\n/**\n * Popover – a small floating panel with interactive content, anchored to its trigger.\n * Opens on click, never on hover. Non-modal: the page stays usable; focus moves in, Esc or a click\n * outside closes it and focus returns to the trigger. One topic per popover, one popover at a time.\n */\nexport function Popover({\n title,\n 'aria-label': ariaLabel,\n children,\n size = 'md',\n primaryAction,\n cancelLabel = 'Cancel',\n closeLabel = 'Close',\n overlay = 'auto',\n placement = 'bottom start',\n className,\n}: PopoverProps) {\n const mobile = useMediaQuery(MOBILE_QUERY);\n const content = (close: () => void) => (typeof children === 'function' ? children(close) : children);\n\n // Mobile: forms and rich content as Bottom Sheet – thumb reach and room for the keyboard.\n if (overlay === 'sheet' || (overlay === 'auto' && mobile)) {\n return (\n <BottomSheet\n title={title ?? ariaLabel}\n closeLabel={closeLabel}\n className={className}\n footer={\n primaryAction &&\n ((close) => (\n <ButtonGroup>\n <Button variant=\"secondary\" size=\"lg\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={close} size=\"lg\" variant=\"primary\" />\n </ButtonGroup>\n ))\n }\n >\n <SheetBody>{content}</SheetBody>\n </BottomSheet>\n );\n }\n\n return (\n <AriaPopover placement={placement} offset={8} containerPadding={16} className={cx('medo-popover', `medo-popover--${size}`, className)}>\n <PopoverDialog aria-label={title ? undefined : ariaLabel}>\n {({ close }) => (\n <>\n {title && (\n <div className=\"medo-popover__header\">\n <Heading slot=\"title\" className=\"medo-popover__title\">\n {title}\n </Heading>\n <IconButton variant=\"ghost\" size=\"sm\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />\n </div>\n )}\n <div className=\"medo-popover__body\">{content(close)}</div>\n {primaryAction && (\n <div className=\"medo-popover__footer\">\n <ButtonGroup>\n <Button variant=\"secondary\" size=\"sm\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={close} size=\"sm\" variant=\"primary\" />\n </ButtonGroup>\n </div>\n )}\n </>\n )}\n </PopoverDialog>\n </AriaPopover>\n );\n}\n\n/** Focus starts in the first field (like Dialog), so a form popover is ready to type. */\nfunction PopoverDialog({ children, ...props }: { 'aria-label'?: string; children: (opts: { close: () => void }) => ReactNode }) {\n const ref = useRef<HTMLElement>(null);\n useInitialFocus(ref);\n return (\n <AriaDialog {...props} ref={ref} className=\"medo-popover__dialog\">\n {children}\n </AriaDialog>\n );\n}\n\n/** Content of the mobile sheet with the sheet's padding. */\nfunction SheetBody({ children }: { children: (close: () => void) => ReactNode }) {\n const state = useContext(OverlayTriggerStateContext);\n return <div className=\"medo-popover__sheet-body\">{children(() => state?.close())}</div>;\n}\n\nexport interface ToggletipProps {\n /** Required. Names the info button and the toggletip after the topic („About billing email“). */\n 'aria-label': string;\n /** One or two short sentences. Text only. */\n children: ReactNode;\n /** Optional link to more help. */\n link?: { label: string; href: string; external?: boolean };\n className?: string;\n}\n\n/**\n * Toggletip – a short explanation behind an info button, next to a label or value.\n * Opens on click, so it works with touch, keyboard and screen readers – unlike a tooltip.\n * Esc or a click outside closes it. Stays a popover on mobile (full width minus 16 px).\n */\nexport function Toggletip({ 'aria-label': label, children, link, className }: ToggletipProps) {\n return (\n <DialogTrigger>\n <IconButton variant=\"ghost\" size=\"sm\" icon={<Info />} aria-label={label} tooltip={false} />\n <AriaPopover placement=\"bottom start\" offset={8} containerPadding={16} className={cx('medo-popover', 'medo-toggletip', className)}>\n <AriaDialog aria-label={label} className=\"medo-popover__dialog medo-toggletip__dialog\">\n <div className=\"medo-toggletip__text\">{children}</div>\n {link && (\n <Link variant=\"standalone\" size=\"md\" href={link.href} external={link.external} target={link.external ? '_blank' : undefined}>\n {link.label}\n </Link>\n )}\n </AriaDialog>\n </AriaPopover>\n </DialogTrigger>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Link as AriaLink, type LinkProps as AriaLinkProps } from 'react-aria-components';\nimport { ArrowRight, ExternalLink } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport '../utils/utilities.css';\nimport './link.css';\n\nexport interface LinkProps extends Omit<AriaLinkProps, 'children' | 'className'> {\n /** The text says where it goes („Privacy policy“, not „click here“). */\n children: ReactNode;\n /** inline: inside running text, always underlined · standalone: own line, underline on hover. */\n variant?: 'inline' | 'standalone';\n /** Standalone only: sm (label/sm) · md (label/md). Inline links take the size of the surrounding text. */\n size?: 'sm' | 'md';\n /** Another website: shows the external icon. With target=\"_blank\" screen readers also hear „opens in a new tab“. */\n external?: boolean;\n /** Standalone only: arrow after the text („View all →“). */\n arrow?: boolean;\n /** Hidden text for links that open a new tab. */\n newTabLabel?: string;\n className?: string;\n}\n\n/**\n * Link – navigates to a page, place or file. Built on React Aria Link:\n * a real `<a href>`, works with client-side routers through RouterProvider. For actions use Button.\n */\nexport function Link({\n children,\n variant = 'inline',\n size = 'md',\n external,\n arrow,\n newTabLabel = '(opens in a new tab)',\n className,\n ...props\n}: LinkProps) {\n const newTab = props.target === '_blank';\n return (\n <AriaLink\n {...props}\n rel={newTab ? (props.rel ?? 'noopener noreferrer') : props.rel}\n className={cx('medo-link', variant === 'standalone' && 'medo-link--standalone', variant === 'standalone' && `medo-link--${size}`, className)}\n >\n {children}\n {external && <ExternalLink className=\"medo-link__icon\" aria-hidden=\"true\" />}\n {!external && arrow && variant === 'standalone' && <ArrowRight className=\"medo-link__icon\" aria-hidden=\"true\" />}\n {newTab && <span className=\"medo-visually-hidden\"> {newTabLabel}</span>}\n </AriaLink>\n );\n}\n","import { Children, createContext, isValidElement, useContext, useEffect, useId, useRef, useState, type ReactElement, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Dialog as AriaDialog,\n DialogTrigger,\n Heading,\n Link as AriaLink,\n Modal,\n ModalOverlay,\n type LinkProps as AriaLinkProps,\n type PressEvent,\n} from 'react-aria-components';\nimport { ChevronDown, Ellipsis, Menu as MenuIcon, PanelLeft, X } from 'lucide-react';\nimport { Avatar } from '../avatar/Avatar';\nimport { BadgeCount, BadgeDot } from '../badge/Badge';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { IconButton } from '../icon-button/IconButton';\nimport { Tooltip, TooltipLink, TooltipTrigger } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { useMediaQuery } from '../utils/useMediaQuery';\nimport { Drawer } from '../drawer/Drawer';\nimport './navigation.css';\n\n/*\n * Navigation – med.o Design System\n * Navigation is always made of links in a named <nav> region; the current page has aria-current=\"page\".\n * One NavItem renders in four forms, chosen by the container: header · sidebar · rail · sheet.\n */\n\nexport type NavVariant = 'header' | 'sidebar' | 'rail' | 'sheet';\nconst NavVariantContext = createContext<NavVariant>('sidebar');\n\n/** Side navigation: groups in the rail expand it (with the group open); links in the tablet drawer close it. */\nconst SideNavContext = createContext<{ expand: (group?: string) => void; openGroup?: string; onNavigate?: () => void } | null>(null);\n\nconst TABLET_QUERY = '(min-width: 640px) and (max-width: 1023.98px)';\nconst SITE_MENU_QUERY = '(max-width: 767.98px)';\n\n/* ---------- Nav item ---------- */\n\nexport interface NavItemProps extends Omit<AriaLinkProps, 'children' | 'className' | 'style'> {\n /** Required. 1–2 words, a noun – the same name in header, sidebar, tab bar and page title. */\n children: string;\n /** Sidebar, rail and sheet: icon before the label (decorative). Header items have no icon. */\n icon?: ReactNode;\n /** The current page (exactly one). Marked with aria-current=\"page\" and action/selected. */\n isCurrent?: boolean;\n /** Number in the item (Badge count, neutral). */\n count?: number;\n /** Screen-reader text of the count („3 unread“, „12 projects“). */\n countLabel?: string;\n /** The count is new or unread: in the rail it turns into a dot. Plain totals („12 projects“) are hidden there. */\n unread?: boolean;\n}\n\n/**\n * One navigation link. Built on React Aria Link, so client-side routing works\n * with any router through RouterProvider. The container decides the form (header, sidebar, rail, sheet).\n */\nexport function NavItem({ children, icon, isCurrent, count, countLabel, unread, ...props }: NavItemProps) {\n const variant = useContext(NavVariantContext);\n const sideNav = useContext(SideNavContext);\n const rail = variant === 'rail';\n const content = (\n <>\n {icon && variant !== 'header' && (\n <span className=\"medo-nav-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className={rail ? 'medo-visually-hidden' : 'medo-nav-item__label'}>{children}</span>\n {count !== undefined &&\n (rail ? (\n unread && count > 0 && <BadgeDot tone=\"danger\" label={countLabel ?? String(count)} className=\"medo-nav-item__dot\" />\n ) : (\n <BadgeCount count={count} tone=\"neutral\" size=\"sm\" label={countLabel ?? String(count)} />\n ))}\n </>\n );\n const linkProps = {\n ...props,\n onPress: (e: PressEvent) => {\n props.onPress?.(e);\n sideNav?.onNavigate?.();\n },\n 'aria-current': isCurrent ? ('page' as const) : undefined,\n className: cx('medo-nav-item', `medo-nav-item--${variant}`),\n };\n return (\n <li className=\"medo-nav__entry\">\n {rail ? (\n // Collapsed: the label appears as tooltip on hover and focus.\n <TooltipTrigger>\n <TooltipLink {...linkProps}>{content}</TooltipLink>\n <Tooltip placement=\"end\">{children}</Tooltip>\n </TooltipTrigger>\n ) : (\n <AriaLink {...linkProps}>{content}</AriaLink>\n )}\n </li>\n );\n}\n\n/* ---------- Group (dropdown in the header, accordion elsewhere) ---------- */\n\nexport interface NavGroupProps {\n /** Label of the group button. */\n label: string;\n /** Sidebar, rail and sheet: icon before the label. */\n icon?: ReactNode;\n /** NavItems – one level only. */\n children: ReactNode;\n /** Open at start. Default: open when it contains the current page (sidebar, sheet). */\n defaultOpen?: boolean;\n}\n\n/** True when a NavItem child is the current page. */\nfunction containsCurrent(children: ReactNode) {\n return Children.toArray(children).some((c) => isValidElement(c) && (c as ReactElement<NavItemProps>).props.isCurrent);\n}\n\n/**\n * A group of links behind a disclosure button (aria-expanded) – never a menu.\n * Header: a dropdown panel on the popover surface; Tab moves through the links, Esc or a click outside closes.\n * Sidebar and sheet: opens in place, one level. The parent shows „current“ only while it is closed.\n */\nexport function NavGroup({ label, icon, children, defaultOpen }: NavGroupProps) {\n const variant = useContext(NavVariantContext);\n const sideNav = useContext(SideNavContext);\n const hasCurrent = containsCurrent(children);\n const [open, setOpen] = useState(defaultOpen ?? (variant !== 'header' && (hasCurrent || sideNav?.openGroup === label)));\n const panelId = useId();\n const itemRef = useRef<HTMLLIElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const floating = variant === 'header';\n\n // Header dropdown: Esc, a click outside or focus leaving closes it.\n useEffect(() => {\n if (!floating || !open) return;\n const item = itemRef.current;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n setOpen(false);\n buttonRef.current?.focus();\n };\n const onPointer = (e: PointerEvent) => !item?.contains(e.target as Node) && setOpen(false);\n const onFocusOut = (e: FocusEvent) => e.relatedTarget && !item?.contains(e.relatedTarget as Node) && setOpen(false);\n document.addEventListener('keydown', onKey);\n document.addEventListener('pointerdown', onPointer);\n item?.addEventListener('focusout', onFocusOut);\n return () => {\n document.removeEventListener('keydown', onKey);\n document.removeEventListener('pointerdown', onPointer);\n item?.removeEventListener('focusout', onFocusOut);\n };\n }, [floating, open]);\n\n // Rail: the group cannot open in 64 px – pressing it expands the sidebar with the group open.\n if (variant === 'rail') {\n return (\n <li className=\"medo-nav__entry\">\n <TooltipTrigger>\n <AriaButton\n className=\"medo-nav-item medo-nav-item--rail\"\n data-current={hasCurrent || undefined}\n onPress={() => {\n setOpen(true);\n sideNav?.expand(label);\n }}\n >\n <span className=\"medo-nav-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <span className=\"medo-visually-hidden\">{label}</span>\n </AriaButton>\n <Tooltip placement=\"end\">{label}</Tooltip>\n </TooltipTrigger>\n </li>\n );\n }\n\n return (\n <li ref={itemRef} className={cx('medo-nav__entry', 'medo-nav-group', floating && 'medo-nav-group--floating')}>\n <AriaButton\n ref={buttonRef}\n aria-expanded={open}\n aria-controls={panelId}\n data-current={(hasCurrent && !open) || undefined}\n onPress={() => setOpen((o) => !o)}\n className={cx('medo-nav-item', `medo-nav-item--${variant}`, 'medo-nav-group__button')}\n >\n {icon && !floating && (\n <span className=\"medo-nav-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-nav-item__label\">{label}</span>\n <ChevronDown className=\"medo-nav-group__chevron\" aria-hidden=\"true\" />\n </AriaButton>\n <NavVariantContext.Provider value={floating ? 'sidebar' : variant}>\n <ul id={panelId} hidden={!open} className={cx('medo-nav__list', floating ? 'medo-nav-group__panel' : 'medo-nav-group__list')}>\n {children}\n </ul>\n </NavVariantContext.Provider>\n </li>\n );\n}\n\n/* ---------- Nav list ---------- */\n\nexport interface NavListProps {\n /** Form of the items: header (row) · sidebar · rail · sheet. */\n variant?: NavVariant;\n /** Name of the navigation region („Footer“, „Account“). */\n 'aria-label': string;\n children: ReactNode;\n className?: string;\n}\n\n/** A named navigation region with items of one form – for navigation outside the ready-made headers and bars. */\nexport function NavList({ variant = 'sidebar', 'aria-label': label, children, className }: NavListProps) {\n return (\n <nav aria-label={label} className={className}>\n <NavVariantContext.Provider value={variant}>\n <ul className={cx('medo-nav__list', variant === 'header' && 'medo-nav__list--row', variant === 'rail' && 'medo-nav__list--rail')}>{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n );\n}\n\n/* ---------- Section (sidebar) ---------- */\n\nexport interface NavSectionProps {\n /** Overline heading („Workspace“). In the rail the section is divided by a line. */\n title: string;\n children: ReactNode;\n}\n\n/** A titled section of the side navigation. */\nexport function NavSection({ title, children }: NavSectionProps) {\n const variant = useContext(NavVariantContext);\n const id = useId();\n return (\n <li className=\"medo-nav__entry medo-nav-section\">\n {variant === 'rail' ? (\n <span className=\"medo-nav-section__divider\" role=\"presentation\" />\n ) : (\n <span id={id} className=\"medo-nav-section__title\">\n {title}\n </span>\n )}\n <ul className=\"medo-nav__list\" aria-labelledby={variant === 'rail' ? undefined : id} aria-label={variant === 'rail' ? title : undefined}>\n {children}\n </ul>\n </li>\n );\n}\n\n/* ---------- Skip link ---------- */\n\nexport interface SkipLinkProps {\n /** Id target of the main content. */\n href?: string;\n children?: string;\n}\n\n/** „Skip to content“ – the first focusable element on every page (WCAG 2.4.1). Visible on focus only. */\nexport function SkipLink({ href = '#main', children = 'Skip to content' }: SkipLinkProps) {\n return (\n <a href={href} className=\"medo-skip-link\">\n {children}\n </a>\n );\n}\n\n/* ---------- Action links (header actions that navigate) ---------- */\n\nexport interface NavAction {\n label: string;\n /** Usually a link („Log in“, „Get started“). */\n href?: string;\n onPress?: (e: PressEvent) => void;\n /** primary: max one · secondary · ghost. */\n variant?: 'primary' | 'secondary' | 'ghost';\n}\n\n/** Link (or press action) with the Button look – the actions of the website header. */\nfunction ActionLink({ action, size }: { action: NavAction; size: 'sm' | 'md' | 'lg' }) {\n return (\n <AriaLink href={action.href} onPress={action.onPress} className={cx('medo-button', `medo-button--${action.variant ?? 'ghost'}`, `medo-button--${size}`)}>\n <span className=\"medo-button__label\">{action.label}</span>\n </AriaLink>\n );\n}\n\n/* ---------- Website header ---------- */\n\nexport interface SiteHeaderProps {\n /** Logo link with a name („med.o home“). */\n logo: ReactNode;\n /** NavItems and NavGroups – max 5 links; more go into a group. */\n children: ReactNode;\n /** Max 2 actions, at most one primary (last). In the mobile menu they are pinned at the bottom (lg). */\n actions?: NavAction[];\n /** Name of the navigation region. */\n 'aria-label'?: string;\n /** Mobile: label of the menu button and title of the fullscreen menu. */\n menuLabel?: string;\n closeLabel?: string;\n /** auto: menu button below 768 px · desktop · mobile (forced, e.g. for previews). */\n layout?: 'auto' | 'desktop' | 'mobile';\n}\n\n/**\n * Website header: logo, links, actions. Sticky, with a divider once the page scrolls.\n * Below 768 px only the logo, the primary action and a menu button remain; the menu opens fullscreen.\n */\nexport function SiteHeader({ logo, children, actions = [], 'aria-label': label = 'Main', menuLabel = 'Menu', closeLabel = 'Close', layout = 'auto' }: SiteHeaderProps) {\n const narrow = useMediaQuery(SITE_MENU_QUERY);\n const compact = layout === 'mobile' || (layout === 'auto' && narrow);\n const scrolled = useScrolled();\n const primary = actions.find((a) => a.variant === 'primary');\n return (\n <header className={cx('medo-site-header', compact && 'medo-site-header--compact')} data-scrolled={scrolled || undefined}>\n <div className=\"medo-site-header__logo\">{logo}</div>\n {compact ? (\n <div className=\"medo-site-header__actions\">\n {primary && <ActionLink action={primary} size=\"sm\" />}\n <NavFullscreen logo={logo} actions={actions} aria-label={label} menuLabel={menuLabel} closeLabel={closeLabel}>\n {children}\n </NavFullscreen>\n </div>\n ) : (\n <>\n <nav aria-label={label} className=\"medo-site-header__nav\">\n <NavVariantContext.Provider value=\"header\">\n <ul className=\"medo-nav__list medo-nav__list--row\">{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n {actions.length > 0 && (\n <div className=\"medo-site-header__actions\">\n {actions.map((a) => (\n <ActionLink key={a.label} action={a} size=\"md\" />\n ))}\n </div>\n )}\n </>\n )}\n </header>\n );\n}\n\n/** Fullscreen menu of the website on mobile: large links, groups inline, actions at the bottom. */\nfunction NavFullscreen({\n logo,\n actions,\n children,\n 'aria-label': label,\n menuLabel,\n closeLabel,\n}: Required<Pick<SiteHeaderProps, 'logo' | 'actions' | 'children' | 'aria-label' | 'menuLabel' | 'closeLabel'>>) {\n // Primary first when stacked – in thumb reach.\n const ordered = [...actions].sort((a, b) => Number(b.variant === 'primary') - Number(a.variant === 'primary'));\n return (\n <DialogTrigger>\n <IconButton variant=\"ghost\" size=\"md\" icon={<MenuIcon />} aria-label={menuLabel} tooltip={false} />\n <ModalOverlay className=\"medo-nav-fullscreen-overlay\">\n <Modal className=\"medo-nav-fullscreen\">\n <AriaDialog aria-label={menuLabel} className=\"medo-nav-fullscreen__dialog\">\n {({ close }) => (\n <>\n <div className=\"medo-nav-fullscreen__header\">\n <div className=\"medo-site-header__logo\">{logo}</div>\n <IconButton variant=\"ghost\" size=\"md\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />\n </div>\n <nav aria-label={label} className=\"medo-nav-fullscreen__nav\">\n <NavVariantContext.Provider value=\"sheet\">\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n {ordered.length > 0 && (\n <div className=\"medo-nav-fullscreen__actions\">\n {ordered.map((a) => (\n <ActionLink key={a.label} action={a.variant === 'ghost' || !a.variant ? { ...a, variant: 'secondary' } : a} size=\"lg\" />\n ))}\n </div>\n )}\n </>\n )}\n </AriaDialog>\n </Modal>\n </ModalOverlay>\n </DialogTrigger>\n );\n}\n\n/* ---------- App header ---------- */\n\nexport interface AppHeaderProps {\n /** Page title – the same name as the current nav item. */\n title: ReactNode;\n /** Heading level of the title (default 1: the page title). */\n headingLevel?: 1 | 2 | 3;\n /** Mobile only: logo mark before the title (the side navigation is hidden there). */\n logo?: ReactNode;\n /** Search field (desktop). */\n search?: ReactNode;\n /** Notifications, account … */\n actions?: ReactNode;\n}\n\n/** App header: page title, search and actions. Navigation lives in the side navigation. */\nexport function AppHeader({ title, headingLevel = 1, logo, search, actions }: AppHeaderProps) {\n const scrolled = useScrolled();\n return (\n <header className=\"medo-app-header\" data-scrolled={scrolled || undefined}>\n {logo && <div className=\"medo-app-header__logo\">{logo}</div>}\n <Heading level={headingLevel} className=\"medo-app-header__title\">\n {title}\n </Heading>\n {search && <div className=\"medo-app-header__search\">{search}</div>}\n {actions && <div className=\"medo-app-header__actions\">{actions}</div>}\n </header>\n );\n}\n\n/* ---------- Side navigation ---------- */\n\nexport interface SideNavUser {\n name: string;\n email?: string;\n src?: string;\n}\n\nexport interface SideNavProps {\n /** Full logo (expanded). */\n logo: ReactNode;\n /** Logo mark (collapsed, 32 px). */\n logoMark: ReactNode;\n /** NavItems, NavSections and NavGroups. Most used first. */\n children: ReactNode;\n /** Signed-in user at the bottom. */\n user?: SideNavUser;\n /** Collapsed to the 64 px rail (controlled). Remember it per user via onCollapsedChange. */\n isCollapsed?: boolean;\n defaultCollapsed?: boolean;\n onCollapsedChange?: (collapsed: boolean) => void;\n /** Name of the navigation region. */\n 'aria-label'?: string;\n collapseLabel?: string;\n expandLabel?: string;\n /** Close button of the tablet drawer. */\n closeLabel?: string;\n}\n\n/**\n * Side navigation for apps: 256 px with icons, counts, sections and groups;\n * collapses to a 64 px rail with tooltips. 640–1023 px: always a rail; expanding opens the full navigation\n * as a Drawer on the left. Below 640 px it is hidden – use the BottomTabBar there.\n */\nexport function SideNav({\n logo,\n logoMark,\n children,\n user,\n isCollapsed,\n defaultCollapsed = false,\n onCollapsedChange,\n 'aria-label': label = 'App',\n collapseLabel = 'Collapse navigation',\n expandLabel = 'Expand navigation',\n closeLabel = 'Close',\n}: SideNavProps) {\n const [ownCollapsed, setOwnCollapsed] = useState(defaultCollapsed);\n const tablet = useMediaQuery(TABLET_QUERY);\n const [drawer, setDrawer] = useState(false);\n const [openGroup, setOpenGroup] = useState<string>();\n const collapsed = tablet || (isCollapsed ?? ownCollapsed);\n\n const expand = (group?: string) => {\n setOpenGroup(group);\n if (tablet) return setDrawer(true);\n if (isCollapsed === undefined) setOwnCollapsed(false);\n onCollapsedChange?.(false);\n };\n const collapse = () => {\n if (isCollapsed === undefined) setOwnCollapsed(true);\n onCollapsedChange?.(true);\n };\n useEffect(() => {\n if (!tablet) setDrawer(false);\n }, [tablet]);\n\n const toggle = (\n <IconButton\n variant=\"ghost\"\n size=\"sm\"\n icon={<PanelLeft />}\n aria-label={collapsed ? expandLabel : collapseLabel}\n aria-expanded={tablet ? drawer : !collapsed}\n onPress={() => (collapsed ? expand() : collapse())}\n />\n );\n\n return (\n <aside className={cx('medo-sidenav', collapsed && 'medo-sidenav--collapsed')}>\n <div className=\"medo-sidenav__panel\">\n <div className=\"medo-sidenav__top\">\n <div className=\"medo-sidenav__logo\">{collapsed ? logoMark : logo}</div>\n {!collapsed && toggle}\n </div>\n <nav aria-label={label} className=\"medo-sidenav__nav\">\n <SideNavContext.Provider value={{ expand, openGroup }}>\n <NavVariantContext.Provider value={collapsed ? 'rail' : 'sidebar'}>\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </SideNavContext.Provider>\n </nav>\n <div className=\"medo-sidenav__bottom\">\n {collapsed && toggle}\n {user && (\n <div className=\"medo-sidenav__user\">\n <Avatar name={user.name} src={user.src} size=\"md\" decorative={!collapsed} />\n {!collapsed && (\n <span className=\"medo-sidenav__user-text\">\n <span className=\"medo-sidenav__user-name\">{user.name}</span>\n {user.email && <span className=\"medo-sidenav__user-email\">{user.email}</span>}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n {tablet && (\n // Tablet: the full navigation as a Drawer on the left. Choosing a page closes it.\n <Drawer side=\"left\" size=\"sm\" title={logo} aria-label={label} closeLabel={closeLabel} isOpen={drawer} onOpenChange={setDrawer}>\n <nav aria-label={label}>\n <SideNavContext.Provider value={{ expand, openGroup, onNavigate: () => setDrawer(false) }}>\n <NavVariantContext.Provider value=\"sidebar\">\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </SideNavContext.Provider>\n </nav>\n </Drawer>\n )}\n </aside>\n );\n}\n\n/* ---------- Bottom tab bar (apps, mobile) ---------- */\n\nexport interface BottomTabBarProps {\n /** 3–5 TabBarItems; the last can be TabBarMore. */\n children: ReactNode;\n 'aria-label'?: string;\n /** mobile: only below 640 px (default) · always (e.g. in a native-like web app). */\n display?: 'mobile' | 'always';\n}\n\n/**\n * Bottom tab bar: the main destinations of an app on phones, in thumb reach.\n * Max 4 destinations + „More“. Fixed to the bottom with the safe area; set `--medo-toast-offset` so toasts stay above it.\n */\nexport function BottomTabBar({ children, 'aria-label': label = 'App', display = 'mobile' }: BottomTabBarProps) {\n return (\n <nav aria-label={label} className={cx('medo-tab-bar', display === 'always' && 'medo-tab-bar--always')}>\n <ul className=\"medo-tab-bar__list\">{children}</ul>\n </nav>\n );\n}\n\nexport interface TabBarItemProps extends Omit<AriaLinkProps, 'children' | 'className' | 'style'> {\n /** Always visible – icons alone are ambiguous. */\n children: string;\n icon: ReactNode;\n isCurrent?: boolean;\n /** Something new (dot). Name it for screen readers with dotLabel. */\n dot?: boolean;\n dotLabel?: string;\n}\n\n/** One destination of the bottom tab bar: icon in a pill indicator, label below. */\nexport function TabBarItem({ children, icon, isCurrent, dot, dotLabel = 'new', ...props }: TabBarItemProps) {\n return (\n <li className=\"medo-tab-bar__entry\">\n <AriaLink {...props} aria-current={isCurrent ? 'page' : undefined} className=\"medo-tab-bar-item\">\n <TabBarIcon icon={icon} dot={dot} dotLabel={dotLabel} />\n <span className=\"medo-tab-bar-item__label\">{children}</span>\n </AriaLink>\n </li>\n );\n}\n\nfunction TabBarIcon({ icon, dot, dotLabel }: { icon: ReactNode; dot?: boolean; dotLabel?: string }) {\n return (\n <span className=\"medo-tab-bar-item__indicator\">\n <span className=\"medo-tab-bar-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n {dot && <BadgeDot tone=\"danger\" label={dotLabel} className=\"medo-tab-bar-item__dot\" />}\n </span>\n );\n}\n\nexport interface TabBarMoreProps {\n /** Label of the button and title of the sheet. */\n label?: string;\n /** NavItems for the remaining destinations (rendered large in the Nav sheet). */\n children: ReactNode;\n closeLabel?: string;\n}\n\n/** „More“: opens the remaining destinations in the Nav sheet (Bottom Sheet). Shows „current“ when one of them is. */\nexport function TabBarMore({ label = 'More', children, closeLabel }: TabBarMoreProps) {\n const hasCurrent = containsCurrent(children);\n return (\n <li className=\"medo-tab-bar__entry\">\n <DialogTrigger>\n <AriaButton className=\"medo-tab-bar-item\" aria-haspopup=\"dialog\" data-current={hasCurrent || undefined}>\n <TabBarIcon icon={<Ellipsis />} />\n <span className=\"medo-tab-bar-item__label\">{label}</span>\n </AriaButton>\n <BottomSheet title={label} closeLabel={closeLabel}>\n <nav aria-label={label} className=\"medo-nav-sheet\">\n <NavVariantContext.Provider value=\"sheet\">\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n </BottomSheet>\n </DialogTrigger>\n </li>\n );\n}\n\n/* ---------- Helpers ---------- */\n\n/** True once the page is scrolled: headers show their divider. */\nfunction useScrolled() {\n const [scrolled, setScrolled] = useState(false);\n useEffect(() => {\n const update = () => setScrolled(window.scrollY > 0);\n update();\n window.addEventListener('scroll', update, { passive: true });\n return () => window.removeEventListener('scroll', update);\n }, []);\n return scrolled;\n}\n","import { useEffect, useRef, type ReactNode } from 'react';\nimport { Dialog as AriaDialog, Heading, Modal, ModalOverlay } from 'react-aria-components';\nimport { X } from 'lucide-react';\nimport { useDirtyGuard, type DirtyGuardProps } from '../dialog/Dialog';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport './drawer.css';\n\nexport interface DrawerProps extends DirtyGuardProps {\n /** Says what it is („Account“, „Filter“, „Invoice #1042“). Can be a logo for a navigation drawer – then set aria-label. */\n title: ReactNode;\n /** Name of the drawer when the title is not text (e.g. a logo). */\n 'aria-label'?: string;\n /** Content; scrolls between header and footer. A function gets `close`: closes without asking – call it after saving. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /**\n * Only for decisions (Apply, Save) – usually a ButtonGroup. Links and switches act immediately.\n * A function gets `close` (after applying or saving, never asks) and `cancel` (asks „Discard changes?“ when isDirty).\n */\n footer?: ReactNode | ((close: () => void, cancel: () => void) => ReactNode);\n /** right: account, filters, details (default) · left: navigation only. */\n side?: 'left' | 'right';\n /** sm 320 (links) · md 400 (filters) · lg 560 (details, forms). */\n size?: 'sm' | 'md' | 'lg';\n /** Accessible name of the close button. */\n closeLabel?: string;\n className?: string;\n}\n\n/**\n * Drawer – a modal panel that slides in from the side. Same building blocks and behaviour\n * as the Dialog (React Aria ModalOverlay + Modal + Dialog): scrim, focus trap, no page scroll, Esc and the close\n * button close it, focus returns to the trigger; `isDirty` asks „Discard changes?“. Below 640 px it keeps its side,\n * viewport − 56 px wide; a swipe towards the edge closes it. Use inside a DialogTrigger or with isOpen.\n */\nexport function Drawer({\n title,\n 'aria-label': ariaLabel,\n children,\n footer,\n side = 'right',\n size = 'sm',\n closeLabel = 'Close',\n isDirty = false,\n discardText,\n className,\n ...openProps\n}: DrawerProps) {\n const { open, onOpenChange, confirmDiscard, forceClose } = useDirtyGuard({ isDirty, discardText, ...openProps });\n return (\n <ModalOverlay isOpen={open} onOpenChange={onOpenChange} isDismissable={!isDirty} className={cx('medo-drawer-overlay', `medo-drawer-overlay--${side}`)}>\n <Modal className={cx('medo-drawer', `medo-drawer--${side}`, `medo-drawer--${size}`, className)}>\n <DrawerDialog aria-label={ariaLabel} side={side}>\n {(close) => (\n <>\n <div className=\"medo-drawer__header\">\n {ariaLabel ? (\n <div className=\"medo-drawer__title\">{title}</div>\n ) : (\n <Heading slot=\"title\" className=\"medo-drawer__title\">\n {title}\n </Heading>\n )}\n <IconButton variant=\"ghost\" size=\"md\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />\n </div>\n <div className=\"medo-drawer__body\">{typeof children === 'function' ? children(forceClose) : children}</div>\n {footer && <div className=\"medo-drawer__footer\">{typeof footer === 'function' ? footer(forceClose, close) : footer}</div>}\n {confirmDiscard}\n </>\n )}\n </DrawerDialog>\n </Modal>\n </ModalOverlay>\n );\n}\n\n/**\n * The dialog section with swipe to close. Focus starts on the drawer itself (React Aria default):\n * screen readers announce the title, Tab then reaches the close button and the content in order –\n * drawers mostly hold links and settings, not a form to type into right away.\n */\nfunction DrawerDialog({ children, side, ...props }: { 'aria-label'?: string; side: 'left' | 'right'; children: (close: () => void) => ReactNode }) {\n const ref = useRef<HTMLElement>(null);\n return (\n <AriaDialog {...props} ref={ref} className=\"medo-drawer__dialog\">\n {({ close }) => (\n <>\n <SwipeToClose target={ref} side={side} onClose={close} />\n {children(close)}\n </>\n )}\n </AriaDialog>\n );\n}\n\n/** Share of the width (or a fast flick) that closes the drawer when swiped towards its edge. */\nconst CLOSE_DISTANCE = 0.25;\nconst CLOSE_VELOCITY = 0.5; // px per ms\nconst START = 10; // px before a horizontal drag starts – vertical scrolling stays native\n\n/**\n * Touch and pen: drag the drawer towards its edge to close it.\n * An addition only – Esc, the close button and the scrim always work (WCAG 2.5.7).\n */\nfunction SwipeToClose({ target, side, onClose }: { target: React.RefObject<HTMLElement | null>; side: 'left' | 'right'; onClose: () => void }) {\n useEffect(() => {\n const el = target.current;\n const drawer = el?.parentElement;\n if (!el || !drawer) return;\n const dir = side === 'right' ? 1 : -1;\n let start: { x: number; y: number; t: number; id: number } | null = null;\n let dragging = false;\n\n const down = (e: PointerEvent) => {\n if (e.pointerType === 'mouse') return;\n start = { x: e.clientX, y: e.clientY, t: e.timeStamp, id: e.pointerId };\n dragging = false;\n };\n const move = (e: PointerEvent) => {\n if (!start || e.pointerId !== start.id) return;\n const dx = (e.clientX - start.x) * dir;\n const dy = e.clientY - start.y;\n if (!dragging) {\n if (Math.abs(dx) < START || Math.abs(dx) < Math.abs(dy)) return;\n if (dx < 0) return void (start = null); // towards the content: not a close gesture\n dragging = true;\n el.setPointerCapture(e.pointerId);\n drawer.setAttribute('data-dragging', '');\n }\n drawer.style.transform = `translateX(${Math.max(0, dx) * dir}px)`;\n };\n const up = (e: PointerEvent) => {\n if (!start || e.pointerId !== start.id) return;\n const dx = Math.max(0, (e.clientX - start.x) * dir);\n const velocity = dx / Math.max(1, e.timeStamp - start.t);\n const wasDragging = dragging;\n start = null;\n dragging = false;\n if (!wasDragging) return;\n drawer.removeAttribute('data-dragging');\n drawer.style.transform = '';\n if (dx > drawer.offsetWidth * CLOSE_DISTANCE || (velocity > CLOSE_VELOCITY && dx > 24)) onClose();\n };\n el.addEventListener('pointerdown', down);\n el.addEventListener('pointermove', move);\n el.addEventListener('pointerup', up);\n el.addEventListener('pointercancel', up);\n return () => {\n el.removeEventListener('pointerdown', down);\n el.removeEventListener('pointermove', move);\n el.removeEventListener('pointerup', up);\n el.removeEventListener('pointercancel', up);\n };\n }, [target, side, onClose]);\n return null;\n}\n","import { createContext, useContext, type HTMLAttributes, type ReactNode } from 'react';\nimport { Check, X } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport './list.css';\n\nexport type ListType = 'bullet' | 'number' | 'check';\n\nconst ListTypeContext = createContext<ListType>('bullet');\n\nexport interface ListProps extends Omit<HTMLAttributes<HTMLUListElement | HTMLOListElement>, 'children'> {\n /** bullet: unordered points (ul) · number: order matters (ol) · check: features, included first (ul). */\n type?: ListType;\n /** Without it the list takes the size of the surrounding text. sm body/sm · md body/md · lg body/lg. */\n size?: 'sm' | 'md' | 'lg';\n /** Number list: first number (e.g. a list that continues after a paragraph). */\n start?: number;\n /** 2–7 ListItems. A nested List inside an item is level 2 (max 2 levels). */\n children: ReactNode;\n}\n\n/**\n * List – a real list in running text: bullets, numbers or a feature list.\n * Plain markup, no library needed. Markers are neutral (text/secondary) in their own column; long items\n * wrap flush with their first line. Level 2 (a List inside a ListItem) switches the marker: ring, „a.“.\n */\nexport function List({ type = 'bullet', size, start, className, style, children, ...props }: ListProps) {\n const Tag = type === 'number' ? 'ol' : 'ul';\n // The markers are CSS counters: start them where the native `start` attribute says.\n const counter = type === 'number' && start !== undefined ? { counterReset: `medo-list ${start - 1}` } : undefined;\n return (\n <ListTypeContext.Provider value={type}>\n <Tag\n {...props}\n start={type === 'number' ? start : undefined}\n style={{ ...counter, ...style }}\n // The markers are drawn in CSS (list-style: none) – Safari/VoiceOver then drops the list semantics, so set the role.\n role=\"list\"\n className={cx('medo-list', `medo-list--${type}`, size && `medo-list--${size}`, className)}\n >\n {children}\n </Tag>\n </ListTypeContext.Provider>\n );\n}\n\nexport interface ListItemProps extends Omit<HTMLAttributes<HTMLLIElement>, 'children'> {\n children: ReactNode;\n /** Feature list: not included – cross, muted text and a hidden „Not included:“ for screen readers. */\n excluded?: boolean;\n /** Hidden prefix of excluded items. */\n excludedLabel?: string;\n}\n\n/** One item of a List. */\nexport function ListItem({ children, excluded, excludedLabel = 'Not included:', className, ...props }: ListItemProps) {\n const type = useContext(ListTypeContext);\n const check = type === 'check';\n return (\n <li {...props} className={cx('medo-list__item', check && excluded && 'medo-list__item--excluded', className)}>\n {check && (\n <span className=\"medo-list__icon\" aria-hidden=\"true\">\n {excluded ? <X /> : <Check />}\n </span>\n )}\n {check && excluded && <span className=\"medo-visually-hidden\">{excludedLabel} </span>}\n {children}\n </li>\n );\n}\n\nexport interface DescriptionListProps extends HTMLAttributes<HTMLDListElement> {\n /** auto: stacked as soon as the list itself is narrower than 22.5 rem (360 px) (phone, Drawer, narrow column) · horizontal · stacked. */\n layout?: 'auto' | 'horizontal' | 'stacked';\n /** DescriptionItems. */\n children: ReactNode;\n}\n\n/** Description list – term–value pairs for details of a record, an order or a profile. */\nexport function DescriptionList({ layout = 'auto', className, children, ...props }: DescriptionListProps) {\n return (\n <dl {...props} className={cx('medo-dl', `medo-dl--${layout}`, className)}>\n {children}\n </dl>\n );\n}\n\nexport interface DescriptionItemProps {\n /** The term („Status“). */\n term: ReactNode;\n /** The value („Active“). */\n children: ReactNode;\n}\n\n/** One term–value pair (a div grouping dt and dd – valid inside dl). */\nexport function DescriptionItem({ term, children }: DescriptionItemProps) {\n return (\n <div className=\"medo-dl__row\">\n <dt className=\"medo-dl__term\">{term}</dt>\n <dd className=\"medo-dl__value\">{children}</dd>\n </div>\n );\n}\n","import { useEffect, useRef, useState, type PointerEvent as ReactPointerEvent, type ReactNode } from 'react';\nimport { GridList, GridListItem, useLocale, type GridListItemProps, type GridListProps } from 'react-aria-components';\nimport { ChevronRight } from 'lucide-react';\nimport { AvatarSizeContext } from '../avatar/Avatar';\nimport { Checkbox } from '../checkbox/Checkbox';\nimport { Skeleton } from '../progress/Progress';\nimport { cx } from '../utils/cx';\nimport './list-view.css';\n\nexport interface ListViewProps<T> extends Omit<GridListProps<T>, 'className' | 'style' | 'layout' | 'keyboardNavigationBehavior'> {\n /** Required: names the list („Inbox“). */\n 'aria-label'?: string;\n /** plain: full-page lists (inbox) · card: inside settings or dashboards (border, radius/lg) · cards: records on mobile (Table cards, use ListCard). */\n variant?: 'plain' | 'card' | 'cards';\n /** Shows 3 skeleton rows instead of the items (aria-busy). */\n isLoading?: boolean;\n /** Shown when there are no rows: an EmptyState with `size=\"inline\"`. */\n emptyState?: ReactNode;\n className?: string;\n}\n\n/**\n * List view – an interactive list of objects in apps: inbox, people, files, notifications, settings\n *. Built on React Aria GridList: ↑ ↓ move between rows, Enter opens a row, Tab reaches\n * the controls inside a row (menu, switch, buttons). `selectionMode=\"multiple\"` shows a checkbox per row and a click\n * toggles the row – use it without `onAction` (React Aria would run the action on click instead).\n * Rows can have swipe actions on touch (`swipeActions`) – the same actions always sit in the row's „…“ menu.\n */\nexport function ListView<T extends object>({ variant = 'plain', isLoading = false, emptyState, className, children, items, ...props }: ListViewProps<T>) {\n if (isLoading) {\n return (\n <div role=\"list\" aria-busy=\"true\" aria-label={props['aria-label']} className={cx('medo-list-view', `medo-list-view--${variant}`, className)}>\n {Array.from({ length: 3 }, (_, i) =>\n variant === 'cards' ? (\n <div key={i} role=\"listitem\" className=\"medo-list-card medo-list-card--loading\">\n <span className=\"medo-list-card__content\">\n <Skeleton width=\"50%\" />\n <Skeleton width=\"35%\" />\n <Skeleton width=\"70%\" />\n </span>\n </div>\n ) : (\n <div key={i} role=\"listitem\" className=\"medo-list-row medo-list-row--loading\">\n <span className=\"medo-list-row__leading\">\n <Skeleton shape=\"circle\" width={40} height={40} />\n </span>\n <span className=\"medo-list-row__main\">\n <span className=\"medo-list-row__content\">\n <Skeleton width=\"40%\" />\n <Skeleton width=\"70%\" />\n </span>\n </span>\n </div>\n ),\n )}\n </div>\n );\n }\n return (\n <GridList<T>\n {...props}\n items={items}\n // Tab reaches the controls inside a row.\n keyboardNavigationBehavior=\"tab\"\n renderEmptyState={emptyState ? () => <div className=\"medo-list-view__empty\">{emptyState}</div> : undefined}\n className={cx('medo-list-view', `medo-list-view--${variant}`, className)}\n >\n {children}\n </GridList>\n );\n}\n\nexport interface ListRowProps extends Omit<GridListItemProps, 'children' | 'className' | 'style' | 'textValue'> {\n /** Required. One line, most important word first. Also the row's accessible name. */\n title: string;\n /** One line (2-line row) or two lines (`lines={3}`). */\n description?: ReactNode;\n /** 3: description up to two lines (row 88). Default: 1 without, 2 with a description. */\n lines?: 2 | 3;\n /** Avatar (sized automatically: sm in 1-line rows, lg otherwise), an icon tile (ListRowIcon) or a 40 px thumbnail. */\n leading?: ReactNode;\n /** Meta text (time, size) in caption. */\n meta?: ReactNode;\n /** One trailing type per list: Badge, Menu („…“), Switch or max 2 Button sm. With buttons the row has no action. */\n trailing?: ReactNode;\n /** The row navigates (href) – shows a chevron. */\n chevron?: boolean;\n /** New or unread: title and excerpt strong, meta in brand, dot below the meta, „Unread“ for screen readers. */\n unread?: boolean;\n /** Screen-reader word for unread rows. */\n unreadLabel?: string;\n /**\n * Touch only: end = swipe toward the start (left in LTR, e.g. Delete) · start = swipe toward the end (a safe action,\n * e.g. Archive). Always put the same actions into the row's „…“ menu – swipe is a shortcut, never the only way.\n */\n swipeActions?: { start?: SwipeAction; end?: SwipeAction };\n}\n\nexport interface SwipeAction {\n /** Short verb („Delete“, „Archive“). */\n label: string;\n icon: ReactNode;\n /** Runs on a full swipe or a tap on the revealed action. Delete: remove at once and offer „Undo“ in a Toast. */\n onAction: () => void;\n /** danger: feedback/danger/solid (Delete) · primary: action/primary (Archive). */\n tone?: 'danger' | 'primary';\n}\n\n/** One row of a List view: leading – content – trailing. Height 48, 64 or 88 by lines. */\nexport function ListRow({ title, description, lines, leading, meta, trailing, chevron, unread, unreadLabel = 'Unread', swipeActions, ...props }: ListRowProps) {\n const rowLines = description ? (lines ?? 2) : 1;\n const swipe = swipeActions?.start || swipeActions?.end;\n return (\n <GridListItem\n {...props}\n textValue={title}\n className={cx('medo-list-row', `medo-list-row--lines-${rowLines}`, unread && 'medo-list-row--unread', swipe && 'medo-list-row--swipe')}\n >\n {({ selectionMode }) => {\n const content = (\n <>\n {selectionMode !== 'none' && (\n <span className=\"medo-list-row__check\">\n <Checkbox slot=\"selection\" />\n </span>\n )}\n {leading && (\n // Avatars size themselves: sm in 1-line rows, lg in 2–3 lines.\n <AvatarSizeContext.Provider value={rowLines === 1 ? 'sm' : 'lg'}>\n <span className=\"medo-list-row__leading\">{leading}</span>\n </AvatarSizeContext.Provider>\n )}\n <span className=\"medo-list-row__main\">\n <span className=\"medo-list-row__content\">\n <span className=\"medo-list-row__title\">\n {unread && <span className=\"medo-visually-hidden\">{unreadLabel}: </span>}\n {title}\n </span>\n {description && <span className=\"medo-list-row__description\">{description}</span>}\n </span>\n {(meta || unread) && (\n <span className=\"medo-list-row__meta\">\n {meta && <span className=\"medo-list-row__meta-text\">{meta}</span>}\n {unread && <span className=\"medo-list-row__dot\" aria-hidden=\"true\" />}\n </span>\n )}\n {trailing && <span className=\"medo-list-row__trailing\">{trailing}</span>}\n {chevron && (\n <span className=\"medo-list-row__chevron\" aria-hidden=\"true\">\n <ChevronRight />\n </span>\n )}\n </span>\n </>\n );\n return swipe ? <Swipeable actions={swipeActions!}>{content}</Swipeable> : content;\n }}\n </GridListItem>\n );\n}\n\n/* ---------- Swipe ---------- */\n\nconst SWIPE = {\n action: 88, // revealed action width – snaps open from here\n lock: 8, // px before the direction is decided\n full: 0.5, // share of the row width that triggers at once\n flick: 0.5, // px per ms\n};\n\n/** Only one row is open at a time. */\nlet closeOpenRow: (() => void) | null = null;\n\nfunction Swipeable({ actions, children }: { actions: { start?: SwipeAction; end?: SwipeAction }; children: ReactNode }) {\n const { direction } = useLocale();\n const rtl = direction === 'rtl';\n const surface = useRef<HTMLSpanElement>(null);\n const drag = useRef<{ x: number; y: number; t: number; base: number; lock: 'x' | 'y' | null; id: number; buzzed: boolean } | null>(null);\n const [offset, setOffset] = useState(0); // logical: < 0 reveals the end action, > 0 the start action\n const [dragging, setDragging] = useState(false);\n const [leaving, setLeaving] = useState(false);\n const open = offset !== 0 && !dragging;\n\n const close = () => setOffset(0);\n\n // An open row closes on a tap elsewhere, on scroll and on Esc.\n useEffect(() => {\n if (!open) return;\n closeOpenRow?.();\n closeOpenRow = close;\n const row = surface.current?.closest('.medo-list-row');\n const onDown = (e: Event) => !row?.contains(e.target as Node) && close();\n const onKey = (e: KeyboardEvent) => e.key === 'Escape' && close();\n document.addEventListener('pointerdown', onDown, true);\n window.addEventListener('scroll', close, true);\n document.addEventListener('keydown', onKey);\n return () => {\n if (closeOpenRow === close) closeOpenRow = null;\n document.removeEventListener('pointerdown', onDown, true);\n window.removeEventListener('scroll', close, true);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const width = () => surface.current?.getBoundingClientRect().width ?? 0;\n const actionFor = (value: number) => (value < 0 ? actions.end : value > 0 ? actions.start : undefined);\n\n const trigger = (action: SwipeAction, side: number) => {\n // The row slides out (250 ms, accelerating), then the action runs – the app removes the row and shows „Undo“.\n setLeaving(true);\n setOffset(side * width());\n window.setTimeout(() => {\n action.onAction();\n setLeaving(false);\n setOffset(0);\n }, 250);\n };\n\n const onPointerDown = (e: ReactPointerEvent) => {\n if (e.pointerType === 'mouse') return; // touch and pen only – mouse and keyboard use the „…“ menu\n drag.current = { x: e.clientX, y: e.clientY, t: e.timeStamp, base: offset, lock: null, id: e.pointerId, buzzed: false };\n };\n\n const onPointerMove = (e: ReactPointerEvent) => {\n const d = drag.current;\n if (!d || e.pointerId !== d.id) return;\n const dx = (e.clientX - d.x) * (rtl ? -1 : 1);\n const dy = e.clientY - d.y;\n if (!d.lock) {\n if (Math.abs(dy) > SWIPE.lock && Math.abs(dy) > Math.abs(dx)) d.lock = 'y';\n else if (Math.abs(dx) > SWIPE.lock) {\n d.lock = 'x';\n setDragging(true);\n surface.current?.setPointerCapture(e.pointerId);\n // A swipe is not a press: cancel the row's press so it does not open.\n e.currentTarget.dispatchEvent(new PointerEvent('pointercancel', { bubbles: true, pointerId: e.pointerId, pointerType: e.pointerType }));\n }\n }\n if (d.lock !== 'x') return;\n let next = d.base + dx;\n // No action on that side: resist (rubber band) instead of revealing an empty area.\n if (!actionFor(next)) next = next / 4;\n // A short haptic tick when the full-swipe threshold is crossed (where supported).\n const past = Math.abs(next) >= width() * SWIPE.full && !!actionFor(next);\n if (past && !d.buzzed) navigator.vibrate?.(10);\n d.buzzed = past;\n setOffset(next);\n };\n\n const onPointerEnd = (e: ReactPointerEvent) => {\n const d = drag.current;\n drag.current = null;\n if (!d || d.lock !== 'x') return;\n setDragging(false);\n const action = actionFor(offset);\n const velocity = ((e.clientX - d.x) * (rtl ? -1 : 1)) / Math.max(1, e.timeStamp - d.t);\n const side = Math.sign(offset);\n if (!action) return close();\n if (Math.abs(offset) >= width() * SWIPE.full || (Math.abs(velocity) > SWIPE.flick && Math.sign(velocity) === side && Math.abs(offset) > SWIPE.action / 2))\n return trigger(action, side);\n setOffset(Math.abs(offset) >= SWIPE.action ? side * SWIPE.action : 0);\n };\n\n const revealed = actionFor(offset);\n return (\n <>\n {revealed && (\n // Visual shortcut for touch; keyboard and screen readers use the „…“ menu, so it is hidden from them.\n <span\n className={cx(\n 'medo-list-row__swipe-action',\n `medo-list-row__swipe-action--${offset < 0 ? 'end' : 'start'}`,\n `medo-list-row__swipe-action--${revealed.tone ?? 'primary'}`,\n )}\n style={{ inlineSize: Math.abs(offset) }}\n aria-hidden=\"true\"\n onPointerDown={(e) => e.stopPropagation()}\n onClick={(e) => {\n e.stopPropagation();\n trigger(revealed, Math.sign(offset));\n }}\n >\n <span className=\"medo-list-row__swipe-label\">\n {revealed.icon}\n {revealed.label}\n </span>\n </span>\n )}\n <span\n ref={surface}\n className={cx('medo-list-row__surface', dragging && 'medo-list-row__surface--dragging', leaving && 'medo-list-row__surface--leaving')}\n style={{ transform: offset ? `translateX(${rtl ? -offset : offset}px)` : undefined }}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerEnd}\n onPointerCancel={(e) => {\n // Our own cancel (to stop the press) must not end the swipe.\n if (!e.isTrusted) return;\n onPointerEnd(e);\n }}\n >\n {children}\n {/* While open, a tap on the row closes it instead of opening the row. */}\n {open && (\n <span\n className=\"medo-list-row__swipe-shield\"\n aria-hidden=\"true\"\n onPointerDown={(e) => {\n e.stopPropagation();\n close();\n }}\n />\n )}\n </span>\n </>\n );\n}\n\n/** Leading icon in a 40 px tile (settings rows). Decorative – the title carries the meaning. */\nexport function ListRowIcon({ children }: { children: ReactNode }) {\n return (\n <span className=\"medo-list-row__icon\" aria-hidden=\"true\">\n {children}\n </span>\n );\n}\n\nexport interface ListCardProps extends Omit<GridListItemProps, 'children' | 'className' | 'style' | 'textValue'> {\n /** Required. The record („INV-2026-0140“). Also the card's accessible name. */\n title: string;\n /** Key number on the right of the title (amount, count) – strong, never truncated. */\n amount?: ReactNode;\n /** Second line, e.g. the owner with an Avatar (sized xs automatically). */\n description?: ReactNode;\n /** Bottom left: date or other meta in caption. */\n meta?: ReactNode;\n /** Bottom right: status as Badge sm with dot. */\n status?: ReactNode;\n}\n\n/**\n * List card – a record as a card, the mobile form of a table row. Use inside\n * `<ListView variant=\"cards\">`: the whole card opens the record (`href` or `onAction`); in selection mode\n * a checkbox lg shows and a tap toggles the card.\n */\nexport function ListCard({ title, amount, description, meta, status, ...props }: ListCardProps) {\n return (\n <GridListItem {...props} textValue={title} className=\"medo-list-card\">\n {({ selectionMode }) => (\n <>\n {selectionMode !== 'none' && (\n <span className=\"medo-list-card__check\">\n <Checkbox slot=\"selection\" size=\"lg\" />\n </span>\n )}\n <span className=\"medo-list-card__content\">\n <span className=\"medo-list-card__top\">\n <span className=\"medo-list-card__title\">{title}</span>\n {amount && <span className=\"medo-list-card__amount\">{amount}</span>}\n </span>\n {description && (\n <AvatarSizeContext.Provider value=\"xs\">\n <span className=\"medo-list-card__description\">{description}</span>\n </AvatarSizeContext.Provider>\n )}\n {(meta || status) && (\n <span className=\"medo-list-card__bottom\">\n <span className=\"medo-list-card__meta\">{meta}</span>\n {status}\n </span>\n )}\n </span>\n </>\n )}\n </GridListItem>\n );\n}\n","import { useEffect, useRef, type KeyboardEvent, type ReactNode } from 'react';\nimport { Button as AriaButton, Toolbar } from 'react-aria-components';\nimport { Ellipsis, X } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { Menu, MenuButton, MenuItem, MenuTrigger } from '../menu/Menu';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport '../toast/toast.css';\nimport './bulk-action-bar.css';\n\nexport interface BulkAction {\n /** Verb („Export“, „Archive“, „Delete“). */\n label: string;\n onAction: () => void;\n /** danger: destructive – confirm it (Alert dialog) or offer Undo (Toast). Mobile: ghost danger. */\n variant?: 'default' | 'danger';\n /** Icon for the „…“ menu (actions after the third). */\n icon?: ReactNode;\n}\n\nexport interface BulkActionBarProps {\n /** Number of selected items. 0 hides the bar. */\n count: number;\n /** Max 3 are shown; more go into the „…“ menu. Destructive last. */\n actions: BulkAction[];\n /** Clears the selection (× and Esc). */\n onClear: () => void;\n /** auto: floating dark bar on desktop, full-width bar at the bottom below 640 px · desktop · mobile. */\n variant?: 'auto' | 'desktop' | 'mobile';\n /** Texts (localize). */\n countLabel?: (count: number) => string;\n clearLabel?: string;\n moreLabel?: string;\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * Bulk action bar – actions for the selected rows of a Table or List view.\n * Appears with ≥ 1 selected item and floats, so selecting never shifts the layout. A toolbar: the count is\n * announced, Esc or × clears the selection. Render it right after the list, so Tab reaches it next.\n */\nexport function BulkActionBar({\n count,\n actions,\n onClear,\n variant = 'auto',\n countLabel = (n) => `${n} selected`,\n clearLabel = 'Clear selection',\n moreLabel = 'More actions',\n 'aria-label': ariaLabel = 'Bulk actions',\n className,\n}: BulkActionBarProps) {\n const mobile = useMediaQuery(MOBILE_QUERY);\n const isMobile = variant === 'mobile' || (variant === 'auto' && mobile);\n const visible = count > 0;\n // Where focus came from (a row checkbox): it goes back there when the bar disappears under it.\n const returnTo = useRef<HTMLElement | null>(null);\n const focusInside = useRef(false);\n\n useEffect(() => {\n if (visible || !focusInside.current) return;\n focusInside.current = false;\n if (returnTo.current?.isConnected) returnTo.current.focus();\n }, [visible]);\n\n const shown = actions.slice(0, 3);\n const more = actions.slice(3);\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && !e.defaultPrevented) {\n e.preventDefault();\n onClear();\n }\n };\n\n const overflow =\n more.length > 0 &&\n (isMobile ? (\n <MenuTrigger>\n <MenuButton aria-label={moreLabel} size=\"lg\" />\n <OverflowMenu actions={more} />\n </MenuTrigger>\n ) : (\n <MenuTrigger>\n <AriaButton aria-label={moreLabel} className=\"medo-toast__button medo-toast__close\">\n <Ellipsis aria-hidden=\"true\" />\n </AriaButton>\n <OverflowMenu actions={more} />\n </MenuTrigger>\n ));\n\n return (\n <>\n {/* Always mounted, so the count is announced reliably (a new live region is often missed). */}\n <span role=\"status\" className=\"medo-visually-hidden\">\n {visible ? countLabel(count) : ''}\n </span>\n {visible && (\n // The wrapper handles Esc and remembers where focus came from (events bubble from the toolbar).\n <div\n className=\"medo-bulk-bar-host\"\n onKeyDown={onKeyDown}\n onFocus={(e) => {\n focusInside.current = true;\n const from = e.relatedTarget as HTMLElement | null;\n if (from && !e.currentTarget.contains(from)) returnTo.current = from;\n }}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) focusInside.current = false;\n }}\n >\n <Toolbar aria-label={ariaLabel} className={cx('medo-bulk-bar', isMobile ? 'medo-bulk-bar--mobile' : 'medo-bulk-bar--desktop', className)}>\n {isMobile ? (\n <>\n <span className=\"medo-bulk-bar__start\">\n <IconButton variant=\"ghost\" size=\"lg\" icon={<X />} aria-label={clearLabel} tooltip={false} onPress={onClear} />\n <span className=\"medo-bulk-bar__count\">{countLabel(count)}</span>\n </span>\n <span className=\"medo-bulk-bar__actions\">\n {shown.map((a) => (\n <Button key={a.label} variant={a.variant === 'danger' ? 'ghost-danger' : 'ghost'} size=\"lg\" onPress={a.onAction}>\n {a.label}\n </Button>\n ))}\n {overflow}\n </span>\n </>\n ) : (\n <>\n <span className=\"medo-bulk-bar__count\">{countLabel(count)}</span>\n <span className=\"medo-bulk-bar__divider\" aria-hidden=\"true\" />\n {shown.map((a) => (\n <AriaButton key={a.label} className=\"medo-toast__button medo-toast__action\" onPress={a.onAction}>\n {a.label}\n </AriaButton>\n ))}\n {overflow}\n <span className=\"medo-bulk-bar__divider\" aria-hidden=\"true\" />\n <AriaButton aria-label={clearLabel} className=\"medo-toast__button medo-toast__close\" onPress={onClear}>\n <X aria-hidden=\"true\" />\n </AriaButton>\n </>\n )}\n </Toolbar>\n </div>\n )}\n </>\n );\n}\n\nfunction OverflowMenu({ actions }: { actions: BulkAction[] }) {\n return (\n <Menu onAction={(key) => actions[Number(key)]?.onAction()}>\n {actions.map((a, i) => (\n <MenuItem key={i} id={i} icon={a.icon} variant={a.variant === 'danger' ? 'danger' : 'default'}>\n {a.label}\n </MenuItem>\n ))}\n </Menu>\n );\n}\n","import { useId, type ElementType, type HTMLAttributes, type ReactNode } from 'react';\nimport { CircleAlert, CircleCheck, Folder, Lock, Search } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { Link } from '../link/Link';\nimport { cx } from '../utils/cx';\nimport './empty-state.css';\n\nexport type EmptyStateType = 'first-use' | 'no-results' | 'error' | 'no-access' | 'all-done';\nexport type EmptyStateSize = 'page' | 'section' | 'inline';\n\nexport interface EmptyStateAction {\n /** Verb that says what happens („Create project“, „Clear filters“, „Try again“). */\n label: string;\n /** Runs the action. */\n onPress?: () => void;\n /** Second action only: navigates – rendered as a Link („Learn more“, „View archive“). */\n href?: string;\n isDisabled?: boolean;\n}\n\nexport interface EmptyStateProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {\n /** Sets the default icon, its tone and the look of the main action. */\n type?: EmptyStateType;\n /** page: a whole view · section: a card or panel · inline: inside a list or table (header stays). */\n size?: EmptyStateSize;\n /** Required. The situation in plain words – never „No data“. */\n title: ReactNode;\n /** Why it is empty or what comes next, in one or two sentences. */\n description?: ReactNode;\n /** Main action: primary for first use, secondary for all other types. „All done“ needs none. */\n action?: EmptyStateAction;\n /** Second action as a text button, or a Link with `href`. */\n secondaryAction?: EmptyStateAction;\n /** Replaces the type's default icon (Lucide). */\n icon?: ReactNode;\n /** Illustration instead of the icon – only from the shared illustration style. Decorative. */\n illustration?: ReactNode;\n /** Heading level of the title (page and section). Match the page outline. Default: page h2, section h3. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n}\n\nconst defaults: Record<EmptyStateType, { icon: ReactNode; tone: IconTileTone }> = {\n 'first-use': { icon: <Folder />, tone: 'neutral' },\n 'no-results': { icon: <Search />, tone: 'neutral' },\n error: { icon: <CircleAlert />, tone: 'danger' },\n 'no-access': { icon: <Lock />, tone: 'neutral' },\n 'all-done': { icon: <CircleCheck />, tone: 'success' },\n};\n\nconst tileSize = { page: 'lg', section: 'md', inline: 'sm' } as const;\n\n/**\n * Empty state – what users see when there is nothing to show, and what they can do next.\n * Page and section render a `<section>` named by its heading; inline renders a plain block, so it does not add\n * a landmark inside a list or table. „No results“ puts its text in a polite status region; focus stays where it was.\n */\nexport function EmptyState({\n type = 'first-use',\n size = 'page',\n title,\n description,\n action,\n secondaryAction,\n icon,\n illustration,\n headingLevel,\n className,\n ...props\n}: EmptyStateProps) {\n const titleId = useId();\n const { icon: defaultIcon, tone } = defaults[type];\n const isInline = size === 'inline';\n const Tag: ElementType = isInline ? 'div' : 'section';\n const Title: ElementType = isInline ? 'p' : `h${headingLevel ?? (size === 'page' ? 2 : 3)}`;\n const buttonSize = size === 'page' ? 'md' : 'sm';\n\n return (\n <Tag {...props} aria-labelledby={isInline ? undefined : titleId} className={cx('medo-empty-state', `medo-empty-state--${size}`, className)}>\n {illustration ? (\n <span className=\"medo-empty-state__illustration\" aria-hidden=\"true\">\n {illustration}\n </span>\n ) : (\n <IconTile size={tileSize[size]} tone={tone}>\n {icon ?? defaultIcon}\n </IconTile>\n )}\n {/* „No results“ after a search or filter is announced politely. */}\n <div className=\"medo-empty-state__content\" role={type === 'no-results' ? 'status' : undefined}>\n <Title id={titleId} className=\"medo-empty-state__title\">\n {title}\n </Title>\n {description && <p className=\"medo-empty-state__description\">{description}</p>}\n </div>\n {(action || secondaryAction) && (\n <div className=\"medo-empty-state__actions\">\n {action && (\n <Button variant={type === 'first-use' ? 'primary' : 'secondary'} size={buttonSize} onPress={action.onPress} isDisabled={action.isDisabled}>\n {action.label}\n </Button>\n )}\n {secondaryAction &&\n (secondaryAction.href ? (\n <Link variant=\"standalone\" href={secondaryAction.href} isDisabled={secondaryAction.isDisabled}>\n {secondaryAction.label}\n </Link>\n ) : (\n <Button variant=\"text\" size={buttonSize} onPress={secondaryAction.onPress} isDisabled={secondaryAction.isDisabled}>\n {secondaryAction.label}\n </Button>\n ))}\n </div>\n )}\n </Tag>\n );\n}\n\n/* ---------- Icon tile (internal – shared with Dropzone and Embed consent) ---------- */\n\n/** raised: surface/default – on surface/subtle (Embed consent). */\nexport type IconTileTone = 'neutral' | 'raised' | 'danger' | 'success';\n\n/** Round, decorative icon tile: sm 40 / icon 20 · md 48 / 24 · lg 64 / 32. Internal, not exported from the package. */\nexport function IconTile({ size = 'md', tone = 'neutral', children }: { size?: 'sm' | 'md' | 'lg'; tone?: IconTileTone; children: ReactNode }) {\n return (\n <span className={cx('medo-icon-tile', `medo-icon-tile--${size}`, `medo-icon-tile--${tone}`)} aria-hidden=\"true\">\n {children}\n </span>\n );\n}\n","import { useId, useRef, useState, type ReactNode } from 'react';\nimport { Button as AriaButton, Link as AriaLink } from 'react-aria-components';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Select } from '../select/Select';\nimport { Option } from '../listbox/ListBox';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport '../button/button.css';\nimport './pagination.css';\n\nexport interface PaginationProps {\n /** Current page (1-based, controlled). */\n page?: number;\n /** Start page when uncontrolled. */\n defaultPage?: number;\n /** Called with the new page (apps). Not needed with `getPageHref`. */\n onChange?: (page: number) => void;\n /** Websites: every page becomes a real link („?page=5“) – shareable, back button works. Works with RouterProvider. */\n getPageHref?: (page: number) => string;\n /** Number of pages. Default: totalItems / pageSize. With 1 page nothing is shown. */\n totalPages?: number;\n /** Total count: shows the summary („81–100 of 380“). */\n totalItems?: number;\n /** Rows per page. */\n pageSize?: number;\n /** Shows „Rows per page“ (Select sm). */\n onPageSizeChange?: (pageSize: number) => void;\n pageSizeOptions?: number[];\n /** auto: compact below 640 px · full: summary, rows per page and pages · compact: ‹ Page 5 of 19 › (narrow panels). */\n variant?: 'auto' | 'full' | 'compact';\n /** Full only: md 40 · lg 48 (touch). Compact is always lg. */\n size?: 'md' | 'lg';\n /** Name of the navigation region. */\n 'aria-label'?: string;\n /** Texts (localize). */\n summary?: (from: number, to: number, total: number) => string;\n pageSizeLabel?: string;\n previousLabel?: string;\n nextLabel?: string;\n /** Accessible name of a page item and the compact text. */\n pageLabel?: (page: number) => string;\n compactLabel?: (page: number, totalPages: number) => string;\n className?: string;\n}\n\n/** Page numbers with ellipsis: max 7 items, first and last always, the current page with one neighbour each side. */\nexport function getPageItems(page: number, totalPages: number): (number | 'ellipsis')[] {\n if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i + 1);\n // Near the start or the end five pages in a row, so an ellipsis never hides a single page.\n if (page <= 4) return [1, 2, 3, 4, 5, 'ellipsis', totalPages];\n if (page >= totalPages - 3) return [1, 'ellipsis', ...Array.from({ length: 5 }, (_, i) => totalPages - 4 + i)];\n return [1, 'ellipsis', page - 1, page, page + 1, 'ellipsis', totalPages];\n}\n\n/**\n * Pagination – move through long lists page by page. A navigation region:\n * buttons for apps (`onChange`) or real links for websites (`getPageHref`). Full on desktop, compact below 640 px.\n * After a change the app scrolls to the top of the list and focuses its heading. „Load more“ is a Button, not a variant.\n */\nexport function Pagination({\n page: pageProp,\n defaultPage = 1,\n onChange,\n getPageHref,\n totalPages: totalPagesProp,\n totalItems,\n pageSize = 20,\n onPageSizeChange,\n pageSizeOptions = [10, 20, 50, 100],\n variant = 'auto',\n size = 'md',\n 'aria-label': ariaLabel = 'Pagination',\n summary = (from, to, total) => `${from}–${to} of ${total}`,\n pageSizeLabel = 'Rows per page',\n previousLabel = 'Previous page',\n nextLabel = 'Next page',\n pageLabel = (p) => `Page ${p}`,\n compactLabel = (p, total) => `Page ${p} of ${total}`,\n className,\n}: PaginationProps) {\n const [innerPage, setInnerPage] = useState(defaultPage);\n const mobile = useMediaQuery(MOBILE_QUERY);\n const totalPages = totalPagesProp ?? (totalItems !== undefined ? Math.ceil(totalItems / pageSize) : 1);\n const page = Math.min(Math.max(pageProp ?? innerPage, 1), Math.max(totalPages, 1));\n const compact = variant === 'compact' || (variant === 'auto' && mobile);\n const itemSize = compact ? 'lg' : size;\n const statusId = useId();\n const navRef = useRef<HTMLElement>(null);\n\n // One page: nothing to navigate.\n if (totalPages <= 1) return null;\n\n const go = (p: number) => {\n if (pageProp === undefined) setInnerPage(p);\n onChange?.(p);\n // „Next“ on the second-last page becomes disabled and drops focus. If the app did not move focus\n // (to the list heading), keep it in the pagination: on the current page, or on the other arrow.\n requestAnimationFrame(() => {\n const nav = navRef.current;\n if (!nav || (document.activeElement && document.activeElement !== document.body)) return;\n (nav.querySelector<HTMLElement>('[aria-current=\"page\"]') ?? nav.querySelector<HTMLElement>('.medo-button:not([data-disabled])'))?.focus();\n });\n };\n\n /** A page item, previous or next: a link on websites, a button in apps. */\n const item = (target: number, props: { className: string; 'aria-label': string; 'aria-current'?: 'page'; isDisabled?: boolean; children: ReactNode }) =>\n getPageHref ? (\n <AriaLink {...props} href={props.isDisabled ? undefined : getPageHref(target)} onPress={() => go(target)} />\n ) : (\n <AriaButton {...props} onPress={() => go(target)} />\n );\n\n const step = (target: number, label: string, icon: ReactNode) =>\n item(target, {\n className: cx('medo-button', 'medo-button--icon-only', 'medo-button--ghost', `medo-button--${itemSize}`),\n 'aria-label': label,\n isDisabled: target < 1 || target > totalPages,\n children: (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ),\n });\n\n const from = (page - 1) * pageSize + 1;\n const to = totalItems !== undefined ? Math.min(page * pageSize, totalItems) : page * pageSize;\n\n return (\n <nav ref={navRef} aria-label={ariaLabel} className={cx('medo-pagination', compact ? 'medo-pagination--compact' : 'medo-pagination--full', className)}>\n {compact ? (\n <>\n {step(page - 1, previousLabel, <ChevronLeft />)}\n {/* Polite live region: the new page is announced after a change. */}\n <p role=\"status\" className=\"medo-pagination__compact-label\">\n {compactLabel(page, totalPages)}\n </p>\n {step(page + 1, nextLabel, <ChevronRight />)}\n </>\n ) : (\n <>\n {(totalItems !== undefined || onPageSizeChange) && (\n <div className=\"medo-pagination__info\">\n {totalItems !== undefined && (\n <p id={statusId} role=\"status\" className=\"medo-pagination__summary\">\n {summary(from, to, totalItems)}\n </p>\n )}\n {onPageSizeChange && (\n <Select\n label={pageSizeLabel}\n size=\"sm\"\n selectedKey={pageSize}\n onSelectionChange={(key) => key != null && onPageSizeChange(Number(key))}\n className=\"medo-pagination__size\"\n >\n {pageSizeOptions.map((n) => (\n <Option key={n} id={n}>\n {String(n)}\n </Option>\n ))}\n </Select>\n )}\n </div>\n )}\n <ul className=\"medo-pagination__pages\" role=\"list\">\n <li>{step(page - 1, previousLabel, <ChevronLeft />)}</li>\n {getPageItems(page, totalPages).map((p, i) =>\n p === 'ellipsis' ? (\n // Text, not a button – hidden from screen readers (the page names say where they jump).\n <li key={`e${i}`} className={cx('medo-page-item', 'medo-page-item--ellipsis', `medo-page-item--${itemSize}`)} aria-hidden=\"true\">\n …\n </li>\n ) : (\n <li key={p}>\n {item(p, {\n className: cx('medo-button', 'medo-button--ghost', `medo-button--${itemSize}`, 'medo-page-item', `medo-page-item--${itemSize}`),\n 'aria-label': pageLabel(p),\n 'aria-current': p === page ? 'page' : undefined,\n children: p,\n })}\n </li>\n ),\n )}\n <li>{step(page + 1, nextLabel, <ChevronRight />)}</li>\n </ul>\n </>\n )}\n </nav>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Button as AriaButton, Input as AriaInput, SearchField as AriaSearchField, type SearchFieldProps as AriaSearchFieldProps } from 'react-aria-components';\nimport { Search, X } from 'lucide-react';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport type { InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport '../text-field/input.css';\nimport './search.css';\n\nexport interface SearchFieldProps extends Omit<AriaSearchFieldProps, 'children' | 'className' | 'style'> {\n /** Visible label. Without it set `aria-label` (e.g. in a table toolbar or the header). */\n label?: ReactNode;\n /** Helper text below the field. */\n description?: ReactNode;\n /** A hint like „Search invoices“. Never the only label. */\n placeholder?: string;\n /** sm 32 (toolbars) · md 40 · lg 48 (search page, Quick search, mobile). */\n size?: InputSize;\n /** Accessible name of the clear button. */\n clearLabel?: string;\n className?: string;\n}\n\n/**\n * Search field – a text field for a search term. Built on React Aria\n * SearchField: Enter submits (`onSubmit`), Esc or × clears. Put it in a `<search>` element (search landmark);\n * keep the term in the field after searching.\n */\nexport function SearchField({ label, description, placeholder, size = 'md', clearLabel = 'Clear search', className, ...props }: SearchFieldProps) {\n return (\n <AriaSearchField {...props} className={cx('medo-field', 'medo-search-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <div className={cx('medo-input', `medo-input--${size}`)}>\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n <Search />\n </span>\n <AriaInput className=\"medo-input__control\" placeholder={placeholder} />\n {/* React Aria keeps it out of the tab order – Esc clears from the field. */}\n <AriaButton aria-label={clearLabel} className=\"medo-input__action medo-search-field__clear\">\n <X />\n </AriaButton>\n </div>\n {description && <FieldFooter description={description} />}\n </AriaSearchField>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Link as AriaLink, type LinkProps as AriaLinkProps } from 'react-aria-components';\nimport { FileText, Globe } from 'lucide-react';\nimport { AvatarSizeContext } from '../avatar/Avatar';\nimport { Badge } from '../badge/Badge';\nimport { IconTile } from '../empty-state/EmptyState';\nimport { cx } from '../utils/cx';\nimport { Highlight } from '../utils/highlight';\nimport './search.css';\n\nexport type SearchResultType = 'page' | 'document' | 'person' | 'media';\n\nexport interface SearchResultProps {\n /** Sets the default leading icon: page (globe), document (file). Person and media take `leading`. */\n type?: SearchResultType;\n /** base: divider between hits, title in brand colour · aesthetic: no divider, larger title, rounded hover surface. */\n variant?: 'base' | 'aesthetic';\n /** Required. The hit's title – a link to the result. */\n title: string;\n href: string;\n /** Search term: shown in bold in title and snippet (every match), never by colour alone. */\n query?: string;\n /** Where it lives („Help center › Billing“). */\n path?: ReactNode;\n /** Text around the match, max 2 lines. A string gets the highlight. */\n snippet?: ReactNode;\n /** Type label as Badge sm („Page“, „PDF“, „Video“). */\n badge?: string;\n /** Meta text next to the badge („Updated 3 days ago“). */\n meta?: ReactNode;\n /** Person: Avatar (sized lg automatically). Media: an image (4:3; 128 wide, 160 in aesthetic). Overrides the type icon. */\n leading?: ReactNode;\n /** Heading level of the title. Match the page outline (default h3 below the results heading). */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Router options or target for the link. */\n linkProps?: Omit<AriaLinkProps, 'href' | 'children' | 'className'>;\n className?: string;\n}\n\nconst icons: Partial<Record<SearchResultType, ReactNode>> = { page: <Globe />, document: <FileText /> };\n\n/**\n * Search result – one hit: path, title with the search term in bold, snippet,\n * meta row with type badge. The whole result is one link (the title), so it is one tab stop.\n * Put results into `<ul role=\"list\" className=\"medo-search-results\">` with one `<li>` per hit.\n */\nexport function SearchResult({\n type = 'page',\n variant = 'base',\n title,\n href,\n query,\n path,\n snippet,\n badge,\n meta,\n leading,\n headingLevel = 3,\n linkProps,\n className,\n}: SearchResultProps) {\n const Heading = `h${headingLevel}` as const;\n const lead = leading ?? (icons[type] && <IconTile size=\"sm\">{icons[type]}</IconTile>);\n return (\n <article className={cx('medo-search-result', `medo-search-result--${variant}`, `medo-search-result--${type}`, className)}>\n {lead && (\n <AvatarSizeContext.Provider value=\"lg\">\n <span className=\"medo-search-result__leading\">{lead}</span>\n </AvatarSizeContext.Provider>\n )}\n <div className=\"medo-search-result__content\">\n {path && <span className=\"medo-search-result__path\">{path}</span>}\n <Heading className=\"medo-search-result__title\">\n <AriaLink {...linkProps} href={href} className=\"medo-search-result__link\">\n <Highlight text={title} query={query} all className=\"medo-search-result__match\" />\n </AriaLink>\n </Heading>\n {snippet && (\n <p className=\"medo-search-result__snippet\">\n {typeof snippet === 'string' ? <Highlight text={snippet} query={query} all className=\"medo-search-result__match\" /> : snippet}\n </p>\n )}\n {(badge || meta) && (\n <span className=\"medo-search-result__meta\">\n {badge && (\n <Badge tone=\"neutral\" size=\"sm\">\n {badge}\n </Badge>\n )}\n {meta && <span className=\"medo-search-result__meta-text\">{meta}</span>}\n </span>\n )}\n </div>\n </article>\n );\n}\n","import { useEffect, useLayoutEffect, useState, type ReactNode } from 'react';\nimport { Autocomplete, Button as AriaButton, Dialog, Modal, ModalOverlay, useFilter } from 'react-aria-components';\nimport { Search } from 'lucide-react';\nimport { Badge } from '../badge/Badge';\nimport { Button } from '../button/Button';\nimport { Link } from '../link/Link';\nimport { ListBox, OptionHighlightContext } from '../listbox/ListBox';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { SearchField } from './SearchField';\nimport '../dialog/dialog.css';\nimport './search.css';\n\nexport interface QuickSearchProps<T extends object> {\n isOpen?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n /** Opens with Cmd / Ctrl + K (ignored while the user types in another field). */\n shortcut?: boolean;\n /** The search term (controlled) – e.g. to load suggestions from the server. */\n inputValue?: string;\n onInputChange?: (value: string) => void;\n /** Filters the options on the client (contains, case insensitive). Off when the server filters. */\n clientFilter?: boolean;\n /** Empty field: Recent and Suggested. While typing: hits grouped by type (ListBoxSection), max 5 per group. */\n children: ReactNode | ((item: T) => ReactNode);\n items?: Iterable<T>;\n /** Opens the highlighted hit (Enter or click). */\n onAction?: (key: React.Key) => void;\n /** „All results“: the search page with the same term. */\n allResultsHref?: (query: string) => string;\n /** Enter without a highlighted hit, and „Search all content“ when nothing matches. */\n onSearch?: (query: string) => void;\n /** Texts (localize). */\n 'aria-label'?: string;\n placeholder?: string;\n cancelLabel?: string;\n suggestionsLabel?: string;\n allResultsLabel?: (query: string) => string;\n noResultsLabel?: (query: string) => string;\n searchAllLabel?: (query: string) => string;\n hints?: { navigate: string; open: string; close: string };\n}\n\n/**\n * Quick search – find and open pages, files and people from anywhere. A modal with\n * React Aria Autocomplete: focus stays in the field while ↑ ↓ move through the suggestions, Enter opens the\n * highlighted hit, Esc closes and focus returns to the trigger. Desktop: overlay 640 wide · mobile: full screen with Cancel.\n */\nexport function QuickSearch<T extends object>({\n isOpen,\n defaultOpen,\n onOpenChange,\n shortcut = true,\n inputValue,\n onInputChange,\n clientFilter = false,\n children,\n items,\n onAction,\n allResultsHref,\n onSearch,\n 'aria-label': ariaLabel = 'Search',\n placeholder = 'Search pages, files, people …',\n cancelLabel = 'Cancel',\n suggestionsLabel = 'Suggestions',\n allResultsLabel = (q) => `All results for “${q}”`,\n noResultsLabel = (q) => `No results for “${q}”. Check the spelling or try other words.`,\n searchAllLabel = (q) => `Search all content for “${q}”`,\n hints = { navigate: 'Navigate', open: 'Open', close: 'Close' },\n}: QuickSearchProps<T>) {\n const mobile = useMediaQuery(MOBILE_QUERY);\n const [innerOpen, setInnerOpen] = useState(defaultOpen ?? false);\n const open = isOpen ?? innerOpen;\n const setOpen = (value: boolean) => {\n if (isOpen === undefined) setInnerOpen(value);\n onOpenChange?.(value);\n };\n const [innerQuery, setInnerQuery] = useState('');\n const query = inputValue ?? innerQuery;\n const setQuery = (value: string) => {\n if (inputValue === undefined) setInnerQuery(value);\n onInputChange?.(value);\n };\n const { contains } = useFilter({ sensitivity: 'base' });\n\n // Cmd / Ctrl + K – not while typing in another field.\n useEffect(() => {\n if (!shortcut) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() !== 'k' || !(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey) return;\n const t = e.target as HTMLElement | null;\n if (t && (t.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName))) return;\n e.preventDefault();\n setOpen(true);\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n });\n\n const term = query.trim();\n const close = () => setOpen(false);\n // The list reports when nothing matches; „Search all content“ then sits below it (a button may not live inside a listbox).\n const [empty, setEmpty] = useState(false);\n\n return (\n <ModalOverlay\n isOpen={open}\n onOpenChange={setOpen}\n isDismissable\n className={cx('medo-dialog-overlay', 'medo-quick-search-overlay', mobile && 'medo-quick-search-overlay--mobile')}\n >\n <Modal className={cx('medo-dialog', 'medo-quick-search', mobile && 'medo-quick-search--mobile')}>\n <Dialog aria-label={ariaLabel} className=\"medo-quick-search__dialog\">\n <Autocomplete inputValue={query} onInputChange={setQuery} filter={clientFilter ? contains : undefined}>\n <div className=\"medo-quick-search__bar\">\n <SearchField\n aria-label={ariaLabel}\n placeholder={placeholder}\n size=\"lg\"\n autoFocus\n onSubmit={(value) => value.trim() && onSearch?.(value.trim())}\n // Esc in an empty field closes the dialog; with text it clears first.\n className=\"medo-quick-search__field\"\n />\n {mobile && (\n <Button variant=\"text\" size=\"lg\" onPress={close}>\n {cancelLabel}\n </Button>\n )}\n </div>\n {/* Scroll region: focusable, so keyboard users can scroll it too (the options use virtual focus). */}\n <div className=\"medo-quick-search__scroll\" tabIndex={0} aria-label={suggestionsLabel} role=\"region\">\n <OptionHighlightContext.Provider value={term}>\n <ListBox<T>\n aria-label={ariaLabel}\n size={mobile ? 'lg' : 'md'}\n items={items}\n onAction={(key) => {\n onAction?.(key);\n close();\n }}\n className=\"medo-quick-search__list\"\n renderEmptyState={() => (term ? <EmptyReporter onChange={setEmpty} message={noResultsLabel(term)} /> : null)}\n >\n {children}\n </ListBox>\n </OptionHighlightContext.Provider>\n {empty && term && onSearch && (\n <AriaButton className=\"medo-quick-search__all\" onPress={() => onSearch(term)}>\n <Search aria-hidden=\"true\" />\n {searchAllLabel(term)}\n </AriaButton>\n )}\n </div>\n </Autocomplete>\n {!mobile && (\n <div className=\"medo-quick-search__footer\">\n <span className=\"medo-quick-search__hint\" aria-hidden=\"true\">\n <Badge size=\"sm\">↑ ↓</Badge>\n {hints.navigate}\n </span>\n <span className=\"medo-quick-search__hint\" aria-hidden=\"true\">\n <Badge size=\"sm\">Enter</Badge>\n {hints.open}\n </span>\n <span className=\"medo-quick-search__hint\" aria-hidden=\"true\">\n <Badge size=\"sm\">Esc</Badge>\n {hints.close}\n </span>\n {term && !empty && allResultsHref && (\n <Link variant=\"standalone\" size=\"md\" arrow href={allResultsHref(term)} className=\"medo-quick-search__all-results\" onPress={close}>\n {allResultsLabel(term)}\n </Link>\n )}\n </div>\n )}\n </Dialog>\n </Modal>\n </ModalOverlay>\n );\n}\n\n/** Renders the „no results“ message and tells QuickSearch that the list is empty. */\nfunction EmptyReporter({ message, onChange }: { message: string; onChange: (empty: boolean) => void }) {\n useLayoutEffect(() => {\n onChange(true);\n return () => onChange(false);\n }, [onChange]);\n return (\n <p role=\"status\" className=\"medo-quick-search__message\">\n {message}\n </p>\n );\n}\n","import { useLayoutEffect, useRef, useState } from 'react';\nimport { Breadcrumb, Breadcrumbs as AriaBreadcrumbs, Button as AriaButton, Link as AriaLink } from 'react-aria-components';\nimport { ChevronLeft, ChevronRight, Ellipsis, Folder, House } from 'lucide-react';\nimport { Menu, MenuItem, MenuTrigger } from '../menu/Menu';\nimport { Tooltip, TooltipLink, TooltipTrigger } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport './breadcrumbs.css';\n\nexport interface BreadcrumbItem {\n /** The page name – the same words as its title. */\n label: string;\n /** Link to the page. The last item is the current page and needs none. */\n href?: string;\n}\n\nexport interface BreadcrumbsProps {\n /** The path from the top: first the start page, last the current page (not a link). */\n items: BreadcrumbItem[];\n /** sm: dense apps (caption, 24) · md: websites (body/sm, 28). */\n size?: 'sm' | 'md';\n /** The first item shows a house icon; its label stays the accessible name („Home“). */\n homeIcon?: boolean;\n /** auto: full path, below 640 px only a link to the parent page · full · back. From 5 levels the middle collapses into „…“. */\n layout?: 'auto' | 'full' | 'back';\n /** Texts (localize). */\n 'aria-label'?: string;\n moreLabel?: (count: number) => string;\n className?: string;\n}\n\n/**\n * Breadcrumbs – where a page sits in the hierarchy, with links to the levels above.\n * Built on React Aria Breadcrumbs: a navigation region with an ordered list, the current page last with\n * aria-current=\"page\". Not on the start page; place it above the page title.\n */\nexport function Breadcrumbs({\n items,\n size = 'md',\n homeIcon = true,\n layout = 'auto',\n 'aria-label': ariaLabel = 'Breadcrumb',\n moreLabel = (n) => `Show ${n} more levels`,\n className,\n}: BreadcrumbsProps) {\n const mobile = useMediaQuery(MOBILE_QUERY);\n const back = layout === 'back' || (layout === 'auto' && mobile);\n\n // A single level needs no breadcrumbs.\n if (items.length < 2) return null;\n\n if (back) {\n const parent = items[items.length - 2];\n return (\n <nav aria-label={ariaLabel} className={cx('medo-breadcrumbs', `medo-breadcrumbs--${size}`, 'medo-breadcrumbs--back', className)}>\n <AriaLink href={parent.href} className=\"medo-breadcrumbs__link medo-breadcrumbs__back\">\n <ChevronLeft className=\"medo-breadcrumbs__back-icon\" aria-hidden=\"true\" />\n <Label text={parent.label} />\n </AriaLink>\n </nav>\n );\n }\n\n // From 5 levels: start page, „…“, the last two levels and the current page.\n const collapse = items.length >= 5;\n const hidden = collapse ? items.slice(1, -3) : [];\n const shown = collapse ? [items[0], null, ...items.slice(-3)] : items;\n const last = shown.length - 1;\n\n return (\n <nav aria-label={ariaLabel} className={cx('medo-breadcrumbs', `medo-breadcrumbs--${size}`, className)}>\n <AriaBreadcrumbs className=\"medo-breadcrumbs__list\">\n {shown.map((item, i) => {\n const separator = i < last && <ChevronRight className=\"medo-breadcrumbs__separator\" aria-hidden=\"true\" />;\n if (!item) {\n return (\n <Breadcrumb key=\"more\" id=\"more\" className=\"medo-breadcrumbs__item\">\n <MenuTrigger>\n <AriaButton aria-label={moreLabel(hidden.length)} className=\"medo-breadcrumbs__icon-part\">\n <Ellipsis aria-hidden=\"true\" />\n </AriaButton>\n <Menu>\n {hidden.map((h) => (\n <MenuItem key={h.label} id={h.label} href={h.href} icon={<Folder />}>\n {h.label}\n </MenuItem>\n ))}\n </Menu>\n </MenuTrigger>\n {separator}\n </Breadcrumb>\n );\n }\n const isHome = homeIcon && i === 0;\n return (\n <Breadcrumb key={`${i}-${item.label}`} id={`${i}-${item.label}`} className=\"medo-breadcrumbs__item\">\n {isHome ? (\n <AriaLink href={item.href} aria-label={item.label} className=\"medo-breadcrumbs__icon-part\">\n <House aria-hidden=\"true\" />\n </AriaLink>\n ) : i === last ? (\n // The current page: not a link (React Aria sets aria-current=\"page\").\n <AriaLink className=\"medo-breadcrumbs__link medo-breadcrumbs__current\">\n <Label text={item.label} />\n </AriaLink>\n ) : (\n <TruncatedLink href={item.href} label={item.label} />\n )}\n {separator}\n </Breadcrumb>\n );\n })}\n </AriaBreadcrumbs>\n </nav>\n );\n}\n\nfunction Label({ text }: { text: string }) {\n return <span className=\"medo-breadcrumbs__label\">{text}</span>;\n}\n\n/** A link whose label is cut at 200 px shows the full name in a Tooltip on hover and focus. */\nfunction TruncatedLink({ href, label }: { href?: string; label: string }) {\n const ref = useRef<HTMLSpanElement>(null);\n const [cut, setCut] = useState(false);\n useLayoutEffect(() => {\n const el = ref.current;\n if (el) setCut(el.scrollWidth > el.clientWidth);\n }, [label]);\n const text = (\n <span ref={ref} className=\"medo-breadcrumbs__label\">\n {label}\n </span>\n );\n if (!cut) {\n return (\n <AriaLink href={href} className=\"medo-breadcrumbs__link\">\n {text}\n </AriaLink>\n );\n }\n return (\n <TooltipTrigger>\n <TooltipLink href={href} className=\"medo-breadcrumbs__link\">\n {text}\n </TooltipLink>\n <Tooltip>{label}</Tooltip>\n </TooltipTrigger>\n );\n}\n","import { Children, createContext, isValidElement, useContext, useEffect, useId, useState, type ReactElement, type ReactNode } from 'react';\nimport { Button as AriaButton, Disclosure, DisclosureGroup, DisclosurePanel, Heading, type DisclosureGroupProps, type Key } from 'react-aria-components';\nimport { ChevronDown } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { cx } from '../utils/cx';\nimport './accordion.css';\n\ntype AccordionSize = 'md' | 'lg';\n\nconst AccordionContext = createContext<{ size: AccordionSize; headingLevel: 2 | 3 | 4 }>({ size: 'md', headingLevel: 3 });\n\nexport interface AccordionProps extends Omit<DisclosureGroupProps, 'className' | 'style' | 'children'> {\n /** md: apps and settings · lg: websites and FAQs. */\n size?: AccordionSize;\n /** Heading level of the item titles (h2–h4), matching the page outline. */\n headingLevel?: 2 | 3 | 4;\n /** Several sections open at once (default). false: one at a time – only for short, mutually exclusive steps. */\n allowsMultipleExpanded?: boolean;\n /** „Expand all“ / „Collapse all“ above groups with more than 6 sections (multiple only). */\n expandAll?: boolean;\n expandAllLabel?: string;\n collapseAllLabel?: string;\n /** AccordionItems. */\n children: ReactNode;\n className?: string;\n}\n\nconst hashId = () => (typeof window === 'undefined' ? '' : decodeURIComponent(window.location.hash.slice(1)));\n\n/**\n * Accordion – sections that open and close in place. Built on React Aria DisclosureGroup:\n * each header is a button inside a real heading (aria-expanded, aria-controls); closed panels stay findable by\n * the browser search (hidden=\"until-found\"). Several open by default. A link to an item's id (#billing) opens it.\n */\nexport function Accordion({\n size = 'md',\n headingLevel = 3,\n allowsMultipleExpanded = true,\n expandAll = true,\n expandAllLabel = 'Expand all',\n collapseAllLabel = 'Collapse all',\n expandedKeys: expandedProp,\n defaultExpandedKeys,\n onExpandedChange,\n children,\n className,\n ...props\n}: AccordionProps) {\n const ids = Children.toArray(children)\n .filter((c): c is ReactElement<AccordionItemProps> => isValidElement(c))\n .filter((c) => !c.props.isDisabled)\n .map((c) => c.props.id);\n const [inner, setInner] = useState<Set<Key>>(() => {\n const start = new Set<Key>(defaultExpandedKeys ?? []);\n const hash = hashId();\n if (ids.includes(hash)) start.add(hash);\n return start;\n });\n const expanded = expandedProp ? new Set(expandedProp) : inner;\n const setExpanded = (keys: Set<Key>) => {\n if (!expandedProp) setInner(keys);\n onExpandedChange?.(keys);\n };\n\n // Deep link: a link to #id opens that section and scrolls to it – on load and on every hash change.\n useEffect(() => {\n const open = () => {\n const hash = hashId();\n if (!ids.includes(hash)) return;\n setExpanded(new Set(allowsMultipleExpanded ? [...expanded, hash] : [hash]));\n requestAnimationFrame(() => document.getElementById(hash)?.scrollIntoView({ block: 'start' }));\n };\n if (hashId()) requestAnimationFrame(() => document.getElementById(hashId())?.scrollIntoView({ block: 'start' }));\n window.addEventListener('hashchange', open);\n return () => window.removeEventListener('hashchange', open);\n });\n\n const allOpen = ids.length > 0 && ids.every((id) => expanded.has(id));\n const showToggle = expandAll && allowsMultipleExpanded && Children.count(children) > 6;\n\n return (\n <AccordionContext.Provider value={{ size, headingLevel }}>\n <div className={cx('medo-accordion-wrap', className)}>\n {showToggle && (\n <div className=\"medo-accordion__toolbar\">\n <Button variant=\"text\" size=\"sm\" onPress={() => setExpanded(allOpen ? new Set() : new Set(ids))}>\n {allOpen ? collapseAllLabel : expandAllLabel}\n </Button>\n </div>\n )}\n <DisclosureGroup\n {...props}\n allowsMultipleExpanded={allowsMultipleExpanded}\n expandedKeys={expanded}\n onExpandedChange={setExpanded}\n className={cx('medo-accordion', `medo-accordion--${size}`)}\n >\n {children}\n </DisclosureGroup>\n </div>\n </AccordionContext.Provider>\n );\n}\n\nexport interface AccordionItemProps {\n /** Required: key in expandedKeys and the anchor for links (#billing). */\n id: string;\n /** Short and scannable: nouns for settings, real questions for FAQs. */\n title: ReactNode;\n /** Second line in the header. Announced as the button's description. */\n description?: ReactNode;\n /** Decorative icon before the title (20 md / 24 lg). */\n icon?: ReactNode;\n /** Badge sm – part of the button name („Billing, Payment failed“). */\n badge?: ReactNode;\n isDisabled?: boolean;\n /** Panel content – text, a form or a list. No accordion inside. */\n children: ReactNode;\n}\n\n/** One section of an Accordion: a header button inside a heading and its panel. */\nexport function AccordionItem({ id, title, description, icon, badge, isDisabled, children }: AccordionItemProps) {\n const { headingLevel } = useContext(AccordionContext);\n const descId = useId();\n return (\n <Disclosure id={id} isDisabled={isDisabled} className={cx('medo-accordion__item', !!icon && 'medo-accordion__item--icon')}>\n <Heading level={headingLevel} id={id} className=\"medo-accordion__heading\">\n <AriaButton slot=\"trigger\" className=\"medo-accordion__trigger\" aria-describedby={description ? descId : undefined}>\n {icon && (\n <span className=\"medo-accordion__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-accordion__text\">\n <span className=\"medo-accordion__title\">{title}</span>\n {description && (\n // Read as description, not as part of the name.\n <span id={descId} className=\"medo-accordion__description\" aria-hidden=\"true\">\n {description}\n </span>\n )}\n </span>\n {badge && <span className=\"medo-accordion__badge\">{badge}</span>}\n <ChevronDown className=\"medo-accordion__chevron\" aria-hidden=\"true\" />\n </AriaButton>\n </Heading>\n <DisclosurePanel className=\"medo-accordion__panel\">\n <div className=\"medo-accordion__content\">{children}</div>\n </DisclosurePanel>\n </Disclosure>\n );\n}\n","import { useMemo, type ReactNode } from 'react';\nimport { Label, Slider as AriaSlider, SliderOutput, SliderThumb, SliderTrack, useLocale, type SliderProps as AriaSliderProps } from 'react-aria-components';\nimport { NumberField } from '../number-field/NumberField';\nimport { cx } from '../utils/cx';\nimport '../tooltip/tooltip.css';\nimport './slider.css';\n\ntype Value = number | number[];\n\nexport interface SliderProps<T extends Value = number> extends Omit<AriaSliderProps<T>, 'children' | 'className' | 'style'> {\n /** Visible label. Without it set `aria-label`. */\n label?: ReactNode;\n /** Range: a name per thumb („Minimum price“, „Maximum price“). Default: „Minimum“ / „Maximum“ + label. */\n thumbLabels?: [string, string];\n /** Tick marks for few fixed steps (≤ 10) – the thumb snaps to them. */\n showTicks?: boolean;\n /** Min and max below the track, when the range is not obvious from the label. */\n showMinMax?: boolean;\n /** The value label above the track (always visible by default). */\n showValue?: boolean;\n className?: string;\n}\n\n/**\n * Slider – pick an approximate value or a range by dragging. Built on React Aria Slider:\n * arrow keys (step), Page Up/Down (10 %), Home/End, a click on the track moves the nearest thumb; range thumbs\n * never cross. The value is always shown next to the label and read out in the same format (`formatOptions`).\n * While dragging, a tooltip repeats it above the thumb. For exact values use SliderField.\n */\nexport function Slider<T extends Value = number>({\n label,\n thumbLabels,\n showTicks,\n showMinMax,\n showValue = true,\n minValue = 0,\n maxValue = 100,\n step = 1,\n formatOptions,\n className,\n ...props\n}: SliderProps<T>) {\n const { locale } = useLocale();\n const format = useMemo(() => new Intl.NumberFormat(locale, formatOptions), [locale, formatOptions]);\n const steps = Math.round((maxValue - minValue) / step);\n const labelText = typeof label === 'string' ? label : (props['aria-label'] ?? '');\n\n return (\n <AriaSlider<T> {...props} minValue={minValue} maxValue={maxValue} step={step} formatOptions={formatOptions} className={cx('medo-slider', className)}>\n {({ state }) => {\n const range = state.values.length > 1;\n const start = range ? state.getThumbPercent(0) : 0;\n const end = state.getThumbPercent(state.values.length - 1);\n return (\n <>\n {(label || showValue) && (\n <div className=\"medo-slider__header\">\n {label && (\n <Label className=\"medo-slider__label\" aria-disabled={props.isDisabled || undefined}>\n {label}\n </Label>\n )}\n {showValue && <SliderOutput className=\"medo-slider__value\" aria-disabled={props.isDisabled || undefined} />}\n </div>\n )}\n <SliderTrack className=\"medo-slider__track\">\n <span className=\"medo-slider__rail\" aria-hidden=\"true\" />\n {showTicks && steps <= 10 && (\n <span className=\"medo-slider__ticks\" aria-hidden=\"true\">\n {Array.from({ length: steps + 1 }, (_, i) => (\n <span key={i} className=\"medo-slider__tick\" style={{ insetInlineStart: `${(i / steps) * 100}%` }} />\n ))}\n </span>\n )}\n <span className=\"medo-slider__fill\" style={{ insetInlineStart: `${start * 100}%`, inlineSize: `${(end - start) * 100}%` }} aria-hidden=\"true\" />\n {state.values.map((_, i) => (\n <SliderThumb\n key={i}\n index={i}\n aria-label={range ? (thumbLabels?.[i] ?? `${i === 0 ? 'Minimum' : 'Maximum'} ${labelText}`.trim()) : undefined}\n className=\"medo-slider__thumb\"\n >\n {({ isDragging }) =>\n // The finger covers the thumb: show the value above it while dragging.\n isDragging && (\n <span className=\"medo-tooltip medo-slider__bubble\" aria-hidden=\"true\">\n {state.getThumbValueLabel(i)}\n </span>\n )\n }\n </SliderThumb>\n ))}\n </SliderTrack>\n {showMinMax && (\n <div className=\"medo-slider__limits\" aria-hidden=\"true\">\n <span>{format.format(minValue)}</span>\n <span>{format.format(maxValue)}</span>\n </div>\n )}\n </>\n );\n }}\n </AriaSlider>\n );\n}\n\nexport interface SliderFieldProps<T extends Value = number> extends Omit<SliderProps<T>, 'value' | 'defaultValue' | 'onChange' | 'showValue'> {\n value: T;\n onChange: (value: T) => void;\n /** Accessible names of the number inputs. Default: the label (single) or the thumb labels (range). */\n inputLabels?: [string, string];\n}\n\n/**\n * Slider field – a Slider plus number inputs for exact values. Single: input on the\n * right (88). Range: two inputs below (min – max). Slider and inputs stay in sync; the inputs clamp on blur.\n */\nexport function SliderField<T extends Value = number>({ value, onChange, inputLabels, ...props }: SliderFieldProps<T>) {\n const { minValue = 0, maxValue = 100, step = 1, formatOptions, isDisabled, label, thumbLabels } = props;\n const labelText = typeof label === 'string' ? label : (props['aria-label'] ?? '');\n const field = { step, formatOptions, isDisabled, size: 'md' as const };\n\n if (Array.isArray(value)) {\n const [lo, hi] = value as number[];\n const names = inputLabels ?? thumbLabels ?? [`Minimum ${labelText}`.trim(), `Maximum ${labelText}`.trim()];\n return (\n <div className=\"medo-slider-field medo-slider-field--range\">\n <Slider<T> {...props} value={value} onChange={onChange} />\n <div className=\"medo-slider-field__inputs\">\n <NumberField {...field} aria-label={names[0]} minValue={minValue} maxValue={hi} value={lo} onChange={(v) => !Number.isNaN(v) && onChange([v, hi] as T)} />\n <span className=\"medo-slider-field__dash\" aria-hidden=\"true\">\n –\n </span>\n <NumberField {...field} aria-label={names[1]} minValue={lo} maxValue={maxValue} value={hi} onChange={(v) => !Number.isNaN(v) && onChange([lo, v] as T)} />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"medo-slider-field medo-slider-field--single\">\n <Slider<T> {...props} value={value} onChange={onChange} showValue={false} />\n <NumberField\n {...field}\n aria-label={inputLabels?.[0] ?? labelText}\n minValue={minValue}\n maxValue={maxValue}\n value={value as number}\n onChange={(v) => !Number.isNaN(v) && onChange(v as T)}\n className=\"medo-slider-field__input\"\n />\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Input as AriaInput, NumberField as AriaNumberField, type NumberFieldProps as AriaNumberFieldProps } from 'react-aria-components';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport type { InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport '../text-field/input.css';\n\nexport interface NumberFieldProps extends Omit<AriaNumberFieldProps, 'children' | 'className' | 'style'> {\n /** Visible label. Without it set `aria-label` – only where the context names the field (e.g. next to a Slider). */\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. lg on mobile and touch. */\n size?: InputSize;\n className?: string;\n}\n\n/**\n * Number field – a number with format and limits. Built on React Aria\n * NumberField: formats with Intl (`formatOptions`: currency, percent, unit), clamps to min/max and rounds to the\n * step when the field is left, ↑ ↓ change by one step. Tabular figures.\n */\nexport function NumberField({ label, description, errorMessage, placeholder, size = 'md', className, ...props }: NumberFieldProps) {\n return (\n <AriaNumberField {...props} className={cx('medo-field', 'medo-number-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <div className={cx('medo-input', `medo-input--${size}`)}>\n <AriaInput className=\"medo-input__control medo-number-field__control\" placeholder={placeholder} />\n </div>\n {(description || errorMessage) && <FieldFooter description={description} errorMessage={errorMessage} />}\n </AriaNumberField>\n );\n}\n","import type { HTMLAttributes, ReactNode } from 'react';\nimport { CircleAlert, CircleCheck, Info, TriangleAlert, X } from 'lucide-react';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport './alert.css';\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'danger';\n\nconst ICONS: Record<AlertTone, typeof Info> = {\n info: Info,\n success: CircleCheck,\n warning: TriangleAlert,\n danger: CircleAlert,\n};\n\nexport interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** danger: failed or blocks · warning: risk ahead · success: done · info: good to know. */\n tone?: AlertTone;\n /** inline: in the content · banner: full width above the header, for app-wide states. */\n variant?: 'inline' | 'banner';\n /** Required. Says what happened („Your trial ends in 3 days“). */\n title: ReactNode;\n /** What to do next. */\n children?: ReactNode;\n /** Max two text buttons (Button variant=\"text\" size=\"sm\"), the main one first. */\n actions?: ReactNode;\n /** Shows the close button. Only when it is safe to hide the message. */\n onDismiss?: () => void;\n dismissLabel?: string;\n /**\n * Set when the alert appears after the page has loaded: danger and warning are announced\n * immediately (role=\"alert\"), info and success politely (role=\"status\").\n */\n announce?: boolean;\n}\n\n/** Alert – persistent message inside the page. Plain markup, no library needed. */\nexport function Alert({\n tone = 'info',\n variant = 'inline',\n title,\n children,\n actions,\n onDismiss,\n dismissLabel = 'Dismiss',\n announce,\n className,\n ...props\n}: AlertProps) {\n const Icon = ICONS[tone];\n const role = announce ? (tone === 'danger' || tone === 'warning' ? 'alert' : 'status') : undefined;\n return (\n <div {...props} role={role ?? props.role} className={cx('medo-alert', `medo-alert--${tone}`, variant === 'banner' && 'medo-alert--banner', className)}>\n <Icon className=\"medo-alert__icon\" aria-hidden=\"true\" />\n <div className=\"medo-alert__content\">\n <p className=\"medo-alert__title\">{title}</p>\n {children && <div className=\"medo-alert__description\">{children}</div>}\n {actions && <div className=\"medo-alert__actions\">{actions}</div>}\n </div>\n {onDismiss && (\n <IconButton className=\"medo-alert__close\" variant=\"ghost\" size=\"sm\" icon={<X />} aria-label={dismissLabel} onPress={onDismiss} />\n )}\n </div>\n );\n}\n","import type { CSSProperties, ElementType, ReactNode } from 'react';\nimport { Link as AriaLink, type LinkProps as AriaLinkProps } from 'react-aria-components';\nimport { cx } from '../utils/cx';\nimport './card.css';\n\nexport interface CardProps {\n /** Required: every card has a heading, so it can be scanned and announced. */\n title: ReactNode;\n subtitle?: ReactNode;\n /** Heading level of the title. Match the page outline (default h3). */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** outlined (default) · elevated (needs attention, draggable) · filled (inside white areas) · brand (one per view) · plain (editorial). */\n variant?: 'outlined' | 'elevated' | 'filled' | 'brand' | 'plain';\n /** standard 24 px · compact 16 px (dense layouts and mobile). */\n density?: 'standard' | 'compact';\n /** vertical (media on top, 16:9) · horizontal (media 180 px left, for lists). */\n layout?: 'vertical' | 'horizontal';\n /** Image or video. Decorative images use alt=\"\". */\n media?: ReactNode;\n /** Actions for the whole card, next to the title (ButtonGroup context=\"header\"). */\n headerActions?: ReactNode;\n /** Actions that finish a task in the card (ButtonGroup context=\"footer\"). */\n footer?: ReactNode;\n /** Makes the whole card open something: the title becomes one link stretched over the card. */\n href?: AriaLinkProps['href'];\n /** Link props such as target or routerOptions. */\n linkProps?: Omit<AriaLinkProps, 'href' | 'children' | 'className'>;\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Card – a container for one topic. Rendered as an article with a heading. */\nexport function Card({\n title,\n subtitle,\n headingLevel = 3,\n variant = 'outlined',\n density = 'standard',\n layout = 'vertical',\n media,\n headerActions,\n footer,\n href,\n linkProps,\n children,\n className,\n style,\n}: CardProps) {\n const Heading = `h${headingLevel}` as ElementType;\n const interactive = href !== undefined;\n return (\n <article\n className={cx(\n 'medo-card',\n `medo-card--${variant}`,\n density === 'compact' && 'medo-card--compact',\n layout === 'horizontal' && 'medo-card--horizontal',\n interactive && 'medo-card--interactive',\n className,\n )}\n style={style}\n >\n {media && <div className=\"medo-card__media\">{media}</div>}\n <div className=\"medo-card__main\">\n <div className=\"medo-card__header\">\n <div className=\"medo-card__heading\">\n <Heading className=\"medo-card__title\">\n {interactive ? (\n <AriaLink {...linkProps} href={href} className=\"medo-card__link\">\n {title}\n </AriaLink>\n ) : (\n title\n )}\n </Heading>\n {subtitle && <p className=\"medo-card__subtitle\">{subtitle}</p>}\n </div>\n {headerActions && <div className=\"medo-card__header-actions\">{headerActions}</div>}\n </div>\n {children && <div className=\"medo-card__body\">{children}</div>}\n {footer && <div className=\"medo-card__footer\">{footer}</div>}\n </div>\n </article>\n );\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport {\n Cell as AriaCell,\n Checkbox as AriaCheckbox,\n Collection,\n Column as AriaColumn,\n Row as AriaRow,\n Table as AriaTable,\n TableBody as AriaTableBody,\n TableHeader as AriaTableHeader,\n useTableOptions,\n type CellProps as AriaCellProps,\n type ColumnProps as AriaColumnProps,\n type RowProps as AriaRowProps,\n type TableBodyProps as AriaTableBodyProps,\n type TableHeaderProps as AriaTableHeaderProps,\n type TableProps as AriaTableProps,\n} from 'react-aria-components';\nimport { ArrowDown, ArrowUp, ArrowUpDown, Check, Minus } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport '../checkbox/choice.css';\nimport './table.css';\n\ntype Density = 'standard' | 'compact';\n\n/* ---------- Static table: a native <table> ---------- */\n\nexport interface StaticTableProps {\n /** thead / tbody / tr / th / td as usual. Use <th scope=\"row\"> for row headers. */\n children: ReactNode;\n /** Visible caption or, with captionHidden, a name for screen readers. */\n caption?: ReactNode;\n captionHidden?: boolean;\n density?: Density;\n striped?: boolean;\n /** Without the border and radius, e.g. inside a card or documentation. */\n plain?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Static table – a native, non-interactive table with the Table look.\n * For content and simple data. Numbers: add className=\"medo-table__cell--number\".\n */\nexport function StaticTable({ children, caption, captionHidden, density = 'standard', striped, plain, className, style }: StaticTableProps) {\n return (\n <div className={cx('medo-table-container', plain && 'medo-table-container--plain', className)} style={style}>\n <table className={cx('medo-table', density === 'compact' && 'medo-table--compact', striped && 'medo-table--striped')}>\n {caption && <caption className={captionHidden ? 'medo-visually-hidden' : undefined}>{caption}</caption>}\n {children}\n </table>\n </div>\n );\n}\n\n/* ---------- Interactive table: React Aria Table (grid) ---------- */\n\nexport interface TableProps extends Omit<AriaTableProps, 'className' | 'style'> {\n density?: Density;\n /** Bar above the header: search (Input sm 240), filter, ColumnsMenu, primary action on the right (Buttons sm). */\n toolbar?: ReactNode;\n /** Bar below the rows, usually Pagination. */\n footer?: ReactNode;\n striped?: boolean;\n plain?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Table – interactive data table. Built on React Aria Table:\n * arrow keys move between cells, Space selects, Enter opens, sortable headers announce the order.\n * Data logic (sorting, filtering, paging) stays in your code or a headless table library.\n */\nexport function Table({ density = 'standard', striped, plain, toolbar, footer, className, style, ...props }: TableProps) {\n const table = <AriaTable {...props} className={cx('medo-table', density === 'compact' && 'medo-table--compact', striped && 'medo-table--striped')} />;\n if (!toolbar && !footer) {\n return (\n <div className={cx('medo-table-container', plain && 'medo-table-container--plain', className)} style={style}>\n {table}\n </div>\n );\n }\n // Toolbar – rows – footer in one bordered surface; only the table scrolls.\n return (\n <div className={cx('medo-table-frame', plain && 'medo-table-frame--plain', className)} style={style}>\n {toolbar && <div className=\"medo-table__toolbar\">{toolbar}</div>}\n <div className=\"medo-table-container medo-table-container--plain\">{table}</div>\n {footer && <div className=\"medo-table__footer\">{footer}</div>}\n </div>\n );\n}\n\n/** Checkbox for row selection (slot=\"selection\"), styled like Checkbox md. */\nfunction SelectionCheckbox() {\n return (\n <AriaCheckbox slot=\"selection\" className=\"medo-choice medo-checkbox medo-choice--md medo-choice__button\">\n {({ isSelected, isIndeterminate }) => (\n <span className=\"medo-choice__control\" aria-hidden=\"true\">\n {isIndeterminate ? <Minus /> : isSelected ? <Check /> : null}\n </span>\n )}\n </AriaCheckbox>\n );\n}\n\nexport function TableHeader<T extends object>({ columns, children, ...props }: Omit<AriaTableHeaderProps<T>, 'className'>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions();\n return (\n <AriaTableHeader {...props} className=\"medo-table__header\">\n {allowsDragging && <AriaColumn className=\"medo-table__column medo-table__column--utility\" />}\n {selectionBehavior === 'toggle' && selectionMode !== 'none' && (\n <AriaColumn className=\"medo-table__column medo-table__column--utility\">{selectionMode === 'multiple' && <SelectionCheckbox />}</AriaColumn>\n )}\n <Collection items={columns}>{children}</Collection>\n </AriaTableHeader>\n );\n}\n\nexport interface ColumnProps extends Omit<AriaColumnProps, 'className' | 'children'> {\n children: ReactNode;\n /** end: numbers, amounts, dates – right-aligned with tabular figures. */\n align?: 'start' | 'end';\n}\n\n/** Header cell. With allowsSorting it is a button: ascending → descending → ascending. */\nexport function Column({ children, align = 'start', ...props }: ColumnProps) {\n return (\n <AriaColumn {...props} data-align={align} className=\"medo-table__column\">\n {({ allowsSorting, sortDirection }) => (\n <span className=\"medo-table__column-inner\">\n {children}\n {allowsSorting &&\n (sortDirection === 'ascending' ? (\n <ArrowUp className=\"medo-table__sort\" aria-hidden=\"true\" />\n ) : sortDirection === 'descending' ? (\n <ArrowDown className=\"medo-table__sort\" aria-hidden=\"true\" />\n ) : (\n <ArrowUpDown className=\"medo-table__sort\" aria-hidden=\"true\" />\n ))}\n </span>\n )}\n </AriaColumn>\n );\n}\n\nexport function TableBody<T extends object>(props: Omit<AriaTableBodyProps<T>, 'className'>) {\n return <AriaTableBody {...props} className=\"medo-table__body\" />;\n}\n\nexport function Row<T extends object>({ id, columns, children, ...props }: Omit<AriaRowProps<T>, 'className'>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions();\n return (\n <AriaRow id={id} {...props} className=\"medo-table__row\">\n {allowsDragging && <AriaCell className=\"medo-table__cell medo-table__cell--utility\" />}\n {selectionBehavior === 'toggle' && selectionMode !== 'none' && (\n <AriaCell className=\"medo-table__cell medo-table__cell--utility\">\n <SelectionCheckbox />\n </AriaCell>\n )}\n <Collection items={columns}>{children}</Collection>\n </AriaRow>\n );\n}\n\nexport interface CellProps extends Omit<AriaCellProps, 'className'> {\n align?: 'start' | 'end';\n}\n\nexport function Cell({ align = 'start', ...props }: CellProps) {\n return <AriaCell {...props} data-align={align} className=\"medo-table__cell\" />;\n}\n","import { Columns3 } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { Checkbox, CheckboxGroup } from '../checkbox/Checkbox';\nimport { Popover, PopoverTrigger } from '../popover/Popover';\n\nexport interface ColumnOption {\n id: string;\n label: string;\n /** Can't be hidden: the first column (row header) and actions. */\n isLocked?: boolean;\n}\n\nexport interface ColumnsMenuProps {\n /** All columns that can be shown, in table order. */\n columns: ColumnOption[];\n /** Ids of the visible columns. */\n visibleColumns: string[];\n onVisibleColumnsChange: (ids: string[]) => void;\n /** Button label. */\n label?: string;\n /** Title of the list. */\n title?: string;\n}\n\n/**\n * Columns menu – shows or hides table columns. A ghost button sm in the\n * table toolbar opens a Popover sm with checkboxes; locked columns stay visible. Render only the visible columns.\n */\nexport function ColumnsMenu({ columns, visibleColumns, onVisibleColumnsChange, label = 'Columns', title = 'Show columns' }: ColumnsMenuProps) {\n const locked = columns.filter((c) => c.isLocked).map((c) => c.id);\n return (\n <PopoverTrigger>\n <Button variant=\"ghost\" size=\"sm\" startIcon={<Columns3 />}>\n {label}\n </Button>\n <Popover size=\"sm\" aria-label={title}>\n <CheckboxGroup\n label={title}\n value={visibleColumns}\n // Locked columns can't be unchecked; keep the table order.\n onChange={(ids) => onVisibleColumnsChange(columns.map((c) => c.id).filter((id) => ids.includes(id) || locked.includes(id)))}\n >\n {columns.map((c) => (\n <Checkbox key={c.id} value={c.id} isDisabled={c.isLocked}>\n {c.label}\n </Checkbox>\n ))}\n </CheckboxGroup>\n </Popover>\n </PopoverTrigger>\n );\n}\n","import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n DropZone,\n FileTrigger as AriaFileTrigger,\n Text,\n useLocale,\n type DropZoneProps as AriaDropZoneProps,\n type FileDropItem,\n} from 'react-aria-components';\nimport { CircleAlert, CircleCheck, CloudUpload, FileText, Image as ImageIcon, RotateCw, Trash2, Upload, X } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { IconTile } from '../empty-state/EmptyState';\nimport { ProgressBar } from '../progress/Progress';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport '../utils/utilities.css';\nimport '../field/field.css';\nimport '../empty-state/empty-state.css';\nimport './upload.css';\n\n/* ---------- Helpers ---------- */\n\nconst units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const;\n\nfunction unitOf(bytes: number) {\n let i = 0;\n let value = bytes;\n while (value >= 1000 && i < units.length - 1) {\n value /= 1000;\n i++;\n }\n return { value, i, digits: i < 2 ? 0 : 1 };\n}\n\n/** „2.4 MB“, „860 kB“ – decimal units like the operating systems' file dialogs. */\nexport function formatBytes(bytes: number, locale = 'en-US') {\n const { value, i, digits } = unitOf(bytes);\n return new Intl.NumberFormat(locale, { style: 'unit', unit: units[i], unitDisplay: 'short', maximumFractionDigits: digits }).format(value);\n}\n\n/** „1.6“ when both values share the unit („1.6 of 2.4 MB“), else the full size („860 kB“). */\nfunction formatLoaded(loaded: number, total: number, locale: string) {\n const a = unitOf(loaded);\n if (a.i !== unitOf(total).i) return formatBytes(loaded, locale);\n return new Intl.NumberFormat(locale, { maximumFractionDigits: a.digits }).format(a.value);\n}\n\n/** Accept list as for <input accept>: „.pdf“, „image/*“, „application/pdf“. */\nfunction isAccepted(file: File, accepted?: string[]) {\n if (!accepted?.length) return true;\n const name = file.name.toLowerCase();\n const type = file.type.toLowerCase();\n return accepted.some((a) => {\n const rule = a.trim().toLowerCase();\n if (rule.startsWith('.')) return name.endsWith(rule);\n if (rule.endsWith('/*')) return type.startsWith(rule.slice(0, -1));\n return type === rule;\n });\n}\n\n/* ---------- File name (truncates in the middle) ---------- */\n\n/**\n * The start shrinks and gets the „…“, the last 12 characters (incl. extension) always stay visible.\n * No measuring: two spans and CSS. The full name is the accessible text and the hover title.\n */\nfunction FileName({ name, className }: { name: string; className?: string }) {\n const keep = 12;\n const start = name.length > keep + 4 ? name.slice(0, -keep) : name;\n const end = name.length > keep + 4 ? name.slice(-keep) : '';\n return (\n <span className={cx('medo-file-name', className)}>\n <span className=\"medo-visually-hidden\">{name}</span>\n <span className=\"medo-file-name__visual\" title={name} aria-hidden=\"true\">\n <span className=\"medo-file-name__start\">{start}</span>\n {end && <span className=\"medo-file-name__end\">{end}</span>}\n </span>\n </span>\n );\n}\n\n/* ---------- Types and texts ---------- */\n\nexport interface UploadFile {\n /** Stable id (e.g. crypto.randomUUID() when the file is added). */\n id: string;\n name: string;\n /** Size in bytes. */\n size: number;\n /** MIME type. image/* with a `previewUrl` shows a thumbnail, everything else a type icon. */\n type?: string;\n status: 'uploading' | 'done' | 'error';\n /** Uploaded bytes (ProgressEvent.loaded). Without it the bar is indeterminate. */\n loaded?: number;\n /** What happened and how to fix it („Upload interrupted. Check your connection and retry.“). No error codes. */\n error?: string;\n /** Thumbnail (URL.createObjectURL(file) or the server URL). */\n previewUrl?: string;\n /** false hides „Retry“ (e.g. the server rejected the file). Default true. */\n canRetry?: boolean;\n}\n\nexport interface UploadTexts {\n /** Dropzone and trigger. */\n title: string;\n dropTitle: string;\n chooseFiles: string;\n chooseFile: string;\n listLabel: string;\n /** File actions – always name the file. */\n cancel: (name: string) => string;\n remove: (name: string) => string;\n retry: (name: string) => string;\n retryShort: string;\n /** Name of the progress bar. */\n uploading: (name: string) => string;\n /** „1.6 of 2.4 MB · 64 %“ */\n progress: (loaded: string, total: string, percent: number) => string;\n /** Validation. */\n typeNotAllowed: (names: string, types: string) => string;\n tooLarge: (size: string, max: string) => string;\n tooMany: (max: number) => string;\n /** Polite announcements. */\n uploaded: (name: string) => string;\n failed: (name: string, error: string) => string;\n}\n\nexport const defaultUploadTexts: UploadTexts = {\n title: 'Drag and drop files here',\n dropTitle: 'Drop files to upload',\n chooseFiles: 'Choose files',\n chooseFile: 'Choose file',\n listLabel: 'Uploaded files',\n cancel: (name) => `Cancel upload of ${name}`,\n remove: (name) => `Remove ${name}`,\n retry: (name) => `Retry ${name}`,\n retryShort: 'Retry',\n uploading: (name) => `Uploading ${name}`,\n progress: (loaded, total, percent) => `${loaded} of ${total} · ${percent} %`,\n typeNotAllowed: (names, types) => `${names} ${names.includes(',') ? 'are' : 'is'} not allowed.${types ? ` Use ${types}.` : ''}`,\n tooLarge: (size, max) => `File is ${size} – max. ${max} allowed`,\n tooMany: (max) => `You can add up to ${max} files. Remove one to add another.`,\n uploaded: (name) => `${name} uploaded`,\n failed: (name, error) => `${name}: ${error}`,\n};\n\ninterface ItemActions {\n onRemove: (id: string) => void;\n onCancel?: (id: string) => void;\n onRetry?: (id: string) => void;\n texts?: Partial<UploadTexts>;\n}\n\nconst isImage = (file: UploadFile) => !!file.previewUrl && (!file.type || file.type.startsWith('image/'));\nconst percentOf = (file: UploadFile) => (file.loaded != null && file.size > 0 ? Math.min(100, Math.round((file.loaded / file.size) * 100)) : undefined);\n\n/* ---------- File item (row) ---------- */\n\nexport interface FileItemProps extends ItemActions {\n file: UploadFile;\n className?: string;\n}\n\n/**\n * File item – one file in the upload list. Uploading: progress + cancel · Done: size +\n * remove · Error: the reason + retry + remove. Images show a 40 px thumbnail, other files a type icon.\n */\nexport function FileItem({ file, onRemove, onCancel, onRetry, texts: own, className }: FileItemProps) {\n const t = { ...defaultUploadTexts, ...own };\n const { locale } = useLocale();\n const percent = percentOf(file);\n const size = formatBytes(file.size, locale);\n\n let meta: ReactNode;\n if (file.status === 'uploading') {\n meta = (\n <>\n <span className=\"medo-file-item__meta\">{percent != null ? t.progress(formatLoaded(file.loaded ?? 0, file.size, locale), size, percent) : size}</span>\n <ProgressBar\n size=\"sm\"\n showValue={false}\n aria-label={t.uploading(file.name)}\n value={percent}\n isIndeterminate={percent == null}\n className=\"medo-file-item__progress\"\n />\n </>\n );\n } else {\n const error = file.status === 'error';\n meta = (\n <span className={cx('medo-file-item__meta', error && 'medo-file-item__meta--error')}>\n {error ? <CircleAlert aria-hidden=\"true\" /> : <CircleCheck aria-hidden=\"true\" className=\"medo-file-item__done\" />}\n <span>{error ? file.error : size}</span>\n </span>\n );\n }\n\n return (\n <div className={cx('medo-file-item', `medo-file-item--${file.status}`, className)}>\n {isImage(file) ? (\n <img className=\"medo-file-item__thumb\" src={file.previewUrl} alt=\"\" />\n ) : (\n <span className=\"medo-file-item__icon\" aria-hidden=\"true\">\n {file.type?.startsWith('image/') ? <ImageIcon /> : <FileText />}\n </span>\n )}\n <div className=\"medo-file-item__content\">\n <FileName name={file.name} className=\"medo-file-item__name\" />\n {meta}\n </div>\n <div className=\"medo-file-item__actions\">\n {file.status === 'uploading' && <IconButton size=\"sm\" icon={<X />} aria-label={t.cancel(file.name)} onPress={() => (onCancel ?? onRemove)(file.id)} />}\n {file.status === 'error' && onRetry && file.canRetry !== false && (\n <IconButton size=\"sm\" icon={<RotateCw />} aria-label={t.retry(file.name)} onPress={() => onRetry(file.id)} />\n )}\n {file.status !== 'uploading' && (\n <IconButton size=\"sm\" icon={file.status === 'done' ? <Trash2 /> : <X />} aria-label={t.remove(file.name)} onPress={() => onRemove(file.id)} />\n )}\n </div>\n </div>\n );\n}\n\n/* ---------- File tile (grid, images) ---------- */\n\nexport interface FileTileProps extends ItemActions {\n file: UploadFile;\n className?: string;\n}\n\n/**\n * File tile – an image in the grid view. Uploading: dark overlay with % and bar ·\n * Done: remove top right · Error: danger border, the overlay retries, the caption names the problem.\n */\nexport function FileTile({ file, onRemove, onCancel, onRetry, texts: own, className }: FileTileProps) {\n const t = { ...defaultUploadTexts, ...own };\n const percent = percentOf(file);\n const retry = file.status === 'error' && onRetry && file.canRetry !== false;\n\n return (\n <div className={cx('medo-file-tile', `medo-file-tile--${file.status}`, className)}>\n <div className=\"medo-file-tile__media\">\n {file.previewUrl ? (\n <img className=\"medo-file-tile__image\" src={file.previewUrl} alt=\"\" />\n ) : (\n <span className=\"medo-file-tile__placeholder\" aria-hidden=\"true\">\n <ImageIcon />\n </span>\n )}\n {file.status === 'uploading' && (\n <div className=\"medo-file-tile__overlay\">\n <span className=\"medo-file-tile__percent\" aria-hidden=\"true\">\n {percent != null ? `${percent} %` : ''}\n </span>\n <ProgressBar\n size=\"sm\"\n showValue={false}\n aria-label={t.uploading(file.name)}\n value={percent}\n isIndeterminate={percent == null}\n className=\"medo-file-tile__progress\"\n />\n </div>\n )}\n {file.status === 'error' &&\n (retry ? (\n <AriaButton className=\"medo-file-tile__overlay medo-file-tile__retry\" aria-label={t.retry(file.name)} onPress={() => onRetry(file.id)}>\n <CircleAlert aria-hidden=\"true\" />\n <span aria-hidden=\"true\">{t.retryShort}</span>\n </AriaButton>\n ) : (\n <div className=\"medo-file-tile__overlay\" aria-hidden=\"true\">\n <CircleAlert />\n </div>\n ))}\n <IconButton\n variant=\"media\"\n size=\"sm\"\n icon={<X />}\n aria-label={file.status === 'uploading' ? t.cancel(file.name) : t.remove(file.name)}\n onPress={() => (file.status === 'uploading' ? (onCancel ?? onRemove) : onRemove)(file.id)}\n className=\"medo-file-tile__remove\"\n />\n </div>\n {file.status === 'error' ? (\n <span className=\"medo-file-tile__caption medo-file-tile__caption--error\">\n <span className=\"medo-visually-hidden\">{file.name}: </span>\n {file.error}\n </span>\n ) : (\n <FileName name={file.name} className=\"medo-file-tile__caption\" />\n )}\n </div>\n );\n}\n\n/* ---------- Dropzone ---------- */\n\ninterface PickerProps {\n /** Accepted types as for <input accept>: [„.pdf“, „image/*“]. Checked again before upload. */\n acceptedFileTypes?: string[];\n /** Several files at once. Default true. */\n allowsMultiple?: boolean;\n /** Mobile: open the camera first („environment“ = back camera). */\n defaultCamera?: 'user' | 'environment';\n isDisabled?: boolean;\n /** Types, size and count – shown before the user picks a file. */\n hint?: ReactNode;\n /** Validation or required message. Never only by color. */\n errorMessage?: ReactNode;\n onSelect: (files: File[]) => void;\n texts?: Partial<UploadTexts>;\n className?: string;\n}\n\nexport interface DropzoneProps extends PickerProps {\n /** Ids of elements that also name the zone (the field label). */\n 'aria-labelledby'?: string;\n}\n\ntype DropEvent = Parameters<NonNullable<AriaDropZoneProps['onDrop']>>[0];\n\nasync function filesFrom(e: DropEvent) {\n const items = e.items.filter((i): i is FileDropItem => i.kind === 'file');\n return Promise.all(items.map((i) => i.getFile()));\n}\n\n/**\n * Dropzone – drag and drop files or choose them. Built on React Aria DropZone +\n * FileTrigger: the button always opens the system picker (drag and drop is only a shortcut, WCAG 2.5.7),\n * the zone is focusable for paste (Ctrl+V). Below 640 px use the FileTrigger instead.\n */\nexport function Dropzone({\n acceptedFileTypes,\n allowsMultiple = true,\n defaultCamera,\n isDisabled,\n hint,\n errorMessage,\n onSelect,\n texts: own,\n className,\n ...props\n}: DropzoneProps) {\n const t = { ...defaultUploadTexts, ...own };\n const hintId = useId();\n const errorId = useId();\n return (\n <DropZone\n aria-labelledby={props['aria-labelledby']}\n isDisabled={isDisabled}\n onDrop={async (e) => onSelect(await filesFrom(e))}\n className={cx('medo-dropzone', !!errorMessage && 'medo-dropzone--invalid', className)}\n >\n {({ isDropTarget }) => (\n <>\n <IconTile size=\"md\">\n <CloudUpload />\n </IconTile>\n <Text slot=\"label\" className=\"medo-dropzone__title\" aria-disabled={isDisabled || undefined}>\n {isDropTarget ? t.dropTitle : t.title}\n </Text>\n <AriaFileTrigger\n acceptedFileTypes={acceptedFileTypes}\n allowsMultiple={allowsMultiple}\n defaultCamera={defaultCamera}\n onSelect={(list) => list && onSelect([...list])}\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n isDisabled={isDisabled}\n className=\"medo-dropzone__button medo-upload__choose\"\n aria-describedby={[hint && hintId, errorMessage && errorId].filter(Boolean).join(' ') || undefined}\n >\n {allowsMultiple ? t.chooseFiles : t.chooseFile}\n </Button>\n </AriaFileTrigger>\n {hint && (\n <span id={hintId} className=\"medo-dropzone__hint\" aria-disabled={isDisabled || undefined}>\n {hint}\n </span>\n )}\n {errorMessage && (\n <span id={errorId} className=\"medo-field__error medo-dropzone__error\">\n <CircleAlert aria-hidden=\"true\" />\n <span>{errorMessage}</span>\n </span>\n )}\n </>\n )}\n </DropZone>\n );\n}\n\n/* ---------- File trigger (compact) ---------- */\n\nexport interface FileTriggerProps extends PickerProps {\n label?: ReactNode;\n /** Visual marker; check „at least one file“ on submit and pass `errorMessage`. */\n isRequired?: boolean;\n}\n\n/**\n * File trigger – compact upload for forms and mobile: label, Button secondary with\n * upload icon, hint, error. The system picker offers camera, photos and files on touch devices.\n */\nexport function FileTrigger({\n label,\n isRequired,\n acceptedFileTypes,\n allowsMultiple = true,\n defaultCamera,\n isDisabled,\n hint,\n errorMessage,\n onSelect,\n texts: own,\n className,\n}: FileTriggerProps) {\n const t = { ...defaultUploadTexts, ...own };\n const labelId = useId();\n const buttonId = useId();\n const hintId = useId();\n const errorId = useId();\n return (\n <div className={cx('medo-field', 'medo-file-trigger', className)}>\n {label && (\n <span id={labelId} className=\"medo-field__label\">\n {label}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n <div>\n <AriaFileTrigger\n acceptedFileTypes={acceptedFileTypes}\n allowsMultiple={allowsMultiple}\n defaultCamera={defaultCamera}\n onSelect={(list) => list && onSelect([...list])}\n >\n <Button\n id={buttonId}\n variant=\"secondary\"\n startIcon={<Upload />}\n isDisabled={isDisabled}\n className=\"medo-upload__choose\"\n aria-labelledby={label ? `${labelId} ${buttonId}` : undefined}\n aria-describedby={[hint && hintId, errorMessage && errorId].filter(Boolean).join(' ') || undefined}\n >\n {allowsMultiple ? t.chooseFiles : t.chooseFile}\n </Button>\n </AriaFileTrigger>\n </div>\n {(hint || errorMessage) && (\n <div className=\"medo-field__footer\">\n {hint && !errorMessage && (\n <span id={hintId} className=\"medo-field__description\">\n {hint}\n </span>\n )}\n {errorMessage && (\n <span id={errorId} className=\"medo-field__error\">\n <CircleAlert aria-hidden=\"true\" />\n <span>{errorMessage}</span>\n </span>\n )}\n </div>\n )}\n </div>\n );\n}\n\n/* ---------- Upload field (composition) ---------- */\n\nexport interface UploadFieldProps extends Omit<ItemActions, 'texts'> {\n /** Visible label. Without it set `aria-label`. */\n label?: ReactNode;\n 'aria-label'?: string;\n /** The files – controlled. The app uploads them (fetch, S3, tus …) and updates status and `loaded`. */\n files: UploadFile[];\n /** Files that passed type, size and count. Start the upload right away. */\n onAdd: (files: File[]) => void;\n /**\n * auto: Dropzone + list, below 640 px the File trigger (default) · list · compact (File trigger + list, forms) ·\n * grid (images only: tiles; below 640 px with the File trigger).\n */\n layout?: 'auto' | 'list' | 'compact' | 'grid';\n acceptedFileTypes?: string[];\n /** Readable form of the types for hint and message („PDF, JPG or PNG“). */\n typesLabel?: string;\n /** Max size per file in bytes. */\n maxSize?: number;\n /** Max number of files. 1 = single file picker. */\n maxFiles?: number;\n defaultCamera?: 'user' | 'environment';\n /** Default: „{typesLabel} · max. {maxSize} each“. */\n hint?: ReactNode;\n /** Field error from the app (e.g. required on submit). Wins over the built-in validation message. */\n errorMessage?: ReactNode;\n isRequired?: boolean;\n isDisabled?: boolean;\n texts?: Partial<UploadTexts>;\n className?: string;\n}\n\n/**\n * Upload field – ready composition. Checks type, size and count in the browser\n * before anything is uploaded (check again on the server). Rejected types and too many files show at the\n * picker, too large files as an error row – removable. Results are announced in a polite live region.\n */\nexport function UploadField({\n label,\n 'aria-label': ariaLabel,\n files,\n onAdd,\n onRemove,\n onCancel,\n onRetry,\n layout = 'auto',\n acceptedFileTypes,\n typesLabel,\n maxSize,\n maxFiles,\n defaultCamera,\n hint,\n errorMessage,\n isRequired,\n isDisabled,\n texts: own,\n className,\n}: UploadFieldProps) {\n const t = useMemo(() => ({ ...defaultUploadTexts, ...own }), [own]);\n const { locale } = useLocale();\n const mobile = useMediaQuery(MOBILE_QUERY);\n const labelId = useId();\n const rootRef = useRef<HTMLDivElement>(null);\n const [rejected, setRejected] = useState<UploadFile[]>([]);\n const [pickerError, setPickerError] = useState<string>();\n const [announcement, setAnnouncement] = useState('');\n\n const compact = layout === 'compact' || (layout !== 'list' && mobile);\n const grid = layout === 'grid';\n const allowsMultiple = maxFiles !== 1;\n const maxLabel = maxSize ? formatBytes(maxSize, locale) : undefined;\n const shownHint = hint ?? ([typesLabel, maxLabel && `max. ${maxLabel}${allowsMultiple ? ' each' : ''}`].filter(Boolean).join(' · ') || undefined);\n\n const add = (picked: File[]) => {\n const wrongType = picked.filter((f) => !isAccepted(f, acceptedFileTypes));\n let ok = picked.filter((f) => isAccepted(f, acceptedFileTypes));\n const tooLarge = maxSize ? ok.filter((f) => f.size > maxSize) : [];\n ok = ok.filter((f) => !tooLarge.includes(f));\n const messages: string[] = [];\n if (wrongType.length) messages.push(t.typeNotAllowed(wrongType.map((f) => `“${f.name}”`).join(', '), typesLabel ?? ''));\n if (maxFiles && files.length + ok.length > maxFiles) {\n ok = ok.slice(0, Math.max(0, maxFiles - files.length));\n messages.push(t.tooMany(maxFiles));\n }\n const errors = tooLarge.map<UploadFile>((f) => ({\n id: `rejected-${f.name}-${f.size}-${f.lastModified}`,\n name: f.name,\n size: f.size,\n type: f.type,\n status: 'error',\n error: t.tooLarge(formatBytes(f.size, locale), maxLabel ?? ''),\n canRetry: false,\n }));\n setRejected((r) => [...r.filter((x) => !errors.some((e) => e.id === x.id)), ...errors]);\n setPickerError(messages.join(' ') || undefined);\n setAnnouncement([...messages, ...errors.map((e) => t.failed(e.name, e.error!))].join(' '));\n if (ok.length) onAdd(ok);\n };\n\n // Announce finished and failed uploads once (the bar itself is not live, so progress never chatters).\n const previous = useRef(new Map<string, UploadFile['status']>());\n useEffect(() => {\n const said: string[] = [];\n for (const f of files) {\n const before = previous.current.get(f.id);\n if (before === f.status) continue;\n if (f.status === 'done' && before) said.push(t.uploaded(f.name));\n if (f.status === 'error' && f.error) said.push(t.failed(f.name, f.error));\n }\n previous.current = new Map(files.map((f) => [f.id, f.status]));\n if (said.length) setAnnouncement(said.join(' '));\n }, [files, t]);\n\n // Removing a file must not lose focus: move it to the same position in the list, else to the picker.\n const focusAt = useRef<number | null>(null);\n const all = [...files, ...rejected];\n useLayoutEffect(() => {\n if (focusAt.current == null) return;\n const items = rootRef.current?.querySelectorAll<HTMLElement>('.medo-upload__item');\n const target = items?.length\n ? items[Math.min(focusAt.current, items.length - 1)].querySelector<HTMLElement>('button')\n : rootRef.current?.querySelector<HTMLElement>('.medo-upload__choose');\n focusAt.current = null;\n target?.focus();\n });\n const remember = (id: string) => (focusAt.current = all.findIndex((f) => f.id === id));\n const actions = {\n texts: own,\n onRetry,\n onCancel: (id: string) => {\n remember(id);\n (onCancel ?? onRemove)(id);\n },\n onRemove: (id: string) => {\n remember(id);\n if (rejected.some((r) => r.id === id)) setRejected((r) => r.filter((x) => x.id !== id));\n else onRemove(id);\n },\n };\n\n const picker = { acceptedFileTypes, allowsMultiple, defaultCamera, isDisabled, hint: shownHint, errorMessage: errorMessage ?? pickerError, onSelect: add, texts: own };\n\n return (\n <div\n ref={rootRef}\n role={compact ? undefined : 'group'}\n aria-labelledby={label && !compact ? labelId : undefined}\n aria-label={label || compact ? undefined : ariaLabel}\n className={cx('medo-upload', grid && 'medo-upload--grid', compact && 'medo-upload--compact', className)}\n >\n {compact ? (\n <FileTrigger {...picker} label={label} isRequired={isRequired} />\n ) : (\n <>\n {label && (\n <span id={labelId} className=\"medo-field__label\">\n {label}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n <Dropzone {...picker} aria-labelledby={label ? labelId : undefined} />\n </>\n )}\n {all.length > 0 && (\n <ul className={cx('medo-upload__list', grid && 'medo-upload__list--grid')} aria-label={t.listLabel}>\n {all.map((file) => (\n <li key={file.id} className=\"medo-upload__item\">\n {grid ? <FileTile file={file} {...actions} /> : <FileItem file={file} {...actions} />}\n </li>\n ))}\n </ul>\n )}\n <span role=\"status\" className=\"medo-visually-hidden\">\n {announcement}\n </span>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Button as AriaButton,\n Calendar as AriaCalendar,\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeaderCell,\n RangeCalendar as AriaRangeCalendar,\n useLocale,\n type CalendarProps as AriaCalendarProps,\n type DateValue,\n type RangeCalendarProps as AriaRangeCalendarProps,\n} from 'react-aria-components';\nimport { DateFormatter, getDayOfWeek, getLocalTimeZone, today, type CalendarDate } from '@internationalized/date';\nimport { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport './date-time.css';\n\ntype View = 'days' | 'months' | 'years';\n\n/** The part of the React Aria calendar state the header and period grids need. */\ninterface ViewState {\n focusedDate: CalendarDate;\n setFocusedDate: (date: CalendarDate) => void;\n minValue?: DateValue | null;\n maxValue?: DateValue | null;\n value?: DateValue | null;\n isDisabled: boolean;\n}\n\nexport interface CalendarTexts {\n previousMonth: string;\n nextMonth: string;\n previousYear: string;\n nextYear: string;\n previousYears: string;\n nextYears: string;\n /** Name of the month-and-year button: „October 2026 – choose month and year“. */\n chooseMonth: (title: string) => string;\n chooseYear: (year: string) => string;\n weekNumber: string;\n}\n\nexport const defaultCalendarTexts: CalendarTexts = {\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n previousYear: 'Previous year',\n nextYear: 'Next year',\n previousYears: 'Previous years',\n nextYears: 'Next years',\n chooseMonth: (title) => `${title} – choose month and year`,\n chooseYear: (year) => `${year} – choose year`,\n weekNumber: 'Wk',\n};\n\ninterface SharedProps {\n /** md: 40 px days for desktop popovers · lg: 48 px for touch (Bottom Sheet). */\n size?: 'md' | 'lg';\n /** ISO week numbers (KW) before each row. */\n showWeekNumbers?: boolean;\n texts?: Partial<CalendarTexts>;\n className?: string;\n}\n\n/** ISO 8601 week of the row: the week of its 4th day, so it fits Monday- and Sunday-first locales. */\nfunction isoWeek(date: CalendarDate) {\n const d = new Date(Date.UTC(date.year, date.month - 1, date.day));\n const day = d.getUTCDay() || 7;\n d.setUTCDate(d.getUTCDate() + 4 - day);\n const yearStart = Date.UTC(d.getUTCFullYear(), 0, 1);\n return Math.ceil(((d.getTime() - yearStart) / 86400000 + 1) / 7);\n}\n\n/* ---------- Header ---------- */\n\nfunction Header({\n view,\n setView,\n state,\n size,\n months,\n t,\n}: {\n view: View;\n setView: (v: View) => void;\n state: ViewState;\n size: 'md' | 'lg';\n months: number;\n t: CalendarTexts;\n}) {\n const { locale } = useLocale();\n const monthTitle = useMemo(() => new DateFormatter(locale, { month: 'long', year: 'numeric', timeZone: getLocalTimeZone() }), [locale]);\n const yearTitle = useMemo(() => new DateFormatter(locale, { year: 'numeric', timeZone: getLocalTimeZone() }), [locale]);\n const tz = getLocalTimeZone();\n const focused = state.focusedDate;\n const buttonSize = size === 'lg' ? 'lg' : 'sm';\n const yearStart = focused.year - 5;\n\n const shift = (step: 1 | -1) => state.setFocusedDate(focused.add(view === 'months' ? { years: step } : { years: 12 * step }));\n\n if (view !== 'days') {\n const title = view === 'months' ? yearTitle.format(focused.toDate(tz)) : `${yearStart} – ${yearStart + 11}`;\n return (\n <div className=\"medo-calendar__header\">\n {view === 'months' ? (\n <Button\n slot={null}\n variant=\"ghost\"\n size={buttonSize}\n endIcon={<ChevronDown />}\n onPress={() => setView('years')}\n aria-label={t.chooseYear(title)}\n className=\"medo-calendar__title\"\n >\n {title}\n </Button>\n ) : (\n <span className=\"medo-calendar__title medo-calendar__title--static\" aria-live=\"polite\">\n {title}\n </span>\n )}\n <div className=\"medo-calendar__nav\">\n <IconButton slot={null} size={buttonSize} icon={<ChevronLeft />} aria-label={view === 'months' ? t.previousYear : t.previousYears} onPress={() => shift(-1)} />\n <IconButton slot={null} size={buttonSize} icon={<ChevronRight />} aria-label={view === 'months' ? t.nextYear : t.nextYears} onPress={() => shift(1)} />\n </div>\n </div>\n );\n }\n\n // Days: one header per month; with two months the arrows sit at the outer edges.\n return (\n <div className=\"medo-calendar__headers\" style={{ gridTemplateColumns: `repeat(${months}, 1fr)` }}>\n {Array.from({ length: months }, (_, i) => {\n const title = monthTitle.format(focused.add({ months: i }).toDate(tz));\n return (\n <div key={i} className=\"medo-calendar__header\">\n <Button\n slot={null}\n variant=\"ghost\"\n size={buttonSize}\n endIcon={<ChevronDown />}\n onPress={() => setView('months')}\n aria-label={t.chooseMonth(title)}\n className=\"medo-calendar__title\"\n >\n {title}\n </Button>\n <div className=\"medo-calendar__nav\">\n {i === 0 && <IconButton slot=\"previous\" size={buttonSize} icon={<ChevronLeft />} aria-label={t.previousMonth} />}\n {i === months - 1 && <IconButton slot=\"next\" size={buttonSize} icon={<ChevronRight />} aria-label={t.nextMonth} />}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n/* ---------- Months · Years ---------- */\n\nfunction PeriodGrid({ view, setView, state }: { view: 'months' | 'years'; setView: (v: View) => void; state: ViewState }) {\n const { locale } = useLocale();\n const tz = getLocalTimeZone();\n const format = useMemo(() => new DateFormatter(locale, { month: 'short', timeZone: tz }), [locale, tz]);\n const focused = state.focusedDate;\n const now = today(tz);\n const ref = useRef<HTMLDivElement>(null);\n const yearStart = focused.year - 5;\n\n const items = Array.from({ length: 12 }, (_, i) => {\n const date = view === 'months' ? focused.set({ month: i + 1, day: 1 }) : focused.set({ year: yearStart + i, month: 1, day: 1 });\n const last = view === 'months' ? date.add({ months: 1 }).subtract({ days: 1 }) : date.add({ years: 1 }).subtract({ days: 1 });\n const outside = (!!state.minValue && last.compare(state.minValue) < 0) || (!!state.maxValue && date.compare(state.maxValue) > 0);\n const same = (d?: DateValue | null) => !!d && d.year === date.year && (view === 'years' || d.month === date.month);\n return {\n key: `${date.year}-${date.month}`,\n label: view === 'months' ? format.format(date.toDate(tz)) : String(date.year),\n isCurrent: same(now),\n isSelected: same(state.value),\n isFocused: view === 'months' ? date.month === focused.month : date.year === focused.year,\n isDisabled: state.isDisabled || outside,\n pick: () => {\n // set() keeps the day where possible and constrains it (31 → 28 in February).\n state.setFocusedDate(view === 'months' ? focused.set({ month: i + 1 }) : focused.set({ year: yearStart + i }));\n setView(view === 'months' ? 'days' : 'months');\n },\n };\n });\n\n // Keep the keyboard where it was: focus the month/year that matches the focused date.\n useEffect(() => {\n ref.current?.querySelector<HTMLElement>('[data-focus-target]')?.focus();\n }, [view]);\n\n return (\n <div ref={ref} className=\"medo-calendar__periods\" role=\"group\">\n {items.map((item) => (\n <AriaButton\n key={item.key}\n slot={null}\n className=\"medo-calendar__period\"\n isDisabled={item.isDisabled}\n onPress={item.pick}\n aria-pressed={item.isSelected}\n aria-current={item.isCurrent ? 'date' : undefined}\n data-current={item.isCurrent || undefined}\n data-selected={item.isSelected || undefined}\n data-focus-target={item.isFocused || undefined}\n >\n {item.label}\n </AriaButton>\n ))}\n </div>\n );\n}\n\n/* ---------- Day grid ---------- */\n\nfunction DayGrid({ offset, showWeekNumbers, t }: { offset: number; showWeekNumbers?: boolean; t: CalendarTexts }) {\n const { locale } = useLocale();\n return (\n <div className={cx('medo-calendar__month', showWeekNumbers && 'medo-calendar__month--weeks')}>\n {showWeekNumbers && (\n <span className=\"medo-calendar__weeks-label\" aria-hidden=\"true\">\n {t.weekNumber}\n </span>\n )}\n <CalendarGrid offset={offset ? { months: offset } : undefined} weekdayStyle=\"short\" className=\"medo-calendar__grid\">\n <CalendarGridHeader>\n {(day) => <CalendarHeaderCell className=\"medo-calendar__weekday\">{day.replace(/\\.$/, '').slice(0, 2)}</CalendarHeaderCell>}\n </CalendarGridHeader>\n <CalendarGridBody>\n {(date) => (\n <CalendarCell date={date} className=\"medo-calendar__cell\">\n {({ formattedDate }) => (\n // The week number is drawn by CSS (data-week), so it is not part of the day's visible name (WCAG 2.5.3).\n <span className=\"medo-calendar__day\" data-week={showWeekNumbers && getDayOfWeek(date, locale) === 0 ? isoWeek(date.add({ days: 3 })) : undefined}>\n {formattedDate}\n </span>\n )}\n </CalendarCell>\n )}\n </CalendarGridBody>\n </CalendarGrid>\n </div>\n );\n}\n\n/* ---------- Body shared by Calendar and RangeCalendar ---------- */\n\nfunction CalendarBody({ state, size, months, showWeekNumbers, t }: { state: ViewState; size: 'md' | 'lg'; months: number; showWeekNumbers?: boolean; t: CalendarTexts }) {\n const [view, setView] = useState<View>('days');\n const ref = useRef<HTMLDivElement>(null);\n const back = useRef(false);\n\n // Back from the month grid: the focused day takes the focus again.\n useEffect(() => {\n if (view !== 'days' || !back.current) return;\n back.current = false;\n ref.current?.querySelector<HTMLElement>('.medo-calendar__cell[tabindex=\"0\"]')?.focus();\n }, [view]);\n\n const changeView = (v: View) => {\n back.current = v === 'days';\n setView(v);\n };\n\n return (\n <div ref={ref} className=\"medo-calendar__body\">\n <Header view={view} setView={changeView} state={state} size={size} months={view === 'days' ? months : 1} t={t} />\n {view === 'days' ? (\n <div className=\"medo-calendar__months\" style={{ gridTemplateColumns: `repeat(${months}, auto)` }}>\n {Array.from({ length: months }, (_, i) => (\n <DayGrid key={i} offset={i} showWeekNumbers={showWeekNumbers} t={t} />\n ))}\n </div>\n ) : (\n <PeriodGrid view={view} setView={changeView} state={state} />\n )}\n </div>\n );\n}\n\n/* ---------- Calendar ---------- */\n\nexport interface CalendarProps<T extends DateValue> extends Omit<AriaCalendarProps<T>, 'children' | 'className' | 'style' | 'visibleDuration'>, SharedProps {}\n\n/**\n * Calendar – pick a day. React Aria Calendar: a grid with arrow keys (day/week),\n * Page Up/Down (month), Shift + Page Up/Down (year), Home/End. The month-and-year button switches to a month\n * grid, then a year grid – far dates in three clicks. Weekdays and the first day of the week from the locale.\n */\nexport function Calendar<T extends DateValue>({ size = 'md', showWeekNumbers, texts, className, ...props }: CalendarProps<T>) {\n const t = { ...defaultCalendarTexts, ...texts };\n return (\n <AriaCalendar<T> {...props} className={cx('medo-calendar', `medo-calendar--${size}`, className)}>\n {({ state }) => <CalendarBody state={state} size={size} months={1} showWeekNumbers={showWeekNumbers} t={t} />}\n </AriaCalendar>\n );\n}\n\n/* ---------- Range calendar ---------- */\n\nexport interface RangeCalendarProps<T extends DateValue> extends Omit<AriaRangeCalendarProps<T>, 'children' | 'className' | 'style' | 'visibleDuration'>, SharedProps {\n /** auto: two months on desktop, one below 640 px. */\n visibleMonths?: 'auto' | 1 | 2;\n}\n\n/**\n * Range calendar – pick a start and an end day. The first click sets the\n * start, the second the end; hovering previews the range. Two months side by side on desktop, one on mobile.\n */\nexport function RangeCalendar<T extends DateValue>({ size = 'md', showWeekNumbers, visibleMonths = 'auto', texts, className, ...props }: RangeCalendarProps<T>) {\n const t = { ...defaultCalendarTexts, ...texts };\n const mobile = useMediaQuery(MOBILE_QUERY);\n const months = visibleMonths === 'auto' ? (mobile ? 1 : 2) : visibleMonths;\n return (\n <AriaRangeCalendar<T> {...props} visibleDuration={{ months }} className={cx('medo-calendar', 'medo-calendar--range', `medo-calendar--${size}`, className)}>\n {({ state }) => (\n <CalendarBody\n state={{\n focusedDate: state.focusedDate,\n setFocusedDate: state.setFocusedDate,\n minValue: state.minValue,\n maxValue: state.maxValue,\n value: state.value?.start ?? null,\n isDisabled: state.isDisabled,\n }}\n size={size}\n months={months}\n showWeekNumbers={showWeekNumbers}\n t={t}\n />\n )}\n </AriaRangeCalendar>\n );\n}\n","import { useMemo, useState, type ReactNode } from 'react';\nimport {\n DateField as AriaDateField,\n DateInput,\n DateSegment,\n TimeField as AriaTimeField,\n type DateFieldProps as AriaDateFieldProps,\n type DateValue,\n type TimeFieldProps as AriaTimeFieldProps,\n type TimeValue,\n type ValidationResult,\n useLocale,\n} from 'react-aria-components';\nimport { DateFormatter } from '@internationalized/date';\nimport { Clock } from 'lucide-react';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox, Option } from '../listbox/ListBox';\nimport { Popover, PopoverTrigger } from '../popover/Popover';\nimport { InputAction } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport '../text-field/input.css';\nimport './date-time.css';\n\n/**\n * The segments inside the Input look. Digits only; a complete segment jumps to the next one. Separators come\n * from the locale (de: TT.MM.JJJJ, 24 h) and are never typed. Styles: `medo-date-box`, `medo-date-segment`.\n */\nexport function DateSegments({ size = 'md', children }: { size?: 'md' | 'lg'; children?: ReactNode }) {\n return (\n <div className={cx('medo-input', `medo-input--${size}`, 'medo-date-box')}>\n <DateInput className=\"medo-date-input\">{(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}</DateInput>\n {children}\n </div>\n );\n}\n\ninterface FieldBase {\n /** Visible label. Without it set `aria-label`. */\n label?: ReactNode;\n description?: ReactNode;\n /** A function gets the validation details (rangeUnderflow, rangeOverflow, badInput) – name the rule. */\n errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);\n /** md 40 (desktop) · lg 48 (touch, below 640 px). */\n size?: 'md' | 'lg';\n className?: string;\n}\n\n/* ---------- Date field ---------- */\n\nexport interface DateFieldProps<T extends DateValue> extends Omit<AriaDateFieldProps<T>, 'children' | 'className' | 'style'>, FieldBase {}\n\n/**\n * Date field – type a date without a calendar. React Aria DateField: every segment is a\n * spinbutton („day“, „month“, „year“), ↑ ↓ change it, ← → move, Backspace clears, a pasted date fills all.\n * `granularity=\"minute\"` adds the time. For a calendar use DatePicker.\n */\nexport function DateField<T extends DateValue>({ label, description, errorMessage, size = 'md', className, ...props }: DateFieldProps<T>) {\n return (\n <AriaDateField<T> shouldForceLeadingZeros {...props} className={cx('medo-field', 'medo-date-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <DateSegments size={size} />\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaDateField>\n );\n}\n\n/* ---------- Time field ---------- */\n\nexport interface TimeSlot {\n value: TimeValue;\n /** Booked slots stay visible, disabled, with the reason („Booked“). */\n isDisabled?: boolean;\n reason?: string;\n}\n\nexport interface TimeFieldProps extends Omit<AriaTimeFieldProps<TimeValue>, 'children' | 'className' | 'style'>, FieldBase {\n /** Optional fixed times (e.g. every 15 min). Adds a clock button that opens them. No clock faces. */\n slots?: TimeSlot[];\n /** Name of the clock button and the list. */\n slotsLabel?: string;\n}\n\n/**\n * Time field – type a time. HH:MM, 24 h in de – from the locale. Typing only;\n * with `slots` a clock button opens a list of fixed times (bookings), booked ones disabled with a reason.\n */\nexport function TimeField({\n label,\n description,\n errorMessage,\n size = 'md',\n slots,\n slotsLabel = 'Available times',\n className,\n defaultValue,\n onChange,\n ...props\n}: TimeFieldProps) {\n // Controlled inside, so a picked slot shows also when the app passes only defaultValue.\n const [inner, setInner] = useState<TimeValue | null>(defaultValue ?? null);\n const value = props.value !== undefined ? props.value : inner;\n const change = (v: TimeValue | null) => {\n setInner(v);\n onChange?.(v);\n };\n const { locale } = useLocale();\n const format = useMemo(\n () => new DateFormatter(locale, { hour: '2-digit', minute: '2-digit', hourCycle: props.hourCycle === 12 ? 'h12' : props.hourCycle === 24 ? 'h23' : undefined }),\n [locale, props.hourCycle],\n );\n const key = (v?: TimeValue | null) => (v ? `${v.hour}:${v.minute}` : '');\n const text = (v: TimeValue) => format.format(new Date(2000, 0, 1, v.hour, v.minute));\n return (\n <AriaTimeField shouldForceLeadingZeros {...props} value={value} onChange={change} className={cx('medo-field', 'medo-date-field', 'medo-time-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <DateSegments size={size}>\n {slots && (\n <PopoverTrigger>\n <InputAction icon={<Clock />} aria-label={slotsLabel} isDisabled={props.isDisabled || props.isReadOnly} />\n <Popover size=\"auto\" aria-label={slotsLabel} placement=\"bottom end\" className=\"medo-time-slots\">\n {(close) => (\n <ListBox\n aria-label={slotsLabel}\n size={size}\n autoFocus\n selectionMode=\"single\"\n selectedKeys={value ? [key(value)] : []}\n disabledKeys={slots.filter((s) => s.isDisabled).map((s) => key(s.value))}\n onSelectionChange={(keys) => {\n const slot = slots.find((s) => keys !== 'all' && keys.has(key(s.value)));\n if (slot) change(slot.value);\n close();\n }}\n >\n {slots.map((s) => (\n <Option key={key(s.value)} id={key(s.value)} textValue={text(s.value)} description={s.isDisabled ? s.reason : undefined}>\n {text(s.value)}\n </Option>\n ))}\n </ListBox>\n )}\n </Popover>\n </PopoverTrigger>\n )}\n </DateSegments>\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaTimeField>\n );\n}\n","import { useContext, useMemo, type ReactNode } from 'react';\nimport {\n DateInput,\n DatePicker as AriaDatePicker,\n DatePickerStateContext,\n DateRangePicker as AriaDateRangePicker,\n DateRangePickerStateContext,\n DateSegment,\n Dialog as AriaDialog,\n Group,\n Popover as AriaPopover,\n useLocale,\n type DatePickerProps as AriaDatePickerProps,\n type DateRangePickerProps as AriaDateRangePickerProps,\n type DateValue,\n type ValidationResult,\n} from 'react-aria-components';\nimport { DateFormatter, endOfMonth, getLocalTimeZone, startOfMonth, today, type CalendarDate } from '@internationalized/date';\nimport { Calendar as CalendarIcon } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button } from '../button/Button';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox, Option } from '../listbox/ListBox';\nimport { InputAction } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { Calendar, defaultCalendarTexts, RangeCalendar, type CalendarTexts } from './Calendar';\nimport { TimeField } from './DateField';\nimport '../popover/popover.css';\nimport '../text-field/input.css';\nimport './date-time.css';\n\nexport interface DatePickerTexts extends CalendarTexts {\n openCalendar: string;\n done: string;\n time: string;\n presets: string;\n /** Validation – name the rule, never just „invalid date“. */\n beforeMin: (date: string) => string;\n afterMax: (date: string) => string;\n unavailable: string;\n reversed: string;\n}\n\nexport const defaultDatePickerTexts: Omit<DatePickerTexts, keyof CalendarTexts> = {\n openCalendar: 'Open calendar',\n done: 'Done',\n time: 'Time',\n presets: 'Periods',\n beforeMin: (date) => `Choose a date from ${date} on.`,\n afterMax: (date) => `Choose a date until ${date}.`,\n unavailable: 'This day is not available. Choose another day.',\n reversed: 'The end date must be after the start date.',\n};\n\ninterface PickerBase {\n label?: ReactNode;\n description?: ReactNode;\n /** Own message or a function of the validation details. Default: the built-in messages (min, max, unavailable, reversed). */\n errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);\n /** md 40 (desktop) · lg 48 (touch). */\n size?: 'md' | 'lg';\n /** auto: popover on desktop, Bottom Sheet with a lg calendar below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n /** ISO week numbers in the calendar. */\n showWeekNumbers?: boolean;\n texts?: Partial<DatePickerTexts>;\n className?: string;\n}\n\n/** Messages that name the rule. Unavailable days: pass `texts.unavailable` with the reason („We don’t deliver on weekends.“). */\nfunction useMessages(t: DatePickerTexts, minValue?: DateValue | null, maxValue?: DateValue | null) {\n const { locale } = useLocale();\n const format = useMemo(() => new DateFormatter(locale, { day: '2-digit', month: '2-digit', year: 'numeric', timeZone: getLocalTimeZone() }), [locale]);\n const show = (d: DateValue) => format.format(d.toDate(getLocalTimeZone()));\n return ({ validationDetails: v, validationErrors }: ValidationResult) => {\n if (v.rangeUnderflow && v.rangeOverflow) return t.reversed;\n if (v.rangeUnderflow && minValue) return t.beforeMin(show(minValue));\n if (v.rangeOverflow && maxValue) return t.afterMax(show(maxValue));\n if (v.badInput) return t.unavailable;\n return validationErrors.join(' ');\n };\n}\n\n/** Popover on desktop (Popover Size Auto), Bottom Sheet with „Done“ on mobile. */\nfunction PickerOverlay({ title, sheet, t, children }: { title: string; sheet: boolean; t: DatePickerTexts; children: ReactNode }) {\n if (sheet) {\n return (\n <BottomSheet\n title={title}\n className=\"medo-date-sheet\"\n footer={(close) => (\n <Button variant=\"primary\" size=\"lg\" onPress={close}>\n {t.done}\n </Button>\n )}\n >\n <div className=\"medo-date-panel\">{children}</div>\n </BottomSheet>\n );\n }\n return (\n <AriaPopover placement=\"bottom start\" offset={8} containerPadding={16} className=\"medo-popover medo-popover--auto medo-date-popover\">\n <AriaDialog aria-label={title} className=\"medo-popover__dialog\">\n <div className=\"medo-popover__body medo-date-panel\">{children}</div>\n </AriaDialog>\n </AriaPopover>\n );\n}\n\n/** Date + time picker: the time of the picker's value, typed (no clock faces). */\nfunction PanelTime({ label, size }: { label: string; size: 'md' | 'lg' }) {\n const state = useContext(DatePickerStateContext);\n if (!state) return null;\n return (\n <div className=\"medo-date-panel__time\">\n <TimeField label={label} size={size} value={state.timeValue} onChange={(v) => v && state.setTimeValue(v)} />\n </div>\n );\n}\n\nconst textOf = (label: ReactNode, ariaLabel?: string) => (typeof label === 'string' ? label : (ariaLabel ?? ''));\n\n/* ---------- Date picker ---------- */\n\nexport interface DatePickerProps<T extends DateValue> extends Omit<AriaDatePickerProps<T>, 'children' | 'className' | 'style'>, PickerBase {}\n\n/**\n * Date picker – type a date or pick it. The field is the main input, the calendar is a\n * helper: the button „Open calendar“ (or Alt + ↓) opens it, picking a day closes it and focus returns to the\n * field. `granularity=\"minute\"` makes it a date + time picker with a time field in the panel.\n */\nexport function DatePicker<T extends DateValue>({\n label,\n description,\n errorMessage,\n size = 'md',\n overlay = 'auto',\n showWeekNumbers,\n texts,\n className,\n ...props\n}: DatePickerProps<T>) {\n const t: DatePickerTexts = { ...defaultCalendarTexts, ...defaultDatePickerTexts, ...texts };\n const mobile = useMediaQuery(MOBILE_QUERY);\n const sheet = overlay === 'sheet' || (overlay === 'auto' && mobile);\n const messages = useMessages(t, props.minValue, props.maxValue);\n const hasTime = !!props.granularity && props.granularity !== 'day';\n\n return (\n <AriaDatePicker<T>\n shouldForceLeadingZeros\n {...props}\n className={cx('medo-field', 'medo-date-field', 'medo-date-picker', hasTime && 'medo-date-picker--time', className)}\n >\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <Group className={cx('medo-input', `medo-input--${size}`, 'medo-date-box')}>\n <DateInput className=\"medo-date-input\">{(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}</DateInput>\n <InputAction icon={<CalendarIcon />} aria-label={t.openCalendar} />\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage ?? messages} />\n <PickerOverlay title={textOf(label, props['aria-label'])} sheet={sheet} t={t}>\n <Calendar size={sheet ? 'lg' : 'md'} showWeekNumbers={showWeekNumbers} texts={t} />\n {hasTime && <PanelTime label={t.time} size={sheet ? 'lg' : 'md'} />}\n </PickerOverlay>\n </AriaDatePicker>\n );\n}\n\n/* ---------- Date range picker ---------- */\n\nexport interface DateRangePreset {\n label: string;\n value: { start: DateValue; end: DateValue };\n}\n\n/** The default presets (Today … Last month), relative to today in the local time zone. */\nexport function defaultDatePresets(\n labels: Partial<Record<'today' | 'yesterday' | 'last7' | 'last14' | 'last30' | 'thisMonth' | 'lastMonth', string>> = {},\n): DateRangePreset[] {\n const now: CalendarDate = today(getLocalTimeZone());\n const lastMonth = now.subtract({ months: 1 });\n return [\n { label: labels.today ?? 'Today', value: { start: now, end: now } },\n { label: labels.yesterday ?? 'Yesterday', value: { start: now.subtract({ days: 1 }), end: now.subtract({ days: 1 }) } },\n { label: labels.last7 ?? 'Last 7 days', value: { start: now.subtract({ days: 6 }), end: now } },\n { label: labels.last14 ?? 'Last 14 days', value: { start: now.subtract({ days: 13 }), end: now } },\n { label: labels.last30 ?? 'Last 30 days', value: { start: now.subtract({ days: 29 }), end: now } },\n { label: labels.thisMonth ?? 'This month', value: { start: startOfMonth(now), end: now } },\n { label: labels.lastMonth ?? 'Last month', value: { start: startOfMonth(lastMonth), end: endOfMonth(lastMonth) } },\n ];\n}\n\nfunction Presets({ presets, label, size }: { presets: DateRangePreset[]; label: string; size: 'md' | 'lg' }) {\n const state = useContext(DateRangePickerStateContext);\n if (!state) return null;\n const same = (a?: DateValue | null, b?: DateValue | null) => !!a && !!b && a.compare(b) === 0;\n const active = presets.findIndex((p) => same(state.value?.start, p.value.start) && same(state.value?.end, p.value.end));\n return (\n <ListBox\n aria-label={label}\n size={size}\n selectionMode=\"single\"\n selectedKeys={active >= 0 ? [String(active)] : []}\n disallowEmptySelection={false}\n onAction={(key) => {\n const preset = presets[Number(key)];\n state.setValue(preset.value);\n state.close();\n }}\n className=\"medo-date-panel__presets\"\n >\n {presets.map((p, i) => (\n <Option key={i} id={String(i)}>\n {p.label}\n </Option>\n ))}\n </ListBox>\n );\n}\n\nexport interface DateRangePickerProps<T extends DateValue> extends Omit<AriaDateRangePickerProps<T>, 'children' | 'className' | 'style'>, PickerBase {\n /** true: the default presets (Today … Last month) · own list · none. Fits dashboards and filters. */\n presets?: boolean | DateRangePreset[];\n}\n\n/**\n * Date range picker – start and end in one field. Two months side by side on desktop,\n * one on mobile; the first click sets the start, the second the end, hovering previews the range. Optional presets.\n */\nexport function DateRangePicker<T extends DateValue>({\n label,\n description,\n errorMessage,\n size = 'md',\n overlay = 'auto',\n showWeekNumbers,\n presets,\n texts,\n className,\n ...props\n}: DateRangePickerProps<T>) {\n const t: DatePickerTexts = { ...defaultCalendarTexts, ...defaultDatePickerTexts, ...texts };\n const mobile = useMediaQuery(MOBILE_QUERY);\n const sheet = overlay === 'sheet' || (overlay === 'auto' && mobile);\n const messages = useMessages(t, props.minValue, props.maxValue);\n const list = presets === true ? defaultDatePresets() : presets || undefined;\n\n return (\n <AriaDateRangePicker<T> shouldForceLeadingZeros {...props} className={cx('medo-field', 'medo-date-field', 'medo-date-picker', 'medo-date-picker--range', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <Group className={cx('medo-input', `medo-input--${size}`, 'medo-date-box')}>\n <DateInput slot=\"start\" className=\"medo-date-input\">\n {(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}\n </DateInput>\n <span className=\"medo-date-box__dash\" aria-hidden=\"true\">\n –\n </span>\n <DateInput slot=\"end\" className=\"medo-date-input\">\n {(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}\n </DateInput>\n <InputAction icon={<CalendarIcon />} aria-label={t.openCalendar} />\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage ?? messages} />\n <PickerOverlay title={textOf(label, props['aria-label'])} sheet={sheet} t={t}>\n <div className={cx('medo-date-panel__range', !!list && 'medo-date-panel__range--presets')}>\n {list && <Presets presets={list} label={t.presets} size={sheet ? 'lg' : 'md'} />}\n <RangeCalendar size={sheet ? 'lg' : 'md'} visibleMonths={sheet ? 1 : 2} showWeekNumbers={showWeekNumbers} texts={t} />\n </div>\n </PickerOverlay>\n </AriaDateRangePicker>\n );\n}\n","export { Button, ButtonGroup } from './button/Button';\nexport type { ButtonProps, ButtonGroupProps, ButtonSize, ButtonVariant } from './button/Button';\nexport { IconButton } from './icon-button/IconButton';\nexport type { IconButtonProps } from './icon-button/IconButton';\nexport { TextField, InputAction } from './text-field/TextField';\nexport type { TextFieldProps, InputActionProps, InputSize } from './text-field/TextField';\nexport { Checkbox, CheckboxGroup } from './checkbox/Checkbox';\nexport type { CheckboxProps, CheckboxGroupProps, ChoiceSize } from './checkbox/Checkbox';\nexport { Radio, RadioGroup } from './radio/Radio';\nexport type { RadioProps, RadioGroupProps } from './radio/Radio';\nexport { Switch } from './switch/Switch';\nexport type { SwitchProps } from './switch/Switch';\nexport { FieldLabel, FieldFooter } from './field/Field';\nexport { Badge, BadgeCount, BadgeDot } from './badge/Badge';\nexport type { BadgeProps, BadgeCountProps, BadgeDotProps, BadgeTone } from './badge/Badge';\nexport { Tag, TagGroup } from './tag/Tag';\nexport type { TagProps, TagGroupProps } from './tag/Tag';\nexport { Avatar, AvatarGroup, initialsOf } from './avatar/Avatar';\nexport type { AvatarProps, AvatarGroupProps, AvatarSize, AvatarStatus } from './avatar/Avatar';\nexport { Tooltip, TooltipTrigger } from './tooltip/Tooltip';\nexport type { TooltipProps } from './tooltip/Tooltip';\nexport { Spinner, ProgressBar, Skeleton } from './progress/Progress';\nexport type { SpinnerProps, ProgressBarProps, SkeletonProps } from './progress/Progress';\nexport { ToggleButton, ToggleButtonGroup, Toolbar, ToolbarSeparator } from './toggle-button/ToggleButton';\nexport type { ToggleButtonProps, ToggleButtonGroupProps, ToolbarProps } from './toggle-button/ToggleButton';\nexport { ListBox, Option, ListBoxSection, ListBoxMessage } from './listbox/ListBox';\nexport type { ListBoxProps, OptionProps, ListBoxSectionProps, ListBoxSize } from './listbox/ListBox';\nexport { Select } from './select/Select';\nexport type { SelectProps, SelectOverlay } from './select/Select';\nexport { BottomSheet } from './bottom-sheet/BottomSheet';\nexport { Menu, MenuButton, MenuItem, MenuSection, MenuTrigger, Submenu } from './menu/Menu';\nexport type { MenuProps, MenuItemProps, MenuSectionProps, MenuTriggerProps, SubmenuProps } from './menu/Menu';\nexport type { BottomSheetProps } from './bottom-sheet/BottomSheet';\nexport { Dialog, DialogTrigger, AlertDialog } from './dialog/Dialog';\nexport type { DialogProps, DialogAction, DialogDiscardText, AlertDialogProps, AlertDialogTone } from './dialog/Dialog';\nexport { Combobox } from './combobox/Combobox';\nexport type { ComboboxProps } from './combobox/Combobox';\nexport { ToastRegion, toast } from './toast/Toast';\nexport type { ToastRegionProps, ToastOptions, ToastAction } from './toast/Toast';\nexport { Tabs, TabList, Tab, TabPanel } from './tabs/Tabs';\nexport type { TabsProps, TabListProps, TabProps, TabPanelProps } from './tabs/Tabs';\nexport { Popover, PopoverTrigger, Toggletip } from './popover/Popover';\nexport type { PopoverProps, ToggletipProps } from './popover/Popover';\nexport {\n NavItem,\n NavGroup,\n NavSection,\n NavList,\n SkipLink,\n SiteHeader,\n AppHeader,\n SideNav,\n BottomTabBar,\n TabBarItem,\n TabBarMore,\n} from './navigation/Navigation';\nexport type {\n NavItemProps,\n NavGroupProps,\n NavSectionProps,\n NavListProps,\n NavVariant,\n NavAction,\n SkipLinkProps,\n SiteHeaderProps,\n AppHeaderProps,\n SideNavProps,\n SideNavUser,\n BottomTabBarProps,\n TabBarItemProps,\n TabBarMoreProps,\n} from './navigation/Navigation';\nexport { Drawer } from './drawer/Drawer';\nexport type { DrawerProps } from './drawer/Drawer';\nexport { List, ListItem, DescriptionList, DescriptionItem } from './list/List';\nexport type { ListProps, ListItemProps, ListType, DescriptionListProps, DescriptionItemProps } from './list/List';\nexport { ListView, ListRow, ListRowIcon, ListCard } from './list-view/ListView';\nexport type { ListViewProps, ListRowProps, ListCardProps } from './list-view/ListView';\nexport { BulkActionBar } from './bulk-action-bar/BulkActionBar';\nexport type { BulkActionBarProps, BulkAction } from './bulk-action-bar/BulkActionBar';\nexport { EmptyState } from './empty-state/EmptyState';\nexport type { EmptyStateProps, EmptyStateAction, EmptyStateType, EmptyStateSize } from './empty-state/EmptyState';\nexport { Pagination } from './pagination/Pagination';\nexport type { PaginationProps } from './pagination/Pagination';\nexport { SearchField } from './search/SearchField';\nexport type { SearchFieldProps } from './search/SearchField';\nexport { SearchResult } from './search/SearchResult';\nexport type { SearchResultProps, SearchResultType } from './search/SearchResult';\nexport { QuickSearch } from './search/QuickSearch';\nexport type { QuickSearchProps } from './search/QuickSearch';\nexport { Highlight } from './utils/highlight';\nexport { Breadcrumbs } from './breadcrumbs/Breadcrumbs';\nexport type { BreadcrumbsProps, BreadcrumbItem } from './breadcrumbs/Breadcrumbs';\nexport { Accordion, AccordionItem } from './accordion/Accordion';\nexport type { AccordionProps, AccordionItemProps } from './accordion/Accordion';\nexport { Slider, SliderField } from './slider/Slider';\nexport type { SliderProps, SliderFieldProps } from './slider/Slider';\nexport { NumberField } from './number-field/NumberField';\nexport type { NumberFieldProps } from './number-field/NumberField';\nexport { Link } from './link/Link';\nexport type { LinkProps } from './link/Link';\nexport { Alert } from './alert/Alert';\nexport type { AlertProps, AlertTone } from './alert/Alert';\nexport { Card } from './card/Card';\nexport type { CardProps } from './card/Card';\nexport { StaticTable, Table, TableHeader, Column, TableBody, Row, Cell } from './table/Table';\nexport type { StaticTableProps, TableProps, ColumnProps, CellProps } from './table/Table';\nexport { ColumnsMenu } from './table/ColumnsMenu';\nexport type { ColumnsMenuProps, ColumnOption } from './table/ColumnsMenu';\nexport { UploadField, Dropzone, FileTrigger, FileItem, FileTile, formatBytes, defaultUploadTexts } from './upload/Upload';\nexport type { UploadFieldProps, DropzoneProps, FileTriggerProps, FileItemProps, FileTileProps, UploadFile, UploadTexts } from './upload/Upload';\nexport { Calendar, RangeCalendar, defaultCalendarTexts } from './date-time/Calendar';\nexport type { CalendarProps, RangeCalendarProps, CalendarTexts } from './date-time/Calendar';\nexport { DateField, TimeField } from './date-time/DateField';\nexport type { DateFieldProps, TimeFieldProps, TimeSlot } from './date-time/DateField';\nexport { DatePicker, DateRangePicker, defaultDatePresets, defaultDatePickerTexts } from './date-time/DatePicker';\nexport type { DatePickerProps, DateRangePickerProps, DateRangePreset, DatePickerTexts } from './date-time/DatePicker';\n/** Date values (React Aria standard): parse ISO strings, today, time zones, weekend checks. */\nexport {\n CalendarDate,\n CalendarDateTime,\n Time,\n ZonedDateTime,\n parseDate,\n parseDateTime,\n parseTime,\n parseZonedDateTime,\n today,\n now,\n getLocalTimeZone,\n isWeekend,\n isToday,\n} from '@internationalized/date';\nexport type { DateValue, TimeValue } from 'react-aria-components';\nexport { Image, Figure, MediaPlayButton } from './media/Image';\nexport type { ImageProps, ImageRatio, FigureProps, MediaPlayButtonProps } from './media/Image';\nexport { EmbedConsent, defaultEmbedTexts } from './media/EmbedConsent';\nexport type { EmbedConsentProps, EmbedTexts, EmbedType } from './media/EmbedConsent';\n","import { useEffect, useLayoutEffect, useRef, useState, type CSSProperties, type ImgHTMLAttributes, type ReactNode } from 'react';\nimport { ImageOff, Play } from 'lucide-react';\nimport { Skeleton } from '../progress/Progress';\nimport { cx } from '../utils/cx';\nimport './media.css';\n\nexport type ImageRatio = '1:1' | '3:4' | '4:3' | '3:2' | '16:9' | '21:9' | 'original';\n\n/* ---------- Media play button ---------- */\n\nexport interface MediaPlayButtonProps {\n /** md 48 (cards, lists) · lg 64 (hero, player). */\n size?: 'md' | 'lg';\n className?: string;\n}\n\n/**\n * Media play button – marks video on a thumbnail. Visual only: the whole\n * thumbnail is the hit area (a link or button around it); hover, pressed and focus come from there.\n */\nexport function MediaPlayButton({ size = 'md', className }: MediaPlayButtonProps) {\n return (\n <span className={cx('medo-media-play', `medo-media-play--${size}`, className)} aria-hidden=\"true\">\n <Play />\n </span>\n );\n}\n\n/* ---------- Image ---------- */\n\nexport interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'alt' | 'src' | 'placeholder' | 'children' | 'className' | 'style'> {\n /** Without src the image stays in its loading state (e.g. while the URL is resolved). */\n src?: string;\n /** Required. Describe the purpose, not the pixels. Decorative images: alt=\"\" on purpose. */\n alt: string;\n /** Reserves the space before the file arrives. original: from width/height (fallback 3:2 while loading). */\n ratio?: ImageRatio;\n /** cover: photos (fills, crops) · contain: logos, screenshots, product shots, charts (shows everything). */\n fit?: 'cover' | 'contain';\n /** Default radius/md; in cards the image takes the card's radius (none). */\n radius?: 'none' | 'sm' | 'md' | 'lg';\n /** 1 px border/media inside – for images on a similar background. */\n bordered?: boolean;\n /** Tiny preview (≈ 20 px, data URI) for blur-up. Without it a Skeleton shows. */\n placeholder?: string;\n /** Hero / largest image at the top: loads first (eager, fetchpriority high). Everything else loads lazily. */\n priority?: boolean;\n /** Text on a gradient – translatable, searchable, read by screen readers. Never bake text into images. */\n overlay?: { title: ReactNode; meta?: ReactNode; position?: 'bottom' | 'top' };\n /** One Badge (sm), top left. */\n badge?: ReactNode;\n /** Marks video. */\n play?: 'md' | 'lg';\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Image – an image with reserved space and calm loading states. Loading: blur-up preview or\n * Skeleton; the image fades in (250 ms; 100 ms with reduced motion). Error keeps the space and shows image-off;\n * the alt text stays available. Overlays (text, badge, play) only on the loaded image.\n */\nexport function Image({\n src,\n alt,\n ratio = 'original',\n fit = 'cover',\n radius = 'md',\n bordered,\n placeholder,\n priority,\n overlay,\n badge,\n play,\n className,\n style,\n onLoad,\n onError,\n ...props\n}: ImageProps) {\n const ref = useRef<HTMLImageElement>(null);\n const [state, setState] = useState<'loading' | 'loaded' | 'error'>('loading');\n\n // A new source starts loading again.\n useLayoutEffect(() => setState('loading'), [src]);\n\n // Cached images can finish before React attaches onLoad.\n useEffect(() => {\n const img = ref.current;\n if (img?.complete && src) setState(img.naturalWidth > 0 ? 'loaded' : 'error');\n }, [src]);\n\n const original = ratio === 'original';\n const { width, height } = props;\n const aspect = original ? (width && height ? `${width} / ${height}` : state === 'loaded' ? undefined : '3 / 2') : ratio.replace(':', ' / ');\n\n return (\n <div\n className={cx('medo-image', `medo-image--${fit}`, `medo-image--radius-${radius}`, bordered && 'medo-image--bordered', className)}\n data-state={state}\n style={{ aspectRatio: aspect, ...style }}\n >\n {state === 'loading' &&\n (placeholder ? <img className=\"medo-image__preview\" src={placeholder} alt=\"\" aria-hidden=\"true\" /> : <Skeleton shape=\"rect\" className=\"medo-image__skeleton\" />)}\n {state === 'error' && (\n <span className=\"medo-image__error\" role={alt ? 'img' : undefined} aria-label={alt || undefined} aria-hidden={alt ? undefined : true}>\n <ImageOff aria-hidden=\"true\" />\n </span>\n )}\n <img\n {...props}\n ref={ref}\n src={src}\n alt={alt}\n hidden={state === 'error'}\n loading={priority ? 'eager' : (props.loading ?? 'lazy')}\n fetchPriority={priority ? 'high' : props.fetchPriority}\n decoding=\"async\"\n className=\"medo-image__img\"\n onLoad={(e) => {\n setState('loaded');\n onLoad?.(e);\n }}\n onError={(e) => {\n setState('error');\n onError?.(e);\n }}\n />\n {state === 'loaded' && overlay && (\n <div className={cx('medo-image__overlay', `medo-image__overlay--${overlay.position ?? 'bottom'}`)}>\n <span className=\"medo-image__title\">{overlay.title}</span>\n {overlay.meta && <span className=\"medo-image__meta\">{overlay.meta}</span>}\n </div>\n )}\n {state === 'loaded' && badge && <span className=\"medo-image__badge\">{badge}</span>}\n {state === 'loaded' && play && <MediaPlayButton size={play} className=\"medo-image__play\" />}\n </div>\n );\n}\n\n/* ---------- Figure ---------- */\n\nexport interface FigureProps {\n /** The Image. */\n children: ReactNode;\n /** Describes what matters (adds to the image – never repeat the alt text). */\n caption?: ReactNode;\n /** Names the source („© Photographer“). */\n credit?: ReactNode;\n className?: string;\n}\n\n/** Figure – image with caption and credit. A real figure + figcaption. */\nexport function Figure({ children, caption, credit, className }: FigureProps) {\n return (\n <figure className={cx('medo-figure', className)}>\n {children}\n {(caption || credit) && (\n <figcaption className=\"medo-figure__caption\">\n {caption && <span>{caption}</span>}\n {credit && <span className=\"medo-figure__credit\">{credit}</span>}\n </figcaption>\n )}\n </figure>\n );\n}\n","import { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { Globe, MapPin, Play } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { Checkbox } from '../checkbox/Checkbox';\nimport { IconTile } from '../empty-state/EmptyState';\nimport { Link } from '../link/Link';\nimport { cx } from '../utils/cx';\nimport type { ImageRatio } from './Image';\nimport '../empty-state/empty-state.css';\nimport './media.css';\n\nexport type EmbedType = 'video' | 'map' | 'generic';\n\nexport interface EmbedTexts {\n title: string;\n /** Default size: who provides it and what is sent. */\n body: string;\n /** Compact size (< 480 px). */\n bodyCompact: string;\n load: string;\n remember: string;\n privacy: string;\n}\n\n/** Texts per type. provider: „YouTube“, „Google Maps“ · company: „Google“. */\nexport function defaultEmbedTexts(type: EmbedType, provider?: string, company?: string): EmbedTexts {\n const to = company ?? provider;\n if (type === 'video')\n return {\n title: 'Load external video',\n body: `This video is provided by ${provider ?? 'a third party'}. Loading it sends data such as your IP address to ${to ?? 'the provider'}.`,\n bodyCompact: `Loading this video sends data to ${provider && company && provider !== company ? `${provider} (${company})` : (to ?? 'a third party')}.`,\n load: 'Load video',\n remember: provider ? `Always load ${provider} videos` : 'Always load videos from this provider',\n privacy: 'Privacy policy',\n };\n if (type === 'map')\n return {\n title: 'Load map',\n body: `This map is provided by ${provider ?? 'a third party'}. Loading it sends data such as your IP address to ${to ?? 'the provider'}.`,\n bodyCompact: `Loading this map sends data to ${to ?? 'a third party'}.`,\n load: 'Load map',\n remember: provider ? `Always load ${provider}` : 'Always load maps from this provider',\n privacy: 'Privacy policy',\n };\n return {\n title: 'Load external content',\n body: `This content is provided by ${provider ?? 'a third party'}. Loading it sends data such as your IP address to ${to ?? 'the provider'}.`,\n bodyCompact: `Loading this content sends data to ${to ?? 'a third party'}.`,\n load: 'Load content',\n remember: provider ? `Always load content from ${provider}` : 'Always load content from this provider',\n privacy: 'Privacy policy',\n };\n}\n\nconst icons = { video: <Play />, map: <MapPin />, generic: <Globe /> };\n\nexport interface EmbedConsentProps {\n type?: EmbedType;\n /** „YouTube“, „Google Maps“, „Vimeo“ … */\n provider?: string;\n /** Who receives the data, when it differs („Google“). */\n company?: string;\n /** The embed URL – requested only after consent. Prefer privacy-friendly URLs (youtube-nocookie.com). */\n src: string;\n /** Required: names the iframe („Video: Product tour“). */\n title: string;\n /** Ratio of the final embed. The placeholder may grow so text never clips. */\n ratio?: Exclude<ImageRatio, 'original'>;\n /** The provider's privacy policy (or your own). */\n privacyHref: string;\n /** Stored consent from the consent manager – loads at once. */\n isConsented?: boolean;\n /** The user clicked „Load“; `remember` = „Always load …“ checked – store it per provider in the consent manager. */\n onConsent?: (remember: boolean) => void;\n /** iframe permissions, e.g. „autoplay; encrypted-media; picture-in-picture; fullscreen“. */\n allow?: string;\n texts?: Partial<EmbedTexts>;\n className?: string;\n}\n\n/**\n * Embed consent – two-click placeholder for third-party embeds.\n * Nothing loads from the provider – not even a thumbnail – until the user clicks. Then the iframe replaces the\n * placeholder in place and takes the focus. Compact below 480 px width (measured on the component).\n */\nexport function EmbedConsent({\n type = 'generic',\n provider,\n company,\n src,\n title,\n ratio = '16:9',\n privacyHref,\n isConsented,\n onConsent,\n allow,\n texts,\n className,\n}: EmbedConsentProps) {\n const t = { ...defaultEmbedTexts(type, provider, company), ...texts };\n const ref = useRef<HTMLDivElement>(null);\n const frame = useRef<HTMLIFrameElement>(null);\n const [clicked, setClicked] = useState(false);\n const [remember, setRemember] = useState(false);\n const [compact, setCompact] = useState(false);\n const loaded = isConsented || clicked;\n\n // Default from 480 px width, Compact below – the component's own width, not the viewport.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || loaded) return;\n const ro = new ResizeObserver(([entry]) => setCompact(entry.contentRect.width < 480));\n ro.observe(el);\n return () => ro.disconnect();\n }, [loaded]);\n\n // After the click the iframe takes the focus, so keyboard users land in the content.\n useEffect(() => {\n if (clicked) frame.current?.focus();\n }, [clicked]);\n\n const style = { aspectRatio: ratio.replace(':', ' / ') };\n\n if (loaded) {\n return (\n <div className={cx('medo-embed', 'medo-embed--loaded', className)} style={style}>\n <iframe\n ref={frame}\n src={src}\n title={title}\n allow={allow}\n allowFullScreen\n referrerPolicy=\"strict-origin-when-cross-origin\"\n loading=\"lazy\"\n className=\"medo-embed__frame\"\n />\n </div>\n );\n }\n\n return (\n <div ref={ref} role=\"region\" aria-label={title} className={cx('medo-embed', compact && 'medo-embed--compact', className)} style={style}>\n {!compact && (\n <IconTile size=\"sm\" tone=\"raised\">\n {icons[type]}\n </IconTile>\n )}\n <div className=\"medo-embed__content\">\n <p className=\"medo-embed__title\">{t.title}</p>\n <p className=\"medo-embed__body\">{compact ? t.bodyCompact : t.body}</p>\n </div>\n <div className=\"medo-embed__actions\">\n <Button\n size={compact ? 'sm' : 'md'}\n onPress={() => {\n onConsent?.(remember);\n setClicked(true);\n }}\n >\n {t.load}\n </Button>\n <Link variant=\"standalone\" size={compact ? 'sm' : 'md'} href={privacyHref}>\n {t.privacy}\n </Link>\n </div>\n {!compact && (\n <Checkbox isSelected={remember} onChange={setRemember}>\n {t.remember}\n </Checkbox>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs","AriaButton","jsx","jsxs","jsx","jsxs","AriaButton","AriaButton","Label","Fragment","jsx","jsxs","Label","Fragment","jsx","jsxs","AriaButton","useContext","Text","Fragment","jsx","jsxs","useContext","Text","useContext","Text","jsx","jsxs","useContext","Text","Text","Check","Fragment","jsx","jsxs","Check","Text","jsx","jsxs","createContext","useContext","useState","AriaButton","Text","Check","X","Fragment","jsx","jsxs","createContext","useState","Text","useContext","Check","AriaButton","X","createContext","useContext","useEffect","useState","AriaButton","jsx","jsxs","createContext","useContext","useState","useEffect","AriaButton","createContext","useContext","useEffect","useRef","jsx","jsxs","createContext","useContext","useRef","useEffect","createContext","useContext","Text","Check","jsx","Tag","Fragment","jsx","jsxs","createContext","useContext","Check","Text","Highlight","useContext","useEffect","useLayoutEffect","useRef","useState","AriaButton","Popover","X","useContext","useId","useRef","X","Fragment","jsx","jsxs","X","useRef","useContext","useId","useState","Fragment","jsx","jsxs","useState","useRef","AriaButton","Popover","useContext","useLayoutEffect","X","useEffect","createContext","useContext","useState","Header","Popover","Text","Fragment","jsx","jsxs","createContext","Popover","useState","useContext","Text","Header","useContext","useEffect","useId","useLayoutEffect","useRef","useState","Heading","Modal","ModalOverlay","OverlayTriggerStateContext","CircleAlert","X","Fragment","jsx","jsxs","useContext","OverlayTriggerStateContext","useState","Dialog","ModalOverlay","Modal","useId","useRef","Heading","X","useLayoutEffect","useEffect","CircleAlert","useContext","useEffect","useId","useRef","useState","AriaButton","Collection","ComboBoxStateContext","Popover","AriaTextField","ChevronDown","CircleAlert","X","Fragment","jsx","jsxs","useRef","useState","text","SelectedTags","ClearButton","AriaButton","ChevronDown","Popover","useContext","ComboBoxStateContext","X","useEffect","Collection","useId","CircleAlert","AriaTextField","useEffect","useState","Button","Text","X","jsx","jsxs","useState","useEffect","Text","Button","X","useLayoutEffect","useRef","SelectionIndicator","jsx","jsxs","useRef","SelectionIndicator","useLayoutEffect","useContext","useRef","AriaDialog","DialogTrigger","Heading","OverlayTriggerStateContext","Info","X","AriaLink","jsx","jsxs","AriaLink","Fragment","jsx","jsxs","DialogTrigger","Popover","Heading","X","useRef","AriaDialog","useContext","OverlayTriggerStateContext","Info","Children","createContext","isValidElement","useContext","useEffect","useId","useRef","useState","AriaButton","AriaDialog","DialogTrigger","Heading","AriaLink","Modal","ModalOverlay","ChevronDown","Ellipsis","X","useEffect","useRef","AriaDialog","Heading","Modal","ModalOverlay","X","Fragment","jsx","jsxs","ModalOverlay","Modal","Heading","X","useRef","AriaDialog","CLOSE_DISTANCE","CLOSE_VELOCITY","useEffect","Fragment","jsx","jsxs","createContext","useContext","AriaLink","Children","isValidElement","useState","useId","useRef","useEffect","AriaButton","ChevronDown","DialogTrigger","ModalOverlay","Modal","AriaDialog","X","Heading","Ellipsis","createContext","useContext","Check","X","jsx","jsxs","createContext","Tag","useContext","X","Check","useEffect","useRef","useState","ChevronRight","Fragment","jsx","jsxs","ChevronRight","useRef","useState","useEffect","useEffect","useRef","AriaButton","Toolbar","Ellipsis","X","Fragment","jsx","jsxs","useRef","useEffect","AriaButton","Ellipsis","Toolbar","X","useId","CircleAlert","Search","jsx","jsxs","Search","CircleAlert","useId","Tag","useId","useRef","useState","AriaButton","AriaLink","ChevronLeft","ChevronRight","Fragment","jsx","jsxs","useState","useId","useRef","AriaLink","AriaButton","ChevronLeft","ChevronRight","AriaButton","AriaInput","Search","X","jsx","jsxs","Search","AriaInput","AriaButton","X","AriaLink","jsx","jsxs","Heading","AriaLink","useEffect","useLayoutEffect","useState","Autocomplete","AriaButton","Dialog","Modal","ModalOverlay","useFilter","Search","jsx","jsxs","useState","useFilter","useEffect","ModalOverlay","Modal","Dialog","Autocomplete","AriaButton","Search","useLayoutEffect","useLayoutEffect","useRef","useState","AriaButton","AriaLink","ChevronLeft","ChevronRight","Ellipsis","Folder","jsx","jsxs","AriaLink","ChevronLeft","Label","ChevronRight","AriaButton","Ellipsis","Folder","useRef","useState","useLayoutEffect","Children","createContext","isValidElement","useContext","useEffect","useId","useState","AriaButton","Heading","ChevronDown","jsx","jsxs","createContext","Children","isValidElement","useState","useEffect","useContext","useId","Heading","AriaButton","ChevronDown","Label","useLocale","AriaInput","jsx","jsxs","AriaInput","Fragment","jsx","jsxs","useLocale","Label","CircleAlert","CircleCheck","Info","TriangleAlert","X","jsx","jsxs","Info","CircleCheck","TriangleAlert","CircleAlert","X","AriaLink","jsx","jsxs","Heading","AriaLink","Collection","Check","Minus","jsx","jsxs","plain","Minus","Check","Collection","jsx","jsxs","Popover","useEffect","useId","useLayoutEffect","useMemo","useRef","useState","AriaButton","Text","useLocale","CircleAlert","CircleCheck","FileText","X","Fragment","jsx","jsxs","useLocale","CircleAlert","CircleCheck","FileText","X","AriaButton","useId","Text","useMemo","useRef","useState","useEffect","useLayoutEffect","useEffect","useMemo","useRef","useState","AriaButton","useLocale","ChevronDown","ChevronLeft","ChevronRight","jsx","jsxs","Header","useLocale","useMemo","ChevronDown","ChevronLeft","ChevronRight","now","useRef","useEffect","AriaButton","useState","useMemo","useState","useLocale","DateFormatter","jsx","jsxs","useState","useLocale","useMemo","DateFormatter","Popover","useContext","useMemo","DateInput","DateSegment","AriaDialog","Group","AriaPopover","useLocale","DateFormatter","getLocalTimeZone","today","jsx","jsxs","useLocale","useMemo","DateFormatter","getLocalTimeZone","AriaPopover","AriaDialog","useContext","Group","DateInput","DateSegment","now","today","today","getLocalTimeZone","useEffect","useLayoutEffect","useRef","useState","jsx","jsxs","useRef","useState","useLayoutEffect","useEffect","useEffect","useLayoutEffect","useRef","useState","Globe","Play","jsx","jsxs","icons","Play","Globe","useRef","useState","useLayoutEffect","useEffect"]}
1
+ {"version":3,"sources":["../src/utils/cx.ts","../src/layout/Layout.tsx","../src/button/Button.tsx","../src/progress/Progress.tsx","../src/i18n/I18n.tsx","../src/i18n/de.ts","../src/i18n/en.ts","../src/icon-button/IconButton.tsx","../src/tooltip/Tooltip.tsx","../src/text-field/TextField.tsx","../src/field/Field.tsx","../src/checkbox/Checkbox.tsx","../src/radio/Radio.tsx","../src/switch/Switch.tsx","../src/badge/Badge.tsx","../src/tag/Tag.tsx","../src/avatar/Avatar.tsx","../src/toggle-button/ToggleButton.tsx","../src/listbox/ListBox.tsx","../src/utils/highlight.tsx","../src/select/Select.tsx","../src/bottom-sheet/BottomSheet.tsx","../src/utils/useFitCount.ts","../src/utils/useMediaQuery.ts","../src/menu/Menu.tsx","../src/dialog/Dialog.tsx","../src/combobox/Combobox.tsx","../src/toast/Toast.tsx","../src/tabs/Tabs.tsx","../src/popover/Popover.tsx","../src/link/Link.tsx","../src/navigation/Navigation.tsx","../src/drawer/Drawer.tsx","../src/list/List.tsx","../src/list-view/ListView.tsx","../src/bulk-action-bar/BulkActionBar.tsx","../src/empty-state/EmptyState.tsx","../src/pagination/Pagination.tsx","../src/search/SearchField.tsx","../src/search/SearchResult.tsx","../src/search/QuickSearch.tsx","../src/breadcrumbs/Breadcrumbs.tsx","../src/accordion/Accordion.tsx","../src/slider/Slider.tsx","../src/number-field/NumberField.tsx","../src/alert/Alert.tsx","../src/card/Card.tsx","../src/table/Table.tsx","../src/table/ColumnsMenu.tsx","../src/upload/Upload.tsx","../src/date-time/Calendar.tsx","../src/date-time/DateField.tsx","../src/date-time/DatePicker.tsx","../src/index.ts","../src/media/Image.tsx","../src/media/EmbedConsent.tsx"],"sourcesContent":["/** Joins class names and drops empty values. */\nexport const cx = (...classes: Array<string | false | null | undefined>) => classes.filter(Boolean).join(' ');\n","import type { CSSProperties, ElementType, HTMLAttributes, Ref } from 'react';\nimport { cx } from '../utils/cx';\n\n/**\n * Spacing rules: every gap between elements comes from one of six rules. The values grow with the layout mode\n * (mobile · tablet · desktop), so a layout needs no breakpoints for its spacing.\n *\n * inline 8 · content 16 · fields 16/24/24 · items 16/24/24 · group 32/40/48 · section 48/64/96 px\n */\nexport type SpacingRule = 'inline' | 'content' | 'fields' | 'items' | 'group' | 'section';\n\n/** Elements a layout component can render as. Choose the one that says what the content is. */\nexport type LayoutElement =\n | 'div'\n | 'section'\n | 'article'\n | 'aside'\n | 'main'\n | 'header'\n | 'footer'\n | 'nav'\n | 'ul'\n | 'ol'\n | 'li'\n | 'form'\n | 'fieldset';\n\ninterface LayoutProps extends HTMLAttributes<HTMLElement> {\n /** HTML element, e.g. `ul` for a list of cards or `section` for a page section. Default: `div`. */\n as?: LayoutElement;\n ref?: Ref<HTMLElement>;\n}\n\n/* ---------- Stack ---------- */\n\nexport interface StackProps extends LayoutProps {\n /** vertical (default) · horizontal. */\n direction?: 'vertical' | 'horizontal';\n /** Spacing rule. Default: `content` when vertical, `inline` when horizontal. */\n gap?: SpacingRule;\n /** Cross axis: start · center · end · stretch (default) · baseline. */\n align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';\n /** Main axis: start · center · end · between. */\n justify?: 'start' | 'center' | 'end' | 'between';\n /** Horizontal only: wrap to the next line when space runs out. */\n wrap?: boolean;\n}\n\n/**\n * Stack – elements below or next to each other with a spacing rule.\n * Vertical uses the rule `content`, horizontal the rule `inline`; pass `gap` for another rule.\n */\nexport function Stack({ as: Tag = 'div', direction = 'vertical', gap, align, justify, wrap, className, ...props }: StackProps) {\n const El = Tag as ElementType;\n return (\n <El\n {...props}\n className={cx(\n 'medo-stack',\n direction === 'horizontal' && 'medo-stack--horizontal',\n wrap && 'medo-stack--wrap',\n align && `medo-stack--align-${align}`,\n justify && `medo-stack--justify-${justify}`,\n gap && `medo-gap-${gap}`,\n className,\n )}\n />\n );\n}\n\n/* ---------- Grid ---------- */\n\nexport interface GridProps extends LayoutProps {\n /**\n * Columns. Without it: as many as fit, each at least `minItemSize` wide – no breakpoints needed.\n * A number: that many equal columns. `layout`: the layout grid (4 · 8 · 12 columns), place children with `GridItem`.\n */\n columns?: number | 'layout';\n /** Without `columns`: the narrowest a column may get (CSS length). Default `16rem`. */\n minItemSize?: string;\n /** Spacing rule. Default: `items` (the layout gutter). */\n gap?: SpacingRule;\n}\n\n/** Grid – cards, tiles and page areas in columns. The gap between items is always the rule `items` unless set. */\nexport function Grid({ as: Tag = 'div', columns, minItemSize, gap, className, style, ...props }: GridProps) {\n const El = Tag as ElementType;\n const vars = {\n ...(typeof columns === 'number' ? { '--medo-grid-columns': columns } : {}),\n ...(minItemSize ? { '--medo-grid-min': minItemSize } : {}),\n } as CSSProperties;\n return (\n <El\n {...props}\n style={{ ...vars, ...style }}\n className={cx(\n 'medo-grid',\n typeof columns === 'number' && 'medo-grid--columns',\n columns === 'layout' && 'medo-grid--layout',\n gap && `medo-gap-${gap}`,\n className,\n )}\n />\n );\n}\n\nexport interface GridItemProps extends LayoutProps {\n /** Columns to span, or `full`. Never more than there are: span 6 is full width on a phone (4 columns). */\n span?: number | 'full';\n}\n\n/** GridItem – a child of `Grid` that spans several columns. */\nexport function GridItem({ as: Tag = 'div', span = 1, className, style, ...props }: GridItemProps) {\n const El = Tag as ElementType;\n return (\n <El\n {...props}\n style={span === 'full' ? style : ({ '--medo-grid-span': span, ...style } as CSSProperties)}\n className={cx('medo-grid__item', span === 'full' && 'medo-grid__item--full', className)}\n />\n );\n}\n\n/* ---------- Container ---------- */\n\nexport interface ContainerProps extends LayoutProps {\n /** Width of the content: prose 680 (running text) · md 768 · lg 1024 · xl 1280 (default) · full. */\n size?: 'prose' | 'md' | 'lg' | 'xl' | 'full';\n}\n\n/** Container – centres the content, limits its width and adds the page margin of the layout mode. */\nexport function Container({ as: Tag = 'div', size = 'xl', className, ...props }: ContainerProps) {\n const El = Tag as ElementType;\n return <El {...props} className={cx('medo-container', size !== 'xl' && `medo-container--${size}`, className)} />;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { Button as AriaButton, type ButtonProps as AriaButtonProps } from 'react-aria-components';\nimport { Spinner } from '../progress/Progress';\nimport { cx } from '../utils/cx';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'text' | 'ghost-danger';\nexport type ButtonSize = 'sm' | 'md' | 'lg';\n\nexport interface ButtonProps extends Omit<AriaButtonProps, 'children' | 'className' | 'style'> {\n /** Visual weight. One primary button per area. */\n variant?: ButtonVariant;\n /** sm 32 px · md 40 px · lg 48 px (touch). */\n size?: ButtonSize;\n /** Icon before the label (decorative, hidden from screen readers). */\n startIcon?: ReactNode;\n /** Icon after the label (decorative, hidden from screen readers). */\n endIcon?: ReactNode;\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Button – triggers an action. Built on React Aria: consistent press,\n * hover and focus behaviour on mouse, touch, keyboard and screen readers.\n * Use onPress instead of onClick and isDisabled instead of disabled.\n * While saving, set isPending and change the label (“Saving…”): the button keeps its look and size.\n */\nexport function Button({ variant = 'primary', size = 'md', startIcon, endIcon, className, children, ...props }: ButtonProps) {\n // isPending: React Aria keeps focus and announces the pending state; a spinner replaces the start icon.\n const icon = props.isPending ? <Spinner decorative /> : startIcon;\n return (\n <AriaButton {...props} className={cx('medo-button', `medo-button--${variant}`, `medo-button--${size}`, className)}>\n {icon && (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-button__label\">{children}</span>\n {endIcon && (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {endIcon}\n </span>\n )}\n </AriaButton>\n );\n}\n\nexport interface ButtonGroupProps {\n /** footer: right, primary last · header: right, next to a title · content: left, primary first. */\n context?: 'footer' | 'header' | 'content';\n /** Buttons in reading order (footer: Cancel, Save · content: Get started, Learn more). */\n children: ReactNode;\n /** Footer only: a destructive action, placed on the far left and separated. */\n destructive?: ReactNode;\n /** Name of the group for screen readers, when it is not obvious from the context. */\n 'aria-label'?: string;\n className?: string;\n}\n\n/** Button group – spacing, alignment and mobile stacking for related buttons. */\nexport function ButtonGroup({ context = 'footer', children, destructive, className, ...props }: ButtonGroupProps) {\n return (\n <div\n role={props['aria-label'] ? 'group' : undefined}\n aria-label={props['aria-label']}\n className={cx('medo-button-group', `medo-button-group--${context}`, className)}\n >\n {destructive && context === 'footer' && <div className=\"medo-button-group__destructive\">{destructive}</div>}\n {children}\n </div>\n );\n}\n","import { useId, type CSSProperties, type ReactNode } from 'react';\nimport { Label, ProgressBar as AriaProgressBar, type ProgressBarProps as AriaProgressBarProps } from 'react-aria-components';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\n/* ---------- Spinner ---------- */\n\nexport interface SpinnerProps {\n /** sm 16 · md 20 · lg 24 · xl 40 px. */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /** current = text colour of the parent (default, fits every button) · brand · neutral · on-brand. */\n tone?: 'current' | 'brand' | 'neutral' | 'on-brand';\n /** Name for screen readers. */\n 'aria-label'?: string;\n /** Inside a control that already says what happens (“Saving…”): hide the spinner from screen readers. */\n decorative?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SpinnerGraphic = () => (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <circle className=\"medo-spinner__track\" cx=\"12\" cy=\"12\" r=\"10\" />\n <circle className=\"medo-spinner__arc\" cx=\"12\" cy=\"12\" r=\"10\" pathLength={100} />\n </svg>\n);\n\n/** Spinner – short wait of unknown length. */\nexport function Spinner({ size = 'md', tone = 'current', decorative, className, style, ...props }: SpinnerProps) {\n const m = useMessages();\n const classes = cx('medo-spinner', `medo-spinner--${size}`, tone !== 'current' && `medo-spinner--${tone}`, className);\n if (decorative) {\n return (\n <span className={classes} style={style} aria-hidden=\"true\">\n <SpinnerGraphic />\n </span>\n );\n }\n return (\n <AriaProgressBar isIndeterminate aria-label={props['aria-label'] ?? m.common.loading} className={classes} style={style}>\n <SpinnerGraphic />\n </AriaProgressBar>\n );\n}\n\n/* ---------- Progress bar ---------- */\n\nexport interface ProgressBarProps extends Omit<AriaProgressBarProps, 'children' | 'className' | 'style'> {\n /** Visible label (“Uploading 3 files”). Without it, set aria-label. */\n label?: ReactNode;\n /** Helper below the bar: files, time left, or what to do after an error. */\n description?: ReactNode;\n /** md 8 px in content · sm 4 px in dense rows (file list). */\n size?: 'sm' | 'md';\n /** success when done, error when it failed. Announced politely. */\n status?: 'default' | 'success' | 'error';\n /** Show the value (“64 %”) next to the label. Hidden when indeterminate. */\n showValue?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Progress bar – measurable or long work. Built on React Aria ProgressBar:\n * role progressbar with value and value text. Use `valueLabel` for words (“64 %, 2 of 3 files”).\n */\nexport function ProgressBar({\n label,\n description,\n size = 'md',\n status = 'default',\n showValue = true,\n className,\n style,\n ...props\n}: ProgressBarProps) {\n const descriptionId = useId();\n return (\n <AriaProgressBar\n {...props}\n aria-describedby={description ? descriptionId : undefined}\n className={cx(\n 'medo-progress',\n `medo-progress--${size}`,\n status !== 'default' && `medo-progress--${status}`,\n props.isIndeterminate && 'medo-progress--indeterminate',\n className,\n )}\n style={style}\n >\n {({ percentage, valueText, isIndeterminate }) => (\n <>\n {(label || (showValue && !isIndeterminate)) && (\n <div className=\"medo-progress__header\">\n {label && <Label className=\"medo-progress__label\">{label}</Label>}\n {showValue && !isIndeterminate && <span className=\"medo-progress__value\">{valueText}</span>}\n </div>\n )}\n <div className=\"medo-progress__track\">\n <div className=\"medo-progress__fill\" style={isIndeterminate ? undefined : { inlineSize: `${percentage}%` }} />\n </div>\n {description && (\n // Live only for the final state, so regular updates (“12 s left”) do not chatter.\n <span id={descriptionId} className=\"medo-progress__description\" aria-live={status === 'default' ? undefined : 'polite'}>\n {description}\n </span>\n )}\n </>\n )}\n </AriaProgressBar>\n );\n}\n\n/* ---------- Skeleton ---------- */\n\nexport interface SkeletonProps {\n /** text: 12 px line · circle: avatar · rect: image or card. */\n shape?: 'text' | 'circle' | 'rect';\n /** Number of text lines; the last one is shorter. */\n lines?: number;\n /** Any CSS length, e.g. \"60%\", 160. Match the real content. */\n width?: CSSProperties['inlineSize'];\n height?: CSSProperties['blockSize'];\n className?: string;\n}\n\n/**\n * Skeleton – placeholder in the shape of the content.\n * Hidden from screen readers; mark the loading region with aria-busy=\"true\".\n */\nexport function Skeleton({ shape = 'text', lines = 1, width, height, className }: SkeletonProps) {\n const style: CSSProperties = { inlineSize: width, blockSize: height };\n const one = (key?: number) => (\n <span key={key} className={cx('medo-skeleton', `medo-skeleton--${shape}`, className)} style={style} aria-hidden=\"true\" />\n );\n if (shape !== 'text' || lines <= 1) return one();\n return (\n <span className=\"medo-skeleton-lines\" aria-hidden=\"true\">\n {Array.from({ length: lines }, (_, i) => one(i))}\n </span>\n );\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport { useLocale } from 'react-aria-components';\nimport { de } from './de';\nimport { en } from './en';\nimport type { Messages } from './messages';\n\n/**\n * Languages of the built-in texts. The language comes from React Aria (`I18nProvider`, else the browser) –\n * the same source as date and number formats. Regional variants use their language (de-AT, de-CH → de).\n * Any other language falls back to English.\n */\nconst builtIn: Record<string, Messages> = { en, de };\n\nconst MessagesContext = createContext<Messages | null>(null);\n\n/**\n * Own texts for all components below, e.g. another language or a different tone:\n * <MessagesProvider messages={{ ...enMessages, common: { ...enMessages.common, close: 'Fermer' } }}>\n * Wins over the built-in languages. Props of a single component still win over both.\n */\nexport function MessagesProvider({ messages, children }: { messages: Messages; children: ReactNode }) {\n return <MessagesContext.Provider value={messages}>{children}</MessagesContext.Provider>;\n}\n\n/** The built-in texts for the current language. */\nexport function useMessages(): Messages {\n const custom = useContext(MessagesContext);\n const { locale } = useLocale();\n return custom ?? builtIn[locale.split('-')[0].toLowerCase()] ?? en;\n}\n\nexport { de, en };\nexport type { EmbedMessages, Messages } from './messages';\n","import type { EmbedMessages, Messages } from './messages';\n\n/*\n * Deutsch. Buttons im Infinitiv („Schließen“), Meldungen ohne Anrede („Bitte ein Datum … wählen“).\n * „Ihre“ nur, wo es nicht anders geht (IP-Adresse). Deutsche Anführungszeichen „…“.\n */\n\nconst embed = (\n title: string,\n subject: { nominative: string; dativeArticle: string },\n load: string,\n remember: (p: string | undefined) => string,\n): EmbedMessages => ({\n title,\n body: (provider, to) =>\n `${subject.nominative} von ${provider ?? 'einem Drittanbieter'} bereitgestellt. Beim Laden werden Daten wie Ihre IP-Adresse an ${to ?? 'den Anbieter'} übertragen.`,\n bodyCompact: (provider, company, to) =>\n `Beim Laden ${subject.dativeArticle} werden Daten an ${\n provider && company && provider !== company ? `${provider} (${company})` : (to ?? 'einen Drittanbieter')\n } übertragen.`,\n load,\n remember,\n});\n\nexport const de: Messages = {\n common: {\n close: 'Schließen',\n cancel: 'Abbrechen',\n back: 'Zurück',\n more: 'Mehr',\n done: 'Fertig',\n search: 'Suche',\n showResults: 'Ergebnisse anzeigen',\n loading: 'Wird geladen',\n clear: 'Eingabe löschen',\n clearAll: 'Alle entfernen',\n noResults: 'Keine Ergebnisse',\n noResultsFor: (q) => `Keine Ergebnisse für „${q}“`,\n selected: (name) => `${name}: ausgewählt`,\n removed: (labels) => `${labels.join(', ')} entfernt`,\n add: (text) => `„${text}“ hinzufügen`,\n create: 'Erstellen',\n reset: 'Zurücksetzen',\n countSelected: (n) => `${n} ausgewählt`,\n selectedValues: 'Ausgewählt',\n },\n keys: { control: 'Strg' },\n accordion: { expandAll: 'Alle aufklappen', collapseAll: 'Alle zuklappen' },\n alert: { dismiss: 'Ausblenden' },\n avatar: {\n status: { online: 'online', away: 'abwesend', busy: 'beschäftigt', offline: 'offline' },\n unknownPerson: 'Unbekannte Person',\n unknownOrganization: 'Unbekannte Organisation',\n more: (n) => `${n} weitere`,\n },\n breadcrumbs: { label: 'Pfadnavigation', more: (n) => (n === 1 ? '1 weitere Ebene anzeigen' : `${n} weitere Ebenen anzeigen`) },\n bulkActionBar: { label: 'Sammelaktionen', count: (n) => `${n} ausgewählt`, clear: 'Auswahl aufheben', more: 'Weitere Aktionen' },\n calendar: {\n previousMonth: 'Vorheriger Monat',\n nextMonth: 'Nächster Monat',\n previousYear: 'Vorheriges Jahr',\n nextYear: 'Nächstes Jahr',\n previousYears: 'Vorherige Jahre',\n nextYears: 'Nächste Jahre',\n chooseMonth: (title) => `${title} – Monat und Jahr wählen`,\n chooseYear: (year) => `${year} – Jahr wählen`,\n weekNumber: 'KW',\n },\n datePicker: {\n openCalendar: 'Kalender öffnen',\n time: 'Uhrzeit',\n presets: 'Zeiträume',\n beforeMin: (date) => `Bitte ein Datum ab dem ${date} wählen.`,\n afterMax: (date) => `Bitte ein Datum bis zum ${date} wählen.`,\n unavailable: 'Dieser Tag ist nicht verfügbar. Bitte einen anderen Tag wählen.',\n reversed: 'Das Enddatum muss nach dem Startdatum liegen.',\n today: 'Heute',\n yesterday: 'Gestern',\n last7Days: 'Letzte 7 Tage',\n last14Days: 'Letzte 14 Tage',\n last30Days: 'Letzte 30 Tage',\n thisMonth: 'Dieser Monat',\n lastMonth: 'Letzter Monat',\n availableTimes: 'Verfügbare Uhrzeiten',\n },\n dialog: {\n discardTitle: 'Änderungen verwerfen?',\n discardDescription: 'Die Änderungen gehen verloren.',\n discardAction: 'Verwerfen',\n discardCancel: 'Weiter bearbeiten',\n },\n embed: {\n video: embed('Externes Video laden', { nominative: 'Dieses Video wird', dativeArticle: 'dieses Videos' }, 'Video laden', (p) =>\n p ? `${p}-Videos immer laden` : 'Videos dieses Anbieters immer laden',\n ),\n map: embed('Karte laden', { nominative: 'Diese Karte wird', dativeArticle: 'dieser Karte' }, 'Karte laden', (p) =>\n p ? `${p} immer laden` : 'Karten dieses Anbieters immer laden',\n ),\n generic: embed('Externe Inhalte laden', { nominative: 'Diese Inhalte werden', dativeArticle: 'dieser Inhalte' }, 'Inhalte laden', (p) =>\n p ? `Inhalte von ${p} immer laden` : 'Inhalte dieses Anbieters immer laden',\n ),\n privacy: 'Datenschutzerklärung',\n },\n list: { notIncluded: 'Nicht enthalten:' },\n listView: { unread: 'Ungelesen' },\n navigation: {\n skipToContent: 'Zum Inhalt springen',\n main: 'Hauptnavigation',\n app: 'App',\n menu: 'Menü',\n collapse: 'Navigation einklappen',\n expand: 'Navigation ausklappen',\n },\n pagination: {\n label: 'Seitennavigation',\n summary: (from, to, total) => `${from}–${to} von ${total}`,\n pageSize: 'Zeilen pro Seite',\n previous: 'Vorherige Seite',\n next: 'Nächste Seite',\n page: (p) => `Seite ${p}`,\n pageOf: (p, total) => `Seite ${p} von ${total}`,\n },\n quickSearch: {\n placeholder: 'Seiten, Dateien, Personen suchen …',\n suggestions: 'Vorschläge',\n allResults: (q) => `Alle Ergebnisse für „${q}“`,\n noResults: (q) => `Keine Ergebnisse für „${q}“. Bitte die Schreibweise prüfen oder andere Begriffe versuchen.`,\n searchAll: (q) => `Alle Inhalte nach „${q}“ durchsuchen`,\n navigate: 'Navigieren',\n open: 'Öffnen',\n },\n searchField: { clear: 'Suche löschen' },\n select: { placeholder: 'Auswählen…', clearSelection: 'Auswahl entfernen' },\n combobox: { placeholder: 'Suchen…' },\n slider: { minimum: (label) => (label ? `${label}, Minimum` : 'Minimum'), maximum: (label) => (label ? `${label}, Maximum` : 'Maximum') },\n table: { columns: 'Spalten', showColumns: 'Spalten anzeigen', scrollRegion: 'Tabelle' },\n textField: {\n counter: (count, limit) => `${count} / ${limit}`,\n tooMany: (over) => `${over} zu viel`,\n charactersLeft: (left) => `Noch ${left} Zeichen`,\n charactersTooMany: (over) => `${over} Zeichen zu viel`,\n },\n upload: {\n title: 'Dateien hierher ziehen',\n dropTitle: 'Dateien zum Hochladen ablegen',\n chooseFiles: 'Dateien auswählen',\n chooseFile: 'Datei auswählen',\n listLabel: 'Hochgeladene Dateien',\n cancel: (name) => `Hochladen von ${name} abbrechen`,\n remove: (name) => `${name} entfernen`,\n retry: (name) => `${name} erneut hochladen`,\n retryShort: 'Wiederholen',\n uploading: (name) => `${name} wird hochgeladen`,\n progress: (loaded, total, percent) => `${loaded} von ${total} · ${percent} %`,\n typeNotAllowed: (names, types) => `${names} ${names.includes(',') ? 'sind' : 'ist'} nicht erlaubt.${types ? ` Erlaubt: ${types}.` : ''}`,\n tooLarge: (size, max) => `Datei ist ${size} groß – max. ${max} erlaubt`,\n tooMany: (max) => `Höchstens ${max} Dateien. Zum Hinzufügen bitte erst eine entfernen.`,\n uploaded: (name) => `${name} hochgeladen`,\n failed: (name, error) => `${name}: ${error}`,\n },\n};\n","import type { EmbedMessages, Messages } from './messages';\n\nconst s = (n: number, one: string, other: string) => (n === 1 ? one : other);\n\nconst embed = (noun: string, title: string, load: string, remember: (p: string | undefined) => string): EmbedMessages => ({\n title,\n body: (provider, to) =>\n `This ${noun} is provided by ${provider ?? 'a third party'}. Loading it sends data such as your IP address to ${to ?? 'the provider'}.`,\n bodyCompact: (provider, company, to) =>\n noun === 'video'\n ? `Loading this video sends data to ${provider && company && provider !== company ? `${provider} (${company})` : (to ?? 'a third party')}.`\n : `Loading this ${noun} sends data to ${to ?? 'a third party'}.`,\n load,\n remember,\n});\n\n/** English (default and fallback). */\nexport const en: Messages = {\n common: {\n close: 'Close',\n cancel: 'Cancel',\n back: 'Back',\n more: 'More',\n done: 'Done',\n search: 'Search',\n showResults: 'Show results',\n loading: 'Loading',\n clear: 'Clear',\n clearAll: 'Clear all',\n noResults: 'No results',\n noResultsFor: (q) => `No results for “${q}”`,\n selected: (name) => `${name}: selected`,\n removed: (labels) => `${labels.join(', ')} removed`,\n add: (text) => `Add “${text}”`,\n create: 'Create',\n reset: 'Reset',\n countSelected: (n) => `${n} selected`,\n selectedValues: 'Selected',\n },\n keys: { control: 'Ctrl' },\n accordion: { expandAll: 'Expand all', collapseAll: 'Collapse all' },\n alert: { dismiss: 'Dismiss' },\n avatar: {\n status: { online: 'online', away: 'away', busy: 'busy', offline: 'offline' },\n unknownPerson: 'Unknown person',\n unknownOrganization: 'Unknown organization',\n more: (n) => `${n} more`,\n },\n breadcrumbs: { label: 'Breadcrumb', more: (n) => `Show ${n} more ${s(n, 'level', 'levels')}` },\n bulkActionBar: { label: 'Bulk actions', count: (n) => `${n} selected`, clear: 'Clear selection', more: 'More actions' },\n calendar: {\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n previousYear: 'Previous year',\n nextYear: 'Next year',\n previousYears: 'Previous years',\n nextYears: 'Next years',\n chooseMonth: (title) => `${title} – choose month and year`,\n chooseYear: (year) => `${year} – choose year`,\n weekNumber: 'Wk',\n },\n datePicker: {\n openCalendar: 'Open calendar',\n time: 'Time',\n presets: 'Periods',\n beforeMin: (date) => `Choose a date from ${date} on.`,\n afterMax: (date) => `Choose a date until ${date}.`,\n unavailable: 'This day is not available. Choose another day.',\n reversed: 'The end date must be after the start date.',\n today: 'Today',\n yesterday: 'Yesterday',\n last7Days: 'Last 7 days',\n last14Days: 'Last 14 days',\n last30Days: 'Last 30 days',\n thisMonth: 'This month',\n lastMonth: 'Last month',\n availableTimes: 'Available times',\n },\n dialog: {\n discardTitle: 'Discard changes?',\n discardDescription: 'Your changes will be lost.',\n discardAction: 'Discard',\n discardCancel: 'Keep editing',\n },\n embed: {\n video: embed('video', 'Load external video', 'Load video', (p) => (p ? `Always load ${p} videos` : 'Always load videos from this provider')),\n map: embed('map', 'Load map', 'Load map', (p) => (p ? `Always load ${p}` : 'Always load maps from this provider')),\n generic: embed('content', 'Load external content', 'Load content', (p) =>\n p ? `Always load content from ${p}` : 'Always load content from this provider',\n ),\n privacy: 'Privacy policy',\n },\n list: { notIncluded: 'Not included:' },\n listView: { unread: 'Unread' },\n navigation: {\n skipToContent: 'Skip to content',\n main: 'Main',\n app: 'App',\n menu: 'Menu',\n collapse: 'Collapse navigation',\n expand: 'Expand navigation',\n },\n pagination: {\n label: 'Pagination',\n summary: (from, to, total) => `${from}–${to} of ${total}`,\n pageSize: 'Rows per page',\n previous: 'Previous page',\n next: 'Next page',\n page: (p) => `Page ${p}`,\n pageOf: (p, total) => `Page ${p} of ${total}`,\n },\n quickSearch: {\n placeholder: 'Search pages, files, people …',\n suggestions: 'Suggestions',\n allResults: (q) => `All results for “${q}”`,\n noResults: (q) => `No results for “${q}”. Check the spelling or try other words.`,\n searchAll: (q) => `Search all content for “${q}”`,\n navigate: 'Navigate',\n open: 'Open',\n },\n searchField: { clear: 'Clear search' },\n select: { placeholder: 'Select…', clearSelection: 'Clear selection' },\n combobox: { placeholder: 'Search…' },\n slider: { minimum: (label) => `Minimum ${label}`.trim(), maximum: (label) => `Maximum ${label}`.trim() },\n table: { columns: 'Columns', showColumns: 'Show columns', scrollRegion: 'Table' },\n textField: {\n counter: (count, limit) => `${count} / ${limit}`,\n tooMany: (over) => `${over} too many`,\n charactersLeft: (left) => `${left} ${s(left, 'character', 'characters')} left`,\n charactersTooMany: (over) => `${over} ${s(over, 'character', 'characters')} too many`,\n },\n upload: {\n title: 'Drag and drop files here',\n dropTitle: 'Drop files to upload',\n chooseFiles: 'Choose files',\n chooseFile: 'Choose file',\n listLabel: 'Uploaded files',\n cancel: (name) => `Cancel upload of ${name}`,\n remove: (name) => `Remove ${name}`,\n retry: (name) => `Retry ${name}`,\n retryShort: 'Retry',\n uploading: (name) => `Uploading ${name}`,\n progress: (loaded, total, percent) => `${loaded} of ${total} · ${percent} %`,\n typeNotAllowed: (names, types) => `${names} ${names.includes(',') ? 'are' : 'is'} not allowed.${types ? ` Use ${types}.` : ''}`,\n tooLarge: (size, max) => `File is ${size} – max. ${max} allowed`,\n tooMany: (max) => `You can add up to ${max} files. Remove one to add another.`,\n uploaded: (name) => `${name} uploaded`,\n failed: (name, error) => `${name}: ${error}`,\n },\n};\n","import type { CSSProperties, ReactNode } from 'react';\nimport { Button as AriaButton, type ButtonProps as AriaButtonProps } from 'react-aria-components';\nimport { Spinner } from '../progress/Progress';\nimport { Tooltip, TooltipTrigger, formatShortcut, resolveShortcut } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface IconButtonProps extends Omit<AriaButtonProps, 'children' | 'className' | 'style'> {\n /** Required: describes the action (“Delete file”), because there is no visible label. */\n 'aria-label': string;\n icon: ReactNode;\n /**\n * ghost (default for toolbars) · secondary · primary · danger.\n * On images and video: media – round overlay/media fill for busy images ·\n * media-ghost – no fill, on a gradient bar (video controls).\n */\n variant?: 'ghost' | 'secondary' | 'primary' | 'danger' | 'media' | 'media-ghost';\n /** sm 32 · md 40 · lg 48 px with 16 / 20 / 24 px icons. Media variants: sm 28 with a 44 px hit area. */\n size?: 'sm' | 'md' | 'lg';\n /**\n * Tooltip text. Default: the aria-label, so sighted users see the same name.\n * Pass false to turn it off (e.g. when a visible label is next to the button).\n */\n tooltip?: ReactNode | false;\n /** Keyboard shortcut in aria-keyshortcuts syntax (e.g. “Control+C”). Exposed to screen readers and shown in the tooltip. */\n shortcut?: string;\n /** Visible form of the shortcut. Default: “Control+C” → “Ctrl C”, “Meta+C” → “⌘ C”. */\n shortcutLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Square icon-only action. Shares the Button styles. Shows its label as a tooltip. */\nexport function IconButton({ icon, variant = 'ghost', size = 'md', tooltip, shortcut, shortcutLabel, className, ...props }: IconButtonProps) {\n const m = useMessages();\n const button = (\n <AriaButton\n {...props}\n aria-keyshortcuts={shortcut && resolveShortcut(shortcut)}\n className={cx('medo-button', 'medo-button--icon-only', `medo-button--${variant}`, `medo-button--${size}`, className)}\n >\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {props.isPending ? <Spinner decorative /> : icon}\n </span>\n </AriaButton>\n );\n\n if (tooltip === false) return button;\n return (\n <TooltipTrigger>\n {button}\n <Tooltip shortcut={shortcutLabel ?? (shortcut && formatShortcut(shortcut, m.keys.control))}>{tooltip ?? props['aria-label']}</Tooltip>\n </TooltipTrigger>\n );\n}\n","import { useContext, type ReactNode } from 'react';\nimport {\n Link as AriaLink,\n Tooltip as AriaTooltip,\n TooltipTrigger as AriaTooltipTrigger,\n TooltipTriggerStateContext,\n type LinkProps as AriaLinkProps,\n type TooltipProps as AriaTooltipProps,\n type TooltipTriggerComponentProps,\n} from 'react-aria-components';\nimport { cx } from '../utils/cx';\n\n/**\n * Wraps a focusable trigger (e.g. Button, IconButton) and its Tooltip.\n * Timing: 500 ms delay on hover, 100 ms close delay, instant on keyboard focus.\n * React Aria handles warm-up between neighbours, Escape and touch (no tooltip on touch).\n */\nexport function TooltipTrigger({ delay = 500, closeDelay = 100, ...props }: TooltipTriggerComponentProps) {\n return <AriaTooltipTrigger delay={delay} closeDelay={closeDelay} {...props} />;\n}\n\nexport interface TooltipProps extends Omit<AriaTooltipProps, 'children' | 'className'> {\n /** A few words, at most one sentence. No links or buttons. */\n children: ReactNode;\n /** Keyboard shortcut, shown dimmed after the text (e.g. “⌘C”). */\n shortcut?: string;\n className?: string;\n}\n\nconst KEY_LABELS: Record<string, string> = { Meta: '⌘', Shift: '⇧', Alt: 'Alt' };\n\n/** True on macOS and iOS: “Mod” means ⌘ there, Ctrl everywhere else. */\nconst isApple = () => typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent);\n\n/** “Mod+D” → “Meta+D” on Apple devices, “Control+D” elsewhere (aria-keyshortcuts syntax). */\nexport const resolveShortcut = (keys: string) => keys.replace(/\\bMod\\b/g, isApple() ? 'Meta' : 'Control');\n\n/**\n * Visible form of an aria-keyshortcuts value: “Control+C” → “Ctrl C”, “Meta+C” → “⌘ C”, “Mod+C” → per platform.\n * `control`: the name of the Control key in the current language (“Strg” in German).\n */\nexport const formatShortcut = (keys: string, control = 'Ctrl') =>\n resolveShortcut(keys)\n .split('+')\n .map((k) => (k === 'Control' ? control : (KEY_LABELS[k] ?? k)))\n .join(' ');\n\n/** Tooltip – short label on hover or focus. Top, 8 px offset, flips if needed. */\nexport function Tooltip({ children, shortcut, placement = 'top', offset = 8, className, ...props }: TooltipProps) {\n return (\n <AriaTooltip {...props} placement={placement} offset={offset} className={cx('medo-tooltip', className)}>\n <span>{children}</span>\n {shortcut && <kbd className=\"medo-tooltip__shortcut\">{shortcut}</kbd>}\n </AriaTooltip>\n );\n}\n\n/**\n * Link as a tooltip trigger. React Aria's Link takes focus but not hover from a TooltipTrigger –\n * this opens the tooltip on hover too. Internal (Navigation rail, Breadcrumbs), not exported from the package.\n */\nexport function TooltipLink(props: AriaLinkProps) {\n const tooltip = useContext(TooltipTriggerStateContext);\n return <AriaLink {...props} onHoverStart={() => tooltip?.open()} onHoverEnd={() => tooltip?.close()} />;\n}\n","import { useEffect, useState, type FormEvent, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Input as AriaInput,\n TextArea as AriaTextArea,\n TextField as AriaTextField,\n type ButtonProps as AriaButtonProps,\n type TextFieldProps as AriaTextFieldProps,\n} from 'react-aria-components';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport type InputSize = 'sm' | 'md' | 'lg';\n\nexport interface TextFieldProps extends Omit<AriaTextFieldProps, 'children' | 'className' | 'style'> {\n /**\n * Visible label. Always set one – a placeholder is no label. Without it set `aria-label` – only where the\n * context names the field (a table row, a filter bar), like Select and NumberField.\n */\n label?: ReactNode;\n /** Helper text below the field. Replaced by the error message when invalid. */\n description?: ReactNode;\n /** Error text shown when the field is invalid (isInvalid or failed validation). */\n errorMessage?: ReactNode;\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. Use lg on mobile and touch. Textareas: md or lg. */\n size?: InputSize;\n /** Decorative icon before the text (hidden from screen readers). */\n leadingIcon?: ReactNode;\n /** Trailing action, e.g. `<InputAction aria-label=\"Show password\" />`. */\n trailing?: ReactNode;\n /** Multi-line text (Textarea): min 3 rows, grows up to 8 rows. */\n multiline?: boolean;\n /** Soft limit: typing beyond is allowed, the counter turns red. Validate on submit. */\n characterLimit?: number;\n className?: string;\n}\n\n/** Text input with label, helper and error text (Field + Input / Textarea). */\nexport function TextField({\n label,\n description,\n errorMessage,\n placeholder,\n size = 'md',\n leadingIcon,\n trailing,\n multiline,\n characterLimit,\n className,\n onChange,\n ...props\n}: TextFieldProps) {\n const [length, setLength] = useState((props.value ?? props.defaultValue ?? '').length);\n const count = props.value !== undefined ? props.value.length : length;\n\n return (\n <AriaTextField\n {...props}\n className={cx('medo-field', className)}\n onChange={(value) => {\n setLength(value.length);\n onChange?.(value);\n }}\n >\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n {multiline ? (\n <AriaTextArea className={cx('medo-textarea', `medo-textarea--${size === 'lg' ? 'lg' : 'md'}`)} placeholder={placeholder} onInput={clearErrorWhenValid} />\n ) : (\n <div className={cx('medo-input', `medo-input--${size}`)}>\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n <AriaInput className=\"medo-input__control\" placeholder={placeholder} onInput={clearErrorWhenValid} />\n {trailing}\n </div>\n )}\n <FieldFooter description={description} errorMessage={errorMessage}>\n {characterLimit !== undefined && <CharacterCount count={count} limit={characterLimit} />}\n </FieldFooter>\n </AriaTextField>\n );\n}\n\n/**\n * “Reward early, punish late”: an error disappears as soon as the input is valid while typing –\n * new errors still only appear on blur or submit. React Aria commits validation on the native\n * change event (blur), so a valid input dispatches it early. Without this the error text vanished\n * on the next mousedown, the layout shifted and the click on e.g. “Save” missed its target.\n * Checked after the render, when React Aria has updated custom validity (validate functions).\n */\nfunction clearErrorWhenValid(e: FormEvent<HTMLInputElement | HTMLTextAreaElement>) {\n const el = e.currentTarget;\n requestAnimationFrame(() => {\n if (el.validity.valid && el.closest('[data-invalid]')) el.dispatchEvent(new Event('change'));\n });\n}\n\n/** Visible counter plus a calm announcement for screen readers, one second after typing stops (not on every key). */\nfunction CharacterCount({ count, limit }: { count: number; limit: number }) {\n const m = useMessages();\n const over = count - limit;\n const text = over > 0 ? m.textField.tooMany(over) : m.textField.counter(count, limit);\n const [announcement, setAnnouncement] = useState('');\n\n useEffect(() => {\n const id = setTimeout(\n () => setAnnouncement(over > 0 ? m.textField.charactersTooMany(over) : m.textField.charactersLeft(limit - count)),\n 1000,\n );\n return () => clearTimeout(id);\n }, [count, limit, over, m]);\n\n return (\n <>\n <span className=\"medo-field__counter\" data-over={over > 0 || undefined} aria-hidden=\"true\">\n {text}\n </span>\n <span className=\"medo-visually-hidden\" aria-live=\"polite\">\n {announcement}\n </span>\n </>\n );\n}\n\nexport interface InputActionProps extends Omit<AriaButtonProps, 'className' | 'children'> {\n /** Required: icon-only buttons need an accessible name. */\n 'aria-label': string;\n icon: ReactNode;\n}\n\n/** Icon button inside an input, e.g. clear or show password. */\nexport function InputAction({ icon, ...props }: InputActionProps) {\n return (\n <AriaButton {...props} className=\"medo-input__action\">\n {icon}\n </AriaButton>\n );\n}\n","import type { ReactNode } from 'react';\nimport { FieldError, Label, Text, type ValidationResult } from 'react-aria-components';\nimport { CircleAlert } from 'lucide-react';\n\n/** Label with the visual required marker. The field itself is announced as required. */\nexport function FieldLabel({ children, isRequired }: { children: ReactNode; isRequired?: boolean }) {\n return (\n <Label className=\"medo-field__label\">\n {children}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </Label>\n );\n}\n\n/** Helper text and error message. The error replaces the helper text when the field is invalid. */\nexport function FieldFooter({\n description,\n errorMessage,\n children,\n}: {\n description?: ReactNode;\n /** A function gets the validation details (rangeUnderflow, badInput …) to name the rule. */\n errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);\n children?: ReactNode;\n}) {\n return (\n <div className=\"medo-field__footer\">\n {description && (\n <Text slot=\"description\" className=\"medo-field__description\">\n {description}\n </Text>\n )}\n <FieldError className=\"medo-field__error\">\n {(validation) => (\n <>\n <CircleAlert aria-hidden=\"true\" />\n <span>{(typeof errorMessage === 'function' ? errorMessage(validation) : errorMessage) || validation.validationErrors.join(' ')}</span>\n </>\n )}\n </FieldError>\n {children}\n </div>\n );\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport {\n CheckboxButton,\n CheckboxField,\n CheckboxGroup as AriaCheckboxGroup,\n Text,\n type CheckboxFieldProps,\n type CheckboxGroupProps as AriaCheckboxGroupProps,\n} from 'react-aria-components';\nimport { Check, Minus } from 'lucide-react';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { cx } from '../utils/cx';\n\nexport type ChoiceSize = 'md' | 'lg';\nexport const ChoiceSizeContext = createContext<ChoiceSize>('md');\n\nexport interface CheckboxProps extends Omit<CheckboxFieldProps, 'children' | 'className' | 'style'> {\n /** Label. Clicking it toggles the checkbox. */\n children?: ReactNode;\n /** Second line below the label. */\n description?: ReactNode;\n /** md (16 px box, 14 px text) · lg (20 px box, 16 px text, mobile). Inherits from a group. */\n size?: ChoiceSize;\n className?: string;\n}\n\n/** Checkbox – on its own or inside a CheckboxGroup. */\nexport function Checkbox({ children, description, size, className, ...props }: CheckboxProps) {\n const groupSize = useContext(ChoiceSizeContext);\n return (\n <CheckboxField {...props} className={cx('medo-choice', 'medo-checkbox', `medo-choice--${size ?? groupSize}`, className)}>\n <CheckboxButton className=\"medo-choice__button\">\n {({ isSelected, isIndeterminate }) => (\n <>\n <span className=\"medo-choice__control\" aria-hidden=\"true\">\n {isIndeterminate ? <Minus /> : isSelected ? <Check /> : null}\n </span>\n {children && <span className=\"medo-choice__label\">{children}</span>}\n </>\n )}\n </CheckboxButton>\n {description && (\n <Text slot=\"description\" className=\"medo-choice__description\">\n {description}\n </Text>\n )}\n </CheckboxField>\n );\n}\n\nexport interface CheckboxGroupProps extends Omit<AriaCheckboxGroupProps, 'children' | 'className' | 'style'> {\n /** Group label (rendered like a legend). Without it set `aria-label` – only where the context names the group (e.g. an Accordion title). */\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n size?: ChoiceSize;\n /** vertical (default) or horizontal for 2–3 short options. */\n orientation?: 'vertical' | 'horizontal';\n children: ReactNode;\n className?: string;\n}\n\n/** Several checkboxes with one label, helper and error text. */\nexport function CheckboxGroup({ label, description, errorMessage, size = 'md', orientation = 'vertical', children, className, ...props }: CheckboxGroupProps) {\n return (\n <AriaCheckboxGroup {...props} className={cx('medo-field', 'medo-field--group', className)} data-orientation={orientation}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <ChoiceSizeContext.Provider value={size}>\n <div className=\"medo-field__options\">{children}</div>\n </ChoiceSizeContext.Provider>\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaCheckboxGroup>\n );\n}\n","import { useContext, type ReactNode } from 'react';\nimport { RadioButton, RadioField, RadioGroup as AriaRadioGroup, Text, type RadioFieldProps, type RadioGroupProps as AriaRadioGroupProps } from 'react-aria-components';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ChoiceSizeContext, type ChoiceSize } from '../checkbox/Checkbox';\nimport { cx } from '../utils/cx';\n\nexport interface RadioProps extends Omit<RadioFieldProps, 'children' | 'className' | 'style'> {\n children?: ReactNode;\n description?: ReactNode;\n size?: ChoiceSize;\n className?: string;\n}\n\n/** One option of a RadioGroup. */\nexport function Radio({ children, description, size, className, ...props }: RadioProps) {\n const groupSize = useContext(ChoiceSizeContext);\n return (\n <RadioField {...props} className={cx('medo-choice', 'medo-radio', `medo-choice--${size ?? groupSize}`, className)}>\n <RadioButton className=\"medo-choice__button\">\n <span className=\"medo-choice__control\" aria-hidden=\"true\" />\n {children && <span className=\"medo-choice__label\">{children}</span>}\n </RadioButton>\n {description && (\n <Text slot=\"description\" className=\"medo-choice__description\">\n {description}\n </Text>\n )}\n </RadioField>\n );\n}\n\nexport interface RadioGroupProps extends Omit<AriaRadioGroupProps, 'children' | 'className' | 'style'> {\n /** Group label (rendered like a legend). Without it set `aria-label` – only where the context names the group (e.g. an Accordion title). */\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n size?: ChoiceSize;\n children: ReactNode;\n className?: string;\n}\n\n/**\n * Pick exactly one of 2–4 visible options (5 or more: use a Select).\n * Arrow keys move and select; a choice cannot be removed again.\n */\nexport function RadioGroup({ label, description, errorMessage, size = 'md', children, className, ...props }: RadioGroupProps) {\n return (\n <AriaRadioGroup {...props} className={cx('medo-field', 'medo-field--group', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <ChoiceSizeContext.Provider value={size}>\n <div className=\"medo-field__options\">{children}</div>\n </ChoiceSizeContext.Provider>\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaRadioGroup>\n );\n}\n","import type { ReactNode } from 'react';\nimport { SwitchButton, SwitchField, Text, type SwitchFieldProps } from 'react-aria-components';\nimport { Check, LoaderCircle, X } from 'lucide-react';\nimport { cx } from '../utils/cx';\n\nexport interface SwitchProps extends Omit<SwitchFieldProps, 'children' | 'className' | 'style'> {\n /** Label. Describes the setting, never the state (“Notifications”, not “On”). */\n children: ReactNode;\n description?: ReactNode;\n /** md (36 × 20) · lg (44 × 24, mobile). */\n size?: 'md' | 'lg';\n /** start: label first, switch at the end (settings lists). end: switch first (forms). */\n labelPosition?: 'start' | 'end';\n /** While the change is being saved. The switch cannot be toggled meanwhile. */\n isLoading?: boolean;\n className?: string;\n}\n\n/** Switch – on / off with immediate effect. */\nexport function Switch({\n children,\n description,\n size = 'md',\n labelPosition = 'end',\n isLoading,\n isReadOnly,\n className,\n ...props\n}: SwitchProps) {\n return (\n <SwitchField\n {...props}\n isReadOnly={isReadOnly || isLoading}\n aria-busy={isLoading || undefined}\n className={cx('medo-switch', `medo-switch--${size}`, `medo-switch--label-${labelPosition}`, className)}\n >\n <SwitchButton className=\"medo-switch__button\">\n {({ isSelected }) => (\n <>\n <span className=\"medo-switch__track\" aria-hidden=\"true\">\n <span className=\"medo-switch__thumb\">\n {isLoading ? <LoaderCircle className=\"medo-switch__spinner\" /> : isSelected ? <Check /> : <X />}\n </span>\n </span>\n <span className=\"medo-switch__label\">{children}</span>\n </>\n )}\n </SwitchButton>\n {description && (\n <Text slot=\"description\" className=\"medo-switch__description\">\n {description}\n </Text>\n )}\n </SwitchField>\n );\n}\n","import type { HTMLAttributes, ReactNode } from 'react';\nimport { cx } from '../utils/cx';\n\nexport type BadgeTone = 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n /** Meaning: success, warning, danger, info. Brand for “New”, neutral for everything else. */\n tone?: BadgeTone;\n /** sm 20 px · md 24 px. */\n size?: 'sm' | 'md';\n /** Leading dot in the text colour, so the status does not rely on colour alone. */\n dot?: boolean;\n /** Leading icon (12 px, decorative). Ignored when `dot` is set. */\n icon?: ReactNode;\n /** 1–2 words, sentence case. */\n children: ReactNode;\n}\n\n/**\n * Badge – short, non-interactive status label.\n * Plain text: never clickable. For a badge that changes live, pass role=\"status\".\n */\nexport function Badge({ tone = 'neutral', size = 'md', dot, icon, className, children, ...props }: BadgeProps) {\n return (\n <span {...props} className={cx('medo-badge', `medo-badge--${tone}`, `medo-badge--${size}`, className)}>\n {dot ? (\n <span className=\"medo-badge__dot\" aria-hidden=\"true\" />\n ) : (\n icon && (\n <span className=\"medo-badge__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )\n )}\n {children}\n </span>\n );\n}\n\nexport interface BadgeCountProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n count: number;\n /** Above this number the badge shows “99+”. */\n max?: number;\n tone?: 'danger' | 'brand' | 'neutral';\n /** sm 16 px · md 20 px. */\n size?: 'sm' | 'md';\n /**\n * Text for screen readers, e.g. “3 unread messages”.\n * Without it the number is hidden: then the parent names it (“Notifications, 3 unread”).\n */\n label?: string;\n}\n\n/** Count for notifications. Hidden at 0. */\nexport function BadgeCount({ count, max = 99, tone = 'danger', size = 'md', label, className, ...props }: BadgeCountProps) {\n if (count <= 0) return null;\n const text = count > max ? `${max}+` : String(count);\n return (\n <span\n {...props}\n aria-hidden={label ? undefined : true}\n className={cx('medo-badge-count', `medo-badge-count--${tone}`, `medo-badge-count--${size}`, className)}\n >\n <span aria-hidden={label ? true : undefined}>{text}</span>\n {label && <span className=\"medo-visually-hidden\">{label}</span>}\n </span>\n );\n}\n\nexport interface BadgeDotProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n tone?: BadgeTone;\n /** Text for screen readers (“Unread”, “Online”). Without it the dot is decorative. */\n label?: string;\n}\n\n/** Dot for unread or presence. Always pair it with text or a label. */\nexport function BadgeDot({ tone = 'neutral', label, className, ...props }: BadgeDotProps) {\n return (\n <span\n {...props}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n className={cx('medo-badge-dot', `medo-badge-dot--${tone}`, className)}\n />\n );\n}\n","import { createContext, useContext, useRef, useState, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Tag as AriaTag,\n TagGroup as AriaTagGroup,\n TagList,\n Text,\n type Key,\n type TagGroupProps as AriaTagGroupProps,\n type TagListProps,\n type TagProps as AriaTagProps,\n} from 'react-aria-components';\nimport { Check, X } from 'lucide-react';\nimport { FieldLabel } from '../field/Field';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\ntype TagSize = 'sm' | 'md';\nconst TagSizeContext = createContext<TagSize>('md');\n\nexport interface TagGroupProps<T> extends Omit<AriaTagGroupProps, 'children' | 'className' | 'style'> {\n /** Visible label. Without it, set aria-label. */\n label?: ReactNode;\n /** Helper text below the tags. */\n description?: ReactNode;\n /** sm 24 px · md 32 px. Follows the field size (Select sm/md → sm, lg/mobile → md). */\n size?: TagSize;\n /** Tags, or a render function together with `items`. */\n children: TagListProps<T>['children'];\n items?: Iterable<T>;\n /** Shown when there are no tags. */\n renderEmptyState?: () => ReactNode;\n /** Text announced after a removal. Default: “{label} removed”. */\n removedMessage?: (labels: string[]) => string;\n className?: string;\n}\n\n/**\n * Tag group – a labelled list of tags. Built on React Aria TagGroup:\n * arrow keys move between tags, Backspace/Delete removes, Space/Enter toggles a filter.\n *\n * Two roles, never mixed in one group:\n * - removable values: pass `onRemove`\n * - filters: pass `selectionMode=\"multiple\"` (or \"single\"). Click again to deselect.\n */\nexport function TagGroup<T extends object>({\n label,\n description,\n size = 'md',\n children,\n items,\n renderEmptyState,\n onRemove,\n removedMessage: removedMessageProp,\n className,\n ...props\n}: TagGroupProps<T>) {\n const m = useMessages();\n const removedMessage = removedMessageProp ?? m.common.removed;\n const ref = useRef<HTMLDivElement>(null);\n const [announcement, setAnnouncement] = useState('');\n\n // Removals are announced politely, so screen reader users know it worked.\n const handleRemove =\n onRemove &&\n ((keys: Set<Key>) => {\n const labels = [...keys].map(\n (key) => ref.current?.querySelector(`[data-key=\"${CSS.escape(String(key))}\"] .medo-tag__label`)?.textContent ?? String(key),\n );\n onRemove(keys);\n setAnnouncement(removedMessage(labels));\n });\n\n return (\n <AriaTagGroup {...props} ref={ref} onRemove={handleRemove} className={cx('medo-field', 'medo-field--group', className)}>\n {label && <FieldLabel>{label}</FieldLabel>}\n <TagSizeContext.Provider value={size}>\n <TagList items={items} renderEmptyState={renderEmptyState} className=\"medo-tag-list\">\n {children}\n </TagList>\n </TagSizeContext.Provider>\n {description && (\n <div className=\"medo-field__footer\">\n <Text slot=\"description\" className=\"medo-field__description\">\n {description}\n </Text>\n </div>\n )}\n <span className=\"medo-visually-hidden\" aria-live=\"polite\">\n {announcement}\n </span>\n </AriaTagGroup>\n );\n}\n\nexport interface TagProps extends Omit<AriaTagProps, 'children' | 'className'> {\n /** Short label; long text is truncated at 200 px. */\n children: ReactNode;\n /** Leading icon (decorative). A selected filter shows a check instead. */\n icon?: ReactNode;\n className?: string;\n}\n\n/** A single tag inside a TagGroup. */\nexport function Tag({ children, icon, textValue, className, ...props }: TagProps) {\n const size = useContext(TagSizeContext);\n return (\n <AriaTag\n {...props}\n textValue={textValue ?? (typeof children === 'string' ? children : undefined)}\n className={({ selectionMode }) =>\n cx('medo-tag', `medo-tag--${size}`, selectionMode !== 'none' && 'medo-tag--selectable', className)\n }\n >\n {({ allowsRemoving, isSelected, selectionMode }) => (\n <>\n {selectionMode !== 'none' && isSelected ? (\n <span className=\"medo-tag__icon\" aria-hidden=\"true\">\n <Check />\n </span>\n ) : (\n icon && (\n <span className=\"medo-tag__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )\n )}\n <span className=\"medo-tag__label\">{children}</span>\n {allowsRemoving && (\n <AriaButton slot=\"remove\" className=\"medo-tag__remove\">\n <X aria-hidden=\"true\" />\n </AriaButton>\n )}\n </>\n )}\n </AriaTag>\n );\n}\n","import {\n Children,\n cloneElement,\n createContext,\n isValidElement,\n useContext,\n useEffect,\n useState,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { Button as AriaButton } from 'react-aria-components';\nimport { Building2, User } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\nexport type AvatarStatus = 'online' | 'away' | 'busy' | 'offline';\n\nconst TONES = ['blue', 'violet', 'pink', 'amber', 'green', 'teal'] as const;\n/** Size for avatars inside a group or a list row (internal, set by the container). */\nexport const AvatarSizeContext = createContext<AvatarSize | undefined>(undefined);\n\n/** Same input, same tone: a small string hash modulo 6. */\nfunction toneFor(key: string) {\n let hash = 0;\n for (const char of key) hash = (hash * 31 + char.codePointAt(0)!) | 0;\n return TONES[Math.abs(hash) % TONES.length];\n}\n\n/** First letters of first and last name; one word: first two letters. */\nexport function initialsOf(name: string) {\n const words = name.trim().split(/\\s+/).filter(Boolean);\n if (words.length === 0) return '';\n if (words.length === 1) return Array.from(words[0]).slice(0, 2).join('').toUpperCase();\n return (Array.from(words[0])[0] + Array.from(words[words.length - 1])[0]).toUpperCase();\n}\n\n\nexport interface AvatarProps {\n /** Person or organization name. Used for alt text, initials and (without `colorKey`) the tone. */\n name?: string;\n /** Photo URL. Falls back to initials if it is missing or fails to load. */\n src?: string;\n /** xs 20 · sm 24 · md 32 · lg 40 · xl 56 · 2xl 80 px. */\n size?: AvatarSize;\n /** circle = person · square = organization, team, workspace. */\n shape?: 'circle' | 'square';\n /** Stable id (user id) for the initials colour, so it survives name changes. */\n colorKey?: string;\n /** Presence dot. Also added to the accessible name (“Lea M., online”). */\n status?: AvatarStatus;\n /** Words for the status in the accessible name. */\n statusLabels?: Partial<Record<AvatarStatus, string>>;\n /** Next to a visible name the avatar is decorative and hidden from screen readers. */\n decorative?: boolean;\n /** Accessible name when the name is unknown (guest, deleted account). */\n unknownLabel?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Avatar – picture of a person or organization with fallback image → initials → icon. */\nexport function Avatar({\n name,\n src,\n size,\n shape = 'circle',\n colorKey,\n status,\n statusLabels,\n decorative,\n unknownLabel,\n className,\n style,\n}: AvatarProps) {\n const m = useMessages();\n const groupSize = useContext(AvatarSizeContext);\n const finalSize = size ?? groupSize ?? 'md';\n const [failed, setFailed] = useState(false);\n useEffect(() => setFailed(false), [src]);\n\n const initials = name ? initialsOf(name) : '';\n const showImage = Boolean(src) && !failed;\n const tone = initials ? toneFor(colorKey ?? name!) : 'neutral';\n const statusText = status ? (statusLabels?.[status] ?? m.avatar.status[status]) : undefined;\n const fallbackName = unknownLabel ?? (shape === 'square' ? m.avatar.unknownOrganization : m.avatar.unknownPerson);\n const label = [name || fallbackName, statusText].filter(Boolean).join(', ');\n\n return (\n <span\n role={decorative ? undefined : 'img'}\n aria-label={decorative ? undefined : label}\n aria-hidden={decorative || undefined}\n className={cx(\n 'medo-avatar',\n `medo-avatar--${finalSize}`,\n `medo-avatar--${shape}`,\n `medo-avatar--${tone}`,\n showImage && 'medo-avatar--has-image',\n className,\n )}\n style={style}\n >\n {initials ? (\n <span className=\"medo-avatar__initials\" aria-hidden=\"true\">\n {initials}\n </span>\n ) : (\n <span className=\"medo-avatar__icon\" aria-hidden=\"true\">\n {shape === 'square' ? <Building2 /> : <User />}\n </span>\n )}\n {showImage && <img className=\"medo-avatar__image\" src={src} alt=\"\" onError={() => setFailed(true)} />}\n {status && <span className={cx('medo-avatar__status', `medo-avatar__status--${status}`)} aria-hidden=\"true\" />}\n </span>\n );\n}\n\nexport interface AvatarGroupProps {\n /** Avatars, most relevant first (owner, you). */\n children: ReactNode;\n /** Visible avatars before “+N”. */\n max?: number;\n /** xs · sm · md · lg. */\n size?: Exclude<AvatarSize, 'xl' | '2xl'>;\n /** Name of the group, e.g. “Assignees”. */\n 'aria-label': string;\n /** Opens the full list (e.g. a popover). Without it “+N” is plain text. */\n onMorePress?: () => void;\n /** Accessible name of “+N”. Default: “N more”. */\n moreLabel?: (count: number) => string;\n className?: string;\n}\n\n/** Overlapping avatars, max 4 + “+N”. */\nexport function AvatarGroup({\n children,\n max = 4,\n size = 'md',\n onMorePress,\n moreLabel: moreLabelProp,\n className,\n ...props\n}: AvatarGroupProps) {\n const m = useMessages();\n const moreLabel = moreLabelProp ?? m.avatar.more;\n const items = Children.toArray(children);\n const visible = items.slice(0, max);\n const hidden = items.length - visible.length;\n const moreClass = cx('medo-avatar', `medo-avatar--${size}`, 'medo-avatar--circle', 'medo-avatar--neutral', 'medo-avatar--more');\n\n return (\n <div role=\"group\" aria-label={props['aria-label']} className={cx('medo-avatar-group', `medo-avatar-group--${size}`, className)}>\n <AvatarSizeContext.Provider value={size}>\n {visible.map((child, i) =>\n // The first avatar sits on top.\n isValidElement<AvatarProps>(child)\n ? cloneElement(child as ReactElement<AvatarProps>, { style: { ...child.props.style, zIndex: visible.length - i } })\n : child,\n )}\n </AvatarSizeContext.Provider>\n {hidden > 0 &&\n (onMorePress ? (\n <AriaButton className={moreClass} onPress={onMorePress} aria-label={moreLabel(hidden)}>\n +{hidden}\n </AriaButton>\n ) : (\n <span className={moreClass} role=\"img\" aria-label={moreLabel(hidden)}>\n +{hidden}\n </span>\n ))}\n </div>\n );\n}\n","import { createContext, useContext, useEffect, useRef, type CSSProperties, type ReactNode } from 'react';\nimport {\n SelectionIndicator,\n Separator,\n ToggleButton as AriaToggleButton,\n ToggleButtonGroup as AriaToggleButtonGroup,\n Toolbar as AriaToolbar,\n type ToggleButtonGroupProps as AriaToggleButtonGroupProps,\n type ToggleButtonProps as AriaToggleButtonProps,\n type ToolbarProps as AriaToolbarProps,\n} from 'react-aria-components';\nimport { Tooltip, TooltipTrigger, formatShortcut, resolveShortcut } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\ntype ToggleSize = 'sm' | 'md' | 'lg';\n\n/** Item size set by a group (segmented items are one size smaller than the group). */\nconst ToggleSizeContext = createContext<ToggleSize | null>(null);\n/** Segmented groups show a sliding indicator: it moves to the new item, so the eye follows the selection. */\nconst SegmentedContext = createContext(false);\n\nexport interface ToggleButtonProps extends Omit<AriaToggleButtonProps, 'children' | 'className' | 'style'> {\n /** Visible label. It never changes with the state (“Bold” stays “Bold”). Leave out for icon only. */\n children?: ReactNode;\n /** Leading icon; alone it makes an icon-only toggle (then aria-label is required). */\n icon?: ReactNode;\n /** sm 32 · md 40 · lg 48 px, like Button. Inside a group the group sets it. */\n size?: ToggleSize;\n /** Icon only: tooltip text. Default: the aria-label. false turns it off. */\n tooltip?: ReactNode | false;\n /** Keyboard shortcut in aria-keyshortcuts syntax (e.g. “Control+B”), shown in the tooltip. */\n shortcut?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Toggle Button – a button that stays pressed.\n * Built on React Aria ToggleButton: announced as pressed / not pressed (aria-pressed).\n * For an immediate, local effect (bold, mute, favourite). Saved settings use Switch, navigation uses Tabs.\n */\nexport function ToggleButton({ children, icon, size, tooltip, shortcut, className, ...props }: ToggleButtonProps) {\n const m = useMessages();\n const groupSize = useContext(ToggleSizeContext);\n const segmented = useContext(SegmentedContext);\n const s = groupSize ?? size ?? 'md';\n const iconOnly = !children;\n const button = (\n <AriaToggleButton\n {...props}\n aria-keyshortcuts={shortcut && resolveShortcut(shortcut)}\n className={cx('medo-button', `medo-button--${s}`, iconOnly && 'medo-button--icon-only', 'medo-toggle', className)}\n >\n {/* Segmented: the selected fill is an indicator that slides from the previous item (React Aria SelectionIndicator). */}\n {segmented && <SelectionIndicator className=\"medo-toggle__indicator\" />}\n {icon && (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n {children}\n </AriaToggleButton>\n );\n\n if (!iconOnly || tooltip === false) return button;\n return (\n <TooltipTrigger>\n {button}\n <Tooltip shortcut={shortcut && formatShortcut(shortcut, m.keys.control)}>{tooltip ?? props['aria-label']}</Tooltip>\n </TooltipTrigger>\n );\n}\n\nexport interface ToggleButtonGroupProps extends Omit<AriaToggleButtonGroupProps, 'children' | 'className' | 'style'> {\n /**\n * segmented: switch between 2–5 views, exactly one on, shared container.\n * toolbar: formatting options, any combination (or selectionMode=\"single\", e.g. text alignment), no container.\n */\n variant?: 'segmented' | 'toolbar';\n /** Height of the group: md 40 · lg 48 (segmented items are one size smaller). */\n size?: 'md' | 'lg';\n /** Segmented only: full width, items share the space (mobile). */\n fullWidth?: boolean;\n /** Required when there is no visible label: names the group (“View”). */\n 'aria-label'?: string;\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Toggle button group. Built on React Aria ToggleButtonGroup:\n * Tab enters once on the selected item, arrow keys move between items.\n */\nexport function ToggleButtonGroup({\n variant = 'segmented',\n size = 'md',\n fullWidth,\n selectionMode,\n disallowEmptySelection,\n children,\n className,\n ...props\n}: ToggleButtonGroupProps) {\n const segmented = variant === 'segmented';\n /*\n * Workaround for React Aria: inside a Toolbar a multi-select group switches to role=\"group\" after\n * mounting but keeps aria-orientation, which ARIA does not allow on a group (axe: aria-allowed-attr).\n * React re-sets the attribute only when its value changes, so removing it once per change is enough.\n */\n const ref = useRef<HTMLDivElement>(null);\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const fix = () => {\n if (el.getAttribute('role') === 'group' && el.hasAttribute('aria-orientation')) el.removeAttribute('aria-orientation');\n };\n fix();\n const observer = new MutationObserver(fix);\n observer.observe(el, { attributes: true, attributeFilter: ['role', 'aria-orientation'] });\n return () => observer.disconnect();\n }, []);\n const itemSize: ToggleSize = segmented ? (size === 'lg' ? 'md' : 'sm') : size;\n return (\n <AriaToggleButtonGroup\n {...props}\n ref={ref}\n selectionMode={segmented ? 'single' : (selectionMode ?? 'multiple')}\n disallowEmptySelection={segmented || disallowEmptySelection}\n className={cx('medo-toggle-group', `medo-toggle-group--${variant}`, `medo-toggle-group--${size}`, segmented && fullWidth && 'medo-toggle-group--full', className)}\n >\n <SegmentedContext.Provider value={segmented}>\n <ToggleSizeContext.Provider value={itemSize}>{children}</ToggleSizeContext.Provider>\n </SegmentedContext.Provider>\n </AriaToggleButtonGroup>\n );\n}\n\nexport interface ToolbarProps extends Omit<AriaToolbarProps, 'className' | 'style'> {\n /** Required: names the toolbar (“Text formatting”). */\n 'aria-label': string;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Toolbar – several toggle groups (and buttons) in one row.\n * Built on React Aria Toolbar: one Tab stop for the whole toolbar, arrow keys move across all groups.\n */\nexport function Toolbar({ className, ...props }: ToolbarProps) {\n return <AriaToolbar {...props} className={cx('medo-toolbar', className)} />;\n}\n\n/** Divider between groups in a Toolbar (1 px border/default, 24 px high). */\nexport function ToolbarSeparator() {\n return <Separator orientation=\"vertical\" className=\"medo-toolbar__separator\" />;\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport {\n Collection,\n ComboBoxStateContext,\n Header,\n ListBox as AriaListBox,\n ListBoxItem,\n ListBoxSection as AriaListBoxSection,\n Text,\n type ListBoxItemProps,\n type ListBoxProps as AriaListBoxProps,\n} from 'react-aria-components';\nimport { Check } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport { Highlight as SharedHighlight } from '../utils/highlight';\n\nexport type ListBoxSize = 'md' | 'lg';\n\nconst ListBoxSizeContext = createContext<ListBoxSize>('md');\n\nexport interface ListBoxProps<T> extends Omit<AriaListBoxProps<T>, 'className' | 'style'> {\n /** md on desktop · lg on mobile and in the Bottom Sheet. */\n size?: ListBoxSize;\n className?: string;\n}\n\n/**\n * Listbox – the list behind Select, Combobox and Bottom Sheet.\n * Built on React Aria ListBox: arrow keys, type-ahead, Home/End; sections and separators.\n */\nexport function ListBox<T extends object>({ size = 'md', className, ...props }: ListBoxProps<T>) {\n return (\n <ListBoxSizeContext.Provider value={size}>\n <AriaListBox {...props} className={cx('medo-listbox', `medo-listbox--${size}`, className)} />\n </ListBoxSizeContext.Provider>\n );\n}\n\nexport interface OptionProps extends Omit<ListBoxItemProps, 'children' | 'className' | 'style'> {\n /** Label. Long labels wrap; keep them short and put details into the description. */\n children: ReactNode;\n /** Second line in text/secondary. */\n description?: ReactNode;\n /** Decorative leading icon. */\n icon?: ReactNode;\n}\n\n/** Option – one row in a Listbox. Single: check on the right. Multi: checkbox on the left. */\nexport function Option({ children, description, icon, textValue, ...props }: OptionProps) {\n const size = useContext(ListBoxSizeContext);\n return (\n <ListBoxItem {...props} textValue={textValue ?? (typeof children === 'string' ? children : undefined)} className=\"medo-option\">\n {({ isSelected, selectionMode }) => (\n <>\n {selectionMode === 'multiple' && (\n <span\n className={cx('medo-choice', 'medo-checkbox', `medo-choice--${size}`, 'medo-option__checkbox')}\n data-selected={isSelected || undefined}\n aria-hidden=\"true\"\n >\n <span className=\"medo-choice__control\">{isSelected && <Check />}</span>\n </span>\n )}\n {icon && (\n <span className=\"medo-option__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-option__content\">\n <Text slot=\"label\" className=\"medo-option__label\">\n <Highlight>{children}</Highlight>\n </Text>\n {description && (\n <Text slot=\"description\" className=\"medo-option__description\">\n {description}\n </Text>\n )}\n </span>\n {selectionMode !== 'multiple' && isSelected && (\n <span className=\"medo-option__check\" aria-hidden=\"true\">\n <Check />\n </span>\n )}\n </>\n )}\n </ListBoxItem>\n );\n}\n\nexport interface ListBoxSectionProps<T> {\n /** Group heading (overline). Use headings only with two or more groups. Without a title, set aria-label. */\n title?: ReactNode;\n 'aria-label'?: string;\n children: ReactNode | ((item: T) => ReactNode);\n items?: Iterable<T>;\n id?: string;\n}\n\n/**\n * A group of options with a heading (announced as the name of the group).\n * Groups are divided by a line automatically (a separator element is not allowed inside a listbox).\n */\nexport function ListBoxSection<T extends object>({ title, children, items, id, ...props }: ListBoxSectionProps<T>) {\n return (\n <AriaListBoxSection id={id} aria-label={props['aria-label']} className=\"medo-listbox__section\">\n {title && <Header className=\"medo-listbox__header\">{title}</Header>}\n {typeof children === 'function' ? <Collection items={items}>{children}</Collection> : children}\n </AriaListBoxSection>\n );\n}\n\n/** Message row for empty and loading states – never an empty popup. Announced as status. */\nexport function ListBoxMessage({ children }: { children: ReactNode }) {\n return (\n <div className=\"medo-listbox__message\" role=\"status\">\n {children}\n </div>\n );\n}\n\n/* ---------- Match highlight (Combobox) ---------- */\n\n/** Search text to highlight, for lists filtered outside a ComboBox (e.g. the search in a Bottom Sheet, Quick search). */\nexport const OptionHighlightContext = createContext<string | null>(null);\n\n/**\n * Inside a Combobox: shows the typed text in bold within the option label (contains match,\n * case and accent insensitive, “mul” → “Müller”). Visual only; screen readers read plain text.\n */\nfunction Highlight({ children }: { children: ReactNode }) {\n const combo = useContext(ComboBoxStateContext);\n const external = useContext(OptionHighlightContext);\n let query = (external ?? combo?.inputValue ?? '').trim();\n // The input shows the chosen value (single): nothing to highlight then.\n if (combo?.selectedItems.some((item) => item?.textValue === query)) query = '';\n if (!query || typeof children !== 'string') return <>{children}</>;\n return <SharedHighlight text={children} query={query} as=\"span\" className=\"medo-option__match\" />;\n}\n","import type { ReactNode } from 'react';\n\nconst plain = (text: string) =>\n text\n .normalize('NFD')\n .replace(/\\p{Diacritic}/gu, '')\n .toLocaleLowerCase();\n\n/**\n * Splits a text into parts that match the query and parts that don't – contains match, case and\n * accent insensitive (“mul” → “Müller”). Indices stay in the original text. `all`: every match, else the first.\n */\nexport function matchParts(text: string, query: string, all = false): { text: string; match: boolean }[] {\n const q = plain(query.trim());\n if (!q) return [{ text, match: false }];\n // Map every character of the text to its plain form, so indices stay in the original text.\n const chars = [...text];\n const map: number[] = [];\n let flat = '';\n chars.forEach((char, i) => {\n const p = plain(char);\n flat += p;\n for (let k = 0; k < p.length; k++) map.push(i);\n });\n const parts: { text: string; match: boolean }[] = [];\n let last = 0;\n let from = 0;\n while (from <= flat.length - q.length) {\n const at = flat.indexOf(q, from);\n if (at < 0) break;\n const start = map[at];\n const end = map[at + q.length - 1] + 1;\n if (start > last) parts.push({ text: chars.slice(last, start).join(''), match: false });\n parts.push({ text: chars.slice(start, end).join(''), match: true });\n last = end;\n from = at + q.length;\n if (!all) break;\n }\n if (last < chars.length) parts.push({ text: chars.slice(last).join(''), match: false });\n return parts;\n}\n\n/** Shows the matching parts of a text in bold (`className` on each match). Visual only; screen readers read plain text. */\nexport function Highlight({\n text,\n query,\n all = false,\n as: Tag = 'mark',\n className,\n}: {\n text: string;\n query?: string;\n all?: boolean;\n as?: 'mark' | 'span';\n className?: string;\n}): ReactNode {\n if (!query?.trim()) return text;\n return matchParts(text, query, all).map((part, i) =>\n part.match ? (\n <Tag key={i} className={className}>\n {part.text}\n </Tag>\n ) : (\n part.text\n ),\n );\n}\n","import { useContext, useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Popover,\n Select as AriaSelect,\n SelectStateContext,\n SelectValue,\n type Key,\n type SelectProps as AriaSelectProps,\n} from 'react-aria-components';\nimport { ChevronDown, X } from 'lucide-react';\nimport { BottomSheetPopover } from '../bottom-sheet/BottomSheet';\nimport { Button } from '../button/Button';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox } from '../listbox/ListBox';\nimport { InputAction, type InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { useFitCount } from '../utils/useFitCount';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { useMessages } from '../i18n/I18n';\n\ntype SelectMode = 'single' | 'multiple';\ntype ValueOf<M extends SelectMode> = M extends 'multiple' ? Key[] : Key | null;\n\n/** Where the options open. auto: popover on desktop; below 640 px native picker (single) or Bottom Sheet (multi). */\nexport type SelectOverlay = 'auto' | 'popover' | 'sheet' | 'native';\n\nexport interface SelectProps<T extends object, M extends SelectMode = 'single'> extends Omit<AriaSelectProps<T, M>, 'children' | 'className' | 'style' | 'placeholder'> {\n /** Visible label. Without it set `aria-label` – only where the context names the field (filter bars, toolbars). */\n label?: ReactNode;\n /** Helper text below the field. Replaced by the error message when invalid. */\n description?: ReactNode;\n /** Error text shown when the field is invalid. Validate on submit or blur, not while open. */\n errorMessage?: ReactNode;\n /** A hint like “Select…”. Never required information. */\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. lg on mobile (opens the lg list). */\n size?: InputSize;\n /** Decorative icon before the value. */\n leadingIcon?: ReactNode;\n /** Single only: shows a clear button for optional fields. Multi always has clear-all. */\n clearable?: boolean;\n /** Value can be read and copied but not changed. Not the same as disabled. */\n isReadOnly?: boolean;\n /** Options as data; then pass a render function as children. */\n items?: Iterable<T>;\n /** Option and ListBoxSection elements, or a render function with items. */\n children: ReactNode | ((item: T) => ReactNode);\n /** auto (default) · popover · sheet (Bottom Sheet) · native (system picker, single only). */\n overlay?: SelectOverlay;\n /**\n * Multi: what happens with the selection. live (forms): it is the value, nothing else happens.\n * onClose (filters, reloads): `onApply` runs once when the list closes – any way – and only if the selection changed.\n */\n commit?: 'live' | 'onClose';\n /** commit=\"onClose\": apply the selection (load results, write the URL …). */\n onApply?: (value: ValueOf<M>) => void;\n /** commit=\"onClose\": label of the primary sheet button, ideally with the live result count (“Show 128 results”). */\n resultLabel?: (value: ValueOf<M>) => ReactNode;\n className?: string;\n}\n\n/**\n * Select – choose one or several values from a list.\n * Built on React Aria Select with a hidden native select: forms, autofill and validation keep working.\n * 2–4 options: Radio. 5–10: Select. More, or users know what to type: Combobox.\n */\nexport function Select<T extends object, M extends SelectMode = 'single'>({\n label,\n description,\n errorMessage,\n placeholder: placeholderProp,\n size = 'md',\n leadingIcon,\n clearable,\n isReadOnly,\n items,\n children,\n overlay = 'auto',\n commit = 'live',\n onApply,\n resultLabel: resultLabelProp,\n className,\n selectionMode,\n ...props\n}: SelectProps<T, M>) {\n const m = useMessages();\n const placeholder = placeholderProp ?? m.select.placeholder;\n const resultLabel = resultLabelProp ?? (() => m.common.showResults);\n const multiple = selectionMode === 'multiple';\n const mobile = useMediaQuery(MOBILE_QUERY);\n const mode = overlay === 'auto' ? (mobile ? (multiple ? 'sheet' : 'native') : 'popover') : overlay === 'native' && multiple ? 'sheet' : overlay;\n const [hasValue, setHasValue] = useState(false);\n /* The popover aligns to the whole field (border incl.), not only the inner trigger button. */\n const fieldRef = useRef<HTMLDivElement>(null);\n return (\n <AriaSelect<T, M>\n {...props}\n selectionMode={selectionMode}\n placeholder={placeholder}\n /* Read-only: never opens. */\n isOpen={isReadOnly ? false : props.isOpen}\n data-readonly={isReadOnly || undefined}\n className={cx(\n 'medo-field',\n 'medo-select',\n multiple && hasValue && 'medo-select--tags',\n (multiple || clearable) && hasValue && !isReadOnly && !props.isDisabled && 'medo-select--clearable',\n className,\n )}\n >\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <div ref={fieldRef} className={cx('medo-input', `medo-input--${size}`, 'medo-select__field')}>\n <ReadOnlyKeys isReadOnly={isReadOnly}>\n {/* With the native picker the invisible <select> on top takes focus and taps; the button only shows the value. */}\n <AriaButton className=\"medo-select__trigger\" excludeFromTabOrder={mode === 'native'} aria-hidden={mode === 'native' || undefined}>\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n <SelectValue<T> className=\"medo-select__value\">\n {/* The field shows only the label of the option – no description or option icon (one line, ellipsis). */}\n {({ defaultChildren, isPlaceholder, selectedText }) => (\n <>\n {isPlaceholder ? defaultChildren : multiple ? <SelectedTags size={size} /> : selectedText}\n {isReadOnly && <span className=\"medo-visually-hidden\">, read only</span>}\n </>\n )}\n </SelectValue>\n {!isReadOnly && (\n <span className=\"medo-select__chevron\" aria-hidden=\"true\">\n <ChevronDown />\n </span>\n )}\n </AriaButton>\n </ReadOnlyKeys>\n {mode === 'native' && !isReadOnly && <NativePicker label={label ?? props['aria-label']} placeholder={placeholder} isRequired={props.isRequired} />}\n <ClearButton enabled={(multiple || !!clearable) && !isReadOnly && !props.isDisabled} onHasValue={setHasValue} />\n </div>\n <FieldFooter description={description} errorMessage={errorMessage} />\n {commit === 'onClose' && onApply && <ApplyOnClose onApply={onApply as (value: Key[] | Key | null) => void} />}\n {mode === 'sheet' ? (\n <BottomSheetPopover\n title={label ?? props['aria-label']}\n footer={multiple ? <SheetFooter commit={commit} resultLabel={resultLabel as (value: Key[] | Key | null) => ReactNode} /> : undefined}\n >\n <ListBox<T> size=\"lg\" items={items}>\n {children}\n </ListBox>\n </BottomSheetPopover>\n ) : (\n <Popover triggerRef={fieldRef} offset={4} className=\"medo-listbox-popover\">\n <ListBox<T> size={size === 'lg' ? 'lg' : 'md'} items={items}>\n {children}\n </ListBox>\n </Popover>\n )}\n </AriaSelect>\n );\n}\n\n/** Read-only: blocks type-to-select and arrow keys on the trigger; Tab still moves on. */\nfunction ReadOnlyKeys({ isReadOnly, children }: { isReadOnly?: boolean; children: ReactNode }) {\n if (!isReadOnly) return <>{children}</>;\n const block = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') e.stopPropagation();\n };\n return (\n <div style={{ display: 'contents' }} onKeyDownCapture={block}>\n {children}\n </div>\n );\n}\n\n/** Clear (single, optional) or clear-all (multi). Next to the trigger, never inside it. */\nfunction ClearButton({ enabled, onHasValue }: { enabled: boolean; onHasValue: (v: boolean) => void }) {\n const m = useMessages();\n const state = useContext(SelectStateContext);\n const hasValue = !!state && (Array.isArray(state.value) ? state.value.length > 0 : state.value != null);\n useLayoutEffect(() => onHasValue(hasValue), [hasValue, onHasValue]);\n const ref = useRef<HTMLSpanElement>(null);\n if (!enabled || !hasValue || !state) return null;\n return (\n <span className=\"medo-select__clear\" ref={ref}>\n <InputAction\n // slot={null}: opts out of the Select's trigger context, so this stays its own button.\n slot={null}\n aria-label={Array.isArray(state.value) ? m.common.clearAll : m.select.clearSelection}\n icon={<X />}\n onPress={() => {\n state.setValue(Array.isArray(state.value) ? [] : null);\n // The clear button disappears: move focus back to the trigger.\n (ref.current?.parentElement?.querySelector('.medo-select__trigger') as HTMLElement | null)?.focus();\n }}\n />\n </span>\n );\n}\n\n/** Selected values as tags in one line; what does not fit becomes “+N”. Screen readers get the full list. */\nfunction SelectedTags({ size }: { size: InputSize }) {\n const state = useContext(SelectStateContext);\n const labels = state?.selectedItems.map((item) => item.textValue) ?? [];\n const key = labels.join('\\u0000');\n const rowRef = useRef<HTMLSpanElement>(null);\n const measureRef = useRef<HTMLSpanElement>(null);\n const visible = useFitCount(rowRef, measureRef, key, labels.length);\n const tagClass = cx('medo-tag', size === 'lg' ? 'medo-tag--md' : 'medo-tag--sm');\n\n const hidden = labels.length - visible;\n return (\n <span className=\"medo-select__tags\" ref={rowRef}>\n <span className=\"medo-visually-hidden\">{labels.join(', ')}</span>\n <span className=\"medo-select__measure\" ref={measureRef} aria-hidden=\"true\">\n {labels.map((label, i) => (\n <span key={i} className={tagClass}>\n {label}\n </span>\n ))}\n <span className={tagClass}>+{labels.length}</span>\n </span>\n {labels.slice(0, visible).map((label, i) => (\n <span key={i} className={tagClass} aria-hidden=\"true\">\n <span className=\"medo-select__tag-label\">{label}</span>\n </span>\n ))}\n {hidden > 0 && (\n <span className={tagClass} aria-hidden=\"true\">\n +{hidden}\n </span>\n )}\n </span>\n );\n}\n\n/**\n * Mobile, single: an invisible native <select> over the field opens the system picker.\n * The options come from the Select's collection; the change goes into the same state.\n */\nfunction NativePicker({ label, placeholder, isRequired }: { label: ReactNode; placeholder: string; isRequired?: boolean }) {\n const state = useContext(SelectStateContext);\n if (!state) return null;\n const keys = new Map<string, Key>();\n const option = (key: Key) => {\n const node = state.collection.getItem(key);\n if (!node || node.type !== 'item') return null;\n keys.set(String(key), key);\n return (\n <option key={String(key)} value={String(key)} disabled={state.selectionManager.isDisabled(key)}>\n {node.textValue}\n </option>\n );\n };\n const value = state.value == null || Array.isArray(state.value) ? '' : String(state.value);\n return (\n <select\n className=\"medo-select__native\"\n aria-label={typeof label === 'string' ? label : undefined}\n required={isRequired}\n value={value}\n onChange={(e) => state.setValue(e.target.value === '' ? null : (keys.get(e.target.value) ?? e.target.value))}\n >\n <option value=\"\" disabled={isRequired}>\n {placeholder}\n </option>\n {[...state.collection].map((node) =>\n node.type === 'section' ? (\n <optgroup key={String(node.key)} label={node.textValue || node['aria-label'] || ''}>\n {[...state.collection.getChildren!(node.key)].map((child) => option(child.key))}\n </optgroup>\n ) : (\n option(node.key)\n ),\n )}\n </select>\n );\n}\n\n/** Sheet footer for multi: live → “3 selected” + Done · onClose → result button + Reset below (thumb reach). */\nfunction SheetFooter({ commit, resultLabel }: { commit: 'live' | 'onClose'; resultLabel: (value: Key[] | Key | null) => ReactNode }) {\n const m = useMessages();\n const state = useContext(SelectStateContext);\n if (!state) return null;\n const count = Array.isArray(state.value) ? state.value.length : state.value == null ? 0 : 1;\n return commit === 'onClose' ? (\n <>\n <Button size=\"lg\" onPress={() => state.close()}>\n {resultLabel(state.value as Key[])}\n </Button>\n <Button size=\"lg\" variant=\"secondary\" onPress={() => state.setValue([])} isDisabled={count === 0}>\n {m.common.reset}\n </Button>\n </>\n ) : (\n <>\n <p className=\"medo-sheet__count\" aria-live=\"polite\">\n {m.common.countSelected(count)}\n </p>\n <Button size=\"lg\" onPress={() => state.close()}>\n {m.common.done}\n </Button>\n </>\n );\n}\n\n/** commit=\"onClose\": calls onApply once when the list closes (any way), if the selection changed while open. */\nfunction ApplyOnClose({ onApply }: { onApply: (value: Key[] | Key | null) => void }) {\n const state = useContext(SelectStateContext);\n const opened = useRef<string | null>(null);\n const isOpen = !!state?.isOpen;\n useEffect(() => {\n if (!state) return;\n const snapshot = JSON.stringify(state.value);\n if (isOpen) opened.current = snapshot;\n else if (opened.current !== null) {\n if (opened.current !== snapshot) onApply(state.value as Key[]);\n opened.current = null;\n }\n // Only the open/close transition matters.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n return null;\n}\n","import { useContext, useId, useRef, type PointerEvent, type ReactNode } from 'react';\nimport { Dialog, Heading, Modal, ModalOverlay, OverlayTriggerStateContext, Popover, type ModalOverlayProps } from 'react-aria-components';\nimport { ChevronLeft, X } from 'lucide-react';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface BottomSheetProps extends Omit<ModalOverlayProps, 'children' | 'className' | 'style'> {\n /** Required: names the dialog (for a Select sheet: the field label). */\n title: ReactNode;\n /** Content; scrolls when taller than the sheet. */\n children: ReactNode;\n /** Sticky footer, e.g. a full-width primary action. A function gets `close`. */\n footer?: ReactNode | ((close: () => void) => ReactNode);\n /** content: height of the content, max 90 % · full: fixed 90 % (with search, so it does not jump). */\n height?: 'content' | 'full';\n /** Accessible name of the close button. */\n closeLabel?: string;\n /** Shows a back button before the title (second view, e.g. a submenu). */\n onBack?: () => void;\n /** Accessible name of the back button. */\n backLabel?: string;\n className?: string;\n}\n\n/** Share of the sheet height (or a fast flick) that closes it when swiped down. */\nconst CLOSE_DISTANCE = 0.25;\nconst CLOSE_VELOCITY = 0.5; // px per ms\n\n/**\n * Bottom Sheet – a modal layer from the bottom on small screens.\n * Built on React Aria ModalOverlay + Modal + Dialog: focus stays inside and returns to the trigger,\n * page scroll is locked, Esc and a tap on the scrim close it. Swipe down on the handle or header closes it,\n * the close button is the non-drag alternative (WCAG 2.5.7). Use inside a DialogTrigger or with isOpen.\n */\nexport function BottomSheet({\n title,\n children,\n footer,\n height = 'content',\n closeLabel,\n onBack,\n backLabel,\n isDismissable = true,\n className,\n ...props\n}: BottomSheetProps) {\n const m = useMessages();\n return (\n <ModalOverlay {...props} isDismissable={isDismissable} className=\"medo-sheet-overlay\">\n <Modal className={cx('medo-sheet', height === 'full' && 'medo-sheet--full', className)}>\n <Dialog className=\"medo-sheet__dialog\">\n {({ close }) => (\n <>\n <SwipeArea onClose={close}>\n <span className=\"medo-sheet__handle\" aria-hidden=\"true\" />\n <div className=\"medo-sheet__header\">\n {onBack && (\n <IconButton variant=\"ghost\" size=\"lg\" icon={<ChevronLeft />} aria-label={backLabel ?? m.common.back} tooltip={false} onPress={onBack} />\n )}\n <Heading slot=\"title\" className=\"medo-sheet__title\">\n {title}\n </Heading>\n <IconButton variant=\"ghost\" size=\"lg\" icon={<X />} aria-label={closeLabel ?? m.common.close} tooltip={false} onPress={close} />\n </div>\n </SwipeArea>\n <div className=\"medo-sheet__content\">{children}</div>\n {footer && <div className=\"medo-sheet__footer\">{typeof footer === 'function' ? footer(close) : footer}</div>}\n </>\n )}\n </Dialog>\n </Modal>\n </ModalOverlay>\n );\n}\n\n/** Handle and header: drag down to close (touch, pen or mouse). Buttons inside keep working. */\nfunction SwipeArea({ onClose, children }: { onClose: () => void; children: ReactNode }) {\n const drag = useRef<{ y: number; t: number; sheet: HTMLElement } | null>(null);\n\n const onPointerDown = (e: PointerEvent<HTMLDivElement>) => {\n if ((e.target as HTMLElement).closest('button')) return;\n const sheet = e.currentTarget.closest<HTMLElement>('.medo-sheet');\n if (!sheet) return;\n drag.current = { y: e.clientY, t: e.timeStamp, sheet };\n e.currentTarget.setPointerCapture(e.pointerId);\n sheet.setAttribute('data-dragging', '');\n };\n\n const onPointerMove = (e: PointerEvent<HTMLDivElement>) => {\n if (!drag.current) return;\n const dy = Math.max(0, e.clientY - drag.current.y);\n drag.current.sheet.style.transform = `translateY(${dy}px)`;\n };\n\n const end = (e: PointerEvent<HTMLDivElement>) => {\n const d = drag.current;\n if (!d) return;\n drag.current = null;\n const dy = Math.max(0, e.clientY - d.y);\n const velocity = dy / Math.max(1, e.timeStamp - d.t);\n d.sheet.removeAttribute('data-dragging');\n d.sheet.style.transform = '';\n if (dy > d.sheet.offsetHeight * CLOSE_DISTANCE || (velocity > CLOSE_VELOCITY && dy > 24)) onClose();\n };\n\n return (\n <div className=\"medo-sheet__grab\" onPointerDown={onPointerDown} onPointerMove={onPointerMove} onPointerUp={end} onPointerCancel={end}>\n {children}\n </div>\n );\n}\n\n/**\n * Bottom Sheet as the popover of a Select. React Aria builds the Select's list\n * from its Popover even while closed – a Modal would hide the options from it – so the sheet is a\n * full-screen popover here: same look, same closing (swipe, scrim, Esc, close button), focus stays inside.\n */\nexport function BottomSheetPopover({\n title,\n children,\n footer,\n height = 'content',\n closeLabel,\n}: Pick<BottomSheetProps, 'title' | 'children' | 'footer' | 'height' | 'closeLabel'>) {\n return (\n <Popover className=\"medo-sheet-overlay medo-sheet-overlay--popover\" offset={0} containerPadding={0}>\n <SheetPopoverBody title={title} footer={footer} height={height} closeLabel={closeLabel}>\n {children}\n </SheetPopoverBody>\n </Popover>\n );\n}\n\nfunction SheetPopoverBody({ title, children, footer, height, closeLabel }: Omit<BottomSheetProps, 'isDismissable' | 'className'>) {\n const m = useMessages();\n const state = useContext(OverlayTriggerStateContext);\n const titleId = useId();\n const close = () => state?.close();\n return (\n // A tap on the scrim (outside the sheet) closes it.\n <div className=\"medo-sheet-scrim\" onClick={(e) => e.target === e.currentTarget && close()}>\n <section className={cx('medo-sheet', height === 'full' && 'medo-sheet--full')} aria-labelledby={titleId}>\n <SwipeArea onClose={close}>\n <span className=\"medo-sheet__handle\" aria-hidden=\"true\" />\n <div className=\"medo-sheet__header\">\n <h2 id={titleId} className=\"medo-sheet__title\">\n {title}\n </h2>\n <IconButton slot={null} variant=\"ghost\" size=\"lg\" icon={<X />} aria-label={closeLabel ?? m.common.close} tooltip={false} onPress={close} />\n </div>\n </SwipeArea>\n <div className=\"medo-sheet__content\">{children}</div>\n {footer && <div className=\"medo-sheet__footer\">{typeof footer === 'function' ? footer(close) : footer}</div>}\n </section>\n </div>\n );\n}\n","import { useLayoutEffect, useState, type RefObject } from 'react';\n\n/**\n * How many items of a one-line row fit, keeping room for a “+N” item (Select and Combobox tags).\n *\n * The caller renders a hidden measure row (same gap as the visible row): one child per item and,\n * as the last child, a “+N” probe. `reserve` keeps extra space free, e.g. for a text input.\n * At least one item stays visible (it may truncate).\n */\nexport function useFitCount(\n rowRef: RefObject<HTMLElement | null>,\n measureRef: RefObject<HTMLElement | null>,\n key: string,\n total: number,\n reserve = 0,\n) {\n const [visible, setVisible] = useState(total);\n\n useLayoutEffect(() => {\n const row = rowRef.current;\n const measure = measureRef.current;\n if (!row || !measure) return;\n const fit = () => {\n const items = [...measure.children] as HTMLElement[];\n const plus = items.pop();\n const gap = parseFloat(getComputedStyle(measure).columnGap) || 0;\n const avail = row.clientWidth - reserve;\n let used = 0;\n let count = 0;\n for (let i = 0; i < items.length; i++) {\n const width = items[i].offsetWidth + (i ? gap : 0);\n const plusRoom = i < items.length - 1 ? gap + (plus?.offsetWidth ?? 0) : 0;\n if (used + width + plusRoom > avail) break;\n used += width;\n count = i + 1;\n }\n setVisible(Math.min(total, Math.max(1, count)));\n };\n fit();\n const observer = new ResizeObserver(fit);\n observer.observe(row);\n return () => observer.disconnect();\n }, [rowRef, measureRef, key, total, reserve]);\n\n return Math.min(visible, total);\n}\n","import { useSyncExternalStore } from 'react';\n\n/** Below breakpoint/sm (640 px): mobile behaviour for Select, Combobox and Bottom Sheet. */\nexport const MOBILE_QUERY = '(max-width: 639.98px)';\n\n/** True while the media query matches. SSR-safe (false on the server). */\nexport function useMediaQuery(query: string) {\n return useSyncExternalStore(\n (onChange) => {\n const list = window.matchMedia(query);\n list.addEventListener('change', onChange);\n return () => list.removeEventListener('change', onChange);\n },\n () => window.matchMedia(query).matches,\n () => false,\n );\n}\n","import { createContext, useContext, useState, type ReactNode } from 'react';\nimport {\n Header,\n Keyboard,\n Menu as AriaMenu,\n MenuItem as AriaMenuItem,\n MenuSection as AriaMenuSection,\n MenuTrigger as AriaMenuTrigger,\n Popover,\n SubmenuTrigger,\n Text,\n type MenuItemProps as AriaMenuItemProps,\n type MenuProps as AriaMenuProps,\n type MenuTriggerProps as AriaMenuTriggerProps,\n} from 'react-aria-components';\nimport { ChevronRight, Ellipsis } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { IconButton } from '../icon-button/IconButton';\nimport { formatShortcut } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { useMessages } from '../i18n/I18n';\n\ntype MenuSize = 'md' | 'lg';\n\n/** md: desktop popover · lg: mobile sheet (no shortcuts); push opens a submenu as second view in the sheet. */\ninterface MenuMode {\n size: MenuSize;\n push?: (title: ReactNode, children: ReactNode) => void;\n}\nconst MenuModeContext = createContext<MenuMode>({ size: 'md' });\n\nexport interface MenuTriggerProps extends Omit<AriaMenuTriggerProps, 'children'> {\n /** The trigger (default: an ellipsis Icon Button) and the Menu. Without a trigger, pass `label`. */\n children: ReactNode;\n}\n\n/** Opens a Menu from a trigger (React Aria MenuTrigger). Focus returns to the trigger. */\nexport function MenuTrigger(props: MenuTriggerProps) {\n return <AriaMenuTrigger {...props} />;\n}\n\n/**\n * Default trigger: ghost Icon Button with an ellipsis. The name includes the object\n * (“More actions for Q3-Report.pdf”); it looks pressed while the menu is open.\n */\nexport function MenuButton({ 'aria-label': label, size = 'md' }: { 'aria-label': string; size?: 'sm' | 'md' | 'lg' }) {\n return <IconButton variant=\"ghost\" size={size} icon={<Ellipsis />} aria-label={label} />;\n}\n\nexport interface MenuProps<T> extends Omit<AriaMenuProps<T>, 'className' | 'style'> {\n /** Mobile sheet title: the object the actions apply to (“Q3-Report.pdf”). */\n title?: ReactNode;\n /** auto: popover on desktop, Bottom Sheet below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n className?: string;\n}\n\n/**\n * Menu – a list of actions. Built on React Aria Menu: arrow keys, Enter runs the item,\n * Esc closes, type to jump, Home/End. Every item has an icon, labels start with a verb; danger items last.\n * Not for values (Select) or site navigation (disclosure pattern).\n */\nexport function Menu<T extends object>({ title, overlay = 'auto', className, ...props }: MenuProps<T>) {\n const mobile = useMediaQuery(MOBILE_QUERY);\n const sheet = overlay === 'sheet' || (overlay === 'auto' && mobile);\n if (sheet) return <SheetMenu title={title} className={className} {...props} />;\n return (\n <Popover placement=\"bottom end\" offset={4} className=\"medo-menu-popover\">\n <MenuModeContext.Provider value={{ size: 'md' }}>\n <AriaMenu {...props} className={cx('medo-menu', 'medo-menu--md', className)} />\n </MenuModeContext.Provider>\n </Popover>\n );\n}\n\n/** Mobile: Bottom Sheet with lg items; a submenu replaces the list as a second view with a back button. */\nfunction SheetMenu<T extends object>({ title, className, ...props }: Omit<MenuProps<T>, 'overlay'>) {\n const [view, setView] = useState<{ title: ReactNode; children: ReactNode } | null>(null);\n return (\n <BottomSheet\n title={view ? view.title : (title ?? props['aria-label'])}\n onBack={view ? () => setView(null) : undefined}\n onOpenChange={(open) => !open && setView(null)}\n >\n <MenuModeContext.Provider value={{ size: 'lg', push: (t, c) => setView({ title: t, children: c }) }}>\n {view ? (\n <AriaMenu key=\"sub\" aria-label={typeof view.title === 'string' ? view.title : undefined} autoFocus=\"first\" className={cx('medo-menu', 'medo-menu--lg', className)}>\n {view.children}\n </AriaMenu>\n ) : (\n <AriaMenu {...props} key=\"main\" className={cx('medo-menu', 'medo-menu--lg', className)} />\n )}\n </MenuModeContext.Provider>\n </BottomSheet>\n );\n}\n\nexport interface MenuItemProps extends Omit<AriaMenuItemProps, 'children' | 'className' | 'style'> {\n /** Label, starting with a verb (“Duplicate”). “…” only when a dialog or second step follows. */\n children: string;\n /** Required: shows the action. Decorative for screen readers – the label carries the meaning. */\n icon: ReactNode;\n /** Keyboard shortcut in aria-keyshortcuts syntax; “Mod” = ⌘ on Apple, Ctrl elsewhere. Desktop only. It must also work without the menu. */\n shortcut?: string;\n /** Destructive action: red, last in its own group. Irreversible actions open a confirmation dialog. */\n variant?: 'default' | 'danger';\n}\n\n/** One action in a Menu. */\nexport function MenuItem({ children, icon, shortcut, variant = 'default', textValue, ...props }: MenuItemProps) {\n const m = useMessages();\n const { size } = useContext(MenuModeContext);\n return (\n <AriaMenuItem\n {...props}\n textValue={textValue ?? children}\n className={cx('medo-menu-item', variant === 'danger' && 'medo-menu-item--danger')}\n >\n {({ hasSubmenu }) => (\n <>\n <span className=\"medo-menu-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <Text slot=\"label\" className=\"medo-menu-item__label\">\n {children}\n </Text>\n {/* Keyboard is linked to the item (aria-describedby), so screen readers hear the shortcut. */}\n {shortcut && size === 'md' && <Keyboard className=\"medo-menu-item__shortcut\">{formatShortcut(shortcut, m.keys.control)}</Keyboard>}\n {hasSubmenu && (\n <span className=\"medo-menu-item__chevron\" aria-hidden=\"true\">\n <ChevronRight />\n </span>\n )}\n </>\n )}\n </AriaMenuItem>\n );\n}\n\nexport interface SubmenuProps {\n /** Label of the parent item. */\n label: string;\n icon: ReactNode;\n /** The submenu's items (one level only). */\n children: ReactNode;\n isDisabled?: boolean;\n}\n\n/** Submenu (one level). Desktop: opens to the side. Mobile: second view in the sheet with a back button. */\nexport function Submenu({ label, icon, children, isDisabled }: SubmenuProps) {\n const { size, push } = useContext(MenuModeContext);\n if (push) {\n return (\n <AriaMenuItem\n textValue={label}\n isDisabled={isDisabled}\n shouldCloseOnSelect={false}\n onAction={() => push(label, children)}\n className=\"medo-menu-item\"\n >\n <span className=\"medo-menu-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <Text slot=\"label\" className=\"medo-menu-item__label\">\n {label}\n </Text>\n <span className=\"medo-menu-item__chevron\" aria-hidden=\"true\">\n <ChevronRight />\n </span>\n </AriaMenuItem>\n );\n }\n return (\n <SubmenuTrigger>\n <MenuItem icon={icon} isDisabled={isDisabled}>\n {label}\n </MenuItem>\n {/* Side placement, first item level with the parent item (popover padding + border). */}\n <Popover placement=\"end top\" offset={4} crossOffset={-5} className=\"medo-menu-popover\">\n <AriaMenu aria-label={label} className={cx('medo-menu', `medo-menu--${size}`)}>\n {children}\n </AriaMenu>\n </Popover>\n </SubmenuTrigger>\n );\n}\n\nexport interface MenuSectionProps {\n /** Optional overline heading. Without a title the group is only divided by a line; then set aria-label if it helps. */\n title?: ReactNode;\n 'aria-label'?: string;\n children: ReactNode;\n}\n\n/** A group of related actions. Groups are divided by a line; the danger group comes last. */\nexport function MenuSection({ title, children, ...props }: MenuSectionProps) {\n return (\n <AriaMenuSection aria-label={props['aria-label']} className=\"medo-menu__section\">\n {title && <Header className=\"medo-listbox__header\">{title}</Header>}\n {children}\n </AriaMenuSection>\n );\n}\n","import { useContext, useEffect, useId, useLayoutEffect, useRef, useState, type ReactNode } from 'react';\nimport { Dialog as AriaDialog, DialogContext, Heading, Modal, ModalOverlay, OverlayTriggerStateContext, Provider } from 'react-aria-components';\nimport { CircleAlert, Info, TriangleAlert, X } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button, ButtonGroup, type ButtonSize } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { useMessages } from '../i18n/I18n';\n\n/** Opens a Dialog or Alert dialog from a trigger (React Aria DialogTrigger). Focus returns to the trigger. */\nexport { DialogTrigger } from 'react-aria-components';\n\n/* ---------- Shared ---------- */\n\nexport interface DialogAction {\n /** Verb that says what happens (“Send invite”, “Delete”). Never “OK”, “Yes” or “Confirm”. */\n label: string;\n /**\n * Runs on press, then the dialog closes. Return a promise to show the pending state until it\n * resolves; when it rejects, the dialog stays open (show the error inside the dialog).\n */\n onAction?: () => void | Promise<unknown>;\n /** Id of a form in the dialog: the button submits it. The form's onSubmit saves and calls `close`. */\n form?: string;\n /** Dialog only: danger for a destructive main action. */\n variant?: 'primary' | 'danger';\n isDisabled?: boolean;\n /** Controlled pending state (e.g. while a submitted form saves). */\n isPending?: boolean;\n}\n\ninterface OpenProps {\n /** Controlled open state. Inside a DialogTrigger the trigger controls it. */\n isOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n}\n\n/** Open state from props, else from the surrounding DialogTrigger. */\nfunction useOpenState({ isOpen, onOpenChange }: OpenProps) {\n const trigger = useContext(OverlayTriggerStateContext);\n const open = isOpen ?? trigger?.isOpen ?? false;\n const setOpen = (next: boolean) => {\n onOpenChange?.(next);\n if (isOpen === undefined) trigger?.setOpen(next);\n };\n return [open, setOpen] as const;\n}\n\n/** Main action button: runs the action and closes; a promise shows the pending state. Shared with Popover (internal, not exported from the package). */\nexport function ActionButton({ action, close, size, variant }: { action: DialogAction; close: () => void; size: ButtonSize; variant: 'primary' | 'danger' }) {\n const [pending, setPending] = useState(false);\n const run = async () => {\n const result = action.onAction?.();\n if (!(result instanceof Promise)) return close();\n setPending(true);\n try {\n await result;\n close();\n } finally {\n setPending(false);\n }\n };\n return (\n <Button\n variant={action.variant ?? variant}\n size={size}\n type={action.form ? 'submit' : 'button'}\n form={action.form}\n isDisabled={action.isDisabled}\n isPending={action.isPending || pending}\n onPress={action.form ? undefined : run}\n >\n {action.label}\n </Button>\n );\n}\n\n/** A nested modal must not inherit the outer dialog's trigger, ids or state. */\nfunction Nested({ children }: { children: ReactNode }) {\n return (\n <Provider\n values={[\n [DialogContext, null],\n [OverlayTriggerStateContext, null],\n ]}\n >\n {children}\n </Provider>\n );\n}\n\n/* ---------- Dialog ---------- */\n\nexport interface DirtyGuardProps extends OpenProps {\n isDirty?: boolean;\n discardText?: Partial<DialogDiscardText>;\n}\n\n/**\n * Open state with the “Discard changes?” guard (protects unsaved input). Every way of closing\n * (X, Cancel, Esc, swipe) goes through onOpenChange; with unsaved input it asks first.\n * Render `confirmDiscard` inside the dialog. Shared with Drawer (internal).\n */\nexport function useDirtyGuard({ isDirty = false, discardText, ...openProps }: DirtyGuardProps) {\n const [open, setOpen] = useOpenState(openProps);\n const [confirm, setConfirm] = useState(false);\n const onOpenChange = (next: boolean) => {\n if (next || !isDirty) setOpen(next);\n else setConfirm(true);\n };\n const m = useMessages();\n const discard: DialogDiscardText = {\n title: m.dialog.discardTitle,\n description: m.dialog.discardDescription,\n actionLabel: m.dialog.discardAction,\n cancelLabel: m.dialog.discardCancel,\n ...discardText,\n };\n const confirmDiscard = (\n <Nested>\n <AlertDialog\n tone=\"warning\"\n isOpen={confirm}\n onOpenChange={setConfirm}\n title={discard.title}\n actionLabel={discard.actionLabel}\n cancelLabel={discard.cancelLabel}\n onAction={() => setOpen(false)}\n >\n {discard.description}\n </AlertDialog>\n </Nested>\n );\n /** Deliberate close after saving – does not ask. */\n const forceClose = () => setOpen(false);\n return { open, onOpenChange, confirmDiscard, forceClose };\n}\n\nexport interface DialogDiscardText {\n title: string;\n description: string;\n actionLabel: string;\n cancelLabel: string;\n}\n\nexport interface DialogProps extends OpenProps {\n /** Required. Names the task (“Invite member”). Screen readers announce it when the dialog opens. */\n title: ReactNode;\n /** One or two sentences under the title. */\n description?: ReactNode;\n /** Content or form. A function gets `close`: closes without asking – call it after saving (X, Cancel and Esc still ask when isDirty). */\n children?: ReactNode | ((close: () => void) => ReactNode);\n /** sm 400 (one or two fields) · md 560 · lg 720 (tables, two-column forms). */\n size?: 'sm' | 'md' | 'lg';\n /** Main action at the end of the footer, next to Cancel. On mobile fullscreen it moves to the header. Without it, no footer. */\n primaryAction?: DialogAction;\n cancelLabel?: string;\n /** Accessible name of the X (and the label of the mobile close button without a main action). */\n closeLabel?: string;\n /** Shows the X in the header. */\n showClose?: boolean;\n /**\n * Unsaved input. While true, a click on the scrim no longer closes, and X, Esc and Cancel\n * first ask “Discard changes?” (Alert dialog).\n */\n isDirty?: boolean;\n /** Text of the “Discard changes?” Alert dialog. */\n discardText?: Partial<DialogDiscardText>;\n /** auto: dialog on desktop, `mobile` below 640 px · dialog · fullscreen · sheet. */\n overlay?: 'auto' | 'dialog' | 'fullscreen' | 'sheet';\n /** Pattern below 640 px: fullscreen for forms (keyboard needs space), sheet for short content. */\n mobile?: 'fullscreen' | 'sheet';\n className?: string;\n}\n\n/**\n * Dialog – a modal window for a focused task. Built on React Aria ModalOverlay,\n * Modal and Dialog: role dialog with aria-modal, the title names it, focus starts in the first field,\n * stays inside and returns to the trigger; the page behind does not scroll. Use inside a DialogTrigger or with isOpen.\n */\nexport function Dialog({\n title,\n description,\n children,\n size = 'md',\n primaryAction,\n cancelLabel: cancelLabelProp,\n closeLabel: closeLabelProp,\n showClose = true,\n isDirty = false,\n discardText,\n overlay = 'auto',\n mobile = 'fullscreen',\n className,\n ...openProps\n}: DialogProps) {\n const m = useMessages();\n const cancelLabel = cancelLabelProp ?? m.common.cancel;\n const closeLabel = closeLabelProp ?? m.common.close;\n const { open, onOpenChange, confirmDiscard, forceClose } = useDirtyGuard({ isDirty, discardText, ...openProps });\n const isMobile = useMediaQuery(MOBILE_QUERY);\n const layout = overlay === 'auto' ? (isMobile ? mobile : 'dialog') : overlay;\n const content = (close: () => void) => (typeof children === 'function' ? children(close) : children);\n\n if (layout === 'sheet') {\n return (\n <BottomSheet\n title={title}\n closeLabel={closeLabel}\n isOpen={open}\n onOpenChange={onOpenChange}\n isDismissable={!isDirty}\n className={className}\n footer={\n primaryAction &&\n ((close) => (\n <ButtonGroup>\n <Button variant=\"secondary\" size=\"lg\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={forceClose} size=\"lg\" variant=\"primary\" />\n </ButtonGroup>\n ))\n }\n >\n <SheetContent description={description}>{content(forceClose)}</SheetContent>\n {confirmDiscard}\n </BottomSheet>\n );\n }\n\n const fullscreen = layout === 'fullscreen';\n return (\n <ModalOverlay\n isOpen={open}\n onOpenChange={onOpenChange}\n isDismissable={!isDirty}\n className={cx('medo-dialog-overlay', fullscreen && 'medo-dialog-overlay--fullscreen')}\n >\n <Modal className={cx('medo-dialog', fullscreen ? 'medo-dialog--fullscreen' : `medo-dialog--${size}`, className)}>\n <DialogFrame\n title={title}\n description={description}\n fullscreen={fullscreen}\n primaryAction={primaryAction}\n cancelLabel={cancelLabel}\n closeLabel={closeLabel}\n showClose={showClose}\n nested={confirmDiscard}\n forceClose={forceClose}\n >\n {content}\n </DialogFrame>\n </Modal>\n </ModalOverlay>\n );\n}\n\ninterface FrameProps extends Pick<DialogProps, 'title' | 'description' | 'primaryAction' | 'showClose'> {\n fullscreen: boolean;\n cancelLabel: string;\n closeLabel: string;\n /** Rendered inside the dialog (focus scope): the “Discard changes?” Alert dialog. */\n nested: ReactNode;\n /** Closes without asking: the main action and the content's `close` (after saving). */\n forceClose: () => void;\n children: (close: () => void) => ReactNode;\n}\n\n/** Header, scrolling body and footer of the centered and the fullscreen dialog. */\nfunction DialogFrame({ title, description, fullscreen, primaryAction, cancelLabel, closeLabel, showClose, nested, forceClose, children }: FrameProps) {\n const descriptionId = useId();\n const ref = useRef<HTMLElement>(null);\n const [scrolls, setScrolls] = useState(false);\n useInitialFocus(ref);\n\n return (\n <AriaDialog ref={ref} className=\"medo-dialog__dialog\" aria-describedby={description ? descriptionId : undefined} data-scrolled={scrolls || undefined}>\n {({ close }) =>\n fullscreen ? (\n <>\n {/* Mobile: Cancel left, title centered, main action right – always visible above the keyboard. */}\n <div className=\"medo-dialog__bar\">\n <Button variant=\"ghost\" size=\"md\" onPress={close}>\n {primaryAction ? cancelLabel : closeLabel}\n </Button>\n <Heading slot=\"title\" className=\"medo-dialog__bar-title\">\n {title}\n </Heading>\n {primaryAction ? <ActionButton action={primaryAction} close={forceClose} size=\"md\" variant=\"primary\" /> : <span />}\n </div>\n <DialogBody onScrollsChange={setScrolls}>\n {description && (\n <p id={descriptionId} className=\"medo-dialog__description\">\n {description}\n </p>\n )}\n {children(forceClose)}\n </DialogBody>\n {nested}\n </>\n ) : (\n <>\n <div className=\"medo-dialog__header\">\n <div className=\"medo-dialog__heading\">\n <Heading slot=\"title\" className=\"medo-dialog__title\">\n {title}\n </Heading>\n {description && (\n <p id={descriptionId} className=\"medo-dialog__description\">\n {description}\n </p>\n )}\n </div>\n {showClose && <IconButton variant=\"ghost\" size=\"sm\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />}\n </div>\n <DialogBody onScrollsChange={setScrolls}>{children(forceClose)}</DialogBody>\n {primaryAction && (\n <div className=\"medo-dialog__footer\">\n <ButtonGroup>\n <Button variant=\"secondary\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={forceClose} size=\"md\" variant=\"primary\" />\n </ButtonGroup>\n </div>\n )}\n {nested}\n </>\n )\n }\n </AriaDialog>\n );\n}\n\n/** Only the body scrolls. While it does, it is focusable (keyboard scrolling) and header and footer get dividers. */\nfunction DialogBody({ children, onScrollsChange }: { children: ReactNode; onScrollsChange: (scrolls: boolean) => void }) {\n const ref = useRef<HTMLDivElement>(null);\n const [scrolls, setScrolls] = useState(false);\n useLayoutEffect(() => {\n const body = ref.current;\n if (!body) return;\n const check = () => setScrolls(body.scrollHeight > body.clientHeight + 1);\n const observer = new ResizeObserver(check);\n observer.observe(body);\n if (body.firstElementChild) observer.observe(body.firstElementChild);\n check();\n return () => observer.disconnect();\n }, []);\n useEffect(() => onScrollsChange(scrolls), [scrolls, onScrollsChange]);\n return (\n <div ref={ref} className=\"medo-dialog__body\" tabIndex={scrolls ? 0 : undefined}>\n <div className=\"medo-dialog__body-inner\">{children}</div>\n </div>\n );\n}\n\n/** Bottom Sheet content: description and the dialog content with the sheet's padding. */\nfunction SheetContent({ description, children }: { description: ReactNode; children: ReactNode }) {\n return (\n <div className=\"medo-dialog__sheet-body\">\n {description && <p className=\"medo-dialog__description\">{description}</p>}\n {children}\n </div>\n );\n}\n\n/** Focus starts in the first field, else on the first button. */\nconst FIELDS = 'input, textarea, select, [role=\"combobox\"], button[aria-haspopup=\"listbox\"]';\nexport function useInitialFocus(ref: React.RefObject<HTMLElement | null>) {\n useEffect(() => {\n const root = ref.current;\n if (!root) return;\n const usable = (el: HTMLElement) => el.tabIndex >= 0 && !el.closest('[aria-hidden=\"true\"], [inert]') && !el.matches(':disabled');\n const field = [...root.querySelectorAll<HTMLElement>(FIELDS)].find(usable);\n (field ?? [...root.querySelectorAll<HTMLElement>('button')].find(usable))?.focus();\n }, [ref]);\n}\n\n/* ---------- Alert dialog ---------- */\n\nexport type AlertDialogTone = 'danger' | 'warning' | 'info';\n\n/** Same icons as the Alert: danger = circle-alert, warning = triangle-alert, info = info. */\nconst TONE_ICONS: Record<AlertDialogTone, typeof Info> = {\n danger: CircleAlert,\n warning: TriangleAlert,\n info: Info,\n};\n\nexport interface AlertDialogProps extends OpenProps {\n /** danger: irreversible or destructive · warning: risk of data loss · info: must be acknowledged. */\n tone?: AlertDialogTone;\n /** Required. A question (“Delete Q3-Report.pdf?”). */\n title: ReactNode;\n /** The consequence (“This cannot be undone.”). */\n children?: ReactNode;\n /** Verb of the action (“Delete”). Danger tone: danger button, else primary. */\n actionLabel: string;\n /** Runs, then the dialog closes. A promise shows the pending state until it resolves. */\n onAction?: () => void | Promise<unknown>;\n cancelLabel?: string;\n className?: string;\n}\n\n/**\n * Alert dialog – a decision that needs an answer before the user can go on.\n * role alertdialog, no X, a click on the scrim never closes, Esc = Cancel. Focus starts on Cancel,\n * so an accidental Enter never deletes. Below 640 px: icon on top, buttons stacked (lg).\n */\nexport function AlertDialog({ tone = 'danger', title, children, actionLabel, onAction, cancelLabel: cancelLabelProp, className, ...openProps }: AlertDialogProps) {\n const m = useMessages();\n const cancelLabel = cancelLabelProp ?? m.common.cancel;\n const [open, setOpen] = useOpenState(openProps);\n const isMobile = useMediaQuery(MOBILE_QUERY);\n const descriptionId = useId();\n const Icon = TONE_ICONS[tone];\n const size: ButtonSize = isMobile ? 'lg' : 'md';\n return (\n <ModalOverlay isOpen={open} onOpenChange={setOpen} isDismissable={false} className=\"medo-dialog-overlay\">\n <Modal className={cx('medo-dialog', 'medo-alert-dialog', `medo-alert-dialog--${tone}`, className)}>\n <AriaDialog role=\"alertdialog\" aria-describedby={children ? descriptionId : undefined} className=\"medo-dialog__dialog\">\n {({ close }) => (\n <>\n <div className=\"medo-alert-dialog__content\">\n <span className=\"medo-alert-dialog__icon\" aria-hidden=\"true\">\n <Icon />\n </span>\n <div className=\"medo-alert-dialog__text\">\n <Heading slot=\"title\" className=\"medo-alert-dialog__title\">\n {title}\n </Heading>\n {children && (\n <div id={descriptionId} className=\"medo-alert-dialog__description\">\n {children}\n </div>\n )}\n </div>\n </div>\n <ButtonGroup>\n <Button variant=\"secondary\" size={size} autoFocus onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={{ label: actionLabel, onAction }} close={close} size={size} variant={tone === 'danger' ? 'danger' : 'primary'} />\n </ButtonGroup>\n </>\n )}\n </AriaDialog>\n </Modal>\n </ModalOverlay>\n );\n}\n","import { useContext, useEffect, useId, useRef, useState, type KeyboardEvent, type MouseEvent, type ReactNode } from 'react';\nimport {\n Autocomplete,\n Button as AriaButton,\n Collection,\n CollectionBuilder,\n ComboBox as AriaComboBox,\n ComboBoxStateContext,\n Group,\n Input,\n Popover,\n TextField as AriaTextField,\n useFilter,\n type ComboBoxProps as AriaComboBoxProps,\n type Key,\n type Selection,\n} from 'react-aria-components';\nimport { ChevronDown, CircleAlert, Plus, Search, X } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button } from '../button/Button';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox, ListBoxMessage, ListBoxSection, OptionHighlightContext, Option } from '../listbox/ListBox';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { Tag, TagGroup } from '../tag/Tag';\nimport { InputAction, type InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { useFitCount } from '../utils/useFitCount';\nimport { useMessages } from '../i18n/I18n';\n\ntype ComboMode = 'single' | 'multiple';\ntype Value = Key | null | Key[];\n\n/** Key of the “Add …” row. Never stored as a value. */\nconst CREATE_KEY = '__medo_create__';\n\nexport interface ComboboxProps<T extends object, M extends ComboMode = 'single'>\n extends Omit<AriaComboBoxProps<T, M>, 'children' | 'className' | 'style' | 'placeholder' | 'menuTrigger'> {\n /** Visible label. Always set one. */\n label: ReactNode;\n /** Helper text below the field. Replaced by the error message when invalid. */\n description?: ReactNode;\n /** Error text shown when the field is invalid. */\n errorMessage?: ReactNode;\n /** A hint like “Search…”. */\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. lg on mobile. */\n size?: InputSize;\n /** Decorative icon before the text, e.g. a search icon. */\n leadingIcon?: ReactNode;\n /** Server search: shows a loading row (previous results stay) and marks the list busy. */\n isLoading?: boolean;\n /** Empty list text. Default: “No results for “…””. */\n noResultsMessage?: (inputValue: string) => ReactNode;\n /** Multi only: shows an “Add …” row for text without an exact match. Return the key of the new item to select it. */\n onCreate?: (text: string) => Key | void;\n /** Option and ListBoxSection elements, or a render function with items / defaultItems. */\n children: ReactNode | ((item: T) => ReactNode);\n /** auto (default): popover on desktop, Bottom Sheet with search below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n /** Multi in the sheet: live (forms, footer “Done”) · onClose (filters: onApply once when the sheet closes, if changed). */\n commit?: 'live' | 'onClose';\n /** commit=\"onClose\": apply the selection (load results, write the URL …). */\n onApply?: (value: Key[]) => void;\n /** commit=\"onClose\": label of the primary sheet button, ideally with the live result count. */\n resultLabel?: (value: Key[]) => ReactNode;\n className?: string;\n}\n\n/**\n * Combobox – a Select you can type into; typing filters the list.\n * Built on React Aria ComboBox: opens on typing, arrow down or the chevron – never on focus.\n * Contains-match, case and accent insensitive; the first match is highlighted, Enter picks it.\n * Leaving without a selection restores the last valid value.\n * Local data: `defaultItems` (filtered here). Server data: `items` + `inputValue` / `onInputChange` + `isLoading`.\n */\nexport function Combobox<T extends object, M extends ComboMode = 'single'>({\n label,\n description,\n errorMessage,\n placeholder: placeholderProp,\n size = 'md',\n leadingIcon,\n isLoading,\n noResultsMessage: noResultsProp,\n onCreate,\n children,\n overlay = 'auto',\n commit = 'live',\n onApply,\n resultLabel: resultLabelProp,\n className,\n selectionMode,\n value: valueProp,\n defaultValue,\n onChange,\n onInputChange,\n ...props\n}: ComboboxProps<T, M>) {\n const m = useMessages();\n const placeholder = placeholderProp ?? m.combobox.placeholder;\n const noResultsMessage = noResultsProp ?? ((text: string) => (text ? m.common.noResultsFor(text) : m.common.noResults));\n const resultLabel = resultLabelProp ?? (() => m.common.showResults);\n const multiple = selectionMode === 'multiple';\n const groupRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const entryRef = useRef<HTMLSpanElement>(null);\n const textRef = useRef('');\n const [text, setText] = useState('');\n const [exact, setExact] = useState(false);\n const [announcement, setAnnouncement] = useState('');\n\n // Own value state, so the “Add …” row can be intercepted before it becomes a value.\n const [inner, setInner] = useState<Value>((defaultValue as Value) ?? (multiple ? [] : null));\n const value = (valueProp !== undefined ? valueProp : inner) as Value;\n const setValue = (next: Value) => {\n if (valueProp === undefined) setInner(next);\n (onChange as ((v: Value) => void) | undefined)?.(next);\n };\n\n const handleChange = (next: Value) => {\n if (Array.isArray(next) && next.includes(CREATE_KEY)) {\n const rest = next.filter((k) => k !== CREATE_KEY);\n const created = onCreate?.(textRef.current.trim());\n setValue(created != null ? [...rest, created] : rest);\n return;\n }\n setValue(next);\n };\n\n const mobile = useMediaQuery(MOBILE_QUERY);\n if (overlay === 'sheet' || (overlay === 'auto' && mobile)) {\n return (\n <ComboboxSheet<T>\n {...{\n label,\n description,\n errorMessage,\n placeholder,\n size,\n leadingIcon,\n isLoading,\n noResultsMessage,\n onCreate,\n children,\n className,\n }}\n multiple={multiple}\n value={value}\n onValueChange={handleChange}\n textRef={textRef}\n items={props.items}\n defaultItems={props.defaultItems}\n inputValue={props.inputValue}\n onInputChange={onInputChange}\n isDisabled={props.isDisabled}\n isReadOnly={props.isReadOnly}\n isInvalid={props.isInvalid}\n isRequired={props.isRequired}\n name={props.name}\n commit={commit}\n onApply={onApply}\n resultLabel={resultLabel}\n />\n );\n }\n\n // Click on the free space of the field puts the caret into the input.\n const focusInput = (e: MouseEvent) => {\n if (e.target === e.currentTarget) {\n e.preventDefault();\n inputRef.current?.focus();\n }\n };\n\n return (\n <AriaComboBox<T, M>\n {...(props as AriaComboBoxProps<T, M>)}\n selectionMode={selectionMode}\n value={value as never}\n onChange={handleChange as never}\n onInputChange={(text) => {\n textRef.current = text;\n setText(text.trim());\n onInputChange?.(text);\n }}\n menuTrigger=\"input\"\n allowsEmptyCollection\n className={cx('medo-field', 'medo-combobox', className)}\n >\n <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>\n <Group ref={groupRef} className={cx('medo-input', `medo-input--${size}`, 'medo-combobox__field')} onMouseDown={focusInput}>\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n {multiple ? (\n /* Tags and input share one line; the tags get what is left after 4 rem for typing. */\n <span className=\"medo-combobox__entry\" ref={entryRef}>\n <SelectedTags entryRef={entryRef} size={size} label={label} isDisabled={props.isDisabled} isReadOnly={props.isReadOnly} />\n <ComboInput ref={inputRef} placeholder={placeholder} multiple onRemoved={setAnnouncement} />\n </span>\n ) : (\n <ComboInput ref={inputRef} placeholder={placeholder} multiple={false} onRemoved={setAnnouncement} />\n )}\n <ClearButton inputRef={inputRef} isDisabled={props.isDisabled || props.isReadOnly} />\n {!props.isReadOnly && (\n <AriaButton className=\"medo-input__action medo-combobox__toggle\">\n <ChevronDown aria-hidden=\"true\" />\n </AriaButton>\n )}\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage} />\n <span className=\"medo-visually-hidden\" aria-live=\"polite\">\n {announcement}\n </span>\n <Popover offset={4} className=\"medo-listbox-popover\">\n <ComboList<T>\n size={size}\n items={props.items ?? props.defaultItems}\n isLoading={isLoading}\n noResultsMessage={noResultsMessage}\n creatable={multiple && !!onCreate}\n text={text}\n exact={exact}\n onExactChange={setExact}\n >\n {children}\n </ComboList>\n </Popover>\n </AriaComboBox>\n );\n}\n\n/** Text input. Multi: Backspace in the empty input removes the last value. */\nfunction ComboInput({\n ref,\n placeholder,\n multiple,\n onRemoved,\n}: {\n ref: React.Ref<HTMLInputElement>;\n placeholder: string;\n multiple: boolean;\n onRemoved: (message: string) => void;\n}) {\n const m = useMessages();\n const state = useContext(ComboBoxStateContext);\n const values = Array.isArray(state?.value) ? state.value : [];\n const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (!multiple || !state || e.key !== 'Backspace' || state.inputValue !== '' || values.length === 0) return;\n const last = state.selectedItems.at(-1);\n state.setValue(values.slice(0, -1));\n if (last) onRemoved(m.common.removed([last.textValue]));\n };\n return (\n <Input\n ref={ref}\n className=\"medo-input__control medo-combobox__input\"\n // Multi with values: the placeholder would compete with the tags.\n placeholder={multiple && values.length > 0 ? undefined : placeholder}\n onKeyDown={onKeyDown}\n />\n );\n}\n\n/** Clears text and value. Visible with text or a value. Beside the toggle, never inside another button. */\nfunction ClearButton({ inputRef, isDisabled }: { inputRef: React.RefObject<HTMLInputElement | null>; isDisabled?: boolean }) {\n const m = useMessages();\n const state = useContext(ComboBoxStateContext);\n if (!state || isDisabled) return null;\n const hasValue = Array.isArray(state.value) ? state.value.length > 0 : state.value != null;\n if (!hasValue && !state.inputValue) return null;\n return (\n <InputAction\n // slot={null}: not the ComboBox's own toggle button.\n slot={null}\n excludeFromTabOrder\n aria-label={Array.isArray(state.value) ? m.common.clearAll : m.common.clear}\n icon={<X />}\n onPress={() => {\n state.setValue(Array.isArray(state.value) ? [] : null);\n state.setInputValue('');\n inputRef.current?.focus();\n }}\n />\n );\n}\n\n/** Multi: chosen values as removable tags in one line, the rest as “+N”; the caret sits after them. */\nfunction SelectedTags({\n entryRef,\n size,\n label,\n isDisabled,\n isReadOnly,\n}: {\n entryRef: React.RefObject<HTMLSpanElement | null>;\n size: InputSize;\n label: ReactNode;\n isDisabled?: boolean;\n isReadOnly?: boolean;\n}) {\n const m = useMessages();\n const state = useContext(ComboBoxStateContext);\n const items = (state?.selectedItems ?? []).filter(Boolean);\n const values = Array.isArray(state?.value) ? state.value : [];\n const key = items.map((item) => item.key).join('\\u0000');\n const measureRef = useRef<HTMLSpanElement>(null);\n // Keeps room for the text input (4 rem + gap) next to the tags.\n const visible = useFitCount(entryRef, measureRef, key, items.length, 68);\n if (!state || items.length === 0) return null;\n const tagSize = size === 'lg' ? 'md' : 'sm';\n const hidden = items.length - visible;\n const name = typeof label === 'string' ? label : m.common.selectedValues;\n\n return (\n <span className=\"medo-combobox__tags-row\">\n <span className={cx('medo-combobox__measure')} ref={measureRef} aria-hidden=\"true\">\n {items.map((item) => (\n <span key={item.key} className={cx('medo-tag', `medo-tag--${tagSize}`)} data-allows-removing=\"\">\n <span className=\"medo-tag__label\">{item.textValue}</span>\n <span className=\"medo-tag__remove\" />\n </span>\n ))}\n <span className={cx('medo-tag', `medo-tag--${tagSize}`)}>+{items.length}</span>\n </span>\n <TagGroup\n aria-label={m.common.selected(name)}\n size={tagSize}\n className=\"medo-combobox__tags\"\n items={items.slice(0, visible)}\n disabledKeys={isDisabled ? items.map((item) => item.key) : undefined}\n onRemove={isReadOnly ? undefined : (keys) => state.setValue(values.filter((k) => !keys.has(k)))}\n >\n {(item) => <Tag id={item.key}>{item.textValue}</Tag>}\n </TagGroup>\n {hidden > 0 && (\n <span className={cx('medo-tag', `medo-tag--${tagSize}`, 'medo-combobox__more')}>\n +{hidden}\n <span className=\"medo-visually-hidden\"> more selected</span>\n </span>\n )}\n </span>\n );\n}\n\n/**\n * The list: options, optional “Add …” row, empty message and loading row.\n * Note: React Aria builds the collection from these children before the ComboBox state exists,\n * so everything inside the ListBox depends on props (`text`, `exact`), never on the state.\n */\nfunction ComboList<T extends object>({\n size,\n items,\n isLoading,\n noResultsMessage,\n creatable,\n text,\n exact,\n onExactChange,\n children,\n}: {\n size: InputSize;\n items?: Iterable<T>;\n isLoading?: boolean;\n noResultsMessage: (inputValue: string) => ReactNode;\n creatable: boolean;\n text: string;\n exact: boolean;\n onExactChange: (exact: boolean) => void;\n children: ReactNode | ((item: T) => ReactNode);\n}) {\n const m = useMessages();\n const state = useContext(ComboBoxStateContext);\n const nodes = state ? [...state.collection].filter((node) => node.key !== CREATE_KEY) : [];\n const hasItems = nodes.length > 0;\n const exactNow = nodes.some((node) => node.textValue.toLocaleLowerCase() === text.toLocaleLowerCase());\n useEffect(() => {\n if (state && exactNow !== exact) onExactChange(exactNow);\n });\n\n // “First match ready”: while typing, the first enabled option is highlighted, so Enter picks it.\n const typing = !!state?.isOpen && text !== '';\n useEffect(() => {\n if (!state || !typing) return;\n // After React Aria's own update (it resets the focused option on every input change).\n const frame = requestAnimationFrame(() => {\n const manager = state.selectionManager;\n let key = state.collection.getFirstKey();\n while (key != null) {\n const node = state.collection.getItem(key);\n if (node?.type === 'item' && !manager.isDisabled(key)) break;\n key = state.collection.getKeyAfter(key);\n }\n if (key == null) return;\n manager.setFocused(true);\n if (manager.focusedKey !== key) manager.setFocusedKey(key);\n });\n return () => cancelAnimationFrame(frame);\n // Re-run when the filter result changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [typing, text, state?.collection]);\n\n return (\n <>\n <ListBox<T>\n size={size === 'lg' ? 'lg' : 'md'}\n renderEmptyState={() => <ListBoxMessage>{isLoading ? `${m.common.loading}…` : noResultsMessage(text)}</ListBoxMessage>}\n >\n {typeof children === 'function' ? <Collection items={items}>{children}</Collection> : children}\n {creatable && text && !exact && (\n <ListBoxSection aria-label={m.common.create}>\n <Option id={CREATE_KEY} icon={<Plus />} textValue={text}>\n {m.common.add(text)}\n </Option>\n </ListBoxSection>\n )}\n </ListBox>\n {/* Server search: previous results stay, the loading row sits below them. */}\n {isLoading && hasItems && <ListBoxMessage>{m.common.loading}…</ListBoxMessage>}\n </>\n );\n}\n\n/* ---------- Mobile: Bottom Sheet with search ---------- */\n\ninterface ComboboxSheetProps<T> {\n label: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n placeholder: string;\n size: InputSize;\n leadingIcon?: ReactNode;\n isLoading?: boolean;\n noResultsMessage: (inputValue: string) => ReactNode;\n onCreate?: (text: string) => Key | void;\n children: ReactNode | ((item: T) => ReactNode);\n className?: string;\n multiple: boolean;\n value: Value;\n onValueChange: (value: Value) => void;\n textRef: React.RefObject<string>;\n items?: Iterable<T>;\n defaultItems?: Iterable<T>;\n inputValue?: string;\n onInputChange?: (value: string) => void;\n isDisabled?: boolean;\n isReadOnly?: boolean;\n isInvalid?: boolean;\n isRequired?: boolean;\n name?: string;\n commit: 'live' | 'onClose';\n onApply?: (value: Key[]) => void;\n resultLabel: (value: Key[]) => ReactNode;\n}\n\n/**\n * Below 640 px the field becomes a button that opens a Bottom Sheet: search on top (fixed 90 % height,\n * so it does not jump with the keyboard), options lg, single closes on tap, multi with Done or result button.\n */\nfunction ComboboxSheet<T extends object>({\n label,\n description,\n errorMessage,\n placeholder,\n size,\n leadingIcon,\n isLoading,\n noResultsMessage,\n onCreate,\n children,\n className,\n multiple,\n value,\n onValueChange,\n textRef,\n items,\n defaultItems,\n inputValue,\n onInputChange,\n isDisabled,\n isReadOnly,\n isInvalid,\n isRequired,\n name,\n commit,\n onApply,\n resultLabel,\n}: ComboboxSheetProps<T>) {\n const m = useMessages();\n const id = useId();\n const [isOpen, setOpen] = useState(false);\n const [ownSearch, setOwnSearch] = useState('');\n const search = inputValue ?? ownSearch;\n const setSearch = (text: string) => {\n textRef.current = text;\n if (inputValue === undefined) setOwnSearch(text);\n onInputChange?.(text);\n };\n const { contains } = useFilter({ sensitivity: 'base' });\n const list = items ?? defaultItems;\n const keys = Array.isArray(value) ? value : value == null ? [] : [value];\n const opened = useRef<string | null>(null);\n\n const query = search.trim();\n const content = typeof children === 'function' ? <Collection items={list}>{children}</Collection> : children;\n\n const open = (next: boolean) => {\n if (next) {\n setSearch('');\n opened.current = JSON.stringify(keys);\n } else if (commit === 'onClose' && multiple && opened.current !== null && opened.current !== JSON.stringify(keys)) {\n onApply?.(keys);\n }\n if (!next) opened.current = null;\n setOpen(next);\n };\n\n const onSelectionChange = (selection: Selection) => {\n const next = selection === 'all' ? [] : [...selection];\n if (multiple) {\n onValueChange(next);\n } else {\n // Tapping the chosen option again deselects it in the list: keep the value, just close (single closes on tap).\n onValueChange(next[0] ?? value);\n open(false);\n }\n };\n\n const descId = description ? `${id}-desc` : undefined;\n const errId = isInvalid && errorMessage ? `${id}-err` : undefined;\n\n // The field shows the labels of the chosen values: React Aria builds the collection from the options\n // without rendering them, the same way the Select gets its labels.\n return (\n <CollectionBuilder content={content}>\n {(collection) => {\n const nodes = [...collection.getKeys()].map((key) => collection.getItem(key)).filter((node) => node?.type === 'item');\n const text = keys.map((key) => collection.getItem(key)?.textValue ?? String(key));\n const exact = nodes.some((node) => node!.textValue.toLocaleLowerCase() === query.toLocaleLowerCase());\n return (\n <div\n className={cx('medo-field', 'medo-combobox', 'medo-select', multiple && keys.length > 0 && 'medo-select--tags', className)}\n data-invalid={isInvalid || undefined}\n data-disabled={isDisabled || undefined}\n data-readonly={isReadOnly || undefined}\n data-open={isOpen || undefined}\n >\n <span className=\"medo-field__label\" id={`${id}-label`}>\n {label}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n <div className={cx('medo-input', `medo-input--${size}`, 'medo-select__field')}>\n <AriaButton\n className=\"medo-select__trigger\"\n isDisabled={isDisabled}\n aria-haspopup=\"dialog\"\n aria-labelledby={`${id}-label ${id}-value`}\n aria-describedby={[errId ?? descId].filter(Boolean).join(' ') || undefined}\n onPress={() => !isReadOnly && open(true)}\n >\n {leadingIcon && (\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n {leadingIcon}\n </span>\n )}\n <span className=\"medo-select__value\" id={`${id}-value`} data-placeholder={keys.length === 0 || undefined}>\n {keys.length === 0 ? placeholder : multiple ? <DisplayTags labels={text} size={size} /> : text[0]}\n {isReadOnly && <span className=\"medo-visually-hidden\">, read only</span>}\n </span>\n {!isReadOnly && (\n <span className=\"medo-select__chevron\" aria-hidden=\"true\">\n <ChevronDown />\n </span>\n )}\n </AriaButton>\n </div>\n <div className=\"medo-field__footer\">\n {isInvalid && errorMessage ? (\n <span className=\"medo-field__error\" id={errId}>\n <CircleAlert aria-hidden=\"true\" />\n <span>{errorMessage}</span>\n </span>\n ) : (\n description && (\n <span className=\"medo-field__description\" id={descId}>\n {description}\n </span>\n )\n )}\n </div>\n {name && keys.map((key) => <input key={String(key)} type=\"hidden\" name={name} value={String(key)} />)}\n\n <BottomSheet\n title={label}\n height=\"full\"\n isOpen={isOpen}\n onOpenChange={open}\n footer={\n multiple\n ? commit === 'onClose'\n ? (close) => (\n <>\n <Button size=\"lg\" onPress={close}>\n {resultLabel(keys)}\n </Button>\n <Button size=\"lg\" variant=\"secondary\" onPress={() => onValueChange([])} isDisabled={keys.length === 0}>\n {m.common.reset}\n </Button>\n </>\n )\n : (close) => (\n <>\n <p className=\"medo-sheet__count\" aria-live=\"polite\">\n {m.common.countSelected(keys.length)}\n </p>\n <Button size=\"lg\" onPress={close}>\n {m.common.done}\n </Button>\n </>\n )\n : undefined\n }\n >\n <Autocomplete inputValue={search} onInputChange={setSearch} filter={items ? undefined : contains}>\n <div className=\"medo-sheet__search\">\n <AriaTextField aria-label={m.common.search} autoFocus className=\"medo-input medo-input--lg\">\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n <Search />\n </span>\n <Input className=\"medo-input__control\" placeholder={placeholder} />\n </AriaTextField>\n </div>\n <OptionHighlightContext.Provider value={query}>\n <ListBox<T>\n size=\"lg\"\n aria-labelledby={`${id}-label`}\n selectionMode={multiple ? 'multiple' : 'single'}\n selectedKeys={keys}\n onSelectionChange={onSelectionChange}\n renderEmptyState={() => <ListBoxMessage>{isLoading ? `${m.common.loading}…` : noResultsMessage(query)}</ListBoxMessage>}\n >\n {content}\n {multiple && onCreate && query && !exact && (\n <ListBoxSection aria-label={m.common.create}>\n <Option id={CREATE_KEY} icon={<Plus />} textValue={query}>\n {m.common.add(query)}\n </Option>\n </ListBoxSection>\n )}\n </ListBox>\n </OptionHighlightContext.Provider>\n {isLoading && list && [...list].length > 0 && <ListBoxMessage>Loading…</ListBoxMessage>}\n </Autocomplete>\n </BottomSheet>\n </div>\n );\n }}\n </CollectionBuilder>\n );\n}\n\n/** Chosen values as display-only tags in one line (inside the trigger button: no remove buttons). */\nfunction DisplayTags({ labels, size }: { labels: string[]; size: InputSize }) {\n const rowRef = useRef<HTMLSpanElement>(null);\n const measureRef = useRef<HTMLSpanElement>(null);\n const visible = useFitCount(rowRef, measureRef, labels.join('\\u0000'), labels.length);\n const tagClass = cx('medo-tag', size === 'lg' ? 'medo-tag--md' : 'medo-tag--sm');\n return (\n <span className=\"medo-select__tags\" ref={rowRef}>\n <span className=\"medo-visually-hidden\">{labels.join(', ')}</span>\n <span className=\"medo-select__measure\" ref={measureRef} aria-hidden=\"true\">\n {labels.map((l, i) => (\n <span key={i} className={tagClass}>\n {l}\n </span>\n ))}\n <span className={tagClass}>+{labels.length}</span>\n </span>\n {labels.slice(0, visible).map((l, i) => (\n <span key={i} className={tagClass} aria-hidden=\"true\">\n <span className=\"medo-select__tag-label\">{l}</span>\n </span>\n ))}\n {labels.length > visible && (\n <span className={tagClass} aria-hidden=\"true\">\n +{labels.length - visible}\n </span>\n )}\n </span>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { flushSync } from 'react-dom';\nimport {\n Button,\n Text,\n UNSTABLE_Toast as AriaToast,\n UNSTABLE_ToastContent as AriaToastContent,\n UNSTABLE_ToastQueue as ToastQueue,\n UNSTABLE_ToastRegion as AriaToastRegion,\n} from 'react-aria-components';\nimport { X } from 'lucide-react';\nimport { useMessages } from '../i18n/I18n';\n\n/*\n * React Aria's Toast is still marked UNSTABLE. Only this file imports it, so an API change\n * in React Aria stays here – apps use `ToastRegion` and `toast()`.\n */\n\nexport interface ToastAction {\n /** “Undo”, “View” or “Retry”. It must also be reachable elsewhere in the app. */\n label: string;\n onAction: () => void;\n}\n\nexport interface ToastOptions {\n /** Max one action. Pressing it runs the action and closes the toast. */\n action?: ToastAction;\n /** Errors (“Could not save”): stays until closed. Otherwise 5 s, with an action 8 s. */\n persistent?: boolean;\n /** Called when the toast closes (timeout, close button, Esc or action). */\n onClose?: () => void;\n}\n\ninterface ToastContent {\n message: string;\n action?: ToastAction;\n}\n\n/** Timing: message only 5 s, with action 8 s, errors without timeout. */\nconst TIMEOUT = 5000;\nconst TIMEOUT_ACTION = 8000;\nconst MAX_VISIBLE = 3;\n\n/** The app-wide queue: max 3 visible, newest first. Changes run in a View Transition where supported. */\nconst queue = new ToastQueue<ToastContent>({\n maxVisibleToasts: MAX_VISIBLE,\n wrapUpdate(fn) {\n if (typeof document !== 'undefined' && 'startViewTransition' in document) {\n document.startViewTransition(() => flushSync(fn));\n } else {\n fn();\n }\n },\n});\n\n/**\n * Shows a toast: short, temporary feedback after an action.\n * Write the result, not the process (“Q3-Report.pdf deleted”), one line, max about 50 characters.\n * Returns the key for `toast.close(key)`. The same message is never shown twice at once.\n */\nexport function toast(message: string, { action, persistent = false, onClose }: ToastOptions = {}): string {\n const same = queue.visibleToasts.find((t) => t.content.message === message);\n if (same) return same.key;\n // Max 3 – the oldest leaves first (React Aria would hold it back and show it again later).\n const visible = queue.visibleToasts;\n if (visible.length >= MAX_VISIBLE) queue.close(visible[visible.length - 1].key);\n return queue.add({ message, action }, { timeout: persistent ? undefined : action ? TIMEOUT_ACTION : TIMEOUT, onClose });\n}\n\n/** Closes a toast by its key. */\ntoast.close = (key: string) => queue.close(key);\n/** Closes all toasts (e.g. on sign-out). */\ntoast.clear = () => queue.clear();\n\nlet regionMounted = false;\n\n/** Esc closes the focused toast (React Aria's Toast has no key handling of its own). React 19 ref cleanup removes the listener. */\nfunction closeOnEscape(el: HTMLElement | null, key: string) {\n if (!el) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n e.stopPropagation();\n queue.close(key);\n };\n el.addEventListener('keydown', onKeyDown);\n return () => el.removeEventListener('keydown', onKeyDown);\n}\n\nexport interface ToastRegionProps {\n /** Accessible name of the landmark. Default: “Notifications” (localized by React Aria). */\n 'aria-label'?: string;\n /** Accessible name of the close buttons. Default: “Close” (localized by React Aria). */\n closeLabel?: string;\n}\n\n/**\n * The place where toasts appear – render it once at the root of the app.\n * A landmark: F6 moves focus into it, new toasts are announced. Desktop bottom right,\n * mobile full width (set `--medo-toast-offset` to the height of a bottom navigation).\n * Hover, focus and a hidden window pause the timers (WCAG 2.2.1).\n */\nexport function ToastRegion({ closeLabel, ...props }: ToastRegionProps) {\n const m = useMessages();\n // One region per page: a second one (e.g. several Storybook stories) stays empty instead of duplicating toasts.\n const [active, setActive] = useState(false);\n useEffect(() => {\n if (regionMounted) return;\n regionMounted = true;\n setActive(true);\n // Do not lose messages in a background tab.\n const onVisibility = () => (document.hidden ? queue.pauseAll() : queue.resumeAll());\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n regionMounted = false;\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, []);\n if (!active) return null;\n\n return (\n <AriaToastRegion {...props} queue={queue} className=\"medo-toast-region\">\n {({ toast: t }) => (\n <AriaToast\n toast={t}\n className=\"medo-toast\"\n style={{ viewTransitionName: t.key }}\n ref={(el) => closeOnEscape(el, t.key)}\n >\n <AriaToastContent className=\"medo-toast__content\">\n <Text slot=\"title\" className=\"medo-toast__message\">\n {t.content.message}\n </Text>\n </AriaToastContent>\n {t.content.action && (\n <Button\n className=\"medo-toast__button medo-toast__action\"\n onPress={() => {\n t.content.action?.onAction();\n queue.close(t.key);\n }}\n >\n {t.content.action.label}\n </Button>\n )}\n <Button slot=\"close\" aria-label={closeLabel ?? m.common.close} className=\"medo-toast__button medo-toast__close\">\n <X aria-hidden=\"true\" />\n </Button>\n </AriaToast>\n )}\n </AriaToastRegion>\n );\n}\n","import { useLayoutEffect, useRef, type ReactNode } from 'react';\nimport {\n SelectionIndicator,\n Tab as AriaTab,\n TabList as AriaTabList,\n TabPanel as AriaTabPanel,\n Tabs as AriaTabs,\n type TabListProps as AriaTabListProps,\n type TabPanelProps as AriaTabPanelProps,\n type TabProps as AriaTabProps,\n type TabsProps as AriaTabsProps,\n} from 'react-aria-components';\nimport { BadgeCount } from '../badge/Badge';\nimport { cx } from '../utils/cx';\n\nexport interface TabsProps extends Omit<AriaTabsProps, 'className' | 'style' | 'orientation'> {\n /** md: tab 32 / track 40 · lg: 40 / 48. Below 640 px tabs are always lg. */\n size?: 'md' | 'lg';\n /** The tabs share the full width. Below 640 px automatic: up to 3 tabs fill, more scroll. */\n fullWidth?: boolean;\n className?: string;\n}\n\n/**\n * Tabs – switch between views of the same context, one panel visible at a time.\n * Built on React Aria Tabs: tablist / tab / tabpanel, only the selected tab is in the Tab order,\n * ← → move and select, Home / End. `keyboardActivation=\"manual\"` for slow panels (select with Enter).\n * Keep the selected tab in the URL with `selectedKey` + `onSelectionChange`.\n */\nexport function Tabs({ size = 'md', fullWidth = false, className, ...props }: TabsProps) {\n return <AriaTabs {...props} className={cx('medo-tabs', `medo-tabs--${size}`, fullWidth && 'medo-tabs--full', className)} />;\n}\n\nexport interface TabListProps<T> extends Omit<AriaTabListProps<T>, 'className' | 'style'> {\n /** Names the tabs when there is no visible heading (“Project”). */\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * The track with the tabs. 2 to 6 tabs. Scrolls horizontally when it does not fit\n * (with a fade at the edge that still has tabs) – tabs never wrap.\n */\nexport function TabList<T extends object>({ className, ...props }: TabListProps<T>) {\n const ref = useRef<HTMLDivElement>(null);\n useScrollEdges(ref);\n return <AriaTabList {...props} ref={ref} className={cx('medo-tabs__list', className)} />;\n}\n\nexport interface TabProps extends Omit<AriaTabProps, 'className' | 'style' | 'children'> {\n /** Required. 1–2 words, a noun (“Activity”). */\n children: string;\n /** Optional, then on all tabs. Decorative – the label carries the meaning. */\n icon?: ReactNode;\n /** Items waiting in the tab (Badge count, neutral). Hidden at 0. */\n count?: number;\n /** Screen-reader text of the count (“3 new”). Without it the number is read as part of the name. */\n countLabel?: string;\n}\n\n/** One tab. The selected tab is a raised thumb that slides to the new tab with a snappy spring (no slide with reduced motion). */\nexport function Tab({ children, icon, count, countLabel, ...props }: TabProps) {\n return (\n <AriaTab {...props} className=\"medo-tab\">\n <SelectionIndicator className=\"medo-tab__thumb\" ref={revealInList} />\n {icon && (\n <span className=\"medo-tab__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-tab__label\">{children}</span>\n {count !== undefined && <BadgeCount count={count} tone=\"neutral\" size=\"sm\" label={countLabel ?? String(count)} />}\n </AriaTab>\n );\n}\n\nexport interface TabPanelProps extends Omit<AriaTabPanelProps, 'className' | 'style' | 'shouldForceMount'> {\n /**\n * Keeps the panel (hidden) while another tab is selected, so input is never lost.\n * Set false for heavy panels (large tables, charts) to unmount them.\n */\n keepMounted?: boolean;\n className?: string;\n}\n\n/** The content of one tab, directly below the tab list. It is focusable when nothing inside is. */\nexport function TabPanel({ keepMounted = true, className, ...props }: TabPanelProps) {\n return <AriaTabPanel {...props} shouldForceMount={keepMounted} className={cx('medo-tabs__panel', className)} />;\n}\n\n/** The thumb mounts in the selected tab: scroll that tab fully into the track (without moving the page). */\nfunction revealInList(thumb: HTMLDivElement | null) {\n const tab = thumb?.parentElement;\n const list = tab?.parentElement;\n if (!tab || !list || list.scrollWidth <= list.clientWidth) return;\n const start = tab.offsetLeft - list.offsetLeft;\n const end = start + tab.offsetWidth;\n if (start < list.scrollLeft) list.scrollTo({ left: start - 32 });\n else if (end > list.scrollLeft + list.clientWidth) list.scrollTo({ left: end - list.clientWidth + 32 });\n}\n\n/** Marks the edges that still have hidden tabs (data-scroll-start / data-scroll-end) for the fade. */\nfunction useScrollEdges(ref: React.RefObject<HTMLDivElement | null>) {\n useLayoutEffect(() => {\n const list = ref.current;\n if (!list) return;\n const update = () => {\n const max = list.scrollWidth - list.clientWidth;\n const start = Math.abs(list.scrollLeft); // RTL scrolls negative\n list.toggleAttribute('data-scroll-start', max > 1 && start > 1);\n list.toggleAttribute('data-scroll-end', max > 1 && start < max - 1);\n };\n update();\n list.addEventListener('scroll', update, { passive: true });\n const observer = new ResizeObserver(update);\n observer.observe(list);\n return () => {\n list.removeEventListener('scroll', update);\n observer.disconnect();\n };\n }, [ref]);\n}\n","import { useContext, useRef, type ReactNode } from 'react';\nimport {\n Dialog as AriaDialog,\n DialogTrigger,\n Heading,\n OverlayTriggerStateContext,\n Popover as AriaPopover,\n type PopoverProps as AriaPopoverProps,\n} from 'react-aria-components';\nimport { Info, X } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button, ButtonGroup } from '../button/Button';\nimport { ActionButton, useInitialFocus, type DialogAction } from '../dialog/Dialog';\nimport { IconButton } from '../icon-button/IconButton';\nimport { Link } from '../link/Link';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { useMessages } from '../i18n/I18n';\n\n/** Opens a Popover from a trigger on click (React Aria DialogTrigger). The trigger is pressed and aria-expanded while open. */\nexport const PopoverTrigger = DialogTrigger;\n\nexport interface PopoverProps {\n /** Header with title and close button. Use it when the content needs a title or holds a form. */\n title?: ReactNode;\n /** Required without a title: names the popover. */\n 'aria-label'?: string;\n /** Interactive content. A function gets `close`. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** sm 240 · md 320 · lg 400 · auto: hugs content without padding (e.g. a calendar). */\n size?: 'sm' | 'md' | 'lg' | 'auto';\n /** Footer, only when changes must be confirmed – otherwise apply them live. Cancel + main action (Button sm). */\n primaryAction?: DialogAction;\n cancelLabel?: string;\n /** Accessible name of the close button. */\n closeLabel?: string;\n /** auto: popover on desktop, Bottom Sheet below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n /** Default bottom start; flips when there is no space. */\n placement?: AriaPopoverProps['placement'];\n className?: string;\n}\n\n/**\n * Popover – a small floating panel with interactive content, anchored to its trigger.\n * Opens on click, never on hover. Non-modal: the page stays usable; focus moves in, Esc or a click\n * outside closes it and focus returns to the trigger. One topic per popover, one popover at a time.\n */\nexport function Popover({\n title,\n 'aria-label': ariaLabel,\n children,\n size = 'md',\n primaryAction,\n cancelLabel: cancelLabelProp,\n closeLabel: closeLabelProp,\n overlay = 'auto',\n placement = 'bottom start',\n className,\n}: PopoverProps) {\n const m = useMessages();\n const cancelLabel = cancelLabelProp ?? m.common.cancel;\n const closeLabel = closeLabelProp ?? m.common.close;\n const mobile = useMediaQuery(MOBILE_QUERY);\n const content = (close: () => void) => (typeof children === 'function' ? children(close) : children);\n\n // Mobile: forms and rich content as Bottom Sheet – thumb reach and room for the keyboard.\n if (overlay === 'sheet' || (overlay === 'auto' && mobile)) {\n return (\n <BottomSheet\n title={title ?? ariaLabel}\n closeLabel={closeLabel}\n className={className}\n footer={\n primaryAction &&\n ((close) => (\n <ButtonGroup>\n <Button variant=\"secondary\" size=\"lg\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={close} size=\"lg\" variant=\"primary\" />\n </ButtonGroup>\n ))\n }\n >\n <SheetBody>{content}</SheetBody>\n </BottomSheet>\n );\n }\n\n return (\n <AriaPopover placement={placement} offset={8} containerPadding={16} className={cx('medo-popover', `medo-popover--${size}`, className)}>\n <PopoverDialog aria-label={title ? undefined : ariaLabel}>\n {({ close }) => (\n <>\n {title && (\n <div className=\"medo-popover__header\">\n <Heading slot=\"title\" className=\"medo-popover__title\">\n {title}\n </Heading>\n <IconButton variant=\"ghost\" size=\"sm\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />\n </div>\n )}\n <div className=\"medo-popover__body\">{content(close)}</div>\n {primaryAction && (\n <div className=\"medo-popover__footer\">\n <ButtonGroup>\n <Button variant=\"secondary\" size=\"sm\" onPress={close}>\n {cancelLabel}\n </Button>\n <ActionButton action={primaryAction} close={close} size=\"sm\" variant=\"primary\" />\n </ButtonGroup>\n </div>\n )}\n </>\n )}\n </PopoverDialog>\n </AriaPopover>\n );\n}\n\n/** Focus starts in the first field (like Dialog), so a form popover is ready to type. */\nfunction PopoverDialog({ children, ...props }: { 'aria-label'?: string; children: (opts: { close: () => void }) => ReactNode }) {\n const ref = useRef<HTMLElement>(null);\n useInitialFocus(ref);\n return (\n <AriaDialog {...props} ref={ref} className=\"medo-popover__dialog\">\n {children}\n </AriaDialog>\n );\n}\n\n/** Content of the mobile sheet with the sheet's padding. */\nfunction SheetBody({ children }: { children: (close: () => void) => ReactNode }) {\n const state = useContext(OverlayTriggerStateContext);\n return <div className=\"medo-popover__sheet-body\">{children(() => state?.close())}</div>;\n}\n\nexport interface ToggletipProps {\n /** Required. Names the info button and the toggletip after the topic (“About billing email”). */\n 'aria-label': string;\n /** One or two short sentences. Text only. */\n children: ReactNode;\n /** Optional link to more help. */\n link?: { label: string; href: string; external?: boolean };\n className?: string;\n}\n\n/**\n * Toggletip – a short explanation behind an info button, next to a label or value.\n * Opens on click, so it works with touch, keyboard and screen readers – unlike a tooltip.\n * Esc or a click outside closes it. Stays a popover on mobile (full width minus 16 px).\n */\nexport function Toggletip({ 'aria-label': label, children, link, className }: ToggletipProps) {\n return (\n <DialogTrigger>\n <IconButton variant=\"ghost\" size=\"sm\" icon={<Info />} aria-label={label} tooltip={false} />\n <AriaPopover placement=\"bottom start\" offset={8} containerPadding={16} className={cx('medo-popover', 'medo-toggletip', className)}>\n <AriaDialog aria-label={label} className=\"medo-popover__dialog medo-toggletip__dialog\">\n <div className=\"medo-toggletip__text\">{children}</div>\n {link && (\n <Link variant=\"standalone\" size=\"md\" href={link.href} external={link.external} target={link.external ? '_blank' : undefined}>\n {link.label}\n </Link>\n )}\n </AriaDialog>\n </AriaPopover>\n </DialogTrigger>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Link as AriaLink, type LinkProps as AriaLinkProps } from 'react-aria-components';\nimport { ArrowRight, ExternalLink } from 'lucide-react';\nimport { cx } from '../utils/cx';\n\nexport interface LinkProps extends Omit<AriaLinkProps, 'children' | 'className'> {\n /** The text says where it goes (“Privacy policy”, not “click here”). */\n children: ReactNode;\n /** inline: inside running text, always underlined · standalone: own line, underline on hover. */\n variant?: 'inline' | 'standalone';\n /** Standalone only: sm (label/sm) · md (label/md). Inline links take the size of the surrounding text. */\n size?: 'sm' | 'md';\n /** Another website: shows the external icon. With target=\"_blank\" screen readers also hear “opens in a new tab”. */\n external?: boolean;\n /** Standalone only: arrow after the text (“View all →”). */\n arrow?: boolean;\n /** Hidden text for links that open a new tab. */\n newTabLabel?: string;\n className?: string;\n}\n\n/**\n * Link – navigates to a page, place or file. Built on React Aria Link:\n * a real `<a href>`, works with client-side routers through RouterProvider. For actions use Button.\n */\nexport function Link({\n children,\n variant = 'inline',\n size = 'md',\n external,\n arrow,\n newTabLabel = '(opens in a new tab)',\n className,\n ...props\n}: LinkProps) {\n const newTab = props.target === '_blank';\n return (\n <AriaLink\n {...props}\n rel={newTab ? (props.rel ?? 'noopener noreferrer') : props.rel}\n className={cx('medo-link', variant === 'standalone' && 'medo-link--standalone', variant === 'standalone' && `medo-link--${size}`, className)}\n >\n {children}\n {external && <ExternalLink className=\"medo-link__icon\" aria-hidden=\"true\" />}\n {!external && arrow && variant === 'standalone' && <ArrowRight className=\"medo-link__icon\" aria-hidden=\"true\" />}\n {newTab && <span className=\"medo-visually-hidden\"> {newTabLabel}</span>}\n </AriaLink>\n );\n}\n","import { Children, createContext, isValidElement, useContext, useEffect, useId, useRef, useState, type ReactElement, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n Dialog as AriaDialog,\n DialogTrigger,\n Heading,\n Link as AriaLink,\n Modal,\n ModalOverlay,\n type LinkProps as AriaLinkProps,\n type PressEvent,\n} from 'react-aria-components';\nimport { ChevronDown, Ellipsis, Menu as MenuIcon, PanelLeft, X } from 'lucide-react';\nimport { Avatar } from '../avatar/Avatar';\nimport { BadgeCount, BadgeDot } from '../badge/Badge';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { IconButton } from '../icon-button/IconButton';\nimport { Tooltip, TooltipLink, TooltipTrigger } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { useMediaQuery } from '../utils/useMediaQuery';\nimport { Drawer } from '../drawer/Drawer';\nimport { useMessages } from '../i18n/I18n';\n\n/*\n * Navigation – med.o Design System\n * Navigation is always made of links in a named <nav> region; the current page has aria-current=\"page\".\n * One NavItem renders in four forms, chosen by the container: header · sidebar · rail · sheet.\n */\n\nexport type NavVariant = 'header' | 'sidebar' | 'rail' | 'sheet';\nconst NavVariantContext = createContext<NavVariant>('sidebar');\n\n/** Side navigation: groups in the rail expand it (with the group open); links in the tablet drawer close it. */\nconst SideNavContext = createContext<{ expand: (group?: string) => void; openGroup?: string; onNavigate?: () => void } | null>(null);\n\nconst TABLET_QUERY = '(min-width: 640px) and (max-width: 1023.98px)';\nconst SITE_MENU_QUERY = '(max-width: 767.98px)';\n\n/* ---------- Nav item ---------- */\n\nexport interface NavItemProps extends Omit<AriaLinkProps, 'children' | 'className' | 'style'> {\n /** Required. 1–2 words, a noun – the same name in header, sidebar, tab bar and page title. */\n children: string;\n /** Sidebar, rail and sheet: icon before the label (decorative). Header items have no icon. */\n icon?: ReactNode;\n /** The current page (exactly one). Marked with aria-current=\"page\" and action/selected. */\n isCurrent?: boolean;\n /** Number in the item (Badge count, neutral). */\n count?: number;\n /** Screen-reader text of the count (“3 unread”, “12 projects”). */\n countLabel?: string;\n /** The count is new or unread: in the rail it turns into a dot. Plain totals (“12 projects”) are hidden there. */\n unread?: boolean;\n}\n\n/**\n * One navigation link. Built on React Aria Link, so client-side routing works\n * with any router through RouterProvider. The container decides the form (header, sidebar, rail, sheet).\n */\nexport function NavItem({ children, icon, isCurrent, count, countLabel, unread, ...props }: NavItemProps) {\n const variant = useContext(NavVariantContext);\n const sideNav = useContext(SideNavContext);\n const rail = variant === 'rail';\n const content = (\n <>\n {icon && variant !== 'header' && (\n <span className=\"medo-nav-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className={rail ? 'medo-visually-hidden' : 'medo-nav-item__label'}>{children}</span>\n {count !== undefined &&\n (rail ? (\n unread && count > 0 && <BadgeDot tone=\"danger\" label={countLabel ?? String(count)} className=\"medo-nav-item__dot\" />\n ) : (\n <BadgeCount count={count} tone=\"neutral\" size=\"sm\" label={countLabel ?? String(count)} />\n ))}\n </>\n );\n const linkProps = {\n ...props,\n onPress: (e: PressEvent) => {\n props.onPress?.(e);\n sideNav?.onNavigate?.();\n },\n 'aria-current': isCurrent ? ('page' as const) : undefined,\n className: cx('medo-nav-item', `medo-nav-item--${variant}`),\n };\n return (\n <li className=\"medo-nav__entry\">\n {rail ? (\n // Collapsed: the label appears as tooltip on hover and focus.\n <TooltipTrigger>\n <TooltipLink {...linkProps}>{content}</TooltipLink>\n <Tooltip placement=\"end\">{children}</Tooltip>\n </TooltipTrigger>\n ) : (\n <AriaLink {...linkProps}>{content}</AriaLink>\n )}\n </li>\n );\n}\n\n/* ---------- Group (dropdown in the header, accordion elsewhere) ---------- */\n\nexport interface NavGroupProps {\n /** Label of the group button. */\n label: string;\n /** Sidebar, rail and sheet: icon before the label. */\n icon?: ReactNode;\n /** NavItems – one level only. */\n children: ReactNode;\n /** Open at start. Default: open when it contains the current page (sidebar, sheet). */\n defaultOpen?: boolean;\n}\n\n/** True when a NavItem child is the current page. */\nfunction containsCurrent(children: ReactNode) {\n return Children.toArray(children).some((c) => isValidElement(c) && (c as ReactElement<NavItemProps>).props.isCurrent);\n}\n\n/**\n * A group of links behind a disclosure button (aria-expanded) – never a menu.\n * Header: a dropdown panel on the popover surface; Tab moves through the links, Esc or a click outside closes.\n * Sidebar and sheet: opens in place, one level. The parent shows “current” only while it is closed.\n */\nexport function NavGroup({ label, icon, children, defaultOpen }: NavGroupProps) {\n const variant = useContext(NavVariantContext);\n const sideNav = useContext(SideNavContext);\n const hasCurrent = containsCurrent(children);\n const [open, setOpen] = useState(defaultOpen ?? (variant !== 'header' && (hasCurrent || sideNav?.openGroup === label)));\n const panelId = useId();\n const itemRef = useRef<HTMLLIElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const floating = variant === 'header';\n\n // Header dropdown: Esc, a click outside or focus leaving closes it.\n useEffect(() => {\n if (!floating || !open) return;\n const item = itemRef.current;\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n setOpen(false);\n buttonRef.current?.focus();\n };\n const onPointer = (e: PointerEvent) => !item?.contains(e.target as Node) && setOpen(false);\n const onFocusOut = (e: FocusEvent) => e.relatedTarget && !item?.contains(e.relatedTarget as Node) && setOpen(false);\n document.addEventListener('keydown', onKey);\n document.addEventListener('pointerdown', onPointer);\n item?.addEventListener('focusout', onFocusOut);\n return () => {\n document.removeEventListener('keydown', onKey);\n document.removeEventListener('pointerdown', onPointer);\n item?.removeEventListener('focusout', onFocusOut);\n };\n }, [floating, open]);\n\n // Rail: the group cannot open in 64 px – pressing it expands the sidebar with the group open.\n if (variant === 'rail') {\n return (\n <li className=\"medo-nav__entry\">\n <TooltipTrigger>\n <AriaButton\n className=\"medo-nav-item medo-nav-item--rail\"\n data-current={hasCurrent || undefined}\n onPress={() => {\n setOpen(true);\n sideNav?.expand(label);\n }}\n >\n <span className=\"medo-nav-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n <span className=\"medo-visually-hidden\">{label}</span>\n </AriaButton>\n <Tooltip placement=\"end\">{label}</Tooltip>\n </TooltipTrigger>\n </li>\n );\n }\n\n return (\n <li ref={itemRef} className={cx('medo-nav__entry', 'medo-nav-group', floating && 'medo-nav-group--floating')}>\n <AriaButton\n ref={buttonRef}\n aria-expanded={open}\n aria-controls={panelId}\n data-current={(hasCurrent && !open) || undefined}\n onPress={() => setOpen((o) => !o)}\n className={cx('medo-nav-item', `medo-nav-item--${variant}`, 'medo-nav-group__button')}\n >\n {icon && !floating && (\n <span className=\"medo-nav-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-nav-item__label\">{label}</span>\n <ChevronDown className=\"medo-nav-group__chevron\" aria-hidden=\"true\" />\n </AriaButton>\n <NavVariantContext.Provider value={floating ? 'sidebar' : variant}>\n <ul id={panelId} hidden={!open} className={cx('medo-nav__list', floating ? 'medo-nav-group__panel' : 'medo-nav-group__list')}>\n {children}\n </ul>\n </NavVariantContext.Provider>\n </li>\n );\n}\n\n/* ---------- Nav list ---------- */\n\nexport interface NavListProps {\n /** Form of the items: header (row) · sidebar · rail · sheet. */\n variant?: NavVariant;\n /** Name of the navigation region (“Footer”, “Account”). */\n 'aria-label': string;\n children: ReactNode;\n className?: string;\n}\n\n/** A named navigation region with items of one form – for navigation outside the ready-made headers and bars. */\nexport function NavList({ variant = 'sidebar', 'aria-label': label, children, className }: NavListProps) {\n return (\n <nav aria-label={label} className={className}>\n <NavVariantContext.Provider value={variant}>\n <ul className={cx('medo-nav__list', variant === 'header' && 'medo-nav__list--row', variant === 'rail' && 'medo-nav__list--rail')}>{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n );\n}\n\n/* ---------- Section (sidebar) ---------- */\n\nexport interface NavSectionProps {\n /** Overline heading (“Workspace”). In the rail the section is divided by a line. */\n title: string;\n children: ReactNode;\n}\n\n/** A titled section of the side navigation. */\nexport function NavSection({ title, children }: NavSectionProps) {\n const variant = useContext(NavVariantContext);\n const id = useId();\n return (\n <li className=\"medo-nav__entry medo-nav-section\">\n {variant === 'rail' ? (\n <span className=\"medo-nav-section__divider\" role=\"presentation\" />\n ) : (\n <span id={id} className=\"medo-nav-section__title\">\n {title}\n </span>\n )}\n <ul className=\"medo-nav__list\" aria-labelledby={variant === 'rail' ? undefined : id} aria-label={variant === 'rail' ? title : undefined}>\n {children}\n </ul>\n </li>\n );\n}\n\n/* ---------- Skip link ---------- */\n\nexport interface SkipLinkProps {\n /** Id target of the main content. */\n href?: string;\n children?: string;\n}\n\n/** “Skip to content” – the first focusable element on every page (WCAG 2.4.1). Visible on focus only. */\nexport function SkipLink({ href = '#main', children }: SkipLinkProps) {\n const m = useMessages();\n return (\n <a href={href} className=\"medo-skip-link\">\n {children ?? m.navigation.skipToContent}\n </a>\n );\n}\n\n/* ---------- Action links (header actions that navigate) ---------- */\n\nexport interface NavAction {\n label: string;\n /** Usually a link (“Log in”, “Get started”). */\n href?: string;\n onPress?: (e: PressEvent) => void;\n /** primary: max one · secondary · ghost. */\n variant?: 'primary' | 'secondary' | 'ghost';\n}\n\n/** Link (or press action) with the Button look – the actions of the website header. */\nfunction ActionLink({ action, size }: { action: NavAction; size: 'sm' | 'md' | 'lg' }) {\n return (\n <AriaLink href={action.href} onPress={action.onPress} className={cx('medo-button', `medo-button--${action.variant ?? 'ghost'}`, `medo-button--${size}`)}>\n <span className=\"medo-button__label\">{action.label}</span>\n </AriaLink>\n );\n}\n\n/* ---------- Website header ---------- */\n\nexport interface SiteHeaderProps {\n /** Logo link with a name (“med.o home”). */\n logo: ReactNode;\n /** NavItems and NavGroups – max 5 links; more go into a group. */\n children: ReactNode;\n /** Max 2 actions, at most one primary (last). In the mobile menu they are pinned at the bottom (lg). */\n actions?: NavAction[];\n /** Name of the navigation region. */\n 'aria-label'?: string;\n /** Mobile: label of the menu button and title of the fullscreen menu. */\n menuLabel?: string;\n closeLabel?: string;\n /** auto: menu button below 768 px · desktop · mobile (forced, e.g. for previews). */\n layout?: 'auto' | 'desktop' | 'mobile';\n}\n\n/**\n * Website header: logo, links, actions. Sticky, with a divider once the page scrolls.\n * Below 768 px only the logo, the primary action and a menu button remain; the menu opens fullscreen.\n */\nexport function SiteHeader({ logo, children, actions = [], 'aria-label': labelProp, menuLabel: menuLabelProp, closeLabel: closeLabelProp, layout = 'auto' }: SiteHeaderProps) {\n const m = useMessages();\n const label = labelProp ?? m.navigation.main;\n const menuLabel = menuLabelProp ?? m.navigation.menu;\n const closeLabel = closeLabelProp ?? m.common.close;\n const narrow = useMediaQuery(SITE_MENU_QUERY);\n const compact = layout === 'mobile' || (layout === 'auto' && narrow);\n const scrolled = useScrolled();\n const primary = actions.find((a) => a.variant === 'primary');\n return (\n <header className={cx('medo-site-header', compact && 'medo-site-header--compact')} data-scrolled={scrolled || undefined}>\n <div className=\"medo-site-header__logo\">{logo}</div>\n {compact ? (\n <div className=\"medo-site-header__actions\">\n {primary && <ActionLink action={primary} size=\"sm\" />}\n <NavFullscreen logo={logo} actions={actions} aria-label={label} menuLabel={menuLabel} closeLabel={closeLabel}>\n {children}\n </NavFullscreen>\n </div>\n ) : (\n <>\n <nav aria-label={label} className=\"medo-site-header__nav\">\n <NavVariantContext.Provider value=\"header\">\n <ul className=\"medo-nav__list medo-nav__list--row\">{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n {actions.length > 0 && (\n <div className=\"medo-site-header__actions\">\n {actions.map((a) => (\n <ActionLink key={a.label} action={a} size=\"md\" />\n ))}\n </div>\n )}\n </>\n )}\n </header>\n );\n}\n\n/** Fullscreen menu of the website on mobile: large links, groups inline, actions at the bottom. */\nfunction NavFullscreen({\n logo,\n actions,\n children,\n 'aria-label': label,\n menuLabel,\n closeLabel,\n}: Required<Pick<SiteHeaderProps, 'logo' | 'actions' | 'children' | 'aria-label' | 'menuLabel' | 'closeLabel'>>) {\n // Primary first when stacked – in thumb reach.\n const ordered = [...actions].sort((a, b) => Number(b.variant === 'primary') - Number(a.variant === 'primary'));\n return (\n <DialogTrigger>\n <IconButton variant=\"ghost\" size=\"md\" icon={<MenuIcon />} aria-label={menuLabel} tooltip={false} />\n <ModalOverlay className=\"medo-nav-fullscreen-overlay\">\n <Modal className=\"medo-nav-fullscreen\">\n <AriaDialog aria-label={menuLabel} className=\"medo-nav-fullscreen__dialog\">\n {({ close }) => (\n <>\n <div className=\"medo-nav-fullscreen__header\">\n <div className=\"medo-site-header__logo\">{logo}</div>\n <IconButton variant=\"ghost\" size=\"md\" icon={<X />} aria-label={closeLabel} tooltip={false} onPress={close} />\n </div>\n <nav aria-label={label} className=\"medo-nav-fullscreen__nav\">\n <NavVariantContext.Provider value=\"sheet\">\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n {ordered.length > 0 && (\n <div className=\"medo-nav-fullscreen__actions\">\n {ordered.map((a) => (\n <ActionLink key={a.label} action={a.variant === 'ghost' || !a.variant ? { ...a, variant: 'secondary' } : a} size=\"lg\" />\n ))}\n </div>\n )}\n </>\n )}\n </AriaDialog>\n </Modal>\n </ModalOverlay>\n </DialogTrigger>\n );\n}\n\n/* ---------- App header ---------- */\n\nexport interface AppHeaderProps {\n /** Page title – the same name as the current nav item. */\n title: ReactNode;\n /** Heading level of the title (default 1: the page title). */\n headingLevel?: 1 | 2 | 3;\n /** Mobile only: logo mark before the title (the side navigation is hidden there). */\n logo?: ReactNode;\n /** Search field (desktop). */\n search?: ReactNode;\n /** Notifications, account … */\n actions?: ReactNode;\n}\n\n/** App header: page title, search and actions. Navigation lives in the side navigation. */\nexport function AppHeader({ title, headingLevel = 1, logo, search, actions }: AppHeaderProps) {\n const scrolled = useScrolled();\n return (\n <header className=\"medo-app-header\" data-scrolled={scrolled || undefined}>\n {logo && <div className=\"medo-app-header__logo\">{logo}</div>}\n <Heading level={headingLevel} className=\"medo-app-header__title\">\n {title}\n </Heading>\n {search && <div className=\"medo-app-header__search\">{search}</div>}\n {actions && <div className=\"medo-app-header__actions\">{actions}</div>}\n </header>\n );\n}\n\n/* ---------- Side navigation ---------- */\n\nexport interface SideNavUser {\n name: string;\n email?: string;\n src?: string;\n}\n\nexport interface SideNavProps {\n /** Full logo (expanded). */\n logo: ReactNode;\n /** Logo mark (collapsed, 32 px). */\n logoMark: ReactNode;\n /** NavItems, NavSections and NavGroups. Most used first. */\n children: ReactNode;\n /** Signed-in user at the bottom. */\n user?: SideNavUser;\n /** Collapsed to the 64 px rail (controlled). Remember it per user via onCollapsedChange. */\n isCollapsed?: boolean;\n defaultCollapsed?: boolean;\n onCollapsedChange?: (collapsed: boolean) => void;\n /** Name of the navigation region. */\n 'aria-label'?: string;\n collapseLabel?: string;\n expandLabel?: string;\n /** Close button of the tablet drawer. */\n closeLabel?: string;\n}\n\n/**\n * Side navigation for apps: 256 px with icons, counts, sections and groups;\n * collapses to a 64 px rail with tooltips. 640–1023 px: always a rail; expanding opens the full navigation\n * as a Drawer on the left. Below 640 px it is hidden – use the BottomTabBar there.\n */\nexport function SideNav({\n logo,\n logoMark,\n children,\n user,\n isCollapsed,\n defaultCollapsed = false,\n onCollapsedChange,\n 'aria-label': labelProp,\n collapseLabel: collapseLabelProp,\n expandLabel: expandLabelProp,\n closeLabel: closeLabelProp,\n}: SideNavProps) {\n const m = useMessages();\n const label = labelProp ?? m.navigation.app;\n const collapseLabel = collapseLabelProp ?? m.navigation.collapse;\n const expandLabel = expandLabelProp ?? m.navigation.expand;\n const closeLabel = closeLabelProp ?? m.common.close;\n const [ownCollapsed, setOwnCollapsed] = useState(defaultCollapsed);\n const tablet = useMediaQuery(TABLET_QUERY);\n const [drawer, setDrawer] = useState(false);\n const [openGroup, setOpenGroup] = useState<string>();\n const collapsed = tablet || (isCollapsed ?? ownCollapsed);\n\n const expand = (group?: string) => {\n setOpenGroup(group);\n if (tablet) return setDrawer(true);\n if (isCollapsed === undefined) setOwnCollapsed(false);\n onCollapsedChange?.(false);\n };\n const collapse = () => {\n if (isCollapsed === undefined) setOwnCollapsed(true);\n onCollapsedChange?.(true);\n };\n useEffect(() => {\n if (!tablet) setDrawer(false);\n }, [tablet]);\n\n const toggle = (\n <IconButton\n variant=\"ghost\"\n size=\"sm\"\n icon={<PanelLeft />}\n aria-label={collapsed ? expandLabel : collapseLabel}\n aria-expanded={tablet ? drawer : !collapsed}\n onPress={() => (collapsed ? expand() : collapse())}\n />\n );\n\n return (\n <aside className={cx('medo-sidenav', collapsed && 'medo-sidenav--collapsed')}>\n <div className=\"medo-sidenav__panel\">\n <div className=\"medo-sidenav__top\">\n <div className=\"medo-sidenav__logo\">{collapsed ? logoMark : logo}</div>\n {!collapsed && toggle}\n </div>\n <nav aria-label={label} className=\"medo-sidenav__nav\">\n <SideNavContext.Provider value={{ expand, openGroup }}>\n <NavVariantContext.Provider value={collapsed ? 'rail' : 'sidebar'}>\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </SideNavContext.Provider>\n </nav>\n <div className=\"medo-sidenav__bottom\">\n {collapsed && toggle}\n {user && (\n <div className=\"medo-sidenav__user\">\n <Avatar name={user.name} src={user.src} size=\"md\" decorative={!collapsed} />\n {!collapsed && (\n <span className=\"medo-sidenav__user-text\">\n <span className=\"medo-sidenav__user-name\">{user.name}</span>\n {user.email && <span className=\"medo-sidenav__user-email\">{user.email}</span>}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n {tablet && (\n // Tablet: the full navigation as a Drawer on the left. Choosing a page closes it.\n <Drawer side=\"left\" size=\"sm\" title={logo} aria-label={label} closeLabel={closeLabel} isOpen={drawer} onOpenChange={setDrawer}>\n <nav aria-label={label}>\n <SideNavContext.Provider value={{ expand, openGroup, onNavigate: () => setDrawer(false) }}>\n <NavVariantContext.Provider value=\"sidebar\">\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </SideNavContext.Provider>\n </nav>\n </Drawer>\n )}\n </aside>\n );\n}\n\n/* ---------- Bottom tab bar (apps, mobile) ---------- */\n\nexport interface BottomTabBarProps {\n /** 3–5 TabBarItems; the last can be TabBarMore. */\n children: ReactNode;\n 'aria-label'?: string;\n /** mobile: only below 640 px (default) · always (e.g. in a native-like web app). */\n display?: 'mobile' | 'always';\n}\n\n/**\n * Bottom tab bar: the main destinations of an app on phones, in thumb reach.\n * Max 4 destinations + “More”. Fixed to the bottom with the safe area; set `--medo-toast-offset` so toasts stay above it.\n */\nexport function BottomTabBar({ children, 'aria-label': labelProp, display = 'mobile' }: BottomTabBarProps) {\n const m = useMessages();\n const label = labelProp ?? m.navigation.app;\n return (\n <nav aria-label={label} className={cx('medo-tab-bar', display === 'always' && 'medo-tab-bar--always')}>\n <ul className=\"medo-tab-bar__list\">{children}</ul>\n </nav>\n );\n}\n\nexport interface TabBarItemProps extends Omit<AriaLinkProps, 'children' | 'className' | 'style'> {\n /** Always visible – icons alone are ambiguous. */\n children: string;\n icon: ReactNode;\n isCurrent?: boolean;\n /** Something new (dot). Name it for screen readers with dotLabel. */\n dot?: boolean;\n dotLabel?: string;\n}\n\n/** One destination of the bottom tab bar: icon in a pill indicator, label below. */\nexport function TabBarItem({ children, icon, isCurrent, dot, dotLabel = 'new', ...props }: TabBarItemProps) {\n return (\n <li className=\"medo-tab-bar__entry\">\n <AriaLink {...props} aria-current={isCurrent ? 'page' : undefined} className=\"medo-tab-bar-item\">\n <TabBarIcon icon={icon} dot={dot} dotLabel={dotLabel} />\n <span className=\"medo-tab-bar-item__label\">{children}</span>\n </AriaLink>\n </li>\n );\n}\n\nfunction TabBarIcon({ icon, dot, dotLabel }: { icon: ReactNode; dot?: boolean; dotLabel?: string }) {\n return (\n <span className=\"medo-tab-bar-item__indicator\">\n <span className=\"medo-tab-bar-item__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n {dot && <BadgeDot tone=\"danger\" label={dotLabel} className=\"medo-tab-bar-item__dot\" />}\n </span>\n );\n}\n\nexport interface TabBarMoreProps {\n /** Label of the button and title of the sheet. */\n label?: string;\n /** NavItems for the remaining destinations (rendered large in the Nav sheet). */\n children: ReactNode;\n closeLabel?: string;\n}\n\n/** “More”: opens the remaining destinations in the Nav sheet (Bottom Sheet). Shows “current” when one of them is. */\nexport function TabBarMore({ label: labelProp, children, closeLabel }: TabBarMoreProps) {\n const m = useMessages();\n const label = labelProp ?? m.common.more;\n const hasCurrent = containsCurrent(children);\n return (\n <li className=\"medo-tab-bar__entry\">\n <DialogTrigger>\n <AriaButton className=\"medo-tab-bar-item\" aria-haspopup=\"dialog\" data-current={hasCurrent || undefined}>\n <TabBarIcon icon={<Ellipsis />} />\n <span className=\"medo-tab-bar-item__label\">{label}</span>\n </AriaButton>\n <BottomSheet title={label} closeLabel={closeLabel}>\n <nav aria-label={label} className=\"medo-nav-sheet\">\n <NavVariantContext.Provider value=\"sheet\">\n <ul className=\"medo-nav__list\">{children}</ul>\n </NavVariantContext.Provider>\n </nav>\n </BottomSheet>\n </DialogTrigger>\n </li>\n );\n}\n\n/* ---------- Helpers ---------- */\n\n/** True once the page is scrolled: headers show their divider. */\nfunction useScrolled() {\n const [scrolled, setScrolled] = useState(false);\n useEffect(() => {\n const update = () => setScrolled(window.scrollY > 0);\n update();\n window.addEventListener('scroll', update, { passive: true });\n return () => window.removeEventListener('scroll', update);\n }, []);\n return scrolled;\n}\n","import { useEffect, useRef, type ReactNode } from 'react';\nimport { Dialog as AriaDialog, Heading, Modal, ModalOverlay } from 'react-aria-components';\nimport { X } from 'lucide-react';\nimport { useDirtyGuard, type DirtyGuardProps } from '../dialog/Dialog';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface DrawerProps extends DirtyGuardProps {\n /** Says what it is (“Account”, “Filter”, “Invoice #1042”). Can be a logo for a navigation drawer – then set aria-label. */\n title: ReactNode;\n /** Name of the drawer when the title is not text (e.g. a logo). */\n 'aria-label'?: string;\n /** Content; scrolls between header and footer. A function gets `close`: closes without asking – call it after saving. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /**\n * Only for decisions (Apply, Save) – usually a ButtonGroup. Links and switches act immediately.\n * A function gets `close` (after applying or saving, never asks) and `cancel` (asks “Discard changes?” when isDirty).\n */\n footer?: ReactNode | ((close: () => void, cancel: () => void) => ReactNode);\n /** right: account, filters, details (default) · left: navigation only. */\n side?: 'left' | 'right';\n /** sm 320 (links) · md 400 (filters) · lg 560 (details, forms). */\n size?: 'sm' | 'md' | 'lg';\n /** Accessible name of the close button. */\n closeLabel?: string;\n className?: string;\n}\n\n/**\n * Drawer – a modal panel that slides in from the side. Same building blocks and behaviour\n * as the Dialog (React Aria ModalOverlay + Modal + Dialog): scrim, focus trap, no page scroll, Esc and the close\n * button close it, focus returns to the trigger; `isDirty` asks “Discard changes?”. Below 640 px it keeps its side,\n * viewport − 56 px wide; a swipe towards the edge closes it. Use inside a DialogTrigger or with isOpen.\n */\nexport function Drawer({\n title,\n 'aria-label': ariaLabel,\n children,\n footer,\n side = 'right',\n size = 'sm',\n closeLabel,\n isDirty = false,\n discardText,\n className,\n ...openProps\n}: DrawerProps) {\n const m = useMessages();\n const { open, onOpenChange, confirmDiscard, forceClose } = useDirtyGuard({ isDirty, discardText, ...openProps });\n return (\n <ModalOverlay isOpen={open} onOpenChange={onOpenChange} isDismissable={!isDirty} className={cx('medo-drawer-overlay', `medo-drawer-overlay--${side}`)}>\n <Modal className={cx('medo-drawer', `medo-drawer--${side}`, `medo-drawer--${size}`, className)}>\n <DrawerDialog aria-label={ariaLabel} side={side}>\n {(close) => (\n <>\n <div className=\"medo-drawer__header\">\n {ariaLabel ? (\n <div className=\"medo-drawer__title\">{title}</div>\n ) : (\n <Heading slot=\"title\" className=\"medo-drawer__title\">\n {title}\n </Heading>\n )}\n <IconButton variant=\"ghost\" size=\"md\" icon={<X />} aria-label={closeLabel ?? m.common.close} tooltip={false} onPress={close} />\n </div>\n <div className=\"medo-drawer__body\">{typeof children === 'function' ? children(forceClose) : children}</div>\n {footer && <div className=\"medo-drawer__footer\">{typeof footer === 'function' ? footer(forceClose, close) : footer}</div>}\n {confirmDiscard}\n </>\n )}\n </DrawerDialog>\n </Modal>\n </ModalOverlay>\n );\n}\n\n/**\n * The dialog section with swipe to close. Focus starts on the drawer itself (React Aria default):\n * screen readers announce the title, Tab then reaches the close button and the content in order –\n * drawers mostly hold links and settings, not a form to type into right away.\n */\nfunction DrawerDialog({ children, side, ...props }: { 'aria-label'?: string; side: 'left' | 'right'; children: (close: () => void) => ReactNode }) {\n const ref = useRef<HTMLElement>(null);\n return (\n <AriaDialog {...props} ref={ref} className=\"medo-drawer__dialog\">\n {({ close }) => (\n <>\n <SwipeToClose target={ref} side={side} onClose={close} />\n {children(close)}\n </>\n )}\n </AriaDialog>\n );\n}\n\n/** Share of the width (or a fast flick) that closes the drawer when swiped towards its edge. */\nconst CLOSE_DISTANCE = 0.25;\nconst CLOSE_VELOCITY = 0.5; // px per ms\nconst START = 10; // px before a horizontal drag starts – vertical scrolling stays native\n\n/**\n * Touch and pen: drag the drawer towards its edge to close it.\n * An addition only – Esc, the close button and the scrim always work (WCAG 2.5.7).\n */\nfunction SwipeToClose({ target, side, onClose }: { target: React.RefObject<HTMLElement | null>; side: 'left' | 'right'; onClose: () => void }) {\n useEffect(() => {\n const el = target.current;\n const drawer = el?.parentElement;\n if (!el || !drawer) return;\n const dir = side === 'right' ? 1 : -1;\n let start: { x: number; y: number; t: number; id: number } | null = null;\n let dragging = false;\n\n const down = (e: PointerEvent) => {\n if (e.pointerType === 'mouse') return;\n start = { x: e.clientX, y: e.clientY, t: e.timeStamp, id: e.pointerId };\n dragging = false;\n };\n const move = (e: PointerEvent) => {\n if (!start || e.pointerId !== start.id) return;\n const dx = (e.clientX - start.x) * dir;\n const dy = e.clientY - start.y;\n if (!dragging) {\n if (Math.abs(dx) < START || Math.abs(dx) < Math.abs(dy)) return;\n if (dx < 0) return void (start = null); // towards the content: not a close gesture\n dragging = true;\n el.setPointerCapture(e.pointerId);\n drawer.setAttribute('data-dragging', '');\n }\n drawer.style.transform = `translateX(${Math.max(0, dx) * dir}px)`;\n };\n const up = (e: PointerEvent) => {\n if (!start || e.pointerId !== start.id) return;\n const dx = Math.max(0, (e.clientX - start.x) * dir);\n const velocity = dx / Math.max(1, e.timeStamp - start.t);\n const wasDragging = dragging;\n start = null;\n dragging = false;\n if (!wasDragging) return;\n drawer.removeAttribute('data-dragging');\n drawer.style.transform = '';\n if (dx > drawer.offsetWidth * CLOSE_DISTANCE || (velocity > CLOSE_VELOCITY && dx > 24)) onClose();\n };\n el.addEventListener('pointerdown', down);\n el.addEventListener('pointermove', move);\n el.addEventListener('pointerup', up);\n el.addEventListener('pointercancel', up);\n return () => {\n el.removeEventListener('pointerdown', down);\n el.removeEventListener('pointermove', move);\n el.removeEventListener('pointerup', up);\n el.removeEventListener('pointercancel', up);\n };\n }, [target, side, onClose]);\n return null;\n}\n","import { createContext, useContext, type HTMLAttributes, type ReactNode } from 'react';\nimport { Check, X } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport type ListType = 'bullet' | 'number' | 'check';\n\nconst ListTypeContext = createContext<ListType>('bullet');\n\nexport interface ListProps extends Omit<HTMLAttributes<HTMLUListElement | HTMLOListElement>, 'children'> {\n /** bullet: unordered points (ul) · number: order matters (ol) · check: features, included first (ul). */\n type?: ListType;\n /** Without it the list takes the size of the surrounding text. sm body/sm · md body/md · lg body/lg. */\n size?: 'sm' | 'md' | 'lg';\n /** Number list: first number (e.g. a list that continues after a paragraph). */\n start?: number;\n /** 2–7 ListItems. A nested List inside an item is level 2 (max 2 levels). */\n children: ReactNode;\n}\n\n/**\n * List – a real list in running text: bullets, numbers or a feature list.\n * Plain markup, no library needed. Markers are neutral (text/secondary) in their own column; long items\n * wrap flush with their first line. Level 2 (a List inside a ListItem) switches the marker: ring, “a.”.\n */\nexport function List({ type = 'bullet', size, start, className, style, children, ...props }: ListProps) {\n const Tag = type === 'number' ? 'ol' : 'ul';\n // The markers are CSS counters: start them where the native `start` attribute says.\n const counter = type === 'number' && start !== undefined ? { counterReset: `medo-list ${start - 1}` } : undefined;\n return (\n <ListTypeContext.Provider value={type}>\n <Tag\n {...props}\n start={type === 'number' ? start : undefined}\n style={{ ...counter, ...style }}\n // The markers are drawn in CSS (list-style: none) – some browser and screen reader combinations then drop the list semantics, so set the role.\n role=\"list\"\n className={cx('medo-list', `medo-list--${type}`, size && `medo-list--${size}`, className)}\n >\n {children}\n </Tag>\n </ListTypeContext.Provider>\n );\n}\n\nexport interface ListItemProps extends Omit<HTMLAttributes<HTMLLIElement>, 'children'> {\n children: ReactNode;\n /** Feature list: not included – cross, muted text and a hidden “Not included:” for screen readers. */\n excluded?: boolean;\n /** Hidden prefix of excluded items. */\n excludedLabel?: string;\n}\n\n/** One item of a List. */\nexport function ListItem({ children, excluded, excludedLabel, className, ...props }: ListItemProps) {\n const m = useMessages();\n const type = useContext(ListTypeContext);\n const check = type === 'check';\n return (\n <li {...props} className={cx('medo-list__item', check && excluded && 'medo-list__item--excluded', className)}>\n {check && (\n <span className=\"medo-list__icon\" aria-hidden=\"true\">\n {excluded ? <X /> : <Check />}\n </span>\n )}\n {check && excluded && <span className=\"medo-visually-hidden\">{excludedLabel ?? m.list.notIncluded} </span>}\n {children}\n </li>\n );\n}\n\nexport interface DescriptionListProps extends HTMLAttributes<HTMLDListElement> {\n /** auto: stacked as soon as the list itself is narrower than 22.5 rem (360 px) (phone, Drawer, narrow column) · horizontal · stacked. */\n layout?: 'auto' | 'horizontal' | 'stacked';\n /** DescriptionItems. */\n children: ReactNode;\n}\n\n/** Description list – term–value pairs for details of a record, an order or a profile. */\nexport function DescriptionList({ layout = 'auto', className, children, ...props }: DescriptionListProps) {\n return (\n <dl {...props} className={cx('medo-dl', `medo-dl--${layout}`, className)}>\n {children}\n </dl>\n );\n}\n\nexport interface DescriptionItemProps {\n /** The term (“Status”). */\n term: ReactNode;\n /** The value (“Active”). */\n children: ReactNode;\n}\n\n/** One term–value pair (a div grouping dt and dd – valid inside dl). */\nexport function DescriptionItem({ term, children }: DescriptionItemProps) {\n return (\n <div className=\"medo-dl__row\">\n <dt className=\"medo-dl__term\">{term}</dt>\n <dd className=\"medo-dl__value\">{children}</dd>\n </div>\n );\n}\n","import { useEffect, useRef, useState, type PointerEvent as ReactPointerEvent, type ReactNode } from 'react';\nimport { GridList, GridListItem, useLocale, type GridListItemProps, type GridListProps } from 'react-aria-components';\nimport { ChevronRight } from 'lucide-react';\nimport { AvatarSizeContext } from '../avatar/Avatar';\nimport { Checkbox } from '../checkbox/Checkbox';\nimport { Skeleton } from '../progress/Progress';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface ListViewProps<T> extends Omit<GridListProps<T>, 'className' | 'style' | 'layout' | 'keyboardNavigationBehavior'> {\n /** Required: names the list (“Inbox”). */\n 'aria-label'?: string;\n /** plain: full-page lists (inbox) · card: inside settings or dashboards (border, radius/lg) · cards: records on mobile (Table cards, use ListCard). */\n variant?: 'plain' | 'card' | 'cards';\n /** Shows 3 skeleton rows instead of the items (aria-busy). */\n isLoading?: boolean;\n /** Shown when there are no rows: an EmptyState with `size=\"inline\"`. */\n emptyState?: ReactNode;\n className?: string;\n}\n\n/**\n * List view – an interactive list of objects in apps: inbox, people, files, notifications, settings\n *. Built on React Aria GridList: ↑ ↓ move between rows, Enter opens a row, Tab reaches\n * the controls inside a row (menu, switch, buttons). `selectionMode=\"multiple\"` shows a checkbox per row and a click\n * toggles the row – use it without `onAction` (React Aria would run the action on click instead).\n * Rows can have swipe actions on touch (`swipeActions`) – the same actions always sit in the row's “…” menu.\n */\nexport function ListView<T extends object>({ variant = 'plain', isLoading = false, emptyState, className, children, items, ...props }: ListViewProps<T>) {\n if (isLoading) {\n return (\n <div role=\"list\" aria-busy=\"true\" aria-label={props['aria-label']} className={cx('medo-list-view', `medo-list-view--${variant}`, className)}>\n {Array.from({ length: 3 }, (_, i) =>\n variant === 'cards' ? (\n <div key={i} role=\"listitem\" className=\"medo-list-card medo-list-card--loading\">\n <span className=\"medo-list-card__content\">\n <Skeleton width=\"50%\" />\n <Skeleton width=\"35%\" />\n <Skeleton width=\"70%\" />\n </span>\n </div>\n ) : (\n <div key={i} role=\"listitem\" className=\"medo-list-row medo-list-row--loading\">\n <span className=\"medo-list-row__leading\">\n <Skeleton shape=\"circle\" width={40} height={40} />\n </span>\n <span className=\"medo-list-row__main\">\n <span className=\"medo-list-row__content\">\n <Skeleton width=\"40%\" />\n <Skeleton width=\"70%\" />\n </span>\n </span>\n </div>\n ),\n )}\n </div>\n );\n }\n return (\n <GridList<T>\n {...props}\n items={items}\n // Tab reaches the controls inside a row.\n keyboardNavigationBehavior=\"tab\"\n renderEmptyState={emptyState ? () => <div className=\"medo-list-view__empty\">{emptyState}</div> : undefined}\n className={cx('medo-list-view', `medo-list-view--${variant}`, className)}\n >\n {children}\n </GridList>\n );\n}\n\nexport interface ListRowProps extends Omit<GridListItemProps, 'children' | 'className' | 'style' | 'textValue'> {\n /** Required. One line, most important word first. Also the row's accessible name. */\n title: string;\n /** One line (2-line row) or two lines (`lines={3}`). */\n description?: ReactNode;\n /** 3: description up to two lines (row 88). Default: 1 without, 2 with a description. */\n lines?: 2 | 3;\n /** Avatar (sized automatically: sm in 1-line rows, lg otherwise), an icon tile (ListRowIcon) or a 40 px thumbnail. */\n leading?: ReactNode;\n /** Meta text (time, size) in caption. */\n meta?: ReactNode;\n /** One trailing type per list: Badge, Menu (“…”), Switch or max 2 Button sm. With buttons the row has no action. */\n trailing?: ReactNode;\n /** The row navigates (href) – shows a chevron. */\n chevron?: boolean;\n /** New or unread: title and excerpt strong, meta in brand, dot below the meta, “Unread” for screen readers. */\n unread?: boolean;\n /** Screen-reader word for unread rows. */\n unreadLabel?: string;\n /**\n * Touch only: end = swipe toward the start (left in LTR, e.g. Delete) · start = swipe toward the end (a safe action,\n * e.g. Archive). Always put the same actions into the row's “…” menu – swipe is a shortcut, never the only way.\n */\n swipeActions?: { start?: SwipeAction; end?: SwipeAction };\n}\n\nexport interface SwipeAction {\n /** Short verb (“Delete”, “Archive”). */\n label: string;\n icon: ReactNode;\n /** Runs on a full swipe or a tap on the revealed action. Delete: remove at once and offer “Undo” in a Toast. */\n onAction: () => void;\n /** danger: feedback/danger/solid (Delete) · primary: action/primary (Archive). */\n tone?: 'danger' | 'primary';\n}\n\n/** One row of a List view: leading – content – trailing. Height 48, 64 or 88 by lines. */\nexport function ListRow({ title, description, lines, leading, meta, trailing, chevron, unread, unreadLabel, swipeActions, ...props }: ListRowProps) {\n const m = useMessages();\n const rowLines = description ? (lines ?? 2) : 1;\n const swipe = swipeActions?.start || swipeActions?.end;\n return (\n <GridListItem\n {...props}\n textValue={title}\n className={cx('medo-list-row', `medo-list-row--lines-${rowLines}`, unread && 'medo-list-row--unread', swipe && 'medo-list-row--swipe')}\n >\n {({ selectionMode }) => {\n const content = (\n <>\n {selectionMode !== 'none' && (\n <span className=\"medo-list-row__check\">\n <Checkbox slot=\"selection\" />\n </span>\n )}\n {leading && (\n // Avatars size themselves: sm in 1-line rows, lg in 2–3 lines.\n <AvatarSizeContext.Provider value={rowLines === 1 ? 'sm' : 'lg'}>\n <span className=\"medo-list-row__leading\">{leading}</span>\n </AvatarSizeContext.Provider>\n )}\n <span className=\"medo-list-row__main\">\n <span className=\"medo-list-row__content\">\n <span className=\"medo-list-row__title\">\n {unread && <span className=\"medo-visually-hidden\">{unreadLabel ?? m.listView.unread}: </span>}\n {title}\n </span>\n {description && <span className=\"medo-list-row__description\">{description}</span>}\n </span>\n {(meta || unread) && (\n <span className=\"medo-list-row__meta\">\n {meta && <span className=\"medo-list-row__meta-text\">{meta}</span>}\n {unread && <span className=\"medo-list-row__dot\" aria-hidden=\"true\" />}\n </span>\n )}\n {trailing && <span className=\"medo-list-row__trailing\">{trailing}</span>}\n {chevron && (\n <span className=\"medo-list-row__chevron\" aria-hidden=\"true\">\n <ChevronRight />\n </span>\n )}\n </span>\n </>\n );\n return swipe ? <Swipeable actions={swipeActions!}>{content}</Swipeable> : content;\n }}\n </GridListItem>\n );\n}\n\n/* ---------- Swipe ---------- */\n\nconst SWIPE = {\n action: 88, // revealed action width – snaps open from here\n lock: 8, // px before the direction is decided\n full: 0.5, // share of the row width that triggers at once\n flick: 0.5, // px per ms\n};\n\n/** Only one row is open at a time. */\nlet closeOpenRow: (() => void) | null = null;\n\nfunction Swipeable({ actions, children }: { actions: { start?: SwipeAction; end?: SwipeAction }; children: ReactNode }) {\n const { direction } = useLocale();\n const rtl = direction === 'rtl';\n const surface = useRef<HTMLSpanElement>(null);\n const drag = useRef<{ x: number; y: number; t: number; base: number; lock: 'x' | 'y' | null; id: number; buzzed: boolean } | null>(null);\n const [offset, setOffset] = useState(0); // logical: < 0 reveals the end action, > 0 the start action\n const [dragging, setDragging] = useState(false);\n const [leaving, setLeaving] = useState(false);\n const open = offset !== 0 && !dragging;\n\n const close = () => setOffset(0);\n\n // An open row closes on a tap elsewhere, on scroll and on Esc.\n useEffect(() => {\n if (!open) return;\n closeOpenRow?.();\n closeOpenRow = close;\n const row = surface.current?.closest('.medo-list-row');\n const onDown = (e: Event) => !row?.contains(e.target as Node) && close();\n const onKey = (e: KeyboardEvent) => e.key === 'Escape' && close();\n document.addEventListener('pointerdown', onDown, true);\n window.addEventListener('scroll', close, true);\n document.addEventListener('keydown', onKey);\n return () => {\n if (closeOpenRow === close) closeOpenRow = null;\n document.removeEventListener('pointerdown', onDown, true);\n window.removeEventListener('scroll', close, true);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const width = () => surface.current?.getBoundingClientRect().width ?? 0;\n const actionFor = (value: number) => (value < 0 ? actions.end : value > 0 ? actions.start : undefined);\n\n const trigger = (action: SwipeAction, side: number) => {\n // The row slides out (250 ms, accelerating), then the action runs – the app removes the row and shows “Undo”.\n setLeaving(true);\n setOffset(side * width());\n window.setTimeout(() => {\n action.onAction();\n setLeaving(false);\n setOffset(0);\n }, 250);\n };\n\n const onPointerDown = (e: ReactPointerEvent) => {\n if (e.pointerType === 'mouse') return; // touch and pen only – mouse and keyboard use the “…” menu\n drag.current = { x: e.clientX, y: e.clientY, t: e.timeStamp, base: offset, lock: null, id: e.pointerId, buzzed: false };\n };\n\n const onPointerMove = (e: ReactPointerEvent) => {\n const d = drag.current;\n if (!d || e.pointerId !== d.id) return;\n const dx = (e.clientX - d.x) * (rtl ? -1 : 1);\n const dy = e.clientY - d.y;\n if (!d.lock) {\n if (Math.abs(dy) > SWIPE.lock && Math.abs(dy) > Math.abs(dx)) d.lock = 'y';\n else if (Math.abs(dx) > SWIPE.lock) {\n d.lock = 'x';\n setDragging(true);\n surface.current?.setPointerCapture(e.pointerId);\n // A swipe is not a press: cancel the row's press so it does not open.\n e.currentTarget.dispatchEvent(new PointerEvent('pointercancel', { bubbles: true, pointerId: e.pointerId, pointerType: e.pointerType }));\n }\n }\n if (d.lock !== 'x') return;\n let next = d.base + dx;\n // No action on that side: resist (rubber band) instead of revealing an empty area.\n if (!actionFor(next)) next = next / 4;\n // A short haptic tick when the full-swipe threshold is crossed (where supported).\n const past = Math.abs(next) >= width() * SWIPE.full && !!actionFor(next);\n if (past && !d.buzzed) navigator.vibrate?.(10);\n d.buzzed = past;\n setOffset(next);\n };\n\n const onPointerEnd = (e: ReactPointerEvent) => {\n const d = drag.current;\n drag.current = null;\n if (!d || d.lock !== 'x') return;\n setDragging(false);\n const action = actionFor(offset);\n const velocity = ((e.clientX - d.x) * (rtl ? -1 : 1)) / Math.max(1, e.timeStamp - d.t);\n const side = Math.sign(offset);\n if (!action) return close();\n if (Math.abs(offset) >= width() * SWIPE.full || (Math.abs(velocity) > SWIPE.flick && Math.sign(velocity) === side && Math.abs(offset) > SWIPE.action / 2))\n return trigger(action, side);\n setOffset(Math.abs(offset) >= SWIPE.action ? side * SWIPE.action : 0);\n };\n\n const revealed = actionFor(offset);\n return (\n <>\n {revealed && (\n // Visual shortcut for touch; keyboard and screen readers use the “…” menu, so it is hidden from them.\n <span\n className={cx(\n 'medo-list-row__swipe-action',\n `medo-list-row__swipe-action--${offset < 0 ? 'end' : 'start'}`,\n `medo-list-row__swipe-action--${revealed.tone ?? 'primary'}`,\n )}\n style={{ inlineSize: Math.abs(offset) }}\n aria-hidden=\"true\"\n onPointerDown={(e) => e.stopPropagation()}\n onClick={(e) => {\n e.stopPropagation();\n trigger(revealed, Math.sign(offset));\n }}\n >\n <span className=\"medo-list-row__swipe-label\">\n {revealed.icon}\n {revealed.label}\n </span>\n </span>\n )}\n <span\n ref={surface}\n className={cx('medo-list-row__surface', dragging && 'medo-list-row__surface--dragging', leaving && 'medo-list-row__surface--leaving')}\n style={{ transform: offset ? `translateX(${rtl ? -offset : offset}px)` : undefined }}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerEnd}\n onPointerCancel={(e) => {\n // Our own cancel (to stop the press) must not end the swipe.\n if (!e.isTrusted) return;\n onPointerEnd(e);\n }}\n >\n {children}\n {/* While open, a tap on the row closes it instead of opening the row. */}\n {open && (\n <span\n className=\"medo-list-row__swipe-shield\"\n aria-hidden=\"true\"\n onPointerDown={(e) => {\n e.stopPropagation();\n close();\n }}\n />\n )}\n </span>\n </>\n );\n}\n\n/** Leading icon in a 40 px tile (settings rows). Decorative – the title carries the meaning. */\nexport function ListRowIcon({ children }: { children: ReactNode }) {\n return (\n <span className=\"medo-list-row__icon\" aria-hidden=\"true\">\n {children}\n </span>\n );\n}\n\nexport interface ListCardProps extends Omit<GridListItemProps, 'children' | 'className' | 'style' | 'textValue'> {\n /** Required. The record (“INV-2026-0140”). Also the card's accessible name. */\n title: string;\n /** Key number on the right of the title (amount, count) – strong, never truncated. */\n amount?: ReactNode;\n /** Second line, e.g. the owner with an Avatar (sized xs automatically). */\n description?: ReactNode;\n /** Bottom left: date or other meta in caption. */\n meta?: ReactNode;\n /** Bottom right: status as Badge sm with dot. */\n status?: ReactNode;\n}\n\n/**\n * List card – a record as a card, the mobile form of a table row. Use inside\n * `<ListView variant=\"cards\">`: the whole card opens the record (`href` or `onAction`); in selection mode\n * a checkbox lg shows and a tap toggles the card.\n */\nexport function ListCard({ title, amount, description, meta, status, ...props }: ListCardProps) {\n return (\n <GridListItem {...props} textValue={title} className=\"medo-list-card\">\n {({ selectionMode }) => (\n <>\n {selectionMode !== 'none' && (\n <span className=\"medo-list-card__check\">\n <Checkbox slot=\"selection\" size=\"lg\" />\n </span>\n )}\n <span className=\"medo-list-card__content\">\n <span className=\"medo-list-card__top\">\n <span className=\"medo-list-card__title\">{title}</span>\n {amount && <span className=\"medo-list-card__amount\">{amount}</span>}\n </span>\n {description && (\n <AvatarSizeContext.Provider value=\"xs\">\n <span className=\"medo-list-card__description\">{description}</span>\n </AvatarSizeContext.Provider>\n )}\n {(meta || status) && (\n <span className=\"medo-list-card__bottom\">\n <span className=\"medo-list-card__meta\">{meta}</span>\n {status}\n </span>\n )}\n </span>\n </>\n )}\n </GridListItem>\n );\n}\n","import { useEffect, useRef, type KeyboardEvent, type ReactNode } from 'react';\nimport { Button as AriaButton, Toolbar } from 'react-aria-components';\nimport { Ellipsis, X } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { Menu, MenuButton, MenuItem, MenuTrigger } from '../menu/Menu';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface BulkAction {\n /** Verb (“Export”, “Archive”, “Delete”). */\n label: string;\n onAction: () => void;\n /** danger: destructive – confirm it (Alert dialog) or offer Undo (Toast). Mobile: ghost danger. */\n variant?: 'default' | 'danger';\n /** Icon for the “…” menu (actions that do not fit in the bar). */\n icon?: ReactNode;\n}\n\nexport interface BulkActionBarProps {\n /** Number of selected items. 0 hides the bar. */\n count: number;\n /** Desktop shows 3, mobile 2 (with more: 1 and “…”); the rest go into the “…” menu. Most important first, destructive last. */\n actions: BulkAction[];\n /** Clears the selection (× and Esc). */\n onClear: () => void;\n /** auto: floating dark bar on desktop, full-width bar at the bottom below 640 px · desktop · mobile. */\n variant?: 'auto' | 'desktop' | 'mobile';\n /** Texts (localize). */\n countLabel?: (count: number) => string;\n clearLabel?: string;\n moreLabel?: string;\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * Bulk action bar – actions for the selected rows of a Table or List view.\n * Appears with ≥ 1 selected item and floats, so selecting never shifts the layout. A toolbar: the count is\n * announced, Esc or × clears the selection. Render it right after the list, so Tab reaches it next.\n */\nexport function BulkActionBar({\n count,\n actions,\n onClear,\n variant = 'auto',\n countLabel: countLabelProp,\n clearLabel: clearLabelProp,\n moreLabel: moreLabelProp,\n 'aria-label': ariaLabelProp,\n className,\n}: BulkActionBarProps) {\n const m = useMessages();\n const countLabel = countLabelProp ?? m.bulkActionBar.count;\n const clearLabel = clearLabelProp ?? m.bulkActionBar.clear;\n const moreLabel = moreLabelProp ?? m.bulkActionBar.more;\n const ariaLabel = ariaLabelProp ?? m.bulkActionBar.label;\n const mobile = useMediaQuery(MOBILE_QUERY);\n const isMobile = variant === 'mobile' || (variant === 'auto' && mobile);\n const visible = count > 0;\n // Where focus came from (a row checkbox): it goes back there when the bar disappears under it.\n const returnTo = useRef<HTMLElement | null>(null);\n const focusInside = useRef(false);\n\n useEffect(() => {\n if (visible || !focusInside.current) return;\n focusInside.current = false;\n if (returnTo.current?.isConnected) returnTo.current.focus();\n }, [visible]);\n\n // Mobile has room for two buttons next to × and the count: with more actions, the first stays and “…” takes the rest.\n const max = isMobile ? (actions.length > 2 ? 1 : 2) : 3;\n const shown = actions.slice(0, max);\n const more = actions.slice(max);\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && !e.defaultPrevented) {\n e.preventDefault();\n onClear();\n }\n };\n\n const overflow =\n more.length > 0 &&\n (isMobile ? (\n <MenuTrigger>\n <MenuButton aria-label={moreLabel} size=\"lg\" />\n <OverflowMenu actions={more} />\n </MenuTrigger>\n ) : (\n <MenuTrigger>\n <AriaButton aria-label={moreLabel} className=\"medo-toast__button medo-toast__close\">\n <Ellipsis aria-hidden=\"true\" />\n </AriaButton>\n <OverflowMenu actions={more} />\n </MenuTrigger>\n ));\n\n return (\n <>\n {/* Always mounted, so the count is announced reliably (a new live region is often missed). */}\n <span role=\"status\" className=\"medo-visually-hidden\">\n {visible ? countLabel(count) : ''}\n </span>\n {visible && (\n // The wrapper handles Esc and remembers where focus came from (events bubble from the toolbar).\n <div\n className=\"medo-bulk-bar-host\"\n onKeyDown={onKeyDown}\n onFocus={(e) => {\n focusInside.current = true;\n const from = e.relatedTarget as HTMLElement | null;\n if (from && !e.currentTarget.contains(from)) returnTo.current = from;\n }}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) focusInside.current = false;\n }}\n >\n <Toolbar aria-label={ariaLabel} className={cx('medo-bulk-bar', isMobile ? 'medo-bulk-bar--mobile' : 'medo-bulk-bar--desktop', className)}>\n {isMobile ? (\n <>\n <span className=\"medo-bulk-bar__start\">\n <IconButton variant=\"ghost\" size=\"lg\" icon={<X />} aria-label={clearLabel} tooltip={false} onPress={onClear} />\n <span className=\"medo-bulk-bar__count\">{countLabel(count)}</span>\n </span>\n <span className=\"medo-bulk-bar__actions\">\n {shown.map((a) => (\n <Button key={a.label} variant={a.variant === 'danger' ? 'ghost-danger' : 'ghost'} size=\"lg\" onPress={a.onAction}>\n {a.label}\n </Button>\n ))}\n {overflow}\n </span>\n </>\n ) : (\n <>\n <span className=\"medo-bulk-bar__count\">{countLabel(count)}</span>\n <span className=\"medo-bulk-bar__divider\" aria-hidden=\"true\" />\n {shown.map((a) => (\n <AriaButton key={a.label} className=\"medo-toast__button medo-toast__action\" onPress={a.onAction}>\n {a.label}\n </AriaButton>\n ))}\n {overflow}\n <span className=\"medo-bulk-bar__divider\" aria-hidden=\"true\" />\n <AriaButton aria-label={clearLabel} className=\"medo-toast__button medo-toast__close\" onPress={onClear}>\n <X aria-hidden=\"true\" />\n </AriaButton>\n </>\n )}\n </Toolbar>\n </div>\n )}\n </>\n );\n}\n\nfunction OverflowMenu({ actions }: { actions: BulkAction[] }) {\n return (\n <Menu onAction={(key) => actions[Number(key)]?.onAction()}>\n {actions.map((a, i) => (\n <MenuItem key={i} id={i} icon={a.icon} variant={a.variant === 'danger' ? 'danger' : 'default'}>\n {a.label}\n </MenuItem>\n ))}\n </Menu>\n );\n}\n","import { useId, type ElementType, type HTMLAttributes, type ReactNode } from 'react';\nimport { CircleAlert, CircleCheck, Folder, Lock, Search } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { Link } from '../link/Link';\nimport { cx } from '../utils/cx';\n\nexport type EmptyStateType = 'first-use' | 'no-results' | 'error' | 'no-access' | 'all-done';\nexport type EmptyStateSize = 'page' | 'section' | 'inline';\n\nexport interface EmptyStateAction {\n /** Verb that says what happens (“Create project”, “Clear filters”, “Try again”). */\n label: string;\n /** Runs the action. */\n onPress?: () => void;\n /** Second action only: navigates – rendered as a Link (“Learn more”, “View archive”). */\n href?: string;\n isDisabled?: boolean;\n}\n\nexport interface EmptyStateProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {\n /** Sets the default icon, its tone and the look of the main action. */\n type?: EmptyStateType;\n /** page: a whole view · section: a card or panel · inline: inside a list or table (header stays). */\n size?: EmptyStateSize;\n /** Required. The situation in plain words – never “No data”. */\n title: ReactNode;\n /** Why it is empty or what comes next, in one or two sentences. */\n description?: ReactNode;\n /** Main action: primary for first use, secondary for all other types. “All done” needs none. */\n action?: EmptyStateAction;\n /** Second action as a text button, or a Link with `href`. */\n secondaryAction?: EmptyStateAction;\n /** Replaces the type's default icon (Lucide). */\n icon?: ReactNode;\n /** Illustration instead of the icon – only from the shared illustration style. Decorative. */\n illustration?: ReactNode;\n /** Heading level of the title (page and section). Match the page outline. Default: page h2, section h3. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n}\n\nconst defaults: Record<EmptyStateType, { icon: ReactNode; tone: IconTileTone }> = {\n 'first-use': { icon: <Folder />, tone: 'neutral' },\n 'no-results': { icon: <Search />, tone: 'neutral' },\n error: { icon: <CircleAlert />, tone: 'danger' },\n 'no-access': { icon: <Lock />, tone: 'neutral' },\n 'all-done': { icon: <CircleCheck />, tone: 'success' },\n};\n\nconst tileSize = { page: 'lg', section: 'md', inline: 'sm' } as const;\n\n/**\n * Empty state – what users see when there is nothing to show, and what they can do next.\n * Page and section render a `<section>` named by its heading; inline renders a plain block, so it does not add\n * a landmark inside a list or table. “No results” puts its text in a polite status region; focus stays where it was.\n */\nexport function EmptyState({\n type = 'first-use',\n size = 'page',\n title,\n description,\n action,\n secondaryAction,\n icon,\n illustration,\n headingLevel,\n className,\n ...props\n}: EmptyStateProps) {\n const titleId = useId();\n const { icon: defaultIcon, tone } = defaults[type];\n const isInline = size === 'inline';\n const Tag: ElementType = isInline ? 'div' : 'section';\n const Title: ElementType = isInline ? 'p' : `h${headingLevel ?? (size === 'page' ? 2 : 3)}`;\n const buttonSize = size === 'page' ? 'md' : 'sm';\n\n return (\n <Tag {...props} aria-labelledby={isInline ? undefined : titleId} className={cx('medo-empty-state', `medo-empty-state--${size}`, className)}>\n {illustration ? (\n <span className=\"medo-empty-state__illustration\" aria-hidden=\"true\">\n {illustration}\n </span>\n ) : (\n <IconTile size={tileSize[size]} tone={tone}>\n {icon ?? defaultIcon}\n </IconTile>\n )}\n {/* “No results” after a search or filter is announced politely. */}\n <div className=\"medo-empty-state__content\" role={type === 'no-results' ? 'status' : undefined}>\n <Title id={titleId} className=\"medo-empty-state__title\">\n {title}\n </Title>\n {description && <p className=\"medo-empty-state__description\">{description}</p>}\n </div>\n {(action || secondaryAction) && (\n <div className=\"medo-empty-state__actions\">\n {action && (\n <Button variant={type === 'first-use' ? 'primary' : 'secondary'} size={buttonSize} onPress={action.onPress} isDisabled={action.isDisabled}>\n {action.label}\n </Button>\n )}\n {secondaryAction &&\n (secondaryAction.href ? (\n <Link variant=\"standalone\" href={secondaryAction.href} isDisabled={secondaryAction.isDisabled}>\n {secondaryAction.label}\n </Link>\n ) : (\n <Button variant=\"text\" size={buttonSize} onPress={secondaryAction.onPress} isDisabled={secondaryAction.isDisabled}>\n {secondaryAction.label}\n </Button>\n ))}\n </div>\n )}\n </Tag>\n );\n}\n\n/* ---------- Icon tile (internal – shared with Dropzone and Embed consent) ---------- */\n\n/** raised: surface/default – on surface/subtle (Embed consent). */\nexport type IconTileTone = 'neutral' | 'raised' | 'danger' | 'success';\n\n/** Round, decorative icon tile: sm 40 / icon 20 · md 48 / 24 · lg 64 / 32. Internal, not exported from the package. */\nexport function IconTile({ size = 'md', tone = 'neutral', children }: { size?: 'sm' | 'md' | 'lg'; tone?: IconTileTone; children: ReactNode }) {\n return (\n <span className={cx('medo-icon-tile', `medo-icon-tile--${size}`, `medo-icon-tile--${tone}`)} aria-hidden=\"true\">\n {children}\n </span>\n );\n}\n","import { useId, useRef, useState, type ReactNode } from 'react';\nimport { Button as AriaButton, Link as AriaLink } from 'react-aria-components';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Select } from '../select/Select';\nimport { Option } from '../listbox/ListBox';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface PaginationProps {\n /** Current page (1-based, controlled). */\n page?: number;\n /** Start page when uncontrolled. */\n defaultPage?: number;\n /** Called with the new page (apps). Not needed with `getPageHref`. */\n onChange?: (page: number) => void;\n /** Websites: every page becomes a real link (“?page=5”) – shareable, back button works. Works with RouterProvider. */\n getPageHref?: (page: number) => string;\n /** Number of pages. Default: totalItems / pageSize. With 1 page nothing is shown. */\n totalPages?: number;\n /** Total count: shows the summary (“81–100 of 380”). */\n totalItems?: number;\n /** Rows per page. */\n pageSize?: number;\n /** Shows “Rows per page” (Select sm). */\n onPageSizeChange?: (pageSize: number) => void;\n pageSizeOptions?: number[];\n /** auto: compact below 640 px · full: summary, rows per page and pages · compact: ‹ Page 5 of 19 › (narrow panels). */\n variant?: 'auto' | 'full' | 'compact';\n /** Full only: md 40 · lg 48 (touch). Compact is always lg. */\n size?: 'md' | 'lg';\n /** Name of the navigation region. */\n 'aria-label'?: string;\n /** Texts (localize). */\n summary?: (from: number, to: number, total: number) => string;\n pageSizeLabel?: string;\n previousLabel?: string;\n nextLabel?: string;\n /** Accessible name of a page item and the compact text. */\n pageLabel?: (page: number) => string;\n compactLabel?: (page: number, totalPages: number) => string;\n className?: string;\n}\n\n/** Page numbers with ellipsis: max 7 items, first and last always, the current page with one neighbour each side. */\nexport function getPageItems(page: number, totalPages: number): (number | 'ellipsis')[] {\n if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i + 1);\n // Near the start or the end five pages in a row, so an ellipsis never hides a single page.\n if (page <= 4) return [1, 2, 3, 4, 5, 'ellipsis', totalPages];\n if (page >= totalPages - 3) return [1, 'ellipsis', ...Array.from({ length: 5 }, (_, i) => totalPages - 4 + i)];\n return [1, 'ellipsis', page - 1, page, page + 1, 'ellipsis', totalPages];\n}\n\n/**\n * Pagination – move through long lists page by page. A navigation region:\n * buttons for apps (`onChange`) or real links for websites (`getPageHref`). Full on desktop, compact below 640 px.\n * After a change the app scrolls to the top of the list and focuses its heading. “Load more” is a Button, not a variant.\n */\nexport function Pagination({\n page: pageProp,\n defaultPage = 1,\n onChange,\n getPageHref,\n totalPages: totalPagesProp,\n totalItems,\n pageSize = 20,\n onPageSizeChange,\n pageSizeOptions = [10, 20, 50, 100],\n variant = 'auto',\n size = 'md',\n 'aria-label': ariaLabelProp,\n summary: summaryProp,\n pageSizeLabel: pageSizeLabelProp,\n previousLabel: previousLabelProp,\n nextLabel: nextLabelProp,\n pageLabel: pageLabelProp,\n compactLabel: compactLabelProp,\n className,\n}: PaginationProps) {\n const m = useMessages();\n const ariaLabel = ariaLabelProp ?? m.pagination.label;\n const summary = summaryProp ?? m.pagination.summary;\n const pageSizeLabel = pageSizeLabelProp ?? m.pagination.pageSize;\n const previousLabel = previousLabelProp ?? m.pagination.previous;\n const nextLabel = nextLabelProp ?? m.pagination.next;\n const pageLabel = pageLabelProp ?? m.pagination.page;\n const compactLabel = compactLabelProp ?? m.pagination.pageOf;\n const [innerPage, setInnerPage] = useState(defaultPage);\n const mobile = useMediaQuery(MOBILE_QUERY);\n const totalPages = totalPagesProp ?? (totalItems !== undefined ? Math.ceil(totalItems / pageSize) : 1);\n const page = Math.min(Math.max(pageProp ?? innerPage, 1), Math.max(totalPages, 1));\n const compact = variant === 'compact' || (variant === 'auto' && mobile);\n const itemSize = compact ? 'lg' : size;\n const statusId = useId();\n const navRef = useRef<HTMLElement>(null);\n\n // One page: nothing to navigate.\n if (totalPages <= 1) return null;\n\n const go = (p: number) => {\n if (pageProp === undefined) setInnerPage(p);\n onChange?.(p);\n // “Next” on the second-last page becomes disabled and drops focus. If the app did not move focus\n // (to the list heading), keep it in the pagination: on the current page, or on the other arrow.\n requestAnimationFrame(() => {\n const nav = navRef.current;\n if (!nav || (document.activeElement && document.activeElement !== document.body)) return;\n (nav.querySelector<HTMLElement>('[aria-current=\"page\"]') ?? nav.querySelector<HTMLElement>('.medo-button:not([data-disabled])'))?.focus();\n });\n };\n\n /** A page item, previous or next: a link on websites, a button in apps. */\n const item = (target: number, props: { className: string; 'aria-label': string; 'aria-current'?: 'page'; isDisabled?: boolean; children: ReactNode }) =>\n getPageHref ? (\n <AriaLink {...props} href={props.isDisabled ? undefined : getPageHref(target)} onPress={() => go(target)} />\n ) : (\n <AriaButton {...props} onPress={() => go(target)} />\n );\n\n const step = (target: number, label: string, icon: ReactNode) =>\n item(target, {\n className: cx('medo-button', 'medo-button--icon-only', 'medo-button--ghost', `medo-button--${itemSize}`),\n 'aria-label': label,\n isDisabled: target < 1 || target > totalPages,\n children: (\n <span className=\"medo-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ),\n });\n\n const from = (page - 1) * pageSize + 1;\n const to = totalItems !== undefined ? Math.min(page * pageSize, totalItems) : page * pageSize;\n\n return (\n <nav ref={navRef} aria-label={ariaLabel} className={cx('medo-pagination', compact ? 'medo-pagination--compact' : 'medo-pagination--full', className)}>\n {compact ? (\n <>\n {step(page - 1, previousLabel, <ChevronLeft />)}\n {/* Polite live region: the new page is announced after a change. */}\n <p role=\"status\" className=\"medo-pagination__compact-label\">\n {compactLabel(page, totalPages)}\n </p>\n {step(page + 1, nextLabel, <ChevronRight />)}\n </>\n ) : (\n <>\n {(totalItems !== undefined || onPageSizeChange) && (\n <div className=\"medo-pagination__info\">\n {totalItems !== undefined && (\n <p id={statusId} role=\"status\" className=\"medo-pagination__summary\">\n {summary(from, to, totalItems)}\n </p>\n )}\n {onPageSizeChange && (\n <Select\n label={pageSizeLabel}\n size=\"sm\"\n selectedKey={pageSize}\n onSelectionChange={(key) => key != null && onPageSizeChange(Number(key))}\n className=\"medo-pagination__size\"\n >\n {pageSizeOptions.map((n) => (\n <Option key={n} id={n}>\n {String(n)}\n </Option>\n ))}\n </Select>\n )}\n </div>\n )}\n <ul className=\"medo-pagination__pages\" role=\"list\">\n <li>{step(page - 1, previousLabel, <ChevronLeft />)}</li>\n {getPageItems(page, totalPages).map((p, i) =>\n p === 'ellipsis' ? (\n // Text, not a button – hidden from screen readers (the page names say where they jump).\n <li key={`e${i}`} className={cx('medo-page-item', 'medo-page-item--ellipsis', `medo-page-item--${itemSize}`)} aria-hidden=\"true\">\n …\n </li>\n ) : (\n <li key={p}>\n {item(p, {\n className: cx('medo-button', 'medo-button--ghost', `medo-button--${itemSize}`, 'medo-page-item', `medo-page-item--${itemSize}`),\n 'aria-label': pageLabel(p),\n 'aria-current': p === page ? 'page' : undefined,\n children: p,\n })}\n </li>\n ),\n )}\n <li>{step(page + 1, nextLabel, <ChevronRight />)}</li>\n </ul>\n </>\n )}\n </nav>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Button as AriaButton, Input as AriaInput, SearchField as AriaSearchField, type SearchFieldProps as AriaSearchFieldProps } from 'react-aria-components';\nimport { Search, X } from 'lucide-react';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport type { InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface SearchFieldProps extends Omit<AriaSearchFieldProps, 'children' | 'className' | 'style'> {\n /** Visible label. Without it set `aria-label` (e.g. in a table toolbar or the header). */\n label?: ReactNode;\n /** Helper text below the field. */\n description?: ReactNode;\n /** A hint like “Search invoices”. Never the only label. */\n placeholder?: string;\n /** sm 32 (toolbars) · md 40 · lg 48 (search page, Quick search, mobile). */\n size?: InputSize;\n /** Accessible name of the clear button. */\n clearLabel?: string;\n className?: string;\n}\n\n/**\n * Search field – a text field for a search term. Built on React Aria\n * SearchField: Enter submits (`onSubmit`), Esc or × clears. Put it in a `<search>` element (search landmark);\n * keep the term in the field after searching.\n */\nexport function SearchField({ label, description, placeholder, size = 'md', clearLabel, className, ...props }: SearchFieldProps) {\n const m = useMessages();\n return (\n <AriaSearchField {...props} className={cx('medo-field', 'medo-search-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <div className={cx('medo-input', `medo-input--${size}`)}>\n <span className=\"medo-input__icon\" aria-hidden=\"true\">\n <Search />\n </span>\n <AriaInput className=\"medo-input__control\" placeholder={placeholder} />\n {/* React Aria keeps it out of the tab order – Esc clears from the field. */}\n <AriaButton aria-label={clearLabel ?? m.searchField.clear} className=\"medo-input__action medo-search-field__clear\">\n <X />\n </AriaButton>\n </div>\n {description && <FieldFooter description={description} />}\n </AriaSearchField>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Link as AriaLink, type LinkProps as AriaLinkProps } from 'react-aria-components';\nimport { FileText, Globe } from 'lucide-react';\nimport { AvatarSizeContext } from '../avatar/Avatar';\nimport { Badge } from '../badge/Badge';\nimport { IconTile } from '../empty-state/EmptyState';\nimport { cx } from '../utils/cx';\nimport { Highlight } from '../utils/highlight';\n\nexport type SearchResultType = 'page' | 'document' | 'person' | 'media';\n\nexport interface SearchResultProps {\n /** Sets the default leading icon: page (globe), document (file). Person and media take `leading`. */\n type?: SearchResultType;\n /** base: divider between hits, title in brand colour · aesthetic: no divider, larger title, rounded hover surface. */\n variant?: 'base' | 'aesthetic';\n /** Required. The hit's title – a link to the result. */\n title: string;\n href: string;\n /** Search term: shown in bold in title and snippet (every match), never by colour alone. */\n query?: string;\n /** Where it lives (“Help center › Billing”). */\n path?: ReactNode;\n /** Text around the match, max 2 lines. A string gets the highlight. */\n snippet?: ReactNode;\n /** Type label as Badge sm (“Page”, “PDF”, “Video”). */\n badge?: string;\n /** Meta text next to the badge (“Updated 3 days ago”). */\n meta?: ReactNode;\n /** Person: Avatar (sized lg automatically). Media: an image (4:3; 128 wide, 160 in aesthetic). Overrides the type icon. */\n leading?: ReactNode;\n /** Heading level of the title. Match the page outline (default h3 below the results heading). */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Router options or target for the link. */\n linkProps?: Omit<AriaLinkProps, 'href' | 'children' | 'className'>;\n className?: string;\n}\n\nconst icons: Partial<Record<SearchResultType, ReactNode>> = { page: <Globe />, document: <FileText /> };\n\n/**\n * Search result – one hit: path, title with the search term in bold, snippet,\n * meta row with type badge. The whole result is one link (the title), so it is one tab stop.\n * Put results into `<ul role=\"list\" className=\"medo-search-results\">` with one `<li>` per hit.\n */\nexport function SearchResult({\n type = 'page',\n variant = 'base',\n title,\n href,\n query,\n path,\n snippet,\n badge,\n meta,\n leading,\n headingLevel = 3,\n linkProps,\n className,\n}: SearchResultProps) {\n const Heading = `h${headingLevel}` as const;\n const lead = leading ?? (icons[type] && <IconTile size=\"sm\">{icons[type]}</IconTile>);\n return (\n <article className={cx('medo-search-result', `medo-search-result--${variant}`, `medo-search-result--${type}`, className)}>\n {lead && (\n <AvatarSizeContext.Provider value=\"lg\">\n <span className=\"medo-search-result__leading\">{lead}</span>\n </AvatarSizeContext.Provider>\n )}\n <div className=\"medo-search-result__content\">\n {path && <span className=\"medo-search-result__path\">{path}</span>}\n <Heading className=\"medo-search-result__title\">\n <AriaLink {...linkProps} href={href} className=\"medo-search-result__link\">\n <Highlight text={title} query={query} all className=\"medo-search-result__match\" />\n </AriaLink>\n </Heading>\n {snippet && (\n <p className=\"medo-search-result__snippet\">\n {typeof snippet === 'string' ? <Highlight text={snippet} query={query} all className=\"medo-search-result__match\" /> : snippet}\n </p>\n )}\n {(badge || meta) && (\n <span className=\"medo-search-result__meta\">\n {badge && (\n <Badge tone=\"neutral\" size=\"sm\">\n {badge}\n </Badge>\n )}\n {meta && <span className=\"medo-search-result__meta-text\">{meta}</span>}\n </span>\n )}\n </div>\n </article>\n );\n}\n","import { useEffect, useLayoutEffect, useState, type ReactNode } from 'react';\nimport { Autocomplete, Button as AriaButton, Dialog, Modal, ModalOverlay, useFilter } from 'react-aria-components';\nimport { Search } from 'lucide-react';\nimport { Badge } from '../badge/Badge';\nimport { Button } from '../button/Button';\nimport { Link } from '../link/Link';\nimport { ListBox, OptionHighlightContext } from '../listbox/ListBox';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { SearchField } from './SearchField';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface QuickSearchProps<T extends object> {\n isOpen?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n /** Opens with Cmd / Ctrl + K (ignored while the user types in another field). */\n shortcut?: boolean;\n /** The search term (controlled) – e.g. to load suggestions from the server. */\n inputValue?: string;\n onInputChange?: (value: string) => void;\n /** Filters the options on the client (contains, case insensitive). Off when the server filters. */\n clientFilter?: boolean;\n /** Empty field: Recent and Suggested. While typing: hits grouped by type (ListBoxSection), max 5 per group. */\n children: ReactNode | ((item: T) => ReactNode);\n items?: Iterable<T>;\n /** Opens the highlighted hit (Enter or click). */\n onAction?: (key: React.Key) => void;\n /** “All results”: the search page with the same term. */\n allResultsHref?: (query: string) => string;\n /** Enter without a highlighted hit, and “Search all content” when nothing matches. */\n onSearch?: (query: string) => void;\n /** Texts (localize). */\n 'aria-label'?: string;\n placeholder?: string;\n cancelLabel?: string;\n suggestionsLabel?: string;\n allResultsLabel?: (query: string) => string;\n noResultsLabel?: (query: string) => string;\n searchAllLabel?: (query: string) => string;\n hints?: { navigate: string; open: string; close: string };\n}\n\n/**\n * Quick search – find and open pages, files and people from anywhere. A modal with\n * React Aria Autocomplete: focus stays in the field while ↑ ↓ move through the suggestions, Enter opens the\n * highlighted hit, Esc closes and focus returns to the trigger. Desktop: overlay 640 wide · mobile: full screen with Cancel.\n */\nexport function QuickSearch<T extends object>({\n isOpen,\n defaultOpen,\n onOpenChange,\n shortcut = true,\n inputValue,\n onInputChange,\n clientFilter = false,\n children,\n items,\n onAction,\n allResultsHref,\n onSearch,\n 'aria-label': ariaLabelProp,\n placeholder: placeholderProp,\n cancelLabel: cancelLabelProp,\n suggestionsLabel: suggestionsLabelProp,\n allResultsLabel: allResultsLabelProp,\n noResultsLabel: noResultsLabelProp,\n searchAllLabel: searchAllLabelProp,\n hints: hintsProp,\n}: QuickSearchProps<T>) {\n const m = useMessages();\n const ariaLabel = ariaLabelProp ?? m.common.search;\n const placeholder = placeholderProp ?? m.quickSearch.placeholder;\n const cancelLabel = cancelLabelProp ?? m.common.cancel;\n const suggestionsLabel = suggestionsLabelProp ?? m.quickSearch.suggestions;\n const allResultsLabel = allResultsLabelProp ?? m.quickSearch.allResults;\n const noResultsLabel = noResultsLabelProp ?? m.quickSearch.noResults;\n const searchAllLabel = searchAllLabelProp ?? m.quickSearch.searchAll;\n const hints = hintsProp ?? { navigate: m.quickSearch.navigate, open: m.quickSearch.open, close: m.common.close };\n const mobile = useMediaQuery(MOBILE_QUERY);\n const [innerOpen, setInnerOpen] = useState(defaultOpen ?? false);\n const open = isOpen ?? innerOpen;\n const setOpen = (value: boolean) => {\n if (isOpen === undefined) setInnerOpen(value);\n onOpenChange?.(value);\n };\n const [innerQuery, setInnerQuery] = useState('');\n const query = inputValue ?? innerQuery;\n const setQuery = (value: string) => {\n if (inputValue === undefined) setInnerQuery(value);\n onInputChange?.(value);\n };\n const { contains } = useFilter({ sensitivity: 'base' });\n\n // Cmd / Ctrl + K – not while typing in another field.\n useEffect(() => {\n if (!shortcut) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() !== 'k' || !(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey) return;\n const t = e.target as HTMLElement | null;\n if (t && (t.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName))) return;\n e.preventDefault();\n setOpen(true);\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n });\n\n const term = query.trim();\n const close = () => setOpen(false);\n // The list reports when nothing matches; “Search all content” then sits below it (a button may not live inside a listbox).\n const [empty, setEmpty] = useState(false);\n\n return (\n <ModalOverlay\n isOpen={open}\n onOpenChange={setOpen}\n isDismissable\n className={cx('medo-dialog-overlay', 'medo-quick-search-overlay', mobile && 'medo-quick-search-overlay--mobile')}\n >\n <Modal className={cx('medo-dialog', 'medo-quick-search', mobile && 'medo-quick-search--mobile')}>\n <Dialog aria-label={ariaLabel} className=\"medo-quick-search__dialog\">\n <Autocomplete inputValue={query} onInputChange={setQuery} filter={clientFilter ? contains : undefined}>\n <div className=\"medo-quick-search__bar\">\n <SearchField\n aria-label={ariaLabel}\n placeholder={placeholder}\n size=\"lg\"\n autoFocus\n onSubmit={(value) => value.trim() && onSearch?.(value.trim())}\n // Esc in an empty field closes the dialog; with text it clears first.\n className=\"medo-quick-search__field\"\n />\n {mobile && (\n <Button variant=\"text\" size=\"lg\" onPress={close}>\n {cancelLabel}\n </Button>\n )}\n </div>\n {/* Scroll region: focusable, so keyboard users can scroll it too (the options use virtual focus). */}\n <div className=\"medo-quick-search__scroll\" tabIndex={0} aria-label={suggestionsLabel} role=\"region\">\n <OptionHighlightContext.Provider value={term}>\n <ListBox<T>\n aria-label={ariaLabel}\n size={mobile ? 'lg' : 'md'}\n items={items}\n onAction={(key) => {\n onAction?.(key);\n close();\n }}\n className=\"medo-quick-search__list\"\n renderEmptyState={() => (term ? <EmptyReporter onChange={setEmpty} message={noResultsLabel(term)} /> : null)}\n >\n {children}\n </ListBox>\n </OptionHighlightContext.Provider>\n {empty && term && onSearch && (\n <AriaButton className=\"medo-quick-search__all\" onPress={() => onSearch(term)}>\n <Search aria-hidden=\"true\" />\n {searchAllLabel(term)}\n </AriaButton>\n )}\n </div>\n </Autocomplete>\n {!mobile && (\n <div className=\"medo-quick-search__footer\">\n <span className=\"medo-quick-search__hint\" aria-hidden=\"true\">\n <Badge size=\"sm\">↑ ↓</Badge>\n {hints.navigate}\n </span>\n <span className=\"medo-quick-search__hint\" aria-hidden=\"true\">\n <Badge size=\"sm\">Enter</Badge>\n {hints.open}\n </span>\n <span className=\"medo-quick-search__hint\" aria-hidden=\"true\">\n <Badge size=\"sm\">Esc</Badge>\n {hints.close}\n </span>\n {term && !empty && allResultsHref && (\n <Link variant=\"standalone\" size=\"md\" arrow href={allResultsHref(term)} className=\"medo-quick-search__all-results\" onPress={close}>\n {allResultsLabel(term)}\n </Link>\n )}\n </div>\n )}\n </Dialog>\n </Modal>\n </ModalOverlay>\n );\n}\n\n/** Renders the “no results” message and tells QuickSearch that the list is empty. */\nfunction EmptyReporter({ message, onChange }: { message: string; onChange: (empty: boolean) => void }) {\n useLayoutEffect(() => {\n onChange(true);\n return () => onChange(false);\n }, [onChange]);\n return (\n <p role=\"status\" className=\"medo-quick-search__message\">\n {message}\n </p>\n );\n}\n","import { useLayoutEffect, useRef, useState } from 'react';\nimport { Breadcrumb, Breadcrumbs as AriaBreadcrumbs, Button as AriaButton, Link as AriaLink } from 'react-aria-components';\nimport { ChevronLeft, ChevronRight, Ellipsis, Folder, House } from 'lucide-react';\nimport { Menu, MenuItem, MenuTrigger } from '../menu/Menu';\nimport { Tooltip, TooltipLink, TooltipTrigger } from '../tooltip/Tooltip';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface BreadcrumbItem {\n /** The page name – the same words as its title. */\n label: string;\n /** Link to the page. The last item is the current page and needs none. */\n href?: string;\n}\n\nexport interface BreadcrumbsProps {\n /** The path from the top: first the start page, last the current page (not a link). */\n items: BreadcrumbItem[];\n /** sm: dense apps (caption, 24) · md: websites (body/sm, 28). */\n size?: 'sm' | 'md';\n /** The first item shows a house icon; its label stays the accessible name (“Home”). */\n homeIcon?: boolean;\n /** auto: full path, below 640 px only a link to the parent page · full · back. From 5 levels the middle collapses into “…”. */\n layout?: 'auto' | 'full' | 'back';\n /** Texts (localize). */\n 'aria-label'?: string;\n moreLabel?: (count: number) => string;\n className?: string;\n}\n\n/**\n * Breadcrumbs – where a page sits in the hierarchy, with links to the levels above.\n * Built on React Aria Breadcrumbs: a navigation region with an ordered list, the current page last with\n * aria-current=\"page\". Not on the start page; place it above the page title.\n */\nexport function Breadcrumbs({\n items,\n size = 'md',\n homeIcon = true,\n layout = 'auto',\n 'aria-label': ariaLabelProp,\n moreLabel: moreLabelProp,\n className,\n}: BreadcrumbsProps) {\n const m = useMessages();\n const ariaLabel = ariaLabelProp ?? m.breadcrumbs.label;\n const moreLabel = moreLabelProp ?? m.breadcrumbs.more;\n const mobile = useMediaQuery(MOBILE_QUERY);\n const back = layout === 'back' || (layout === 'auto' && mobile);\n\n // A single level needs no breadcrumbs.\n if (items.length < 2) return null;\n\n if (back) {\n const parent = items[items.length - 2];\n return (\n <nav aria-label={ariaLabel} className={cx('medo-breadcrumbs', `medo-breadcrumbs--${size}`, 'medo-breadcrumbs--back', className)}>\n <AriaLink href={parent.href} className=\"medo-breadcrumbs__link medo-breadcrumbs__back\">\n <ChevronLeft className=\"medo-breadcrumbs__back-icon\" aria-hidden=\"true\" />\n <Label text={parent.label} />\n </AriaLink>\n </nav>\n );\n }\n\n // From 5 levels: start page, “…”, the last two levels and the current page.\n const collapse = items.length >= 5;\n const hidden = collapse ? items.slice(1, -3) : [];\n const shown = collapse ? [items[0], null, ...items.slice(-3)] : items;\n const last = shown.length - 1;\n\n return (\n <nav aria-label={ariaLabel} className={cx('medo-breadcrumbs', `medo-breadcrumbs--${size}`, className)}>\n <AriaBreadcrumbs className=\"medo-breadcrumbs__list\">\n {shown.map((item, i) => {\n const separator = i < last && <ChevronRight className=\"medo-breadcrumbs__separator\" aria-hidden=\"true\" />;\n if (!item) {\n return (\n <Breadcrumb key=\"more\" id=\"more\" className=\"medo-breadcrumbs__item\">\n <MenuTrigger>\n <AriaButton aria-label={moreLabel(hidden.length)} className=\"medo-breadcrumbs__icon-part\">\n <Ellipsis aria-hidden=\"true\" />\n </AriaButton>\n <Menu>\n {hidden.map((h) => (\n <MenuItem key={h.label} id={h.label} href={h.href} icon={<Folder />}>\n {h.label}\n </MenuItem>\n ))}\n </Menu>\n </MenuTrigger>\n {separator}\n </Breadcrumb>\n );\n }\n const isHome = homeIcon && i === 0;\n return (\n <Breadcrumb key={`${i}-${item.label}`} id={`${i}-${item.label}`} className=\"medo-breadcrumbs__item\">\n {isHome ? (\n <AriaLink href={item.href} aria-label={item.label} className=\"medo-breadcrumbs__icon-part\">\n <House aria-hidden=\"true\" />\n </AriaLink>\n ) : i === last ? (\n // The current page: not a link (React Aria sets aria-current=\"page\").\n <AriaLink className=\"medo-breadcrumbs__link medo-breadcrumbs__current\">\n <Label text={item.label} />\n </AriaLink>\n ) : (\n <TruncatedLink href={item.href} label={item.label} />\n )}\n {separator}\n </Breadcrumb>\n );\n })}\n </AriaBreadcrumbs>\n </nav>\n );\n}\n\nfunction Label({ text }: { text: string }) {\n return <span className=\"medo-breadcrumbs__label\">{text}</span>;\n}\n\n/** A link whose label is cut at 200 px shows the full name in a Tooltip on hover and focus. */\nfunction TruncatedLink({ href, label }: { href?: string; label: string }) {\n const ref = useRef<HTMLSpanElement>(null);\n const [cut, setCut] = useState(false);\n useLayoutEffect(() => {\n const el = ref.current;\n if (el) setCut(el.scrollWidth > el.clientWidth);\n }, [label]);\n const text = (\n <span ref={ref} className=\"medo-breadcrumbs__label\">\n {label}\n </span>\n );\n if (!cut) {\n return (\n <AriaLink href={href} className=\"medo-breadcrumbs__link\">\n {text}\n </AriaLink>\n );\n }\n return (\n <TooltipTrigger>\n <TooltipLink href={href} className=\"medo-breadcrumbs__link\">\n {text}\n </TooltipLink>\n <Tooltip>{label}</Tooltip>\n </TooltipTrigger>\n );\n}\n","import { Children, createContext, isValidElement, useContext, useEffect, useId, useState, type ReactElement, type ReactNode } from 'react';\nimport { Button as AriaButton, Disclosure, DisclosureGroup, DisclosurePanel, Heading, type DisclosureGroupProps, type Key } from 'react-aria-components';\nimport { ChevronDown } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\ntype AccordionSize = 'md' | 'lg';\n\nconst AccordionContext = createContext<{ size: AccordionSize; headingLevel: 2 | 3 | 4 }>({ size: 'md', headingLevel: 3 });\n\nexport interface AccordionProps extends Omit<DisclosureGroupProps, 'className' | 'style' | 'children'> {\n /** md: apps and settings · lg: websites and FAQs. */\n size?: AccordionSize;\n /** Heading level of the item titles (h2–h4), matching the page outline. */\n headingLevel?: 2 | 3 | 4;\n /** Several sections open at once (default). false: one at a time – only for short, mutually exclusive steps. */\n allowsMultipleExpanded?: boolean;\n /** “Expand all” / “Collapse all” above groups with more than 6 sections (multiple only). */\n expandAll?: boolean;\n expandAllLabel?: string;\n collapseAllLabel?: string;\n /** AccordionItems. */\n children: ReactNode;\n className?: string;\n}\n\nconst hashId = () => (typeof window === 'undefined' ? '' : decodeURIComponent(window.location.hash.slice(1)));\n\n/**\n * Accordion – sections that open and close in place. Built on React Aria DisclosureGroup:\n * each header is a button inside a real heading (aria-expanded, aria-controls); closed panels stay findable by\n * the browser search (hidden=\"until-found\"). Several open by default. A link to an item's id (#billing) opens it.\n */\nexport function Accordion({\n size = 'md',\n headingLevel = 3,\n allowsMultipleExpanded = true,\n expandAll = true,\n expandAllLabel,\n collapseAllLabel,\n expandedKeys: expandedProp,\n defaultExpandedKeys,\n onExpandedChange,\n children,\n className,\n ...props\n}: AccordionProps) {\n const m = useMessages();\n const ids = Children.toArray(children)\n .filter((c): c is ReactElement<AccordionItemProps> => isValidElement(c))\n .filter((c) => !c.props.isDisabled)\n .map((c) => c.props.id);\n const [inner, setInner] = useState<Set<Key>>(() => {\n const start = new Set<Key>(defaultExpandedKeys ?? []);\n const hash = hashId();\n if (ids.includes(hash)) start.add(hash);\n return start;\n });\n const expanded = expandedProp ? new Set(expandedProp) : inner;\n const setExpanded = (keys: Set<Key>) => {\n if (!expandedProp) setInner(keys);\n onExpandedChange?.(keys);\n };\n\n // Deep link: a link to #id opens that section and scrolls to it – on load and on every hash change.\n useEffect(() => {\n const open = () => {\n const hash = hashId();\n if (!ids.includes(hash)) return;\n setExpanded(new Set(allowsMultipleExpanded ? [...expanded, hash] : [hash]));\n requestAnimationFrame(() => document.getElementById(hash)?.scrollIntoView({ block: 'start' }));\n };\n if (hashId()) requestAnimationFrame(() => document.getElementById(hashId())?.scrollIntoView({ block: 'start' }));\n window.addEventListener('hashchange', open);\n return () => window.removeEventListener('hashchange', open);\n });\n\n const allOpen = ids.length > 0 && ids.every((id) => expanded.has(id));\n const showToggle = expandAll && allowsMultipleExpanded && Children.count(children) > 6;\n\n return (\n <AccordionContext.Provider value={{ size, headingLevel }}>\n <div className={cx('medo-accordion-wrap', className)}>\n {showToggle && (\n <div className=\"medo-accordion__toolbar\">\n <Button variant=\"text\" size=\"sm\" onPress={() => setExpanded(allOpen ? new Set() : new Set(ids))}>\n {allOpen ? (collapseAllLabel ?? m.accordion.collapseAll) : (expandAllLabel ?? m.accordion.expandAll)}\n </Button>\n </div>\n )}\n <DisclosureGroup\n {...props}\n allowsMultipleExpanded={allowsMultipleExpanded}\n expandedKeys={expanded}\n onExpandedChange={setExpanded}\n className={cx('medo-accordion', `medo-accordion--${size}`)}\n >\n {children}\n </DisclosureGroup>\n </div>\n </AccordionContext.Provider>\n );\n}\n\nexport interface AccordionItemProps {\n /** Required: key in expandedKeys and the anchor for links (#billing). */\n id: string;\n /** Short and scannable: nouns for settings, real questions for FAQs. */\n title: ReactNode;\n /** Second line in the header. Announced as the button's description. */\n description?: ReactNode;\n /** Decorative icon before the title (20 md / 24 lg). */\n icon?: ReactNode;\n /** Badge sm – part of the button name (“Billing, Payment failed”). */\n badge?: ReactNode;\n isDisabled?: boolean;\n /** Panel content – text, a form or a list. No accordion inside. */\n children: ReactNode;\n}\n\n/** One section of an Accordion: a header button inside a heading and its panel. */\nexport function AccordionItem({ id, title, description, icon, badge, isDisabled, children }: AccordionItemProps) {\n const { headingLevel } = useContext(AccordionContext);\n const descId = useId();\n return (\n <Disclosure id={id} isDisabled={isDisabled} className={cx('medo-accordion__item', !!icon && 'medo-accordion__item--icon')}>\n <Heading level={headingLevel} id={id} className=\"medo-accordion__heading\">\n <AriaButton slot=\"trigger\" className=\"medo-accordion__trigger\" aria-describedby={description ? descId : undefined}>\n {icon && (\n <span className=\"medo-accordion__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span className=\"medo-accordion__text\">\n <span className=\"medo-accordion__title\">{title}</span>\n {description && (\n // Read as description, not as part of the name.\n <span id={descId} className=\"medo-accordion__description\" aria-hidden=\"true\">\n {description}\n </span>\n )}\n </span>\n {badge && <span className=\"medo-accordion__badge\">{badge}</span>}\n <ChevronDown className=\"medo-accordion__chevron\" aria-hidden=\"true\" />\n </AriaButton>\n </Heading>\n <DisclosurePanel className=\"medo-accordion__panel\">\n <div className=\"medo-accordion__content\">{children}</div>\n </DisclosurePanel>\n </Disclosure>\n );\n}\n","import { useMemo, type ReactNode } from 'react';\nimport { Label, Slider as AriaSlider, SliderOutput, SliderThumb, SliderTrack, useLocale, type SliderProps as AriaSliderProps } from 'react-aria-components';\nimport { NumberField } from '../number-field/NumberField';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\ntype Value = number | number[];\n\nexport interface SliderProps<T extends Value = number> extends Omit<AriaSliderProps<T>, 'children' | 'className' | 'style'> {\n /** Visible label. Without it set `aria-label`. */\n label?: ReactNode;\n /** Range: a name per thumb (“Minimum price”, “Maximum price”). Default: “Minimum” / “Maximum” + label. */\n thumbLabels?: [string, string];\n /** Tick marks for few fixed steps (≤ 10) – the thumb snaps to them. */\n showTicks?: boolean;\n /** Min and max below the track, when the range is not obvious from the label. */\n showMinMax?: boolean;\n /** The value label above the track (always visible by default). */\n showValue?: boolean;\n className?: string;\n}\n\n/**\n * Slider – pick an approximate value or a range by dragging. Built on React Aria Slider:\n * arrow keys (step), Page Up/Down (10 %), Home/End, a click on the track moves the nearest thumb; range thumbs\n * never cross. The value is always shown next to the label and read out in the same format (`formatOptions`).\n * While dragging, a tooltip repeats it above the thumb. For exact values use SliderField.\n */\nexport function Slider<T extends Value = number>({\n label,\n thumbLabels,\n showTicks,\n showMinMax,\n showValue = true,\n minValue = 0,\n maxValue = 100,\n step = 1,\n formatOptions,\n className,\n ...props\n}: SliderProps<T>) {\n const m = useMessages();\n const { locale } = useLocale();\n const format = useMemo(() => new Intl.NumberFormat(locale, formatOptions), [locale, formatOptions]);\n const steps = Math.round((maxValue - minValue) / step);\n const labelText = typeof label === 'string' ? label : (props['aria-label'] ?? '');\n\n return (\n <AriaSlider<T> {...props} minValue={minValue} maxValue={maxValue} step={step} formatOptions={formatOptions} className={cx('medo-slider', className)}>\n {({ state }) => {\n const range = state.values.length > 1;\n const start = range ? state.getThumbPercent(0) : 0;\n const end = state.getThumbPercent(state.values.length - 1);\n return (\n <>\n {(label || showValue) && (\n <div className=\"medo-slider__header\">\n {label && (\n <Label className=\"medo-slider__label\" aria-disabled={props.isDisabled || undefined}>\n {label}\n </Label>\n )}\n {showValue && <SliderOutput className=\"medo-slider__value\" aria-disabled={props.isDisabled || undefined} />}\n </div>\n )}\n <SliderTrack className=\"medo-slider__track\">\n <span className=\"medo-slider__rail\" aria-hidden=\"true\" />\n {showTicks && steps <= 10 && (\n <span className=\"medo-slider__ticks\" aria-hidden=\"true\">\n {Array.from({ length: steps + 1 }, (_, i) => (\n <span key={i} className=\"medo-slider__tick\" style={{ insetInlineStart: `${(i / steps) * 100}%` }} />\n ))}\n </span>\n )}\n <span className=\"medo-slider__fill\" style={{ insetInlineStart: `${start * 100}%`, inlineSize: `${(end - start) * 100}%` }} aria-hidden=\"true\" />\n {state.values.map((_, i) => (\n <SliderThumb\n key={i}\n index={i}\n aria-label={range ? (thumbLabels?.[i] ?? (i === 0 ? m.slider.minimum(labelText) : m.slider.maximum(labelText))) : undefined}\n className=\"medo-slider__thumb\"\n >\n {({ isDragging }) =>\n // The finger covers the thumb: show the value above it while dragging.\n isDragging && (\n <span className=\"medo-tooltip medo-slider__bubble\" aria-hidden=\"true\">\n {state.getThumbValueLabel(i)}\n </span>\n )\n }\n </SliderThumb>\n ))}\n </SliderTrack>\n {showMinMax && (\n <div className=\"medo-slider__limits\" aria-hidden=\"true\">\n <span>{format.format(minValue)}</span>\n <span>{format.format(maxValue)}</span>\n </div>\n )}\n </>\n );\n }}\n </AriaSlider>\n );\n}\n\nexport interface SliderFieldProps<T extends Value = number> extends Omit<SliderProps<T>, 'value' | 'defaultValue' | 'onChange' | 'showValue'> {\n value: T;\n onChange: (value: T) => void;\n /** Accessible names of the number inputs. Default: the label (single) or the thumb labels (range). */\n inputLabels?: [string, string];\n}\n\n/**\n * Slider field – a Slider plus number inputs for exact values. Single: input on the\n * right (88). Range: two inputs below (min – max). Slider and inputs stay in sync; the inputs clamp on blur.\n */\nexport function SliderField<T extends Value = number>({ value, onChange, inputLabels, ...props }: SliderFieldProps<T>) {\n const m = useMessages();\n const { minValue = 0, maxValue = 100, step = 1, formatOptions, isDisabled, label, thumbLabels } = props;\n const labelText = typeof label === 'string' ? label : (props['aria-label'] ?? '');\n const field = { step, formatOptions, isDisabled, size: 'md' as const };\n\n if (Array.isArray(value)) {\n const [lo, hi] = value as number[];\n const names = inputLabels ?? thumbLabels ?? [m.slider.minimum(labelText), m.slider.maximum(labelText)];\n return (\n <div className=\"medo-slider-field medo-slider-field--range\">\n <Slider<T> {...props} value={value} onChange={onChange} />\n <div className=\"medo-slider-field__inputs\">\n <NumberField {...field} aria-label={names[0]} minValue={minValue} maxValue={hi} value={lo} onChange={(v) => !Number.isNaN(v) && onChange([v, hi] as T)} />\n <span className=\"medo-slider-field__dash\" aria-hidden=\"true\">\n –\n </span>\n <NumberField {...field} aria-label={names[1]} minValue={lo} maxValue={maxValue} value={hi} onChange={(v) => !Number.isNaN(v) && onChange([lo, v] as T)} />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"medo-slider-field medo-slider-field--single\">\n <Slider<T> {...props} value={value} onChange={onChange} showValue={false} />\n <NumberField\n {...field}\n aria-label={inputLabels?.[0] ?? labelText}\n minValue={minValue}\n maxValue={maxValue}\n value={value as number}\n onChange={(v) => !Number.isNaN(v) && onChange(v as T)}\n className=\"medo-slider-field__input\"\n />\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport { Input as AriaInput, NumberField as AriaNumberField, type NumberFieldProps as AriaNumberFieldProps } from 'react-aria-components';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport type { InputSize } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\n\nexport interface NumberFieldProps extends Omit<AriaNumberFieldProps, 'children' | 'className' | 'style'> {\n /** Visible label. Without it set `aria-label` – only where the context names the field (e.g. next to a Slider). */\n label?: ReactNode;\n description?: ReactNode;\n errorMessage?: ReactNode;\n placeholder?: string;\n /** sm 32 · md 40 · lg 48 px. lg on mobile and touch. */\n size?: InputSize;\n className?: string;\n}\n\n/**\n * Number field – a number with format and limits. Built on React Aria\n * NumberField: formats with Intl (`formatOptions`: currency, percent, unit), clamps to min/max and rounds to the\n * step when the field is left, ↑ ↓ change by one step. Tabular figures.\n */\nexport function NumberField({ label, description, errorMessage, placeholder, size = 'md', className, ...props }: NumberFieldProps) {\n return (\n <AriaNumberField {...props} className={cx('medo-field', 'medo-number-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <div className={cx('medo-input', `medo-input--${size}`)}>\n <AriaInput className=\"medo-input__control medo-number-field__control\" placeholder={placeholder} />\n </div>\n {(description || errorMessage) && <FieldFooter description={description} errorMessage={errorMessage} />}\n </AriaNumberField>\n );\n}\n","import type { HTMLAttributes, ReactNode } from 'react';\nimport { CircleAlert, CircleCheck, Info, TriangleAlert, X } from 'lucide-react';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'danger';\n\nconst ICONS: Record<AlertTone, typeof Info> = {\n info: Info,\n success: CircleCheck,\n warning: TriangleAlert,\n danger: CircleAlert,\n};\n\nexport interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** danger: failed or blocks · warning: risk ahead · success: done · info: good to know. */\n tone?: AlertTone;\n /** inline: in the content · banner: full width above the header, for app-wide states. */\n variant?: 'inline' | 'banner';\n /** Required. Says what happened (“Your trial ends in 3 days”). */\n title: ReactNode;\n /** What to do next. */\n children?: ReactNode;\n /** Max two text buttons (Button variant=\"text\" size=\"sm\"), the main one first. */\n actions?: ReactNode;\n /** Shows the close button. Only when it is safe to hide the message. */\n onDismiss?: () => void;\n dismissLabel?: string;\n /**\n * Set when the alert appears after the page has loaded: danger and warning are announced\n * immediately (role=\"alert\"), info and success politely (role=\"status\").\n */\n announce?: boolean;\n}\n\n/** Alert – persistent message inside the page. Plain markup, no library needed. */\nexport function Alert({\n tone = 'info',\n variant = 'inline',\n title,\n children,\n actions,\n onDismiss,\n dismissLabel,\n announce,\n className,\n ...props\n}: AlertProps) {\n const m = useMessages();\n const Icon = ICONS[tone];\n const role = announce ? (tone === 'danger' || tone === 'warning' ? 'alert' : 'status') : undefined;\n return (\n <div {...props} role={role ?? props.role} className={cx('medo-alert', `medo-alert--${tone}`, variant === 'banner' && 'medo-alert--banner', className)}>\n <Icon className=\"medo-alert__icon\" aria-hidden=\"true\" />\n <div className=\"medo-alert__content\">\n <p className=\"medo-alert__title\">{title}</p>\n {children && <div className=\"medo-alert__description\">{children}</div>}\n {actions && <div className=\"medo-alert__actions\">{actions}</div>}\n </div>\n {onDismiss && (\n <IconButton className=\"medo-alert__close\" variant=\"ghost\" size=\"sm\" icon={<X />} aria-label={dismissLabel ?? m.alert.dismiss} onPress={onDismiss} />\n )}\n </div>\n );\n}\n","import type { CSSProperties, ElementType, ReactNode } from 'react';\nimport { Link as AriaLink, type LinkProps as AriaLinkProps } from 'react-aria-components';\nimport { cx } from '../utils/cx';\n\nexport interface CardProps {\n /** Required: every card has a heading, so it can be scanned and announced. */\n title: ReactNode;\n subtitle?: ReactNode;\n /** Heading level of the title. Match the page outline (default h3). */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** outlined (default) · elevated (needs attention, draggable) · filled (inside white areas) · brand (one per view) · plain (editorial). */\n variant?: 'outlined' | 'elevated' | 'filled' | 'brand' | 'plain';\n /** standard 24 px · compact 16 px (dense layouts and mobile). */\n density?: 'standard' | 'compact';\n /** vertical (media on top, 16:9) · horizontal (media 180 px left, for lists). */\n layout?: 'vertical' | 'horizontal';\n /** Image or video. Decorative images use alt=\"\". */\n media?: ReactNode;\n /** Actions for the whole card, next to the title (ButtonGroup context=\"header\"). */\n headerActions?: ReactNode;\n /** Actions that finish a task in the card (ButtonGroup context=\"footer\"). */\n footer?: ReactNode;\n /** Makes the whole card open something: the title becomes one link stretched over the card. */\n href?: AriaLinkProps['href'];\n /** Link props such as target or routerOptions. */\n linkProps?: Omit<AriaLinkProps, 'href' | 'children' | 'className'>;\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\n/** Card – a container for one topic. Rendered as an article with a heading. */\nexport function Card({\n title,\n subtitle,\n headingLevel = 3,\n variant = 'outlined',\n density = 'standard',\n layout = 'vertical',\n media,\n headerActions,\n footer,\n href,\n linkProps,\n children,\n className,\n style,\n}: CardProps) {\n const Heading = `h${headingLevel}` as ElementType;\n const interactive = href !== undefined;\n return (\n <article\n className={cx(\n 'medo-card',\n `medo-card--${variant}`,\n density === 'compact' && 'medo-card--compact',\n layout === 'horizontal' && 'medo-card--horizontal',\n interactive && 'medo-card--interactive',\n className,\n )}\n style={style}\n >\n {media && <div className=\"medo-card__media\">{media}</div>}\n <div className=\"medo-card__main\">\n <div className=\"medo-card__header\">\n <div className=\"medo-card__heading\">\n <Heading className=\"medo-card__title\">\n {interactive ? (\n <AriaLink {...linkProps} href={href} className=\"medo-card__link\">\n {title}\n </AriaLink>\n ) : (\n title\n )}\n </Heading>\n {subtitle && <p className=\"medo-card__subtitle\">{subtitle}</p>}\n </div>\n {headerActions && <div className=\"medo-card__header-actions\">{headerActions}</div>}\n </div>\n {children && <div className=\"medo-card__body\">{children}</div>}\n {footer && <div className=\"medo-card__footer\">{footer}</div>}\n </div>\n </article>\n );\n}\n","import { useEffect, useId, useRef, useState, type CSSProperties, type ReactNode } from 'react';\nimport {\n Cell as AriaCell,\n Checkbox as AriaCheckbox,\n Collection,\n Column as AriaColumn,\n Row as AriaRow,\n Table as AriaTable,\n TableBody as AriaTableBody,\n TableHeader as AriaTableHeader,\n useTableOptions,\n type CellProps as AriaCellProps,\n type ColumnProps as AriaColumnProps,\n type RowProps as AriaRowProps,\n type TableBodyProps as AriaTableBodyProps,\n type TableHeaderProps as AriaTableHeaderProps,\n type TableProps as AriaTableProps,\n} from 'react-aria-components';\nimport { ArrowDown, ArrowUp, ArrowUpDown, Check, Minus } from 'lucide-react';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\ntype Density = 'standard' | 'compact';\n\n/* ---------- Static table: a native <table> ---------- */\n\nexport interface StaticTableProps {\n /** thead / tbody / tr / th / td as usual. Use <th scope=\"row\"> for row headers. */\n children: ReactNode;\n /** Visible caption or, with captionHidden, a name for screen readers. */\n caption?: ReactNode;\n captionHidden?: boolean;\n density?: Density;\n striped?: boolean;\n /** Without the border and radius, e.g. inside a card or documentation. */\n plain?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * True while the element is wider inside than outside, i.e. it scrolls sideways.\n * Scrolling content must be reachable by keyboard (WCAG 2.1.1), so the container then becomes a focusable region.\n */\nfunction useScrollsSideways<T extends HTMLElement>() {\n const ref = useRef<T>(null);\n const [scrolls, setScrolls] = useState(false);\n useEffect(() => {\n const el = ref.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const check = () => setScrolls(el.scrollWidth > el.clientWidth + 1);\n const observer = new ResizeObserver(check);\n observer.observe(el);\n if (el.firstElementChild) observer.observe(el.firstElementChild);\n check();\n return () => observer.disconnect();\n }, []);\n return [ref, scrolls] as const;\n}\n\n/**\n * Static table – a native, non-interactive table with the Table look.\n * For content and simple data. Numbers: add className=\"medo-table__cell--number\".\n * When it is wider than its container it scrolls sideways; the container then takes the keyboard focus\n * (arrow keys scroll) and is announced as a region named by the caption.\n */\nexport function StaticTable({ children, caption, captionHidden, density = 'standard', striped, plain, className, style }: StaticTableProps) {\n const [ref, scrolls] = useScrollsSideways<HTMLDivElement>();\n const captionId = useId();\n const m = useMessages();\n const region = scrolls\n ? caption\n ? { role: 'region', tabIndex: 0, 'aria-labelledby': captionId }\n : { role: 'region', tabIndex: 0, 'aria-label': m.table.scrollRegion }\n : {};\n return (\n <div ref={ref} {...region} className={cx('medo-table-container', plain && 'medo-table-container--plain', className)} style={style}>\n <table className={cx('medo-table', density === 'compact' && 'medo-table--compact', striped && 'medo-table--striped')}>\n {caption && (\n <caption id={captionId} className={captionHidden ? 'medo-visually-hidden' : undefined}>\n {caption}\n </caption>\n )}\n {children}\n </table>\n </div>\n );\n}\n\n/* ---------- Interactive table: React Aria Table (grid) ---------- */\n\nexport interface TableProps extends Omit<AriaTableProps, 'className' | 'style'> {\n density?: Density;\n /** Bar above the header: search (Input sm 240), filter, ColumnsMenu, primary action on the right (Buttons sm). */\n toolbar?: ReactNode;\n /** Bar below the rows, usually Pagination. */\n footer?: ReactNode;\n striped?: boolean;\n plain?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Table – interactive data table. Built on React Aria Table:\n * arrow keys move between cells, Space selects, Enter opens, sortable headers announce the order.\n * Data logic (sorting, filtering, paging) stays in your code or a headless table library.\n */\nexport function Table({ density = 'standard', striped, plain, toolbar, footer, className, style, ...props }: TableProps) {\n const table = <AriaTable {...props} className={cx('medo-table', density === 'compact' && 'medo-table--compact', striped && 'medo-table--striped')} />;\n if (!toolbar && !footer) {\n return (\n <div className={cx('medo-table-container', plain && 'medo-table-container--plain', className)} style={style}>\n {table}\n </div>\n );\n }\n // Toolbar – rows – footer in one bordered surface; only the table scrolls.\n return (\n <div className={cx('medo-table-frame', plain && 'medo-table-frame--plain', className)} style={style}>\n {toolbar && <div className=\"medo-table__toolbar\">{toolbar}</div>}\n <div className=\"medo-table-container medo-table-container--plain\">{table}</div>\n {footer && <div className=\"medo-table__footer\">{footer}</div>}\n </div>\n );\n}\n\n/** Checkbox for row selection (slot=\"selection\"), styled like Checkbox md. */\nfunction SelectionCheckbox() {\n return (\n <AriaCheckbox slot=\"selection\" className=\"medo-choice medo-checkbox medo-choice--md medo-choice__button\">\n {({ isSelected, isIndeterminate }) => (\n <span className=\"medo-choice__control\" aria-hidden=\"true\">\n {isIndeterminate ? <Minus /> : isSelected ? <Check /> : null}\n </span>\n )}\n </AriaCheckbox>\n );\n}\n\nexport function TableHeader<T extends object>({ columns, children, ...props }: Omit<AriaTableHeaderProps<T>, 'className'>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions();\n return (\n <AriaTableHeader {...props} className=\"medo-table__header\">\n {allowsDragging && <AriaColumn className=\"medo-table__column medo-table__column--utility\" />}\n {selectionBehavior === 'toggle' && selectionMode !== 'none' && (\n <AriaColumn className=\"medo-table__column medo-table__column--utility\">{selectionMode === 'multiple' && <SelectionCheckbox />}</AriaColumn>\n )}\n <Collection items={columns}>{children}</Collection>\n </AriaTableHeader>\n );\n}\n\nexport interface ColumnProps extends Omit<AriaColumnProps, 'className' | 'children'> {\n children: ReactNode;\n /** end: numbers, amounts, dates – right-aligned with tabular figures. */\n align?: 'start' | 'end';\n}\n\n/** Header cell. With allowsSorting it is a button: ascending → descending → ascending. */\nexport function Column({ children, align = 'start', ...props }: ColumnProps) {\n return (\n <AriaColumn {...props} data-align={align} className=\"medo-table__column\">\n {({ allowsSorting, sortDirection }) => (\n <span className=\"medo-table__column-inner\">\n {children}\n {allowsSorting &&\n (sortDirection === 'ascending' ? (\n <ArrowUp className=\"medo-table__sort\" aria-hidden=\"true\" />\n ) : sortDirection === 'descending' ? (\n <ArrowDown className=\"medo-table__sort\" aria-hidden=\"true\" />\n ) : (\n <ArrowUpDown className=\"medo-table__sort\" aria-hidden=\"true\" />\n ))}\n </span>\n )}\n </AriaColumn>\n );\n}\n\nexport function TableBody<T extends object>(props: Omit<AriaTableBodyProps<T>, 'className'>) {\n return <AriaTableBody {...props} className=\"medo-table__body\" />;\n}\n\nexport function Row<T extends object>({ id, columns, children, ...props }: Omit<AriaRowProps<T>, 'className'>) {\n const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions();\n return (\n <AriaRow id={id} {...props} className=\"medo-table__row\">\n {allowsDragging && <AriaCell className=\"medo-table__cell medo-table__cell--utility\" />}\n {selectionBehavior === 'toggle' && selectionMode !== 'none' && (\n <AriaCell className=\"medo-table__cell medo-table__cell--utility\">\n <SelectionCheckbox />\n </AriaCell>\n )}\n <Collection items={columns}>{children}</Collection>\n </AriaRow>\n );\n}\n\nexport interface CellProps extends Omit<AriaCellProps, 'className'> {\n align?: 'start' | 'end';\n}\n\nexport function Cell({ align = 'start', ...props }: CellProps) {\n return <AriaCell {...props} data-align={align} className=\"medo-table__cell\" />;\n}\n","import { Columns3 } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { Checkbox, CheckboxGroup } from '../checkbox/Checkbox';\nimport { Popover, PopoverTrigger } from '../popover/Popover';\nimport { useMessages } from '../i18n/I18n';\n\nexport interface ColumnOption {\n id: string;\n label: string;\n /** Can't be hidden: the first column (row header) and actions. */\n isLocked?: boolean;\n}\n\nexport interface ColumnsMenuProps {\n /** All columns that can be shown, in table order. */\n columns: ColumnOption[];\n /** Ids of the visible columns. */\n visibleColumns: string[];\n onVisibleColumnsChange: (ids: string[]) => void;\n /** Button label. */\n label?: string;\n /** Title of the list. */\n title?: string;\n}\n\n/**\n * Columns menu – shows or hides table columns. A ghost button sm in the\n * table toolbar opens a Popover sm with checkboxes; locked columns stay visible. Render only the visible columns.\n */\nexport function ColumnsMenu({ columns, visibleColumns, onVisibleColumnsChange, label: labelProp, title: titleProp }: ColumnsMenuProps) {\n const m = useMessages();\n const label = labelProp ?? m.table.columns;\n const title = titleProp ?? m.table.showColumns;\n const locked = columns.filter((c) => c.isLocked).map((c) => c.id);\n return (\n <PopoverTrigger>\n <Button variant=\"ghost\" size=\"sm\" startIcon={<Columns3 />}>\n {label}\n </Button>\n <Popover size=\"sm\" aria-label={title}>\n <CheckboxGroup\n label={title}\n value={visibleColumns}\n // Locked columns can't be unchecked; keep the table order.\n onChange={(ids) => onVisibleColumnsChange(columns.map((c) => c.id).filter((id) => ids.includes(id) || locked.includes(id)))}\n >\n {columns.map((c) => (\n <Checkbox key={c.id} value={c.id} isDisabled={c.isLocked}>\n {c.label}\n </Checkbox>\n ))}\n </CheckboxGroup>\n </Popover>\n </PopoverTrigger>\n );\n}\n","import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n DropZone,\n FileTrigger as AriaFileTrigger,\n Text,\n useLocale,\n type DropZoneProps as AriaDropZoneProps,\n type FileDropItem,\n} from 'react-aria-components';\nimport { CircleAlert, CircleCheck, CloudUpload, FileText, Image as ImageIcon, RotateCw, Trash2, Upload, X } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { IconTile } from '../empty-state/EmptyState';\nimport { ProgressBar } from '../progress/Progress';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { en, useMessages } from '../i18n/I18n';\n\n/* ---------- Helpers ---------- */\n\nconst units = ['byte', 'kilobyte', 'megabyte', 'gigabyte'] as const;\n\nfunction unitOf(bytes: number) {\n let i = 0;\n let value = bytes;\n while (value >= 1000 && i < units.length - 1) {\n value /= 1000;\n i++;\n }\n return { value, i, digits: i < 2 ? 0 : 1 };\n}\n\n/** “2.4 MB”, “860 kB” – decimal units like the operating systems' file dialogs. */\nexport function formatBytes(bytes: number, locale = 'en-US') {\n const { value, i, digits } = unitOf(bytes);\n return new Intl.NumberFormat(locale, { style: 'unit', unit: units[i], unitDisplay: 'short', maximumFractionDigits: digits }).format(value);\n}\n\n/** “1.6” when both values share the unit (“1.6 of 2.4 MB”), else the full size (“860 kB”). */\nfunction formatLoaded(loaded: number, total: number, locale: string) {\n const a = unitOf(loaded);\n if (a.i !== unitOf(total).i) return formatBytes(loaded, locale);\n return new Intl.NumberFormat(locale, { maximumFractionDigits: a.digits }).format(a.value);\n}\n\n/** Accept list as for <input accept>: “.pdf”, “image/*”, “application/pdf”. */\nfunction isAccepted(file: File, accepted?: string[]) {\n if (!accepted?.length) return true;\n const name = file.name.toLowerCase();\n const type = file.type.toLowerCase();\n return accepted.some((a) => {\n const rule = a.trim().toLowerCase();\n if (rule.startsWith('.')) return name.endsWith(rule);\n if (rule.endsWith('/*')) return type.startsWith(rule.slice(0, -1));\n return type === rule;\n });\n}\n\n/* ---------- File name (truncates in the middle) ---------- */\n\n/**\n * The start shrinks and gets the “…”, the last 12 characters (incl. extension) always stay visible.\n * No measuring: two spans and CSS. The full name is the accessible text and the hover title.\n */\nfunction FileName({ name, className }: { name: string; className?: string }) {\n const keep = 12;\n const start = name.length > keep + 4 ? name.slice(0, -keep) : name;\n const end = name.length > keep + 4 ? name.slice(-keep) : '';\n return (\n <span className={cx('medo-file-name', className)}>\n <span className=\"medo-visually-hidden\">{name}</span>\n <span className=\"medo-file-name__visual\" title={name} aria-hidden=\"true\">\n <span className=\"medo-file-name__start\">{start}</span>\n {end && <span className=\"medo-file-name__end\">{end}</span>}\n </span>\n </span>\n );\n}\n\n/* ---------- Types and texts ---------- */\n\nexport interface UploadFile {\n /** Stable id (e.g. crypto.randomUUID() when the file is added). */\n id: string;\n name: string;\n /** Size in bytes. */\n size: number;\n /** MIME type. image/* with a `previewUrl` shows a thumbnail, everything else a type icon. */\n type?: string;\n status: 'uploading' | 'done' | 'error';\n /** Uploaded bytes (ProgressEvent.loaded). Without it the bar is indeterminate. */\n loaded?: number;\n /** What happened and how to fix it (“Upload interrupted. Check your connection and retry.”). No error codes. */\n error?: string;\n /** Thumbnail (URL.createObjectURL(file) or the server URL). */\n previewUrl?: string;\n /** false hides “Retry” (e.g. the server rejected the file). Default true. */\n canRetry?: boolean;\n}\n\nexport interface UploadTexts {\n /** Dropzone and trigger. */\n title: string;\n dropTitle: string;\n chooseFiles: string;\n chooseFile: string;\n listLabel: string;\n /** File actions – always name the file. */\n cancel: (name: string) => string;\n remove: (name: string) => string;\n retry: (name: string) => string;\n retryShort: string;\n /** Name of the progress bar. */\n uploading: (name: string) => string;\n /** “1.6 of 2.4 MB · 64 %” */\n progress: (loaded: string, total: string, percent: number) => string;\n /** Validation. */\n typeNotAllowed: (names: string, types: string) => string;\n tooLarge: (size: string, max: string) => string;\n tooMany: (max: number) => string;\n /** Polite announcements. */\n uploaded: (name: string) => string;\n failed: (name: string, error: string) => string;\n}\n\n/** English defaults. The components use the texts of the current language (see i18n). */\nexport const defaultUploadTexts: UploadTexts = en.upload;\n\ninterface ItemActions {\n onRemove: (id: string) => void;\n onCancel?: (id: string) => void;\n onRetry?: (id: string) => void;\n texts?: Partial<UploadTexts>;\n}\n\nconst isImage = (file: UploadFile) => !!file.previewUrl && (!file.type || file.type.startsWith('image/'));\nconst percentOf = (file: UploadFile) => (file.loaded != null && file.size > 0 ? Math.min(100, Math.round((file.loaded / file.size) * 100)) : undefined);\n\n/* ---------- File item (row) ---------- */\n\nexport interface FileItemProps extends ItemActions {\n file: UploadFile;\n className?: string;\n}\n\n/**\n * File item – one file in the upload list. Uploading: progress + cancel · Done: size +\n * remove · Error: the reason + retry + remove. Images show a 40 px thumbnail, other files a type icon.\n */\nexport function FileItem({ file, onRemove, onCancel, onRetry, texts: own, className }: FileItemProps) {\n const m = useMessages();\n const t = { ...m.upload, ...own };\n const { locale } = useLocale();\n const percent = percentOf(file);\n const size = formatBytes(file.size, locale);\n\n let meta: ReactNode;\n if (file.status === 'uploading') {\n meta = (\n <>\n <span className=\"medo-file-item__meta\">{percent != null ? t.progress(formatLoaded(file.loaded ?? 0, file.size, locale), size, percent) : size}</span>\n <ProgressBar\n size=\"sm\"\n showValue={false}\n aria-label={t.uploading(file.name)}\n value={percent}\n isIndeterminate={percent == null}\n className=\"medo-file-item__progress\"\n />\n </>\n );\n } else {\n const error = file.status === 'error';\n meta = (\n <span className={cx('medo-file-item__meta', error && 'medo-file-item__meta--error')}>\n {error ? <CircleAlert aria-hidden=\"true\" /> : <CircleCheck aria-hidden=\"true\" className=\"medo-file-item__done\" />}\n <span>{error ? file.error : size}</span>\n </span>\n );\n }\n\n return (\n <div className={cx('medo-file-item', `medo-file-item--${file.status}`, className)}>\n {isImage(file) ? (\n <img className=\"medo-file-item__thumb\" src={file.previewUrl} alt=\"\" />\n ) : (\n <span className=\"medo-file-item__icon\" aria-hidden=\"true\">\n {file.type?.startsWith('image/') ? <ImageIcon /> : <FileText />}\n </span>\n )}\n <div className=\"medo-file-item__content\">\n <FileName name={file.name} className=\"medo-file-item__name\" />\n {meta}\n </div>\n <div className=\"medo-file-item__actions\">\n {file.status === 'uploading' && <IconButton size=\"sm\" icon={<X />} aria-label={t.cancel(file.name)} onPress={() => (onCancel ?? onRemove)(file.id)} />}\n {file.status === 'error' && onRetry && file.canRetry !== false && (\n <IconButton size=\"sm\" icon={<RotateCw />} aria-label={t.retry(file.name)} onPress={() => onRetry(file.id)} />\n )}\n {file.status !== 'uploading' && (\n <IconButton size=\"sm\" icon={file.status === 'done' ? <Trash2 /> : <X />} aria-label={t.remove(file.name)} onPress={() => onRemove(file.id)} />\n )}\n </div>\n </div>\n );\n}\n\n/* ---------- File tile (grid, images) ---------- */\n\nexport interface FileTileProps extends ItemActions {\n file: UploadFile;\n className?: string;\n}\n\n/**\n * File tile – an image in the grid view. Uploading: dark overlay with % and bar ·\n * Done: remove top right · Error: danger border, the overlay retries, the caption names the problem.\n */\nexport function FileTile({ file, onRemove, onCancel, onRetry, texts: own, className }: FileTileProps) {\n const m = useMessages();\n const t = { ...m.upload, ...own };\n const percent = percentOf(file);\n const retry = file.status === 'error' && onRetry && file.canRetry !== false;\n\n return (\n <div className={cx('medo-file-tile', `medo-file-tile--${file.status}`, className)}>\n <div className=\"medo-file-tile__media\">\n {file.previewUrl ? (\n <img className=\"medo-file-tile__image\" src={file.previewUrl} alt=\"\" />\n ) : (\n <span className=\"medo-file-tile__placeholder\" aria-hidden=\"true\">\n <ImageIcon />\n </span>\n )}\n {file.status === 'uploading' && (\n <div className=\"medo-file-tile__overlay\">\n <span className=\"medo-file-tile__percent\" aria-hidden=\"true\">\n {percent != null ? `${percent} %` : ''}\n </span>\n <ProgressBar\n size=\"sm\"\n showValue={false}\n aria-label={t.uploading(file.name)}\n value={percent}\n isIndeterminate={percent == null}\n className=\"medo-file-tile__progress\"\n />\n </div>\n )}\n {file.status === 'error' &&\n (retry ? (\n <AriaButton className=\"medo-file-tile__overlay medo-file-tile__retry\" aria-label={t.retry(file.name)} onPress={() => onRetry(file.id)}>\n <CircleAlert aria-hidden=\"true\" />\n <span aria-hidden=\"true\">{t.retryShort}</span>\n </AriaButton>\n ) : (\n <div className=\"medo-file-tile__overlay\" aria-hidden=\"true\">\n <CircleAlert />\n </div>\n ))}\n <IconButton\n variant=\"media\"\n size=\"sm\"\n icon={<X />}\n aria-label={file.status === 'uploading' ? t.cancel(file.name) : t.remove(file.name)}\n onPress={() => (file.status === 'uploading' ? (onCancel ?? onRemove) : onRemove)(file.id)}\n className=\"medo-file-tile__remove\"\n />\n </div>\n {file.status === 'error' ? (\n <span className=\"medo-file-tile__caption medo-file-tile__caption--error\">\n <span className=\"medo-visually-hidden\">{file.name}: </span>\n {file.error}\n </span>\n ) : (\n <FileName name={file.name} className=\"medo-file-tile__caption\" />\n )}\n </div>\n );\n}\n\n/* ---------- Dropzone ---------- */\n\ninterface PickerProps {\n /** Accepted types as for <input accept>: [“.pdf”, “image/*”]. Checked again before upload. */\n acceptedFileTypes?: string[];\n /** Several files at once. Default true. */\n allowsMultiple?: boolean;\n /** Mobile: open the camera first (“environment” = back camera). */\n defaultCamera?: 'user' | 'environment';\n isDisabled?: boolean;\n /** Types, size and count – shown before the user picks a file. */\n hint?: ReactNode;\n /** Validation or required message. Never only by color. */\n errorMessage?: ReactNode;\n onSelect: (files: File[]) => void;\n texts?: Partial<UploadTexts>;\n className?: string;\n}\n\nexport interface DropzoneProps extends PickerProps {\n /** Ids of elements that also name the zone (the field label). */\n 'aria-labelledby'?: string;\n}\n\ntype DropEvent = Parameters<NonNullable<AriaDropZoneProps['onDrop']>>[0];\n\nasync function filesFrom(e: DropEvent) {\n const items = e.items.filter((i): i is FileDropItem => i.kind === 'file');\n return Promise.all(items.map((i) => i.getFile()));\n}\n\n/**\n * Dropzone – drag and drop files or choose them. Built on React Aria DropZone +\n * FileTrigger: the button always opens the system picker (drag and drop is only a shortcut, WCAG 2.5.7),\n * the zone is focusable for paste (Ctrl+V). Below 640 px use the FileTrigger instead.\n */\nexport function Dropzone({\n acceptedFileTypes,\n allowsMultiple = true,\n defaultCamera,\n isDisabled,\n hint,\n errorMessage,\n onSelect,\n texts: own,\n className,\n ...props\n}: DropzoneProps) {\n const m = useMessages();\n const t = { ...m.upload, ...own };\n const hintId = useId();\n const errorId = useId();\n return (\n <DropZone\n aria-labelledby={props['aria-labelledby']}\n isDisabled={isDisabled}\n onDrop={async (e) => onSelect(await filesFrom(e))}\n className={cx('medo-dropzone', !!errorMessage && 'medo-dropzone--invalid', className)}\n >\n {({ isDropTarget }) => (\n <>\n <IconTile size=\"md\">\n <CloudUpload />\n </IconTile>\n <Text slot=\"label\" className=\"medo-dropzone__title\" aria-disabled={isDisabled || undefined}>\n {isDropTarget ? t.dropTitle : t.title}\n </Text>\n <AriaFileTrigger\n acceptedFileTypes={acceptedFileTypes}\n allowsMultiple={allowsMultiple}\n defaultCamera={defaultCamera}\n onSelect={(list) => list && onSelect([...list])}\n >\n <Button\n variant=\"secondary\"\n size=\"sm\"\n isDisabled={isDisabled}\n className=\"medo-dropzone__button medo-upload__choose\"\n aria-describedby={[hint && hintId, errorMessage && errorId].filter(Boolean).join(' ') || undefined}\n >\n {allowsMultiple ? t.chooseFiles : t.chooseFile}\n </Button>\n </AriaFileTrigger>\n {hint && (\n <span id={hintId} className=\"medo-dropzone__hint\" aria-disabled={isDisabled || undefined}>\n {hint}\n </span>\n )}\n {errorMessage && (\n <span id={errorId} className=\"medo-field__error medo-dropzone__error\">\n <CircleAlert aria-hidden=\"true\" />\n <span>{errorMessage}</span>\n </span>\n )}\n </>\n )}\n </DropZone>\n );\n}\n\n/* ---------- File trigger (compact) ---------- */\n\nexport interface FileTriggerProps extends PickerProps {\n label?: ReactNode;\n /** Visual marker; check “at least one file” on submit and pass `errorMessage`. */\n isRequired?: boolean;\n}\n\n/**\n * File trigger – compact upload for forms and mobile: label, Button secondary with\n * upload icon, hint, error. The system picker offers camera, photos and files on touch devices.\n */\nexport function FileTrigger({\n label,\n isRequired,\n acceptedFileTypes,\n allowsMultiple = true,\n defaultCamera,\n isDisabled,\n hint,\n errorMessage,\n onSelect,\n texts: own,\n className,\n}: FileTriggerProps) {\n const m = useMessages();\n const t = { ...m.upload, ...own };\n const labelId = useId();\n const buttonId = useId();\n const hintId = useId();\n const errorId = useId();\n return (\n <div className={cx('medo-field', 'medo-file-trigger', className)}>\n {label && (\n <span id={labelId} className=\"medo-field__label\">\n {label}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n <div>\n <AriaFileTrigger\n acceptedFileTypes={acceptedFileTypes}\n allowsMultiple={allowsMultiple}\n defaultCamera={defaultCamera}\n onSelect={(list) => list && onSelect([...list])}\n >\n <Button\n id={buttonId}\n variant=\"secondary\"\n startIcon={<Upload />}\n isDisabled={isDisabled}\n className=\"medo-upload__choose\"\n aria-labelledby={label ? `${labelId} ${buttonId}` : undefined}\n aria-describedby={[hint && hintId, errorMessage && errorId].filter(Boolean).join(' ') || undefined}\n >\n {allowsMultiple ? t.chooseFiles : t.chooseFile}\n </Button>\n </AriaFileTrigger>\n </div>\n {(hint || errorMessage) && (\n <div className=\"medo-field__footer\">\n {hint && !errorMessage && (\n <span id={hintId} className=\"medo-field__description\">\n {hint}\n </span>\n )}\n {errorMessage && (\n <span id={errorId} className=\"medo-field__error\">\n <CircleAlert aria-hidden=\"true\" />\n <span>{errorMessage}</span>\n </span>\n )}\n </div>\n )}\n </div>\n );\n}\n\n/* ---------- Upload field (composition) ---------- */\n\nexport interface UploadFieldProps extends Omit<ItemActions, 'texts'> {\n /** Visible label. Without it set `aria-label`. */\n label?: ReactNode;\n 'aria-label'?: string;\n /** The files – controlled. The app uploads them (fetch, S3, tus …) and updates status and `loaded`. */\n files: UploadFile[];\n /** Files that passed type, size and count. Start the upload right away. */\n onAdd: (files: File[]) => void;\n /**\n * auto: Dropzone + list, below 640 px the File trigger (default) · list · compact (File trigger + list, forms) ·\n * grid (images only: tiles; below 640 px with the File trigger).\n */\n layout?: 'auto' | 'list' | 'compact' | 'grid';\n acceptedFileTypes?: string[];\n /** Readable form of the types for hint and message (“PDF, JPG or PNG”). */\n typesLabel?: string;\n /** Max size per file in bytes. */\n maxSize?: number;\n /** Max number of files. 1 = single file picker. */\n maxFiles?: number;\n defaultCamera?: 'user' | 'environment';\n /** Default: “{typesLabel} · max. {maxSize} each”. */\n hint?: ReactNode;\n /** Field error from the app (e.g. required on submit). Wins over the built-in validation message. */\n errorMessage?: ReactNode;\n isRequired?: boolean;\n isDisabled?: boolean;\n texts?: Partial<UploadTexts>;\n className?: string;\n}\n\n/**\n * Upload field – ready composition. Checks type, size and count in the browser\n * before anything is uploaded (check again on the server). Rejected types and too many files show at the\n * picker, too large files as an error row – removable. Results are announced in a polite live region.\n */\nexport function UploadField({\n label,\n 'aria-label': ariaLabel,\n files,\n onAdd,\n onRemove,\n onCancel,\n onRetry,\n layout = 'auto',\n acceptedFileTypes,\n typesLabel,\n maxSize,\n maxFiles,\n defaultCamera,\n hint,\n errorMessage,\n isRequired,\n isDisabled,\n texts: own,\n className,\n}: UploadFieldProps) {\n const m = useMessages();\n const t = useMemo(() => ({ ...m.upload, ...own }), [m, own]);\n const { locale } = useLocale();\n const mobile = useMediaQuery(MOBILE_QUERY);\n const labelId = useId();\n const rootRef = useRef<HTMLDivElement>(null);\n const [rejected, setRejected] = useState<UploadFile[]>([]);\n const [pickerError, setPickerError] = useState<string>();\n const [announcement, setAnnouncement] = useState('');\n\n const compact = layout === 'compact' || (layout !== 'list' && mobile);\n const grid = layout === 'grid';\n const allowsMultiple = maxFiles !== 1;\n const maxLabel = maxSize ? formatBytes(maxSize, locale) : undefined;\n const shownHint = hint ?? ([typesLabel, maxLabel && `max. ${maxLabel}${allowsMultiple ? ' each' : ''}`].filter(Boolean).join(' · ') || undefined);\n\n const add = (picked: File[]) => {\n const wrongType = picked.filter((f) => !isAccepted(f, acceptedFileTypes));\n let ok = picked.filter((f) => isAccepted(f, acceptedFileTypes));\n const tooLarge = maxSize ? ok.filter((f) => f.size > maxSize) : [];\n ok = ok.filter((f) => !tooLarge.includes(f));\n const messages: string[] = [];\n if (wrongType.length) messages.push(t.typeNotAllowed(wrongType.map((f) => `“${f.name}”`).join(', '), typesLabel ?? ''));\n if (maxFiles && files.length + ok.length > maxFiles) {\n ok = ok.slice(0, Math.max(0, maxFiles - files.length));\n messages.push(t.tooMany(maxFiles));\n }\n const errors = tooLarge.map<UploadFile>((f) => ({\n id: `rejected-${f.name}-${f.size}-${f.lastModified}`,\n name: f.name,\n size: f.size,\n type: f.type,\n status: 'error',\n error: t.tooLarge(formatBytes(f.size, locale), maxLabel ?? ''),\n canRetry: false,\n }));\n setRejected((r) => [...r.filter((x) => !errors.some((e) => e.id === x.id)), ...errors]);\n setPickerError(messages.join(' ') || undefined);\n setAnnouncement([...messages, ...errors.map((e) => t.failed(e.name, e.error!))].join(' '));\n if (ok.length) onAdd(ok);\n };\n\n // Announce finished and failed uploads once (the bar itself is not live, so progress never chatters).\n const previous = useRef(new Map<string, UploadFile['status']>());\n useEffect(() => {\n const said: string[] = [];\n for (const f of files) {\n const before = previous.current.get(f.id);\n if (before === f.status) continue;\n if (f.status === 'done' && before) said.push(t.uploaded(f.name));\n if (f.status === 'error' && f.error) said.push(t.failed(f.name, f.error));\n }\n previous.current = new Map(files.map((f) => [f.id, f.status]));\n if (said.length) setAnnouncement(said.join(' '));\n }, [files, t]);\n\n // Removing a file must not lose focus: move it to the same position in the list, else to the picker.\n const focusAt = useRef<number | null>(null);\n const all = [...files, ...rejected];\n useLayoutEffect(() => {\n if (focusAt.current == null) return;\n const items = rootRef.current?.querySelectorAll<HTMLElement>('.medo-upload__item');\n const target = items?.length\n ? items[Math.min(focusAt.current, items.length - 1)].querySelector<HTMLElement>('button')\n : rootRef.current?.querySelector<HTMLElement>('.medo-upload__choose');\n focusAt.current = null;\n target?.focus();\n });\n const remember = (id: string) => (focusAt.current = all.findIndex((f) => f.id === id));\n const actions = {\n texts: own,\n onRetry,\n onCancel: (id: string) => {\n remember(id);\n (onCancel ?? onRemove)(id);\n },\n onRemove: (id: string) => {\n remember(id);\n if (rejected.some((r) => r.id === id)) setRejected((r) => r.filter((x) => x.id !== id));\n else onRemove(id);\n },\n };\n\n const picker = { acceptedFileTypes, allowsMultiple, defaultCamera, isDisabled, hint: shownHint, errorMessage: errorMessage ?? pickerError, onSelect: add, texts: own };\n\n return (\n <div\n ref={rootRef}\n role={compact ? undefined : 'group'}\n aria-labelledby={label && !compact ? labelId : undefined}\n aria-label={label || compact ? undefined : ariaLabel}\n className={cx('medo-upload', grid && 'medo-upload--grid', compact && 'medo-upload--compact', className)}\n >\n {compact ? (\n <FileTrigger {...picker} label={label} isRequired={isRequired} />\n ) : (\n <>\n {label && (\n <span id={labelId} className=\"medo-field__label\">\n {label}\n {isRequired && (\n <span className=\"medo-field__required\" aria-hidden=\"true\">\n *\n </span>\n )}\n </span>\n )}\n <Dropzone {...picker} aria-labelledby={label ? labelId : undefined} />\n </>\n )}\n {all.length > 0 && (\n <ul className={cx('medo-upload__list', grid && 'medo-upload__list--grid')} aria-label={t.listLabel}>\n {all.map((file) => (\n <li key={file.id} className=\"medo-upload__item\">\n {grid ? <FileTile file={file} {...actions} /> : <FileItem file={file} {...actions} />}\n </li>\n ))}\n </ul>\n )}\n <span role=\"status\" className=\"medo-visually-hidden\">\n {announcement}\n </span>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Button as AriaButton,\n Calendar as AriaCalendar,\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeaderCell,\n RangeCalendar as AriaRangeCalendar,\n useLocale,\n type CalendarProps as AriaCalendarProps,\n type DateValue,\n type RangeCalendarProps as AriaRangeCalendarProps,\n} from 'react-aria-components';\nimport { DateFormatter, getDayOfWeek, getLocalTimeZone, today, type CalendarDate } from '@internationalized/date';\nimport { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { en, useMessages } from '../i18n/I18n';\n\ntype View = 'days' | 'months' | 'years';\n\n/** The part of the React Aria calendar state the header and period grids need. */\ninterface ViewState {\n focusedDate: CalendarDate;\n setFocusedDate: (date: CalendarDate) => void;\n minValue?: DateValue | null;\n maxValue?: DateValue | null;\n value?: DateValue | null;\n isDisabled: boolean;\n}\n\nexport interface CalendarTexts {\n previousMonth: string;\n nextMonth: string;\n previousYear: string;\n nextYear: string;\n previousYears: string;\n nextYears: string;\n /** Name of the month-and-year button: “October 2026 – choose month and year”. */\n chooseMonth: (title: string) => string;\n chooseYear: (year: string) => string;\n weekNumber: string;\n}\n\n/** English defaults. The components use the texts of the current language (see i18n). */\nexport const defaultCalendarTexts: CalendarTexts = en.calendar;\n\ninterface SharedProps {\n /** md: 40 px days for desktop popovers · lg: 48 px for touch (Bottom Sheet). */\n size?: 'md' | 'lg';\n /** ISO week numbers (KW) before each row. */\n showWeekNumbers?: boolean;\n texts?: Partial<CalendarTexts>;\n className?: string;\n}\n\n/** ISO 8601 week of the row: the week of its 4th day, so it fits Monday- and Sunday-first locales. */\nfunction isoWeek(date: CalendarDate) {\n const d = new Date(Date.UTC(date.year, date.month - 1, date.day));\n const day = d.getUTCDay() || 7;\n d.setUTCDate(d.getUTCDate() + 4 - day);\n const yearStart = Date.UTC(d.getUTCFullYear(), 0, 1);\n return Math.ceil(((d.getTime() - yearStart) / 86400000 + 1) / 7);\n}\n\n/* ---------- Header ---------- */\n\nfunction Header({\n view,\n setView,\n state,\n size,\n months,\n t,\n}: {\n view: View;\n setView: (v: View) => void;\n state: ViewState;\n size: 'md' | 'lg';\n months: number;\n t: CalendarTexts;\n}) {\n const { locale } = useLocale();\n const monthTitle = useMemo(() => new DateFormatter(locale, { month: 'long', year: 'numeric', timeZone: getLocalTimeZone() }), [locale]);\n const yearTitle = useMemo(() => new DateFormatter(locale, { year: 'numeric', timeZone: getLocalTimeZone() }), [locale]);\n const tz = getLocalTimeZone();\n const focused = state.focusedDate;\n const buttonSize = size === 'lg' ? 'lg' : 'sm';\n const yearStart = focused.year - 5;\n\n const shift = (step: 1 | -1) => state.setFocusedDate(focused.add(view === 'months' ? { years: step } : { years: 12 * step }));\n\n if (view !== 'days') {\n const title = view === 'months' ? yearTitle.format(focused.toDate(tz)) : `${yearStart} – ${yearStart + 11}`;\n return (\n <div className=\"medo-calendar__header\">\n {view === 'months' ? (\n <Button\n slot={null}\n variant=\"ghost\"\n size={buttonSize}\n endIcon={<ChevronDown />}\n onPress={() => setView('years')}\n aria-label={t.chooseYear(title)}\n className=\"medo-calendar__title\"\n >\n {title}\n </Button>\n ) : (\n <span className=\"medo-calendar__title medo-calendar__title--static\" aria-live=\"polite\">\n {title}\n </span>\n )}\n <div className=\"medo-calendar__nav\">\n <IconButton slot={null} size={buttonSize} icon={<ChevronLeft />} aria-label={view === 'months' ? t.previousYear : t.previousYears} onPress={() => shift(-1)} />\n <IconButton slot={null} size={buttonSize} icon={<ChevronRight />} aria-label={view === 'months' ? t.nextYear : t.nextYears} onPress={() => shift(1)} />\n </div>\n </div>\n );\n }\n\n // Days: one header per month; with two months the arrows sit at the outer edges.\n return (\n <div className=\"medo-calendar__headers\" style={{ gridTemplateColumns: `repeat(${months}, 1fr)` }}>\n {Array.from({ length: months }, (_, i) => {\n const title = monthTitle.format(focused.add({ months: i }).toDate(tz));\n return (\n <div key={i} className=\"medo-calendar__header\">\n <Button\n slot={null}\n variant=\"ghost\"\n size={buttonSize}\n endIcon={<ChevronDown />}\n onPress={() => setView('months')}\n aria-label={t.chooseMonth(title)}\n className=\"medo-calendar__title\"\n >\n {title}\n </Button>\n <div className=\"medo-calendar__nav\">\n {i === 0 && <IconButton slot=\"previous\" size={buttonSize} icon={<ChevronLeft />} aria-label={t.previousMonth} />}\n {i === months - 1 && <IconButton slot=\"next\" size={buttonSize} icon={<ChevronRight />} aria-label={t.nextMonth} />}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n\n/* ---------- Months · Years ---------- */\n\nfunction PeriodGrid({ view, setView, state }: { view: 'months' | 'years'; setView: (v: View) => void; state: ViewState }) {\n const { locale } = useLocale();\n const tz = getLocalTimeZone();\n const format = useMemo(() => new DateFormatter(locale, { month: 'short', timeZone: tz }), [locale, tz]);\n const focused = state.focusedDate;\n const now = today(tz);\n const ref = useRef<HTMLDivElement>(null);\n const yearStart = focused.year - 5;\n\n const items = Array.from({ length: 12 }, (_, i) => {\n const date = view === 'months' ? focused.set({ month: i + 1, day: 1 }) : focused.set({ year: yearStart + i, month: 1, day: 1 });\n const last = view === 'months' ? date.add({ months: 1 }).subtract({ days: 1 }) : date.add({ years: 1 }).subtract({ days: 1 });\n const outside = (!!state.minValue && last.compare(state.minValue) < 0) || (!!state.maxValue && date.compare(state.maxValue) > 0);\n const same = (d?: DateValue | null) => !!d && d.year === date.year && (view === 'years' || d.month === date.month);\n return {\n key: `${date.year}-${date.month}`,\n label: view === 'months' ? format.format(date.toDate(tz)) : String(date.year),\n isCurrent: same(now),\n isSelected: same(state.value),\n isFocused: view === 'months' ? date.month === focused.month : date.year === focused.year,\n isDisabled: state.isDisabled || outside,\n pick: () => {\n // set() keeps the day where possible and constrains it (31 → 28 in February).\n state.setFocusedDate(view === 'months' ? focused.set({ month: i + 1 }) : focused.set({ year: yearStart + i }));\n setView(view === 'months' ? 'days' : 'months');\n },\n };\n });\n\n // Keep the keyboard where it was: focus the month/year that matches the focused date.\n useEffect(() => {\n ref.current?.querySelector<HTMLElement>('[data-focus-target]')?.focus();\n }, [view]);\n\n return (\n <div ref={ref} className=\"medo-calendar__periods\" role=\"group\">\n {items.map((item) => (\n <AriaButton\n key={item.key}\n slot={null}\n className=\"medo-calendar__period\"\n isDisabled={item.isDisabled}\n onPress={item.pick}\n aria-pressed={item.isSelected}\n aria-current={item.isCurrent ? 'date' : undefined}\n data-current={item.isCurrent || undefined}\n data-selected={item.isSelected || undefined}\n data-focus-target={item.isFocused || undefined}\n >\n {item.label}\n </AriaButton>\n ))}\n </div>\n );\n}\n\n/* ---------- Day grid ---------- */\n\nfunction DayGrid({ offset, showWeekNumbers, t }: { offset: number; showWeekNumbers?: boolean; t: CalendarTexts }) {\n const { locale } = useLocale();\n return (\n <div className={cx('medo-calendar__month', showWeekNumbers && 'medo-calendar__month--weeks')}>\n {showWeekNumbers && (\n <span className=\"medo-calendar__weeks-label\" aria-hidden=\"true\">\n {t.weekNumber}\n </span>\n )}\n <CalendarGrid offset={offset ? { months: offset } : undefined} weekdayStyle=\"short\" className=\"medo-calendar__grid\">\n <CalendarGridHeader>\n {(day) => <CalendarHeaderCell className=\"medo-calendar__weekday\">{day.replace(/\\.$/, '').slice(0, 2)}</CalendarHeaderCell>}\n </CalendarGridHeader>\n <CalendarGridBody>\n {(date) => (\n <CalendarCell date={date} className=\"medo-calendar__cell\">\n {({ formattedDate }) => (\n // The week number is drawn by CSS (data-week), so it is not part of the day's visible name (WCAG 2.5.3).\n <span className=\"medo-calendar__day\" data-week={showWeekNumbers && getDayOfWeek(date, locale) === 0 ? isoWeek(date.add({ days: 3 })) : undefined}>\n {formattedDate}\n </span>\n )}\n </CalendarCell>\n )}\n </CalendarGridBody>\n </CalendarGrid>\n </div>\n );\n}\n\n/* ---------- Body shared by Calendar and RangeCalendar ---------- */\n\nfunction CalendarBody({ state, size, months, showWeekNumbers, t }: { state: ViewState; size: 'md' | 'lg'; months: number; showWeekNumbers?: boolean; t: CalendarTexts }) {\n const [view, setView] = useState<View>('days');\n const ref = useRef<HTMLDivElement>(null);\n const back = useRef(false);\n\n // Back from the month grid: the focused day takes the focus again.\n useEffect(() => {\n if (view !== 'days' || !back.current) return;\n back.current = false;\n ref.current?.querySelector<HTMLElement>('.medo-calendar__cell[tabindex=\"0\"]')?.focus();\n }, [view]);\n\n const changeView = (v: View) => {\n back.current = v === 'days';\n setView(v);\n };\n\n return (\n <div ref={ref} className=\"medo-calendar__body\">\n <Header view={view} setView={changeView} state={state} size={size} months={view === 'days' ? months : 1} t={t} />\n {view === 'days' ? (\n <div className=\"medo-calendar__months\" style={{ gridTemplateColumns: `repeat(${months}, auto)` }}>\n {Array.from({ length: months }, (_, i) => (\n <DayGrid key={i} offset={i} showWeekNumbers={showWeekNumbers} t={t} />\n ))}\n </div>\n ) : (\n <PeriodGrid view={view} setView={changeView} state={state} />\n )}\n </div>\n );\n}\n\n/* ---------- Calendar ---------- */\n\nexport interface CalendarProps<T extends DateValue> extends Omit<AriaCalendarProps<T>, 'children' | 'className' | 'style' | 'visibleDuration'>, SharedProps {}\n\n/**\n * Calendar – pick a day. React Aria Calendar: a grid with arrow keys (day/week),\n * Page Up/Down (month), Shift + Page Up/Down (year), Home/End. The month-and-year button switches to a month\n * grid, then a year grid – far dates in three clicks. Weekdays and the first day of the week from the locale.\n */\nexport function Calendar<T extends DateValue>({ size = 'md', showWeekNumbers, texts, className, ...props }: CalendarProps<T>) {\n const m = useMessages();\n const t = { ...m.calendar, ...texts };\n return (\n <AriaCalendar<T> {...props} className={cx('medo-calendar', `medo-calendar--${size}`, className)}>\n {({ state }) => <CalendarBody state={state} size={size} months={1} showWeekNumbers={showWeekNumbers} t={t} />}\n </AriaCalendar>\n );\n}\n\n/* ---------- Range calendar ---------- */\n\nexport interface RangeCalendarProps<T extends DateValue> extends Omit<AriaRangeCalendarProps<T>, 'children' | 'className' | 'style' | 'visibleDuration'>, SharedProps {\n /** auto: two months on desktop, one below 640 px. */\n visibleMonths?: 'auto' | 1 | 2;\n}\n\n/**\n * Range calendar – pick a start and an end day. The first click sets the\n * start, the second the end; hovering previews the range. Two months side by side on desktop, one on mobile.\n */\nexport function RangeCalendar<T extends DateValue>({ size = 'md', showWeekNumbers, visibleMonths = 'auto', texts, className, ...props }: RangeCalendarProps<T>) {\n const m = useMessages();\n const t = { ...m.calendar, ...texts };\n const mobile = useMediaQuery(MOBILE_QUERY);\n const months = visibleMonths === 'auto' ? (mobile ? 1 : 2) : visibleMonths;\n return (\n <AriaRangeCalendar<T> {...props} visibleDuration={{ months }} className={cx('medo-calendar', 'medo-calendar--range', `medo-calendar--${size}`, className)}>\n {({ state }) => (\n <CalendarBody\n state={{\n focusedDate: state.focusedDate,\n setFocusedDate: state.setFocusedDate,\n minValue: state.minValue,\n maxValue: state.maxValue,\n value: state.value?.start ?? null,\n isDisabled: state.isDisabled,\n }}\n size={size}\n months={months}\n showWeekNumbers={showWeekNumbers}\n t={t}\n />\n )}\n </AriaRangeCalendar>\n );\n}\n","import { useMemo, useState, type ReactNode } from 'react';\nimport {\n DateField as AriaDateField,\n DateInput,\n DateSegment,\n TimeField as AriaTimeField,\n type DateFieldProps as AriaDateFieldProps,\n type DateValue,\n type TimeFieldProps as AriaTimeFieldProps,\n type TimeValue,\n type ValidationResult,\n useLocale,\n} from 'react-aria-components';\nimport { DateFormatter } from '@internationalized/date';\nimport { Clock } from 'lucide-react';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox, Option } from '../listbox/ListBox';\nimport { Popover, PopoverTrigger } from '../popover/Popover';\nimport { InputAction } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { useMessages } from '../i18n/I18n';\n\n/**\n * The segments inside the Input look. Digits only; a complete segment jumps to the next one. Separators come\n * from the locale (de: TT.MM.JJJJ, 24 h) and are never typed. Styles: `medo-date-box`, `medo-date-segment`.\n */\nexport function DateSegments({ size = 'md', children }: { size?: 'md' | 'lg'; children?: ReactNode }) {\n return (\n <div className={cx('medo-input', `medo-input--${size}`, 'medo-date-box')}>\n <DateInput className=\"medo-date-input\">{(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}</DateInput>\n {children}\n </div>\n );\n}\n\ninterface FieldBase {\n /** Visible label. Without it set `aria-label`. */\n label?: ReactNode;\n description?: ReactNode;\n /** A function gets the validation details (rangeUnderflow, rangeOverflow, badInput) – name the rule. */\n errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);\n /** md 40 (desktop) · lg 48 (touch, below 640 px). */\n size?: 'md' | 'lg';\n className?: string;\n}\n\n/* ---------- Date field ---------- */\n\nexport interface DateFieldProps<T extends DateValue> extends Omit<AriaDateFieldProps<T>, 'children' | 'className' | 'style'>, FieldBase {}\n\n/**\n * Date field – type a date without a calendar. React Aria DateField: every segment is a\n * spinbutton (“day”, “month”, “year”), ↑ ↓ change it, ← → move, Backspace clears, a pasted date fills all.\n * `granularity=\"minute\"` adds the time. For a calendar use DatePicker.\n */\nexport function DateField<T extends DateValue>({ label, description, errorMessage, size = 'md', className, ...props }: DateFieldProps<T>) {\n return (\n <AriaDateField<T> shouldForceLeadingZeros {...props} className={cx('medo-field', 'medo-date-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <DateSegments size={size} />\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaDateField>\n );\n}\n\n/* ---------- Time field ---------- */\n\nexport interface TimeSlot {\n value: TimeValue;\n /** Booked slots stay visible, disabled, with the reason (“Booked”). */\n isDisabled?: boolean;\n reason?: string;\n}\n\nexport interface TimeFieldProps extends Omit<AriaTimeFieldProps<TimeValue>, 'children' | 'className' | 'style'>, FieldBase {\n /** Optional fixed times (e.g. every 15 min). Adds a clock button that opens them. No clock faces. */\n slots?: TimeSlot[];\n /** Name of the clock button and the list. */\n slotsLabel?: string;\n}\n\n/**\n * Time field – type a time. HH:MM, 24 h in de – from the locale. Typing only;\n * with `slots` a clock button opens a list of fixed times (bookings), booked ones disabled with a reason.\n */\nexport function TimeField({\n label,\n description,\n errorMessage,\n size = 'md',\n slots,\n slotsLabel: slotsLabelProp,\n className,\n defaultValue,\n onChange,\n ...props\n}: TimeFieldProps) {\n const m = useMessages();\n const slotsLabel = slotsLabelProp ?? m.datePicker.availableTimes;\n // Controlled inside, so a picked slot shows also when the app passes only defaultValue.\n const [inner, setInner] = useState<TimeValue | null>(defaultValue ?? null);\n const value = props.value !== undefined ? props.value : inner;\n const change = (v: TimeValue | null) => {\n setInner(v);\n onChange?.(v);\n };\n const { locale } = useLocale();\n const format = useMemo(\n () => new DateFormatter(locale, { hour: '2-digit', minute: '2-digit', hourCycle: props.hourCycle === 12 ? 'h12' : props.hourCycle === 24 ? 'h23' : undefined }),\n [locale, props.hourCycle],\n );\n const key = (v?: TimeValue | null) => (v ? `${v.hour}:${v.minute}` : '');\n const text = (v: TimeValue) => format.format(new Date(2000, 0, 1, v.hour, v.minute));\n return (\n <AriaTimeField shouldForceLeadingZeros {...props} value={value} onChange={change} className={cx('medo-field', 'medo-date-field', 'medo-time-field', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <DateSegments size={size}>\n {slots && (\n <PopoverTrigger>\n <InputAction icon={<Clock />} aria-label={slotsLabel} isDisabled={props.isDisabled || props.isReadOnly} />\n <Popover size=\"auto\" aria-label={slotsLabel} placement=\"bottom end\" className=\"medo-time-slots\">\n {(close) => (\n <ListBox\n aria-label={slotsLabel}\n size={size}\n autoFocus\n selectionMode=\"single\"\n selectedKeys={value ? [key(value)] : []}\n disabledKeys={slots.filter((s) => s.isDisabled).map((s) => key(s.value))}\n onSelectionChange={(keys) => {\n const slot = slots.find((s) => keys !== 'all' && keys.has(key(s.value)));\n if (slot) change(slot.value);\n close();\n }}\n >\n {slots.map((s) => (\n <Option key={key(s.value)} id={key(s.value)} textValue={text(s.value)} description={s.isDisabled ? s.reason : undefined}>\n {text(s.value)}\n </Option>\n ))}\n </ListBox>\n )}\n </Popover>\n </PopoverTrigger>\n )}\n </DateSegments>\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaTimeField>\n );\n}\n","import { useContext, useMemo, type ReactNode } from 'react';\nimport {\n DateInput,\n DatePicker as AriaDatePicker,\n DatePickerStateContext,\n DateRangePicker as AriaDateRangePicker,\n DateRangePickerStateContext,\n DateSegment,\n Dialog as AriaDialog,\n Group,\n Popover as AriaPopover,\n useLocale,\n type DatePickerProps as AriaDatePickerProps,\n type DateRangePickerProps as AriaDateRangePickerProps,\n type DateValue,\n type ValidationResult,\n} from 'react-aria-components';\nimport { DateFormatter, endOfMonth, getLocalTimeZone, startOfMonth, today, type CalendarDate } from '@internationalized/date';\nimport { Calendar as CalendarIcon } from 'lucide-react';\nimport { BottomSheet } from '../bottom-sheet/BottomSheet';\nimport { Button } from '../button/Button';\nimport { FieldFooter, FieldLabel } from '../field/Field';\nimport { ListBox, Option } from '../listbox/ListBox';\nimport { InputAction } from '../text-field/TextField';\nimport { cx } from '../utils/cx';\nimport { MOBILE_QUERY, useMediaQuery } from '../utils/useMediaQuery';\nimport { Calendar, RangeCalendar, type CalendarTexts } from './Calendar';\nimport { en, useMessages, type Messages } from '../i18n/I18n';\nimport { TimeField } from './DateField';\n\nexport interface DatePickerTexts extends CalendarTexts {\n openCalendar: string;\n done: string;\n time: string;\n presets: string;\n /** Validation – name the rule, never just “invalid date”. */\n beforeMin: (date: string) => string;\n afterMax: (date: string) => string;\n unavailable: string;\n reversed: string;\n}\n\n/** Picker texts of one language (without the calendar texts). */\nfunction pickerTexts(m: Messages): Omit<DatePickerTexts, keyof CalendarTexts> {\n const d = m.datePicker;\n return {\n openCalendar: d.openCalendar,\n done: m.common.done,\n time: d.time,\n presets: d.presets,\n beforeMin: d.beforeMin,\n afterMax: d.afterMax,\n unavailable: d.unavailable,\n reversed: d.reversed,\n };\n}\n\n/** English defaults. The components use the texts of the current language (see i18n). */\nexport const defaultDatePickerTexts: Omit<DatePickerTexts, keyof CalendarTexts> = pickerTexts(en);\n\ninterface PickerBase {\n label?: ReactNode;\n description?: ReactNode;\n /** Own message or a function of the validation details. Default: the built-in messages (min, max, unavailable, reversed). */\n errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);\n /** md 40 (desktop) · lg 48 (touch). */\n size?: 'md' | 'lg';\n /** auto: popover on desktop, Bottom Sheet with a lg calendar below 640 px · popover · sheet. */\n overlay?: 'auto' | 'popover' | 'sheet';\n /** ISO week numbers in the calendar. */\n showWeekNumbers?: boolean;\n texts?: Partial<DatePickerTexts>;\n className?: string;\n}\n\n/** Messages that name the rule. Unavailable days: pass `texts.unavailable` with the reason (“We don’t deliver on weekends.”). */\nfunction useValidationMessages(t: DatePickerTexts, minValue?: DateValue | null, maxValue?: DateValue | null) {\n const { locale } = useLocale();\n const format = useMemo(() => new DateFormatter(locale, { day: '2-digit', month: '2-digit', year: 'numeric', timeZone: getLocalTimeZone() }), [locale]);\n const show = (d: DateValue) => format.format(d.toDate(getLocalTimeZone()));\n return ({ validationDetails: v, validationErrors }: ValidationResult) => {\n if (v.rangeUnderflow && v.rangeOverflow) return t.reversed;\n if (v.rangeUnderflow && minValue) return t.beforeMin(show(minValue));\n if (v.rangeOverflow && maxValue) return t.afterMax(show(maxValue));\n if (v.badInput) return t.unavailable;\n return validationErrors.join(' ');\n };\n}\n\n/** Popover on desktop (Popover Size Auto), Bottom Sheet with “Done” on mobile. */\nfunction PickerOverlay({ title, sheet, t, children }: { title: string; sheet: boolean; t: DatePickerTexts; children: ReactNode }) {\n if (sheet) {\n return (\n <BottomSheet\n title={title}\n className=\"medo-date-sheet\"\n footer={(close) => (\n <Button variant=\"primary\" size=\"lg\" onPress={close}>\n {t.done}\n </Button>\n )}\n >\n <div className=\"medo-date-panel\">{children}</div>\n </BottomSheet>\n );\n }\n return (\n <AriaPopover placement=\"bottom start\" offset={8} containerPadding={16} className=\"medo-popover medo-popover--auto medo-date-popover\">\n <AriaDialog aria-label={title} className=\"medo-popover__dialog\">\n <div className=\"medo-popover__body medo-date-panel\">{children}</div>\n </AriaDialog>\n </AriaPopover>\n );\n}\n\n/** Date + time picker: the time of the picker's value, typed (no clock faces). */\nfunction PanelTime({ label, size }: { label: string; size: 'md' | 'lg' }) {\n const state = useContext(DatePickerStateContext);\n if (!state) return null;\n return (\n <div className=\"medo-date-panel__time\">\n <TimeField label={label} size={size} value={state.timeValue} onChange={(v) => v && state.setTimeValue(v)} />\n </div>\n );\n}\n\nconst textOf = (label: ReactNode, ariaLabel?: string) => (typeof label === 'string' ? label : (ariaLabel ?? ''));\n\n/* ---------- Date picker ---------- */\n\nexport interface DatePickerProps<T extends DateValue> extends Omit<AriaDatePickerProps<T>, 'children' | 'className' | 'style'>, PickerBase {}\n\n/**\n * Date picker – type a date or pick it. The field is the main input, the calendar is a\n * helper: the button “Open calendar” (or Alt + ↓) opens it, picking a day closes it and focus returns to the\n * field. `granularity=\"minute\"` makes it a date + time picker with a time field in the panel.\n */\nexport function DatePicker<T extends DateValue>({\n label,\n description,\n errorMessage,\n size = 'md',\n overlay = 'auto',\n showWeekNumbers,\n texts,\n className,\n ...props\n}: DatePickerProps<T>) {\n const m = useMessages();\n const t: DatePickerTexts = { ...m.calendar, ...pickerTexts(m), ...texts };\n const mobile = useMediaQuery(MOBILE_QUERY);\n const sheet = overlay === 'sheet' || (overlay === 'auto' && mobile);\n const messages = useValidationMessages(t, props.minValue, props.maxValue);\n const hasTime = !!props.granularity && props.granularity !== 'day';\n\n return (\n <AriaDatePicker<T>\n shouldForceLeadingZeros\n {...props}\n className={cx('medo-field', 'medo-date-field', 'medo-date-picker', hasTime && 'medo-date-picker--time', className)}\n >\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <Group className={cx('medo-input', `medo-input--${size}`, 'medo-date-box')}>\n <DateInput className=\"medo-date-input\">{(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}</DateInput>\n <InputAction icon={<CalendarIcon />} aria-label={t.openCalendar} />\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage ?? messages} />\n <PickerOverlay title={textOf(label, props['aria-label'])} sheet={sheet} t={t}>\n <Calendar size={sheet ? 'lg' : 'md'} showWeekNumbers={showWeekNumbers} texts={t} />\n {hasTime && <PanelTime label={t.time} size={sheet ? 'lg' : 'md'} />}\n </PickerOverlay>\n </AriaDatePicker>\n );\n}\n\n/* ---------- Date range picker ---------- */\n\nexport interface DateRangePreset {\n label: string;\n value: { start: DateValue; end: DateValue };\n}\n\n/**\n * The default presets (Today … Last month), relative to today in the local time zone.\n * Labels: own ones win, else those of `messages` (default English; the DateRangePicker passes the current language).\n */\nexport function defaultDatePresets(\n labels: Partial<Record<'today' | 'yesterday' | 'last7' | 'last14' | 'last30' | 'thisMonth' | 'lastMonth', string>> = {},\n messages: Messages = en,\n): DateRangePreset[] {\n const d = messages.datePicker;\n const now: CalendarDate = today(getLocalTimeZone());\n const lastMonth = now.subtract({ months: 1 });\n return [\n { label: labels.today ?? d.today, value: { start: now, end: now } },\n { label: labels.yesterday ?? d.yesterday, value: { start: now.subtract({ days: 1 }), end: now.subtract({ days: 1 }) } },\n { label: labels.last7 ?? d.last7Days, value: { start: now.subtract({ days: 6 }), end: now } },\n { label: labels.last14 ?? d.last14Days, value: { start: now.subtract({ days: 13 }), end: now } },\n { label: labels.last30 ?? d.last30Days, value: { start: now.subtract({ days: 29 }), end: now } },\n { label: labels.thisMonth ?? d.thisMonth, value: { start: startOfMonth(now), end: now } },\n { label: labels.lastMonth ?? d.lastMonth, value: { start: startOfMonth(lastMonth), end: endOfMonth(lastMonth) } },\n ];\n}\n\nfunction Presets({ presets, label, size }: { presets: DateRangePreset[]; label: string; size: 'md' | 'lg' }) {\n const state = useContext(DateRangePickerStateContext);\n if (!state) return null;\n const same = (a?: DateValue | null, b?: DateValue | null) => !!a && !!b && a.compare(b) === 0;\n const active = presets.findIndex((p) => same(state.value?.start, p.value.start) && same(state.value?.end, p.value.end));\n return (\n <ListBox\n aria-label={label}\n size={size}\n selectionMode=\"single\"\n selectedKeys={active >= 0 ? [String(active)] : []}\n disallowEmptySelection={false}\n onAction={(key) => {\n const preset = presets[Number(key)];\n state.setValue(preset.value);\n state.close();\n }}\n className=\"medo-date-panel__presets\"\n >\n {presets.map((p, i) => (\n <Option key={i} id={String(i)}>\n {p.label}\n </Option>\n ))}\n </ListBox>\n );\n}\n\nexport interface DateRangePickerProps<T extends DateValue> extends Omit<AriaDateRangePickerProps<T>, 'children' | 'className' | 'style'>, PickerBase {\n /** true: the default presets (Today … Last month) · own list · none. Fits dashboards and filters. */\n presets?: boolean | DateRangePreset[];\n}\n\n/**\n * Date range picker – start and end in one field. Two months side by side on desktop,\n * one on mobile; the first click sets the start, the second the end, hovering previews the range. Optional presets.\n */\nexport function DateRangePicker<T extends DateValue>({\n label,\n description,\n errorMessage,\n size = 'md',\n overlay = 'auto',\n showWeekNumbers,\n presets,\n texts,\n className,\n ...props\n}: DateRangePickerProps<T>) {\n const m = useMessages();\n const t: DatePickerTexts = { ...m.calendar, ...pickerTexts(m), ...texts };\n const mobile = useMediaQuery(MOBILE_QUERY);\n const sheet = overlay === 'sheet' || (overlay === 'auto' && mobile);\n const messages = useValidationMessages(t, props.minValue, props.maxValue);\n const list = presets === true ? defaultDatePresets({}, m) : presets || undefined;\n\n return (\n <AriaDateRangePicker<T> shouldForceLeadingZeros {...props} className={cx('medo-field', 'medo-date-field', 'medo-date-picker', 'medo-date-picker--range', className)}>\n {label && <FieldLabel isRequired={props.isRequired}>{label}</FieldLabel>}\n <Group className={cx('medo-input', `medo-input--${size}`, 'medo-date-box')}>\n <DateInput slot=\"start\" className=\"medo-date-input\">\n {(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}\n </DateInput>\n <span className=\"medo-date-box__dash\" aria-hidden=\"true\">\n –\n </span>\n <DateInput slot=\"end\" className=\"medo-date-input\">\n {(segment) => <DateSegment segment={segment} className=\"medo-date-segment\" />}\n </DateInput>\n <InputAction icon={<CalendarIcon />} aria-label={t.openCalendar} />\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage ?? messages} />\n <PickerOverlay title={textOf(label, props['aria-label'])} sheet={sheet} t={t}>\n <div className={cx('medo-date-panel__range', !!list && 'medo-date-panel__range--presets')}>\n {list && <Presets presets={list} label={t.presets} size={sheet ? 'lg' : 'md'} />}\n <RangeCalendar size={sheet ? 'lg' : 'md'} visibleMonths={sheet ? 1 : 2} showWeekNumbers={showWeekNumbers} texts={t} />\n </div>\n </PickerOverlay>\n </AriaDateRangePicker>\n );\n}\n","// Layout: Stack, Grid and Container place everything with the six spacing rules.\nexport { Stack, Grid, GridItem, Container } from './layout/Layout';\nexport type { StackProps, GridProps, GridItemProps, ContainerProps, SpacingRule, LayoutElement } from './layout/Layout';\nexport { Button, ButtonGroup } from './button/Button';\nexport type { ButtonProps, ButtonGroupProps, ButtonSize, ButtonVariant } from './button/Button';\nexport { IconButton } from './icon-button/IconButton';\nexport type { IconButtonProps } from './icon-button/IconButton';\nexport { TextField, InputAction } from './text-field/TextField';\nexport type { TextFieldProps, InputActionProps, InputSize } from './text-field/TextField';\nexport { Checkbox, CheckboxGroup } from './checkbox/Checkbox';\nexport type { CheckboxProps, CheckboxGroupProps, ChoiceSize } from './checkbox/Checkbox';\nexport { Radio, RadioGroup } from './radio/Radio';\nexport type { RadioProps, RadioGroupProps } from './radio/Radio';\nexport { Switch } from './switch/Switch';\nexport type { SwitchProps } from './switch/Switch';\nexport { FieldLabel, FieldFooter } from './field/Field';\nexport { Badge, BadgeCount, BadgeDot } from './badge/Badge';\nexport type { BadgeProps, BadgeCountProps, BadgeDotProps, BadgeTone } from './badge/Badge';\nexport { Tag, TagGroup } from './tag/Tag';\nexport type { TagProps, TagGroupProps } from './tag/Tag';\nexport { Avatar, AvatarGroup, initialsOf } from './avatar/Avatar';\nexport type { AvatarProps, AvatarGroupProps, AvatarSize, AvatarStatus } from './avatar/Avatar';\nexport { Tooltip, TooltipTrigger } from './tooltip/Tooltip';\nexport type { TooltipProps } from './tooltip/Tooltip';\nexport { Spinner, ProgressBar, Skeleton } from './progress/Progress';\nexport type { SpinnerProps, ProgressBarProps, SkeletonProps } from './progress/Progress';\nexport { ToggleButton, ToggleButtonGroup, Toolbar, ToolbarSeparator } from './toggle-button/ToggleButton';\nexport type { ToggleButtonProps, ToggleButtonGroupProps, ToolbarProps } from './toggle-button/ToggleButton';\nexport { ListBox, Option, ListBoxSection, ListBoxMessage } from './listbox/ListBox';\nexport type { ListBoxProps, OptionProps, ListBoxSectionProps, ListBoxSize } from './listbox/ListBox';\nexport { Select } from './select/Select';\nexport type { SelectProps, SelectOverlay } from './select/Select';\nexport { BottomSheet } from './bottom-sheet/BottomSheet';\nexport { Menu, MenuButton, MenuItem, MenuSection, MenuTrigger, Submenu } from './menu/Menu';\nexport type { MenuProps, MenuItemProps, MenuSectionProps, MenuTriggerProps, SubmenuProps } from './menu/Menu';\nexport type { BottomSheetProps } from './bottom-sheet/BottomSheet';\nexport { Dialog, DialogTrigger, AlertDialog } from './dialog/Dialog';\nexport type { DialogProps, DialogAction, DialogDiscardText, AlertDialogProps, AlertDialogTone } from './dialog/Dialog';\nexport { Combobox } from './combobox/Combobox';\nexport type { ComboboxProps } from './combobox/Combobox';\nexport { ToastRegion, toast } from './toast/Toast';\nexport type { ToastRegionProps, ToastOptions, ToastAction } from './toast/Toast';\nexport { Tabs, TabList, Tab, TabPanel } from './tabs/Tabs';\nexport type { TabsProps, TabListProps, TabProps, TabPanelProps } from './tabs/Tabs';\nexport { Popover, PopoverTrigger, Toggletip } from './popover/Popover';\nexport type { PopoverProps, ToggletipProps } from './popover/Popover';\nexport {\n NavItem,\n NavGroup,\n NavSection,\n NavList,\n SkipLink,\n SiteHeader,\n AppHeader,\n SideNav,\n BottomTabBar,\n TabBarItem,\n TabBarMore,\n} from './navigation/Navigation';\nexport type {\n NavItemProps,\n NavGroupProps,\n NavSectionProps,\n NavListProps,\n NavVariant,\n NavAction,\n SkipLinkProps,\n SiteHeaderProps,\n AppHeaderProps,\n SideNavProps,\n SideNavUser,\n BottomTabBarProps,\n TabBarItemProps,\n TabBarMoreProps,\n} from './navigation/Navigation';\nexport { Drawer } from './drawer/Drawer';\nexport type { DrawerProps } from './drawer/Drawer';\nexport { List, ListItem, DescriptionList, DescriptionItem } from './list/List';\nexport type { ListProps, ListItemProps, ListType, DescriptionListProps, DescriptionItemProps } from './list/List';\nexport { ListView, ListRow, ListRowIcon, ListCard } from './list-view/ListView';\nexport type { ListViewProps, ListRowProps, ListCardProps } from './list-view/ListView';\nexport { BulkActionBar } from './bulk-action-bar/BulkActionBar';\nexport type { BulkActionBarProps, BulkAction } from './bulk-action-bar/BulkActionBar';\nexport { EmptyState } from './empty-state/EmptyState';\nexport type { EmptyStateProps, EmptyStateAction, EmptyStateType, EmptyStateSize } from './empty-state/EmptyState';\nexport { Pagination } from './pagination/Pagination';\nexport type { PaginationProps } from './pagination/Pagination';\nexport { SearchField } from './search/SearchField';\nexport type { SearchFieldProps } from './search/SearchField';\nexport { SearchResult } from './search/SearchResult';\nexport type { SearchResultProps, SearchResultType } from './search/SearchResult';\nexport { QuickSearch } from './search/QuickSearch';\nexport type { QuickSearchProps } from './search/QuickSearch';\nexport { Highlight } from './utils/highlight';\nexport { Breadcrumbs } from './breadcrumbs/Breadcrumbs';\nexport type { BreadcrumbsProps, BreadcrumbItem } from './breadcrumbs/Breadcrumbs';\nexport { Accordion, AccordionItem } from './accordion/Accordion';\nexport type { AccordionProps, AccordionItemProps } from './accordion/Accordion';\nexport { Slider, SliderField } from './slider/Slider';\nexport type { SliderProps, SliderFieldProps } from './slider/Slider';\nexport { NumberField } from './number-field/NumberField';\nexport type { NumberFieldProps } from './number-field/NumberField';\nexport { Link } from './link/Link';\nexport type { LinkProps } from './link/Link';\nexport { Alert } from './alert/Alert';\nexport type { AlertProps, AlertTone } from './alert/Alert';\nexport { Card } from './card/Card';\nexport type { CardProps } from './card/Card';\nexport { StaticTable, Table, TableHeader, Column, TableBody, Row, Cell } from './table/Table';\nexport type { StaticTableProps, TableProps, ColumnProps, CellProps } from './table/Table';\nexport { ColumnsMenu } from './table/ColumnsMenu';\nexport type { ColumnsMenuProps, ColumnOption } from './table/ColumnsMenu';\nexport { UploadField, Dropzone, FileTrigger, FileItem, FileTile, formatBytes, defaultUploadTexts } from './upload/Upload';\nexport type { UploadFieldProps, DropzoneProps, FileTriggerProps, FileItemProps, FileTileProps, UploadFile, UploadTexts } from './upload/Upload';\nexport { Calendar, RangeCalendar, defaultCalendarTexts } from './date-time/Calendar';\nexport type { CalendarProps, RangeCalendarProps, CalendarTexts } from './date-time/Calendar';\nexport { DateField, TimeField } from './date-time/DateField';\nexport type { DateFieldProps, TimeFieldProps, TimeSlot } from './date-time/DateField';\nexport { DatePicker, DateRangePicker, defaultDatePresets, defaultDatePickerTexts } from './date-time/DatePicker';\nexport type { DatePickerProps, DateRangePickerProps, DateRangePreset, DatePickerTexts } from './date-time/DatePicker';\n/** Date values (React Aria standard): parse ISO strings, today, time zones, weekend checks. */\nexport {\n CalendarDate,\n CalendarDateTime,\n Time,\n ZonedDateTime,\n parseDate,\n parseDateTime,\n parseTime,\n parseZonedDateTime,\n today,\n now,\n getLocalTimeZone,\n isWeekend,\n isToday,\n} from '@internationalized/date';\nexport type { DateValue, TimeValue } from 'react-aria-components';\nexport { Image, Figure, MediaPlayButton } from './media/Image';\nexport type { ImageProps, ImageRatio, FigureProps, MediaPlayButtonProps } from './media/Image';\nexport { EmbedConsent, defaultEmbedTexts } from './media/EmbedConsent';\nexport type { EmbedConsentProps, EmbedTexts, EmbedType } from './media/EmbedConsent';\n\n// Built-in texts: English and German, the language comes from React Aria's I18nProvider (else the browser).\nexport { MessagesProvider, useMessages, en as enMessages, de as deMessages } from './i18n/I18n';\nexport type { Messages, EmbedMessages } from './i18n/I18n';\n","import { useEffect, useLayoutEffect, useRef, useState, type CSSProperties, type ImgHTMLAttributes, type ReactNode } from 'react';\nimport { ImageOff, Play } from 'lucide-react';\nimport { Skeleton } from '../progress/Progress';\nimport { cx } from '../utils/cx';\n\nexport type ImageRatio = '1:1' | '3:4' | '4:3' | '3:2' | '16:9' | '21:9' | 'original';\n\n/* ---------- Media play button ---------- */\n\nexport interface MediaPlayButtonProps {\n /** md 48 (cards, lists) · lg 64 (hero, player). */\n size?: 'md' | 'lg';\n className?: string;\n}\n\n/**\n * Media play button – marks video on a thumbnail. Visual only: the whole\n * thumbnail is the hit area (a link or button around it); hover, pressed and focus come from there.\n */\nexport function MediaPlayButton({ size = 'md', className }: MediaPlayButtonProps) {\n return (\n <span className={cx('medo-media-play', `medo-media-play--${size}`, className)} aria-hidden=\"true\">\n <Play />\n </span>\n );\n}\n\n/* ---------- Image ---------- */\n\nexport interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 'alt' | 'src' | 'placeholder' | 'children' | 'className' | 'style'> {\n /** Without src the image stays in its loading state (e.g. while the URL is resolved). */\n src?: string;\n /** Required. Describe the purpose, not the pixels. Decorative images: alt=\"\" on purpose. */\n alt: string;\n /** Reserves the space before the file arrives. original: from width/height (fallback 3:2 while loading). */\n ratio?: ImageRatio;\n /** cover: photos (fills, crops) · contain: logos, screenshots, product shots, charts (shows everything). */\n fit?: 'cover' | 'contain';\n /** Default radius/md; in cards the image takes the card's radius (none). */\n radius?: 'none' | 'sm' | 'md' | 'lg';\n /** 1 px border/media inside – for images on a similar background. */\n bordered?: boolean;\n /** Tiny preview (≈ 20 px, data URI) for blur-up. Without it a Skeleton shows. */\n placeholder?: string;\n /** Hero / largest image at the top: loads first (eager, fetchpriority high). Everything else loads lazily. */\n priority?: boolean;\n /** Text on a gradient – translatable, searchable, read by screen readers. Never bake text into images. */\n overlay?: { title: ReactNode; meta?: ReactNode; position?: 'bottom' | 'top' };\n /** One Badge (sm), top left. */\n badge?: ReactNode;\n /** Marks video. */\n play?: 'md' | 'lg';\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Image – an image with reserved space and calm loading states. Loading: blur-up preview or\n * Skeleton; the image fades in (250 ms; 100 ms with reduced motion). Error keeps the space and shows image-off;\n * the alt text stays available. Overlays (text, badge, play) only on the loaded image.\n */\nexport function Image({\n src,\n alt,\n ratio = 'original',\n fit = 'cover',\n radius = 'md',\n bordered,\n placeholder,\n priority,\n overlay,\n badge,\n play,\n className,\n style,\n onLoad,\n onError,\n ...props\n}: ImageProps) {\n const ref = useRef<HTMLImageElement>(null);\n const [state, setState] = useState<'loading' | 'loaded' | 'error'>('loading');\n\n // A new source starts loading again.\n useLayoutEffect(() => setState('loading'), [src]);\n\n // Cached images can finish before React attaches onLoad.\n useEffect(() => {\n const img = ref.current;\n if (img?.complete && src) setState(img.naturalWidth > 0 ? 'loaded' : 'error');\n }, [src]);\n\n const original = ratio === 'original';\n const { width, height } = props;\n const aspect = original ? (width && height ? `${width} / ${height}` : state === 'loaded' ? undefined : '3 / 2') : ratio.replace(':', ' / ');\n\n return (\n <div\n className={cx('medo-image', `medo-image--${fit}`, `medo-image--radius-${radius}`, bordered && 'medo-image--bordered', className)}\n data-state={state}\n style={{ aspectRatio: aspect, ...style }}\n >\n {state === 'loading' &&\n (placeholder ? <img className=\"medo-image__preview\" src={placeholder} alt=\"\" aria-hidden=\"true\" /> : <Skeleton shape=\"rect\" className=\"medo-image__skeleton\" />)}\n {state === 'error' && (\n <span className=\"medo-image__error\" role={alt ? 'img' : undefined} aria-label={alt || undefined} aria-hidden={alt ? undefined : true}>\n <ImageOff aria-hidden=\"true\" />\n </span>\n )}\n <img\n {...props}\n ref={ref}\n src={src}\n alt={alt}\n hidden={state === 'error'}\n loading={priority ? 'eager' : (props.loading ?? 'lazy')}\n fetchPriority={priority ? 'high' : props.fetchPriority}\n decoding=\"async\"\n className=\"medo-image__img\"\n onLoad={(e) => {\n setState('loaded');\n onLoad?.(e);\n }}\n onError={(e) => {\n setState('error');\n onError?.(e);\n }}\n />\n {state === 'loaded' && overlay && (\n <div className={cx('medo-image__overlay', `medo-image__overlay--${overlay.position ?? 'bottom'}`)}>\n <span className=\"medo-image__title\">{overlay.title}</span>\n {overlay.meta && <span className=\"medo-image__meta\">{overlay.meta}</span>}\n </div>\n )}\n {state === 'loaded' && badge && <span className=\"medo-image__badge\">{badge}</span>}\n {state === 'loaded' && play && <MediaPlayButton size={play} className=\"medo-image__play\" />}\n </div>\n );\n}\n\n/* ---------- Figure ---------- */\n\nexport interface FigureProps {\n /** The Image. */\n children: ReactNode;\n /** Describes what matters (adds to the image – never repeat the alt text). */\n caption?: ReactNode;\n /** Names the source (“© Photographer”). */\n credit?: ReactNode;\n className?: string;\n}\n\n/** Figure – image with caption and credit. A real figure + figcaption. */\nexport function Figure({ children, caption, credit, className }: FigureProps) {\n return (\n <figure className={cx('medo-figure', className)}>\n {children}\n {(caption || credit) && (\n <figcaption className=\"medo-figure__caption\">\n {caption && <span>{caption}</span>}\n {credit && <span className=\"medo-figure__credit\">{credit}</span>}\n </figcaption>\n )}\n </figure>\n );\n}\n","import { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { Globe, MapPin, Play } from 'lucide-react';\nimport { Button } from '../button/Button';\nimport { Checkbox } from '../checkbox/Checkbox';\nimport { IconTile } from '../empty-state/EmptyState';\nimport { Link } from '../link/Link';\nimport { cx } from '../utils/cx';\nimport type { ImageRatio } from './Image';\nimport { en, useMessages, type Messages } from '../i18n/I18n';\n\nexport type EmbedType = 'video' | 'map' | 'generic';\n\nexport interface EmbedTexts {\n title: string;\n /** Default size: who provides it and what is sent. */\n body: string;\n /** Compact size (< 480 px). */\n bodyCompact: string;\n load: string;\n remember: string;\n privacy: string;\n}\n\n/**\n * Texts per type. provider: the service (“Example Video”) · company: who runs it, when it differs (“Example Inc.”).\n * `messages`: the language (default English); the component passes the current one.\n */\nexport function defaultEmbedTexts(type: EmbedType, provider?: string, company?: string, messages: Messages = en): EmbedTexts {\n const to = company ?? provider;\n const e = messages.embed[type];\n return {\n title: e.title,\n body: e.body(provider, to),\n bodyCompact: e.bodyCompact(provider, company, to),\n load: e.load,\n remember: e.remember(provider),\n privacy: messages.embed.privacy,\n };\n}\n\nconst icons = { video: <Play />, map: <MapPin />, generic: <Globe /> };\n\nexport interface EmbedConsentProps {\n type?: EmbedType;\n /** Name of the service that provides the content (“Example Video”). */\n provider?: string;\n /** Who receives the data, when it differs from the service (“Example Inc.”). */\n company?: string;\n /** The embed URL – requested only after consent. Prefer the privacy-friendly embed URL of the service, if it offers one. */\n src: string;\n /** Required: names the iframe (“Video: Product tour”). */\n title: string;\n /** Ratio of the final embed. The placeholder may grow so text never clips. */\n ratio?: Exclude<ImageRatio, 'original'>;\n /** The provider's privacy policy (or your own). */\n privacyHref: string;\n /** Stored consent from the consent manager – loads at once. */\n isConsented?: boolean;\n /** The user clicked “Load”; `remember` = “Always load …” checked – store it per provider in the consent manager. */\n onConsent?: (remember: boolean) => void;\n /** iframe permissions, e.g. “autoplay; encrypted-media; picture-in-picture; fullscreen”. */\n allow?: string;\n texts?: Partial<EmbedTexts>;\n className?: string;\n}\n\n/**\n * Embed consent – two-click placeholder for third-party embeds.\n * Nothing loads from the provider – not even a thumbnail – until the user clicks. Then the iframe replaces the\n * placeholder in place and takes the focus. Compact below 480 px width (measured on the component).\n */\nexport function EmbedConsent({\n type = 'generic',\n provider,\n company,\n src,\n title,\n ratio = '16:9',\n privacyHref,\n isConsented,\n onConsent,\n allow,\n texts,\n className,\n}: EmbedConsentProps) {\n const m = useMessages();\n const t = { ...defaultEmbedTexts(type, provider, company, m), ...texts };\n const ref = useRef<HTMLDivElement>(null);\n const frame = useRef<HTMLIFrameElement>(null);\n const [clicked, setClicked] = useState(false);\n const [remember, setRemember] = useState(false);\n const [compact, setCompact] = useState(false);\n const loaded = isConsented || clicked;\n\n // Default from 480 px width, Compact below – the component's own width, not the viewport.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || loaded) return;\n const ro = new ResizeObserver(([entry]) => setCompact(entry.contentRect.width < 480));\n ro.observe(el);\n return () => ro.disconnect();\n }, [loaded]);\n\n // After the click the iframe takes the focus, so keyboard users land in the content.\n useEffect(() => {\n if (clicked) frame.current?.focus();\n }, [clicked]);\n\n const style = { aspectRatio: ratio.replace(':', ' / ') };\n\n if (loaded) {\n return (\n <div className={cx('medo-embed', 'medo-embed--loaded', className)} style={style}>\n <iframe\n ref={frame}\n src={src}\n title={title}\n allow={allow}\n allowFullScreen\n referrerPolicy=\"strict-origin-when-cross-origin\"\n loading=\"lazy\"\n className=\"medo-embed__frame\"\n />\n </div>\n );\n }\n\n return (\n <div ref={ref} role=\"region\" aria-label={title} className={cx('medo-embed', compact && 'medo-embed--compact', className)} style={style}>\n {!compact && (\n <IconTile size=\"sm\" tone=\"raised\">\n {icons[type]}\n </IconTile>\n )}\n <div className=\"medo-embed__content\">\n <p className=\"medo-embed__title\">{t.title}</p>\n <p className=\"medo-embed__body\">{compact ? t.bodyCompact : t.body}</p>\n </div>\n <div className=\"medo-embed__actions\">\n <Button\n size={compact ? 'sm' : 'md'}\n onPress={() => {\n onConsent?.(remember);\n setClicked(true);\n }}\n >\n {t.load}\n </Button>\n <Link variant=\"standalone\" size={compact ? 'sm' : 'md'} href={privacyHref}>\n {t.privacy}\n </Link>\n </div>\n {!compact && (\n <Checkbox isSelected={remember} onChange={setRemember}>\n {t.remember}\n </Checkbox>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["Tag","embed","jsx","jsx","jsx","jsxs","AriaButton","useContext","jsx","jsxs","useContext","jsx","jsxs","AriaButton","AriaButton","Label","Fragment","jsx","jsxs","Fragment","jsx","jsxs","AriaButton","createContext","useContext","Text","Fragment","jsx","jsxs","createContext","useContext","Text","useContext","Text","jsx","jsxs","useContext","Text","Text","Check","Fragment","jsx","jsxs","Check","Text","jsx","jsxs","createContext","useContext","useState","AriaButton","Text","Check","X","Fragment","jsx","jsxs","createContext","useState","Text","useContext","Check","AriaButton","X","createContext","useContext","useEffect","useState","AriaButton","jsx","jsxs","createContext","useContext","useState","useEffect","AriaButton","createContext","useContext","useEffect","useRef","jsx","jsxs","createContext","useContext","s","useRef","useEffect","createContext","useContext","Text","Check","jsx","Tag","Fragment","jsx","jsxs","createContext","useContext","Check","Text","Highlight","useContext","useEffect","useLayoutEffect","useRef","useState","AriaButton","Popover","X","useContext","useId","useRef","X","Fragment","jsx","jsxs","X","useRef","useContext","useId","useState","Fragment","jsx","jsxs","useState","useRef","AriaButton","Popover","useContext","useLayoutEffect","X","useEffect","createContext","useContext","useState","Header","Popover","Text","Fragment","jsx","jsxs","createContext","Popover","useState","useContext","Text","Header","useContext","useEffect","useId","useLayoutEffect","useRef","useState","Heading","Modal","ModalOverlay","OverlayTriggerStateContext","CircleAlert","X","Fragment","jsx","jsxs","useContext","OverlayTriggerStateContext","useState","Dialog","ModalOverlay","Modal","useId","useRef","Heading","X","useLayoutEffect","useEffect","CircleAlert","useContext","useEffect","useId","useRef","useState","AriaButton","Collection","ComboBoxStateContext","Popover","AriaTextField","ChevronDown","CircleAlert","X","Fragment","jsx","jsxs","text","useRef","useState","SelectedTags","ClearButton","AriaButton","ChevronDown","Popover","useContext","ComboBoxStateContext","X","useEffect","Collection","useId","CircleAlert","AriaTextField","useEffect","useState","Button","Text","X","jsx","jsxs","useState","useEffect","Text","Button","X","useLayoutEffect","useRef","SelectionIndicator","jsx","jsxs","useRef","SelectionIndicator","useLayoutEffect","useContext","useRef","AriaDialog","DialogTrigger","Heading","OverlayTriggerStateContext","Info","X","AriaLink","jsx","jsxs","AriaLink","Fragment","jsx","jsxs","DialogTrigger","Popover","Heading","X","useRef","AriaDialog","useContext","OverlayTriggerStateContext","Info","Children","createContext","isValidElement","useContext","useEffect","useId","useRef","useState","AriaButton","AriaDialog","DialogTrigger","Heading","AriaLink","Modal","ModalOverlay","ChevronDown","Ellipsis","X","useEffect","useRef","AriaDialog","Heading","Modal","ModalOverlay","X","Fragment","jsx","jsxs","ModalOverlay","Modal","Heading","X","useRef","AriaDialog","CLOSE_DISTANCE","CLOSE_VELOCITY","useEffect","Fragment","jsx","jsxs","createContext","useContext","AriaLink","Children","isValidElement","useState","useId","useRef","useEffect","AriaButton","ChevronDown","DialogTrigger","ModalOverlay","Modal","AriaDialog","X","Heading","Ellipsis","createContext","useContext","Check","X","jsx","jsxs","createContext","Tag","useContext","X","Check","useEffect","useRef","useState","useLocale","ChevronRight","Fragment","jsx","jsxs","ChevronRight","useLocale","useRef","useState","useEffect","useEffect","useRef","AriaButton","Toolbar","Ellipsis","X","Fragment","jsx","jsxs","useRef","useEffect","AriaButton","Ellipsis","Toolbar","X","useId","CircleAlert","Search","jsx","jsxs","Search","CircleAlert","useId","Tag","useId","useRef","useState","AriaButton","AriaLink","ChevronLeft","ChevronRight","Fragment","jsx","jsxs","useState","useId","useRef","AriaLink","AriaButton","ChevronLeft","ChevronRight","AriaButton","AriaInput","Search","X","jsx","jsxs","Search","AriaInput","AriaButton","X","AriaLink","jsx","jsxs","Heading","AriaLink","useEffect","useLayoutEffect","useState","Autocomplete","AriaButton","Dialog","Modal","ModalOverlay","useFilter","Search","jsx","jsxs","useState","useFilter","useEffect","ModalOverlay","Modal","Dialog","Autocomplete","AriaButton","Search","useLayoutEffect","useLayoutEffect","useRef","useState","AriaButton","AriaLink","ChevronLeft","ChevronRight","Ellipsis","Folder","jsx","jsxs","AriaLink","ChevronLeft","Label","ChevronRight","AriaButton","Ellipsis","Folder","useRef","useState","useLayoutEffect","Children","createContext","isValidElement","useContext","useEffect","useId","useState","AriaButton","Heading","ChevronDown","jsx","jsxs","createContext","Children","isValidElement","useState","useEffect","useContext","useId","Heading","AriaButton","ChevronDown","Label","useLocale","AriaInput","jsx","jsxs","AriaInput","Fragment","jsx","jsxs","useLocale","Label","CircleAlert","CircleCheck","Info","TriangleAlert","X","jsx","jsxs","Info","CircleCheck","TriangleAlert","CircleAlert","X","AriaLink","jsx","jsxs","Heading","AriaLink","useEffect","useId","useRef","useState","Collection","Check","Minus","jsx","jsxs","useRef","useState","useEffect","plain","useId","Minus","Check","Collection","jsx","jsxs","Popover","useEffect","useId","useLayoutEffect","useMemo","useRef","useState","AriaButton","Text","useLocale","CircleAlert","CircleCheck","FileText","X","Fragment","jsx","jsxs","useLocale","CircleAlert","CircleCheck","FileText","X","AriaButton","useId","Text","useMemo","useRef","useState","useEffect","useLayoutEffect","useEffect","useMemo","useRef","useState","AriaButton","useLocale","ChevronDown","ChevronLeft","ChevronRight","jsx","jsxs","Header","useLocale","useMemo","ChevronDown","ChevronLeft","ChevronRight","now","useRef","useEffect","AriaButton","useState","useMemo","useState","useLocale","DateFormatter","jsx","jsxs","useState","useLocale","useMemo","DateFormatter","Popover","s","useContext","useMemo","DateInput","DateSegment","AriaDialog","Group","AriaPopover","useLocale","DateFormatter","getLocalTimeZone","today","jsx","jsxs","useLocale","useMemo","DateFormatter","getLocalTimeZone","AriaPopover","AriaDialog","useContext","Group","DateInput","DateSegment","now","today","today","getLocalTimeZone","useEffect","useLayoutEffect","useRef","useState","jsx","jsxs","useRef","useState","useLayoutEffect","useEffect","useEffect","useLayoutEffect","useRef","useState","Globe","Play","jsx","jsxs","icons","Play","Globe","useRef","useState","useLayoutEffect","useEffect"]}