@mortenbrudvik/waveui 0.14.0 → 0.15.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 +142 -32
- package/dist/components/data-display/InfoButton.cjs +1 -1
- package/dist/components/data-display/InfoButton.cjs.map +1 -1
- package/dist/components/data-display/InfoButton.mjs +90 -82
- package/dist/components/data-display/InfoButton.mjs.map +1 -1
- package/dist/components/data-display/InfoLabel.cjs +1 -1
- package/dist/components/data-display/InfoLabel.cjs.map +1 -1
- package/dist/components/data-display/InfoLabel.mjs +19 -18
- package/dist/components/data-display/InfoLabel.mjs.map +1 -1
- package/dist/components/feedback/MessageBarGroup.cjs +2 -0
- package/dist/components/feedback/MessageBarGroup.cjs.map +1 -0
- package/dist/components/feedback/MessageBarGroup.mjs +63 -0
- package/dist/components/feedback/MessageBarGroup.mjs.map +1 -0
- package/dist/components/feedback/ProgressBar.cjs +1 -1
- package/dist/components/feedback/ProgressBar.cjs.map +1 -1
- package/dist/components/feedback/ProgressBar.mjs +41 -39
- package/dist/components/feedback/ProgressBar.mjs.map +1 -1
- package/dist/components/feedback/Toaster.cjs +1 -1
- package/dist/components/feedback/Toaster.cjs.map +1 -1
- package/dist/components/feedback/Toaster.mjs +222 -216
- package/dist/components/feedback/Toaster.mjs.map +1 -1
- package/dist/components/layout/Accordion.cjs +1 -1
- package/dist/components/layout/Accordion.cjs.map +1 -1
- package/dist/components/layout/Accordion.mjs +124 -109
- package/dist/components/layout/Accordion.mjs.map +1 -1
- package/dist/components/layout/Carousel.cjs +1 -1
- package/dist/components/layout/Carousel.cjs.map +1 -1
- package/dist/components/layout/Carousel.mjs +207 -193
- package/dist/components/layout/Carousel.mjs.map +1 -1
- package/dist/components/layout/TabList.cjs +1 -1
- package/dist/components/layout/TabList.cjs.map +1 -1
- package/dist/components/layout/TabList.mjs +149 -108
- package/dist/components/layout/TabList.mjs.map +1 -1
- package/dist/components/layout/Tree.cjs.map +1 -1
- package/dist/components/layout/Tree.context.cjs +1 -1
- package/dist/components/layout/Tree.context.cjs.map +1 -1
- package/dist/components/layout/Tree.context.mjs +2 -1
- package/dist/components/layout/Tree.context.mjs.map +1 -1
- package/dist/components/layout/Tree.core.cjs +1 -1
- package/dist/components/layout/Tree.core.cjs.map +1 -1
- package/dist/components/layout/Tree.core.mjs +178 -165
- package/dist/components/layout/Tree.core.mjs.map +1 -1
- package/dist/components/layout/Tree.mjs.map +1 -1
- package/dist/components/navigation/Menu.popover.cjs +1 -1
- package/dist/components/navigation/Menu.popover.cjs.map +1 -1
- package/dist/components/navigation/Menu.popover.mjs +154 -168
- package/dist/components/navigation/Menu.popover.mjs.map +1 -1
- package/dist/components/navigation/Nav.cjs +1 -1
- package/dist/components/navigation/Nav.cjs.map +1 -1
- package/dist/components/navigation/Nav.mjs +156 -136
- package/dist/components/navigation/Nav.mjs.map +1 -1
- package/dist/components/navigation/NavDrawer.cjs +1 -1
- package/dist/components/navigation/NavDrawer.cjs.map +1 -1
- package/dist/components/navigation/NavDrawer.mjs +48 -45
- package/dist/components/navigation/NavDrawer.mjs.map +1 -1
- package/dist/components/overlays/Dialog.cjs +1 -1
- package/dist/components/overlays/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog.mjs +128 -122
- package/dist/components/overlays/Dialog.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 +12 -12
- package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
- package/dist/components/overlays/Drawer.cjs.map +1 -1
- package/dist/components/overlays/Drawer.mjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.cjs +1 -1
- package/dist/components/overlays/Drawer.panel.cjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.mjs +97 -81
- package/dist/components/overlays/Drawer.panel.mjs.map +1 -1
- package/dist/components/overlays/Drawer.root.cjs +1 -1
- package/dist/components/overlays/Drawer.root.cjs.map +1 -1
- package/dist/components/overlays/Drawer.root.mjs +34 -31
- package/dist/components/overlays/Drawer.root.mjs.map +1 -1
- package/dist/components/overlays/Popover.cjs +1 -1
- package/dist/components/overlays/Popover.cjs.map +1 -1
- package/dist/components/overlays/Popover.mjs +231 -216
- package/dist/components/overlays/Popover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.parts.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.parts.mjs +202 -173
- package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.root.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.root.mjs +108 -99
- package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -1
- package/dist/components/overlays/Tooltip.cjs +1 -1
- package/dist/components/overlays/Tooltip.cjs.map +1 -1
- package/dist/components/overlays/Tooltip.mjs +66 -61
- package/dist/components/overlays/Tooltip.mjs.map +1 -1
- package/dist/components/provider/WaveProvider.cjs +1 -1
- package/dist/components/provider/WaveProvider.cjs.map +1 -1
- package/dist/components/provider/WaveProvider.mjs +26 -23
- package/dist/components/provider/WaveProvider.mjs.map +1 -1
- package/dist/hooks/useCollapsePresence.cjs +2 -0
- package/dist/hooks/useCollapsePresence.cjs.map +1 -0
- package/dist/hooks/useCollapsePresence.mjs +21 -0
- package/dist/hooks/useCollapsePresence.mjs.map +1 -0
- package/dist/hooks/useFocusBeforeClose.cjs +2 -0
- package/dist/hooks/useFocusBeforeClose.cjs.map +1 -0
- package/dist/hooks/useFocusBeforeClose.mjs +33 -0
- package/dist/hooks/useFocusBeforeClose.mjs.map +1 -0
- package/dist/hooks/useMotion.cjs +2 -0
- package/dist/hooks/useMotion.cjs.map +1 -0
- package/dist/hooks/useMotion.mjs +14 -0
- package/dist/hooks/useMotion.mjs.map +1 -0
- package/dist/hooks/usePresenceGroup.cjs +2 -0
- package/dist/hooks/usePresenceGroup.cjs.map +1 -0
- package/dist/hooks/usePresenceGroup.mjs +68 -0
- package/dist/hooks/usePresenceGroup.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +721 -131
- package/dist/index.d.ts +721 -131
- package/dist/index.mjs +136 -135
- package/dist/lib/classNames.cjs +1 -1
- package/dist/lib/classNames.cjs.map +1 -1
- package/dist/lib/classNames.mjs +101 -90
- package/dist/lib/classNames.mjs.map +1 -1
- package/dist/lib/motion.cjs +2 -0
- package/dist/lib/motion.cjs.map +1 -0
- package/dist/lib/motion.mjs +43 -0
- package/dist/lib/motion.mjs.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +2 -1
|
@@ -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","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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"}
|
|
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","DEFAULT_MOTION_DURATION","defaultSlidesLabel","start","end","useAutoPageSize","subscribe","enabled","root","observer","notify","slide","perPage","slideWidth","rootWidth","requestedCarouselMotion","motion","preference","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","requestedMotion","useMotionPreference","fadeFallback","resolvedMotion","warnOnce","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","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","fading","trackMoves","durationStyle","motionDuration","slideLayout","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 { carouselFadeMotion, carouselSlideMotion } from '../../lib/motion';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\nimport type { MotionPreference, 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 { useMotionPreference } from '../../hooks/useMotion';\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/**\n * How a Carousel moves between pages: `slide` moves the slides in from the side of the page order,\n * `fade` cross-fades them in place (one slide per page only).\n */\nexport type CarouselMotion = 'slide' | 'fade';\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. Under `motion=\"fade\"` the slides do not\n * follow the pointer (they share one place): the same drag still changes the page on release,\n * and the slides cross-fade. The click that ends a drag is not delivered to the slide, and a\n * vertical swipe still scrolls the page. Dragging pauses autoplay like the pointer over the\n * carousel does. The buttons and the keyboard stay the way to operate the carousel without a\n * 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 /**\n * How the carousel moves between pages: `slide` glides the slides in from the side of the page\n * order (mirrored in right-to-left layouts), `fade` cross-fades them in place, and `null` turns\n * the motion off (the page changes at once). Fluent's `motion`; its object form with a\n * `duration` is not offered: use `motionDuration`. `fade` needs one slide per page: with\n * `groupSize` above 1 or `'auto'` the slides slide, and a development warning says so. Under\n * `fade` a drag still changes the page on release, but the slides do not follow the pointer.\n * Below a `WaveProvider` with `motion=\"none\"` the carousel does not move unless this prop is\n * set. Either motion is off while the user prefers reduced motion. The root renders the motion\n * it resolves from this prop, `groupSize` and the provider as `data-motion` (`slide`, `fade` or\n * `none`); reduced motion leaves it unchanged.\n * @default 'slide'\n */\n motion?: CarouselMotion | null;\n /**\n * How long the slide or the fade takes, in milliseconds. Fluent's `duration` is a different\n * unit (Embla's unitless speed, 20 to 60), so a value ported from Fluent is far too short.\n * @default 300\n */\n motionDuration?: number;\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/** The default `motionDuration`: the slow duration token, which the motion classes carry. */\nconst DEFAULT_MOTION_DURATION = 300;\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\n/**\n * The motion a carousel asks for: its own `motion` (`null` none), else none below a provider that\n * turns motion off, else the slide.\n */\nfunction requestedCarouselMotion(\n motion: CarouselMotion | null | undefined,\n preference: MotionPreference,\n): CarouselMotion | 'none' {\n if (motion === undefined) return preference === 'none' ? 'none' : 'slide';\n if (motion === null) return 'none';\n return motion === 'fade' ? 'fade' : 'slide';\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 motion,\n motionDuration = DEFAULT_MOTION_DURATION,\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 // The motion: the carousel's own, else none under a provider that turns motion off, else the\n // slide. A fade needs one slide per page, so pages of several slides slide (warned below).\n const requestedMotion = requestedCarouselMotion(motion, useMotionPreference());\n const fadeFallback = requestedMotion === 'fade' && (auto || size > 1);\n const resolvedMotion = fadeFallback ? 'slide' : requestedMotion;\n\n React.useEffect(() => {\n if (fadeFallback) {\n warnOnce(\n 'Carousel:fade-group',\n 'Carousel: `motion=\"fade\"` needs one slide per page; with `groupSize` above 1 or ' +\n '`\"auto\"` the slides slide.',\n );\n }\n }, [fadeFallback]);\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 data-motion={resolvedMotion}\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 // The slide moves the track; the fade stacks the slides in the track's one cell and hides the\n // inactive ones by their opacity (they are inert either way), with no transform, so a drag\n // pages on release but the slides do not follow the pointer. The track's transition is off\n // while it follows a drag.\n const fading = resolvedMotion === 'fade';\n const trackMoves = resolvedMotion === 'slide' && !drag.dragging;\n // A `motionDuration` other than the motion classes' own is an inline duration on the element\n // that transitions (D4), written only while that element has its transition: without a\n // property list, an inline duration would time every property.\n const durationStyle =\n motionDuration === DEFAULT_MOTION_DURATION\n ? undefined\n : { transitionDuration: `${motionDuration}ms` };\n // A slide is as wide as its content (`auto`), the viewport (one per page) or its share of it;\n // under the fade it fills the track's one cell, which every slide shares.\n const slideLayout = fading\n ? 'col-start-1 row-start-1'\n : auto\n ? 'w-auto shrink-0'\n : size === 1\n ? 'w-full shrink-0'\n : 'shrink-0';\n const slideWidth = !auto && size > 1 ? { width: `calc(100% / ${size})` } : undefined;\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 // One column with a zero minimum: the slides keep the viewport's width, whatever their\n // content's longest line.\n fading ? 'grid grid-cols-[minmax(0,1fr)]' : 'flex',\n trackMoves && carouselSlideMotion,\n // Horizontal pointer moves belong to the drag; a vertical swipe still scrolls the page.\n draggable && 'touch-pan-y',\n )}\n style={fading ? undefined : { transform, ...(trackMoves ? durationStyle : undefined) }}\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 slideLayout,\n fading && carouselFadeMotion,\n fading && !active && 'opacity-0',\n grouped &&\n 'focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring',\n )}\n style={fading ? durationStyle : slideWidth}\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 data-motion={resolvedMotion}\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 * - The slides glide to the new page over 300 ms; `motion=\"fade\"` cross-fades them instead (one\n * slide per page), `motion={null}` turns the motion off and `motionDuration` times it. Under\n * reduced motion, or below a `WaveProvider` with `motion=\"none\"` (unless `motion` is set), the\n * page changes at once.\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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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
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/slot.cjs"),a=require("../../lib/composeEventHandlers.cjs"),o=require("../../lib/classNames.cjs"),s=require("../../hooks/useEventCallback.cjs"),c=require("../../hooks/useControllable.cjs"),l=require("../../hooks/useId.cjs"),u=require("../../hooks/useRovingTabIndex.cjs"),d=require("../../hooks/useMergedRefs.cjs"),f=require("../../lib/styles.cjs"),p=require("./disclosureIds.cjs");let m=require("react");m=e.__toESM(m,1);let h=require("react/jsx-runtime");function g(e){r.warnOnce(`TabList:duplicate:${e}`,`TabList: several tabs share the value "${e}". Tab values must be unique within a TabList; tabs with the same value share one id and are selected (and tab stops) together.`)}function _(){let e={tab:new Map,panel:new Map},t=new Set,n=!1,r=()=>{t.forEach(e=>e())};return{register(t,n,i){let a=e[t],o=a.get(n)??[];return t===`tab`&&o.length>0&&g(n),a.set(n,[...o,i]),r(),()=>{let e=[...a.get(n)??[]],t=e.indexOf(i);t!==-1&&e.splice(t,1),e.length>0?a.set(n,e):a.delete(n),r()}},get:(t,r)=>n?e[t].get(r)?.[0]??null:void 0,markReady(){n||(n=!0,r())},subscribe(e){return t.add(e),()=>{t.delete(e)}}}}var v={register:()=>()=>{},get:()=>void 0,markReady:()=>{},subscribe:()=>()=>{}},y=m.createContext(null),b={orientation:`horizontal`,appearance:`transparent`,size:`medium`,isSelected:()=>!1,select:()=>{},getTabIndex:()=>-1,getGeneratedId:(e,t)=>`wave-tablist-inert-${e}-${t}`,getStaticTabId:e=>`wave-tablist-inert-tab-${e}`,getStaticPanelId:()=>void 0,registry:v};function x(e){return m.useContext(y)||(r.reportMissingContext(e,`<TabList>`),b)}function S(e){let t=e[`aria-disabled`];return e.disabled===!0||t===!0||t===`true`}function C(e){return typeof e==`string`&&e!==``?e:null}function w(e,t){if(Array.isArray(e))return e.forEach(e=>w(e,t)),t;if(!m.isValidElement(e))return t;let{props:r}=e,i=n.getElementType(e,{suspend:!1}),a=typeof r.value==`string`?r.value:void 0;if(i===P){if(a!==void 0){t.firstEnabled===void 0&&!S(r)&&(t.firstEnabled=a);let e=C(r.id);e!==null&&t.tabIds.push([a,e])}return t}return i===F?(a!==void 0&&t.panels.push([a,C(r.id)]),t):i===k?t:w(r.children,t)}function T(e,t){if(Array.isArray(e))return e.some(e=>T(e,t));if(!m.isValidElement(e))return!1;let r=n.getElementType(e,{suspend:!1});return r===P?t===`tab`:r===F||r===I?t===`panel`:r!==k&&T(e.props.children,t)}function E(e){return T(e,`panel`)&&!T(e,`tab`)}var D=m.createContext(null),O=`TabList.Panel was rendered inside the role="tablist" element, where only tabs belong (axe aria-required-children). The TabList moves a Panel after the tablist when it is its child, or in a wrapper that holds no Tab, but it cannot see a Panel that a component renders itself, or separate a wrapper's Panels from its Tabs. Place such panels inside TabList.Panels, which renders after the tablist.`,k=({value:e,defaultValue:i,onValueChange:f,orientation:g,appearance:v=`transparent`,size:b=`medium`,selectTabOnFocus:x=!0,selectedValue:S,defaultSelectedValue:C,onTabSelect:T,vertical:O,className:k,children:A,onKeyDown:j,onFocus:M,ref:N,...P})=>{let F=r.resolveDeprecatedProp(`TabList`,e,S,`selectedValue`,`value`),I=r.resolveDeprecatedProp(`TabList`,i,C,`defaultSelectedValue`,`defaultValue`),L=r.resolveDeprecatedProp(`TabList`,g,O===void 0?void 0:O?`vertical`:`horizontal`,`vertical`,`orientation`)??`horizontal`;T&&r.warnDeprecated(`TabList`,`onTabSelect`,`onValueChange`,"`onValueChange` is called only when the selected tab changes.");let[R,z,B]=c.useControllable(F,I??``,f),V=JSON.stringify(w(A,{tabIds:[],panels:[]})),H=m.useMemo(()=>{let e=JSON.parse(V);return{firstEnabled:e.firstEnabled,tabIds:new Map(e.tabIds),panels:new Map(e.panels)}},[V]),U=!B&&R===``,{containerProps:W,getTabIndex:G}=u.useRovingTabIndex({activeValue:U?H.firstEnabled??null:R,orientation:L,loop:!0,onFocusMove:x?e=>q(e):void 0}),K=m.useCallback(e=>U?G(e)===0:R===e,[U,G,R]),q=s.useEventCallback(e=>{T?.(e),K(e)||z(e)}),J=l.useId(`tablist`),[Y]=m.useState(_);m.useLayoutEffect(()=>Y.markReady(),[Y]);let X=m.useMemo(()=>({orientation:L,appearance:v,size:b,isSelected:K,select:q,getTabIndex:G,getGeneratedId:(e,t)=>p.getPartId(J,e,t),getStaticTabId:e=>H.tabIds.get(e)??p.getPartId(J,`tab`,e),getStaticPanelId:e=>{let t=H.panels.get(e);if(t!==void 0)return t??p.getPartId(J,`panel`,e)},registry:Y}),[L,v,b,K,q,G,J,H,Y]),ee=d.useMergedRefs(N,W.ref),Z=[],Q=[];n.flattenChildren(A).forEach(({key:e,node:t})=>{let n=(0,h.jsx)(m.Fragment,{children:t},e);(E(t)?Q:Z).push(n)});let $=L===`vertical`;return(0,h.jsx)(y.Provider,{value:X,children:(0,h.jsxs)(`div`,{className:t.cn($&&`flex`),children:[(0,h.jsx)(`div`,{role:`tablist`,"aria-orientation":L,"data-appearance":v,"data-size":b,"data-orientation":L,className:t.cn(o.tabListClassNames.root,$?`flex w-40 flex-col`:`flex`,v===`transparent`?$?`border-e border-border`:`border-b border-border`:`gap-1`,k),...P,"data-roving-container":``,onKeyDown:a.composeEventHandlers(j,W.onKeyDown),onFocus:a.composeEventHandlers(M,W.onFocus,{checkDefaultPrevented:!1}),ref:ee,children:(0,h.jsx)(D.Provider,{value:`tabs`,children:Z})}),(0,h.jsx)(D.Provider,{value:`panels`,children:Q})]})})};k.displayName=`TabList`;var A={small:`px-3 py-1.5`,medium:`px-4 py-2`,large:`px-5 py-3`},j={small:`p-1.5`,medium:`p-2`,large:`p-3`},M={small:`text-caption-1`,medium:`text-body-1`,large:`text-body-2`};function N(e,n,r){switch(e){case`subtle`:case`subtle-circular`:{let r=e===`subtle`?`rounded-md`:`rounded-full`;return n?t.cn(r,`bg-subtle-selected text-foreground`,f.forcedColors.selectedContainer):t.cn(r,`text-muted-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-subtle-pressed`)}case`filled-circular`:return n?t.cn(`rounded-full bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed`,f.forcedColors.selectedContainer):`rounded-full bg-muted text-muted-foreground not-disabled:not-aria-disabled:hover:bg-muted-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-muted-pressed`;default:return n?t.cn(`text-primary forced-colors:border-[Highlight]`,r?`border-s-2 border-s-primary`:`border-b-2 border-b-primary`):`text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground`}}var P=({value:e,id:n,icon:s,className:c,children:l,onClick:u,ref:d,...p})=>{let g=x(`TabList.Tab`),_=g.isSelected(e),v=g.orientation===`vertical`,y=S(p),b=!!s&&i.slotRendersContent(s),w=b&&!i.slotRendersContent(l),T=p[`aria-label`],E=p[`aria-labelledby`],D=typeof T==`string`&&T.trim()!==``||typeof E==`string`&&E.trim()!==``;m.useEffect(()=>{w&&!D&&r.warnOnce(`TabList.Tab:icon-only-name`,"TabList.Tab: a tab with an icon and no text has no accessible name. Pass `aria-label` (or `aria-labelledby`).")},[w,D]);let{registry:O}=g,k=C(n)??g.getGeneratedId(`tab`,e);m.useLayoutEffect(()=>O.register(`tab`,e,k),[O,e,k]);let P=m.useSyncExternalStore(O.subscribe,()=>O.get(`panel`,e),()=>void 0),F=P===void 0?g.getStaticPanelId(e):P??void 0;return(0,h.jsxs)(`button`,{type:`button`,role:`tab`,className:t.cn(o.tabListTabClassNames.root,`font-semibold transition-colors motion-reduce:transition-none`,w?j[g.size]:A[g.size],M[g.size],b&&`inline-flex items-center justify-center gap-2`,v&&`text-start`,N(g.appearance,_,v),f.disabledStyles,f.focusRingInset,c),...p,id:k,"aria-selected":_,"aria-controls":_?F:void 0,tabIndex:g.getTabIndex(e),"data-roving-value":e,"data-selected":_?``:void 0,"data-icon-only":w?``:void 0,onClick:a.composeEventHandlers(u,()=>{y||g.select(e)}),ref:d,children:[b&&i.renderSlot(s,`span`,o.tabListTabClassNames.icon,{"aria-hidden":!0}),l]})};P.displayName=`Tab`;var F=({value:e,id:n,children:i,className:a,ref:s,...c})=>{let l=x(`TabList.Panel`),u=m.useContext(D)===`tabs`;m.useEffect(()=>{u&&r.warnOnce(`TabList.Panel:inside-tablist`,O)},[u]);let{registry:d}=l,p=C(n)??l.getGeneratedId(`panel`,e);m.useLayoutEffect(()=>d.register(`panel`,e,p),[d,e,p]);let g=m.useSyncExternalStore(d.subscribe,()=>d.get(`tab`,e),()=>void 0);if(!l.isSelected(e))return null;let _=g===void 0?l.getStaticTabId(e):g??void 0;return(0,h.jsx)(`div`,{role:`tabpanel`,tabIndex:0,className:t.cn(o.tabListPanelClassNames.root,`p-4`,f.focusRing,a),...c,id:p,"aria-labelledby":_,ref:s,children:i})};F.displayName=`TabPanel`;var I=({className:e,children:n,ref:r,...i})=>(0,h.jsx)(`div`,{ref:r,className:t.cn(o.tabListPanelsClassNames.root,`min-w-0 flex-1`,e),...i,children:n});I.displayName=`TabPanels`;var L=Object.assign(k,{Tab:P,Panel:F,Panels:I});exports.TabList=L,exports.TabListPanel=F,exports.TabListPanels=I,exports.TabListTab=P;
|
|
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/slot.cjs"),a=require("../../lib/composeEventHandlers.cjs"),o=require("../../lib/classNames.cjs"),s=require("../../hooks/useEventCallback.cjs"),c=require("../../hooks/useControllable.cjs"),l=require("../../hooks/useId.cjs"),u=require("../../hooks/useRovingTabIndex.cjs"),d=require("../../hooks/useMergedRefs.cjs"),f=require("../../hooks/usePrefersReducedMotion.cjs"),p=require("../../lib/styles.cjs"),m=require("../../lib/motion.cjs"),h=require("../../hooks/useMotion.cjs"),g=require("./disclosureIds.cjs");let _=require("react");_=e.__toESM(_,1);let v=require("react/jsx-runtime");function y(e){r.warnOnce(`TabList:duplicate:${e}`,`TabList: several tabs share the value "${e}". Tab values must be unique within a TabList; tabs with the same value share one id and are selected (and tab stops) together.`)}function b(){let e={tab:new Map,panel:new Map},t=new Set,n=!1,r=()=>{t.forEach(e=>e())};return{register(t,n,i){let a=e[t],o=a.get(n)??[];return t===`tab`&&o.length>0&&y(n),a.set(n,[...o,i]),r(),()=>{let e=[...a.get(n)??[]],t=e.indexOf(i);t!==-1&&e.splice(t,1),e.length>0?a.set(n,e):a.delete(n),r()}},get:(t,r)=>n?e[t].get(r)?.[0]??null:void 0,markReady(){n||(n=!0,r())},subscribe(e){return t.add(e),()=>{t.delete(e)}}}}var x={register:()=>()=>{},get:()=>void 0,markReady:()=>{},subscribe:()=>()=>{}},S=_.createContext(null),C={orientation:`horizontal`,appearance:`transparent`,size:`medium`,isSelected:()=>!1,select:()=>{},getTabIndex:()=>-1,getGeneratedId:(e,t)=>`wave-tablist-inert-${e}-${t}`,getStaticTabId:e=>`wave-tablist-inert-tab-${e}`,getStaticPanelId:()=>void 0,registry:x,indicator:null,indicatorMotion:``};function w(e){return _.useContext(S)||(r.reportMissingContext(e,`<TabList>`),C)}function T(e){let t=e[`aria-disabled`];return e.disabled===!0||t===!0||t===`true`}function E(e){return typeof e==`string`&&e!==``?e:null}function D(e,t){if(Array.isArray(e))return e.forEach(e=>D(e,t)),t;if(!_.isValidElement(e))return t;let{props:r}=e,i=n.getElementType(e,{suspend:!1}),a=typeof r.value==`string`?r.value:void 0;if(i===L){if(a!==void 0){t.firstEnabled===void 0&&!T(r)&&(t.firstEnabled=a);let e=E(r.id);e!==null&&t.tabIds.push([a,e])}return t}return i===R?(a!==void 0&&t.panels.push([a,E(r.id)]),t):i===M?t:D(r.children,t)}function O(e,t){if(Array.isArray(e))return e.some(e=>O(e,t));if(!_.isValidElement(e))return!1;let r=n.getElementType(e,{suspend:!1});return r===L?t===`tab`:r===R||r===z?t===`panel`:r!==M&&O(e.props.children,t)}function k(e){return O(e,`panel`)&&!O(e,`tab`)}var A=_.createContext(null),j=`TabList.Panel was rendered inside the role="tablist" element, where only tabs belong (axe aria-required-children). The TabList moves a Panel after the tablist when it is its child, or in a wrapper that holds no Tab, but it cannot see a Panel that a component renders itself, or separate a wrapper's Panels from its Tabs. Place such panels inside TabList.Panels, which renders after the tablist.`,M=({value:e,defaultValue:i,onValueChange:p,orientation:y,appearance:x=`transparent`,size:C=`medium`,selectTabOnFocus:w=!0,motion:T,selectedValue:E,defaultSelectedValue:O,onTabSelect:j,vertical:M,className:N,children:P,onKeyDown:ee,onFocus:F,ref:I,...L})=>{let R=r.resolveDeprecatedProp(`TabList`,e,E,`selectedValue`,`value`),z=r.resolveDeprecatedProp(`TabList`,i,O,`defaultSelectedValue`,`defaultValue`),B=r.resolveDeprecatedProp(`TabList`,y,M===void 0?void 0:M?`vertical`:`horizontal`,`vertical`,`orientation`)??`horizontal`;j&&r.warnDeprecated(`TabList`,`onTabSelect`,`onValueChange`,"`onValueChange` is called only when the selected tab changes.");let[V,te,ne]=c.useControllable(R,z??``,p),H=JSON.stringify(D(P,{tabIds:[],panels:[]})),U=_.useMemo(()=>{let e=JSON.parse(H);return{firstEnabled:e.firstEnabled,tabIds:new Map(e.tabIds),panels:new Map(e.panels)}},[H]),W=!ne&&V===``,{containerProps:G,getTabIndex:K}=u.useRovingTabIndex({activeValue:W?U.firstEnabled??null:V,orientation:B,loop:!0,onFocusMove:w?e=>J(e):void 0}),q=_.useCallback(e=>W?K(e)===0:V===e,[W,K,V]),J=s.useEventCallback(e=>{j?.(e),q(e)||te(e)}),Y=l.useId(`tablist`),[X]=_.useState(b);_.useLayoutEffect(()=>X.markReady(),[X]);let Z=B===`vertical`,Q=h.useMotionClasses(T,m.tabIndicatorMotion),re=f.usePrefersReducedMotion(),ie=x===`transparent`&&Q!==``&&!re,[$,ae]=_.useState(null),oe=_.useRef(null),se=_.useRef(null);_.useLayoutEffect(()=>{let e=oe.current;if(!e)return;let t=Array.from(e.querySelectorAll(`[role="tab"]`)),n=e=>e.getAttribute(`data-roving-value`),r=t.find(e=>{let t=n(e);return t!==null&&q(t)}),i=r?n(r):null,a=se.current;if(se.current=i,!ie||!r||i===null||a===null||i===a)return;let o=t.find(e=>n(e)===a);if(!o)return;let s=o.getBoundingClientRect(),c=r.getBoundingClientRect(),l=Z?c.height:c.width;l!==0&&ae({value:i,offset:Z?s.top-c.top:s.left-c.left,scale:(Z?s.height:s.width)/l})},[q,ie,Z]),_.useEffect(()=>{if(!$)return;let e=requestAnimationFrame(()=>ae(null));return()=>cancelAnimationFrame(e)},[$]);let ce=_.useMemo(()=>({orientation:B,appearance:x,size:C,isSelected:q,select:J,getTabIndex:K,getGeneratedId:(e,t)=>g.getPartId(Y,e,t),getStaticTabId:e=>U.tabIds.get(e)??g.getPartId(Y,`tab`,e),getStaticPanelId:e=>{let t=U.panels.get(e);if(t!==void 0)return t??g.getPartId(Y,`panel`,e)},registry:X,indicator:$,indicatorMotion:Q}),[B,x,C,q,J,K,Y,U,X,$,Q]),le=d.useMergedRefs(I,G.ref,oe),ue=[],de=[];return n.flattenChildren(P).forEach(({key:e,node:t})=>{let n=(0,v.jsx)(_.Fragment,{children:t},e);(k(t)?de:ue).push(n)}),(0,v.jsx)(S.Provider,{value:ce,children:(0,v.jsxs)(`div`,{className:t.cn(Z&&`flex`),children:[(0,v.jsx)(`div`,{role:`tablist`,"aria-orientation":B,"data-appearance":x,"data-size":C,"data-orientation":B,className:t.cn(o.tabListClassNames.root,Z?`flex w-40 flex-col`:`flex`,x===`transparent`?Z?`border-e border-border`:`border-b border-border`:`gap-1`,N),...L,"data-roving-container":``,onKeyDown:a.composeEventHandlers(ee,G.onKeyDown),onFocus:a.composeEventHandlers(F,G.onFocus,{checkDefaultPrevented:!1}),ref:le,children:(0,v.jsx)(A.Provider,{value:`tabs`,children:ue})}),(0,v.jsx)(A.Provider,{value:`panels`,children:de})]})})};M.displayName=`TabList`;var N={small:`px-3 py-1.5`,medium:`px-4 py-2`,large:`px-5 py-3`},P={small:`p-1.5`,medium:`p-2`,large:`p-3`},ee={small:`text-caption-1`,medium:`text-body-1`,large:`text-body-2`},F={horizontal:`relative border-b-2 border-b-transparent after:absolute after:inset-x-0 after:-bottom-0.5 after:border-b-2 after:border-b-primary after:origin-left after:translate-x-[var(--wave-tab-indicator-offset,0px)] after:scale-x-[var(--wave-tab-indicator-scale,1)] forced-colors:after:border-[Highlight]`,vertical:`relative border-s-2 border-s-transparent after:absolute after:inset-y-0 after:-start-0.5 after:border-s-2 after:border-s-primary after:origin-top after:translate-y-[var(--wave-tab-indicator-offset,0px)] after:scale-y-[var(--wave-tab-indicator-scale,1)] forced-colors:after:border-[Highlight]`};function I(e,n,r){switch(e){case`subtle`:case`subtle-circular`:{let r=e===`subtle`?`rounded-md`:`rounded-full`;return n?t.cn(r,`bg-subtle-selected text-foreground`,p.forcedColors.selectedContainer):t.cn(r,`text-muted-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-subtle-pressed`)}case`filled-circular`:return n?t.cn(`rounded-full bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed`,p.forcedColors.selectedContainer):`rounded-full bg-muted text-muted-foreground not-disabled:not-aria-disabled:hover:bg-muted-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-muted-pressed`;default:return t.cn(`border-transparent forced-colors:border-[Canvas]`,n?t.cn(`text-primary`,F[r?`vertical`:`horizontal`]):`text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground`)}}var L=({value:e,id:n,icon:s,className:c,style:l,children:u,onClick:d,ref:f,...m})=>{let h=w(`TabList.Tab`),g=h.isSelected(e),y=h.orientation===`vertical`,b=g&&h.indicator?.value===e?h.indicator:null,x=g&&h.appearance===`transparent`&&!b?h.indicatorMotion:void 0,S=b?{...l,"--wave-tab-indicator-offset":`${b.offset}px`,"--wave-tab-indicator-scale":String(b.scale)}:l,C=T(m),D=!!s&&i.slotRendersContent(s),O=D&&!i.slotRendersContent(u),k=m[`aria-label`],A=m[`aria-labelledby`],j=typeof k==`string`&&k.trim()!==``||typeof A==`string`&&A.trim()!==``;_.useEffect(()=>{O&&!j&&r.warnOnce(`TabList.Tab:icon-only-name`,"TabList.Tab: a tab with an icon and no text has no accessible name. Pass `aria-label` (or `aria-labelledby`).")},[O,j]);let{registry:M}=h,F=E(n)??h.getGeneratedId(`tab`,e);_.useLayoutEffect(()=>M.register(`tab`,e,F),[M,e,F]);let L=_.useSyncExternalStore(M.subscribe,()=>M.get(`panel`,e),()=>void 0),R=L===void 0?h.getStaticPanelId(e):L??void 0;return(0,v.jsxs)(`button`,{type:`button`,role:`tab`,className:t.cn(o.tabListTabClassNames.root,`font-semibold transition-colors motion-reduce:transition-none`,O?P[h.size]:N[h.size],ee[h.size],D&&`inline-flex items-center justify-center gap-2`,y&&`text-start`,I(h.appearance,g,y),p.disabledStyles,p.focusRingInset,x,c),style:S,...m,id:F,"aria-selected":g,"aria-controls":g?R:void 0,tabIndex:h.getTabIndex(e),"data-roving-value":e,"data-selected":g?``:void 0,"data-icon-only":O?``:void 0,onClick:a.composeEventHandlers(d,()=>{C||h.select(e)}),ref:f,children:[D&&i.renderSlot(s,`span`,o.tabListTabClassNames.icon,{"aria-hidden":!0}),u]})};L.displayName=`Tab`;var R=({value:e,id:n,children:i,className:a,ref:s,...c})=>{let l=w(`TabList.Panel`),u=_.useContext(A)===`tabs`;_.useEffect(()=>{u&&r.warnOnce(`TabList.Panel:inside-tablist`,j)},[u]);let{registry:d}=l,f=E(n)??l.getGeneratedId(`panel`,e);_.useLayoutEffect(()=>d.register(`panel`,e,f),[d,e,f]);let m=_.useSyncExternalStore(d.subscribe,()=>d.get(`tab`,e),()=>void 0);if(!l.isSelected(e))return null;let h=m===void 0?l.getStaticTabId(e):m??void 0;return(0,v.jsx)(`div`,{role:`tabpanel`,tabIndex:0,className:t.cn(o.tabListPanelClassNames.root,`p-4`,p.focusRing,a),...c,id:f,"aria-labelledby":h,ref:s,children:i})};R.displayName=`TabPanel`;var z=({className:e,children:n,ref:r,...i})=>(0,v.jsx)(`div`,{ref:r,className:t.cn(o.tabListPanelsClassNames.root,`min-w-0 flex-1`,e),...i,children:n});z.displayName=`TabPanels`;var B=Object.assign(M,{Tab:L,Panel:R,Panels:z});exports.TabList=B,exports.TabListPanel=R,exports.TabListPanels=z,exports.TabListTab=L;
|
|
2
2
|
//# sourceMappingURL=TabList.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabList.cjs","names":["React","getElementType","resolveDeprecatedProp","useControllable","useRovingTabIndex","useEventCallback","useId","getPartId","useMergedRefs","cn","tabListClassNames","composeEventHandlers","forcedColors","slotRendersContent","tabListTabClassNames","disabledStyles","focusRingInset","renderSlot","tabListPanelClassNames","focusRing","tabListPanelsClassNames","require_runtime","require_cn","require_children","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_useRovingTabIndex","require_useMergedRefs","require_styles","require_disclosureIds","react","react_jsx_runtime","warnDuplicateTabValue","value","createRegistry","entries","listeners","ready","emit","listener","map","part","ids","id","index","INERT_REGISTRY","TabListContext","INERT_CONTEXT","useTabListContext","component","isUnavailable","ariaDisabled","props","consumerId","collectStructure","node","child","into","type","Tab","TabPanel","TabListRoot","containsPart","TabPanels","rendersAfterTablist","TabListAreaContext","PANEL_IN_TABLIST_MESSAGE","valueProp","defaultValueProp","orientationProp","rest","selectedValue","defaultValue","defaultSelectedValue","orientation","vertical","onTabSelect","selected","setSelected","isControlled","onValueChange","structureKey","children","structure","parsed","derivesSelection","selectTabOnFocus","select","next","isSelected","getTabIndex","tabValue","baseId","registry","context","itemValue","panel","appearance","size","mergedRef","ref","containerProps","tabs","panels","keyed","key","isVertical","className","onKeyDown","onFocus","tabPadding","tabIconOnlyPadding","tabText","tabLookClasses","shape","idProp","ctx","unavailable","hasIcon","icon","iconOnly","ariaLabel","ariaLabelledBy","named","mountedPanelId","panelId","onClick","insideTablist","mountedTabId","tabId","TabList"],"sources":["../../../src/components/layout/TabList.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n tabListClassNames,\n tabListPanelClassNames,\n tabListPanelsClassNames,\n tabListTabClassNames,\n} from '../../lib/classNames';\nimport { flattenChildren, getElementType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport {\n reportMissingContext,\n resolveDeprecatedProp,\n warnDeprecated,\n warnOnce,\n} from '../../lib/dev';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\nimport { disabledStyles, focusRing, focusRingInset, forcedColors } from '../../lib/styles';\nimport type { CoreSize, Orientation, Slot } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { getPartId } from './disclosureIds';\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\ntype TabListPart = 'tab' | 'panel';\n\n/**\n * The ids of the mounted Tabs and Panels by value. A Tab references a panel only while one with\n * its value is mounted (a TabList used as a filter bar has none), and each side references the\n * other's actual id, a consumer `id` included. Read with `useSyncExternalStore`.\n *\n * Before the TabList has mounted (server HTML, hydration and the first client render) the\n * registry is not ready and the static structure of the children stands in for it; once it is\n * ready, it alone decides, so a Panel that is in the element tree but never mounts (inside a\n * wrapper that renders nothing) is not referenced.\n */\ninterface TabListRegistry {\n /** Registers a mounted Tab or Panel; returns the unregister function. */\n register: (part: TabListPart, value: string, id: string) => () => void;\n /**\n * Id of the first mounted Tab or Panel with this value, `null` when none is mounted, or\n * `undefined` while the registry is not ready (use the static structure then).\n */\n get: (part: TabListPart, value: string) => string | null | undefined;\n /** Called by the TabList once it (and so every Tab and Panel mounted with it) has mounted. */\n markReady: () => void;\n subscribe: (listener: () => void) => () => void;\n}\n\n/** Tabs that share a value share one id, and are selected and tab stops together. */\nfunction warnDuplicateTabValue(value: string): void {\n warnOnce(\n `TabList:duplicate:${value}`,\n `TabList: several tabs share the value \"${value}\". Tab values must be unique within a ` +\n 'TabList; tabs with the same value share one id and are selected (and tab stops) together.',\n );\n}\n\nfunction createRegistry(): TabListRegistry {\n const entries: Record<TabListPart, Map<string, string[]>> = { tab: new Map(), panel: new Map() };\n const listeners = new Set<() => void>();\n let ready = false;\n const emit = () => {\n listeners.forEach((listener) => listener());\n };\n return {\n register(part, value, id) {\n const map = entries[part];\n const ids = map.get(value) ?? [];\n // Called from the part's layout effect (C-DEV). Two Panels may share a value (the Tab links\n // to the first mounted one); two Tabs may not.\n if (part === 'tab' && ids.length > 0) warnDuplicateTabValue(value);\n map.set(value, [...ids, id]);\n emit();\n return () => {\n const ids = [...(map.get(value) ?? [])];\n const index = ids.indexOf(id);\n if (index !== -1) ids.splice(index, 1);\n if (ids.length > 0) map.set(value, ids);\n else map.delete(value);\n emit();\n };\n },\n get: (part, value) => (ready ? (entries[part].get(value)?.[0] ?? null) : undefined),\n markReady() {\n if (ready) return;\n ready = true;\n emit();\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n\nconst INERT_REGISTRY: TabListRegistry = {\n register: () => () => {},\n get: () => undefined,\n markReady: () => {},\n subscribe: () => () => {},\n};\n\n/**\n * What the TabList's children show before anything mounts (server HTML and the first render):\n * found in the element tree through Fragments and the `children` of wrapper elements, but not\n * inside a component that renders a Tab or Panel itself (the registry covers those once mounted).\n */\ninterface TabListStructure {\n /** Value of the first Tab without `disabled`/`aria-disabled`: the uncontrolled default. */\n firstEnabled?: string;\n /** Consumer `id`s of Tabs, by value. */\n tabIds: Array<[string, string]>;\n /** Values of the Panels, each with its consumer `id` or `null`. */\n panels: Array<[string, string | null]>;\n}\n\n/** The look of a TabList: an underline, subtle fills, or circular subtle or filled tabs. */\nexport type TabListAppearance = 'transparent' | 'subtle' | 'subtle-circular' | 'filled-circular';\n\ninterface TabListContextValue {\n orientation: Orientation;\n appearance: TabListAppearance;\n size: CoreSize;\n /** Whether the tab with this value is the selected one (explicit value, else the tab stop). */\n isSelected: (value: string) => boolean;\n /**\n * Activates a tab: a click (Enter and Space click the tab button), or with automatic activation\n * focus moved by the keys.\n */\n select: (value: string) => void;\n getTabIndex: (value: string) => 0 | -1;\n /** The generated id of a Tab or Panel (used when it has no consumer `id`). */\n getGeneratedId: (part: TabListPart, value: string) => string;\n /**\n * Id of the Tab with this value before the TabList mounts: its consumer `id`, else the\n * generated one.\n */\n getStaticTabId: (value: string) => string;\n /**\n * Id of the Panel with this value before the TabList mounts, or `undefined` when the children\n * have none.\n */\n getStaticPanelId: (value: string) => string | undefined;\n registry: TabListRegistry;\n}\n\nconst TabListContext = React.createContext<TabListContextValue | null>(null);\n\nconst INERT_CONTEXT: TabListContextValue = {\n orientation: 'horizontal',\n appearance: 'transparent',\n size: 'medium',\n isSelected: () => false,\n select: () => {},\n getTabIndex: () => -1,\n getGeneratedId: (part, value) => `wave-tablist-inert-${part}-${value}`,\n getStaticTabId: (value) => `wave-tablist-inert-tab-${value}`,\n getStaticPanelId: () => undefined,\n registry: INERT_REGISTRY,\n};\n\n/** C-CONTEXT: throws in development, logs once and returns an inert value in production. */\nfunction useTabListContext(component: string): TabListContextValue {\n const context = React.useContext(TabListContext);\n if (context) return context;\n reportMissingContext(component, '<TabList>');\n return INERT_CONTEXT;\n}\n\ninterface StructureProps {\n value?: unknown;\n id?: unknown;\n disabled?: unknown;\n 'aria-disabled'?: unknown;\n children?: unknown;\n}\n\n/** Whether a Tab's props make it unavailable (it cannot be selected and is skipped by keys). */\nfunction isUnavailable(props: StructureProps): boolean {\n const ariaDisabled = props['aria-disabled'];\n return props.disabled === true || ariaDisabled === true || ariaDisabled === 'true';\n}\n\n/** A consumer `id` that replaces the generated one: a non-empty string (`''` counts as none). */\nfunction consumerId(id: unknown): string | null {\n return typeof id === 'string' && id !== '' ? id : null;\n}\n\n/**\n * Walks the element tree of the TabList's children (see {@link TabListStructure}). Parts are\n * identified through their element type, so parts written in a Server Component (lazy\n * references) count too. A `React.lazy` still loading (inside the consumer's own `<Suspense>`,\n * such as code-split panels in `TabList.Panels`) is no part and never suspends the TabList: its\n * children are walked instead. Runs during render only.\n */\nfunction collectStructure(node: unknown, into: TabListStructure): TabListStructure {\n if (Array.isArray(node)) {\n node.forEach((child) => collectStructure(child, into));\n return into;\n }\n if (!React.isValidElement<StructureProps>(node)) return into;\n const { props } = node;\n const type = getElementType(node, { suspend: false });\n const value = typeof props.value === 'string' ? props.value : undefined;\n if (type === Tab) {\n if (value !== undefined) {\n if (into.firstEnabled === undefined && !isUnavailable(props)) into.firstEnabled = value;\n const id = consumerId(props.id);\n if (id !== null) into.tabIds.push([value, id]);\n }\n return into;\n }\n if (type === TabPanel) {\n if (value !== undefined) into.panels.push([value, consumerId(props.id)]);\n return into;\n }\n if (type === TabListRoot) return into;\n return collectStructure(props.children, into);\n}\n\n/**\n * Whether an element tree shows a Tab, or a Panel (`TabList.Panel` or `TabList.Panels`), found as\n * in {@link collectStructure}: through Fragments and the `children` of wrapper elements, not inside\n * a nested TabList or a component that renders the part itself.\n */\nfunction containsPart(node: unknown, part: TabListPart): boolean {\n if (Array.isArray(node)) return node.some((child) => containsPart(child, part));\n if (!React.isValidElement<StructureProps>(node)) return false;\n const type = getElementType(node, { suspend: false });\n if (type === Tab) return part === 'tab';\n if (type === TabPanel || type === TabPanels) return part === 'panel';\n if (type === TabListRoot) return false;\n return containsPart(node.props.children, part);\n}\n\n/**\n * Whether a child of the TabList renders after the tablist: a Panel, `TabList.Panels`, or a\n * wrapper (an element, `Suspense`, an error boundary) that holds panels and no tab.\n */\nfunction rendersAfterTablist(child: React.ReactNode): boolean {\n return containsPart(child, 'panel') && !containsPart(child, 'tab');\n}\n\n/**\n * Where the TabList renders its children: inside the `role=\"tablist\"` element (`'tabs'`) or after\n * it (`'panels'`). A Panel that ends up inside the tablist warns in development.\n */\nconst TabListAreaContext = React.createContext<'tabs' | 'panels' | null>(null);\n\nconst PANEL_IN_TABLIST_MESSAGE =\n 'TabList.Panel was rendered inside the role=\"tablist\" element, where only tabs belong (axe ' +\n 'aria-required-children). The TabList moves a Panel after the tablist when it is its child, or ' +\n 'in a wrapper that holds no Tab, but it cannot see a Panel that a component renders itself, or ' +\n \"separate a wrapper's Panels from its Tabs. Place such panels inside TabList.Panels, which \" +\n 'renders after the tablist.';\n\n/* ------------------------------------------------------------------ */\n/* TabList */\n/* ------------------------------------------------------------------ */\n\n/** Properties for the TabList component. */\nexport interface TabListProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'defaultValue'> {\n /**\n * Controlled value of the selected tab (`''`: no tab selected). A controlled value that becomes\n * `undefined` also selects no tab: the TabList stays controlled.\n */\n value?: string;\n /**\n * Selected tab for uncontrolled usage. When it is omitted (or `''`), the first enabled tab\n * written in the TabList's children is selected, from the first render (and in server-rendered\n * HTML) on. Tabs written directly in the children, in Fragments or in wrapper elements that\n * pass them as `children` (such as a Tooltip) count; a tab rendered by a custom component that\n * renders `TabList.Tab` itself does not, even when it comes first in the DOM, so that server\n * and client pick the same tab. When every tab comes from such a component, the first enabled\n * tab in the DOM is selected once the tabs mount. To select a tab that a custom component\n * renders, pass `defaultValue`.\n */\n defaultValue?: string;\n /** Called with the new value when the selected tab changes (not when it is activated again). */\n onValueChange?: (value: string) => void;\n /**\n * Layout and arrow-key axis: `'horizontal'` (Left/Right, mirrored in RTL) or `'vertical'`\n * (Up/Down).\n * @default 'horizontal'\n */\n orientation?: Orientation;\n /**\n * Look of the tabs: `transparent` underlines the selected tab, `subtle` and `subtle-circular`\n * fill it with a subtle color (square or fully rounded), `filled-circular` fills it with the\n * primary color. In forced colors the selected tab keeps a Highlight outline (or underline) in\n * every appearance.\n * @default 'transparent'\n */\n appearance?: TabListAppearance;\n /**\n * Size of the tabs: their padding and type (`medium` is 14px text on 16 by 8px padding).\n * @default 'medium'\n */\n size?: CoreSize;\n /**\n * Whether moving focus with the arrow keys, Home and End also selects the tab (automatic\n * activation, as in 0.5). With `false`, the keys only move focus and Enter, Space or a click\n * selects the focused tab (manual activation, for panels that are slow to show). Fluent's\n * default is `false`.\n * @default true\n */\n selectTabOnFocus?: boolean;\n /** @deprecated Use `value`. */\n selectedValue?: string;\n /** @deprecated Use `defaultValue`. */\n defaultSelectedValue?: string;\n /**\n * @deprecated Use `onValueChange`. Unlike `onValueChange`, it is called on every activation,\n * including a click on the tab that is already selected.\n */\n onTabSelect?: (value: string) => void;\n /** @deprecated Use `orientation=\"vertical\"`. */\n vertical?: boolean;\n /** Ref to the `role=\"tablist\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst TabListRoot = ({\n value: valueProp,\n defaultValue: defaultValueProp,\n onValueChange,\n orientation: orientationProp,\n appearance = 'transparent',\n size = 'medium',\n selectTabOnFocus = true,\n selectedValue,\n defaultSelectedValue,\n onTabSelect,\n vertical,\n className,\n children,\n onKeyDown,\n onFocus,\n ref,\n ...rest\n}: TabListProps) => {\n const value = resolveDeprecatedProp(\n 'TabList',\n valueProp,\n selectedValue,\n 'selectedValue',\n 'value',\n );\n const defaultValue = resolveDeprecatedProp(\n 'TabList',\n defaultValueProp,\n defaultSelectedValue,\n 'defaultSelectedValue',\n 'defaultValue',\n );\n const orientation =\n resolveDeprecatedProp<Orientation>(\n 'TabList',\n orientationProp,\n vertical === undefined ? undefined : vertical ? 'vertical' : 'horizontal',\n 'vertical',\n 'orientation',\n ) ?? 'horizontal';\n if (onTabSelect) {\n warnDeprecated(\n 'TabList',\n 'onTabSelect',\n 'onValueChange',\n '`onValueChange` is called only when the selected tab changes.',\n );\n }\n\n // The sticky mode: a controlled value that becomes `undefined` clears the selection (`''`).\n const [selected, setSelected, isControlled] = useControllable(\n value,\n defaultValue ?? '',\n onValueChange,\n );\n\n // The children are a new element tree on every parent render: memoized by content, so the\n // context value stays stable while the tabs and panels stay the same.\n const structureKey = JSON.stringify(collectStructure(children, { tabIds: [], panels: [] }));\n const structure = React.useMemo(() => {\n const parsed = JSON.parse(structureKey) as TabListStructure;\n return {\n firstEnabled: parsed.firstEnabled,\n tabIds: new Map(parsed.tabIds),\n panels: new Map(parsed.panels),\n };\n }, [structureKey]);\n\n // Uncontrolled without a selection: the first enabled tab is selected. It is the tab stop the\n // roving store resolves from `activeValue` (the first enabled tab of the children, replaced by\n // the first enabled tab in the DOM once the store sees it disabled), so the selection is\n // derived during render, present from the first render on, and follows tabs that disable\n // themselves.\n const derivesSelection = !isControlled && selected === '';\n\n const { containerProps, getTabIndex } = useRovingTabIndex({\n activeValue: derivesSelection ? (structure.firstEnabled ?? null) : selected,\n orientation,\n loop: true,\n // Automatic activation (APG Tabs): moving focus selects the tab. With manual activation the\n // keys only move focus; the tab stop stays on the selected tab (`tabStop: 'active'`), and Enter\n // or Space selects the focused tab through its native click.\n onFocusMove: selectTabOnFocus ? (next) => select(next) : undefined,\n });\n\n const isSelected = React.useCallback(\n (tabValue: string) => (derivesSelection ? getTabIndex(tabValue) === 0 : selected === tabValue),\n [derivesSelection, getTabIndex, selected],\n );\n\n const select = useEventCallback((next: string) => {\n onTabSelect?.(next);\n if (!isSelected(next)) setSelected(next);\n });\n\n const baseId = useId('tablist');\n const [registry] = React.useState(createRegistry);\n // Runs after the layout effects of the Tabs and Panels mounted with the TabList, which have\n // registered by then: from here on the registry, not the static structure, decides the links.\n React.useLayoutEffect(() => registry.markReady(), [registry]);\n const context = React.useMemo<TabListContextValue>(\n () => ({\n orientation,\n appearance,\n size,\n isSelected,\n select,\n getTabIndex,\n getGeneratedId: (part, itemValue) => getPartId(baseId, part, itemValue),\n getStaticTabId: (tabValue) =>\n structure.tabIds.get(tabValue) ?? getPartId(baseId, 'tab', tabValue),\n getStaticPanelId: (tabValue) => {\n const panel = structure.panels.get(tabValue);\n if (panel === undefined) return undefined;\n return panel ?? getPartId(baseId, 'panel', tabValue);\n },\n registry,\n }),\n [orientation, appearance, size, isSelected, select, getTabIndex, baseId, structure, registry],\n );\n\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, containerProps.ref);\n\n const tabs: React.ReactNode[] = [];\n const panels: React.ReactNode[] = [];\n flattenChildren(children).forEach(({ key, node: child }) => {\n const keyed = <React.Fragment key={key}>{child}</React.Fragment>;\n (rendersAfterTablist(child) ? panels : tabs).push(keyed);\n });\n\n const isVertical = orientation === 'vertical';\n return (\n <TabListContext.Provider value={context}>\n <div className={cn(isVertical && 'flex')}>\n <div\n role=\"tablist\"\n aria-orientation={orientation}\n data-appearance={appearance}\n data-size={size}\n data-orientation={orientation}\n className={cn(\n tabListClassNames.root,\n isVertical ? 'flex w-40 flex-col' : 'flex',\n appearance === 'transparent'\n ? isVertical\n ? 'border-e border-border'\n : 'border-b border-border'\n : 'gap-1',\n className,\n )}\n {...rest}\n data-roving-container=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, containerProps.onKeyDown)}\n onFocus={composeEventHandlers(onFocus, containerProps.onFocus, {\n checkDefaultPrevented: false,\n })}\n ref={mergedRef}\n >\n <TabListAreaContext.Provider value=\"tabs\">{tabs}</TabListAreaContext.Provider>\n </div>\n <TabListAreaContext.Provider value=\"panels\">{panels}</TabListAreaContext.Provider>\n </div>\n </TabListContext.Provider>\n );\n};\nTabListRoot.displayName = 'TabList';\n\n/* ------------------------------------------------------------------ */\n/* TabList.Tab */\n/* ------------------------------------------------------------------ */\n\n/** Padding of a tab with text, per size. Literal strings only. */\nconst tabPadding: Readonly<Record<CoreSize, string>> = {\n small: 'px-3 py-1.5',\n medium: 'px-4 py-2',\n large: 'px-5 py-3',\n};\n\n/** Padding of an icon-only tab (a square hit area), per size. */\nconst tabIconOnlyPadding: Readonly<Record<CoreSize, string>> = {\n small: 'p-1.5',\n medium: 'p-2',\n large: 'p-3',\n};\n\n/** Type step of a tab, per size. */\nconst tabText: Readonly<Record<CoreSize, string>> = {\n small: 'text-caption-1',\n medium: 'text-body-1',\n large: 'text-body-2',\n};\n\n/**\n * The colors, fill and selected indicator of a tab per appearance. Literal strings only; hover and\n * pressed use the gated rules (a disabled tab keeps its look). In forced colors fills are dropped,\n * so every selected tab keeps a Highlight outline (or, for the underline, a Highlight border).\n */\nfunction tabLookClasses(\n appearance: TabListAppearance,\n selected: boolean,\n vertical: boolean,\n): string {\n switch (appearance) {\n case 'subtle':\n case 'subtle-circular': {\n const shape = appearance === 'subtle' ? 'rounded-md' : 'rounded-full';\n return selected\n ? cn(shape, 'bg-subtle-selected text-foreground', forcedColors.selectedContainer)\n : cn(\n shape,\n 'text-muted-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n );\n }\n case 'filled-circular':\n return selected\n ? cn(\n 'rounded-full bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n forcedColors.selectedContainer,\n )\n : 'rounded-full bg-muted text-muted-foreground not-disabled:not-aria-disabled:hover:bg-muted-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-muted-pressed';\n default:\n return selected\n ? cn(\n 'text-primary forced-colors:border-[Highlight]',\n vertical ? 'border-s-2 border-s-primary' : 'border-b-2 border-b-primary',\n )\n : 'text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground';\n }\n}\n\n/** Properties for the Tab sub-component. */\nexport interface TabProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Unique value identifying this tab (and its panel). */\n value: string;\n /**\n * An icon before the text, hidden from assistive technology. A tab with an icon and no text is\n * icon-only (a square hit area): name it with `aria-label`, or a development warning asks for it.\n */\n icon?: Slot<'span'>;\n /** Ref to the tab `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * A tab button. `onClick` runs before the selection (call `event.preventDefault()` to keep the\n * current tab). A `disabled` (or `aria-disabled=\"true\"`) tab is skipped by the keyboard and cannot\n * be selected. A non-empty `id` replaces the generated one (its panel's `aria-labelledby` follows\n * it). The selected tab references its panel with `aria-controls` only while a `TabList.Panel`\n * with its value is mounted.\n */\nconst Tab = ({ value, id: idProp, icon, className, children, onClick, ref, ...rest }: TabProps) => {\n const ctx = useTabListContext('TabList.Tab');\n const selected = ctx.isSelected(value);\n const isVertical = ctx.orientation === 'vertical';\n const unavailable = isUnavailable(rest);\n const hasIcon = !!icon && slotRendersContent(icon);\n const iconOnly = hasIcon && !slotRendersContent(children);\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n const named =\n (typeof ariaLabel === 'string' && ariaLabel.trim() !== '') ||\n (typeof ariaLabelledBy === 'string' && ariaLabelledBy.trim() !== '');\n React.useEffect(() => {\n if (iconOnly && !named) {\n warnOnce(\n 'TabList.Tab:icon-only-name',\n 'TabList.Tab: a tab with an icon and no text has no accessible name. Pass `aria-label` (or `aria-labelledby`).',\n );\n }\n }, [iconOnly, named]);\n\n const { registry } = ctx;\n const id = consumerId(idProp) ?? ctx.getGeneratedId('tab', value);\n React.useLayoutEffect(() => registry.register('tab', value, id), [registry, value, id]);\n const mountedPanelId = React.useSyncExternalStore(\n registry.subscribe,\n () => registry.get('panel', value),\n () => undefined,\n );\n // Before the TabList mounts the static structure stands in; after that only a mounted panel is\n // referenced (`null`: none).\n const panelId =\n mountedPanelId === undefined ? ctx.getStaticPanelId(value) : (mountedPanelId ?? undefined);\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n className={cn(\n tabListTabClassNames.root,\n 'font-semibold transition-colors motion-reduce:transition-none',\n iconOnly ? tabIconOnlyPadding[ctx.size] : tabPadding[ctx.size],\n tabText[ctx.size],\n hasIcon && 'inline-flex items-center justify-center gap-2',\n isVertical && 'text-start',\n tabLookClasses(ctx.appearance, selected, isVertical),\n disabledStyles,\n focusRingInset,\n className,\n )}\n {...rest}\n id={id}\n aria-selected={selected}\n aria-controls={selected ? panelId : undefined}\n tabIndex={ctx.getTabIndex(value)}\n data-roving-value={value}\n data-selected={selected ? '' : undefined}\n data-icon-only={iconOnly ? '' : undefined}\n onClick={composeEventHandlers(onClick, () => {\n if (!unavailable) ctx.select(value);\n })}\n ref={ref}\n >\n {hasIcon && renderSlot(icon, 'span', tabListTabClassNames.icon, { 'aria-hidden': true })}\n {children}\n </button>\n );\n};\nTab.displayName = 'Tab';\n\n/* ------------------------------------------------------------------ */\n/* TabList.Panel */\n/* ------------------------------------------------------------------ */\n\n/** Properties for the TabPanel sub-component. */\nexport interface TabPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Value of the Tab that shows this panel. */\n value: string;\n /** Ref to the `role=\"tabpanel\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The content of one tab, rendered only while its tab is selected and labelled by it (while a Tab\n * with its value is mounted). A non-empty `id` replaces the generated one (the tab's\n * `aria-controls` follows it).\n */\nconst TabPanel = ({ value, id: idProp, children, className, ref, ...rest }: TabPanelProps) => {\n const ctx = useTabListContext('TabList.Panel');\n const insideTablist = React.useContext(TabListAreaContext) === 'tabs';\n React.useEffect(() => {\n if (insideTablist) warnOnce('TabList.Panel:inside-tablist', PANEL_IN_TABLIST_MESSAGE);\n }, [insideTablist]);\n const { registry } = ctx;\n const id = consumerId(idProp) ?? ctx.getGeneratedId('panel', value);\n // Registered while mounted, also while hidden: the tab that selects it links to it.\n React.useLayoutEffect(() => registry.register('panel', value, id), [registry, value, id]);\n const mountedTabId = React.useSyncExternalStore(\n registry.subscribe,\n () => registry.get('tab', value),\n () => undefined,\n );\n if (!ctx.isSelected(value)) return null;\n // As for the Tab's aria-controls: the static structure only before the TabList mounts.\n const tabId =\n mountedTabId === undefined ? ctx.getStaticTabId(value) : (mountedTabId ?? undefined);\n return (\n <div\n role=\"tabpanel\"\n tabIndex={0}\n className={cn(tabListPanelClassNames.root, 'p-4', focusRing, className)}\n {...rest}\n id={id}\n aria-labelledby={tabId}\n ref={ref}\n >\n {children}\n </div>\n );\n};\nTabPanel.displayName = 'TabPanel';\n\n/* ------------------------------------------------------------------ */\n/* TabList.Panels */\n/* ------------------------------------------------------------------ */\n\n/** Properties for the TabPanels sub-component. */\nexport interface TabPanelsProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the container `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Optional container for the panels, rendered after the tablist. Use it to style the panel area,\n * and for panels that components render themselves: the TabList finds a Panel in its children, in\n * a Fragment or in a wrapper that holds no Tab, but a component that renders a Panel itself\n * renders inside the tablist unless it is placed in `TabList.Panels`.\n */\nconst TabPanels = ({ className, children, ref, ...rest }: TabPanelsProps) => (\n <div\n ref={ref}\n className={cn(tabListPanelsClassNames.root, 'min-w-0 flex-1', className)}\n {...rest}\n >\n {children}\n </div>\n);\nTabPanels.displayName = 'TabPanels';\n\n/* ------------------------------------------------------------------ */\n/* Export */\n/* ------------------------------------------------------------------ */\n\n/**\n * A set of tabs with their panels (WAI-ARIA Tabs pattern): the arrow keys (Left/Right, mirrored\n * in RTL; Up/Down when vertical), Home and End move focus and select (automatic activation); with\n * `selectTabOnFocus={false}` they only move focus, and Enter, Space or a click selects the focused\n * tab (manual activation). The selected tab is the only tab stop; disabled tabs are skipped. Every\n * tab needs a `value` that is unique within the TabList (a development warning names a value that\n * several tabs share).\n *\n * Tabs register through context and are found in DOM order, so they may be wrapped (a Fragment,\n * a Tooltip). The children render inside the `role=\"tablist\"` element, except panels, which render\n * after it: a `TabList.Panel` or `TabList.Panels` child, or a wrapper (an element, `Suspense`, an\n * error boundary) that holds panels and no Tab. A Panel that a component renders itself cannot be\n * seen from the children: put that component inside `TabList.Panels` (a development warning names\n * a Panel that ends up inside the tablist). Content that is not a tab, such as a button next to\n * the tabs, does not belong in a tablist either: render it outside the TabList.\n *\n * Sub-components are also exported under flat names (`TabListTab`, `TabListPanel`,\n * `TabListPanels`) for React Server Components, which cannot use the dotted form.\n */\nexport const TabList = /* @__PURE__ */ Object.assign(TabListRoot, {\n Tab,\n Panel: TabPanel,\n Panels: TabPanels,\n});\n\nexport { Tab as TabListTab, TabPanel as TabListPanel, TabPanels as TabListPanels };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TabList.cjs","names":["React","getElementType","resolveDeprecatedProp","useControllable","useRovingTabIndex","useEventCallback","useId","useMotionClasses","tabIndicatorMotion","usePrefersReducedMotion","getPartId","useMergedRefs","cn","tabListClassNames","composeEventHandlers","forcedColors","slotRendersContent","tabListTabClassNames","disabledStyles","focusRingInset","renderSlot","tabListPanelClassNames","focusRing","tabListPanelsClassNames","require_runtime","require_cn","require_children","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_useRovingTabIndex","require_useMergedRefs","require_usePrefersReducedMotion","require_styles","require_motion","require_useMotion","require_disclosureIds","react","react_jsx_runtime","warnDuplicateTabValue","value","createRegistry","entries","listeners","ready","emit","listener","map","part","ids","id","index","INERT_REGISTRY","TabListContext","INERT_CONTEXT","useTabListContext","component","isUnavailable","ariaDisabled","props","consumerId","collectStructure","node","child","into","type","Tab","TabPanel","TabListRoot","containsPart","TabPanels","rendersAfterTablist","TabListAreaContext","PANEL_IN_TABLIST_MESSAGE","valueProp","defaultValueProp","orientationProp","rest","selectedValue","defaultValue","defaultSelectedValue","orientation","vertical","onTabSelect","selected","setSelected","isControlled","onValueChange","structureKey","children","structure","parsed","derivesSelection","selectTabOnFocus","select","next","isSelected","getTabIndex","tabValue","baseId","registry","isVertical","indicatorMotion","motion","prefersReducedMotion","slidesIndicator","appearance","indicator","setIndicator","tablistRef","lineValueRef","tablist","tabs","valueOf","tab","nextValue","previousValue","previous","from","to","size","frame","context","itemValue","panel","mergedRef","ref","containerProps","panels","keyed","key","className","onKeyDown","onFocus","tabPadding","tabIconOnlyPadding","tabText","tabIndicatorClasses","tabLookClasses","shape","idProp","ctx","lineStart","lineMotion","tabStyle","style","unavailable","hasIcon","icon","iconOnly","ariaLabel","ariaLabelledBy","named","mountedPanelId","panelId","onClick","insideTablist","mountedTabId","tabId","TabList"],"sources":["../../../src/components/layout/TabList.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n tabListClassNames,\n tabListPanelClassNames,\n tabListPanelsClassNames,\n tabListTabClassNames,\n} from '../../lib/classNames';\nimport { flattenChildren, getElementType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport {\n reportMissingContext,\n resolveDeprecatedProp,\n warnDeprecated,\n warnOnce,\n} from '../../lib/dev';\nimport { tabIndicatorMotion } from '../../lib/motion';\nimport { renderSlot, slotRendersContent } from '../../lib/slot';\nimport { disabledStyles, focusRing, focusRingInset, forcedColors } from '../../lib/styles';\nimport type { CoreSize, MotionSlot, Orientation, Slot } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useMotionClasses } from '../../hooks/useMotion';\nimport { usePrefersReducedMotion } from '../../hooks/usePrefersReducedMotion';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { getPartId } from './disclosureIds';\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\ntype TabListPart = 'tab' | 'panel';\n\n/**\n * The ids of the mounted Tabs and Panels by value. A Tab references a panel only while one with\n * its value is mounted (a TabList used as a filter bar has none), and each side references the\n * other's actual id, a consumer `id` included. Read with `useSyncExternalStore`.\n *\n * Before the TabList has mounted (server HTML, hydration and the first client render) the\n * registry is not ready and the static structure of the children stands in for it; once it is\n * ready, it alone decides, so a Panel that is in the element tree but never mounts (inside a\n * wrapper that renders nothing) is not referenced.\n */\ninterface TabListRegistry {\n /** Registers a mounted Tab or Panel; returns the unregister function. */\n register: (part: TabListPart, value: string, id: string) => () => void;\n /**\n * Id of the first mounted Tab or Panel with this value, `null` when none is mounted, or\n * `undefined` while the registry is not ready (use the static structure then).\n */\n get: (part: TabListPart, value: string) => string | null | undefined;\n /** Called by the TabList once it (and so every Tab and Panel mounted with it) has mounted. */\n markReady: () => void;\n subscribe: (listener: () => void) => () => void;\n}\n\n/** Tabs that share a value share one id, and are selected and tab stops together. */\nfunction warnDuplicateTabValue(value: string): void {\n warnOnce(\n `TabList:duplicate:${value}`,\n `TabList: several tabs share the value \"${value}\". Tab values must be unique within a ` +\n 'TabList; tabs with the same value share one id and are selected (and tab stops) together.',\n );\n}\n\nfunction createRegistry(): TabListRegistry {\n const entries: Record<TabListPart, Map<string, string[]>> = { tab: new Map(), panel: new Map() };\n const listeners = new Set<() => void>();\n let ready = false;\n const emit = () => {\n listeners.forEach((listener) => listener());\n };\n return {\n register(part, value, id) {\n const map = entries[part];\n const ids = map.get(value) ?? [];\n // Called from the part's layout effect (C-DEV). Two Panels may share a value (the Tab links\n // to the first mounted one); two Tabs may not.\n if (part === 'tab' && ids.length > 0) warnDuplicateTabValue(value);\n map.set(value, [...ids, id]);\n emit();\n return () => {\n const ids = [...(map.get(value) ?? [])];\n const index = ids.indexOf(id);\n if (index !== -1) ids.splice(index, 1);\n if (ids.length > 0) map.set(value, ids);\n else map.delete(value);\n emit();\n };\n },\n get: (part, value) => (ready ? (entries[part].get(value)?.[0] ?? null) : undefined),\n markReady() {\n if (ready) return;\n ready = true;\n emit();\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n\nconst INERT_REGISTRY: TabListRegistry = {\n register: () => () => {},\n get: () => undefined,\n markReady: () => {},\n subscribe: () => () => {},\n};\n\n/**\n * What the TabList's children show before anything mounts (server HTML and the first render):\n * found in the element tree through Fragments and the `children` of wrapper elements, but not\n * inside a component that renders a Tab or Panel itself (the registry covers those once mounted).\n */\ninterface TabListStructure {\n /** Value of the first Tab without `disabled`/`aria-disabled`: the uncontrolled default. */\n firstEnabled?: string;\n /** Consumer `id`s of Tabs, by value. */\n tabIds: Array<[string, string]>;\n /** Values of the Panels, each with its consumer `id` or `null`. */\n panels: Array<[string, string | null]>;\n}\n\n/** The look of a TabList: an underline, subtle fills, or circular subtle or filled tabs. */\nexport type TabListAppearance = 'transparent' | 'subtle' | 'subtle-circular' | 'filled-circular';\n\n/**\n * Where the selected tab's line starts its slide (FLIP), measured in physical pixels from the tab\n * selected before: its offset along the list's axis and its size as a ratio of the new tab's.\n */\ninterface TabIndicatorStart {\n /** The value of the tab that draws the line. */\n value: string;\n /** The previous tab's left (top when vertical) minus the new tab's, in pixels. */\n offset: number;\n /** The previous tab's width (height when vertical) divided by the new tab's. */\n scale: number;\n}\n\ninterface TabListContextValue {\n orientation: Orientation;\n appearance: TabListAppearance;\n size: CoreSize;\n /** Whether the tab with this value is the selected one (explicit value, else the tab stop). */\n isSelected: (value: string) => boolean;\n /**\n * Activates a tab: a click (Enter and Space click the tab button), or with automatic activation\n * focus moved by the keys.\n */\n select: (value: string) => void;\n getTabIndex: (value: string) => 0 | -1;\n /** The generated id of a Tab or Panel (used when it has no consumer `id`). */\n getGeneratedId: (part: TabListPart, value: string) => string;\n /**\n * Id of the Tab with this value before the TabList mounts: its consumer `id`, else the\n * generated one.\n */\n getStaticTabId: (value: string) => string;\n /**\n * Id of the Panel with this value before the TabList mounts, or `undefined` when the children\n * have none.\n */\n getStaticPanelId: (value: string) => string | undefined;\n registry: TabListRegistry;\n /**\n * The line's start for the one frame after the selection moved, rendered by the tab with its\n * value as custom properties (without `indicatorMotion`); `null` otherwise.\n */\n indicator: TabIndicatorStart | null;\n /** The motion classes of the selected tab's line (`''`: none). */\n indicatorMotion: string;\n}\n\nconst TabListContext = React.createContext<TabListContextValue | null>(null);\n\nconst INERT_CONTEXT: TabListContextValue = {\n orientation: 'horizontal',\n appearance: 'transparent',\n size: 'medium',\n isSelected: () => false,\n select: () => {},\n getTabIndex: () => -1,\n getGeneratedId: (part, value) => `wave-tablist-inert-${part}-${value}`,\n getStaticTabId: (value) => `wave-tablist-inert-tab-${value}`,\n getStaticPanelId: () => undefined,\n registry: INERT_REGISTRY,\n indicator: null,\n indicatorMotion: '',\n};\n\n/** C-CONTEXT: throws in development, logs once and returns an inert value in production. */\nfunction useTabListContext(component: string): TabListContextValue {\n const context = React.useContext(TabListContext);\n if (context) return context;\n reportMissingContext(component, '<TabList>');\n return INERT_CONTEXT;\n}\n\ninterface StructureProps {\n value?: unknown;\n id?: unknown;\n disabled?: unknown;\n 'aria-disabled'?: unknown;\n children?: unknown;\n}\n\n/** Whether a Tab's props make it unavailable (it cannot be selected and is skipped by keys). */\nfunction isUnavailable(props: StructureProps): boolean {\n const ariaDisabled = props['aria-disabled'];\n return props.disabled === true || ariaDisabled === true || ariaDisabled === 'true';\n}\n\n/** A consumer `id` that replaces the generated one: a non-empty string (`''` counts as none). */\nfunction consumerId(id: unknown): string | null {\n return typeof id === 'string' && id !== '' ? id : null;\n}\n\n/**\n * Walks the element tree of the TabList's children (see {@link TabListStructure}). Parts are\n * identified through their element type, so parts written in a Server Component (lazy\n * references) count too. A `React.lazy` still loading (inside the consumer's own `<Suspense>`,\n * such as code-split panels in `TabList.Panels`) is no part and never suspends the TabList: its\n * children are walked instead. Runs during render only.\n */\nfunction collectStructure(node: unknown, into: TabListStructure): TabListStructure {\n if (Array.isArray(node)) {\n node.forEach((child) => collectStructure(child, into));\n return into;\n }\n if (!React.isValidElement<StructureProps>(node)) return into;\n const { props } = node;\n const type = getElementType(node, { suspend: false });\n const value = typeof props.value === 'string' ? props.value : undefined;\n if (type === Tab) {\n if (value !== undefined) {\n if (into.firstEnabled === undefined && !isUnavailable(props)) into.firstEnabled = value;\n const id = consumerId(props.id);\n if (id !== null) into.tabIds.push([value, id]);\n }\n return into;\n }\n if (type === TabPanel) {\n if (value !== undefined) into.panels.push([value, consumerId(props.id)]);\n return into;\n }\n if (type === TabListRoot) return into;\n return collectStructure(props.children, into);\n}\n\n/**\n * Whether an element tree shows a Tab, or a Panel (`TabList.Panel` or `TabList.Panels`), found as\n * in {@link collectStructure}: through Fragments and the `children` of wrapper elements, not inside\n * a nested TabList or a component that renders the part itself.\n */\nfunction containsPart(node: unknown, part: TabListPart): boolean {\n if (Array.isArray(node)) return node.some((child) => containsPart(child, part));\n if (!React.isValidElement<StructureProps>(node)) return false;\n const type = getElementType(node, { suspend: false });\n if (type === Tab) return part === 'tab';\n if (type === TabPanel || type === TabPanels) return part === 'panel';\n if (type === TabListRoot) return false;\n return containsPart(node.props.children, part);\n}\n\n/**\n * Whether a child of the TabList renders after the tablist: a Panel, `TabList.Panels`, or a\n * wrapper (an element, `Suspense`, an error boundary) that holds panels and no tab.\n */\nfunction rendersAfterTablist(child: React.ReactNode): boolean {\n return containsPart(child, 'panel') && !containsPart(child, 'tab');\n}\n\n/**\n * Where the TabList renders its children: inside the `role=\"tablist\"` element (`'tabs'`) or after\n * it (`'panels'`). A Panel that ends up inside the tablist warns in development.\n */\nconst TabListAreaContext = React.createContext<'tabs' | 'panels' | null>(null);\n\nconst PANEL_IN_TABLIST_MESSAGE =\n 'TabList.Panel was rendered inside the role=\"tablist\" element, where only tabs belong (axe ' +\n 'aria-required-children). The TabList moves a Panel after the tablist when it is its child, or ' +\n 'in a wrapper that holds no Tab, but it cannot see a Panel that a component renders itself, or ' +\n \"separate a wrapper's Panels from its Tabs. Place such panels inside TabList.Panels, which \" +\n 'renders after the tablist.';\n\n/* ------------------------------------------------------------------ */\n/* TabList */\n/* ------------------------------------------------------------------ */\n\n/** Properties for the TabList component. */\nexport interface TabListProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'defaultValue'> {\n /**\n * Controlled value of the selected tab (`''`: no tab selected). A controlled value that becomes\n * `undefined` also selects no tab: the TabList stays controlled.\n */\n value?: string;\n /**\n * Selected tab for uncontrolled usage. When it is omitted (or `''`), the first enabled tab\n * written in the TabList's children is selected, from the first render (and in server-rendered\n * HTML) on. Tabs written directly in the children, in Fragments or in wrapper elements that\n * pass them as `children` (such as a Tooltip) count; a tab rendered by a custom component that\n * renders `TabList.Tab` itself does not, even when it comes first in the DOM, so that server\n * and client pick the same tab. When every tab comes from such a component, the first enabled\n * tab in the DOM is selected once the tabs mount. To select a tab that a custom component\n * renders, pass `defaultValue`.\n */\n defaultValue?: string;\n /** Called with the new value when the selected tab changes (not when it is activated again). */\n onValueChange?: (value: string) => void;\n /**\n * Layout and arrow-key axis: `'horizontal'` (Left/Right, mirrored in RTL) or `'vertical'`\n * (Up/Down).\n * @default 'horizontal'\n */\n orientation?: Orientation;\n /**\n * Look of the tabs: `transparent` underlines the selected tab, `subtle` and `subtle-circular`\n * fill it with a subtle color (square or fully rounded), `filled-circular` fills it with the\n * primary color. In forced colors the selected tab keeps a Highlight outline (or underline) in\n * every appearance.\n * @default 'transparent'\n */\n appearance?: TabListAppearance;\n /**\n * Size of the tabs: their padding and type (`medium` is 14px text on 16 by 8px padding).\n * @default 'medium'\n */\n size?: CoreSize;\n /**\n * Whether moving focus with the arrow keys, Home and End also selects the tab (automatic\n * activation, as in 0.5). With `false`, the keys only move focus and Enter, Space or a click\n * selects the focused tab (manual activation, for panels that are slow to show). Fluent's\n * default is `false`.\n * @default true\n */\n selectTabOnFocus?: boolean;\n /**\n * Replaces the slide of the selected tab's line in the `transparent` appearance (the other\n * appearances have no line and do not move): by default, when the selection moves, the line\n * slides and stretches from the tab selected before to the new one, over the slow duration\n * (300 ms) with the max decelerating curve. The classes go on the selected tab and time its\n * line, the tab's after pseudo-element (write them with the after variant, and a reduced-motion\n * counterpart); the line starts from the previous tab through two custom properties the\n * TabList writes for one frame. `null` turns the slide off (the line moves at once); a class\n * string or `{ className }` replaces the classes with plain transition classes for the line, as\n * above (it has no presence phases). A\n * `WaveProvider` with `motion=\"none\"` turns the default off, and a value here still applies\n * under it. The line also moves at once while the user prefers reduced motion. Fluent's\n * TabList slides its indicator with no prop to turn it off: this prop is a WaveUI addition.\n * @default the slide described above\n */\n motion?: MotionSlot | null;\n /** @deprecated Use `value`. */\n selectedValue?: string;\n /** @deprecated Use `defaultValue`. */\n defaultSelectedValue?: string;\n /**\n * @deprecated Use `onValueChange`. Unlike `onValueChange`, it is called on every activation,\n * including a click on the tab that is already selected.\n */\n onTabSelect?: (value: string) => void;\n /** @deprecated Use `orientation=\"vertical\"`. */\n vertical?: boolean;\n /** Ref to the `role=\"tablist\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\nconst TabListRoot = ({\n value: valueProp,\n defaultValue: defaultValueProp,\n onValueChange,\n orientation: orientationProp,\n appearance = 'transparent',\n size = 'medium',\n selectTabOnFocus = true,\n motion,\n selectedValue,\n defaultSelectedValue,\n onTabSelect,\n vertical,\n className,\n children,\n onKeyDown,\n onFocus,\n ref,\n ...rest\n}: TabListProps) => {\n const value = resolveDeprecatedProp(\n 'TabList',\n valueProp,\n selectedValue,\n 'selectedValue',\n 'value',\n );\n const defaultValue = resolveDeprecatedProp(\n 'TabList',\n defaultValueProp,\n defaultSelectedValue,\n 'defaultSelectedValue',\n 'defaultValue',\n );\n const orientation =\n resolveDeprecatedProp<Orientation>(\n 'TabList',\n orientationProp,\n vertical === undefined ? undefined : vertical ? 'vertical' : 'horizontal',\n 'vertical',\n 'orientation',\n ) ?? 'horizontal';\n if (onTabSelect) {\n warnDeprecated(\n 'TabList',\n 'onTabSelect',\n 'onValueChange',\n '`onValueChange` is called only when the selected tab changes.',\n );\n }\n\n // The sticky mode: a controlled value that becomes `undefined` clears the selection (`''`).\n const [selected, setSelected, isControlled] = useControllable(\n value,\n defaultValue ?? '',\n onValueChange,\n );\n\n // The children are a new element tree on every parent render: memoized by content, so the\n // context value stays stable while the tabs and panels stay the same.\n const structureKey = JSON.stringify(collectStructure(children, { tabIds: [], panels: [] }));\n const structure = React.useMemo(() => {\n const parsed = JSON.parse(structureKey) as TabListStructure;\n return {\n firstEnabled: parsed.firstEnabled,\n tabIds: new Map(parsed.tabIds),\n panels: new Map(parsed.panels),\n };\n }, [structureKey]);\n\n // Uncontrolled without a selection: the first enabled tab is selected. It is the tab stop the\n // roving store resolves from `activeValue` (the first enabled tab of the children, replaced by\n // the first enabled tab in the DOM once the store sees it disabled), so the selection is\n // derived during render, present from the first render on, and follows tabs that disable\n // themselves.\n const derivesSelection = !isControlled && selected === '';\n\n const { containerProps, getTabIndex } = useRovingTabIndex({\n activeValue: derivesSelection ? (structure.firstEnabled ?? null) : selected,\n orientation,\n loop: true,\n // Automatic activation (APG Tabs): moving focus selects the tab. With manual activation the\n // keys only move focus; the tab stop stays on the selected tab (`tabStop: 'active'`), and Enter\n // or Space selects the focused tab through its native click.\n onFocusMove: selectTabOnFocus ? (next) => select(next) : undefined,\n });\n\n const isSelected = React.useCallback(\n (tabValue: string) => (derivesSelection ? getTabIndex(tabValue) === 0 : selected === tabValue),\n [derivesSelection, getTabIndex, selected],\n );\n\n const select = useEventCallback((next: string) => {\n onTabSelect?.(next);\n if (!isSelected(next)) setSelected(next);\n });\n\n const baseId = useId('tablist');\n const [registry] = React.useState(createRegistry);\n // Runs after the layout effects of the Tabs and Panels mounted with the TabList, which have\n // registered by then: from here on the registry, not the static structure, decides the links.\n React.useLayoutEffect(() => registry.markReady(), [registry]);\n\n const isVertical = orientation === 'vertical';\n const indicatorMotion = useMotionClasses(motion, tabIndicatorMotion);\n const prefersReducedMotion = usePrefersReducedMotion();\n // Only the underline look has a line, and only a motion slides it (spec §9.2).\n const slidesIndicator =\n appearance === 'transparent' && indicatorMotion !== '' && !prefersReducedMotion;\n const [indicator, setIndicator] = React.useState<TabIndicatorStart | null>(null);\n const tablistRef = React.useRef<HTMLDivElement>(null);\n // The value of the tab that drew the line after the last selection change seen, `null` before\n // the first one is seen (nothing slides on mount).\n const lineValueRef = React.useRef<string | null>(null);\n\n // The FLIP of the line (spec §9.2, Ruling R12), keyed on the selection (`isSelected` changes\n // with it, the derived default included): once the newly selected tab is in the DOM, both tabs\n // are measured (physical pixels, so right-to-left needs nothing of its own) and the new tab\n // starts its line over the previous one for one frame. Tabs are matched by their value as a\n // string, never through a selector built from it.\n React.useLayoutEffect(() => {\n const tablist = tablistRef.current;\n if (!tablist) return;\n const tabs = Array.from(tablist.querySelectorAll<HTMLElement>('[role=\"tab\"]'));\n const valueOf = (tab: HTMLElement) => tab.getAttribute('data-roving-value');\n const next = tabs.find((tab) => {\n const tabValue = valueOf(tab);\n return tabValue !== null && isSelected(tabValue);\n });\n const nextValue = next ? valueOf(next) : null;\n const previousValue = lineValueRef.current;\n lineValueRef.current = nextValue;\n if (!slidesIndicator || !next || nextValue === null || previousValue === null) return;\n if (nextValue === previousValue) return;\n const previous = tabs.find((tab) => valueOf(tab) === previousValue);\n if (!previous) return;\n const from = previous.getBoundingClientRect();\n const to = next.getBoundingClientRect();\n const size = isVertical ? to.height : to.width;\n if (size === 0) return;\n setIndicator({\n value: nextValue,\n offset: isVertical ? from.top - to.top : from.left - to.left,\n scale: (isVertical ? from.height : from.width) / size,\n });\n }, [isSelected, slidesIndicator, isVertical]);\n\n // The start is painted for one frame, then cleared (C-HOOKS deferred update): the next commit\n // drops the properties and adds the motion, so the line glides back to its own tab. A newer\n // start, or an unmount, cancels the frame of the one before.\n React.useEffect(() => {\n if (!indicator) return;\n const frame = requestAnimationFrame(() => setIndicator(null));\n return () => cancelAnimationFrame(frame);\n }, [indicator]);\n\n const context = React.useMemo<TabListContextValue>(\n () => ({\n orientation,\n appearance,\n size,\n isSelected,\n select,\n getTabIndex,\n getGeneratedId: (part, itemValue) => getPartId(baseId, part, itemValue),\n getStaticTabId: (tabValue) =>\n structure.tabIds.get(tabValue) ?? getPartId(baseId, 'tab', tabValue),\n getStaticPanelId: (tabValue) => {\n const panel = structure.panels.get(tabValue);\n if (panel === undefined) return undefined;\n return panel ?? getPartId(baseId, 'panel', tabValue);\n },\n registry,\n indicator,\n indicatorMotion,\n }),\n [\n orientation,\n appearance,\n size,\n isSelected,\n select,\n getTabIndex,\n baseId,\n structure,\n registry,\n indicator,\n indicatorMotion,\n ],\n );\n\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, containerProps.ref, tablistRef);\n\n const tabs: React.ReactNode[] = [];\n const panels: React.ReactNode[] = [];\n flattenChildren(children).forEach(({ key, node: child }) => {\n const keyed = <React.Fragment key={key}>{child}</React.Fragment>;\n (rendersAfterTablist(child) ? panels : tabs).push(keyed);\n });\n\n return (\n <TabListContext.Provider value={context}>\n <div className={cn(isVertical && 'flex')}>\n <div\n role=\"tablist\"\n aria-orientation={orientation}\n data-appearance={appearance}\n data-size={size}\n data-orientation={orientation}\n className={cn(\n tabListClassNames.root,\n isVertical ? 'flex w-40 flex-col' : 'flex',\n appearance === 'transparent'\n ? isVertical\n ? 'border-e border-border'\n : 'border-b border-border'\n : 'gap-1',\n className,\n )}\n {...rest}\n data-roving-container=\"\"\n onKeyDown={composeEventHandlers(onKeyDown, containerProps.onKeyDown)}\n onFocus={composeEventHandlers(onFocus, containerProps.onFocus, {\n checkDefaultPrevented: false,\n })}\n ref={mergedRef}\n >\n <TabListAreaContext.Provider value=\"tabs\">{tabs}</TabListAreaContext.Provider>\n </div>\n <TabListAreaContext.Provider value=\"panels\">{panels}</TabListAreaContext.Provider>\n </div>\n </TabListContext.Provider>\n );\n};\nTabListRoot.displayName = 'TabList';\n\n/* ------------------------------------------------------------------ */\n/* TabList.Tab */\n/* ------------------------------------------------------------------ */\n\n/** Padding of a tab with text, per size. Literal strings only. */\nconst tabPadding: Readonly<Record<CoreSize, string>> = {\n small: 'px-3 py-1.5',\n medium: 'px-4 py-2',\n large: 'px-5 py-3',\n};\n\n/** Padding of an icon-only tab (a square hit area), per size. */\nconst tabIconOnlyPadding: Readonly<Record<CoreSize, string>> = {\n small: 'p-1.5',\n medium: 'p-2',\n large: 'p-3',\n};\n\n/** Type step of a tab, per size. */\nconst tabText: Readonly<Record<CoreSize, string>> = {\n small: 'text-caption-1',\n medium: 'text-body-1',\n large: 'text-body-2',\n};\n\n/**\n * The line of the selected tab with the underline look, per orientation. A transparent 2px border\n * on the tab's edge keeps the tab's box, and the after pseudo-element draws the line exactly over\n * it, as a border, so forced colors keep it (in Highlight). The line's translate and scale read\n * the two custom properties of its FLIP start, so it begins over the tab selected before for one\n * frame. Literal strings only.\n */\nconst tabIndicatorClasses: Readonly<Record<Orientation, string>> = {\n horizontal:\n 'relative border-b-2 border-b-transparent after:absolute after:inset-x-0 after:-bottom-0.5 after:border-b-2 after:border-b-primary after:origin-left after:translate-x-[var(--wave-tab-indicator-offset,0px)] after:scale-x-[var(--wave-tab-indicator-scale,1)] forced-colors:after:border-[Highlight]', // wave-allow-physical: the FLIP offset is measured in physical pixels\n vertical:\n 'relative border-s-2 border-s-transparent after:absolute after:inset-y-0 after:-start-0.5 after:border-s-2 after:border-s-primary after:origin-top after:translate-y-[var(--wave-tab-indicator-offset,0px)] after:scale-y-[var(--wave-tab-indicator-scale,1)] forced-colors:after:border-[Highlight]', // wave-allow-physical: the FLIP offset is measured in physical pixels\n};\n\n/**\n * The colors, fill and selected indicator of a tab per appearance. Literal strings only; hover and\n * pressed use the gated rules (a disabled tab keeps its look). In forced colors fills are dropped,\n * so every selected tab keeps a Highlight outline (or, for the underline, a Highlight line).\n */\nfunction tabLookClasses(\n appearance: TabListAppearance,\n selected: boolean,\n vertical: boolean,\n): string {\n switch (appearance) {\n case 'subtle':\n case 'subtle-circular': {\n const shape = appearance === 'subtle' ? 'rounded-md' : 'rounded-full';\n return selected\n ? cn(shape, 'bg-subtle-selected text-foreground', forcedColors.selectedContainer)\n : cn(\n shape,\n 'text-muted-foreground not-disabled:not-aria-disabled:hover:bg-subtle-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-subtle-pressed',\n );\n }\n case 'filled-circular':\n return selected\n ? cn(\n 'rounded-full bg-primary text-primary-foreground not-disabled:not-aria-disabled:hover:bg-primary-hover not-disabled:not-aria-disabled:active:bg-primary-pressed',\n forcedColors.selectedContainer,\n )\n : 'rounded-full bg-muted text-muted-foreground not-disabled:not-aria-disabled:hover:bg-muted-hover not-disabled:not-aria-disabled:hover:text-foreground not-disabled:not-aria-disabled:active:bg-muted-pressed';\n default:\n // Every tab's own border has one color whether selected or not (forced colors would turn a\n // transparent one into the text color, but keep a system color): the tab's color transition\n // covers its border, so a color that changed with the selection would fade a second line in\n // under the new tab while its line slides there.\n return cn(\n 'border-transparent forced-colors:border-[Canvas]',\n selected\n ? cn('text-primary', tabIndicatorClasses[vertical ? 'vertical' : 'horizontal'])\n : 'text-muted-foreground not-disabled:not-aria-disabled:hover:text-foreground',\n );\n }\n}\n\n/** Properties for the Tab sub-component. */\nexport interface TabProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Unique value identifying this tab (and its panel). */\n value: string;\n /**\n * An icon before the text, hidden from assistive technology. A tab with an icon and no text is\n * icon-only (a square hit area): name it with `aria-label`, or a development warning asks for it.\n */\n icon?: Slot<'span'>;\n /** Ref to the tab `<button>`. */\n ref?: React.Ref<HTMLButtonElement>;\n}\n\n/**\n * A tab button. `onClick` runs before the selection (call `event.preventDefault()` to keep the\n * current tab). A `disabled` (or `aria-disabled=\"true\"`) tab is skipped by the keyboard and cannot\n * be selected. A non-empty `id` replaces the generated one (its panel's `aria-labelledby` follows\n * it). The selected tab references its panel with `aria-controls` only while a `TabList.Panel`\n * with its value is mounted.\n */\nconst Tab = ({\n value,\n id: idProp,\n icon,\n className,\n style,\n children,\n onClick,\n ref,\n ...rest\n}: TabProps) => {\n const ctx = useTabListContext('TabList.Tab');\n const selected = ctx.isSelected(value);\n const isVertical = ctx.orientation === 'vertical';\n // The selected tab's line: over the tab selected before for one frame after the selection moved\n // (its FLIP start, without the motion), then on this tab with the motion, so it slides back.\n const lineStart = selected && ctx.indicator?.value === value ? ctx.indicator : null;\n const lineMotion =\n selected && ctx.appearance === 'transparent' && !lineStart ? ctx.indicatorMotion : undefined;\n const tabStyle = lineStart\n ? ({\n ...style,\n '--wave-tab-indicator-offset': `${lineStart.offset}px`,\n '--wave-tab-indicator-scale': String(lineStart.scale),\n } as React.CSSProperties)\n : style;\n const unavailable = isUnavailable(rest);\n const hasIcon = !!icon && slotRendersContent(icon);\n const iconOnly = hasIcon && !slotRendersContent(children);\n const ariaLabel = rest['aria-label'];\n const ariaLabelledBy = rest['aria-labelledby'];\n const named =\n (typeof ariaLabel === 'string' && ariaLabel.trim() !== '') ||\n (typeof ariaLabelledBy === 'string' && ariaLabelledBy.trim() !== '');\n React.useEffect(() => {\n if (iconOnly && !named) {\n warnOnce(\n 'TabList.Tab:icon-only-name',\n 'TabList.Tab: a tab with an icon and no text has no accessible name. Pass `aria-label` (or `aria-labelledby`).',\n );\n }\n }, [iconOnly, named]);\n\n const { registry } = ctx;\n const id = consumerId(idProp) ?? ctx.getGeneratedId('tab', value);\n React.useLayoutEffect(() => registry.register('tab', value, id), [registry, value, id]);\n const mountedPanelId = React.useSyncExternalStore(\n registry.subscribe,\n () => registry.get('panel', value),\n () => undefined,\n );\n // Before the TabList mounts the static structure stands in; after that only a mounted panel is\n // referenced (`null`: none).\n const panelId =\n mountedPanelId === undefined ? ctx.getStaticPanelId(value) : (mountedPanelId ?? undefined);\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n className={cn(\n tabListTabClassNames.root,\n 'font-semibold transition-colors motion-reduce:transition-none',\n iconOnly ? tabIconOnlyPadding[ctx.size] : tabPadding[ctx.size],\n tabText[ctx.size],\n hasIcon && 'inline-flex items-center justify-center gap-2',\n isVertical && 'text-start',\n tabLookClasses(ctx.appearance, selected, isVertical),\n disabledStyles,\n focusRingInset,\n lineMotion,\n className,\n )}\n style={tabStyle}\n {...rest}\n id={id}\n aria-selected={selected}\n aria-controls={selected ? panelId : undefined}\n tabIndex={ctx.getTabIndex(value)}\n data-roving-value={value}\n data-selected={selected ? '' : undefined}\n data-icon-only={iconOnly ? '' : undefined}\n onClick={composeEventHandlers(onClick, () => {\n if (!unavailable) ctx.select(value);\n })}\n ref={ref}\n >\n {hasIcon && renderSlot(icon, 'span', tabListTabClassNames.icon, { 'aria-hidden': true })}\n {children}\n </button>\n );\n};\nTab.displayName = 'Tab';\n\n/* ------------------------------------------------------------------ */\n/* TabList.Panel */\n/* ------------------------------------------------------------------ */\n\n/** Properties for the TabPanel sub-component. */\nexport interface TabPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Value of the Tab that shows this panel. */\n value: string;\n /** Ref to the `role=\"tabpanel\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * The content of one tab, rendered only while its tab is selected and labelled by it (while a Tab\n * with its value is mounted). A non-empty `id` replaces the generated one (the tab's\n * `aria-controls` follows it).\n */\nconst TabPanel = ({ value, id: idProp, children, className, ref, ...rest }: TabPanelProps) => {\n const ctx = useTabListContext('TabList.Panel');\n const insideTablist = React.useContext(TabListAreaContext) === 'tabs';\n React.useEffect(() => {\n if (insideTablist) warnOnce('TabList.Panel:inside-tablist', PANEL_IN_TABLIST_MESSAGE);\n }, [insideTablist]);\n const { registry } = ctx;\n const id = consumerId(idProp) ?? ctx.getGeneratedId('panel', value);\n // Registered while mounted, also while hidden: the tab that selects it links to it.\n React.useLayoutEffect(() => registry.register('panel', value, id), [registry, value, id]);\n const mountedTabId = React.useSyncExternalStore(\n registry.subscribe,\n () => registry.get('tab', value),\n () => undefined,\n );\n if (!ctx.isSelected(value)) return null;\n // As for the Tab's aria-controls: the static structure only before the TabList mounts.\n const tabId =\n mountedTabId === undefined ? ctx.getStaticTabId(value) : (mountedTabId ?? undefined);\n return (\n <div\n role=\"tabpanel\"\n tabIndex={0}\n className={cn(tabListPanelClassNames.root, 'p-4', focusRing, className)}\n {...rest}\n id={id}\n aria-labelledby={tabId}\n ref={ref}\n >\n {children}\n </div>\n );\n};\nTabPanel.displayName = 'TabPanel';\n\n/* ------------------------------------------------------------------ */\n/* TabList.Panels */\n/* ------------------------------------------------------------------ */\n\n/** Properties for the TabPanels sub-component. */\nexport interface TabPanelsProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Ref to the container `<div>`. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/**\n * Optional container for the panels, rendered after the tablist. Use it to style the panel area,\n * and for panels that components render themselves: the TabList finds a Panel in its children, in\n * a Fragment or in a wrapper that holds no Tab, but a component that renders a Panel itself\n * renders inside the tablist unless it is placed in `TabList.Panels`.\n */\nconst TabPanels = ({ className, children, ref, ...rest }: TabPanelsProps) => (\n <div\n ref={ref}\n className={cn(tabListPanelsClassNames.root, 'min-w-0 flex-1', className)}\n {...rest}\n >\n {children}\n </div>\n);\nTabPanels.displayName = 'TabPanels';\n\n/* ------------------------------------------------------------------ */\n/* Export */\n/* ------------------------------------------------------------------ */\n\n/**\n * A set of tabs with their panels (WAI-ARIA Tabs pattern): the arrow keys (Left/Right, mirrored\n * in RTL; Up/Down when vertical), Home and End move focus and select (automatic activation); with\n * `selectTabOnFocus={false}` they only move focus, and Enter, Space or a click selects the focused\n * tab (manual activation). The selected tab is the only tab stop; disabled tabs are skipped. Every\n * tab needs a `value` that is unique within the TabList (a development warning names a value that\n * several tabs share).\n *\n * Tabs register through context and are found in DOM order, so they may be wrapped (a Fragment,\n * a Tooltip). The children render inside the `role=\"tablist\"` element, except panels, which render\n * after it: a `TabList.Panel` or `TabList.Panels` child, or a wrapper (an element, `Suspense`, an\n * error boundary) that holds panels and no Tab. A Panel that a component renders itself cannot be\n * seen from the children: put that component inside `TabList.Panels` (a development warning names\n * a Panel that ends up inside the tablist). Content that is not a tab, such as a button next to\n * the tabs, does not belong in a tablist either: render it outside the TabList.\n *\n * In the `transparent` appearance the selected tab draws its line with its after pseudo-element,\n * over a transparent 2px border on its bottom edge (its start edge when vertical), so the tab keeps\n * the box it has without the line; a class that recolours the line targets that pseudo-element's\n * border. When the selection moves, the line slides from the tab selected before (`motion`).\n *\n * Sub-components are also exported under flat names (`TabListTab`, `TabListPanel`,\n * `TabListPanels`) for React Server Components, which cannot use the dotted form.\n */\nexport const TabList = /* @__PURE__ */ Object.assign(TabListRoot, {\n Tab,\n Panel: TabPanel,\n Panels: TabPanels,\n});\n\nexport { Tab as TabListTab, TabPanel as TabListPanel, TabPanels as TabListPanels };\n"],"mappings":"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"}
|