@mortenbrudvik/waveui 0.14.1 → 0.16.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.
Files changed (265) hide show
  1. package/README.md +413 -53
  2. package/dist/components/data-display/InfoButton.cjs +1 -1
  3. package/dist/components/data-display/InfoButton.cjs.map +1 -1
  4. package/dist/components/data-display/InfoButton.mjs +90 -82
  5. package/dist/components/data-display/InfoButton.mjs.map +1 -1
  6. package/dist/components/data-display/InfoLabel.cjs +1 -1
  7. package/dist/components/data-display/InfoLabel.cjs.map +1 -1
  8. package/dist/components/data-display/InfoLabel.mjs +19 -18
  9. package/dist/components/data-display/InfoLabel.mjs.map +1 -1
  10. package/dist/components/data-display/List.cjs +1 -1
  11. package/dist/components/data-display/List.cjs.map +1 -1
  12. package/dist/components/data-display/List.mjs +405 -219
  13. package/dist/components/data-display/List.mjs.map +1 -1
  14. package/dist/components/data-display/List.registry.cjs +1 -1
  15. package/dist/components/data-display/List.registry.cjs.map +1 -1
  16. package/dist/components/data-display/List.registry.mjs +12 -6
  17. package/dist/components/data-display/List.registry.mjs.map +1 -1
  18. package/dist/components/feedback/MessageBarGroup.cjs +2 -0
  19. package/dist/components/feedback/MessageBarGroup.cjs.map +1 -0
  20. package/dist/components/feedback/MessageBarGroup.mjs +63 -0
  21. package/dist/components/feedback/MessageBarGroup.mjs.map +1 -0
  22. package/dist/components/feedback/ProgressBar.cjs +1 -1
  23. package/dist/components/feedback/ProgressBar.cjs.map +1 -1
  24. package/dist/components/feedback/ProgressBar.mjs +41 -39
  25. package/dist/components/feedback/ProgressBar.mjs.map +1 -1
  26. package/dist/components/feedback/Toaster.cjs +1 -1
  27. package/dist/components/feedback/Toaster.cjs.map +1 -1
  28. package/dist/components/feedback/Toaster.mjs +222 -216
  29. package/dist/components/feedback/Toaster.mjs.map +1 -1
  30. package/dist/components/input/Combobox.cjs +1 -1
  31. package/dist/components/input/Combobox.cjs.map +1 -1
  32. package/dist/components/input/Combobox.mjs +163 -148
  33. package/dist/components/input/Combobox.mjs.map +1 -1
  34. package/dist/components/input/Dropdown.cjs +1 -1
  35. package/dist/components/input/Dropdown.cjs.map +1 -1
  36. package/dist/components/input/Dropdown.mjs +132 -117
  37. package/dist/components/input/Dropdown.mjs.map +1 -1
  38. package/dist/components/input/Listbox.cjs +1 -1
  39. package/dist/components/input/Listbox.cjs.map +1 -1
  40. package/dist/components/input/Listbox.mjs +90 -78
  41. package/dist/components/input/Listbox.mjs.map +1 -1
  42. package/dist/components/input/Option.cjs +1 -1
  43. package/dist/components/input/Option.cjs.map +1 -1
  44. package/dist/components/input/Option.data.cjs +2 -0
  45. package/dist/components/input/Option.data.cjs.map +1 -0
  46. package/dist/components/input/Option.data.mjs +114 -0
  47. package/dist/components/input/Option.data.mjs.map +1 -0
  48. package/dist/components/input/Option.mjs +21 -17
  49. package/dist/components/input/Option.mjs.map +1 -1
  50. package/dist/components/layout/Accordion.cjs +1 -1
  51. package/dist/components/layout/Accordion.cjs.map +1 -1
  52. package/dist/components/layout/Accordion.mjs +124 -109
  53. package/dist/components/layout/Accordion.mjs.map +1 -1
  54. package/dist/components/layout/Carousel.cjs +1 -1
  55. package/dist/components/layout/Carousel.cjs.map +1 -1
  56. package/dist/components/layout/Carousel.mjs +207 -193
  57. package/dist/components/layout/Carousel.mjs.map +1 -1
  58. package/dist/components/layout/FlatTree.cjs +2 -0
  59. package/dist/components/layout/FlatTree.cjs.map +1 -0
  60. package/dist/components/layout/FlatTree.context.cjs +2 -0
  61. package/dist/components/layout/FlatTree.context.cjs.map +1 -0
  62. package/dist/components/layout/FlatTree.context.mjs +20 -0
  63. package/dist/components/layout/FlatTree.context.mjs.map +1 -0
  64. package/dist/components/layout/FlatTree.item.cjs +2 -0
  65. package/dist/components/layout/FlatTree.item.cjs.map +1 -0
  66. package/dist/components/layout/FlatTree.item.mjs +90 -0
  67. package/dist/components/layout/FlatTree.item.mjs.map +1 -0
  68. package/dist/components/layout/FlatTree.mjs +276 -0
  69. package/dist/components/layout/FlatTree.mjs.map +1 -0
  70. package/dist/components/layout/TabList.cjs +1 -1
  71. package/dist/components/layout/TabList.cjs.map +1 -1
  72. package/dist/components/layout/TabList.mjs +149 -108
  73. package/dist/components/layout/TabList.mjs.map +1 -1
  74. package/dist/components/layout/Tree.cjs.map +1 -1
  75. package/dist/components/layout/Tree.context.cjs +1 -1
  76. package/dist/components/layout/Tree.context.cjs.map +1 -1
  77. package/dist/components/layout/Tree.context.mjs +2 -1
  78. package/dist/components/layout/Tree.context.mjs.map +1 -1
  79. package/dist/components/layout/Tree.core.cjs +1 -1
  80. package/dist/components/layout/Tree.core.cjs.map +1 -1
  81. package/dist/components/layout/Tree.core.mjs +162 -148
  82. package/dist/components/layout/Tree.core.mjs.map +1 -1
  83. package/dist/components/layout/Tree.mjs.map +1 -1
  84. package/dist/components/layout/Tree.selection.cjs +1 -1
  85. package/dist/components/layout/Tree.selection.cjs.map +1 -1
  86. package/dist/components/layout/Tree.selection.mjs +11 -57
  87. package/dist/components/layout/Tree.selection.mjs.map +1 -1
  88. package/dist/components/layout/useFlatTree.cjs +2 -0
  89. package/dist/components/layout/useFlatTree.cjs.map +1 -0
  90. package/dist/components/layout/useFlatTree.mjs +83 -0
  91. package/dist/components/layout/useFlatTree.mjs.map +1 -0
  92. package/dist/components/navigation/Menu.popover.cjs +1 -1
  93. package/dist/components/navigation/Menu.popover.cjs.map +1 -1
  94. package/dist/components/navigation/Menu.popover.mjs +154 -168
  95. package/dist/components/navigation/Menu.popover.mjs.map +1 -1
  96. package/dist/components/navigation/Nav.cjs +1 -1
  97. package/dist/components/navigation/Nav.cjs.map +1 -1
  98. package/dist/components/navigation/Nav.mjs +156 -136
  99. package/dist/components/navigation/Nav.mjs.map +1 -1
  100. package/dist/components/navigation/NavDrawer.cjs +1 -1
  101. package/dist/components/navigation/NavDrawer.cjs.map +1 -1
  102. package/dist/components/navigation/NavDrawer.mjs +48 -45
  103. package/dist/components/navigation/NavDrawer.mjs.map +1 -1
  104. package/dist/components/overlays/Dialog.cjs +1 -1
  105. package/dist/components/overlays/Dialog.cjs.map +1 -1
  106. package/dist/components/overlays/Dialog.mjs +128 -122
  107. package/dist/components/overlays/Dialog.mjs.map +1 -1
  108. package/dist/components/overlays/Dialog.slots.cjs +1 -1
  109. package/dist/components/overlays/Dialog.slots.cjs.map +1 -1
  110. package/dist/components/overlays/Dialog.slots.mjs +12 -12
  111. package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
  112. package/dist/components/overlays/Drawer.cjs.map +1 -1
  113. package/dist/components/overlays/Drawer.mjs.map +1 -1
  114. package/dist/components/overlays/Drawer.panel.cjs +1 -1
  115. package/dist/components/overlays/Drawer.panel.cjs.map +1 -1
  116. package/dist/components/overlays/Drawer.panel.mjs +97 -81
  117. package/dist/components/overlays/Drawer.panel.mjs.map +1 -1
  118. package/dist/components/overlays/Drawer.root.cjs +1 -1
  119. package/dist/components/overlays/Drawer.root.cjs.map +1 -1
  120. package/dist/components/overlays/Drawer.root.mjs +34 -31
  121. package/dist/components/overlays/Drawer.root.mjs.map +1 -1
  122. package/dist/components/overlays/Popover.cjs +1 -1
  123. package/dist/components/overlays/Popover.cjs.map +1 -1
  124. package/dist/components/overlays/Popover.mjs +231 -216
  125. package/dist/components/overlays/Popover.mjs.map +1 -1
  126. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  127. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  128. package/dist/components/overlays/TeachingPopover.parts.cjs +1 -1
  129. package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -1
  130. package/dist/components/overlays/TeachingPopover.parts.mjs +199 -177
  131. package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -1
  132. package/dist/components/overlays/TeachingPopover.root.cjs +1 -1
  133. package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -1
  134. package/dist/components/overlays/TeachingPopover.root.mjs +93 -92
  135. package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -1
  136. package/dist/components/overlays/Tooltip.cjs +1 -1
  137. package/dist/components/overlays/Tooltip.cjs.map +1 -1
  138. package/dist/components/overlays/Tooltip.mjs +66 -61
  139. package/dist/components/overlays/Tooltip.mjs.map +1 -1
  140. package/dist/components/provider/WaveProvider.cjs +1 -1
  141. package/dist/components/provider/WaveProvider.cjs.map +1 -1
  142. package/dist/components/provider/WaveProvider.mjs +26 -23
  143. package/dist/components/provider/WaveProvider.mjs.map +1 -1
  144. package/dist/components/table/DataGrid.cjs +1 -1
  145. package/dist/components/table/DataGrid.cjs.map +1 -1
  146. package/dist/components/table/DataGrid.context.cjs +2 -0
  147. package/dist/components/table/DataGrid.context.cjs.map +1 -0
  148. package/dist/components/table/DataGrid.context.mjs +74 -0
  149. package/dist/components/table/DataGrid.context.mjs.map +1 -0
  150. package/dist/components/table/DataGrid.header.cjs +2 -0
  151. package/dist/components/table/DataGrid.header.cjs.map +1 -0
  152. package/dist/components/table/DataGrid.header.mjs +168 -0
  153. package/dist/components/table/DataGrid.header.mjs.map +1 -0
  154. package/dist/components/table/DataGrid.mjs +488 -591
  155. package/dist/components/table/DataGrid.mjs.map +1 -1
  156. package/dist/components/table/DataGrid.sizing.cjs +2 -0
  157. package/dist/components/table/DataGrid.sizing.cjs.map +1 -0
  158. package/dist/components/table/DataGrid.sizing.mjs +187 -0
  159. package/dist/components/table/DataGrid.sizing.mjs.map +1 -0
  160. package/dist/components/table/DataGrid.store.cjs +2 -0
  161. package/dist/components/table/DataGrid.store.cjs.map +1 -0
  162. package/dist/components/table/DataGrid.store.mjs +108 -0
  163. package/dist/components/table/DataGrid.store.mjs.map +1 -0
  164. package/dist/components/table/DataGrid.window.cjs +2 -0
  165. package/dist/components/table/DataGrid.window.cjs.map +1 -0
  166. package/dist/components/table/DataGrid.window.mjs +165 -0
  167. package/dist/components/table/DataGrid.window.mjs.map +1 -0
  168. package/dist/components/table/Table.cjs +1 -1
  169. package/dist/components/table/Table.cjs.map +1 -1
  170. package/dist/components/table/Table.mjs +74 -72
  171. package/dist/components/table/Table.mjs.map +1 -1
  172. package/dist/components/table/Table.resize.cjs +2 -0
  173. package/dist/components/table/Table.resize.cjs.map +1 -0
  174. package/dist/components/table/Table.resize.mjs +98 -0
  175. package/dist/components/table/Table.resize.mjs.map +1 -0
  176. package/dist/components/table/useGridNavigation.cjs +1 -1
  177. package/dist/components/table/useGridNavigation.cjs.map +1 -1
  178. package/dist/components/table/useGridNavigation.mjs +343 -140
  179. package/dist/components/table/useGridNavigation.mjs.map +1 -1
  180. package/dist/components/table/useTableColumnSizing.cjs +2 -0
  181. package/dist/components/table/useTableColumnSizing.cjs.map +1 -0
  182. package/dist/components/table/useTableColumnSizing.mjs +76 -0
  183. package/dist/components/table/useTableColumnSizing.mjs.map +1 -0
  184. package/dist/components/table/useTableFeatures.cjs +2 -0
  185. package/dist/components/table/useTableFeatures.cjs.map +1 -0
  186. package/dist/components/table/useTableFeatures.mjs +110 -0
  187. package/dist/components/table/useTableFeatures.mjs.map +1 -0
  188. package/dist/components/table/useTableSelection.cjs +2 -0
  189. package/dist/components/table/useTableSelection.cjs.map +1 -0
  190. package/dist/components/table/useTableSelection.mjs +39 -0
  191. package/dist/components/table/useTableSelection.mjs.map +1 -0
  192. package/dist/components/table/useTableSort.cjs +2 -0
  193. package/dist/components/table/useTableSort.cjs.map +1 -0
  194. package/dist/components/table/useTableSort.mjs +58 -0
  195. package/dist/components/table/useTableSort.mjs.map +1 -0
  196. package/dist/hooks/useActiveDescendant.cjs +1 -1
  197. package/dist/hooks/useActiveDescendant.cjs.map +1 -1
  198. package/dist/hooks/useActiveDescendant.mjs +33 -25
  199. package/dist/hooks/useActiveDescendant.mjs.map +1 -1
  200. package/dist/hooks/useCollapsePresence.cjs +2 -0
  201. package/dist/hooks/useCollapsePresence.cjs.map +1 -0
  202. package/dist/hooks/useCollapsePresence.mjs +21 -0
  203. package/dist/hooks/useCollapsePresence.mjs.map +1 -0
  204. package/dist/hooks/useFocusBeforeClose.cjs +2 -0
  205. package/dist/hooks/useFocusBeforeClose.cjs.map +1 -0
  206. package/dist/hooks/useFocusBeforeClose.mjs +33 -0
  207. package/dist/hooks/useFocusBeforeClose.mjs.map +1 -0
  208. package/dist/hooks/useListbox.cjs +1 -1
  209. package/dist/hooks/useListbox.cjs.map +1 -1
  210. package/dist/hooks/useListbox.mjs +140 -130
  211. package/dist/hooks/useListbox.mjs.map +1 -1
  212. package/dist/hooks/useMotion.cjs +2 -0
  213. package/dist/hooks/useMotion.cjs.map +1 -0
  214. package/dist/hooks/useMotion.mjs +14 -0
  215. package/dist/hooks/useMotion.mjs.map +1 -0
  216. package/dist/hooks/usePresenceGroup.cjs +2 -0
  217. package/dist/hooks/usePresenceGroup.cjs.map +1 -0
  218. package/dist/hooks/usePresenceGroup.mjs +68 -0
  219. package/dist/hooks/usePresenceGroup.mjs.map +1 -0
  220. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  221. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  222. package/dist/hooks/useRovingTabIndex.mjs +1 -1
  223. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  224. package/dist/hooks/useSelection.cjs +2 -0
  225. package/dist/hooks/useSelection.cjs.map +1 -0
  226. package/dist/hooks/useSelection.mjs +57 -0
  227. package/dist/hooks/useSelection.mjs.map +1 -0
  228. package/dist/hooks/useVirtualWindow.cjs +2 -0
  229. package/dist/hooks/useVirtualWindow.cjs.map +1 -0
  230. package/dist/hooks/useVirtualWindow.mjs +102 -0
  231. package/dist/hooks/useVirtualWindow.mjs.map +1 -0
  232. package/dist/index.cjs +1 -1
  233. package/dist/index.d.cts +2249 -179
  234. package/dist/index.d.ts +2249 -179
  235. package/dist/index.mjs +147 -135
  236. package/dist/lib/classNames.cjs +1 -1
  237. package/dist/lib/classNames.cjs.map +1 -1
  238. package/dist/lib/classNames.mjs +125 -95
  239. package/dist/lib/classNames.mjs.map +1 -1
  240. package/dist/lib/columnSizing.cjs +2 -0
  241. package/dist/lib/columnSizing.cjs.map +1 -0
  242. package/dist/lib/columnSizing.mjs +27 -0
  243. package/dist/lib/columnSizing.mjs.map +1 -0
  244. package/dist/lib/flatTree.cjs +2 -0
  245. package/dist/lib/flatTree.cjs.map +1 -0
  246. package/dist/lib/flatTree.mjs +118 -0
  247. package/dist/lib/flatTree.mjs.map +1 -0
  248. package/dist/lib/motion.cjs +2 -0
  249. package/dist/lib/motion.cjs.map +1 -0
  250. package/dist/lib/motion.mjs +43 -0
  251. package/dist/lib/motion.mjs.map +1 -0
  252. package/dist/lib/selection.cjs +2 -0
  253. package/dist/lib/selection.cjs.map +1 -0
  254. package/dist/lib/selection.mjs +28 -0
  255. package/dist/lib/selection.mjs.map +1 -0
  256. package/dist/lib/treeCascade.cjs +2 -0
  257. package/dist/lib/treeCascade.cjs.map +1 -0
  258. package/dist/lib/treeCascade.mjs +52 -0
  259. package/dist/lib/treeCascade.mjs.map +1 -0
  260. package/dist/lib/virtual.cjs +2 -0
  261. package/dist/lib/virtual.cjs.map +1 -0
  262. package/dist/lib/virtual.mjs +54 -0
  263. package/dist/lib/virtual.mjs.map +1 -0
  264. package/dist/styles.css +1 -1
  265. 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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"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/dev.cjs"),r=require("../../lib/composeEventHandlers.cjs"),i=require("../../lib/classNames.cjs"),a=require("../../hooks/useEventCallback.cjs"),o=require("../../lib/direction.cjs"),s=require("../../hooks/useTypeahead.cjs"),c=require("../../hooks/useMergedRefs.cjs"),l=require("../../lib/events.cjs"),u=require("./FlatTree.context.cjs"),d=require("./FlatTree.item.cjs");let f=require("react");f=e.__toESM(f,1);let p=require("react/jsx-runtime");var m={focused:null,pending:null},ee=class{state=m;listeners=new Set;subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)});getSnapshot=()=>this.state;getServerSnapshot=()=>m;update(e){let t={...this.state,...e};if(t.focused!==this.state.focused||t.pending!==this.state.pending){this.state=t;for(let e of this.listeners)e()}}};function h({size:e}){return(0,p.jsx)(`div`,{role:`none`,"aria-hidden":`true`,"data-virtual-spacer":``,className:i.flatTreeClassNames.spacer,style:{height:e}})}h.displayName=`FlatTreeSpacer`;function g(e,t){let n=t instanceof Element?t:null;for(;n&&n.parentElement!==e;)n=n.parentElement;return n instanceof HTMLElement&&n.getAttribute(`role`)===`treeitem`?n:null}function _(e){let t=e.getAttribute(`data-index`);return t!==null&&/^\d+$/.test(t)?Number(t):null}function v(e,t){return e.querySelector(`:scope > [data-index="${t}"]`)}function y(e,t,n){for(let r=t+n;r>=0&&r<e.length;r+=n)if(!e[r].item.disabled)return r}function te(e,t){let{level:n}=e[t];for(let r=t+1;r<e.length&&e[r].level>n;r+=1)if(e[r].level===n+1&&!e[r].item.disabled)return r}var ne="FlatTree: a tree needs an accessible name. Pass `aria-label` or `aria-labelledby`.",re="FlatTree: selectionMode=\"multiple\" needs a model that holds the check states: pass `selectionMode: 'multiple'` to `useFlatTree` as well; until then every item shows unchecked.",ie='FlatTree: `selected` has no effect with selectionMode="multiple"; use the model\'s `checkedItems`, and `current` for the item the user is on.',ae='FlatTree: selectionMode="single" draws a radio on every item for `selected`; pass `selected` (null while nothing is selected) and update it from `onItemSelect`.',b=({model:e,virtualWindow:m,renderItem:b,selectionMode:x,selected:S,current:C,onItemSelect:oe,className:se,onKeyDown:ce,onFocus:le,onBlur:ue,onPointerDownCapture:w,ref:de,...T})=>{let E=e.getTreeProps().selectionMode,D=x??E,O=e.visibleItems,k=O.length,A=m!==void 0,j=D===`multiple`?void 0:D===`single`?S??null:S,[M]=f.useState(()=>new ee),{focused:N,pending:P}=f.useSyncExternalStore(M.subscribe,M.getSnapshot,M.getServerSnapshot),fe=f.useMemo(()=>O.find(e=>!e.item.disabled),[O]),pe=N===null?void 0:e.getItem(N),F=j==null?void 0:e.getItem(j),I=pe??(F&&!F.item.disabled?F:fe),L=I?.index,R=P===null?void 0:e.getItem(P)?.index,z=f.useMemo(()=>[L,R].filter(e=>e!==void 0),[L,R]),B=a.useEventCallback(t=>{t.item.disabled||(t.isBranch&&e.toggle(t.item.value),oe?.(t.item.value))}),V=a.useEventCallback((t,n)=>{t.item.disabled||e.setChecked(t.item.value,t.checked!==`checked`,n)}),H=m?.itemSize,U=I?.item.value??null,me=f.useMemo(()=>({selectionMode:D,selected:j,current:C,tabStop:U,itemSize:H,activate:B,toggleChecked:V}),[D,j,C,U,H,B,V]),W=f.useRef(null),he=c.useMergedRefs(de,W,m?.scrollRef),G=(e,t)=>{let n=O[t];if(!n)return;m?.scrollToIndex(t,{align:`auto`});let r=v(e,t);r?(M.update({pending:null}),r.focus()):M.update({pending:n.item.value})},{onTypeahead:ge,isSearching:_e}=s.useTypeahead({getItems:()=>O.map(e=>({value:e.item.value,text:e.item.label??e.item.value,disabled:e.item.disabled})),onMatch:t=>{let n=W.current,r=e.getItem(t);n&&r&&G(n,r.index)}}),K=f.useRef(null),q=f.useRef(!1),ve=a.useEventCallback(e=>{A&&l.isOwnEvent(e)&&(q.current=!0)});f.useEffect(()=>{let e=W.current?.ownerDocument;if(!A||!e)return;let t=()=>{q.current=!1};return e.addEventListener(`keydown`,t,!0),()=>e.removeEventListener(`keydown`,t,!0)},[A]);let J=f.useRef(!1),ye=a.useEventCallback(t=>{let n=q.current;q.current=!1,J.current=!t.currentTarget.contains(t.target);let r=g(t.currentTarget,t.target),i=r?_(r):null,a=i===null?void 0:O[i];if(!a||i===null)return;M.update({focused:a.item.value,pending:null});let o=[];for(let t=a.parentValue;t!==void 0;)o.push(t),t=e.getItem(t)?.parentValue;K.current={path:o,index:i},m&&!n&&m.scrollToIndex(i,{align:`auto`})}),Y=a.useEventCallback(e=>{let t=e.currentTarget,n=e.relatedTarget;if(n&&t.contains(n))return;J.current=!1;let r=e.target;queueMicrotask(()=>{if(!t.isConnected||J.current)return;let e=t.ownerDocument.activeElement;e&&t.contains(e)||r.isConnected&&M.update({focused:null})})}),be=a.useEventCallback(t=>{let n=t.currentTarget,r=g(n,t.target),i=r?_(r):null;if(i===null||i>=k||l.isEditableTarget(t.target))return;let a=O[i],s=M.getSnapshot().pending,c=(s===null?void 0:e.getItem(s)?.index)??i;if(t.key.length===1&&(t.key!==`*`||_e())&&ge(t,O[c].item.value)){t.preventDefault();return}if(t.altKey||t.ctrlKey||t.metaKey)return;let u;switch(t.key){case`ArrowDown`:u=y(O,c,1);break;case`ArrowUp`:u=y(O,c,-1);break;case`Home`:u=y(O,-1,1);break;case`End`:u=y(O,k,-1);break;case`Enter`:t.preventDefault(),B(a);return;case` `:t.preventDefault(),D===`multiple`?V(a,t.nativeEvent):B(a);return;case`*`:{t.preventDefault();let n=O.filter(e=>e.parentValue===a.parentValue&&e.isBranch&&!e.expanded&&!e.item.disabled).map(e=>e.item.value);n.length>0&&e.expand(n);return}default:{let r=o.getArrowIntent(t.key,{orientation:`horizontal`,dir:o.getDirection(n)});if(r===null)return;if(r===`next`){if(a.isBranch&&!a.expanded){t.preventDefault(),a.item.disabled||e.expand(a.item.value);return}a.expanded&&(u=te(O,i))}else{if(a.isBranch&&a.expanded&&!a.item.disabled){t.preventDefault(),e.collapse(a.item.value);return}for(let t=a.parentValue;t!==void 0&&u===void 0;){let n=e.getItem(t);if(!n)break;n.item.disabled||(u=n.index),t=n.parentValue}}if(u===void 0){t.preventDefault();return}}}t.preventDefault();let d=u??c;if(d===i){M.update({pending:null}),m?.scrollToIndex(d,{align:`auto`});return}G(n,d)}),X=f.useRef(null);f.useLayoutEffect(()=>{let t=W.current,n=M.getSnapshot().focused,r=n===null?void 0:e.getItem(n)?.index,i=X.current;if(X.current=null,!m||!t||n===null||r===void 0)return;let a=m.itemSize,o=t.scrollTop;if(i?.value===n&&r!==i.index&&t.contains(t.ownerDocument.activeElement)){let e=Math.floor(o/a)===Math.floor(i.top/a)?o:i.top,n=i.index*a;n+a>e&&n<e+t.clientHeight&&(t.scrollTop=e+(r-i.index)*a,m.scrollToIndex(r,{align:`auto`}),o=t.scrollTop)}X.current={value:n,index:r,top:o}}),f.useLayoutEffect(()=>{let t=W.current;if(!t)return;let n=t.ownerDocument,r=n.activeElement,i=!r||r===n.body||!r.isConnected,a=M.getSnapshot();if(a.pending!==null){M.update({pending:null});let n=e.getItem(a.pending),o=n?v(t,n.index):null;o&&(i||t.contains(r))&&o.focus();return}if(a.focused===null||e.getItem(a.focused)||(M.update({focused:null}),!i||k===0))return;let o=K.current,s=o?.path.map(t=>e.getItem(t)).find(e=>e)?.index;s??=Math.min(o?.index??0,k-1),G(t,s)});let Z=!T[`aria-label`]&&!T[`aria-labelledby`];f.useEffect(()=>{Z&&n.warnOnce(`FlatTree:name`,ne)},[Z]);let Q=D===`multiple`&&E!==`multiple`;f.useEffect(()=>{Q&&n.warnOnce(`FlatTree:selection-mode`,re)},[Q]),f.useEffect(()=>{D===`multiple`&&S!==void 0&&n.warnOnce(`FlatTree:selected-with-multiple`,ie),D===`single`&&S===void 0&&n.warnOnce(`FlatTree:single-without-selected`,ae)},[D,S]);let $=e=>(0,p.jsx)(d.FlatTreeItem,{item:e,children:b?b(e):e.item.label??e.item.value},`item:${e.item.value}`),xe=m?m.layout(k,{keep:z}).map(e=>e.kind===`item`?$(O[e.index]):(0,p.jsx)(h,{size:e.size},`spacer:${e.key}`)):O.map($);return(0,p.jsx)(u.FlatTreeContext.Provider,{value:me,children:(0,p.jsx)(`div`,{role:`tree`,"aria-multiselectable":D===`multiple`||void 0,"data-selection-mode":D,tabIndex:A&&U!==null?-1:void 0,className:t.cn(i.flatTreeClassNames.root,`text-body-1`,A&&`overflow-y-auto [overflow-anchor:none]`,se),...T,onKeyDown:r.composeEventHandlers(ce,be),onFocus:r.composeEventHandlers(le,ye,{checkDefaultPrevented:!1}),onBlur:r.composeEventHandlers(ue,Y,{checkDefaultPrevented:!1}),onPointerDownCapture:r.composeEventHandlers(w,ve),ref:he,children:xe})})};b.displayName=`FlatTree`;var x=Object.assign(b,{Item:d.FlatTreeItem});exports.FlatTree=x,exports.FlatTreeItem=d.FlatTreeItem;
