@mortenbrudvik/waveui 0.12.0 → 0.14.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/README.md +362 -60
- package/dist/components/data-display/Avatar.cjs +1 -1
- package/dist/components/data-display/Avatar.cjs.map +1 -1
- package/dist/components/data-display/Avatar.colors.cjs +2 -0
- package/dist/components/data-display/Avatar.colors.cjs.map +1 -0
- package/dist/components/data-display/Avatar.colors.mjs +45 -0
- package/dist/components/data-display/Avatar.colors.mjs.map +1 -0
- package/dist/components/data-display/Avatar.context.cjs +1 -1
- package/dist/components/data-display/Avatar.context.cjs.map +1 -1
- package/dist/components/data-display/Avatar.context.mjs +4 -2
- package/dist/components/data-display/Avatar.context.mjs.map +1 -1
- package/dist/components/data-display/Avatar.mjs +103 -96
- package/dist/components/data-display/Avatar.mjs.map +1 -1
- package/dist/components/data-display/Avatar.sizes.cjs +2 -0
- package/dist/components/data-display/Avatar.sizes.cjs.map +1 -0
- package/dist/components/data-display/Avatar.sizes.mjs +41 -0
- package/dist/components/data-display/Avatar.sizes.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.cjs +1 -1
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.context.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.context.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.context.mjs +9 -0
- package/dist/components/data-display/AvatarGroup.context.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.mjs +65 -122
- package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.partition.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.partition.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.partition.mjs +14 -0
- package/dist/components/data-display/AvatarGroup.partition.mjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.parts.cjs +2 -0
- package/dist/components/data-display/AvatarGroup.parts.cjs.map +1 -0
- package/dist/components/data-display/AvatarGroup.parts.mjs +178 -0
- package/dist/components/data-display/AvatarGroup.parts.mjs.map +1 -0
- package/dist/components/data-display/InteractionTag.cjs +1 -1
- package/dist/components/data-display/InteractionTag.cjs.map +1 -1
- package/dist/components/data-display/InteractionTag.mjs +36 -33
- package/dist/components/data-display/InteractionTag.mjs.map +1 -1
- package/dist/components/data-display/List.cjs +1 -1
- package/dist/components/data-display/List.cjs.map +1 -1
- package/dist/components/data-display/List.mjs +245 -195
- package/dist/components/data-display/List.mjs.map +1 -1
- package/dist/components/data-display/List.registry.cjs.map +1 -1
- package/dist/components/data-display/List.registry.mjs.map +1 -1
- package/dist/components/data-display/Persona.cjs +1 -1
- package/dist/components/data-display/Persona.cjs.map +1 -1
- package/dist/components/data-display/Persona.mjs +96 -37
- package/dist/components/data-display/Persona.mjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.cjs +1 -1
- package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
- package/dist/components/data-display/PresenceBadge.mjs +42 -28
- package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
- package/dist/components/data-display/Tag.cjs +1 -1
- package/dist/components/data-display/Tag.cjs.map +1 -1
- package/dist/components/data-display/Tag.mjs +111 -108
- package/dist/components/data-display/Tag.mjs.map +1 -1
- package/dist/components/layout/Card.cjs +1 -1
- package/dist/components/layout/Card.cjs.map +1 -1
- package/dist/components/layout/Card.context.cjs +2 -0
- package/dist/components/layout/Card.context.cjs.map +1 -0
- package/dist/components/layout/Card.context.mjs +14 -0
- package/dist/components/layout/Card.context.mjs.map +1 -0
- package/dist/components/layout/Card.mjs +138 -92
- package/dist/components/layout/Card.mjs.map +1 -1
- package/dist/components/layout/Card.preview.cjs +2 -0
- package/dist/components/layout/Card.preview.cjs.map +1 -0
- package/dist/components/layout/Card.preview.mjs +22 -0
- package/dist/components/layout/Card.preview.mjs.map +1 -0
- package/dist/components/layout/Carousel.button.cjs +2 -0
- package/dist/components/layout/Carousel.button.cjs.map +1 -0
- package/dist/components/layout/Carousel.button.mjs +34 -0
- package/dist/components/layout/Carousel.button.mjs.map +1 -0
- package/dist/components/layout/Carousel.cjs +1 -1
- package/dist/components/layout/Carousel.cjs.map +1 -1
- package/dist/components/layout/Carousel.context.cjs +2 -0
- package/dist/components/layout/Carousel.context.cjs.map +1 -0
- package/dist/components/layout/Carousel.context.mjs +24 -0
- package/dist/components/layout/Carousel.context.mjs.map +1 -0
- package/dist/components/layout/Carousel.drag.cjs +2 -0
- package/dist/components/layout/Carousel.drag.cjs.map +1 -0
- package/dist/components/layout/Carousel.drag.mjs +79 -0
- package/dist/components/layout/Carousel.drag.mjs.map +1 -0
- package/dist/components/layout/Carousel.groups.cjs +2 -0
- package/dist/components/layout/Carousel.groups.cjs.map +1 -0
- package/dist/components/layout/Carousel.groups.mjs +23 -0
- package/dist/components/layout/Carousel.groups.mjs.map +1 -0
- package/dist/components/layout/Carousel.mjs +288 -150
- package/dist/components/layout/Carousel.mjs.map +1 -1
- package/dist/components/layout/Carousel.styles.cjs +2 -0
- package/dist/components/layout/Carousel.styles.cjs.map +1 -0
- package/dist/components/layout/Carousel.styles.mjs +30 -0
- package/dist/components/layout/Carousel.styles.mjs.map +1 -0
- package/dist/components/layout/Overflow.cjs +1 -1
- package/dist/components/layout/Overflow.cjs.map +1 -1
- package/dist/components/layout/Overflow.mjs +240 -192
- package/dist/components/layout/Overflow.mjs.map +1 -1
- package/dist/components/layout/Overflow.store.cjs +2 -0
- package/dist/components/layout/Overflow.store.cjs.map +1 -0
- package/dist/components/layout/Overflow.store.mjs +209 -0
- package/dist/components/layout/Overflow.store.mjs.map +1 -0
- package/dist/components/layout/TabList.cjs +1 -1
- package/dist/components/layout/TabList.cjs.map +1 -1
- package/dist/components/layout/TabList.mjs +163 -124
- package/dist/components/layout/TabList.mjs.map +1 -1
- package/dist/components/navigation/Breadcrumb.cjs +1 -1
- package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
- package/dist/components/navigation/Breadcrumb.mjs +239 -84
- package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.cjs +1 -1
- package/dist/components/overlays/Dialog.slots.cjs.map +1 -1
- package/dist/components/overlays/Dialog.slots.mjs +19 -15
- package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.context.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.context.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.context.mjs +51 -0
- package/dist/components/overlays/TeachingPopover.context.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.mjs +15 -185
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.parts.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.parts.mjs +398 -0
- package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.root.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.root.mjs +150 -0
- package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.stack.cjs +2 -0
- package/dist/components/overlays/TeachingPopover.stack.cjs.map +1 -0
- package/dist/components/overlays/TeachingPopover.stack.mjs +86 -0
- package/dist/components/overlays/TeachingPopover.stack.mjs.map +1 -0
- package/dist/components/table/DataGrid.cjs +1 -1
- package/dist/components/table/DataGrid.cjs.map +1 -1
- package/dist/components/table/DataGrid.mjs +540 -311
- package/dist/components/table/DataGrid.mjs.map +1 -1
- package/dist/components/table/Table.cjs +1 -1
- package/dist/components/table/Table.cjs.map +1 -1
- package/dist/components/table/Table.mjs +183 -60
- package/dist/components/table/Table.mjs.map +1 -1
- package/dist/components/table/Table.shared.cjs +2 -0
- package/dist/components/table/Table.shared.cjs.map +1 -0
- package/dist/components/table/Table.shared.mjs +65 -0
- package/dist/components/table/Table.shared.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2299 -213
- package/dist/index.d.ts +2299 -213
- package/dist/index.mjs +135 -127
- package/dist/lib/breadcrumb.cjs +2 -0
- package/dist/lib/breadcrumb.cjs.map +1 -0
- package/dist/lib/breadcrumb.mjs +26 -0
- package/dist/lib/breadcrumb.mjs.map +1 -0
- package/dist/lib/classNames.cjs +1 -1
- package/dist/lib/classNames.cjs.map +1 -1
- package/dist/lib/classNames.mjs +143 -95
- package/dist/lib/classNames.mjs.map +1 -1
- package/dist/lib/events.cjs +1 -1
- package/dist/lib/events.cjs.map +1 -1
- package/dist/lib/events.mjs +35 -8
- package/dist/lib/events.mjs.map +1 -1
- package/dist/lib/icons.cjs +1 -1
- package/dist/lib/icons.cjs.map +1 -1
- package/dist/lib/icons.mjs +34 -20
- package/dist/lib/icons.mjs.map +1 -1
- package/dist/lib/initials.cjs +2 -0
- package/dist/lib/initials.cjs.map +1 -0
- package/dist/lib/initials.mjs +21 -0
- package/dist/lib/initials.mjs.map +1 -0
- package/dist/lib/table.cjs +2 -0
- package/dist/lib/table.cjs.map +1 -0
- package/dist/lib/table.mjs +16 -0
- package/dist/lib/table.mjs.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/tokens.css +102 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Carousel.mjs","names":["useId","useId$1","React","DEFAULT_PAUSE_LABEL","DEFAULT_PLAY_LABEL","DEFAULT_PREVIOUS_LABEL","DEFAULT_NEXT_LABEL","DEFAULT_PICKER_LABEL","defaultSlideLabel","index","total","DEFAULT_CAROUSEL_ROLE_DESCRIPTION","DEFAULT_SLIDE_ROLE_DESCRIPTION","clampIndex","isRotationControl","target","controlButton","focusRing","disabledStyles","PauseGlyph","PlayGlyph","CarouselRoot","controlledValue","rest","storedIndex","setActiveIndex","useControllable","defaultValue","onValueChange","trackId","rootEl","setRootEl","rootRef","useMergedRefs","ref","renderedDir","useDirection","dir","prefersReducedMotion","usePrefersReducedMotion","userPaused","setUserPaused","endedAt","setEndedAt","hovered","setHovered","pointerOnControl","setPointerOnControl","focusWithin","setFocusWithin","startedFromControl","setStartedFromControl","items","droppedChildren","child","flattenChildren","children","isElementOfType","CarouselItem","slotRendersContent","warnOnce","atStart","atEnd","prevDisabled","loop","nextDisabled","ended","stopped","hasRotation","autoPlay","rotating","goTo","goPrev","goNext","advance","useEventCallback","current","prev","id","autoPlayInterval","toggleRotation","rootHandlers","composeEventHandlers","onMouseEnter","onMouseLeave","onFocus","from","event","entering","onBlur","next","cn","carouselClassNames","className","offset","chevronClass","pauseLabel","autoPlayLabels","playLabel","previousLabel","labels","nextLabel","pickerLabel","slideLabel","carouselRoleDescription","slideRoleDescription","jsx","active","i","node","key","focusableDisabledProps","preventIfDisabled","ChevronLeftIcon","ChevronRightIcon","forcedColors","carouselItemClassNames","Carousel"],"sources":["../../../src/components/layout/Carousel.tsx"],"sourcesContent":["import * as React from 'react';\nimport { carouselClassNames, carouselItemClassNames } from '../../lib/classNames';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { slotRendersContent } from '../../lib/slot';\nimport { focusableDisabledProps, preventIfDisabled } from '../../lib/aria';\nimport { disabledStyles, focusRing, forcedColors } from '../../lib/styles';\nimport { ChevronLeftIcon, ChevronRightIcon } from '../../lib/icons';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useDirection } from '../../hooks/useDirection';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePrefersReducedMotion } from '../../hooks/usePrefersReducedMotion';\n\n/** Accessible names of the rotation control shown while `autoPlay` is on. */\nexport interface CarouselAutoPlayLabels {\n /** Name of the control while slides rotate (activating it stops the rotation).\n * @default 'Pause slide rotation'\n */\n pause?: string;\n /** Name of the control while rotation is stopped (activating it starts the rotation).\n * @default 'Start slide rotation'\n */\n play?: string;\n}\n\n/**\n * Accessible names of the Carousel's built-in controls and slides, and the role descriptions of\n * the carousel and its slides, for localization. Each member is optional and falls back to its\n * English default. The rotation control has its own `autoPlayLabels`; the region's name comes\n * from `aria-label` or `aria-labelledby`.\n */\nexport interface CarouselLabels {\n /** Name of the Previous button.\n * @default 'Previous slide'\n */\n previous?: string;\n /** Name of the Next button.\n * @default 'Next slide'\n */\n next?: string;\n /** Name of the group that holds the slide picker buttons.\n * @default 'Choose slide'\n */\n picker?: string;\n /**\n * Name of the slide at `index` (zero-based, like `value`) out of `total` slides. It names the\n * slide itself and its picker button, and is announced by the live region when that slide is\n * shown.\n * @default (index, total) => `Slide ${index + 1} of ${total}`\n */\n slide?: (index: number, total: number) => string;\n /** How assistive technology announces the carousel region (`aria-roledescription`).\n * @default 'carousel'\n */\n carouselRoleDescription?: string;\n /** How assistive technology announces each slide (`aria-roledescription`).\n * @default 'slide'\n */\n slideRoleDescription?: string;\n}\n\n/** Properties for the Carousel component. */\nexport interface CarouselProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Controlled index of the currently active slide. Out-of-range values show the nearest slide. */\n value?: number;\n /** Default active slide index for uncontrolled usage.\n * @default 0\n */\n defaultValue?: number;\n /** Called with the new index when the active slide changes (not when it stays the same). */\n onValueChange?: (index: number) => void;\n /**\n * Rotates the slides automatically. A Pause/Start control is rendered as the first focusable\n * element. Rotation pauses while focus is anywhere inside the carousel (the control included;\n * clicking a control also moves focus there in most browsers) or the pointer is over it (except\n * over the control), and resumes when they leave, unless rotation is stopped. Activating Start\n * rotates at once, also while focus stays on the control; moving focus on to other content\n * pauses again. It starts stopped when the user prefers reduced motion. Without `loop`, rotation\n * ends at the last slide: the control shows Start, and rotation stays stopped (also after the\n * user moves back to an earlier slide) until Start is activated, which continues from the shown\n * slide, or from the first one while the last is shown. The end is tied to its cause: when the\n * number of slides changes (slides loaded later) or `loop` is turned on, rotation continues on\n * its own, unless the user stopped it with Pause.\n * @default false\n */\n autoPlay?: boolean;\n /** Interval in milliseconds between auto-play transitions.\n * @default 5000\n */\n autoPlayInterval?: number;\n /** Accessible names of the rotation control. */\n autoPlayLabels?: CarouselAutoPlayLabels;\n /**\n * Accessible names of the Previous and Next buttons, the slide picker and the slides (also\n * announced by the live region), and the role descriptions of the carousel and its slides, for\n * localization. Unset members keep their English defaults.\n */\n labels?: CarouselLabels;\n /** Whether the carousel loops back to the first slide after the last.\n * @default false\n */\n loop?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the CarouselItem sub-component. */\nexport interface CarouselItemProps extends React.HTMLAttributes<HTMLDivElement> {\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst DEFAULT_PAUSE_LABEL = 'Pause slide rotation';\nconst DEFAULT_PLAY_LABEL = 'Start slide rotation';\nconst DEFAULT_PREVIOUS_LABEL = 'Previous slide';\nconst DEFAULT_NEXT_LABEL = 'Next slide';\nconst DEFAULT_PICKER_LABEL = 'Choose slide';\nconst defaultSlideLabel = (index: number, total: number) => `Slide ${index + 1} of ${total}`;\nconst DEFAULT_CAROUSEL_ROLE_DESCRIPTION = 'carousel';\nconst DEFAULT_SLIDE_ROLE_DESCRIPTION = 'slide';\n\nfunction clampIndex(index: number, total: number): number {\n if (total <= 0 || !Number.isFinite(index)) return 0;\n return Math.min(Math.max(Math.trunc(index), 0), total - 1);\n}\n\nfunction isRotationControl(target: EventTarget | null): boolean {\n return target instanceof Element && target.closest('[data-carousel-rotation]') !== null;\n}\n\nconst controlButton = [\n 'absolute z-10 inline-flex h-8 w-8 items-center justify-center rounded-full border border-border bg-background text-foreground shadow-2',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n focusRing,\n disabledStyles,\n].join(' ');\n\nconst PauseGlyph = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"3\" width=\"3\" height=\"10\" rx=\"1\" />\n <rect x=\"9\" y=\"3\" width=\"3\" height=\"10\" rx=\"1\" />\n </svg>\n);\n\nconst PlayGlyph = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M5 3.5v9a.5.5 0 0 0 .77.42l7-4.5a.5.5 0 0 0 0-.84l-7-4.5A.5.5 0 0 0 5 3.5Z\" />\n </svg>\n);\n\n// The Carousel root, documented on the exported `Carousel` const.\nconst CarouselRoot = ({\n value: controlledValue,\n defaultValue = 0,\n onValueChange,\n autoPlay = false,\n autoPlayInterval = 5000,\n autoPlayLabels,\n labels,\n loop = false,\n className,\n children,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: CarouselProps) => {\n const [storedIndex, setActiveIndex] = useControllable(\n controlledValue,\n defaultValue,\n onValueChange,\n );\n const trackId = useId('carousel-slides');\n const [rootEl, setRootEl] = React.useState<HTMLDivElement | null>(null);\n const rootRef = useMergedRefs<HTMLDivElement>(ref, setRootEl);\n // The direction that applies to the rendered root (its own or an ancestor's `dir`, e.g. an RTL\n // section inside an LTR WaveProvider); before mount and on the server, the provider's/document's.\n const renderedDir = useDirection(rootEl);\n const dir = rest.dir === 'rtl' || rest.dir === 'ltr' ? rest.dir : renderedDir;\n const prefersReducedMotion = usePrefersReducedMotion();\n\n // Rotation state: stopped or not (the user's choice, stopped by default under reduced motion, or\n // ended at the last slide without loop) and the temporary pauses while the pointer is over the\n // content or focus is inside. An explicit Start overrides the focus pause while focus stays on\n // the rotation control (APG `hasUserActivatedPlay`), so pressing Start visibly starts the\n // rotation.\n const [userPaused, setUserPaused] = React.useState<boolean | null>(null);\n // The slide count at which rotation ended at the last slide (null while it has not ended), kept\n // apart from the user's choice so the end lasts only while its cause does.\n const [endedAt, setEndedAt] = React.useState<number | null>(null);\n const [hovered, setHovered] = React.useState(false);\n const [pointerOnControl, setPointerOnControl] = React.useState(false);\n const [focusWithin, setFocusWithin] = React.useState(false);\n const [startedFromControl, setStartedFromControl] = React.useState(false);\n\n // Slides are the `CarouselItem` children, Fragments flattened; the element type is unwrapped, so\n // slides written in a Server Component (lazy client references) count too (C-COMPOUND).\n const items: Array<{ key: string; node: React.ReactNode }> = [];\n let droppedChildren = false;\n for (const child of flattenChildren(children)) {\n if (isElementOfType(child.node, CarouselItem)) items.push(child);\n else if (slotRendersContent(child.node)) droppedChildren = true;\n }\n const total = items.length;\n\n React.useEffect(() => {\n if (droppedChildren) {\n warnOnce(\n 'Carousel:non-item-children',\n 'Carousel: only `Carousel.Item` (`CarouselItem`) children are slides, directly or in ' +\n 'Fragments; other children are not rendered. A component that renders `Carousel.Item` ' +\n 'itself is not recognised: render the `Carousel.Item` in the Carousel and put the ' +\n 'component inside it.',\n );\n }\n }, [droppedChildren]);\n\n // Derived during render (C-HOOKS): removed slides or an out-of-range value show the nearest one.\n const index = clampIndex(storedIndex, total);\n const atStart = index <= 0;\n const atEnd = index >= total - 1;\n const prevDisabled = total <= 1 || (!loop && atStart);\n const nextDisabled = total <= 1 || (!loop && atEnd);\n\n // Without loop, rotation ends at the last slide (however it got there) and stays stopped: moving\n // back to an earlier slide does not restart it, only Start does. The end applies to the slide\n // count it happened at: once slides are added or removed, or loop is turned on, it is dropped\n // and rotation continues unless the user stopped it (adjusting state during render, C-HOOKS).\n const ended = endedAt === total && !loop;\n const stopped = (userPaused ?? prefersReducedMotion) || ended;\n const hasRotation = autoPlay && total > 1;\n if (hasRotation && !loop && atEnd && !stopped) setEndedAt(total);\n else if (endedAt !== null && !ended) setEndedAt(null);\n const pausedByPointer = hovered && !pointerOnControl;\n const pausedByFocus = focusWithin && !startedFromControl;\n const rotating = hasRotation && !stopped && !pausedByPointer && !pausedByFocus;\n\n // Compares with the shown (clamped) index, so re-picking the visible slide reports nothing.\n const goTo = (target: number) => {\n if (target >= 0 && target < total && target !== index) setActiveIndex(target);\n };\n const goPrev = () => goTo(atStart ? total - 1 : index - 1);\n const goNext = () => goTo(atEnd ? 0 : index + 1);\n\n // Reads the latest index at tick time (the updater's base), so the interval does not restart on\n // every slide or parent render and consecutive ticks chain even before a re-render.\n const advance = useEventCallback(() => {\n setActiveIndex((prev) => {\n const current = clampIndex(prev, total);\n if (current < total - 1) return current + 1;\n return loop ? 0 : prev;\n });\n });\n\n React.useEffect(() => {\n if (!rotating) return;\n const id = setInterval(advance, autoPlayInterval);\n return () => clearInterval(id);\n }, [rotating, autoPlayInterval, advance]);\n\n const toggleRotation = () => {\n if (stopped) {\n // Start: from the first slide when rotation had ended at the last one.\n if (!loop && atEnd) goTo(0);\n setEndedAt(null);\n setUserPaused(false);\n setStartedFromControl(true);\n } else {\n setUserPaused(true);\n setStartedFromControl(false);\n }\n };\n\n // The consumer's pointer and focus handlers composed with the pause tracking (C-COMPOSE). The\n // empty root gets them too: the consumer's handlers still run, and a pointer or focus that leaves\n // while there are no slides (slides being reloaded) does not keep rotation paused afterwards.\n const rootHandlers = {\n onMouseEnter: composeEventHandlers(onMouseEnter, () => setHovered(true)),\n onMouseLeave: composeEventHandlers(onMouseLeave, () => setHovered(false)),\n onFocus: composeEventHandlers(onFocus, (event: React.FocusEvent<HTMLDivElement>) => {\n // Any focus inside pauses (APG), the rotation control included. Focus that enters from\n // outside or moves on to other content ends the exemption of an explicit Start.\n const from = event.relatedTarget;\n const entering = !(from instanceof Node && event.currentTarget.contains(from));\n setFocusWithin(true);\n if (entering || !isRotationControl(event.target)) setStartedFromControl(false);\n }),\n onBlur: composeEventHandlers(onBlur, (event: React.FocusEvent<HTMLDivElement>) => {\n const next = event.relatedTarget;\n if (!(next instanceof Node && event.currentTarget.contains(next))) {\n setFocusWithin(false);\n setStartedFromControl(false);\n }\n }),\n };\n\n if (total === 0) {\n return (\n <div\n ref={rootRef}\n className={cn(carouselClassNames.root, 'relative', className)}\n {...rootHandlers}\n {...rest}\n />\n );\n }\n\n const offset = (dir === 'rtl' ? 1 : -1) * index * 100;\n // The chevrons mirror by the same resolved direction as the track. A CSS `rtl:` variant would\n // also match `[dir=rtl] *`, so an LTR carousel inside an RTL ancestor got mirrored chevrons.\n const chevronClass = dir === 'rtl' ? '-scale-x-100' : undefined;\n const pauseLabel = autoPlayLabels?.pause ?? DEFAULT_PAUSE_LABEL;\n const playLabel = autoPlayLabels?.play ?? DEFAULT_PLAY_LABEL;\n const previousLabel = labels?.previous ?? DEFAULT_PREVIOUS_LABEL;\n const nextLabel = labels?.next ?? DEFAULT_NEXT_LABEL;\n const pickerLabel = labels?.picker ?? DEFAULT_PICKER_LABEL;\n const slideLabel = labels?.slide ?? defaultSlideLabel;\n const carouselRoleDescription =\n labels?.carouselRoleDescription ?? DEFAULT_CAROUSEL_ROLE_DESCRIPTION;\n const slideRoleDescription = labels?.slideRoleDescription ?? DEFAULT_SLIDE_ROLE_DESCRIPTION;\n\n return (\n <div\n ref={rootRef}\n role=\"region\"\n aria-roledescription={carouselRoleDescription}\n aria-label=\"Carousel\"\n // A stacking context of its own: the controls' z-index cannot lift them over page headers.\n className={cn(carouselClassNames.root, 'relative isolate overflow-hidden', className)}\n {...rootHandlers}\n {...rest}\n >\n {hasRotation && (\n <button\n type=\"button\"\n data-carousel-rotation=\"\"\n aria-label={stopped ? playLabel : pauseLabel}\n aria-controls={trackId}\n onClick={toggleRotation}\n // The pointer over the control does not pause (APG): the user is operating it.\n onMouseEnter={() => setPointerOnControl(true)}\n onMouseLeave={() => setPointerOnControl(false)}\n className={cn(carouselClassNames.autoPlayButton, controlButton, 'top-2 start-2')}\n >\n {stopped ? <PlayGlyph /> : <PauseGlyph />}\n </button>\n )}\n <div\n id={trackId}\n className={cn(\n carouselClassNames.track,\n 'flex transition-transform duration-300 ease-in-out motion-reduce:transition-none',\n )}\n style={{ transform: `translateX(${offset}%)` }}\n >\n {items.map(({ key, node }, i) => {\n const active = i === index;\n return (\n <div\n key={key}\n role=\"group\"\n aria-roledescription={slideRoleDescription}\n aria-label={slideLabel(i, total)}\n aria-hidden={active ? undefined : true}\n inert={!active}\n className={cn(carouselClassNames.slide, 'w-full shrink-0')}\n >\n {node}\n </div>\n );\n })}\n </div>\n {/* Announces the current slide, except while slides rotate on their own. */}\n <div aria-live={rotating ? 'off' : 'polite'} aria-atomic=\"true\" className=\"sr-only\">\n {slideLabel(index, total)}\n </div>\n <button\n type=\"button\"\n aria-label={previousLabel}\n aria-controls={trackId}\n {...focusableDisabledProps(prevDisabled)}\n onClick={preventIfDisabled(prevDisabled, goPrev)}\n className={cn(\n carouselClassNames.previousButton,\n controlButton,\n 'top-1/2 start-2 -translate-y-1/2',\n )}\n >\n <ChevronLeftIcon size={16} className={chevronClass} />\n </button>\n <button\n type=\"button\"\n aria-label={nextLabel}\n aria-controls={trackId}\n {...focusableDisabledProps(nextDisabled)}\n onClick={preventIfDisabled(nextDisabled, goNext)}\n className={cn(\n carouselClassNames.nextButton,\n controlButton,\n 'top-1/2 end-2 -translate-y-1/2',\n )}\n >\n <ChevronRightIcon size={16} className={chevronClass} />\n </button>\n <div\n role=\"group\"\n aria-label={pickerLabel}\n className={cn(\n carouselClassNames.picker,\n 'absolute inset-x-0 bottom-1 z-10 mx-auto flex w-fit',\n )}\n >\n {items.map(({ key }, i) => {\n const active = i === index;\n return (\n <button\n key={key}\n type=\"button\"\n aria-label={slideLabel(i, total)}\n aria-current={active ? 'true' : undefined}\n onClick={() => goTo(i)}\n className={cn(\n carouselClassNames.pickerButton,\n 'group inline-flex h-6 min-w-6 items-center justify-center',\n focusRing,\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n carouselClassNames.pickerIndicator,\n 'block h-2 rounded-full transition-[width,background-color] duration-200 motion-reduce:transition-none',\n active\n ? cn('w-5 bg-primary', forcedColors.selectedLeaf)\n : 'w-2 bg-stroke-accessible group-hover:bg-foreground forced-colors:bg-[ButtonText] forced-colors:forced-color-adjust-none',\n )}\n />\n </button>\n );\n })}\n </div>\n </div>\n );\n};\nCarouselRoot.displayName = 'Carousel';\n\n/**\n * One slide of a {@link Carousel}. Write it in the Carousel, directly or in a Fragment: a component\n * that renders `Carousel.Item` itself is not recognised as a slide (put that component inside the\n * `Carousel.Item` instead).\n */\nexport const CarouselItem = ({ className, children, ref, ...rest }: CarouselItemProps) => {\n return (\n <div ref={ref} className={cn(carouselItemClassNames.root, 'p-4', className)} {...rest}>\n {children}\n </div>\n );\n};\nCarouselItem.displayName = 'CarouselItem';\n\n/**\n * A slideshow that shows one slide at a time (WAI-ARIA APG carousel with previous/next buttons\n * and a slide picker).\n *\n * - Slides are the `Carousel.Item` (`CarouselItem`) children, written directly in the Carousel or\n * in Fragments. Other children are not rendered (a development warning says so). A component\n * that renders `Carousel.Item` itself is not recognised: write the `Carousel.Item` in the\n * Carousel and put the component inside it.\n * - Previous/Next stay focusable at the ends (`aria-disabled`), so keyboard focus is not lost.\n * - The slide picker is a group of buttons named \"Slide n of m\"; the active one has\n * `aria-current=\"true\"`.\n * - Inactive slides are `aria-hidden` and `inert`, so neither Tab nor a screen reader reaches\n * their content.\n * - With `autoPlay`, a Pause/Start control comes first (WAI-ARIA APG): rotation pauses while\n * focus is inside the carousel (in most browsers also after a click on one of its controls) or\n * the pointer is over its content, activating Start rotates at once, and the live region is\n * silent (`aria-live=\"off\"`) while slides rotate. Without `loop` rotation ends at the last slide\n * and stays stopped until the control's Start is activated (or the number of slides changes, or\n * `loop` is turned on).\n * - Right-to-left layouts slide the other way and mirror the Previous/Next chevrons: the direction\n * is read from the rendered element (its `dir` prop, the nearest ancestor's `dir`, WaveProvider\n * `dir` or the document's), so an LTR section inside an RTL page stays LTR throughout.\n * - Name the carousel with `aria-label` or `aria-labelledby` (the fallback name is \"Carousel\").\n * The built-in names and role descriptions are English: `labels` and `autoPlayLabels`\n * translate them.\n * - The controls are layered over the slides inside the carousel's own stacking context, so they\n * never paint over page headers that stay in view while the page scrolls.\n *\n * Compound access (`Carousel.Item`) needs a client module; React Server Components import the\n * flat name `CarouselItem` instead.\n */\nexport const Carousel = /* @__PURE__ */ Object.assign(CarouselRoot, {\n Item: CarouselItem,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Carousel.mjs","names":["useId","useId$1","React","DEFAULT_PAUSE_LABEL","DEFAULT_PLAY_LABEL","DEFAULT_PREVIOUS_LABEL","DEFAULT_NEXT_LABEL","DEFAULT_PICKER_LABEL","defaultSlideLabel","index","total","DEFAULT_CAROUSEL_ROLE_DESCRIPTION","DEFAULT_SLIDE_ROLE_DESCRIPTION","defaultSlidesLabel","start","end","useAutoPageSize","subscribe","enabled","root","observer","notify","slide","perPage","slideWidth","rootWidth","isRotationControl","target","thumbnailSlot","thumbnail","PauseGlyph","PlayGlyph","CarouselRoot","controlledValue","rest","storedIndex","setActiveIndex","useControllable","defaultValue","onValueChange","trackId","rootEl","setRootEl","rootRef","useMergedRefs","ref","renderedDir","useDirection","dir","prefersReducedMotion","usePrefersReducedMotion","firstSlideEl","setFirstSlideEl","trackEl","setTrackEl","viewportEl","setViewportEl","auto","groupSize","measured","size","userPaused","setUserPaused","endedAt","setEndedAt","hovered","setHovered","pointerOnControl","setPointerOnControl","focusWithin","setFocusWithin","startedFromControl","setStartedFromControl","items","customButtons","droppedChildren","child","flattenChildren","children","isElementOfType","CarouselItem","CarouselButton","direction","slotRendersContent","hasThumbnails","item","warnOnce","clampToPage","pages","pageCount","lastStart","lastPageStart","atStart","atEnd","prevDisabled","loop","nextDisabled","ended","stopped","hasRotation","autoPlay","drag","useCarouselDrag","draggable","delta","goTo","pausedByPointer","rotating","goPrev","goNext","advance","useEventCallback","current","prev","id","autoPlayInterval","toggleRotation","rootHandlers","composeEventHandlers","onMouseEnter","onMouseLeave","onFocus","from","event","entering","onBlur","next","grouped","pageEnd","visibleValues","k","roving","useRovingTabIndex","trackRef","pendingFocus","pending","handleTrackKeyDown","slideIndex","intent","getArrowIntent","previousLabel","labels","nextLabel","goPrevious","goToNext","context","controlsLayout","appearance","cn","carouselClassNames","className","sign","transform","leftover","alignShift","align","slidesLabel","pageLabel","slideLabel","chevronClass","pauseLabel","autoPlayLabels","playLabel","pickerLabel","carouselRoleDescription","slideRoleDescription","inline","layoutClasses","CAROUSEL_CONTROL_LAYOUT","previousControl","focusableDisabledProps","preventIfDisabled","CAROUSEL_CONTROL_BASE","ChevronLeftIcon","nextControl","ChevronRightIcon","viewport","active","i","node","key","CarouselContext","jsx","page","focusRing","forcedColors","renderSlot","carouselItemClassNames","_thumbnail","Carousel"],"sources":["../../../src/components/layout/Carousel.tsx"],"sourcesContent":["import * as React from 'react';\nimport { carouselClassNames, carouselItemClassNames } from '../../lib/classNames';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { getArrowIntent } from '../../lib/direction';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { Slot } from '../../lib/types';\nimport { focusableDisabledProps, preventIfDisabled } from '../../lib/aria';\nimport { focusRing, forcedColors } from '../../lib/styles';\nimport { ChevronLeftIcon, ChevronRightIcon } from '../../lib/icons';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useDirection } from '../../hooks/useDirection';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePrefersReducedMotion } from '../../hooks/usePrefersReducedMotion';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { CarouselButton } from './Carousel.button';\nimport { CarouselContext } from './Carousel.context';\nimport type { CarouselContextValue, CarouselControlsLayout } from './Carousel.context';\nimport { useCarouselDrag } from './Carousel.drag';\nimport { clampToPage, lastPageStart, pageCount } from './Carousel.groups';\nimport { CAROUSEL_CONTROL_BASE, CAROUSEL_CONTROL_LAYOUT } from './Carousel.styles';\n\nexport type { CarouselControlsLayout };\n\n/** How a Carousel is drawn: `flat`, or `elevated` with rounded corners and a shadow. */\nexport type CarouselAppearance = 'flat' | 'elevated';\n\n/** Accessible names of the rotation control shown while `autoPlay` is on. */\nexport interface CarouselAutoPlayLabels {\n /** Name of the control while slides rotate (activating it stops the rotation).\n * @default 'Pause slide rotation'\n */\n pause?: string;\n /** Name of the control while rotation is stopped (activating it starts the rotation).\n * @default 'Start slide rotation'\n */\n play?: string;\n}\n\n/**\n * Accessible names of the Carousel's built-in controls and slides, and the role descriptions of\n * the carousel and its slides, for localization. Each member is optional and falls back to its\n * English default. The rotation control has its own `autoPlayLabels`; the region's name comes\n * from `aria-label` or `aria-labelledby`.\n */\nexport interface CarouselLabels {\n /** Name of the Previous button.\n * @default 'Previous slide'\n */\n previous?: string;\n /** Name of the Next button.\n * @default 'Next slide'\n */\n next?: string;\n /** Name of the group that holds the slide picker buttons.\n * @default 'Choose slide'\n */\n picker?: string;\n /**\n * Name of the slide at `index` (zero-based, like `value`) out of `total` slides. It names the\n * slide itself and its picker button, and is announced by the live region when that slide is\n * shown.\n * @default (index, total) => `Slide ${index + 1} of ${total}`\n */\n slide?: (index: number, total: number) => string;\n /**\n * Name of a page of several slides, from the one-based number of its first and last slide, out\n * of `total` slides (`groupSize` above 1). It names the page's picker button and is announced\n * by the live region when the page is shown. A page of one slide uses `slide`.\n * @default (start, end, total) => `Slides ${start} to ${end} of ${total}`\n */\n slides?: (start: number, end: number, total: number) => string;\n /** How assistive technology announces the carousel region (`aria-roledescription`).\n * @default 'carousel'\n */\n carouselRoleDescription?: string;\n /** How assistive technology announces each slide (`aria-roledescription`).\n * @default 'slide'\n */\n slideRoleDescription?: string;\n}\n\n/** Properties for the Carousel component. */\nexport interface CarouselProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Controlled index of the active slide: with `groupSize` above 1, the first slide of the shown\n * page. A value in the middle of a page shows that page and out-of-range values show the\n * nearest one.\n */\n value?: number;\n /** Default active slide index for uncontrolled usage.\n * @default 0\n */\n defaultValue?: number;\n /**\n * Called with the new index when the active slide changes (not when it stays the same): the\n * first slide of the new page when `groupSize` is above 1.\n */\n onValueChange?: (index: number) => void;\n /**\n * How many slides one page shows: a number, or `'auto'` to show as many as fit the width of the\n * carousel (the slides keep their own width, which must be equal). Previous, Next, the picker\n * (one button per page), looping and autoplay move by page, and the slides of the shown page\n * form one arrow-key focus group. With `1` each slide fills the width, as before.\n * @default 1\n */\n groupSize?: number | 'auto';\n /**\n * With `groupSize=\"auto\"`, where the shown page sits when its slides do not fill the width.\n * @default 'start'\n */\n align?: 'start' | 'center' | 'end';\n /**\n * Lets the pointer drag the slides (mouse, touch and pen). The track follows the pointer and,\n * on release, the page changes when the drag passed a quarter of the width or left fast, else\n * it snaps back; the direction follows the carousel's. The click that ends a drag is not\n * delivered to the slide, and a vertical swipe still scrolls the page. Dragging pauses\n * autoplay like the pointer over the carousel does. The buttons and the keyboard stay the way\n * to operate the carousel without a pointer.\n * @default false\n */\n draggable?: boolean;\n /**\n * Where the Previous and Next buttons go. `overlay` floats round buttons over the slides;\n * `overlay-wide` makes them full-height strips at the edges; `inline` puts them in a row with\n * the slides, outside them; `inline-wide` is `inline` with full-height buttons. The rotation\n * control stays the first focusable element at the start corner in every layout.\n * @default 'overlay'\n */\n controlsLayout?: CarouselControlsLayout;\n /**\n * `elevated` rounds the corners and adds a shadow.\n * @default 'flat'\n */\n appearance?: CarouselAppearance;\n /**\n * Rotates the slides automatically. A Pause/Start control is rendered as the first focusable\n * element. Rotation pauses while focus is anywhere inside the carousel (the control included;\n * clicking a control also moves focus there in most browsers) or the pointer is over it (except\n * over the control), and resumes when they leave, unless rotation is stopped. Activating Start\n * rotates at once, also while focus stays on the control; moving focus on to other content\n * pauses again. It starts stopped when the user prefers reduced motion. Without `loop`, rotation\n * ends at the last slide: the control shows Start, and rotation stays stopped (also after the\n * user moves back to an earlier slide) until Start is activated, which continues from the shown\n * slide, or from the first one while the last is shown. The end is tied to its cause: when the\n * number of slides changes (slides loaded later) or `loop` is turned on, rotation continues on\n * its own, unless the user stopped it with Pause.\n * @default false\n */\n autoPlay?: boolean;\n /** Interval in milliseconds between auto-play transitions.\n * @default 5000\n */\n autoPlayInterval?: number;\n /** Accessible names of the rotation control. */\n autoPlayLabels?: CarouselAutoPlayLabels;\n /**\n * Accessible names of the Previous and Next buttons, the slide picker and the slides (also\n * announced by the live region), and the role descriptions of the carousel and its slides, for\n * localization. Unset members keep their English defaults.\n */\n labels?: CarouselLabels;\n /** Whether the carousel loops back to the first slide after the last.\n * @default false\n */\n loop?: boolean;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the CarouselItem sub-component. */\nexport interface CarouselItemProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * An image for this slide's button in the picker, in place of the dot. A string is the image\n * `src`; an object sets the `<img>`'s attributes. The button keeps its slide-label name, so the\n * image is decorative (`alt=\"\"`). When any slide has one, the picker becomes a row of\n * thumbnails below the slides; a slide without one keeps its dot. With `groupSize` above 1, a\n * page shows the thumbnail of its first slide.\n */\n thumbnail?: Slot<'img'>;\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst DEFAULT_PAUSE_LABEL = 'Pause slide rotation';\nconst DEFAULT_PLAY_LABEL = 'Start slide rotation';\nconst DEFAULT_PREVIOUS_LABEL = 'Previous slide';\nconst DEFAULT_NEXT_LABEL = 'Next slide';\nconst DEFAULT_PICKER_LABEL = 'Choose slide';\nconst defaultSlideLabel = (index: number, total: number) => `Slide ${index + 1} of ${total}`;\nconst DEFAULT_CAROUSEL_ROLE_DESCRIPTION = 'carousel';\nconst DEFAULT_SLIDE_ROLE_DESCRIPTION = 'slide';\n\nconst defaultSlidesLabel = (start: number, end: number, total: number) =>\n `Slides ${start} to ${end} of ${total}`;\n\n/**\n * With `groupSize=\"auto\"`: how many slides fit the width of the carousel, from the width of the\n * first slide, and the two widths. A snapshot string (`perPage:slideWidth:rootWidth`) so that\n * `useSyncExternalStore` compares it by value; one slide per page before anything is measured.\n */\nfunction useAutoPageSize(\n enabled: boolean,\n root: HTMLElement | null,\n slide: HTMLElement | null,\n): { perPage: number; slideWidth: number; rootWidth: number } {\n const subscribe = React.useCallback(\n (notify: () => void) => {\n if (!enabled || !root || typeof ResizeObserver === 'undefined') return () => {};\n const observer = new ResizeObserver(notify);\n observer.observe(root);\n if (slide) observer.observe(slide);\n return () => observer.disconnect();\n },\n [enabled, root, slide],\n );\n const getSnapshot = () => {\n if (!enabled || !root || !slide) return '1:0:0';\n const slideWidth = slide.offsetWidth;\n const rootWidth = root.clientWidth;\n const perPage = slideWidth > 0 ? Math.max(1, Math.floor(rootWidth / slideWidth)) : 1;\n return `${perPage}:${slideWidth}:${rootWidth}`;\n };\n const snapshot = React.useSyncExternalStore(subscribe, getSnapshot, () => '1:0:0');\n const [perPage, slideWidth, rootWidth] = snapshot.split(':').map(Number) as [\n number,\n number,\n number,\n ];\n return { perPage, slideWidth, rootWidth };\n}\n\nfunction isRotationControl(target: EventTarget | null): boolean {\n return target instanceof Element && target.closest('[data-carousel-rotation]') !== null;\n}\n\n/** The `<img>` slot of a thumbnail: a string is its `src`. */\nfunction thumbnailSlot(thumbnail: Slot<'img'>): Slot<'img'> {\n return typeof thumbnail === 'string' ? { src: thumbnail } : thumbnail;\n}\n\nconst PauseGlyph = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"3\" width=\"3\" height=\"10\" rx=\"1\" />\n <rect x=\"9\" y=\"3\" width=\"3\" height=\"10\" rx=\"1\" />\n </svg>\n);\n\nconst PlayGlyph = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M5 3.5v9a.5.5 0 0 0 .77.42l7-4.5a.5.5 0 0 0 0-.84l-7-4.5A.5.5 0 0 0 5 3.5Z\" />\n </svg>\n);\n\n// The Carousel root, documented on the exported `Carousel` const.\nconst CarouselRoot = ({\n value: controlledValue,\n defaultValue = 0,\n onValueChange,\n autoPlay = false,\n autoPlayInterval = 5000,\n autoPlayLabels,\n labels,\n loop = false,\n groupSize = 1,\n align = 'start',\n draggable = false,\n controlsLayout = 'overlay',\n appearance = 'flat',\n className,\n children,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ref,\n ...rest\n}: CarouselProps) => {\n const [storedIndex, setActiveIndex] = useControllable(\n controlledValue,\n defaultValue,\n onValueChange,\n );\n const trackId = useId('carousel-slides');\n const [rootEl, setRootEl] = React.useState<HTMLDivElement | null>(null);\n const rootRef = useMergedRefs<HTMLDivElement>(ref, setRootEl);\n // The direction that applies to the rendered root (its own or an ancestor's `dir`, e.g. an RTL\n // section inside an LTR WaveProvider); before mount and on the server, the provider's/document's.\n const renderedDir = useDirection(rootEl);\n const dir = rest.dir === 'rtl' || rest.dir === 'ltr' ? rest.dir : renderedDir;\n const prefersReducedMotion = usePrefersReducedMotion();\n const [firstSlideEl, setFirstSlideEl] = React.useState<HTMLElement | null>(null);\n const [trackEl, setTrackEl] = React.useState<HTMLElement | null>(null);\n const [viewportEl, setViewportEl] = React.useState<HTMLElement | null>(null);\n const auto = groupSize === 'auto';\n const measured = useAutoPageSize(auto, viewportEl, firstSlideEl);\n const size = auto ? measured.perPage : Math.max(1, Math.floor(groupSize) || 1);\n\n // Rotation state: stopped or not (the user's choice, stopped by default under reduced motion, or\n // ended at the last slide without loop) and the temporary pauses while the pointer is over the\n // content or focus is inside. An explicit Start overrides the focus pause while focus stays on\n // the rotation control (APG `hasUserActivatedPlay`), so pressing Start visibly starts the\n // rotation.\n const [userPaused, setUserPaused] = React.useState<boolean | null>(null);\n // The slide count at which rotation ended at the last slide (null while it has not ended), kept\n // apart from the user's choice so the end lasts only while its cause does.\n const [endedAt, setEndedAt] = React.useState<number | null>(null);\n const [hovered, setHovered] = React.useState(false);\n const [pointerOnControl, setPointerOnControl] = React.useState(false);\n const [focusWithin, setFocusWithin] = React.useState(false);\n const [startedFromControl, setStartedFromControl] = React.useState(false);\n\n // Slides are the `CarouselItem` children, Fragments flattened; the element type is unwrapped, so\n // slides written in a Server Component (lazy client references) count too (C-COMPOUND).\n const items: Array<{ key: string; node: React.ReactNode; thumbnail?: Slot<'img'> }> = [];\n // A `Carousel.Button` of each direction replaces the built-in button; a second one of the same\n // direction is not rendered.\n const customButtons: { previous?: React.ReactElement; next?: React.ReactElement } = {};\n let droppedChildren = false;\n for (const child of flattenChildren(children)) {\n if (isElementOfType<CarouselItemProps>(child.node, CarouselItem)) {\n items.push({ ...child, thumbnail: child.node.props.thumbnail });\n } else if (isElementOfType<{ direction?: 'previous' | 'next' }>(child.node, CarouselButton)) {\n const direction = child.node.props.direction === 'next' ? 'next' : 'previous';\n if (customButtons[direction]) droppedChildren = true;\n else customButtons[direction] = React.cloneElement(child.node, { key: child.key });\n } else if (slotRendersContent(child.node)) droppedChildren = true;\n }\n const hasThumbnails = items.some((item) => item.thumbnail !== undefined);\n const total = items.length;\n\n React.useEffect(() => {\n if (droppedChildren) {\n warnOnce(\n 'Carousel:non-item-children',\n 'Carousel: only `Carousel.Item` (`CarouselItem`) children are slides, directly or in ' +\n 'Fragments; other children are not rendered. A component that renders `Carousel.Item` ' +\n 'itself is not recognised: render the `Carousel.Item` in the Carousel and put the ' +\n 'component inside it.',\n );\n }\n }, [droppedChildren]);\n\n // Derived during render (C-HOOKS): removed slides or an out-of-range value show the nearest one.\n const index = clampToPage(storedIndex, size, total);\n const pages = pageCount(total, size);\n const lastStart = lastPageStart(total, size);\n const atStart = index <= 0;\n const atEnd = index >= lastStart;\n const prevDisabled = pages <= 1 || (!loop && atStart);\n const nextDisabled = pages <= 1 || (!loop && atEnd);\n\n // Without loop, rotation ends at the last slide (however it got there) and stays stopped: moving\n // back to an earlier slide does not restart it, only Start does. The end applies to the slide\n // count it happened at: once slides are added or removed, or loop is turned on, it is dropped\n // and rotation continues unless the user stopped it (adjusting state during render, C-HOOKS).\n const ended = endedAt === total && !loop;\n const stopped = (userPaused ?? prefersReducedMotion) || ended;\n const hasRotation = autoPlay && pages > 1;\n if (hasRotation && !loop && atEnd && !stopped) setEndedAt(total);\n else if (endedAt !== null && !ended) setEndedAt(null);\n // A release moves one page towards the drag; past the ends it only loops with `loop`.\n const drag = useCarouselDrag({\n enabled: draggable && pages > 1,\n dir,\n onCommit: (delta) => {\n if (delta === 1) {\n if (!atEnd) goTo(index + size);\n else if (loop) goTo(0);\n } else if (delta === -1) {\n if (!atStart) goTo(index - size);\n else if (loop) goTo(lastStart);\n }\n },\n });\n const pausedByPointer = (hovered && !pointerOnControl) || drag.dragging;\n const pausedByFocus = focusWithin && !startedFromControl;\n const rotating = hasRotation && !stopped && !pausedByPointer && !pausedByFocus;\n\n // Compares with the shown (clamped) index, so re-picking the visible slide reports nothing.\n const goTo = (target: number) => {\n if (target >= 0 && target < total && target !== index) setActiveIndex(target);\n };\n const goPrev = () => goTo(atStart ? lastStart : index - size);\n const goNext = () => goTo(atEnd ? 0 : index + size);\n\n // Reads the latest index at tick time (the updater's base), so the interval does not restart on\n // every slide or parent render and consecutive ticks chain even before a re-render.\n const advance = useEventCallback(() => {\n setActiveIndex((prev) => {\n const current = clampToPage(prev, size, total);\n if (current < lastStart) return current + size;\n return loop ? 0 : prev;\n });\n });\n\n React.useEffect(() => {\n if (!rotating) return;\n const id = setInterval(advance, autoPlayInterval);\n return () => clearInterval(id);\n }, [rotating, autoPlayInterval, advance]);\n\n const toggleRotation = () => {\n if (stopped) {\n // Start: from the first slide when rotation had ended at the last one.\n if (!loop && atEnd) goTo(0);\n setEndedAt(null);\n setUserPaused(false);\n setStartedFromControl(true);\n } else {\n setUserPaused(true);\n setStartedFromControl(false);\n }\n };\n\n // The consumer's pointer and focus handlers composed with the pause tracking (C-COMPOSE). The\n // empty root gets them too: the consumer's handlers still run, and a pointer or focus that leaves\n // while there are no slides (slides being reloaded) does not keep rotation paused afterwards.\n const rootHandlers = {\n onMouseEnter: composeEventHandlers(onMouseEnter, () => setHovered(true)),\n onMouseLeave: composeEventHandlers(onMouseLeave, () => setHovered(false)),\n onFocus: composeEventHandlers(onFocus, (event: React.FocusEvent<HTMLDivElement>) => {\n // Any focus inside pauses (APG), the rotation control included. Focus that enters from\n // outside or moves on to other content ends the exemption of an explicit Start.\n const from = event.relatedTarget;\n const entering = !(from instanceof Node && event.currentTarget.contains(from));\n setFocusWithin(true);\n if (entering || !isRotationControl(event.target)) setStartedFromControl(false);\n }),\n onBlur: composeEventHandlers(onBlur, (event: React.FocusEvent<HTMLDivElement>) => {\n const next = event.relatedTarget;\n if (!(next instanceof Node && event.currentTarget.contains(next))) {\n setFocusWithin(false);\n setStartedFromControl(false);\n }\n }),\n };\n\n // The slides of the shown page form one arrow-key focus group (groupSize above 1). Only they\n // carry a roving value; the others are inert.\n const grouped = size > 1;\n const pageEnd = Math.min(index + size, total);\n const visibleValues = React.useMemo(\n () => (grouped ? Array.from({ length: pageEnd - index }, (_, k) => String(index + k)) : []),\n [grouped, index, pageEnd],\n );\n const roving = useRovingTabIndex({\n items: visibleValues,\n activeValue: String(index),\n orientation: 'horizontal',\n loop: false,\n dir,\n tabStop: 'last-focused',\n });\n const trackRef = useMergedRefs<HTMLDivElement>(roving.containerProps.ref, setTrackEl);\n // Which slide of the new page takes focus after an arrow past the end of a page.\n const pendingFocus = React.useRef<'first' | 'last' | null>(null);\n React.useLayoutEffect(() => {\n const pending = pendingFocus.current;\n if (!pending || !trackEl) return;\n pendingFocus.current = null;\n const target = pending === 'first' ? index : pageEnd - 1;\n trackEl.querySelector<HTMLElement>(`[data-roving-value=\"${target}\"]`)?.focus();\n }, [index, pageEnd, trackEl]);\n const handleTrackKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n const slideIndex = (event.target as HTMLElement).getAttribute('data-roving-value');\n const intent = getArrowIntent(event.key, { orientation: 'horizontal', dir });\n if (\n slideIndex !== null &&\n intent &&\n !event.defaultPrevented &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n const current = Number(slideIndex);\n if (intent === 'next' && current === pageEnd - 1) {\n event.preventDefault();\n if (!nextDisabled) {\n pendingFocus.current = 'first';\n goNext();\n }\n return;\n }\n if (intent === 'prev' && current === index) {\n event.preventDefault();\n if (!prevDisabled) {\n pendingFocus.current = 'last';\n goPrev();\n }\n return;\n }\n }\n roving.containerProps.onKeyDown(event);\n };\n\n const previousLabel = labels?.previous ?? DEFAULT_PREVIOUS_LABEL;\n const nextLabel = labels?.next ?? DEFAULT_NEXT_LABEL;\n const goPrevious = useEventCallback(() => goPrev());\n const goToNext = useEventCallback(() => goNext());\n // What `Carousel.Button` reads (C-MEMO).\n const context = React.useMemo<CarouselContextValue>(\n () => ({\n trackId,\n previousLabel,\n nextLabel,\n previousDisabled: prevDisabled,\n nextDisabled,\n goPrevious,\n goNext: goToNext,\n controlsLayout,\n dir,\n }),\n [\n trackId,\n previousLabel,\n nextLabel,\n prevDisabled,\n nextDisabled,\n goPrevious,\n goToNext,\n controlsLayout,\n dir,\n ],\n );\n\n if (total === 0) {\n return (\n <div\n ref={rootRef}\n data-controls-layout={controlsLayout}\n data-appearance={appearance}\n className={cn(carouselClassNames.root, 'relative', className)}\n {...rootHandlers}\n {...rest}\n />\n );\n }\n\n const sign = dir === 'rtl' ? 1 : -1;\n // A page is as wide as the carousel: the track moves by pages. With `auto` the slides keep their\n // own width and the track moves by whole slides, in pixels, plus the alignment of the page.\n let transform = `translateX(${sign * (index / size) * 100}%)`;\n if (drag.offsetPx !== 0) {\n transform = `translateX(calc(${sign * (index / size) * 100}% + ${drag.offsetPx}px))`;\n }\n if (auto) {\n const leftover = Math.max(0, measured.rootWidth - size * measured.slideWidth);\n const alignShift = align === 'center' ? leftover / 2 : align === 'end' ? leftover : 0;\n const px = sign * index * measured.slideWidth + (dir === 'rtl' ? -alignShift : alignShift);\n transform = `translateX(${px + drag.offsetPx + 0}px)`;\n }\n const slidesLabel = labels?.slides ?? defaultSlidesLabel;\n /** The name of the page that starts at `start`: its slides, or the one slide it holds. */\n const pageLabel = (start: number) => {\n const end = Math.min(start + size, total);\n return end - start === 1 ? slideLabel(start, total) : slidesLabel(start + 1, end, total);\n };\n // The chevrons mirror by the same resolved direction as the track. A CSS `rtl:` variant would\n // also match `[dir=rtl] *`, so an LTR carousel inside an RTL ancestor got mirrored chevrons.\n const chevronClass = dir === 'rtl' ? '-scale-x-100' : undefined;\n const pauseLabel = autoPlayLabels?.pause ?? DEFAULT_PAUSE_LABEL;\n const playLabel = autoPlayLabels?.play ?? DEFAULT_PLAY_LABEL;\n const pickerLabel = labels?.picker ?? DEFAULT_PICKER_LABEL;\n const slideLabel = labels?.slide ?? defaultSlideLabel;\n const carouselRoleDescription =\n labels?.carouselRoleDescription ?? DEFAULT_CAROUSEL_ROLE_DESCRIPTION;\n const slideRoleDescription = labels?.slideRoleDescription ?? DEFAULT_SLIDE_ROLE_DESCRIPTION;\n\n const inline = controlsLayout === 'inline' || controlsLayout === 'inline-wide';\n const layoutClasses = CAROUSEL_CONTROL_LAYOUT[controlsLayout];\n const previousControl = customButtons.previous ?? (\n <button\n key=\"previous\"\n type=\"button\"\n aria-label={previousLabel}\n aria-controls={trackId}\n {...focusableDisabledProps(prevDisabled)}\n onClick={preventIfDisabled(prevDisabled, goPrev)}\n className={cn(\n carouselClassNames.previousButton,\n CAROUSEL_CONTROL_BASE,\n layoutClasses.previous,\n )}\n >\n <ChevronLeftIcon size={16} className={chevronClass} />\n </button>\n );\n const nextControl = customButtons.next ?? (\n <button\n key=\"next\"\n type=\"button\"\n aria-label={nextLabel}\n aria-controls={trackId}\n {...focusableDisabledProps(nextDisabled)}\n onClick={preventIfDisabled(nextDisabled, goNext)}\n className={cn(carouselClassNames.nextButton, CAROUSEL_CONTROL_BASE, layoutClasses.next)}\n >\n <ChevronRightIcon size={16} className={chevronClass} />\n </button>\n );\n\n const viewport = (\n <div\n ref={setViewportEl}\n className={cn(carouselClassNames.viewport, 'relative min-w-0 flex-1 overflow-hidden')}\n >\n <div\n id={trackId}\n className={cn(\n carouselClassNames.track,\n drag.dragging\n ? 'flex'\n : 'flex transition-transform duration-300 ease-in-out motion-reduce:transition-none',\n // Horizontal pointer moves belong to the drag; a vertical swipe still scrolls the page.\n draggable && 'touch-pan-y',\n )}\n style={{ transform }}\n data-dragging={drag.dragging ? '' : undefined}\n {...drag.handlers}\n {...(grouped ? roving.containerProps : null)}\n ref={grouped ? trackRef : setTrackEl}\n onKeyDown={grouped ? handleTrackKeyDown : undefined}\n >\n {items.map(({ key, node }, i) => {\n const active = i >= index && i < index + size;\n return (\n <div\n key={key}\n ref={i === 0 ? setFirstSlideEl : undefined}\n role=\"group\"\n aria-roledescription={slideRoleDescription}\n aria-label={slideLabel(i, total)}\n aria-hidden={active ? undefined : true}\n inert={!active}\n data-roving-value={grouped && active ? String(i) : undefined}\n tabIndex={grouped && active ? roving.getTabIndex(String(i)) : undefined}\n className={cn(\n carouselClassNames.slide,\n auto ? 'w-auto shrink-0' : size === 1 ? 'w-full shrink-0' : 'shrink-0',\n grouped &&\n 'focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring',\n )}\n style={!auto && size > 1 ? { width: `calc(100% / ${size})` } : undefined}\n >\n {node}\n </div>\n );\n })}\n </div>\n {/* Overlaid on the slides, after them in the tab order, like before the layouts. */}\n {!inline && previousControl}\n {!inline && nextControl}\n </div>\n );\n\n return (\n <CarouselContext.Provider value={context}>\n <div\n ref={rootRef}\n role=\"region\"\n aria-roledescription={carouselRoleDescription}\n aria-label=\"Carousel\"\n data-controls-layout={controlsLayout}\n data-appearance={appearance}\n // A stacking context of its own: the controls' z-index cannot lift them over page headers.\n className={cn(\n carouselClassNames.root,\n 'relative isolate overflow-hidden',\n appearance === 'elevated' && 'rounded-md shadow-4',\n className,\n )}\n {...rootHandlers}\n {...rest}\n >\n {hasRotation && (\n <button\n type=\"button\"\n data-carousel-rotation=\"\"\n aria-label={stopped ? playLabel : pauseLabel}\n aria-controls={trackId}\n onClick={toggleRotation}\n // The pointer over the control does not pause (APG): the user is operating it.\n onMouseEnter={() => setPointerOnControl(true)}\n onMouseLeave={() => setPointerOnControl(false)}\n className={cn(\n carouselClassNames.autoPlayButton,\n CAROUSEL_CONTROL_BASE,\n // Above the edge strips of the wide layouts, which would dim and cover it.\n 'absolute z-20 h-8 w-8 rounded-full border border-border bg-background shadow-2 top-2',\n // Over the viewport's corner: past the Previous button of an inline layout.\n inline ? 'start-12' : 'start-2',\n )}\n >\n {stopped ? <PlayGlyph /> : <PauseGlyph />}\n </button>\n )}\n {inline ? (\n <div className=\"flex items-stretch\">\n {previousControl}\n {viewport}\n {nextControl}\n </div>\n ) : (\n viewport\n )}\n {/* Announces the current slide, except while slides rotate on their own. */}\n <div aria-live={rotating ? 'off' : 'polite'} aria-atomic=\"true\" className=\"sr-only\">\n {pageLabel(index)}\n </div>\n <div\n role=\"group\"\n aria-label={pickerLabel}\n className={cn(\n carouselClassNames.picker,\n hasThumbnails\n ? 'relative mx-auto flex w-fit flex-wrap justify-center gap-2 p-2'\n : 'absolute inset-x-0 bottom-1 z-10 mx-auto flex w-fit',\n )}\n >\n {items\n .filter((_, i) => i % size === 0)\n .map(({ key, thumbnail }, page) => {\n const start = page * size;\n const active = start === index;\n return (\n <button\n key={key}\n type=\"button\"\n aria-label={pageLabel(start)}\n aria-current={active ? 'true' : undefined}\n onClick={() => goTo(start)}\n className={cn(\n carouselClassNames.pickerButton,\n 'group inline-flex items-center justify-center',\n thumbnail !== undefined ? 'rounded-md p-0.5' : 'h-6 min-w-6',\n focusRing,\n )}\n >\n {thumbnail !== undefined ? (\n renderSlot(\n thumbnailSlot(thumbnail),\n 'img',\n cn(\n carouselItemClassNames.thumbnail,\n 'block h-12 w-16 rounded object-cover',\n active\n ? cn('outline-2 outline-primary', forcedColors.selectedContainer)\n : 'opacity-70 group-hover:opacity-100',\n ),\n { alt: '', draggable: false },\n )\n ) : (\n <span\n aria-hidden=\"true\"\n className={cn(\n carouselClassNames.pickerIndicator,\n 'block h-2 rounded-full transition-[width,background-color] duration-200 motion-reduce:transition-none',\n active\n ? cn('w-5 bg-primary', forcedColors.selectedLeaf)\n : 'w-2 bg-stroke-accessible group-hover:bg-foreground forced-colors:bg-[ButtonText] forced-colors:forced-color-adjust-none',\n )}\n />\n )}\n </button>\n );\n })}\n </div>\n </div>\n </CarouselContext.Provider>\n );\n};\nCarouselRoot.displayName = 'Carousel';\n\n/**\n * One slide of a {@link Carousel}. Write it in the Carousel, directly or in a Fragment: a component\n * that renders `Carousel.Item` itself is not recognised as a slide (put that component inside the\n * `Carousel.Item` instead).\n */\nexport const CarouselItem = ({\n thumbnail: _thumbnail,\n className,\n children,\n ref,\n ...rest\n}: CarouselItemProps) => {\n return (\n <div ref={ref} className={cn(carouselItemClassNames.root, 'p-4', className)} {...rest}>\n {children}\n </div>\n );\n};\nCarouselItem.displayName = 'CarouselItem';\n\n/**\n * A slideshow that shows one slide at a time (WAI-ARIA APG carousel with previous/next buttons\n * and a slide picker).\n *\n * - Slides are the `Carousel.Item` (`CarouselItem`) children, written directly in the Carousel or\n * in Fragments. Other children are not rendered (a development warning says so). A component\n * that renders `Carousel.Item` itself is not recognised: write the `Carousel.Item` in the\n * Carousel and put the component inside it.\n * - Previous/Next stay focusable at the ends (`aria-disabled`), so keyboard focus is not lost.\n * - The slide picker is a group of buttons named \"Slide n of m\"; the active one has\n * `aria-current=\"true\"`.\n * - Inactive slides are `aria-hidden` and `inert`, so neither Tab nor a screen reader reaches\n * their content.\n * - With `autoPlay`, a Pause/Start control comes first (WAI-ARIA APG): rotation pauses while\n * focus is inside the carousel (in most browsers also after a click on one of its controls) or\n * the pointer is over its content, activating Start rotates at once, and the live region is\n * silent (`aria-live=\"off\"`) while slides rotate. Without `loop` rotation ends at the last slide\n * and stays stopped until the control's Start is activated (or the number of slides changes, or\n * `loop` is turned on).\n * - Right-to-left layouts slide the other way and mirror the Previous/Next chevrons: the direction\n * is read from the rendered element (its `dir` prop, the nearest ancestor's `dir`, WaveProvider\n * `dir` or the document's), so an LTR section inside an RTL page stays LTR throughout.\n * - Name the carousel with `aria-label` or `aria-labelledby` (the fallback name is \"Carousel\").\n * The built-in names and role descriptions are English: `labels` and `autoPlayLabels`\n * translate them.\n * - The controls are layered over the slides inside the carousel's own stacking context, so they\n * never paint over page headers that stay in view while the page scrolls.\n *\n * - `groupSize` shows several slides per page, `draggable` lets the pointer drag them, and a\n * `thumbnail` on a `Carousel.Item` turns the picker into a row of thumbnails.\n * - `controlsLayout` places the Previous and Next buttons over the slides (`overlay`,\n * `overlay-wide`) or beside them (`inline`, `inline-wide`); `Carousel.Button` replaces the\n * built-in button of its `direction` with one of your own glyph.\n *\n * Compound access (`Carousel.Item`, `Carousel.Button`) needs a client module; React Server\n * Components import the flat names `CarouselItem` and `CarouselButton` instead.\n */\nexport const Carousel = /* @__PURE__ */ Object.assign(CarouselRoot, {\n Item: CarouselItem,\n Button: CarouselButton,\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";const e=require("../../lib/styles.cjs");var t=[`z-10 inline-flex items-center justify-center text-foreground`,`not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed`,e.focusRing,e.disabledStyles].join(` `),n=`h-8 w-8 rounded-full border border-border bg-background shadow-2`,r=`w-10 rounded-none bg-background/70`,i={overlay:{previous:`absolute top-1/2 start-2 -translate-y-1/2 ${n}`,next:`absolute top-1/2 end-2 -translate-y-1/2 ${n}`},"overlay-wide":{previous:`absolute inset-y-0 start-0 ${r}`,next:`absolute inset-y-0 end-0 ${r}`},inline:{previous:`relative mx-1 shrink-0 self-center ${n}`,next:`relative mx-1 shrink-0 self-center ${n}`},"inline-wide":{previous:`relative shrink-0 self-stretch ${r}`,next:`relative shrink-0 self-stretch ${r}`}};exports.CAROUSEL_CONTROL_BASE=t,exports.CAROUSEL_CONTROL_LAYOUT=i;
|
|
2
|
+
//# sourceMappingURL=Carousel.styles.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.styles.cjs","names":["focusRing","disabledStyles","require_styles","CAROUSEL_CONTROL_BASE","ROUND","WIDE","CAROUSEL_CONTROL_LAYOUT"],"sources":["../../../src/components/layout/Carousel.styles.ts"],"sourcesContent":["import { disabledStyles, focusRing } from '../../lib/styles';\nimport type { CarouselControlsLayout } from './Carousel.context';\n\n/**\n * What every Previous/Next button shares, the built-in ones and `Carousel.Button`: the stacking\n * above the slides, the colour, the gated hover and pressed states, the focus ring and the\n * disabled look.\n */\nexport const CAROUSEL_CONTROL_BASE = [\n 'z-10 inline-flex items-center justify-center text-foreground',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n focusRing,\n disabledStyles,\n].join(' ');\n\nconst ROUND = 'h-8 w-8 rounded-full border border-border bg-background shadow-2';\nconst WIDE = 'w-10 rounded-none bg-background/70';\n\n/**\n * Position and shape per layout and direction: round buttons floating over the slides, full-height\n * strips at the edges, or the same two in a row with the slides (inline layouts).\n */\nexport const CAROUSEL_CONTROL_LAYOUT: Record<\n CarouselControlsLayout,\n Record<'previous' | 'next', string>\n> = {\n overlay: {\n previous: `absolute top-1/2 start-2 -translate-y-1/2 ${ROUND}`,\n next: `absolute top-1/2 end-2 -translate-y-1/2 ${ROUND}`,\n },\n 'overlay-wide': {\n previous: `absolute inset-y-0 start-0 ${WIDE}`,\n next: `absolute inset-y-0 end-0 ${WIDE}`,\n },\n inline: {\n previous: `relative mx-1 shrink-0 self-center ${ROUND}`,\n next: `relative mx-1 shrink-0 self-center ${ROUND}`,\n },\n 'inline-wide': {\n previous: `relative shrink-0 self-stretch ${WIDE}`,\n next: `relative shrink-0 self-stretch ${WIDE}`,\n },\n};\n"],"mappings":"qDAQA,IAAaG,EAAwB,CACnC,+DACA,+GACAH,EAAAA,UACAC,EAAAA,cACF,CAAC,CAAC,KAAK,GAAG,EAEJG,EAAQ,mEACRC,EAAO,qCAMAC,EAGT,CACF,QAAS,CACP,SAAU,6CAA6CF,IACvD,KAAM,2CAA2CA,GACnD,EACA,eAAgB,CACd,SAAU,8BAA8BC,IACxC,KAAM,4BAA4BA,GACpC,EACA,OAAQ,CACN,SAAU,sCAAsCD,IAChD,KAAM,sCAAsCA,GAC9C,EACA,cAAe,CACb,SAAU,kCAAkCC,IAC5C,KAAM,kCAAkCA,GAC1C,CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { disabledStyles as e, focusRing as t } from "../../lib/styles.mjs";
|
|
3
|
+
//#region src/components/layout/Carousel.styles.ts
|
|
4
|
+
var n = [
|
|
5
|
+
"z-10 inline-flex items-center justify-center text-foreground",
|
|
6
|
+
"not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed",
|
|
7
|
+
t,
|
|
8
|
+
e
|
|
9
|
+
].join(" "), r = "h-8 w-8 rounded-full border border-border bg-background shadow-2", i = "w-10 rounded-none bg-background/70", a = {
|
|
10
|
+
overlay: {
|
|
11
|
+
previous: `absolute top-1/2 start-2 -translate-y-1/2 ${r}`,
|
|
12
|
+
next: `absolute top-1/2 end-2 -translate-y-1/2 ${r}`
|
|
13
|
+
},
|
|
14
|
+
"overlay-wide": {
|
|
15
|
+
previous: `absolute inset-y-0 start-0 ${i}`,
|
|
16
|
+
next: `absolute inset-y-0 end-0 ${i}`
|
|
17
|
+
},
|
|
18
|
+
inline: {
|
|
19
|
+
previous: `relative mx-1 shrink-0 self-center ${r}`,
|
|
20
|
+
next: `relative mx-1 shrink-0 self-center ${r}`
|
|
21
|
+
},
|
|
22
|
+
"inline-wide": {
|
|
23
|
+
previous: `relative shrink-0 self-stretch ${i}`,
|
|
24
|
+
next: `relative shrink-0 self-stretch ${i}`
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { n as CAROUSEL_CONTROL_BASE, a as CAROUSEL_CONTROL_LAYOUT };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=Carousel.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.styles.mjs","names":["CAROUSEL_CONTROL_BASE","focusRing","disabledStyles","ROUND","WIDE","CAROUSEL_CONTROL_LAYOUT"],"sources":["../../../src/components/layout/Carousel.styles.ts"],"sourcesContent":["import { disabledStyles, focusRing } from '../../lib/styles';\nimport type { CarouselControlsLayout } from './Carousel.context';\n\n/**\n * What every Previous/Next button shares, the built-in ones and `Carousel.Button`: the stacking\n * above the slides, the colour, the gated hover and pressed states, the focus ring and the\n * disabled look.\n */\nexport const CAROUSEL_CONTROL_BASE = [\n 'z-10 inline-flex items-center justify-center text-foreground',\n 'not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n focusRing,\n disabledStyles,\n].join(' ');\n\nconst ROUND = 'h-8 w-8 rounded-full border border-border bg-background shadow-2';\nconst WIDE = 'w-10 rounded-none bg-background/70';\n\n/**\n * Position and shape per layout and direction: round buttons floating over the slides, full-height\n * strips at the edges, or the same two in a row with the slides (inline layouts).\n */\nexport const CAROUSEL_CONTROL_LAYOUT: Record<\n CarouselControlsLayout,\n Record<'previous' | 'next', string>\n> = {\n overlay: {\n previous: `absolute top-1/2 start-2 -translate-y-1/2 ${ROUND}`,\n next: `absolute top-1/2 end-2 -translate-y-1/2 ${ROUND}`,\n },\n 'overlay-wide': {\n previous: `absolute inset-y-0 start-0 ${WIDE}`,\n next: `absolute inset-y-0 end-0 ${WIDE}`,\n },\n inline: {\n previous: `relative mx-1 shrink-0 self-center ${ROUND}`,\n next: `relative mx-1 shrink-0 self-center ${ROUND}`,\n },\n 'inline-wide': {\n previous: `relative shrink-0 self-stretch ${WIDE}`,\n next: `relative shrink-0 self-stretch ${WIDE}`,\n },\n};\n"],"mappings":";;;AAQA,IAAaA,IAAwB;CACnC;CACA;CACAC;CACAC;AACF,CAAC,CAAC,KAAK,GAAG,GAEJC,IAAQ,oEACRC,IAAO,sCAMAC,IAGT;CACF,SAAS;EACP,UAAU,6CAA6CF;EACvD,MAAM,2CAA2CA;CACnD;CACA,gBAAgB;EACd,UAAU,8BAA8BC;EACxC,MAAM,4BAA4BA;CACpC;CACA,QAAQ;EACN,UAAU,sCAAsCD;EAChD,MAAM,sCAAsCA;CAC9C;CACA,eAAe;EACb,UAAU,kCAAkCC;EAC5C,MAAM,kCAAkCA;CAC1C;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/
|
|
1
|
+
"use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/children.cjs"),r=require("../../lib/dev.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useEventCallback.cjs"),o=require("../../lib/focus.cjs"),s=require("../../hooks/useMergedRefs.cjs"),c=require("../../lib/mergeProps.cjs"),l=require("../../hooks/usePreserveFocus.cjs"),u=require("../../lib/renderTrigger.cjs"),d=require("./Overflow.store.cjs");let f=require("react");f=e.__toESM(f,1);let p=require("react/jsx-runtime");function m(){return f.useReducer(e=>e+1,0)[1]}var h=f.createContext(null),g={store:new d.OverflowStore,hiddenIds:d.NO_IDS,hiddenSet:new Set,groupVisibility:d.NO_GROUPS,direction:`end`,orientation:`horizontal`,hasHiddenItems:!1};function _(e){return f.useContext(h)||(r.reportMissingContext(e,`Overflow`),g)}function v(){let{hiddenIds:e}=_(`useOverflowMenu`);return f.useMemo(()=>({hiddenIds:[...e],count:e.length}),[e])}function y(e){let{hiddenSet:t}=_(`useIsOverflowItemVisible`);return!t.has(e)}function b(e){let{groupVisibility:t}=_(`useIsOverflowGroupVisible`);return t[e]??`visible`}function x(){return _(`useHasHiddenItems`).hasHiddenItems}function S(e){return e.nodeType===Node.ELEMENT_NODE}function C(e,t,n){for(let r of n)r.type===`childList`&&r.target===t&&(r.removedNodes.forEach(t=>{S(t)&&e.unobserve(t)}),r.addedNodes.forEach(n=>{S(n)&&n.parentNode===t&&e.observe(n)}))}var w=class{element=null;value=!1;listeners=new Set;teardown=null;subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)});getSnapshot=()=>this.value;getServerSnapshot=()=>!1;setElement(e){e!==this.element&&(this.disconnect(),this.element=e,e&&(this.teardown=this.observe(e)),this.check())}disconnect(){this.teardown?.(),this.teardown=null,this.element=null}observe(e){let t=()=>this.check(),n=[],r=d.hasResizeObserver()?new ResizeObserver(t):null;if(r){r.observe(e);for(let t of Array.from(e.children))r.observe(t);n.push(()=>r.disconnect())}else typeof window<`u`&&(window.addEventListener(`resize`,t),n.push(()=>window.removeEventListener(`resize`,t)));if(typeof MutationObserver<`u`){let i=new MutationObserver(n=>{r&&C(r,e,n),t()});i.observe(e,{childList:!0,subtree:!0,characterData:!0}),n.push(()=>i.disconnect())}return()=>n.forEach(e=>e())}check(){let e=this.element,t=e!==null&&e.scrollWidth>e.clientWidth;if(t!==this.value){this.value=t;for(let e of Array.from(this.listeners))e()}}};function T(e){return typeof e==`object`&&!!e&&`current`in e}function E(e){let[t]=f.useState(()=>new w),n=f.useSyncExternalStore(t.subscribe,t.getSnapshot,t.getServerSnapshot),r=m();return f.useLayoutEffect(()=>{let n=t.subscribe(r);t.setElement(T(e)?e.current:e),n()}),f.useLayoutEffect(()=>()=>t.disconnect(),[t]),n}var D={horizontal:`items-center`,vertical:`flex-col items-start`},O={horizontal:`flex shrink-0 items-center self-stretch`,vertical:`flex shrink-0 flex-col items-start self-stretch`},k={end:{horizontal:`sticky -end-1 flex shrink-0 items-center self-stretch ps-1 data-[overflow-pinned]:bg-background data-[overflow-pinned]:pe-1`,vertical:`sticky -bottom-1 flex shrink-0 items-center self-stretch pt-1 data-[overflow-pinned]:bg-background data-[overflow-pinned]:pb-1`},"before-hidden":{horizontal:`sticky -end-1 flex shrink-0 items-center self-stretch data-[overflow-pinned]:bg-background data-[overflow-pinned]:pe-1`,vertical:`sticky -bottom-1 flex shrink-0 items-center self-stretch data-[overflow-pinned]:bg-background data-[overflow-pinned]:pb-1`}},A=`wave-overflow-button`;function j(e){return o.isFocusable(e)?e:o.getFirstTabbable(e)??Array.from(e.querySelectorAll(o.FOCUSABLE_SELECTOR)).find(o.isFocusable)??null}function M(e,t){let n=new Set(t),r=e.findIndex(({id:e})=>n.has(e)),i=r<0?[...e].reverse():[...e.filter(({id:e})=>n.has(e)),...e.slice(0,r).reverse(),...e.slice(r).filter(({id:e})=>!n.has(e))];for(let{element:e}of i){let t=j(e);if(t)return t}return null}function N({store:e,hiddenIds:t,buttonRef:n,...r}){let i=f.useRef(null),a=s.useMergedRefs(n,i),o=f.useRef(d.NO_IDS);return f.useLayoutEffect(()=>{o.current=t}),l.usePreserveFocus(i,()=>M(e.getItemElements(),o.current)),(0,p.jsx)(`div`,{ref:a,...r})}N.displayName=`OverflowButtonSlot`;function P(e,t,r){let i=n.flattenChildren(e).map(({key:e,node:t})=>f.isValidElement(t)?f.cloneElement(t,{key:e}):t);if(!t)return{nodes:i,missing:!1};let a=r===void 0?-1:i.findIndex(e=>n.isElementOfType(e,I)&&e.props.itemId===r);return i.splice(a<0?i.length:a,0,t),{nodes:i,missing:r!==void 0&&a<0}}var F=({overflowButton:e,buttonPosition:n=`end`,overflowDirection:o=`end`,orientation:c=`horizontal`,minimumVisible:l=0,hasHiddenItems:u=!1,onOverflowChange:g,children:_,className:v,ref:y,...b})=>{let[x]=f.useState(()=>new d.OverflowStore),S=f.useSyncExternalStore(x.subscribe,x.getSnapshot,x.getServerSnapshot),C=f.useSyncExternalStore(x.subscribe,x.getMeasured,x.getServerFlag),w=f.useSyncExternalStore(x.subscribe,x.getButtonCovers,x.getServerFlag),T=f.useSyncExternalStore(x.subscribe,x.getGroups,x.getServerGroups),E=f.useCallback(e=>x.setContainer(e),[x]),O=f.useCallback(e=>x.setButton(e),[x]),j=s.useMergedRefs(y,E),M=m();f.useLayoutEffect(()=>{x.setConfig({direction:o,orientation:c,minimumVisible:l,hasHiddenItems:u})},[x,o,c,l,u]),f.useLayoutEffect(()=>{let e=x.subscribe(M),t=x.connect();return e(),t},[x,M]),f.useLayoutEffect(()=>{x.checkOrder()});let F=f.useMemo(()=>new Set(S),[S]),I=f.useMemo(()=>[...S],[S]),L=S.length,R=f.useMemo(()=>({store:x,hiddenIds:S,hiddenSet:F,groupVisibility:T,direction:o,orientation:c,hasHiddenItems:L>0}),[x,S,F,T,o,c,L]),z=a.useEventCallback(g),B=f.useRef(d.NO_IDS),V=e!==void 0;f.useEffect(()=>{let e=x.getSnapshot();d.sameIds(e,S)&&x.isSettled(V)&&(d.sameIds(e,B.current)||(B.current=e,z([...e],{visibleItems:x.getVisibleIds(),groupVisibility:Object.assign(Object.create(null),x.getGroups())})))},[x,S,V,z]);let H=(L>0||u&&!C)&&e?(0,p.jsx)(N,{store:x,hiddenIds:S,buttonRef:O,role:b.role===`list`?`listitem`:void 0,"data-overflow-button":``,"data-overflow-pinned":w?``:void 0,className:t.cn(i.overflowClassNames.overflowButton,k[n][c]),children:e(L,I)},A):null,U=n===`before-hidden`?P(_,H,S[0]):null,W=U?.missing??!1;return f.useEffect(()=>{W&&r.warnOnce(`Overflow:button-position`,`Overflow: buttonPosition="before-hidden" puts the button before the first hidden item only when that item is a child of the Overflow (Fragments and arrays are opened), not one rendered by another component; the button is rendered after the items instead.`)},[W]),(0,p.jsx)(h.Provider,{value:R,children:(0,p.jsxs)(`div`,{ref:j,className:t.cn(i.overflowClassNames.root,`flex overflow-hidden p-1`,D[c],v),"data-orientation":c,"data-overflow-direction":o,"data-button-position":n,...b,children:[U?U.nodes:_,U?null:H]})})};F.displayName=`Overflow`;var I=({itemId:e,priority:n,pinned:a=!1,groupId:o,asChild:l=!1,children:d,className:m,style:h,ref:g,"aria-hidden":v,inert:y,...b})=>{let{store:x,hiddenSet:S}=_(`OverflowItem`),C=S.has(e);f.useEffect(()=>x.registerItemId(e),[x,e]);let w=l?u.unwrapFragment(d):void 0,T=u.isCloneableElement(w)?w:null,{ref:E,...D}=(T?T.props:null)??{},O=l&&T===null&&d!=null;f.useEffect(()=>{O&&r.warnOnce(`Overflow.Item:as-child-children`,`Overflow.Item: asChild expects a single React element child (not text or several elements); the children are rendered inside a <div> instead.`)},[O]);let k=f.useCallback(t=>t?x.registerItem(t,e):void 0,[x,e]),A=f.useRef(null),j=s.useMergedRefs(g,k,A,E);f.useLayoutEffect(()=>{A.current&&x.setItemMeta(A.current,n,a,o)});let M=t.cn(i.overflowItemClassNames.root,`shrink-0`,m);if(T){let e=C?{"aria-hidden":!0,inert:!0,"data-overflow-hidden":``}:{};!C&&v!==void 0&&(e[`aria-hidden`]=v),!C&&y!==void 0&&(e.inert=y);let t=c.mergeProps({...b,...e,className:M,style:h},D,{oursWin:[`aria-hidden`,`inert`,`data-overflow-hidden`]}),n=t.style;return f.cloneElement(T,{...t,ref:j,style:C?{...n,display:`none`}:n})}return(0,p.jsx)(`div`,{ref:j,className:M,...b,style:C?{...h,display:`none`}:h,"aria-hidden":C?!0:v,inert:C?!0:y,"data-overflow-hidden":C?``:void 0,children:d})};I.displayName=`OverflowItem`;var L=({groupId:e,children:n,className:r,style:a,ref:o,"aria-hidden":c,inert:l,...u})=>{let{store:d,groupVisibility:m,orientation:h}=_(`OverflowDivider`),g=m[e]===`hidden`,v=f.useCallback(t=>t?d.registerDivider(t,e):void 0,[d,e]),y=s.useMergedRefs(o,v);return(0,p.jsx)(`div`,{ref:y,className:t.cn(i.overflowDividerClassNames.root,O[h],r),...u,style:g?{...a,display:`none`}:a,"aria-hidden":g?!0:c,inert:g?!0:l,"data-overflow-hidden":g?``:void 0,children:n})};L.displayName=`OverflowDivider`;var R=Object.assign(F,{Item:I,Divider:L});exports.Overflow=R,exports.OverflowDivider=L,exports.OverflowItem=I,exports.useHasHiddenItems=x,exports.useIsOverflowGroupVisible=b,exports.useIsOverflowItemVisible=y,exports.useIsOverflowing=E,exports.useOverflowMenu=v;
|
|
2
2
|
//# sourceMappingURL=Overflow.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Overflow.cjs","names":["React","isDev","useMergedRefs","cn","overflowClassNames","overflowItemClassNames","require_runtime","require_cn","require_dev","require_classNames","require_useMergedRefs","react","react_jsx_runtime","NO_IDS","useForceRender","n","hasResizeObserver","documentOrder","a","b","REORDER_OBSERVER_OPTIONS","sameIds","id","i","warnDuplicateItemId","itemId","noop","readContainer","paddingInline","gap","view","container","style","OverflowStore","listener","el","onResize","node","order","counts","count","remaining","elements","entries","widths","total","sum","width","next","pinned","available","limit","used","cut","end","hiddenChanged","OverflowContext","INERT_CONTEXT","useOverflowContext","componentName","useOverflowMenu","hiddenIds","useIsOverflowItemVisible","hiddenSet","isElement","followDirectChildren","record","records","parent","observer","OverflowingStore","element","check","cleanups","resizeObserver","child","mutationObserver","cleanup","isRefObject","target","useIsOverflowing","store","isOverflowing","forceRender","unsubscribe","OverflowRoot","rest","setContainer","setButton","containerRef","ref","disconnect","buttonIds","ctx","hiddenCount","className","children","overflowButton","OverflowItem","ariaHidden","isHidden","registerRef","mergedRef","inert","Overflow"],"sources":["../../../src/components/layout/Overflow.tsx"],"sourcesContent":["import * as React from 'react';\nimport { overflowClassNames, overflowItemClassNames } from '../../lib/classNames';\nimport { cn } from '../../lib/cn';\nimport { isDev, reportMissingContext, warnOnce } from '../../lib/dev';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\n\n/** Properties for the Overflow component. */\nexport interface OverflowProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Renders the overflow button (for example a \"+3\" menu trigger) while at least one item is\n * hidden. Receives the number of hidden items and their `itemId`s in DOM order, so the button\n * can open a menu of the hidden items. `hiddenIds` is the button's own array (sorting it in\n * place affects nobody else). Its width is measured and reserved when items overflow.\n * Components rendered by it can also read the hidden items with {@link useOverflowMenu}.\n */\n overflowButton?: (count: number, hiddenIds: string[]) => React.ReactNode;\n /**\n * The {@link OverflowItem}s to lay out in one row. Only items and the overflow button are\n * measured: the container's whole content box is the room for them, so other content placed in\n * the row is not accounted for and could clip items that still count as visible. Keep fixed\n * content outside the Overflow (for example in a surrounding flex row), or wrap it in an\n * `OverflowItem` (the first item is never hidden).\n */\n children: React.ReactNode;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the OverflowItem sub-component. */\nexport interface OverflowItemProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Identifier for tracking this item's overflow visibility, unique within the Overflow (a\n * duplicate warns in development: items that share one are hidden and shown together).\n */\n itemId: string;\n /** Content of the overflow item. */\n children: React.ReactNode;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Result of {@link useOverflowMenu}. */\nexport interface UseOverflowMenuResult {\n /** `itemId`s of the hidden items, in DOM order (the caller's own array). */\n hiddenIds: string[];\n /** Number of hidden items. */\n count: number;\n}\n\n// ---------------------------------------------------------------------------\n// Measurement store\n// ---------------------------------------------------------------------------\n\n/**\n * The empty snapshot. Snapshots are internal: they are compared by identity and never handed to\n * consumers, who receive their own copies (see `useOverflowMenu` and `overflowButton`).\n */\nconst NO_IDS: string[] = [];\n\n/** A stable function that re-renders the calling component. */\nfunction useForceRender(): () => void {\n return React.useReducer((n: number) => n + 1, 0)[1];\n}\n\nfunction hasResizeObserver(): boolean {\n return typeof ResizeObserver !== 'undefined';\n}\n\nfunction documentOrder(a: Element, b: Element): number {\n if (a === b) return 0;\n return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;\n}\n\n/** Moves anywhere in the row: items reordered directly or inside wrappers. */\nconst REORDER_OBSERVER_OPTIONS: MutationObserverInit = { childList: true, subtree: true };\n\nfunction sameIds(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((id, i) => id === b[i]);\n}\n\nfunction warnDuplicateItemId(itemId: string): void {\n warnOnce(\n `Overflow:duplicate:${itemId}`,\n `Overflow: several items share the itemId \"${itemId}\". Item ids must be unique within an ` +\n 'Overflow; items with the same itemId are hidden and shown together.',\n );\n}\n\nconst noop = () => {};\n\n/** Width available to items: the content box of the container, and the flex gap between items. */\nfunction readContainer(container: HTMLElement): { available: number; gap: number } {\n let paddingInline = 0;\n let gap = 0;\n const view = container.ownerDocument.defaultView;\n if (view) {\n const style = view.getComputedStyle(container);\n paddingInline = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);\n gap = parseFloat(style.columnGap) || 0;\n }\n return { available: container.clientWidth - paddingInline, gap };\n}\n\n/**\n * Tracks the container, the items and the overflow button of one `Overflow` and publishes the ids\n * of the hidden items (DOM order), and whether the button covers the first item, to\n * `useSyncExternalStore`.\n *\n * - **Measurement never writes styles.** An item's width is read (`offsetWidth`) only while it is\n * visible and cached; a hidden item (`data-overflow-hidden` and an inline `display: none`, both\n * rendered by React) keeps its last visible width. All reads happen before React applies the\n * result.\n * - **Membership-only updates.** A new snapshot is published only when the hidden set (or whether\n * the button covers the first item) changes, so a resize that hides the same items renders\n * nothing.\n * - **One observer.** A single `ResizeObserver` (created when the root mounts) watches the\n * container, every item and the overflow button. Without `ResizeObserver` the store measures\n * whenever something registers and on window `resize`.\n * - **Reorders.** A keyed reorder moves item elements without registering them again or changing\n * a size. The order of the last measurement is re-checked (n − 1 `compareDocumentPosition`\n * calls, no layout reads) after every commit of the root and, through a `MutationObserver`\n * (`childList`, `subtree`) on the container, after moves that do not render the root (a list\n * component inside the row that owns its order); only an inversion re-measures.\n */\nclass OverflowStore {\n private container: HTMLElement | null = null;\n private button: HTMLElement | null = null;\n private buttonWidth = 0;\n private readonly items = new Map<HTMLElement, string>();\n /** How many mounted items use each `itemId` (development only: a repeated one warns). */\n private readonly itemIdCounts = new Map<string, number>();\n private readonly widths = new WeakMap<HTMLElement, number>();\n private readonly listeners = new Set<() => void>();\n private hidden: string[] = NO_IDS;\n /** The first item is wider than the room beside the button, so the button covers its end. */\n private pinned = false;\n /** The item elements of the last measurement, in the DOM order they had then. */\n private order: HTMLElement[] = [];\n private connected = false;\n private observer: ResizeObserver | null = null;\n private reorderObserver: MutationObserver | null = null;\n private removeResizeListener: (() => void) | null = null;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): string[] => this.hidden;\n\n getServerSnapshot = (): string[] => NO_IDS;\n\n getPinned = (): boolean => this.pinned;\n\n getServerPinned = (): boolean => false;\n\n /** Starts observing (root layout effect); returns the teardown. */\n connect = (): (() => void) => {\n this.connected = true;\n if (hasResizeObserver()) {\n this.observer = new ResizeObserver(() => this.measure());\n for (const el of this.observedElements()) this.observer.observe(el);\n } else if (typeof window !== 'undefined') {\n const onResize = () => this.measure();\n window.addEventListener('resize', onResize);\n this.removeResizeListener = () => window.removeEventListener('resize', onResize);\n }\n if (typeof MutationObserver !== 'undefined') {\n this.reorderObserver = new MutationObserver(() => this.checkOrder());\n if (this.container) this.reorderObserver.observe(this.container, REORDER_OBSERVER_OPTIONS);\n }\n this.measure();\n return () => {\n this.connected = false;\n this.observer?.disconnect();\n this.observer = null;\n this.reorderObserver?.disconnect();\n this.reorderObserver = null;\n this.removeResizeListener?.();\n this.removeResizeListener = null;\n };\n };\n\n /** Ref callback of the container. */\n setContainer = (node: HTMLDivElement | null): void => {\n if (node === this.container) return;\n if (this.container) this.observer?.unobserve(this.container);\n this.container = node;\n if (node) this.observer?.observe(node);\n if (this.reorderObserver) {\n this.reorderObserver.disconnect();\n if (node) this.reorderObserver.observe(node, REORDER_OBSERVER_OPTIONS);\n }\n this.measure();\n };\n\n /**\n * Re-measures when the items of the last measurement are no longer in DOM order (a keyed\n * reorder). Cheap: neighbour comparisons only, no layout reads.\n */\n checkOrder = (): void => {\n const order = this.order;\n for (let i = 1; i < order.length; i++) {\n if (documentOrder(order[i - 1], order[i]) > 0) {\n this.measure();\n return;\n }\n }\n };\n\n /** Ref callback of the overflow button wrapper. The last measured width outlives it. */\n setButton = (node: HTMLDivElement | null): void => {\n if (node === this.button) return;\n if (this.button) this.observer?.unobserve(this.button);\n this.button = node;\n if (node) this.observer?.observe(node);\n this.measure();\n };\n\n /** Registers an item element; returns its unregistration. */\n registerItem(el: HTMLElement, id: string): () => void {\n this.items.set(el, id);\n this.observer?.observe(el);\n this.measure();\n return () => {\n if (this.items.get(el) !== id) return;\n this.items.delete(el);\n this.observer?.unobserve(el);\n this.measure();\n };\n }\n\n /**\n * Counts the `itemId` of a mounted item (called from the item's effect, C-DEV); a second item\n * with an id already in use warns once per id. Returns the cleanup.\n */\n registerItemId = (itemId: string): (() => void) => {\n if (!isDev) return noop;\n const counts = this.itemIdCounts;\n const count = (counts.get(itemId) ?? 0) + 1;\n counts.set(itemId, count);\n if (count > 1) warnDuplicateItemId(itemId);\n return () => {\n const remaining = (counts.get(itemId) ?? 1) - 1;\n if (remaining > 0) counts.set(itemId, remaining);\n else counts.delete(itemId);\n };\n };\n\n private observedElements(): HTMLElement[] {\n const elements = Array.from(this.items.keys());\n if (this.container) elements.push(this.container);\n if (this.button) elements.push(this.button);\n return elements;\n }\n\n private measure(): void {\n const container = this.container;\n if (!this.connected || !container) return;\n\n // Reads first: widths of the visible items, the button and the container.\n const entries = Array.from(this.items)\n .filter(([el]) => el.isConnected && container.contains(el))\n .sort(([a], [b]) => documentOrder(a, b));\n this.order = entries.map(([el]) => el);\n for (const [el] of entries) {\n if (!el.hasAttribute('data-overflow-hidden')) this.widths.set(el, el.offsetWidth);\n }\n if (this.button?.isConnected) this.buttonWidth = this.button.offsetWidth;\n const { available, gap } = readContainer(container);\n\n const widths = entries.map(([el]) => this.widths.get(el) ?? 0);\n const total = widths.reduce((sum, width, i) => sum + width + (i > 0 ? gap : 0), 0);\n\n let next: string[] = NO_IDS;\n let pinned = false;\n if (total > available) {\n // Items that fit next to the overflow button stay; the first item always stays.\n const limit = available - (this.buttonWidth > 0 ? this.buttonWidth + gap : 0);\n let used = 0;\n let cut = entries.length;\n for (let i = 0; i < entries.length; i++) {\n const end = used + widths[i] + (i > 0 ? gap : 0);\n if (i > 0 && end > limit) {\n cut = i;\n break;\n }\n used = end;\n }\n next = entries.slice(cut).map(([, id]) => id);\n // The sticky button eats the gap before it first; it covers the first item only when the\n // two do not fit side by side.\n pinned = next.length > 0 && widths[0] + this.buttonWidth > available;\n }\n\n const hiddenChanged = !sameIds(next, this.hidden);\n if (!hiddenChanged && pinned === this.pinned) return;\n // The same hidden set keeps its array, so the items and useOverflowMenu() do not update.\n if (hiddenChanged) this.hidden = next.length > 0 ? next : NO_IDS;\n this.pinned = pinned;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Context (C-CONTEXT)\n// ---------------------------------------------------------------------------\n\ninterface OverflowContextValue {\n store: OverflowStore;\n hiddenIds: string[];\n hiddenSet: ReadonlySet<string>;\n}\n\nconst OverflowContext = React.createContext<OverflowContextValue | null>(null);\n\n/** Production fallback for a misplaced sub-component: a store that is never connected. */\nconst INERT_CONTEXT: OverflowContextValue = {\n store: /* @__PURE__ */ new OverflowStore(),\n hiddenIds: NO_IDS,\n hiddenSet: /* @__PURE__ */ new Set<string>(),\n};\n\n/**\n * The enclosing Overflow's context. Outside an Overflow it throws in development and, in\n * production, logs an error once and returns an inert value (C-CONTEXT).\n */\nfunction useOverflowContext(componentName: string): OverflowContextValue {\n const ctx = React.useContext(OverflowContext);\n if (ctx) return ctx;\n reportMissingContext(componentName, 'Overflow');\n return INERT_CONTEXT;\n}\n\n// ---------------------------------------------------------------------------\n// Hooks\n// ---------------------------------------------------------------------------\n\n/**\n * The items an {@link Overflow} currently hides: their `itemId`s in DOM order and their count. Use\n * it in the component that `overflowButton` renders to list the hidden items in a menu. Must be\n * called inside `Overflow`.\n */\nexport function useOverflowMenu(): UseOverflowMenuResult {\n const { hiddenIds } = useOverflowContext('useOverflowMenu');\n // A copy per caller and snapshot: sorting or reversing it cannot affect other consumers.\n return React.useMemo(() => ({ hiddenIds: [...hiddenIds], count: hiddenIds.length }), [hiddenIds]);\n}\n\n/**\n * Whether the {@link OverflowItem} with `itemId` is currently shown (`false` while it overflows).\n * Must be called inside `Overflow`.\n */\nexport function useIsOverflowItemVisible(itemId: string): boolean {\n const { hiddenSet } = useOverflowContext('useIsOverflowItemVisible');\n return !hiddenSet.has(itemId);\n}\n\nfunction isElement(node: Node): node is Element {\n return node.nodeType === Node.ELEMENT_NODE;\n}\n\n/**\n * Keeps `observer` on the element children of `parent`: unobserves the removed ones and observes\n * the added ones that are still attached to `parent` (records are replayed in order, so a child\n * moved or re-added within one batch ends up observed exactly when it is present).\n */\nfunction followDirectChildren(\n observer: ResizeObserver,\n parent: Element,\n records: readonly MutationRecord[],\n): void {\n for (const record of records) {\n if (record.type !== 'childList' || record.target !== parent) continue;\n record.removedNodes.forEach((node) => {\n if (isElement(node)) observer.unobserve(node);\n });\n record.addedNodes.forEach((node) => {\n if (isElement(node) && node.parentNode === parent) observer.observe(node);\n });\n }\n}\n\n/** Tracks `scrollWidth > clientWidth` of one element. */\nclass OverflowingStore {\n private element: HTMLElement | null = null;\n private value = false;\n private readonly listeners = new Set<() => void>();\n private teardown: (() => void) | null = null;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): boolean => this.value;\n\n getServerSnapshot = (): boolean => false;\n\n /** Follows `element` (layout effect of every render); re-subscribes when it changes. */\n setElement(element: HTMLElement | null): void {\n if (element === this.element) return;\n this.disconnect();\n this.element = element;\n if (element) this.teardown = this.observe(element);\n this.check();\n }\n\n disconnect(): void {\n this.teardown?.();\n this.teardown = null;\n this.element = null;\n }\n\n private observe(element: HTMLElement): () => void {\n const check = () => this.check();\n const cleanups: Array<() => void> = [];\n\n // Resizes of the element and of its direct children (content that grows or shrinks).\n const resizeObserver = hasResizeObserver() ? new ResizeObserver(check) : null;\n if (resizeObserver) {\n resizeObserver.observe(element);\n for (const child of Array.from(element.children)) resizeObserver.observe(child);\n cleanups.push(() => resizeObserver.disconnect());\n } else if (typeof window !== 'undefined') {\n window.addEventListener('resize', check);\n cleanups.push(() => window.removeEventListener('resize', check));\n }\n\n // Content added, removed or edited. Only a change of the direct children changes what the\n // ResizeObserver watches, and only those children are (un)observed; text edits and deeper\n // changes just re-check.\n if (typeof MutationObserver !== 'undefined') {\n const mutationObserver = new MutationObserver((records) => {\n if (resizeObserver) followDirectChildren(resizeObserver, element, records);\n check();\n });\n mutationObserver.observe(element, { childList: true, subtree: true, characterData: true });\n cleanups.push(() => mutationObserver.disconnect());\n }\n\n return () => cleanups.forEach((cleanup) => cleanup());\n }\n\n private check(): void {\n const el = this.element;\n const next = el !== null && el.scrollWidth > el.clientWidth;\n if (next === this.value) return;\n this.value = next;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\nfunction isRefObject(\n target: React.RefObject<HTMLElement | null> | HTMLElement | null | undefined,\n): target is React.RefObject<HTMLElement | null> {\n return target != null && typeof target === 'object' && 'current' in target;\n}\n\n/**\n * Whether `target`'s content is wider than the element (`scrollWidth > clientWidth`).\n *\n * `target` is a ref object or the element itself (for example from callback-ref state:\n * `const [el, setEl] = useState(null)` + `ref={setEl}`). The hook re-checks when the element\n * resizes, when its direct children resize, and when content is added, removed or edited; an\n * element that mounts later (a ref attached conditionally) is picked up after the render that\n * mounts it. Without `ResizeObserver` it re-checks on window `resize` and content changes. Returns\n * `false` on the server.\n */\nexport function useIsOverflowing(\n target: React.RefObject<HTMLElement | null> | HTMLElement | null,\n): boolean {\n const [store] = React.useState(() => new OverflowingStore());\n const isOverflowing = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot,\n );\n const forceRender = useForceRender();\n\n // Every render: follow the element the ref points to now (cheap identity check). A change found\n // here re-renders from the layout phase, before paint: useSyncExternalStore only subscribes in a\n // passive effect, so on mount it would pick the first value up after the browser painted.\n React.useLayoutEffect(() => {\n const unsubscribe = store.subscribe(forceRender);\n store.setElement(isRefObject(target) ? target.current : target);\n unsubscribe();\n });\n\n React.useLayoutEffect(() => () => store.disconnect(), [store]);\n\n return isOverflowing;\n}\n\n// ---------------------------------------------------------------------------\n// Components\n// ---------------------------------------------------------------------------\n\nconst OverflowRoot = ({ overflowButton, children, className, ref, ...rest }: OverflowProps) => {\n const [store] = React.useState(() => new OverflowStore());\n const hiddenIds = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot,\n );\n const pinned = React.useSyncExternalStore(\n store.subscribe,\n store.getPinned,\n store.getServerPinned,\n );\n const setContainer = React.useCallback(\n (node: HTMLDivElement | null) => store.setContainer(node),\n [store],\n );\n const setButton = React.useCallback(\n (node: HTMLDivElement | null) => store.setButton(node),\n [store],\n );\n const containerRef = useMergedRefs<HTMLDivElement>(ref, setContainer);\n const forceRender = useForceRender();\n\n // Observers are created once per instance (not per render or per children change). The first\n // measurement (in connect) re-renders from this layout effect, before paint: useSyncExternalStore\n // only subscribes in a passive effect, which can run after the browser painted every item.\n React.useLayoutEffect(() => {\n const unsubscribe = store.subscribe(forceRender);\n const disconnect = store.connect();\n unsubscribe();\n return disconnect;\n }, [store, forceRender]);\n\n // After every commit of the root (new children, a keyed reorder): items moved without any size\n // change or registration are re-measured before paint. Cheap when nothing moved.\n React.useLayoutEffect(() => {\n store.checkOrder();\n });\n\n const hiddenSet = React.useMemo(() => new Set(hiddenIds), [hiddenIds]);\n // The overflowButton's own copy (consumers may sort it in place).\n const buttonIds = React.useMemo(() => [...hiddenIds], [hiddenIds]);\n const ctx = React.useMemo<OverflowContextValue>(\n () => ({ store, hiddenIds, hiddenSet }),\n [store, hiddenIds, hiddenSet],\n );\n\n const hiddenCount = hiddenIds.length;\n\n return (\n <OverflowContext.Provider value={ctx}>\n <div\n ref={containerRef}\n // The row clips its content at its padding edge: the 4px padding leaves room for the focus\n // indicator a focused item draws 4px around itself. No negative margin offsets it: the\n // row's box would then reach past its container, which a scroll container around an\n // edge-to-edge row (or the page) counts as overflow. The store measures the room without\n // the padding.\n className={cn(overflowClassNames.root, 'flex items-center overflow-hidden p-1', className)}\n {...rest}\n >\n {children}\n {hiddenCount > 0 && overflowButton && (\n // In the row's flow (it adds to the row height and follows justify-*), sticking to the\n // inline end when the first item is wider than the room beside it. Browsers stop a\n // sticky element at the scroll container's padding, so -end-1 lets it reach the\n // clipping edge, and while pinned it keeps 4px inside for its own focus indicator.\n // (WebKit stops a sticky element short of the inline end of a right-to-left row; it\n // stays in the row.)\n <div\n ref={setButton}\n data-overflow-button=\"\"\n data-overflow-pinned={pinned ? '' : undefined}\n className={cn(\n overflowClassNames.overflowButton,\n 'sticky -end-1 flex shrink-0 items-center self-stretch ps-1 data-[overflow-pinned]:bg-background data-[overflow-pinned]:pe-1',\n )}\n >\n {overflowButton(hiddenCount, buttonIds)}\n </div>\n )}\n </div>\n </OverflowContext.Provider>\n );\n};\nOverflowRoot.displayName = 'Overflow';\n\n/**\n * One entry of an {@link Overflow}. While it does not fit it stays mounted but is hidden\n * (`data-overflow-hidden` and an inline `display: none` placed after the consumer's own `style`),\n * `aria-hidden` and `inert`. The inline style wins over the consumer's `style.display` and over\n * display utilities in any cascade layer (a prefixed Tailwind app's `tw:flex` included), so a\n * hidden item is never shown while it is counted in \"+N\". Must be rendered inside `Overflow`.\n */\nexport const OverflowItem = ({\n itemId,\n children,\n className,\n style,\n ref,\n 'aria-hidden': ariaHidden,\n inert,\n ...rest\n}: OverflowItemProps) => {\n const { store, hiddenSet } = useOverflowContext('OverflowItem');\n const isHidden = hiddenSet.has(itemId);\n React.useEffect(() => store.registerItemId(itemId), [store, itemId]);\n\n const registerRef = React.useCallback(\n (node: HTMLDivElement | null) => (node ? store.registerItem(node, itemId) : undefined),\n [store, itemId],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, registerRef);\n\n return (\n <div\n ref={mergedRef}\n className={cn(overflowItemClassNames.root, 'shrink-0', className)}\n {...rest}\n style={isHidden ? { ...style, display: 'none' } : style}\n aria-hidden={isHidden ? true : ariaHidden}\n inert={isHidden ? true : inert}\n data-overflow-hidden={isHidden ? '' : undefined}\n >\n {children}\n </div>\n );\n};\nOverflowItem.displayName = 'OverflowItem';\n\n/**\n * A single row that hides the items which do not fit and shows an overflow button instead.\n *\n * Wrap each entry in {@link OverflowItem} with a unique `itemId`; the row holds only items (other\n * content is not measured, see `children`). Items are measured while visible, hidden from the end\n * (in DOM order; the first item always stays) and hidden items get `data-overflow-hidden`, an\n * inline `display: none`, `aria-hidden` and `inert`. Reordered items (for example a keyed sort) are\n * re-measured in their new order. `overflowButton(count, hiddenIds)` renders the button after the\n * visible items (its measured width is reserved); components inside it can use\n * {@link useOverflowMenu} to list the hidden items (e.g. in a Menu), and\n * {@link useIsOverflowItemVisible} reports a single item. The button sticks to the inline end of\n * the row, so a first item wider than the room beside it cannot push it out of view: it then covers\n * the end of that item and gets `data-overflow-pinned`, with the `background` token behind it. (In\n * a right-to-left row, WebKit stops the pinned button short of the end, still inside the row.)\n *\n * The row clips what does not fit. So that the focus indicators of its items are not cut off, it\n * has a 4px padding: the items sit 4px in from its edges, and the row is 8px taller than they are.\n * An explicit width (such as `w-full` or a style width) includes that padding. The row never\n * reaches past its own box, so an edge-to-edge row adds no scrollbar to the page or to a scroll\n * container around it. A negative margin of 4px lines the items up with the content around the\n * row; add it only where nothing within 4px of the row scrolls (the row's box then reaches 4px past\n * its container on every side). `p-0` removes the room (focus indicators at the row's edges are\n * then clipped).\n *\n * Works without `ResizeObserver` (jsdom, old browsers): it then re-measures on window resize and\n * when items mount, unmount or move.\n *\n * The item is also `Overflow.Item`. The same component is exported as `OverflowItem`; React Server\n * Components import that flat name (dotted access needs a client file).\n */\nexport const Overflow = /* @__PURE__ */ Object.assign(OverflowRoot, {\n Item: OverflowItem,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Overflow.cjs","names":["React","OverflowStore","NO_IDS","NO_GROUPS","hasResizeObserver","isFocusable","getFirstTabbable","FOCUSABLE_SELECTOR","useMergedRefs","flattenChildren","isElementOfType","useEventCallback","sameIds","cn","overflowClassNames","unwrapFragment","isCloneableElement","overflowItemClassNames","mergeProps","overflowDividerClassNames","require_runtime","require_cn","require_children","require_dev","require_classNames","require_useEventCallback","require_focus","require_useMergedRefs","require_mergeProps","require_usePreserveFocus","require_renderTrigger","require_Overflow_store","react","react_jsx_runtime","useForceRender","n","OverflowContext","INERT_CONTEXT","useOverflowContext","componentName","useOverflowMenu","hiddenIds","useIsOverflowItemVisible","hiddenSet","itemId","useIsOverflowGroupVisible","groupVisibility","groupId","useHasHiddenItems","isElement","node","followDirectChildren","record","records","parent","observer","OverflowingStore","listener","element","check","cleanups","resizeObserver","child","mutationObserver","cleanup","el","next","isRefObject","target","useIsOverflowing","store","isOverflowing","forceRender","unsubscribe","ROOT_ORIENTATION_CLASSES","DIVIDER_ORIENTATION_CLASSES","BUTTON_CLASSES","BUTTON_KEY","focusTargetIn","item","overflowFocusFallback","hidden","wereHidden","first","items","id","candidates","OverflowButtonSlot","rest","elementRef","ref","buttonRef","wereHiddenRef","placeButtonBeforeHidden","nodes","children","button","index","firstHiddenId","OverflowItem","OverflowRoot","measured","buttonCovers","setContainer","setButton","containerRef","overflowDirection","orientation","minimumVisible","hasHiddenItems","disconnect","buttonIds","hiddenCount","ctx","emitOverflowChange","onOverflowChange","reported","hasButton","overflowButton","current","buttonPosition","placed","unplaced","className","ariaHidden","isHidden","asChild","childElement","childRef","ownChildProps","wrapsChildren","registerRef","mergedRef","priority","pinned","itemClassName","hiddenProps","inert","merged","mergedStyle","style","OverflowDivider","Overflow"],"sources":["../../../src/components/layout/Overflow.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n overflowClassNames,\n overflowDividerClassNames,\n overflowItemClassNames,\n} from '../../lib/classNames';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { reportMissingContext, warnOnce } from '../../lib/dev';\nimport { FOCUSABLE_SELECTOR, getFirstTabbable, isFocusable } from '../../lib/focus';\nimport { mergeProps } from '../../lib/mergeProps';\nimport { isCloneableElement, unwrapFragment } from '../../lib/renderTrigger';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { usePreserveFocus } from '../../hooks/usePreserveFocus';\nimport type { Orientation } from '../../lib/types';\nimport { NO_GROUPS, NO_IDS, OverflowStore, hasResizeObserver, sameIds } from './Overflow.store';\nimport type {\n GroupVisibilityRecord,\n OverflowDirection,\n OverflowGroupVisibility,\n} from './Overflow.store';\n\nexport type { OverflowDirection, OverflowGroupVisibility };\n\n/** What {@link OverflowProps.onOverflowChange} reports besides the hidden ids. */\nexport interface OverflowChangeDetails {\n /** `itemId`s of the shown items, in DOM order. */\n visibleItems: string[];\n /**\n * The visibility of each item group, by `groupId` (only groups with an item; a record without a\n * prototype): `'visible'` when every member is shown, `'hidden'` when none is, `'overflow'` for\n * a mix.\n */\n groupVisibility: Record<string, OverflowGroupVisibility>;\n}\n\n/** Properties for the Overflow component. */\nexport interface OverflowProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Renders the overflow button (for example a \"+3\" menu trigger) while at least one item is\n * hidden. Receives the number of hidden items and their `itemId`s in DOM order, so the button\n * can open a menu of the hidden items. `hiddenIds` is the button's own array (sorting it in\n * place affects nobody else). Its size on the row's axis (width, or height for a vertical row)\n * is measured and reserved when items overflow. In a list row (`role=\"list\"`, with `asChild`\n * `<li>` items) the button's wrapper is a list item (`role=\"listitem\"`).\n * Components rendered by it can also read the hidden items with {@link useOverflowMenu}.\n */\n overflowButton?: (count: number, hiddenIds: string[]) => React.ReactNode;\n /**\n * The {@link OverflowItem}s (and {@link OverflowDivider}s) to lay out in one row or column.\n * Only items, dividers and the overflow button are measured: the container's whole content box\n * is the room for them, so other content placed in the row is not accounted for and could clip\n * items that still count as visible. Keep fixed content outside the Overflow (for example in a\n * surrounding flex row), or wrap it in an `OverflowItem` and pin it with `pinned`.\n */\n children: React.ReactNode;\n /**\n * Which end of the row overflows first (`start` is the start of the DOM order, so the right side\n * of a right-to-left row). While no item sets `priority` or `pinned` (`pinned={false}` does not\n * count) the first item (`end`) or the last one (`start`) is never hidden, as in 0.13; once any\n * item pins itself or sets a priority, only `pinned` items are protected, the first one included.\n * @default 'end'\n */\n overflowDirection?: OverflowDirection;\n /**\n * Where the overflow button goes while items are hidden: `'end'` after every item, sticking to\n * the end of the axis; `'before-hidden'` just before the first hidden item in DOM order, so it\n * stands in for the hidden items (a breadcrumb trail), and takes the row's gap as the items do.\n * With `'before-hidden'` the items must be children of the Overflow (Fragments and arrays are\n * opened): when the first hidden item is rendered by another component the button stays at the\n * end, with a development warning. The button moves without remounting. While nothing is\n * hidden there is no button, except the one `hasHiddenItems` reserves, at the end.\n * @default 'end'\n */\n buttonPosition?: 'end' | 'before-hidden';\n /**\n * The axis items are laid out on. `'vertical'` stacks them in a column and measures heights\n * (Fluent's `overflowAxis`); the column needs a definite height (a `height`, or a flex or grid\n * cell with one), since it has no room to measure otherwise.\n * @default 'horizontal'\n */\n orientation?: Orientation;\n /**\n * The number of items that stay visible however little room there is (pinned items count).\n * @default 0\n */\n minimumVisible?: number;\n /**\n * Renders the overflow button before the first measurement (for example in the server HTML) so\n * the row reserves its room; `overflowButton` then receives `0` and `[]`. It goes away after the\n * first measurement when every item fits.\n * @default false\n */\n hasHiddenItems?: boolean;\n /**\n * Called, from an effect, when the set of hidden items changes (not for the initial, empty set),\n * with the hidden `itemId`s in DOM order and the {@link OverflowChangeDetails}. Called once per\n * change in StrictMode, and only for a set that has been rendered. The Overflow always passes\n * `details`; it is typed optional until 1.0, as the second argument of every callback is, so a\n * handler of the hidden ids alone fits.\n */\n onOverflowChange?: (hiddenItems: string[], details?: OverflowChangeDetails) => void;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * An item hides in ascending `priority` (higher overflows later, default 0), or it is `pinned` and\n * never hides: `priority` or `pinned`, never both.\n */\nexport type OverflowItemPriorityProps =\n | {\n /**\n * Items with a lower priority overflow first; equal priorities follow the direction.\n * @default 0\n */\n priority?: number;\n pinned?: never;\n }\n | {\n /**\n * The item never overflows. Pinning any item drops the 0.13 protection of the first item for\n * the whole row; `pinned={false}` alone keeps it.\n * @default false\n */\n pinned?: boolean;\n priority?: never;\n };\n\n/** Properties for the OverflowItem sub-component. */\nexport type OverflowItemProps = OverflowItemBaseProps & OverflowItemPriorityProps;\n\n/** The props of an {@link OverflowItem} besides `priority` and `pinned`. */\nexport interface OverflowItemBaseProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Identifier for tracking this item's overflow visibility, unique within the Overflow (a\n * duplicate warns in development: items that share one are hidden and shown together).\n */\n itemId: string;\n /**\n * The group the item belongs to. A group is `'visible'`, `'hidden'` or `'overflow'` (some members\n * hidden); an {@link OverflowDivider} with the same `groupId` hides with a hidden group, and\n * {@link useIsOverflowGroupVisible} reads it.\n */\n groupId?: string;\n /**\n * Puts the item's props on its single element child (an `<li>`, a Toolbar button) instead of on\n * a wrapper `<div>`: handlers and refs are composed with the child's, classes and styles merged,\n * and the hidden state (`data-overflow-hidden`, `display: none`, `aria-hidden`, `inert`) wins\n * over the child's own. A child that is not a single element (text, several elements) renders in\n * the wrapper `<div>` and warns in development.\n * @default false\n */\n asChild?: boolean;\n /** Content of the overflow item: with `asChild`, the single element that takes its props. */\n children: React.ReactNode;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the OverflowDivider sub-component. */\nexport interface OverflowDividerProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The group the divider belongs to: it is hidden while that group is `'hidden'` and takes room\n * in the row otherwise. A group without items counts as visible.\n */\n groupId: string;\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Result of {@link useOverflowMenu}. */\nexport interface UseOverflowMenuResult {\n /** `itemId`s of the hidden items, in DOM order (the caller's own array). */\n hiddenIds: string[];\n /** Number of hidden items. */\n count: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** A stable function that re-renders the calling component. */\nfunction useForceRender(): () => void {\n return React.useReducer((n: number) => n + 1, 0)[1];\n}\n\n// ---------------------------------------------------------------------------\n// Context (C-CONTEXT)\n// ---------------------------------------------------------------------------\n\ninterface OverflowContextValue {\n store: OverflowStore;\n hiddenIds: string[];\n hiddenSet: ReadonlySet<string>;\n groupVisibility: GroupVisibilityRecord;\n direction: OverflowDirection;\n orientation: Orientation;\n /** At least one item is hidden (not the button that `hasHiddenItems` reserves). */\n hasHiddenItems: boolean;\n}\n\nconst OverflowContext = React.createContext<OverflowContextValue | null>(null);\n\n/** Production fallback for a misplaced sub-component: a store that is never connected. */\nconst INERT_CONTEXT: OverflowContextValue = {\n store: /* @__PURE__ */ new OverflowStore(),\n hiddenIds: NO_IDS,\n hiddenSet: /* @__PURE__ */ new Set<string>(),\n groupVisibility: NO_GROUPS,\n direction: 'end',\n orientation: 'horizontal',\n hasHiddenItems: false,\n};\n\n/**\n * The enclosing Overflow's context. Outside an Overflow it throws in development and, in\n * production, logs an error once and returns an inert value (C-CONTEXT).\n */\nfunction useOverflowContext(componentName: string): OverflowContextValue {\n const ctx = React.useContext(OverflowContext);\n if (ctx) return ctx;\n reportMissingContext(componentName, 'Overflow');\n return INERT_CONTEXT;\n}\n\n// ---------------------------------------------------------------------------\n// Hooks\n// ---------------------------------------------------------------------------\n\n/**\n * The items an {@link Overflow} currently hides: their `itemId`s in DOM order and their count. Use\n * it in the component that `overflowButton` renders to list the hidden items in a menu. Must be\n * called inside `Overflow`.\n */\nexport function useOverflowMenu(): UseOverflowMenuResult {\n const { hiddenIds } = useOverflowContext('useOverflowMenu');\n // A copy per caller and snapshot: sorting or reversing it cannot affect other consumers.\n return React.useMemo(() => ({ hiddenIds: [...hiddenIds], count: hiddenIds.length }), [hiddenIds]);\n}\n\n/**\n * Whether the {@link OverflowItem} with `itemId` is currently shown (`false` while it overflows).\n * Must be called inside `Overflow`.\n */\nexport function useIsOverflowItemVisible(itemId: string): boolean {\n const { hiddenSet } = useOverflowContext('useIsOverflowItemVisible');\n return !hiddenSet.has(itemId);\n}\n\n/**\n * How much of the item group `groupId` is shown: `'visible'` (every member, and also a group\n * without items), `'hidden'` (none) or `'overflow'` (some). Must be called inside `Overflow`.\n */\nexport function useIsOverflowGroupVisible(groupId: string): OverflowGroupVisibility {\n const { groupVisibility } = useOverflowContext('useIsOverflowGroupVisible');\n return groupVisibility[groupId] ?? 'visible';\n}\n\n/**\n * Whether the enclosing {@link Overflow} currently hides at least one item (the button that the\n * `hasHiddenItems` prop reserves does not count). Must be called inside `Overflow`.\n */\nexport function useHasHiddenItems(): boolean {\n return useOverflowContext('useHasHiddenItems').hasHiddenItems;\n}\n\nfunction isElement(node: Node): node is Element {\n return node.nodeType === Node.ELEMENT_NODE;\n}\n\n/**\n * Keeps `observer` on the element children of `parent`: unobserves the removed ones and observes\n * the added ones that are still attached to `parent` (records are replayed in order, so a child\n * moved or re-added within one batch ends up observed exactly when it is present).\n */\nfunction followDirectChildren(\n observer: ResizeObserver,\n parent: Element,\n records: readonly MutationRecord[],\n): void {\n for (const record of records) {\n if (record.type !== 'childList' || record.target !== parent) continue;\n record.removedNodes.forEach((node) => {\n if (isElement(node)) observer.unobserve(node);\n });\n record.addedNodes.forEach((node) => {\n if (isElement(node) && node.parentNode === parent) observer.observe(node);\n });\n }\n}\n\n/** Tracks `scrollWidth > clientWidth` of one element. */\nclass OverflowingStore {\n private element: HTMLElement | null = null;\n private value = false;\n private readonly listeners = new Set<() => void>();\n private teardown: (() => void) | null = null;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): boolean => this.value;\n\n getServerSnapshot = (): boolean => false;\n\n /** Follows `element` (layout effect of every render); re-subscribes when it changes. */\n setElement(element: HTMLElement | null): void {\n if (element === this.element) return;\n this.disconnect();\n this.element = element;\n if (element) this.teardown = this.observe(element);\n this.check();\n }\n\n disconnect(): void {\n this.teardown?.();\n this.teardown = null;\n this.element = null;\n }\n\n private observe(element: HTMLElement): () => void {\n const check = () => this.check();\n const cleanups: Array<() => void> = [];\n\n // Resizes of the element and of its direct children (content that grows or shrinks).\n const resizeObserver = hasResizeObserver() ? new ResizeObserver(check) : null;\n if (resizeObserver) {\n resizeObserver.observe(element);\n for (const child of Array.from(element.children)) resizeObserver.observe(child);\n cleanups.push(() => resizeObserver.disconnect());\n } else if (typeof window !== 'undefined') {\n window.addEventListener('resize', check);\n cleanups.push(() => window.removeEventListener('resize', check));\n }\n\n // Content added, removed or edited. Only a change of the direct children changes what the\n // ResizeObserver watches, and only those children are (un)observed; text edits and deeper\n // changes just re-check.\n if (typeof MutationObserver !== 'undefined') {\n const mutationObserver = new MutationObserver((records) => {\n if (resizeObserver) followDirectChildren(resizeObserver, element, records);\n check();\n });\n mutationObserver.observe(element, { childList: true, subtree: true, characterData: true });\n cleanups.push(() => mutationObserver.disconnect());\n }\n\n return () => cleanups.forEach((cleanup) => cleanup());\n }\n\n private check(): void {\n const el = this.element;\n const next = el !== null && el.scrollWidth > el.clientWidth;\n if (next === this.value) return;\n this.value = next;\n for (const listener of Array.from(this.listeners)) listener();\n }\n}\n\nfunction isRefObject(\n target: React.RefObject<HTMLElement | null> | HTMLElement | null | undefined,\n): target is React.RefObject<HTMLElement | null> {\n return target != null && typeof target === 'object' && 'current' in target;\n}\n\n/**\n * Whether `target`'s content is wider than the element (`scrollWidth > clientWidth`).\n *\n * `target` is a ref object or the element itself (for example from callback-ref state:\n * `const [el, setEl] = useState(null)` + `ref={setEl}`). The hook re-checks when the element\n * resizes, when its direct children resize, and when content is added, removed or edited; an\n * element that mounts later (a ref attached conditionally) is picked up after the render that\n * mounts it. Without `ResizeObserver` it re-checks on window `resize` and content changes. Returns\n * `false` on the server.\n */\nexport function useIsOverflowing(\n target: React.RefObject<HTMLElement | null> | HTMLElement | null,\n): boolean {\n const [store] = React.useState(() => new OverflowingStore());\n const isOverflowing = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot,\n );\n const forceRender = useForceRender();\n\n // Every render: follow the element the ref points to now (cheap identity check). A change found\n // here re-renders from the layout phase, before paint: useSyncExternalStore only subscribes in a\n // passive effect, so on mount it would pick the first value up after the browser painted.\n React.useLayoutEffect(() => {\n const unsubscribe = store.subscribe(forceRender);\n store.setElement(isRefObject(target) ? target.current : target);\n unsubscribe();\n });\n\n React.useLayoutEffect(() => () => store.disconnect(), [store]);\n\n return isOverflowing;\n}\n\n// ---------------------------------------------------------------------------\n// Components\n// ---------------------------------------------------------------------------\n\nconst ROOT_ORIENTATION_CLASSES: Record<Orientation, string> = {\n horizontal: 'items-center',\n vertical: 'flex-col items-start',\n};\n\n// The divider stretches across the row (to its height, or to a column's width) and lays its child\n// out on the row's cross axis: a child that stretches itself (Toolbar.Divider) spans the row, and\n// an explicitly sized child is centred in a row and kept at the start of a column.\nconst DIVIDER_ORIENTATION_CLASSES: Record<Orientation, string> = {\n horizontal: 'flex shrink-0 items-center self-stretch',\n vertical: 'flex shrink-0 flex-col items-start self-stretch',\n};\n\n// The button sticks to the end of the axis and keeps room inside for its own focus indicator while\n// it covers an item. After the items it keeps 4px from the last one; between items it takes the\n// row's gap, as they do (its size never depends on where it stands).\nconst BUTTON_CLASSES = {\n end: {\n horizontal:\n 'sticky -end-1 flex shrink-0 items-center self-stretch ps-1 ' +\n 'data-[overflow-pinned]:bg-background data-[overflow-pinned]:pe-1',\n vertical:\n 'sticky -bottom-1 flex shrink-0 items-center self-stretch pt-1 ' +\n 'data-[overflow-pinned]:bg-background data-[overflow-pinned]:pb-1',\n },\n 'before-hidden': {\n horizontal:\n 'sticky -end-1 flex shrink-0 items-center self-stretch ' +\n 'data-[overflow-pinned]:bg-background data-[overflow-pinned]:pe-1',\n vertical:\n 'sticky -bottom-1 flex shrink-0 items-center self-stretch ' +\n 'data-[overflow-pinned]:bg-background data-[overflow-pinned]:pb-1',\n },\n} as const satisfies Record<\n NonNullable<OverflowProps['buttonPosition']>,\n Record<Orientation, string>\n>;\n\n/**\n * The key of the button among the children of a `before-hidden` row; the keys of flattened\n * children start with a dot.\n */\nconst BUTTON_KEY = 'wave-overflow-button';\n\n/** The element of an item that takes focus: the item itself, else a Tab stop or a focusable element in it. */\nfunction focusTargetIn(item: HTMLElement): HTMLElement | null {\n if (isFocusable(item)) return item;\n return (\n getFirstTabbable(item) ??\n Array.from(item.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).find(isFocusable) ??\n null\n );\n}\n\n/**\n * Where focus goes when the overflow button held it and went away (C-DISABLED): the first item\n * the button stood for (`wereHidden`, in DOM order) that can take focus; else the nearest item\n * before them, then the items after them. Without such items, the nearest item to the end.\n */\nfunction overflowFocusFallback(\n items: ReadonlyArray<{ element: HTMLElement; id: string }>,\n wereHidden: readonly string[],\n): HTMLElement | null {\n const hidden = new Set(wereHidden);\n const first = items.findIndex(({ id }) => hidden.has(id));\n const candidates =\n first < 0\n ? [...items].reverse()\n : [\n ...items.filter(({ id }) => hidden.has(id)),\n ...items.slice(0, first).reverse(),\n ...items.slice(first).filter(({ id }) => !hidden.has(id)),\n ];\n for (const { element } of candidates) {\n const target = focusTargetIn(element);\n if (target) return target;\n }\n return null;\n}\n\ninterface OverflowButtonSlotProps extends React.HTMLAttributes<HTMLDivElement> {\n store: OverflowStore;\n /** The items the button stands for. */\n hiddenIds: string[];\n /** The store's ref callback for the wrapper. */\n buttonRef: (node: HTMLDivElement | null) => void;\n}\n\n/**\n * The overflow button's wrapper (internal). When every item fits again it unmounts; focus that it\n * held then moves to the first item it stood for (the items hidden at its last commit), so it\n * never falls to the body (`usePreserveFocus`). Focus inside the button's menu is not inside the\n * wrapper, so an open menu keeps its own focus return.\n */\nfunction OverflowButtonSlot({ store, hiddenIds, buttonRef, ...rest }: OverflowButtonSlotProps) {\n const elementRef = React.useRef<HTMLDivElement>(null);\n const ref = useMergedRefs<HTMLDivElement>(buttonRef, elementRef);\n const wereHiddenRef = React.useRef<readonly string[]>(NO_IDS);\n React.useLayoutEffect(() => {\n wereHiddenRef.current = hiddenIds;\n });\n usePreserveFocus(elementRef, () =>\n overflowFocusFallback(store.getItemElements(), wereHiddenRef.current),\n );\n return <div ref={ref} {...rest} />;\n}\nOverflowButtonSlot.displayName = 'OverflowButtonSlot';\n\n/**\n * The children of a `before-hidden` row with the button just before the item `firstHiddenId`\n * (Fragments and arrays opened, every child keyed, so the button moves without remounting), and\n * whether that item could not be found (the button is then last).\n */\nfunction placeButtonBeforeHidden(\n children: React.ReactNode,\n button: React.ReactElement | null,\n firstHiddenId: string | undefined,\n): { nodes: React.ReactNode[]; missing: boolean } {\n const nodes = flattenChildren(children).map(({ key, node }) =>\n React.isValidElement(node) ? React.cloneElement(node, { key }) : node,\n );\n if (!button) return { nodes, missing: false };\n const index =\n firstHiddenId === undefined\n ? -1\n : nodes.findIndex(\n (node) =>\n isElementOfType<{ itemId?: string }>(node, OverflowItem) &&\n node.props.itemId === firstHiddenId,\n );\n nodes.splice(index < 0 ? nodes.length : index, 0, button);\n return { nodes, missing: firstHiddenId !== undefined && index < 0 };\n}\n\nconst OverflowRoot = ({\n overflowButton,\n buttonPosition = 'end',\n overflowDirection = 'end',\n orientation = 'horizontal',\n minimumVisible = 0,\n hasHiddenItems = false,\n onOverflowChange,\n children,\n className,\n ref,\n ...rest\n}: OverflowProps) => {\n const [store] = React.useState(() => new OverflowStore());\n const hiddenIds = React.useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n store.getServerSnapshot,\n );\n const measured = React.useSyncExternalStore(\n store.subscribe,\n store.getMeasured,\n store.getServerFlag,\n );\n const buttonCovers = React.useSyncExternalStore(\n store.subscribe,\n store.getButtonCovers,\n store.getServerFlag,\n );\n const groupVisibility = React.useSyncExternalStore(\n store.subscribe,\n store.getGroups,\n store.getServerGroups,\n );\n const setContainer = React.useCallback(\n (node: HTMLDivElement | null) => store.setContainer(node),\n [store],\n );\n const setButton = React.useCallback(\n (node: HTMLDivElement | null) => store.setButton(node),\n [store],\n );\n const containerRef = useMergedRefs<HTMLDivElement>(ref, setContainer);\n const forceRender = useForceRender();\n\n // The props the measurement depends on, before the observers connect (the effects of one\n // component run in order), so the first measurement already uses them.\n React.useLayoutEffect(() => {\n store.setConfig({ direction: overflowDirection, orientation, minimumVisible, hasHiddenItems });\n }, [store, overflowDirection, orientation, minimumVisible, hasHiddenItems]);\n\n // Observers are created once per instance (not per render or per children change). The first\n // measurement (in connect) re-renders from this layout effect, before paint: useSyncExternalStore\n // only subscribes in a passive effect, which can run after the browser painted every item.\n React.useLayoutEffect(() => {\n const unsubscribe = store.subscribe(forceRender);\n const disconnect = store.connect();\n unsubscribe();\n return disconnect;\n }, [store, forceRender]);\n\n // After every commit of the root (new children, a keyed reorder): items moved without any size\n // change or registration are re-measured before paint. Cheap when nothing moved.\n React.useLayoutEffect(() => {\n store.checkOrder();\n });\n\n const hiddenSet = React.useMemo(() => new Set(hiddenIds), [hiddenIds]);\n // The overflowButton's own copy (consumers may sort it in place).\n const buttonIds = React.useMemo(() => [...hiddenIds], [hiddenIds]);\n const hiddenCount = hiddenIds.length;\n const ctx = React.useMemo<OverflowContextValue>(\n () => ({\n store,\n hiddenIds,\n hiddenSet,\n groupVisibility,\n direction: overflowDirection,\n orientation,\n hasHiddenItems: hiddenCount > 0,\n }),\n [store, hiddenIds, hiddenSet, groupVisibility, overflowDirection, orientation, hiddenCount],\n );\n\n // Reported from an effect, once per change of the hidden set (the initial, empty set is no\n // change). The last reported set outlives the StrictMode effect replay, so it reports once.\n const emitOverflowChange = useEventCallback(onOverflowChange);\n const reported = React.useRef<string[]>(NO_IDS);\n const hasButton = overflowButton !== undefined;\n React.useEffect(() => {\n // The store's current set, and only once this render shows it: measuring the button that the\n // first hidden items bring in can hide more before the browser paints, and a re-render with\n // the final set always follows.\n const current = store.getSnapshot();\n if (!sameIds(current, hiddenIds) || !store.isSettled(hasButton)) return;\n if (sameIds(current, reported.current)) return;\n reported.current = current;\n emitOverflowChange([...current], {\n visibleItems: store.getVisibleIds(),\n // The consumer's own copy, without a prototype as the store's record: a group id such as\n // `constructor` or `__proto__` is an entry like any other, and an absent one reads nothing.\n groupVisibility: Object.assign(\n Object.create(null) as Record<string, OverflowGroupVisibility>,\n store.getGroups(),\n ),\n });\n }, [store, hiddenIds, hasButton, emitOverflowChange]);\n\n const button =\n (hiddenCount > 0 || (hasHiddenItems && !measured)) && overflowButton ? (\n // In the row's flow (it adds to the row height and follows justify-*), sticking to the end\n // of the axis when the visible items are wider than the room beside it. Browsers stop a\n // sticky element at the scroll container's padding, so -end-1 lets it reach the clipping\n // edge, and while pinned it keeps 4px inside for its own focus indicator. (WebKit stops a\n // sticky element short of the inline end of a right-to-left row; it stays in the row.)\n <OverflowButtonSlot\n key={BUTTON_KEY}\n store={store}\n hiddenIds={hiddenIds}\n buttonRef={setButton}\n // A list row (role=\"list\", a Breadcrumb trail) holds only list items.\n role={rest.role === 'list' ? 'listitem' : undefined}\n data-overflow-button=\"\"\n data-overflow-pinned={buttonCovers ? '' : undefined}\n className={cn(\n overflowClassNames.overflowButton,\n BUTTON_CLASSES[buttonPosition][orientation],\n )}\n >\n {overflowButton(hiddenCount, buttonIds)}\n </OverflowButtonSlot>\n ) : null;\n // `before-hidden`: the button stands just before the first hidden item (hiddenIds are in DOM\n // order).\n const placed =\n buttonPosition === 'before-hidden'\n ? placeButtonBeforeHidden(children, button, hiddenIds[0])\n : null;\n const unplaced = placed?.missing ?? false;\n React.useEffect(() => {\n if (!unplaced) return;\n warnOnce(\n 'Overflow:button-position',\n 'Overflow: buttonPosition=\"before-hidden\" puts the button before the first hidden ' +\n 'item only when that item is a child of the Overflow (Fragments and arrays are opened), ' +\n 'not one rendered by another component; the button is rendered after the items instead.',\n );\n }, [unplaced]);\n\n return (\n <OverflowContext.Provider value={ctx}>\n <div\n ref={containerRef}\n // The row clips its content at its padding edge: the 4px padding leaves room for the focus\n // indicator a focused item draws 4px around itself. No negative margin offsets it: the\n // row's box would then reach past its container, which a scroll container around an\n // edge-to-edge row (or the page) counts as overflow. The store measures the room without\n // the padding.\n className={cn(\n overflowClassNames.root,\n 'flex overflow-hidden p-1',\n ROOT_ORIENTATION_CLASSES[orientation],\n className,\n )}\n data-orientation={orientation}\n data-overflow-direction={overflowDirection}\n data-button-position={buttonPosition}\n {...rest}\n >\n {placed ? placed.nodes : children}\n {placed ? null : button}\n </div>\n </OverflowContext.Provider>\n );\n};\nOverflowRoot.displayName = 'Overflow';\n\n/**\n * One entry of an {@link Overflow}. `priority` (higher overflows later, default 0) or `pinned`\n * (never overflows) decide when it hides; setting either on any item makes every item without\n * `pinned` hidable, the first one included. `groupId` puts it in a group that an\n * {@link OverflowDivider} and {@link useIsOverflowGroupVisible} follow. While it does not fit it\n * stays mounted but is hidden (`data-overflow-hidden` and an inline `display: none` placed after\n * the consumer's own `style`), `aria-hidden` and `inert`. The inline style wins over the\n * consumer's `style.display` and over display utilities in any cascade layer (a prefixed Tailwind\n * app's `tw:flex` included), so a hidden item is never shown while it is counted in \"+N\". With\n * `asChild` the item renders no wrapper: its props are merged onto its single element child.\n * Must be rendered inside `Overflow`.\n */\nexport const OverflowItem = ({\n itemId,\n priority,\n pinned = false,\n groupId,\n asChild = false,\n children,\n className,\n style,\n ref,\n 'aria-hidden': ariaHidden,\n inert,\n ...rest\n}: OverflowItemProps) => {\n const { store, hiddenSet } = useOverflowContext('OverflowItem');\n const isHidden = hiddenSet.has(itemId);\n React.useEffect(() => store.registerItemId(itemId), [store, itemId]);\n\n // asChild: the single element (a Fragment around one is unwrapped) that takes the item's props.\n const child = asChild ? unwrapFragment(children) : undefined;\n const childElement = isCloneableElement(child) ? child : null;\n const childProps = childElement ? (childElement.props as Record<string, unknown>) : null;\n const { ref: childRef, ...ownChildProps } = childProps ?? {};\n const wrapsChildren = asChild && childElement === null && children != null;\n React.useEffect(() => {\n if (!wrapsChildren) return;\n warnOnce(\n 'Overflow.Item:as-child-children',\n 'Overflow.Item: asChild expects a single React element child (not text or several ' +\n 'elements); the children are rendered inside a <div> instead.',\n );\n }, [wrapsChildren]);\n\n const registerRef = React.useCallback(\n (node: HTMLElement | null) => (node ? store.registerItem(node, itemId) : undefined),\n [store, itemId],\n );\n const elementRef = React.useRef<HTMLElement | null>(null);\n const mergedRef = useMergedRefs<HTMLElement>(\n ref as React.Ref<HTMLElement> | undefined,\n registerRef,\n elementRef,\n childRef as React.Ref<HTMLElement> | undefined,\n );\n // After the ref has registered the item: its priority, pinned state or group re-measures the\n // row. Runs after every commit, not only when these change: registering an element (with asChild\n // the element is replaced by a toggle, a child of another type or key) resets what the store\n // knows about it, and the call is a no-op while nothing differs.\n React.useLayoutEffect(() => {\n if (elementRef.current) store.setItemMeta(elementRef.current, priority, pinned, groupId);\n });\n\n const itemClassName = cn(overflowItemClassNames.root, 'shrink-0', className);\n\n if (childElement) {\n // Only a hidden item sets these (and a consumer's own values), so a shown item keeps the\n // child's.\n const hiddenProps: Record<string, unknown> = isHidden\n ? { 'aria-hidden': true, inert: true, 'data-overflow-hidden': '' }\n : {};\n if (!isHidden && ariaHidden !== undefined) hiddenProps['aria-hidden'] = ariaHidden;\n if (!isHidden && inert !== undefined) hiddenProps.inert = inert;\n const merged = mergeProps(\n { ...rest, ...hiddenProps, className: itemClassName, style },\n ownChildProps,\n { oursWin: ['aria-hidden', 'inert', 'data-overflow-hidden'] },\n );\n // The hidden display wins over the child's own style, as it does over the consumer's.\n const mergedStyle = merged.style as React.CSSProperties | undefined;\n return React.cloneElement(childElement, {\n ...merged,\n ref: mergedRef,\n style: isHidden ? { ...mergedStyle, display: 'none' } : mergedStyle,\n } as Record<string, unknown>);\n }\n\n return (\n <div\n ref={mergedRef as React.Ref<HTMLDivElement>}\n className={itemClassName}\n {...rest}\n style={isHidden ? { ...style, display: 'none' } : style}\n aria-hidden={isHidden ? true : ariaHidden}\n inert={isHidden ? true : inert}\n data-overflow-hidden={isHidden ? '' : undefined}\n >\n {children}\n </div>\n );\n};\nOverflowItem.displayName = 'OverflowItem';\n\n/**\n * A divider between item groups of an {@link Overflow}, drawn by its children (for example a\n * vertical `Divider` or a `Toolbar.Divider`). It renders a `<div>` that stretches across the row\n * (to the row's height, or to a vertical column's width) and lays out its child on that axis, so\n * a child that stretches itself, such as `Toolbar.Divider`, spans the row; an explicitly sized\n * child is centred in a row and kept at the start of a column. It is measured like an item and\n * hidden, with `data-overflow-hidden`, an inline `display: none`, `aria-hidden` and `inert`, while\n * the group `groupId` is `'hidden'` (none of its items is shown). Must be rendered inside\n * `Overflow`.\n */\nexport const OverflowDivider = ({\n groupId,\n children,\n className,\n style,\n ref,\n 'aria-hidden': ariaHidden,\n inert,\n ...rest\n}: OverflowDividerProps) => {\n const { store, groupVisibility, orientation } = useOverflowContext('OverflowDivider');\n const isHidden = groupVisibility[groupId] === 'hidden';\n const registerRef = React.useCallback(\n (node: HTMLDivElement | null) => (node ? store.registerDivider(node, groupId) : undefined),\n [store, groupId],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, registerRef);\n\n return (\n <div\n ref={mergedRef}\n className={cn(\n overflowDividerClassNames.root,\n DIVIDER_ORIENTATION_CLASSES[orientation],\n className,\n )}\n {...rest}\n style={isHidden ? { ...style, display: 'none' } : style}\n aria-hidden={isHidden ? true : ariaHidden}\n inert={isHidden ? true : inert}\n data-overflow-hidden={isHidden ? '' : undefined}\n >\n {children}\n </div>\n );\n};\nOverflowDivider.displayName = 'OverflowDivider';\n\n/**\n * A single row (or column) that hides the items which do not fit and shows an overflow button\n * instead.\n *\n * Wrap each entry in {@link OverflowItem} with a unique `itemId`; the row holds only items and\n * {@link OverflowDivider}s (other content is not measured, see `children`). Items are measured\n * while visible and hidden while they do not fit: by ascending `priority` (equal priorities from\n * the end of the DOM order, or from its start with `overflowDirection=\"start\"`), never a `pinned`\n * item and never below `minimumVisible`. Until an item sets `priority` or `pinned`, the first item\n * (`end`) or the last one (`start`) always stays, as in 0.13. `orientation=\"vertical\"` lays the\n * items out in a column and measures heights; the column needs a definite height. The room is the\n * row's own box, so it must not depend on the items shown: in a container as wide as its content,\n * such as a Toolbar at its default width, the row narrows as items hide and never gets the room\n * back to show them again; give the Overflow a width of its own, or put it in a row that takes its\n * width from its parent and let it fill that row.\n *\n * Items with the same `groupId` form a group that is `'visible'`, `'hidden'` or `'overflow'` (some\n * members hidden): a divider with that `groupId` hides with a hidden group,\n * {@link useIsOverflowGroupVisible} reads a group and {@link useHasHiddenItems} whether anything\n * is hidden. `onOverflowChange` reports the hidden `itemId`s and the group visibility when the\n * hidden items change. Hidden items get `data-overflow-hidden`, an inline `display: none`,\n * `aria-hidden` and `inert`. Reordered items (for example a keyed sort) are re-measured in their\n * new order. `overflowButton(count, hiddenIds)` renders the button after the visible items, or\n * just before the first hidden item with `buttonPosition=\"before-hidden\"` (its measured size is\n * reserved); components inside it can use {@link useOverflowMenu} to list the\n * hidden items (e.g. in a Menu), and {@link useIsOverflowItemVisible} reports a single item. In a\n * horizontal row the button sticks to the inline end, so a first item wider than the room beside\n * it cannot push it out of view: it then covers the end of that item and gets\n * `data-overflow-pinned`, with the `background` token behind it (a vertical column sticks it to\n * the bottom). (In a right-to-left row, WebKit stops the pinned button short of the end, still\n * inside the row.)\n *\n * The row clips what does not fit. So that the focus indicators of its items are not cut off, it\n * has a 4px padding: the items sit 4px in from its edges, and the row is 8px taller than they are.\n * An explicit width (such as `w-full` or a style width) includes that padding. The row never\n * reaches past its own box, so an edge-to-edge row adds no scrollbar to the page or to a scroll\n * container around it. A negative margin of 4px lines the items up with the content around the\n * row; add it only where nothing within 4px of the row scrolls (the row's box then reaches 4px past\n * its container on every side). `p-0` removes the room (focus indicators at the row's edges are\n * then clipped).\n *\n * Works without `ResizeObserver` (jsdom, old browsers): it then re-measures on window resize and\n * when items mount, unmount or move.\n *\n * The item is also `Overflow.Item` and the divider `Overflow.Divider`. The same components are\n * exported as `OverflowItem` and `OverflowDivider`; React Server Components import those flat names\n * (dotted access needs a client file).\n */\nexport const Overflow = /* @__PURE__ */ Object.assign(OverflowRoot, {\n Item: OverflowItem,\n Divider: OverflowDivider,\n});\n"],"mappings":"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"}
|