2
+ //# sourceMappingURL=FlatTree.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlatTree.cjs","names":["flatTreeClassNames","React","useEventCallback","useMergedRefs","useTypeahead","isOwnEvent","isEditableTarget","getArrowIntent","getDirection","FlatTreeItem","FlatTreeContext","cn","composeEventHandlers","require_runtime","require_cn","require_dev","require_composeEventHandlers","require_classNames","require_useEventCallback","require_direction","require_useTypeahead","require_useMergedRefs","require_events","require_FlatTree_context","require_FlatTree_item","react","react_jsx_runtime","NO_FOCUS","FlatTreeFocusStore","listener","state","next","FlatTreeSpacer","size","getOwnItem","el","target","root","getIndex","value","getRenderedItem","index","nextEnabled","at","from","step","rows","firstEnabledChild","level","NAME_MESSAGE","SELECTION_MODE_MESSAGE","SELECTED_WITH_MULTIPLE_MESSAGE","SINGLE_WITHOUT_SELECTED_MESSAGE","FlatTreeRoot","selectionModeProp","rest","modelMode","model","selectionMode","count","windowed","virtualWindow","effectiveSelected","selected","focusStore","firstEnabled","row","focusedRow","focused","selectedRow","tabStopRow","tabStopIndex","pendingIndex","pending","keep","activate","onItemSelect","toggleChecked","event","itemSize","tabStop","context","current","rootRef","mergedRef","ref","moveTo","focusPathRef","pointerPressRef","handlePointerDownCapture","doc","clear","focusInPopupRef","handleFocus","pointerFocus","path","parent","handleBlur","blurred","active","handleKeyDown","awaited","isSearching","onTypeahead","siblings","other","intent","parentRow","goal","focusPlaceRef","last","top","before","lastTop","lost","snapshot","record","unnamed","missingChecks","renderRow","renderItem","content","entry","className","onKeyDown","onFocus","onBlur","onPointerDownCapture","FlatTree"],"sources":["../../../src/components/layout/FlatTree.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flatTreeClassNames } from '../../lib/classNames';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport { isEditableTarget, isOwnEvent } from '../../lib/events';\nimport type { VisibleFlatItem } from '../../lib/flatTree';\nimport type { CheckState } from '../../lib/treeCascade';\nimport type { SelectionMode } from '../../lib/types';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useTypeahead } from '../../hooks/useTypeahead';\nimport type { VirtualWindow } from '../../hooks/useVirtualWindow';\nimport { FlatTreeContext, type FlatTreeContextValue, type FlatTreeRow } from './FlatTree.context';\nimport { FlatTreeItem } from './FlatTree.item';\nimport type { FlatTreeModel } from './useFlatTree';\n\nexport type { FlatTreeItemProps } from './FlatTree.item';\n\n/** Properties for the FlatTree component. */\nexport interface FlatTreeProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children' | 'onSelect'\n> {\n /** The tree's model, from `useFlatTree`: the visible rows, the expanded and the checked state. */\n model: FlatTreeModel;\n /**\n * Renders only the items in view (and a few beyond), from `useVirtualWindow({ itemSize })`. The\n * tree is then the scrolling element: give it a bounded height (a class or a style). Every item\n * is exactly `itemSize` pixels tall, so its content must fit in one row. Without it every visible\n * item is rendered.\n *\n * The tree element is then no tab stop of its own while an item is (`tabIndex` -1, as Firefox\n * would stop on a scroller; a `tabIndex` you pass wins), and the browser's scroll anchoring is\n * off on it (the window lays the items out): when rows are inserted or removed above the focused\n * item while it is in view (`*`, or a change of the model from code), the tree moves the view\n * with it, so it stays where it was.\n */\n virtualWindow?: VirtualWindow;\n /**\n * The content of an item, from its row: the item data with its level, position, set size,\n * expanded state and, in multiple mode, its check state. Called for the rendered items only.\n * @default the item's `label`, else its `value`\n */\n renderItem?: (item: VisibleFlatItem & { checked?: CheckState }) => React.ReactNode;\n /**\n * How items are selected, as the nested `Tree`'s `selectionMode`. `'multiple'` draws a checkbox\n * on every item, bound to the model's checked items (create the model with\n * `selectionMode: 'multiple'`); `'single'` draws a radio for `selected`. Spread\n * `model.getTreeProps()` on the tree to pass the model's mode.\n * @default the model's mode (`model.getTreeProps().selectionMode`)\n */\n selectionMode?: 'none' | SelectionMode;\n /**\n * Value of the selected item. When set (also to `null`), every item carries `aria-selected`, and\n * the selected item is where keyboard focus enters the tree while it is visible. It has no effect\n * with `selectionMode=\"multiple\"` (a development warning). With `selectionMode=\"single\"` every\n * item carries `aria-selected` even while it is not set (a development warning: the radios need\n * it).\n */\n selected?: string | null;\n /** Value of the current item (for example the open page): it gets `aria-current=\"true\"`. */\n current?: string | null;\n /**\n * Called with an item's value every time it is activated (a click on its row, Enter, or Space\n * unless the tree has checkboxes), also when the same item is activated again.\n */\n onItemSelect?: (value: string) => void;\n /** Ref to the `role=\"tree\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** The focused and the awaited item of a FlatTree, by value (see {@link FlatTreeFocusStore}). */\ninterface FlatTreeFocus {\n /** The item that has focus while focus is inside the tree: kept rendered, and the tab stop. */\n focused: string | null;\n /** The item a key moved to that was not rendered: kept rendered, focused after the commit. */\n pending: string | null;\n}\n\nconst NO_FOCUS: FlatTreeFocus = { focused: null, pending: null };\n\n/**\n * The focused and the awaited item of a FlatTree, read during render through\n * `useSyncExternalStore` and written by the tree's handlers and layout effect (C-HOOKS: no state\n * set in an effect, no ref read during render).\n */\nclass FlatTreeFocusStore {\n private state: FlatTreeFocus = NO_FOCUS;\n private readonly listeners = new Set<() => void>();\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): FlatTreeFocus => this.state;\n\n getServerSnapshot = (): FlatTreeFocus => NO_FOCUS;\n\n /** Changes the given fields; notifies only when one of them changed. */\n update(next: Partial<FlatTreeFocus>): void {\n const state = { ...this.state, ...next };\n if (state.focused === this.state.focused && state.pending === this.state.pending) return;\n this.state = state;\n for (const listener of this.listeners) listener();\n }\n}\n\n/** The element that stands in for the items of a windowed tree that are not rendered. */\nfunction FlatTreeSpacer({ size }: { size: number }) {\n return (\n <div\n role=\"none\"\n aria-hidden=\"true\"\n data-virtual-spacer=\"\"\n className={flatTreeClassNames.spacer}\n style={{ height: size }}\n />\n );\n}\nFlatTreeSpacer.displayName = 'FlatTreeSpacer';\n\n/** The item element (a treeitem child of `root`) that holds `target`; `null` for a portal's. */\nfunction getOwnItem(root: Element, target: EventTarget | null): HTMLElement | null {\n let el = target instanceof Element ? target : null;\n while (el && el.parentElement !== root) el = el.parentElement;\n return el instanceof HTMLElement && el.getAttribute('role') === 'treeitem' ? el : null;\n}\n\n/** The place of an item element in the visible rows (`data-index`). */\nfunction getIndex(el: Element): number | null {\n const value = el.getAttribute('data-index');\n return value !== null && /^\\d+$/.test(value) ? Number(value) : null;\n}\n\n/** The rendered item at `index` of the visible rows, or `null` while it is not rendered. */\nfunction getRenderedItem(root: Element, index: number): HTMLElement | null {\n return root.querySelector<HTMLElement>(`:scope > [data-index=\"${index}\"]`);\n}\n\n/** The next enabled row from `from` (exclusive) in the direction of `step`, or `undefined`. */\nfunction nextEnabled(rows: readonly FlatTreeRow[], from: number, step: 1 | -1): number | undefined {\n for (let at = from + step; at >= 0 && at < rows.length; at += step) {\n if (!rows[at].item.disabled) return at;\n }\n return undefined;\n}\n\n/** The first enabled child row of the expanded row at `index`, or `undefined`. */\nfunction firstEnabledChild(rows: readonly FlatTreeRow[], index: number): number | undefined {\n const { level } = rows[index];\n for (let at = index + 1; at < rows.length && rows[at].level > level; at += 1) {\n if (rows[at].level === level + 1 && !rows[at].item.disabled) return at;\n }\n return undefined;\n}\n\nconst NAME_MESSAGE =\n 'FlatTree: a tree needs an accessible name. Pass `aria-label` or `aria-labelledby`.';\n\nconst SELECTION_MODE_MESSAGE =\n 'FlatTree: selectionMode=\"multiple\" needs a model that holds the check states: pass ' +\n \"`selectionMode: 'multiple'` to `useFlatTree` as well; until then every item shows unchecked.\";\n\nconst SELECTED_WITH_MULTIPLE_MESSAGE =\n 'FlatTree: `selected` has no effect with selectionMode=\"multiple\"; use the model\\'s ' +\n '`checkedItems`, and `current` for the item the user is on.';\n\nconst SINGLE_WITHOUT_SELECTED_MESSAGE =\n 'FlatTree: selectionMode=\"single\" draws a radio on every item for `selected`; pass `selected` ' +\n '(null while nothing is selected) and update it from `onItemSelect`.';\n\n// The FlatTree root, documented on the exported `FlatTree` const.\nconst FlatTreeRoot = ({\n model,\n virtualWindow,\n renderItem,\n selectionMode: selectionModeProp,\n selected,\n current,\n onItemSelect,\n className,\n onKeyDown,\n onFocus,\n onBlur,\n onPointerDownCapture,\n ref,\n ...rest\n}: FlatTreeProps) => {\n const modelMode = model.getTreeProps().selectionMode;\n const selectionMode = selectionModeProp ?? modelMode;\n const rows = model.visibleItems;\n const count = rows.length;\n const windowed = virtualWindow !== undefined;\n\n // An item carries aria-checked or aria-selected, never both (APG); in single mode every item\n // carries aria-selected from the first render, so the radios and the state agree.\n const effectiveSelected =\n selectionMode === 'multiple'\n ? undefined\n : selectionMode === 'single'\n ? (selected ?? null)\n : selected;\n\n const [focusStore] = React.useState(() => new FlatTreeFocusStore());\n const { focused, pending } = React.useSyncExternalStore(\n focusStore.subscribe,\n focusStore.getSnapshot,\n focusStore.getServerSnapshot,\n );\n\n // The tab stop follows the model, not the DOM (most items are not rendered): the focused item,\n // else the selected item while it is visible and enabled, else the first enabled item.\n const firstEnabled = React.useMemo(() => rows.find((row) => !row.item.disabled), [rows]);\n const focusedRow = focused === null ? undefined : model.getItem(focused);\n const selectedRow =\n effectiveSelected === undefined || effectiveSelected === null\n ? undefined\n : model.getItem(effectiveSelected);\n const tabStopRow =\n focusedRow ?? (selectedRow && !selectedRow.item.disabled ? selectedRow : firstEnabled);\n const tabStopIndex = tabStopRow?.index;\n const pendingIndex = pending === null ? undefined : model.getItem(pending)?.index;\n // The tab stop and the awaited item stay rendered outside the window (a focused item scrolled\n // away keeps focus and its tab stop).\n const keep = React.useMemo(\n () => [tabStopIndex, pendingIndex].filter((index): index is number => index !== undefined),\n [tabStopIndex, pendingIndex],\n );\n\n const activate = useEventCallback((row: FlatTreeRow) => {\n if (row.item.disabled) return;\n if (row.isBranch) model.toggle(row.item.value);\n onItemSelect?.(row.item.value);\n });\n const toggleChecked = useEventCallback((row: FlatTreeRow, event: Event) => {\n if (row.item.disabled) return;\n model.setChecked(row.item.value, row.checked !== 'checked', event);\n });\n\n const itemSize = virtualWindow?.itemSize;\n const tabStop = tabStopRow?.item.value ?? null;\n const context = React.useMemo<FlatTreeContextValue>(\n () => ({\n selectionMode,\n selected: effectiveSelected,\n current,\n tabStop,\n itemSize,\n activate,\n toggleChecked,\n }),\n [selectionMode, effectiveSelected, current, tabStop, itemSize, activate, toggleChecked],\n );\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n // The tree is the window's scroller.\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, rootRef, virtualWindow?.scrollRef);\n\n /**\n * Focuses the row at `index`, moving the window to it first (in the same update, so no frame\n * shows the spacer); a row that is not rendered is awaited and focused after the commit that\n * renders it.\n */\n const moveTo = (root: HTMLElement, index: number) => {\n const row = rows[index];\n if (!row) return;\n virtualWindow?.scrollToIndex(index, { align: 'auto' });\n const el = getRenderedItem(root, index);\n if (el) {\n focusStore.update({ pending: null });\n el.focus();\n } else {\n focusStore.update({ pending: row.item.value });\n }\n };\n\n // Typeahead over the visible items' labels (disabled items are skipped).\n const { onTypeahead, isSearching } = useTypeahead({\n getItems: () =>\n rows.map((row) => ({\n value: row.item.value,\n text: row.item.label ?? row.item.value,\n disabled: row.item.disabled,\n })),\n onMatch: (value) => {\n const root = rootRef.current;\n const row = model.getItem(value);\n if (root && row) moveTo(root, row.index);\n },\n });\n\n /** The visible item, its ancestors from the parent up, and its place, of the focused item. */\n const focusPathRef = React.useRef<{ path: string[]; index: number } | null>(null);\n\n /**\n * Set by a pointer press in a windowed tree until the focus it gives, or until a key press:\n * keyboard focus always follows one, so a press that gave no focus never keeps a later keyboard\n * focus from being scrolled into view. A press in a popup an item opened is the popup's.\n */\n const pointerPressRef = React.useRef(false);\n const handlePointerDownCapture = useEventCallback((event: React.PointerEvent<HTMLDivElement>) => {\n if (windowed && isOwnEvent(event)) pointerPressRef.current = true;\n });\n React.useEffect(() => {\n const doc = rootRef.current?.ownerDocument;\n if (!windowed || !doc) return;\n const clear = () => {\n pointerPressRef.current = false;\n };\n doc.addEventListener('keydown', clear, true);\n return () => doc.removeEventListener('keydown', clear, true);\n }, [windowed]);\n\n /**\n * Whether focus is in a popup that an item opened (an element outside the tree's DOM whose focus\n * React bubbles through the tree): the focused item stays kept. Written by the focus and blur\n * handlers.\n */\n const focusInPopupRef = React.useRef(false);\n\n // Focus moving onto an item makes it the focused item (the tab stop, kept rendered). Unless a\n // pointer press gave the focus, the window moves to it in the same update (a browser's own focus\n // scrolling moves the view a frame before the window would follow).\n const handleFocus = useEventCallback((event: React.FocusEvent<HTMLDivElement>) => {\n const pointerFocus = pointerPressRef.current;\n pointerPressRef.current = false;\n focusInPopupRef.current = !event.currentTarget.contains(event.target as Node);\n const el = getOwnItem(event.currentTarget, event.target);\n const index = el ? getIndex(el) : null;\n const row = index === null ? undefined : rows[index];\n if (!row || index === null) return;\n focusStore.update({ focused: row.item.value, pending: null });\n const path: string[] = [];\n for (let parent = row.parentValue; parent !== undefined;) {\n path.push(parent);\n parent = model.getItem(parent)?.parentValue;\n }\n focusPathRef.current = { path, index };\n if (virtualWindow && !pointerFocus) virtualWindow.scrollToIndex(index, { align: 'auto' });\n });\n\n // Focus leaving the tree (for an element outside it, or for nothing) ends the focused item; the\n // tab stop then returns to the selected or the first item. Decided once focus has landed: a\n // popup an item opened takes focus in the same task (`focusInPopupRef`).\n const handleBlur = useEventCallback((event: React.FocusEvent<HTMLDivElement>) => {\n const root = event.currentTarget;\n const next = event.relatedTarget as Node | null;\n if (next && root.contains(next)) return;\n focusInPopupRef.current = false;\n const blurred = event.target as Node;\n queueMicrotask(() => {\n if (!root.isConnected || focusInPopupRef.current) return;\n const active = root.ownerDocument.activeElement;\n if (active && root.contains(active)) return;\n // A focused item that left the document (a branch collapsed around it): the commit's check\n // below has moved focus, or decided that it cannot.\n if (!blurred.isConnected) return;\n focusStore.update({ focused: null });\n });\n });\n\n const handleKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n const root = event.currentTarget;\n // A key from a portal is the portal's; a text field in the content keeps its keys.\n const el = getOwnItem(root, event.target);\n const current = el ? getIndex(el) : null;\n if (current === null || current >= count || isEditableTarget(event.target)) return;\n const row = rows[current];\n // Keys pressed before an awaited item renders move from it (possible only within one task).\n const awaited = focusStore.getSnapshot().pending;\n const from = (awaited === null ? undefined : model.getItem(awaited)?.index) ?? current;\n\n // Typeahead; a Space continues a search, and `*` starts none.\n if (event.key.length === 1 && (event.key !== '*' || isSearching())) {\n if (onTypeahead(event, rows[from].item.value)) {\n event.preventDefault();\n return;\n }\n }\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n\n let target: number | undefined;\n switch (event.key) {\n case 'ArrowDown':\n target = nextEnabled(rows, from, 1);\n break;\n case 'ArrowUp':\n target = nextEnabled(rows, from, -1);\n break;\n case 'Home':\n target = nextEnabled(rows, -1, 1);\n break;\n case 'End':\n target = nextEnabled(rows, count, -1);\n break;\n case 'Enter':\n event.preventDefault();\n activate(row);\n return;\n case ' ':\n event.preventDefault();\n // A checkbox tree toggles the focused item's check (APG); the other modes activate.\n if (selectionMode === 'multiple') toggleChecked(row, event.nativeEvent);\n else activate(row);\n return;\n case '*': {\n event.preventDefault();\n // The siblings of a visible item are all visible (their parent is expanded).\n const siblings = rows\n .filter(\n (other) =>\n other.parentValue === row.parentValue &&\n other.isBranch &&\n !other.expanded &&\n !other.item.disabled,\n )\n .map((other) => other.item.value);\n if (siblings.length > 0) model.expand(siblings);\n return;\n }\n default: {\n const intent = getArrowIntent(event.key, {\n orientation: 'horizontal',\n dir: getDirection(root),\n });\n if (intent === null) return;\n if (intent === 'next') {\n // Expand a collapsed branch (focus stays), else move to the first child.\n if (row.isBranch && !row.expanded) {\n event.preventDefault();\n if (!row.item.disabled) model.expand(row.item.value);\n return;\n }\n if (row.expanded) target = firstEnabledChild(rows, current);\n } else {\n // Collapse an expanded branch (focus stays), else move to the nearest enabled ancestor.\n if (row.isBranch && row.expanded && !row.item.disabled) {\n event.preventDefault();\n model.collapse(row.item.value);\n return;\n }\n for (let parent = row.parentValue; parent !== undefined && target === undefined;) {\n const parentRow = model.getItem(parent);\n if (!parentRow) break;\n if (!parentRow.item.disabled) target = parentRow.index;\n parent = parentRow.parentValue;\n }\n }\n if (target === undefined) {\n event.preventDefault();\n return;\n }\n }\n }\n event.preventDefault();\n // No item to move to: the focused item stays, and is brought into view.\n const goal = target ?? from;\n if (goal === current) {\n focusStore.update({ pending: null });\n virtualWindow?.scrollToIndex(goal, { align: 'auto' });\n return;\n }\n moveTo(root, goal);\n });\n\n /**\n * The focused item of a windowed tree, its place in the visible rows and the scroll offset, at\n * the last commit (written by the layout effect below).\n */\n const focusPlaceRef = React.useRef<{ value: string; index: number; top: number } | null>(null);\n\n // After every commit of a windowed tree: rows inserted or removed above the focused item while\n // it was in view (`*`, a model change from code) move the view with it, so it stays where it\n // was, and the window follows in the same update. The browser's scroll anchoring would do the\n // same a frame before the window follows; it is off (the window lays the rows out).\n React.useLayoutEffect(() => {\n const root = rootRef.current;\n const value = focusStore.getSnapshot().focused;\n const index = value === null ? undefined : model.getItem(value)?.index;\n const last = focusPlaceRef.current;\n focusPlaceRef.current = null;\n if (!virtualWindow || !root || value === null || index === undefined) return;\n const size = virtualWindow.itemSize;\n let top = root.scrollTop;\n if (\n last?.value === value &&\n index !== last.index &&\n root.contains(root.ownerDocument.activeElement)\n ) {\n // Rows removed above may leave less content than the offset, which the browser has clamped\n // by now: an offset in another row than the one recorded (the tree commits at every row the\n // view enters) stands for that, and the recorded one is where the view was.\n const before = Math.floor(top / size) === Math.floor(last.top / size) ? top : last.top;\n const lastTop = last.index * size;\n if (lastTop + size > before && lastTop < before + root.clientHeight) {\n root.scrollTop = before + (index - last.index) * size;\n virtualWindow.scrollToIndex(index, { align: 'auto' });\n top = root.scrollTop;\n }\n }\n focusPlaceRef.current = { value, index, top };\n });\n\n // After every commit: focus the awaited item, which the commit rendered (it is kept), unless\n // focus went outside the tree meanwhile; and when the focused item is no longer visible (a\n // branch collapsed around it, or the items changed) while focus is lost with it, move focus to\n // its nearest visible ancestor, else to the visible item nearest to its place. Never to the body.\n React.useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root) return;\n const doc = root.ownerDocument;\n const active = doc.activeElement;\n const lost = !active || active === doc.body || !active.isConnected;\n const snapshot = focusStore.getSnapshot();\n if (snapshot.pending !== null) {\n focusStore.update({ pending: null });\n const row = model.getItem(snapshot.pending);\n const el = row ? getRenderedItem(root, row.index) : null;\n if (el && (lost || root.contains(active))) el.focus();\n return;\n }\n if (snapshot.focused === null || model.getItem(snapshot.focused)) return;\n focusStore.update({ focused: null });\n if (!lost || count === 0) return;\n const record = focusPathRef.current;\n let target = record?.path.map((value) => model.getItem(value)).find((row) => row)?.index;\n target ??= Math.min(record?.index ?? 0, count - 1);\n moveTo(root, target);\n });\n\n // Development diagnostics (C-DEV): emitted from effects, once per page.\n const unnamed = !rest['aria-label'] && !rest['aria-labelledby'];\n React.useEffect(() => {\n if (unnamed) warnOnce('FlatTree:name', NAME_MESSAGE);\n }, [unnamed]);\n const missingChecks = selectionMode === 'multiple' && modelMode !== 'multiple';\n React.useEffect(() => {\n if (missingChecks) warnOnce('FlatTree:selection-mode', SELECTION_MODE_MESSAGE);\n }, [missingChecks]);\n React.useEffect(() => {\n if (selectionMode === 'multiple' && selected !== undefined) {\n warnOnce('FlatTree:selected-with-multiple', SELECTED_WITH_MULTIPLE_MESSAGE);\n }\n if (selectionMode === 'single' && selected === undefined) {\n warnOnce('FlatTree:single-without-selected', SINGLE_WITHOUT_SELECTED_MESSAGE);\n }\n }, [selectionMode, selected]);\n\n const renderRow = (row: FlatTreeRow) => (\n <FlatTreeItem key={`item:${row.item.value}`} item={row}>\n {renderItem ? renderItem(row) : (row.item.label ?? row.item.value)}\n </FlatTreeItem>\n );\n const content = virtualWindow\n ? virtualWindow\n .layout(count, { keep })\n .map((entry) =>\n entry.kind === 'item' ? (\n renderRow(rows[entry.index])\n ) : (\n <FlatTreeSpacer key={`spacer:${entry.key}`} size={entry.size} />\n ),\n )\n : rows.map(renderRow);\n\n return (\n <FlatTreeContext.Provider value={context}>\n <div\n role=\"tree\"\n aria-multiselectable={selectionMode === 'multiple' ? true : undefined}\n data-selection-mode={selectionMode}\n // A windowed tree's tab stop is an item: the scroller is none of its own (Firefox makes a\n // scroller a tab stop). The consumer's `tabIndex` wins.\n tabIndex={windowed && tabStop !== null ? -1 : undefined}\n className={cn(\n flatTreeClassNames.root,\n 'text-body-1',\n // The window lays the rows out: the browser's scroll anchoring only fights it.\n windowed && 'overflow-y-auto [overflow-anchor:none]',\n className,\n )}\n {...rest}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n onFocus={composeEventHandlers(onFocus, handleFocus, { checkDefaultPrevented: false })}\n onBlur={composeEventHandlers(onBlur, handleBlur, { checkDefaultPrevented: false })}\n onPointerDownCapture={composeEventHandlers(onPointerDownCapture, handlePointerDownCapture)}\n ref={mergedRef}\n >\n {content}\n </div>\n </FlatTreeContext.Provider>\n );\n};\nFlatTreeRoot.displayName = 'FlatTree';\n\n/**\n * A tree built from flat data (WAI-ARIA Tree View pattern) that can render only the items in\n * view, for trees of thousands of items. Its model comes from `useFlatTree(items, options)`: items\n * listed with a `parentValue`, in any order, the expanded and the checked state. The tree renders\n * the visible items (the roots and the children of every expanded branch) as sibling\n * `role=\"treeitem\"` elements with `aria-level`, `aria-setsize` and `aria-posinset` from the data,\n * `aria-expanded` on branches, and the nested `Tree`'s chevron, checkbox and radio.\n *\n * ```tsx\n * const model = useFlatTree(items, { defaultExpandedItems: ['docs'] });\n * const virtualWindow = useVirtualWindow({ itemSize: 28 });\n * <FlatTree aria-label=\"Files\" model={model} {...model.getTreeProps()} virtualWindow={virtualWindow} style={{ height: 400 }} />\n * ```\n *\n * Windowing: with `virtualWindow` the tree is the scrolling element (it needs a bounded height),\n * renders the items in view plus the window's overscan and spacers for the others, and every item\n * is exactly the window's `itemSize` tall. The server renders the first window. Keys move over the\n * whole visible list, scrolling an item that is not rendered into view before focusing it, and the\n * focused item stays rendered (and focused) while it is scrolled away.\n *\n * Keyboard: a single tab stop, on the focused item while focus is inside, else on the `selected`\n * item while it is visible, else on the first enabled item; Tab leaves the tree. Up/Down move\n * between the visible items, Home/End to the first and last, Right expands a collapsed branch or\n * moves to its first child, Left collapses an expanded branch or moves to the parent (both\n * mirrored in right-to-left layouts), Enter activates (and toggles a branch), and so does Space\n * unless the tree has checkboxes, `*` expands the sibling branches, and typing moves to the next\n * visible item whose label starts with the typed text (items under a collapsed branch are not\n * searched). The focused item stays the focused item (rendered, and the tab stop) while focus is\n * in a popup that its content opened, such as a menu in a portal, so the popup can return focus\n * to it.\n *\n * Selection, as the nested `Tree`: `selected` and `onItemSelect` (single selection and activation,\n * with radios in `selectionMode=\"single\"`), `current`, and with `selectionMode=\"multiple\"` a\n * checkbox on every item bound to the model's `checkedItems` (Space or a click on the checkbox\n * toggles it, and checks cascade). An item whose data is `disabled` is `aria-disabled`, is skipped\n * by the keys and typeahead, never holds the tab stop (except while a pointer press has focused\n * it), and is neither activated, expanded nor checked by the user (a check of its parent still\n * includes it).\n *\n * When a branch collapses around the focused item (from code), focus moves to that branch, so it\n * never falls to the page. Items expand and collapse at once, without motion: there is no child\n * group to animate. A selected item under a collapsed branch is not the tab stop until it is\n * visible again.\n *\n * `FlatTree.Item` is the row the tree renders for each visible item (it is not written by hand);\n * it is also exported as `FlatTreeItem` for React Server Components, which cannot use the dotted\n * form.\n */\nexport const FlatTree = /* @__PURE__ */ Object.assign(FlatTreeRoot, { Item: FlatTreeItem });\n\nexport { FlatTreeItem };\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/dev.cjs");let n=require("react");n=e.__toESM(n,1);var r=n.createContext(null),i={selectionMode:`none`,selected:void 0,current:void 0,tabStop:null,itemSize:void 0,activate:()=>{},toggleChecked:()=>{}};function a(e){return n.useContext(r)||(t.reportMissingContext(e,`<FlatTree>`),i)}exports.FlatTreeContext=r,exports.useFlatTreeContext=a;
2
+ //# sourceMappingURL=FlatTree.context.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlatTree.context.cjs","names":["React","require_runtime","require_dev","react","FlatTreeContext","INERT_CONTEXT","useFlatTreeContext","component"],"sources":["../../../src/components/layout/FlatTree.context.ts"],"sourcesContent":["import * as React from 'react';\nimport { reportMissingContext } from '../../lib/dev';\nimport type { VisibleFlatItem } from '../../lib/flatTree';\nimport type { CheckState } from '../../lib/treeCascade';\nimport type { SelectionMode } from '../../lib/types';\n\n/** One row of a FlatTree: a visible item of its model, with its check state in multiple mode. */\nexport type FlatTreeRow = VisibleFlatItem & { checked?: CheckState };\n\n/** What a FlatTree gives each of its items. */\nexport interface FlatTreeContextValue {\n /** The resolved selection mode. */\n selectionMode: 'none' | SelectionMode;\n /** The selected value; `undefined` while no item carries `aria-selected` (multiple mode). */\n selected: string | null | undefined;\n /** The value of the current item, which gets `aria-current`. */\n current: string | null | undefined;\n /** The value of the item that holds the tab stop; `null` while no item can take it. */\n tabStop: string | null;\n /** The height of every item of a windowed tree, in pixels; `undefined` without a window. */\n itemSize: number | undefined;\n /** Activates a row (a click, Enter): a branch expands or collapses, and `onItemSelect` runs. */\n activate: (row: FlatTreeRow) => void;\n /** Toggles a row's check (multiple mode); `event` becomes `details.event`. */\n toggleChecked: (row: FlatTreeRow, event: Event) => void;\n}\n\nexport const FlatTreeContext = React.createContext<FlatTreeContextValue | null>(null);\n\nconst INERT_CONTEXT: FlatTreeContextValue = {\n selectionMode: 'none',\n selected: undefined,\n current: undefined,\n tabStop: null,\n itemSize: undefined,\n activate: () => {},\n toggleChecked: () => {},\n};\n\n/** C-CONTEXT: throws in development, logs once and returns an inert value in production. */\nexport function useFlatTreeContext(component: string): FlatTreeContextValue {\n const context = React.useContext(FlatTreeContext);\n if (context) return context;\n reportMissingContext(component, '<FlatTree>');\n return INERT_CONTEXT;\n}\n"],"mappings":"4IA2BA,IAAaI,EAAkBJ,EAAM,cAA2C,IAAI,EAE9EK,EAAsC,CAC1C,cAAe,OACf,SAAU,IAAA,GACV,QAAS,IAAA,GACT,QAAS,KACT,SAAU,IAAA,GACV,aAAgB,CAAC,EACjB,kBAAqB,CAAC,CACxB,EAGA,SAAgBC,EAAmB,EAAyC,CAI1E,OAHgBN,EAAM,WAAWI,CAC7B,IACJF,EAAA,qBAAqBK,EAAW,YAAY,EACrCF,EACT"}
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { reportMissingContext as e } from "../../lib/dev.mjs";
3
+ import * as t from "react";
4
+ //#region src/components/layout/FlatTree.context.ts
5
+ var n = t.createContext(null), r = {
6
+ selectionMode: "none",
7
+ selected: void 0,
8
+ current: void 0,
9
+ tabStop: null,
10
+ itemSize: void 0,
11
+ activate: () => {},
12
+ toggleChecked: () => {}
13
+ };
14
+ function i(i) {
15
+ return t.useContext(n) || (e(i, "<FlatTree>"), r);
16
+ }
17
+ //#endregion
18
+ export { n as FlatTreeContext, i as useFlatTreeContext };
19
+
20
+ //# sourceMappingURL=FlatTree.context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlatTree.context.mjs","names":["React","FlatTreeContext","INERT_CONTEXT","useFlatTreeContext","reportMissingContext","component"],"sources":["../../../src/components/layout/FlatTree.context.ts"],"sourcesContent":["import * as React from 'react';\nimport { reportMissingContext } from '../../lib/dev';\nimport type { VisibleFlatItem } from '../../lib/flatTree';\nimport type { CheckState } from '../../lib/treeCascade';\nimport type { SelectionMode } from '../../lib/types';\n\n/** One row of a FlatTree: a visible item of its model, with its check state in multiple mode. */\nexport type FlatTreeRow = VisibleFlatItem & { checked?: CheckState };\n\n/** What a FlatTree gives each of its items. */\nexport interface FlatTreeContextValue {\n /** The resolved selection mode. */\n selectionMode: 'none' | SelectionMode;\n /** The selected value; `undefined` while no item carries `aria-selected` (multiple mode). */\n selected: string | null | undefined;\n /** The value of the current item, which gets `aria-current`. */\n current: string | null | undefined;\n /** The value of the item that holds the tab stop; `null` while no item can take it. */\n tabStop: string | null;\n /** The height of every item of a windowed tree, in pixels; `undefined` without a window. */\n itemSize: number | undefined;\n /** Activates a row (a click, Enter): a branch expands or collapses, and `onItemSelect` runs. */\n activate: (row: FlatTreeRow) => void;\n /** Toggles a row's check (multiple mode); `event` becomes `details.event`. */\n toggleChecked: (row: FlatTreeRow, event: Event) => void;\n}\n\nexport const FlatTreeContext = React.createContext<FlatTreeContextValue | null>(null);\n\nconst INERT_CONTEXT: FlatTreeContextValue = {\n selectionMode: 'none',\n selected: undefined,\n current: undefined,\n tabStop: null,\n itemSize: undefined,\n activate: () => {},\n toggleChecked: () => {},\n};\n\n/** C-CONTEXT: throws in development, logs once and returns an inert value in production. */\nexport function useFlatTreeContext(component: string): FlatTreeContextValue {\n const context = React.useContext(FlatTreeContext);\n if (context) return context;\n reportMissingContext(component, '<FlatTree>');\n return INERT_CONTEXT;\n}\n"],"mappings":";;;;AA2BA,IAAaC,IAAkBD,EAAM,cAA2C,IAAI,GAE9EE,IAAsC;CAC1C,eAAe;CACf,UAAU,KAAA;CACV,SAAS,KAAA;CACT,SAAS;CACT,UAAU,KAAA;CACV,gBAAgB,CAAC;CACjB,qBAAqB,CAAC;AACxB;AAGA,SAAgBC,EAAmB,GAAyC;CAI1E,OAHgBH,EAAM,WAAWC,CAC7B,MACJG,EAAqBC,GAAW,YAAY,GACrCH;AACT"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/classNames.cjs"),r=require("../../hooks/useId.cjs"),i=require("../../hooks/useMergedRefs.cjs"),a=require("../../lib/styles.cjs"),o=require("../../lib/icons.cjs"),s=require("../../lib/events.cjs"),c=require("./FlatTree.context.cjs");let l=require("react");l=e.__toESM(l,1);let u=require("react/jsx-runtime");function d(e){return e.target?.closest?.(`[data-flat-tree-checkbox]`)!=null}var f=({item:e,children:f,className:p,style:m,onClick:h,ref:g,..._})=>{let v=c.useFlatTreeContext(`FlatTree.Item`),{item:y,level:b,position:x,setSize:S,isBranch:C,expanded:w,index:T}=e,{value:E}=y,D=y.disabled===!0,O=r.useId(`flat-tree-item-label`),k=l.useRef(null),A=i.useMergedRefs(g,k),j=v.selectionMode===`multiple`?e.checked??`unchecked`:void 0,M=v.selected===void 0?void 0:v.selected===E,N=v.current!==void 0&&v.current!==null&&v.current===E,P=t=>{s.isOwnEvent(t)&&!d(t)&&(h?.(t),t.defaultPrevented||v.activate(e))},F=e=>{e.preventDefault(),k.current?.focus({preventScroll:!0})},I=t=>{v.toggleChecked(e,t.nativeEvent)},L=C?(0,u.jsx)(o.ChevronRightIcon,{className:t.cn(n.flatTreeItemClassNames.expandIcon,`shrink-0 transition-transform motion-reduce:transition-none`,w?`rotate-90`:`wave-rtl:-scale-x-100`)}):(0,u.jsx)(`span`,{className:`w-3 shrink-0`,"aria-hidden":`true`}),R=j===void 0?null:(0,u.jsx)(`span`,{role:`checkbox`,"aria-checked":j===`mixed`?`mixed`:j===`checked`,"aria-labelledby":O,"aria-disabled":D?!0:void 0,tabIndex:-1,"data-flat-tree-checkbox":``,onMouseDown:F,onClick:I,className:t.cn(n.flatTreeItemClassNames.indicator,`relative inline-flex size-4 shrink-0 items-center justify-center rounded-xs border transition-colors motion-reduce:transition-none`,`before:absolute before:-inset-1`,j===`unchecked`?t.cn(`border-stroke-accessible bg-transparent`,a.forcedColors.control):`border-primary bg-primary text-primary-foreground forced-colors:border-[Highlight] forced-colors:bg-[Highlight]`),children:j===`mixed`?(0,u.jsx)(o.SubtractIcon,{size:12,className:a.forcedColors.selectedLeaf}):j===`checked`?(0,u.jsx)(o.CheckIcon,{size:12,className:a.forcedColors.selectedLeaf}):null}),z=v.selectionMode===`single`?(0,u.jsx)(`span`,{"aria-hidden":`true`,className:t.cn(n.flatTreeItemClassNames.indicator,`inline-flex size-4 shrink-0 items-center justify-center rounded-full border transition-colors motion-reduce:transition-none`,M?`border-2 border-primary forced-colors:border-[Highlight]`:t.cn(`border-stroke-accessible`,a.forcedColors.control)),children:M&&(0,u.jsx)(`span`,{className:t.cn(`block size-2 rounded-full bg-primary`,a.forcedColors.selectedLeaf)})}):null,B={...m};return b>1&&(B.paddingInlineStart=`${b-1}rem`),v.itemSize!==void 0&&(B.height=v.itemSize),(0,u.jsx)(`div`,{role:`treeitem`,"aria-selected":M,"aria-current":N?!0:void 0,"aria-disabled":D?!0:void 0,"data-selected":M?``:void 0,"data-current":N?``:void 0,"data-checked":j===`checked`?``:void 0,"data-mixed":j===`mixed`?``:void 0,"data-disabled":D?``:void 0,className:t.cn(n.flatTreeItemClassNames.root,`box-border block outline-none`,`[&:focus-visible>[data-flat-tree-row]]:outline-2 [&:focus-visible>[data-flat-tree-row]]:-outline-offset-2 [&:focus-visible>[data-flat-tree-row]]:outline-ring`,a.disabledStyles,p),..._,"aria-labelledby":_[`aria-labelledby`]??(_[`aria-label`]===void 0?O:void 0),"aria-level":b,"aria-setsize":S,"aria-posinset":x,"aria-expanded":C?w:void 0,"aria-checked":j===void 0?void 0:j===`mixed`?`mixed`:j===`checked`,"data-index":T,tabIndex:v.tabStop===E?0:-1,style:B,onClick:P,ref:A,children:(0,u.jsxs)(`div`,{"data-flat-tree-row":``,className:t.cn(n.flatTreeItemClassNames.row,`box-border flex items-center gap-1.5 rounded px-2 py-1`,v.itemSize!==void 0&&`h-full`,D?`cursor-not-allowed`:`cursor-pointer hover:bg-subtle-hover`,M&&t.cn(`bg-subtle-selected font-semibold`,a.forcedColors.selectedContainer)),children:[L,R??z,(0,u.jsx)(`span`,{id:O,className:t.cn(n.flatTreeItemClassNames.label,`min-w-0 truncate`),children:f})]})})};f.displayName=`FlatTreeItem`,exports.FlatTreeItem=f;
2
+ //# sourceMappingURL=FlatTree.item.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlatTree.item.cjs","names":["useFlatTreeContext","useId","React","useMergedRefs","isOwnEvent","ChevronRightIcon","cn","flatTreeItemClassNames","forcedColors","SubtractIcon","CheckIcon","disabledStyles","require_runtime","require_cn","require_classNames","require_useId","require_useMergedRefs","require_styles","require_icons","require_events","require_FlatTree_context","react","react_jsx_runtime","isCheckboxClick","event","FlatTreeItem","row","rest","ctx","item","disabled","labelId","itemRef","mergedRef","ref","checkState","isSelected","value","isCurrent","handleClick","onClick","keepFocusOnItem","handleCheckboxClick","chevron","isBranch","expanded","checkbox","radio","itemStyle","style","level","className","setSize","position","index"],"sources":["../../../src/components/layout/FlatTree.item.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flatTreeItemClassNames } from '../../lib/classNames';\nimport { cn } from '../../lib/cn';\nimport { isOwnEvent } from '../../lib/events';\nimport type { VisibleFlatItem } from '../../lib/flatTree';\nimport { CheckIcon, ChevronRightIcon, SubtractIcon } from '../../lib/icons';\nimport { disabledStyles, forcedColors } from '../../lib/styles';\nimport type { CheckState } from '../../lib/treeCascade';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useFlatTreeContext } from './FlatTree.context';\n\n/** Properties for the FlatTreeItem sub-component. */\nexport interface FlatTreeItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** The row the item shows: a visible item of the tree's model (`model.visibleItems`). */\n item: VisibleFlatItem & { checked?: CheckState };\n /** The item's content: what the tree's `renderItem` returns, else the item's label. */\n children?: React.ReactNode;\n /** Ref to the `role=\"treeitem\"` element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Whether a click landed on the item's checkbox, which has a click of its own. */\nfunction isCheckboxClick(event: React.MouseEvent<HTMLElement>): boolean {\n const target = event.target as Element | null;\n return target?.closest?.('[data-flat-tree-checkbox]') != null;\n}\n\n/**\n * One row of a FlatTree, rendered by the tree for each visible item of its model (it is not\n * written by hand): a `role=\"treeitem\"` element with the item's level, set size and position,\n * `aria-expanded` on a branch, and the expand chevron, the checkbox (multiple mode) or the radio\n * (single mode) of the nested `Tree`'s items, before the content. Levels are drawn by indenting\n * the row, since the items are siblings. In a windowed tree it is exactly the window's `itemSize`\n * tall.\n *\n * `ref`, `className` and the other props land on the treeitem element; its `onClick` receives the\n * clicks on the row, not those on the checkbox, and runs before the built-in activation (call\n * `event.preventDefault()` to skip it).\n */\nexport const FlatTreeItem = ({\n item: row,\n children,\n className,\n style,\n onClick,\n ref,\n ...rest\n}: FlatTreeItemProps) => {\n const ctx = useFlatTreeContext('FlatTree.Item');\n const { item, level, position, setSize, isBranch, expanded, index } = row;\n const { value } = item;\n const disabled = item.disabled === true;\n const labelId = useId('flat-tree-item-label');\n const itemRef = React.useRef<HTMLDivElement>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, itemRef);\n\n const checkState: CheckState | undefined =\n ctx.selectionMode === 'multiple' ? (row.checked ?? 'unchecked') : undefined;\n const isSelected = ctx.selected !== undefined ? ctx.selected === value : undefined;\n const isCurrent = ctx.current !== undefined && ctx.current !== null && ctx.current === value;\n\n const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {\n // A click from a portal opened in the content, or on the checkbox, is not the row's.\n if (!isOwnEvent(event) || isCheckboxClick(event)) return;\n onClick?.(event);\n if (!event.defaultPrevented) ctx.activate(row);\n };\n\n // The checkbox never takes focus (APG: focus stays on tree items): a press on it focuses its\n // item instead, and its click toggles the check without activating the item.\n const keepFocusOnItem = (event: React.MouseEvent<HTMLSpanElement>) => {\n event.preventDefault();\n itemRef.current?.focus({ preventScroll: true });\n };\n const handleCheckboxClick = (event: React.MouseEvent<HTMLSpanElement>) => {\n ctx.toggleChecked(row, event.nativeEvent);\n };\n\n const chevron = isBranch ? (\n <ChevronRightIcon\n className={cn(\n flatTreeItemClassNames.expandIcon,\n 'shrink-0 transition-transform motion-reduce:transition-none',\n expanded ? 'rotate-90' : 'wave-rtl:-scale-x-100',\n )}\n />\n ) : (\n <span className=\"w-3 shrink-0\" aria-hidden=\"true\" />\n );\n\n const checkbox =\n checkState === undefined ? null : (\n <span\n role=\"checkbox\"\n aria-checked={checkState === 'mixed' ? 'mixed' : checkState === 'checked'}\n aria-labelledby={labelId}\n aria-disabled={disabled ? true : undefined}\n tabIndex={-1}\n data-flat-tree-checkbox=\"\"\n onMouseDown={keepFocusOnItem}\n onClick={handleCheckboxClick}\n className={cn(\n flatTreeItemClassNames.indicator,\n // Checkbox's box: 16px inside a 24px target (the pseudo-element), WCAG 2.5.8.\n 'relative inline-flex size-4 shrink-0 items-center justify-center rounded-xs border transition-colors motion-reduce:transition-none',\n 'before:absolute before:-inset-1',\n checkState === 'unchecked'\n ? cn('border-stroke-accessible bg-transparent', forcedColors.control)\n : 'border-primary bg-primary text-primary-foreground forced-colors:border-[Highlight] forced-colors:bg-[Highlight]',\n )}\n >\n {checkState === 'mixed' ? (\n <SubtractIcon size={12} className={forcedColors.selectedLeaf} />\n ) : checkState === 'checked' ? (\n <CheckIcon size={12} className={forcedColors.selectedLeaf} />\n ) : null}\n </span>\n );\n\n // Single mode: a decorative radio (the treeitem's aria-selected carries the state). A click on\n // it is a click on the row, so it activates the item.\n const radio =\n ctx.selectionMode === 'single' ? (\n <span\n aria-hidden=\"true\"\n className={cn(\n flatTreeItemClassNames.indicator,\n 'inline-flex size-4 shrink-0 items-center justify-center rounded-full border transition-colors motion-reduce:transition-none',\n isSelected\n ? 'border-2 border-primary forced-colors:border-[Highlight]'\n : cn('border-stroke-accessible', forcedColors.control),\n )}\n >\n {isSelected && (\n <span className={cn('block size-2 rounded-full bg-primary', forcedColors.selectedLeaf)} />\n )}\n </span>\n ) : null;\n\n // The level is drawn as indentation (one step per level, as a nested group's), and a windowed\n // item is exactly the window's item height: the window's arithmetic counts on it.\n const itemStyle: React.CSSProperties = { ...style };\n if (level > 1) itemStyle.paddingInlineStart = `${level - 1}rem`;\n if (ctx.itemSize !== undefined) itemStyle.height = ctx.itemSize;\n\n return (\n <div\n role=\"treeitem\"\n aria-selected={isSelected}\n aria-current={isCurrent ? true : undefined}\n aria-disabled={disabled ? true : undefined}\n data-selected={isSelected ? '' : undefined}\n data-current={isCurrent ? '' : undefined}\n data-checked={checkState === 'checked' ? '' : undefined}\n data-mixed={checkState === 'mixed' ? '' : undefined}\n data-disabled={disabled ? '' : undefined}\n className={cn(\n flatTreeItemClassNames.root,\n // The focus ring is drawn on the row, inside the item's box.\n 'box-border block outline-none',\n '[&:focus-visible>[data-flat-tree-row]]:outline-2 [&:focus-visible>[data-flat-tree-row]]:-outline-offset-2 [&:focus-visible>[data-flat-tree-row]]:outline-ring',\n disabledStyles,\n className,\n )}\n {...rest}\n // Named by its content only: the treeitem also holds the chevron and the checkbox. A consumer\n // aria-labelledby or aria-label replaces it.\n aria-labelledby={\n rest['aria-labelledby'] ?? (rest['aria-label'] === undefined ? labelId : undefined)\n }\n // From the model, after the rest props: the positions and states are the data's.\n aria-level={level}\n aria-setsize={setSize}\n aria-posinset={position}\n aria-expanded={isBranch ? expanded : undefined}\n aria-checked={\n checkState === undefined\n ? undefined\n : checkState === 'mixed'\n ? 'mixed'\n : checkState === 'checked'\n }\n data-index={index}\n tabIndex={ctx.tabStop === value ? 0 : -1}\n style={itemStyle}\n onClick={handleClick}\n ref={mergedRef}\n >\n <div\n data-flat-tree-row=\"\"\n className={cn(\n flatTreeItemClassNames.row,\n 'box-border flex items-center gap-1.5 rounded px-2 py-1',\n ctx.itemSize !== undefined && 'h-full',\n disabled ? 'cursor-not-allowed' : 'cursor-pointer hover:bg-subtle-hover',\n isSelected && cn('bg-subtle-selected font-semibold', forcedColors.selectedContainer),\n )}\n >\n {chevron}\n {checkbox ?? radio}\n <span id={labelId} className={cn(flatTreeItemClassNames.label, 'min-w-0 truncate')}>\n {children}\n </span>\n </div>\n </div>\n );\n};\nFlatTreeItem.displayName = 'FlatTreeItem';\n"],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { flatTreeItemClassNames as t } from "../../lib/classNames.mjs";
4
+ import { useId as n } from "../../hooks/useId.mjs";
5
+ import { useMergedRefs as r } from "../../hooks/useMergedRefs.mjs";
6
+ import { disabledStyles as i, forcedColors as a } from "../../lib/styles.mjs";
7
+ import { CheckIcon as o, ChevronRightIcon as s, SubtractIcon as c } from "../../lib/icons.mjs";
8
+ import { isOwnEvent as l } from "../../lib/events.mjs";
9
+ import { useFlatTreeContext as u } from "./FlatTree.context.mjs";
10
+ import * as d from "react";
11
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
12
+ //#region src/components/layout/FlatTree.item.tsx
13
+ function m(e) {
14
+ return e.target?.closest?.("[data-flat-tree-checkbox]") != null;
15
+ }
16
+ var h = ({ item: h, children: g, className: _, style: v, onClick: y, ref: b, ...x }) => {
17
+ let S = u("FlatTree.Item"), { item: C, level: w, position: T, setSize: E, isBranch: D, expanded: O, index: k } = h, { value: A } = C, j = C.disabled === !0, M = n("flat-tree-item-label"), N = d.useRef(null), P = r(b, N), F = S.selectionMode === "multiple" ? h.checked ?? "unchecked" : void 0, I = S.selected === void 0 ? void 0 : S.selected === A, L = S.current !== void 0 && S.current !== null && S.current === A, R = (e) => {
18
+ l(e) && !m(e) && (y?.(e), e.defaultPrevented || S.activate(h));
19
+ }, z = (e) => {
20
+ e.preventDefault(), N.current?.focus({ preventScroll: !0 });
21
+ }, B = (e) => {
22
+ S.toggleChecked(h, e.nativeEvent);
23
+ }, V = D ? /* @__PURE__ */ f(s, { className: e(t.expandIcon, "shrink-0 transition-transform motion-reduce:transition-none", O ? "rotate-90" : "wave-rtl:-scale-x-100") }) : /* @__PURE__ */ f("span", {
24
+ className: "w-3 shrink-0",
25
+ "aria-hidden": "true"
26
+ }), H = F === void 0 ? null : /* @__PURE__ */ f("span", {
27
+ role: "checkbox",
28
+ "aria-checked": F === "mixed" ? "mixed" : F === "checked",
29
+ "aria-labelledby": M,
30
+ "aria-disabled": j ? !0 : void 0,
31
+ tabIndex: -1,
32
+ "data-flat-tree-checkbox": "",
33
+ onMouseDown: z,
34
+ onClick: B,
35
+ className: e(t.indicator, "relative inline-flex size-4 shrink-0 items-center justify-center rounded-xs border transition-colors motion-reduce:transition-none", "before:absolute before:-inset-1", F === "unchecked" ? e("border-stroke-accessible bg-transparent", a.control) : "border-primary bg-primary text-primary-foreground forced-colors:border-[Highlight] forced-colors:bg-[Highlight]"),
36
+ children: F === "mixed" ? /* @__PURE__ */ f(c, {
37
+ size: 12,
38
+ className: a.selectedLeaf
39
+ }) : F === "checked" ? /* @__PURE__ */ f(o, {
40
+ size: 12,
41
+ className: a.selectedLeaf
42
+ }) : null
43
+ }), U = S.selectionMode === "single" ? /* @__PURE__ */ f("span", {
44
+ "aria-hidden": "true",
45
+ className: e(t.indicator, "inline-flex size-4 shrink-0 items-center justify-center rounded-full border transition-colors motion-reduce:transition-none", I ? "border-2 border-primary forced-colors:border-[Highlight]" : e("border-stroke-accessible", a.control)),
46
+ children: I && /* @__PURE__ */ f("span", { className: e("block size-2 rounded-full bg-primary", a.selectedLeaf) })
47
+ }) : null, W = { ...v };
48
+ return w > 1 && (W.paddingInlineStart = `${w - 1}rem`), S.itemSize !== void 0 && (W.height = S.itemSize), /* @__PURE__ */ f("div", {
49
+ role: "treeitem",
50
+ "aria-selected": I,
51
+ "aria-current": L ? !0 : void 0,
52
+ "aria-disabled": j ? !0 : void 0,
53
+ "data-selected": I ? "" : void 0,
54
+ "data-current": L ? "" : void 0,
55
+ "data-checked": F === "checked" ? "" : void 0,
56
+ "data-mixed": F === "mixed" ? "" : void 0,
57
+ "data-disabled": j ? "" : void 0,
58
+ className: e(t.root, "box-border block outline-none", "[&:focus-visible>[data-flat-tree-row]]:outline-2 [&:focus-visible>[data-flat-tree-row]]:-outline-offset-2 [&:focus-visible>[data-flat-tree-row]]:outline-ring", i, _),
59
+ ...x,
60
+ "aria-labelledby": x["aria-labelledby"] ?? (x["aria-label"] === void 0 ? M : void 0),
61
+ "aria-level": w,
62
+ "aria-setsize": E,
63
+ "aria-posinset": T,
64
+ "aria-expanded": D ? O : void 0,
65
+ "aria-checked": F === void 0 ? void 0 : F === "mixed" ? "mixed" : F === "checked",
66
+ "data-index": k,
67
+ tabIndex: S.tabStop === A ? 0 : -1,
68
+ style: W,
69
+ onClick: R,
70
+ ref: P,
71
+ children: /* @__PURE__ */ p("div", {
72
+ "data-flat-tree-row": "",
73
+ className: e(t.row, "box-border flex items-center gap-1.5 rounded px-2 py-1", S.itemSize !== void 0 && "h-full", j ? "cursor-not-allowed" : "cursor-pointer hover:bg-subtle-hover", I && e("bg-subtle-selected font-semibold", a.selectedContainer)),
74
+ children: [
75
+ V,
76
+ H ?? U,
77
+ /* @__PURE__ */ f("span", {
78
+ id: M,
79
+ className: e(t.label, "min-w-0 truncate"),
80
+ children: g
81
+ })
82
+ ]
83
+ })
84
+ });
85
+ };
86
+ h.displayName = "FlatTreeItem";
87
+ //#endregion
88
+ export { h as FlatTreeItem };
89
+
90
+ //# sourceMappingURL=FlatTree.item.mjs.map