@charcoal-ui/react 6.0.0-rc.7 → 6.0.0-rc.9

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 (285) hide show
  1. package/dist/_lib/createDivComponent.cjs +20 -0
  2. package/dist/_lib/createDivComponent.cjs.map +1 -0
  3. package/dist/_lib/createDivComponent.js +19 -0
  4. package/dist/_lib/createDivComponent.js.map +1 -0
  5. package/dist/_lib/index.cjs +22 -0
  6. package/dist/_lib/index.cjs.map +1 -0
  7. package/dist/_lib/index.js +20 -0
  8. package/dist/_lib/index.js.map +1 -0
  9. package/dist/_lib/useClassNames.cjs +15 -0
  10. package/dist/_lib/useClassNames.cjs.map +1 -0
  11. package/dist/_lib/useClassNames.js +14 -0
  12. package/dist/_lib/useClassNames.js.map +1 -0
  13. package/dist/_lib/useForwardedRef.cjs +19 -0
  14. package/dist/_lib/useForwardedRef.cjs.map +1 -0
  15. package/dist/_lib/useForwardedRef.js +17 -0
  16. package/dist/_lib/useForwardedRef.js.map +1 -0
  17. package/dist/_lib/useIsomorphicLayoutEffect.cjs +13 -0
  18. package/dist/_lib/useIsomorphicLayoutEffect.cjs.map +1 -0
  19. package/dist/_lib/useIsomorphicLayoutEffect.js +12 -0
  20. package/dist/_lib/useIsomorphicLayoutEffect.js.map +1 -0
  21. package/dist/_virtual/_rolldown/runtime.cjs +30 -0
  22. package/dist/components/Button/index2.cjs +26 -0
  23. package/dist/components/Button/index2.cjs.map +1 -0
  24. package/dist/components/Button/index2.js +24 -0
  25. package/dist/components/Button/index2.js.map +1 -0
  26. package/dist/components/Carousel/CarouselItem.cjs +46 -0
  27. package/dist/components/Carousel/CarouselItem.cjs.map +1 -0
  28. package/dist/components/Carousel/CarouselItem.js +45 -0
  29. package/dist/components/Carousel/CarouselItem.js.map +1 -0
  30. package/dist/components/Carousel/carouselStore.cjs +38 -0
  31. package/dist/components/Carousel/carouselStore.cjs.map +1 -0
  32. package/dist/components/Carousel/carouselStore.js +37 -0
  33. package/dist/components/Carousel/carouselStore.js.map +1 -0
  34. package/dist/components/Carousel/index2.cjs +145 -0
  35. package/dist/components/Carousel/index2.cjs.map +1 -0
  36. package/dist/components/Carousel/index2.js +144 -0
  37. package/dist/components/Carousel/index2.js.map +1 -0
  38. package/dist/components/Carousel/intersectionObserver.cjs +46 -0
  39. package/dist/components/Carousel/intersectionObserver.cjs.map +1 -0
  40. package/dist/components/Carousel/intersectionObserver.js +45 -0
  41. package/dist/components/Carousel/intersectionObserver.js.map +1 -0
  42. package/dist/components/Carousel/resizeObserver.cjs +34 -0
  43. package/dist/components/Carousel/resizeObserver.cjs.map +1 -0
  44. package/dist/components/Carousel/resizeObserver.js +33 -0
  45. package/dist/components/Carousel/resizeObserver.js.map +1 -0
  46. package/dist/components/Carousel/store.cjs +24 -0
  47. package/dist/components/Carousel/store.cjs.map +1 -0
  48. package/dist/components/Carousel/store.js +23 -0
  49. package/dist/components/Carousel/store.js.map +1 -0
  50. package/dist/components/Carousel/useCarouselScroller.cjs +149 -0
  51. package/dist/components/Carousel/useCarouselScroller.cjs.map +1 -0
  52. package/dist/components/Carousel/useCarouselScroller.js +148 -0
  53. package/dist/components/Carousel/useCarouselScroller.js.map +1 -0
  54. package/dist/components/Checkbox/CheckboxInput/index2.cjs +29 -0
  55. package/dist/components/Checkbox/CheckboxInput/index2.cjs.map +1 -0
  56. package/dist/components/Checkbox/CheckboxInput/index2.js +28 -0
  57. package/dist/components/Checkbox/CheckboxInput/index2.js.map +1 -0
  58. package/dist/components/Checkbox/CheckboxWithLabel.cjs +23 -0
  59. package/dist/components/Checkbox/CheckboxWithLabel.cjs.map +1 -0
  60. package/dist/components/Checkbox/CheckboxWithLabel.js +21 -0
  61. package/dist/components/Checkbox/CheckboxWithLabel.js.map +1 -0
  62. package/dist/components/Checkbox/index2.cjs +34 -0
  63. package/dist/components/Checkbox/index2.cjs.map +1 -0
  64. package/dist/components/Checkbox/index2.js +33 -0
  65. package/dist/components/Checkbox/index2.js.map +1 -0
  66. package/dist/components/Clickable/index2.cjs +21 -0
  67. package/dist/components/Clickable/index2.cjs.map +1 -0
  68. package/dist/components/Clickable/index2.js +19 -0
  69. package/dist/components/Clickable/index2.js.map +1 -0
  70. package/dist/components/DropdownSelector/DropdownMenuItem/index2.cjs +44 -0
  71. package/dist/components/DropdownSelector/DropdownMenuItem/index2.cjs.map +1 -0
  72. package/dist/components/DropdownSelector/DropdownMenuItem/index2.js +43 -0
  73. package/dist/components/DropdownSelector/DropdownMenuItem/index2.js.map +1 -0
  74. package/dist/components/DropdownSelector/DropdownPopover.cjs +41 -0
  75. package/dist/components/DropdownSelector/DropdownPopover.cjs.map +1 -0
  76. package/dist/components/DropdownSelector/DropdownPopover.js +40 -0
  77. package/dist/components/DropdownSelector/DropdownPopover.js.map +1 -0
  78. package/dist/components/DropdownSelector/ListItem/index2.cjs +19 -0
  79. package/dist/components/DropdownSelector/ListItem/index2.cjs.map +1 -0
  80. package/dist/components/DropdownSelector/ListItem/index2.js +18 -0
  81. package/dist/components/DropdownSelector/ListItem/index2.js.map +1 -0
  82. package/dist/components/DropdownSelector/MenuItem/index.cjs +30 -0
  83. package/dist/components/DropdownSelector/MenuItem/index.cjs.map +1 -0
  84. package/dist/components/DropdownSelector/MenuItem/index.js +29 -0
  85. package/dist/components/DropdownSelector/MenuItem/index.js.map +1 -0
  86. package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.cjs +30 -0
  87. package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.cjs.map +1 -0
  88. package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.js +29 -0
  89. package/dist/components/DropdownSelector/MenuItem/internals/handleFocusByKeyBoard.js.map +1 -0
  90. package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.cjs +53 -0
  91. package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.cjs.map +1 -0
  92. package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.js +52 -0
  93. package/dist/components/DropdownSelector/MenuItem/internals/useMenuItemHandleKeyDown.js.map +1 -0
  94. package/dist/components/DropdownSelector/MenuItemGroup/index2.cjs +20 -0
  95. package/dist/components/DropdownSelector/MenuItemGroup/index2.cjs.map +1 -0
  96. package/dist/components/DropdownSelector/MenuItemGroup/index2.js +19 -0
  97. package/dist/components/DropdownSelector/MenuItemGroup/index2.js.map +1 -0
  98. package/dist/components/DropdownSelector/MenuList/MenuListContext.cjs +15 -0
  99. package/dist/components/DropdownSelector/MenuList/MenuListContext.cjs.map +1 -0
  100. package/dist/components/DropdownSelector/MenuList/MenuListContext.js +14 -0
  101. package/dist/components/DropdownSelector/MenuList/MenuListContext.js.map +1 -0
  102. package/dist/components/DropdownSelector/MenuList/index2.cjs +32 -0
  103. package/dist/components/DropdownSelector/MenuList/index2.cjs.map +1 -0
  104. package/dist/components/DropdownSelector/MenuList/index2.js +31 -0
  105. package/dist/components/DropdownSelector/MenuList/index2.js.map +1 -0
  106. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.cjs +34 -0
  107. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.cjs.map +1 -0
  108. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.js +32 -0
  109. package/dist/components/DropdownSelector/MenuList/internals/getValuesRecursive.js.map +1 -0
  110. package/dist/components/DropdownSelector/Popover/index2.cjs +71 -0
  111. package/dist/components/DropdownSelector/Popover/index2.cjs.map +1 -0
  112. package/dist/components/DropdownSelector/Popover/index2.js +70 -0
  113. package/dist/components/DropdownSelector/Popover/index2.js.map +1 -0
  114. package/dist/components/DropdownSelector/Popover/usePreventScroll.cjs +27 -0
  115. package/dist/components/DropdownSelector/Popover/usePreventScroll.cjs.map +1 -0
  116. package/dist/components/DropdownSelector/Popover/usePreventScroll.js +26 -0
  117. package/dist/components/DropdownSelector/Popover/usePreventScroll.js.map +1 -0
  118. package/dist/components/DropdownSelector/index2.cjs +113 -0
  119. package/dist/components/DropdownSelector/index2.cjs.map +1 -0
  120. package/dist/components/DropdownSelector/index2.js +111 -0
  121. package/dist/components/DropdownSelector/index2.js.map +1 -0
  122. package/dist/components/DropdownSelector/utils/findPreviewRecursive.cjs +34 -0
  123. package/dist/components/DropdownSelector/utils/findPreviewRecursive.cjs.map +1 -0
  124. package/dist/components/DropdownSelector/utils/findPreviewRecursive.js +32 -0
  125. package/dist/components/DropdownSelector/utils/findPreviewRecursive.js.map +1 -0
  126. package/dist/components/FieldLabel/index2.cjs +35 -0
  127. package/dist/components/FieldLabel/index2.cjs.map +1 -0
  128. package/dist/components/FieldLabel/index2.js +33 -0
  129. package/dist/components/FieldLabel/index2.js.map +1 -0
  130. package/dist/components/HintText/index2.cjs +25 -0
  131. package/dist/components/HintText/index2.cjs.map +1 -0
  132. package/dist/components/HintText/index2.js +24 -0
  133. package/dist/components/HintText/index2.js.map +1 -0
  134. package/dist/components/Icon/index.cjs +39 -0
  135. package/dist/components/Icon/index.cjs.map +1 -0
  136. package/dist/components/Icon/index.js +37 -0
  137. package/dist/components/Icon/index.js.map +1 -0
  138. package/dist/components/IconButton/index2.cjs +46 -0
  139. package/dist/components/IconButton/index2.cjs.map +1 -0
  140. package/dist/components/IconButton/index2.js +44 -0
  141. package/dist/components/IconButton/index2.js.map +1 -0
  142. package/dist/components/LoadingSpinner/index2.cjs +43 -0
  143. package/dist/components/LoadingSpinner/index2.cjs.map +1 -0
  144. package/dist/components/LoadingSpinner/index2.js +41 -0
  145. package/dist/components/LoadingSpinner/index2.js.map +1 -0
  146. package/dist/components/Modal/Dialog/index2.cjs +30 -0
  147. package/dist/components/Modal/Dialog/index2.cjs.map +1 -0
  148. package/dist/components/Modal/Dialog/index2.js +28 -0
  149. package/dist/components/Modal/Dialog/index2.js.map +1 -0
  150. package/dist/components/Modal/ModalBackgroundContext.cjs +14 -0
  151. package/dist/components/Modal/ModalBackgroundContext.cjs.map +1 -0
  152. package/dist/components/Modal/ModalBackgroundContext.js +12 -0
  153. package/dist/components/Modal/ModalBackgroundContext.js.map +1 -0
  154. package/dist/components/Modal/ModalPlumbing2.cjs +30 -0
  155. package/dist/components/Modal/ModalPlumbing2.cjs.map +1 -0
  156. package/dist/components/Modal/ModalPlumbing2.js +26 -0
  157. package/dist/components/Modal/ModalPlumbing2.js.map +1 -0
  158. package/dist/components/Modal/index2.cjs +121 -0
  159. package/dist/components/Modal/index2.cjs.map +1 -0
  160. package/dist/components/Modal/index2.js +118 -0
  161. package/dist/components/Modal/index2.js.map +1 -0
  162. package/dist/components/Modal/useCustomModalOverlay.cjs +48 -0
  163. package/dist/components/Modal/useCustomModalOverlay.cjs.map +1 -0
  164. package/dist/components/Modal/useCustomModalOverlay.js +45 -0
  165. package/dist/components/Modal/useCustomModalOverlay.js.map +1 -0
  166. package/dist/components/Modal/useTransitionPresence.cjs +57 -0
  167. package/dist/components/Modal/useTransitionPresence.cjs.map +1 -0
  168. package/dist/components/Modal/useTransitionPresence.js +56 -0
  169. package/dist/components/Modal/useTransitionPresence.js.map +1 -0
  170. package/dist/components/MultiSelect/context.cjs +19 -0
  171. package/dist/components/MultiSelect/context.cjs.map +1 -0
  172. package/dist/components/MultiSelect/context.js +18 -0
  173. package/dist/components/MultiSelect/context.js.map +1 -0
  174. package/dist/components/MultiSelect/index2.cjs +97 -0
  175. package/dist/components/MultiSelect/index2.cjs.map +1 -0
  176. package/dist/components/MultiSelect/index2.js +93 -0
  177. package/dist/components/MultiSelect/index2.js.map +1 -0
  178. package/dist/components/Pagination/PaginationContext.cjs +16 -0
  179. package/dist/components/Pagination/PaginationContext.cjs.map +1 -0
  180. package/dist/components/Pagination/PaginationContext.js +14 -0
  181. package/dist/components/Pagination/PaginationContext.js.map +1 -0
  182. package/dist/components/Pagination/helper.cjs +63 -0
  183. package/dist/components/Pagination/helper.cjs.map +1 -0
  184. package/dist/components/Pagination/helper.js +61 -0
  185. package/dist/components/Pagination/helper.js.map +1 -0
  186. package/dist/components/Pagination/index2.cjs +301 -0
  187. package/dist/components/Pagination/index2.cjs.map +1 -0
  188. package/dist/components/Pagination/index2.js +288 -0
  189. package/dist/components/Pagination/index2.js.map +1 -0
  190. package/dist/components/Radio/RadioGroup/index2.cjs +49 -0
  191. package/dist/components/Radio/RadioGroup/index2.cjs.map +1 -0
  192. package/dist/components/Radio/RadioGroup/index2.js +47 -0
  193. package/dist/components/Radio/RadioGroup/index2.js.map +1 -0
  194. package/dist/components/Radio/RadioGroupContext.cjs +20 -0
  195. package/dist/components/Radio/RadioGroupContext.cjs.map +1 -0
  196. package/dist/components/Radio/RadioGroupContext.js +18 -0
  197. package/dist/components/Radio/RadioGroupContext.js.map +1 -0
  198. package/dist/components/Radio/RadioInput/index2.cjs +27 -0
  199. package/dist/components/Radio/RadioInput/index2.cjs.map +1 -0
  200. package/dist/components/Radio/RadioInput/index2.js +26 -0
  201. package/dist/components/Radio/RadioInput/index2.js.map +1 -0
  202. package/dist/components/Radio/index2.cjs +42 -0
  203. package/dist/components/Radio/index2.cjs.map +1 -0
  204. package/dist/components/Radio/index2.js +39 -0
  205. package/dist/components/Radio/index2.js.map +1 -0
  206. package/dist/components/SegmentedControl/RadioGroupContext.cjs +24 -0
  207. package/dist/components/SegmentedControl/RadioGroupContext.cjs.map +1 -0
  208. package/dist/components/SegmentedControl/RadioGroupContext.js +21 -0
  209. package/dist/components/SegmentedControl/RadioGroupContext.js.map +1 -0
  210. package/dist/components/SegmentedControl/index2.cjs +72 -0
  211. package/dist/components/SegmentedControl/index2.cjs.map +1 -0
  212. package/dist/components/SegmentedControl/index2.js +70 -0
  213. package/dist/components/SegmentedControl/index2.js.map +1 -0
  214. package/dist/components/Switch/SwitchInput/index2.cjs +25 -0
  215. package/dist/components/Switch/SwitchInput/index2.cjs.map +1 -0
  216. package/dist/components/Switch/SwitchInput/index2.js +24 -0
  217. package/dist/components/Switch/SwitchInput/index2.js.map +1 -0
  218. package/dist/components/Switch/SwitchWithLabel.cjs +23 -0
  219. package/dist/components/Switch/SwitchWithLabel.cjs.map +1 -0
  220. package/dist/components/Switch/SwitchWithLabel.js +21 -0
  221. package/dist/components/Switch/SwitchWithLabel.js.map +1 -0
  222. package/dist/components/Switch/index2.cjs +37 -0
  223. package/dist/components/Switch/index2.cjs.map +1 -0
  224. package/dist/components/Switch/index2.js +36 -0
  225. package/dist/components/Switch/index2.js.map +1 -0
  226. package/dist/components/TagItem/index2.cjs +57 -0
  227. package/dist/components/TagItem/index2.cjs.map +1 -0
  228. package/dist/components/TagItem/index2.js +55 -0
  229. package/dist/components/TagItem/index2.js.map +1 -0
  230. package/dist/components/TextArea/index2.cjs +134 -0
  231. package/dist/components/TextArea/index2.cjs.map +1 -0
  232. package/dist/components/TextArea/index2.js +133 -0
  233. package/dist/components/TextArea/index2.js.map +1 -0
  234. package/dist/components/TextEllipsis/helper.cjs +31 -0
  235. package/dist/components/TextEllipsis/helper.cjs.map +1 -0
  236. package/dist/components/TextEllipsis/helper.js +30 -0
  237. package/dist/components/TextEllipsis/helper.js.map +1 -0
  238. package/dist/components/TextEllipsis/index2.cjs +119 -0
  239. package/dist/components/TextEllipsis/index2.cjs.map +1 -0
  240. package/dist/components/TextEllipsis/index2.js +114 -0
  241. package/dist/components/TextEllipsis/index2.js.map +1 -0
  242. package/dist/components/TextField/AssistiveText/index2.cjs +10 -0
  243. package/dist/components/TextField/AssistiveText/index2.cjs.map +1 -0
  244. package/dist/components/TextField/AssistiveText/index2.js +10 -0
  245. package/dist/components/TextField/AssistiveText/index2.js.map +1 -0
  246. package/dist/components/TextField/index2.cjs +101 -0
  247. package/dist/components/TextField/index2.cjs.map +1 -0
  248. package/dist/components/TextField/index2.js +100 -0
  249. package/dist/components/TextField/index2.js.map +1 -0
  250. package/dist/components/TextField/useFocusWithClick.cjs +23 -0
  251. package/dist/components/TextField/useFocusWithClick.cjs.map +1 -0
  252. package/dist/components/TextField/useFocusWithClick.js +22 -0
  253. package/dist/components/TextField/useFocusWithClick.js.map +1 -0
  254. package/dist/core/CharcoalProvider.cjs +16 -0
  255. package/dist/core/CharcoalProvider.cjs.map +1 -0
  256. package/dist/core/CharcoalProvider.js +14 -0
  257. package/dist/core/CharcoalProvider.js.map +1 -0
  258. package/dist/core/OverlayProvider.js +4 -0
  259. package/dist/core/SSRProvider.cjs +15 -0
  260. package/dist/core/SSRProvider.cjs.map +1 -0
  261. package/dist/core/SSRProvider.js +14 -0
  262. package/dist/core/SSRProvider.js.map +1 -0
  263. package/dist/core/SetThemeScript.cjs +45 -0
  264. package/dist/core/SetThemeScript.cjs.map +1 -0
  265. package/dist/core/SetThemeScript.js +43 -0
  266. package/dist/core/SetThemeScript.js.map +1 -0
  267. package/dist/core/themeHelper.cjs +154 -0
  268. package/dist/core/themeHelper.cjs.map +1 -0
  269. package/dist/core/themeHelper.js +143 -0
  270. package/dist/core/themeHelper.js.map +1 -0
  271. package/dist/index.cjs +81 -12
  272. package/dist/index.css +1536 -1530
  273. package/dist/index.js +31 -12
  274. package/dist/layered.css +1508 -1502
  275. package/dist/layered.css.map +1 -1
  276. package/package.json +5 -5
  277. package/src/__tests__/css-shorthand-safety.test.ts +150 -0
  278. package/src/components/Button/__snapshots__/index.css.snap +8 -3
  279. package/src/components/Button/index.css +8 -3
  280. package/src/components/LoadingSpinner/__snapshots__/index.css.snap +1 -2
  281. package/src/components/LoadingSpinner/index.css +1 -2
  282. package/src/components/Pagination/__snapshots__/index.css.snap +3 -1
  283. package/src/components/Pagination/index.css +3 -1
  284. package/dist/index.cjs.map +0 -1
  285. package/dist/index.js.map +0 -1
@@ -0,0 +1,145 @@
1
+ "use client";
2
+ const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
3
+ const require_useClassNames = require('../../_lib/useClassNames.cjs');
4
+ const require_index = require('../IconButton/index2.cjs');
5
+ require('./index.cjs');
6
+ const require_CarouselItem = require('./CarouselItem.cjs');
7
+ const require_carouselStore = require('./carouselStore.cjs');
8
+ const require_useCarouselScroller = require('./useCarouselScroller.cjs');
9
+ let react = require("react");
10
+ let react_jsx_runtime = require("react/jsx-runtime");
11
+ let react_aria = require("react-aria");
12
+
13
+ //#region src/components/Carousel/index.tsx
14
+ const getServerSnapshot = () => require_carouselStore.INITIAL_CAROUSEL_STATE;
15
+ const DEFAULT_SCROLL_STEP = .75;
16
+ const NAV_ICON = {
17
+ prev: "24/Prev",
18
+ next: "24/Next"
19
+ };
20
+ const CarouselNavigationButton = ({ direction, canScroll, onScroll }) => {
21
+ const handleClick = (0, react.useCallback)(() => {
22
+ onScroll(direction);
23
+ }, [onScroll, direction]);
24
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.default, {
25
+ variant: "Overlay",
26
+ size: "S",
27
+ icon: NAV_ICON[direction],
28
+ "aria-label": direction === "prev" ? "Previous" : "Next",
29
+ disabled: !canScroll,
30
+ onClick: handleClick,
31
+ className: "charcoal-carousel__navigation__item",
32
+ "data-direction": direction,
33
+ "data-hidden": !canScroll
34
+ });
35
+ };
36
+ const CarouselIndicatorItem = ({ index, isActive, onSelect }) => {
37
+ const handleClick = (0, react.useCallback)(() => {
38
+ onSelect(index);
39
+ }, [onSelect, index]);
40
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
41
+ className: "charcoal-carousel__indicator__item",
42
+ "data-active": isActive,
43
+ "aria-current": isActive || void 0,
44
+ "aria-label": `Go to slide ${index + 1}`,
45
+ onClick: handleClick
46
+ });
47
+ };
48
+ const Carousel = (0, react.forwardRef)(function Render({ size = "M", navigationButtons, indicator, hasGradient = false, fullWidth = false, scrollStep = DEFAULT_SCROLL_STEP, scrollSnap, onScroll, onResize, onScrollStateChange, defaultScroll: { align = "left", offset = 0 } = {}, gap, children, ...props }, ref) {
49
+ const className = require_useClassNames.useClassNames("charcoal-carousel", props.className);
50
+ const showNavigationButtons = navigationButtons ?? size === "M";
51
+ const showIndicator = indicator ?? size === "S";
52
+ const snapType = scrollSnap?.type ?? (size === "S" ? "mandatory" : "none");
53
+ const snapAlign = scrollSnap?.align ?? "center";
54
+ const slides = react.Children.toArray(children);
55
+ const slideKeys = slides.map((slide, i) => (0, react.isValidElement)(slide) && slide.key != null ? slide.key : i);
56
+ const scrollerRef = (0, react.useRef)(null);
57
+ const [store] = (0, react.useState)(require_carouselStore.createCarouselStore);
58
+ const { scrollByStep, onItemResize, resetScroll } = require_useCarouselScroller.useCarouselScroller(scrollerRef, store, slides.length, {
59
+ align,
60
+ offset,
61
+ scrollStep,
62
+ onScroll,
63
+ onResize,
64
+ onScrollStateChange
65
+ });
66
+ (0, react.useImperativeHandle)(ref, () => ({ resetScroll }), [resetScroll]);
67
+ const { activeIndex, canPrev, canNext } = (0, react.useSyncExternalStore)(store.subscribe, store.getSnapshot, getServerSnapshot);
68
+ const scrollToItem = (0, react.useCallback)((index) => store.dispatch({
69
+ type: "requestScroll",
70
+ index
71
+ }), [store]);
72
+ const { keyboardProps } = (0, react_aria.useKeyboard)({ onKeyDown: (e) => {
73
+ if (e.key === "ArrowRight") {
74
+ e.preventDefault();
75
+ scrollByStep("next");
76
+ } else if (e.key === "ArrowLeft") {
77
+ e.preventDefault();
78
+ scrollByStep("prev");
79
+ } else e.continuePropagation();
80
+ } });
81
+ const { focusProps: scrollerFocusProps, isFocusVisible: scrollerFocusVisible } = (0, react_aria.useFocusRing)();
82
+ const { focusProps: rootFocusProps, isFocusVisible: rootFocusVisible } = (0, react_aria.useFocusRing)({ within: true });
83
+ const gapStyle = (0, react.useMemo)(() => ({ ...gap != null && { "--charcoal-carousel-gap": typeof gap === "number" ? `${gap}px` : gap } }), [gap]);
84
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
85
+ ...rootFocusProps,
86
+ className,
87
+ style: gapStyle,
88
+ "data-size": size,
89
+ "data-has-gradient": hasGradient,
90
+ "data-full-width": fullWidth,
91
+ "data-indicator": showIndicator,
92
+ "data-scroll-snap-type": snapType,
93
+ "data-scroll-snap-align": snapAlign,
94
+ "data-can-prev": canPrev,
95
+ "data-can-next": canNext,
96
+ "data-focus-visible-within": rootFocusVisible || void 0,
97
+ role: "region",
98
+ "aria-roledescription": "carousel",
99
+ "aria-label": "Carousel",
100
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
101
+ className: "charcoal-carousel__viewport",
102
+ "data-focus-visible": scrollerFocusVisible || void 0,
103
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
104
+ ...(0, react_aria.mergeProps)(scrollerFocusProps, keyboardProps),
105
+ ref: scrollerRef,
106
+ className: "charcoal-carousel__scroller",
107
+ tabIndex: 0,
108
+ children: slides.map((slide, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_CarouselItem.CarouselItem, {
109
+ index: i,
110
+ store,
111
+ onResize: onItemResize,
112
+ children: slide
113
+ }, slideKeys[i]))
114
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
115
+ className: "charcoal-carousel__navigation",
116
+ "data-visible": showNavigationButtons,
117
+ "aria-hidden": !showNavigationButtons,
118
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CarouselNavigationButton, {
119
+ direction: "prev",
120
+ canScroll: canPrev,
121
+ onScroll: scrollByStep
122
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CarouselNavigationButton, {
123
+ direction: "next",
124
+ canScroll: canNext,
125
+ onScroll: scrollByStep
126
+ })]
127
+ })]
128
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
129
+ className: "charcoal-carousel__indicator",
130
+ "data-visible": showIndicator,
131
+ "aria-hidden": !showIndicator,
132
+ children: slides.map((_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CarouselIndicatorItem, {
133
+ index: i,
134
+ isActive: i === activeIndex,
135
+ onSelect: scrollToItem
136
+ }, slideKeys[i]))
137
+ })]
138
+ });
139
+ });
140
+ Carousel.displayName = "Carousel";
141
+ var Carousel_default = (0, react.memo)(Carousel);
142
+
143
+ //#endregion
144
+ exports.default = Carousel_default;
145
+ //# sourceMappingURL=index2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index2.cjs","names":["Children","forwardRef","isValidElement","memo","useCallback","useImperativeHandle","useMemo","useRef","useState","useSyncExternalStore","CSSProperties","ReactNode","mergeProps","useFocusRing","useKeyboard","useClassNames","IconButton","CarouselItem","CarouselSlide","createCarouselStore","INITIAL_CAROUSEL_STATE","CarouselState","useCarouselScroller","getServerSnapshot","ScrollAlign","ScrollSnapType","ScrollSnapAlign","ScrollSnap","Readonly","type","align","ScrollStepContext","clientWidth","scrollWidth","scrollLeft","direction","ScrollStep","ctx","CarouselHandlerRef","resetScroll","CarouselProps","className","hasGradient","fullWidth","navigationButtons","indicator","size","scrollStep","scrollSnap","onScroll","left","onResize","width","onScrollStateChange","canScroll","defaultScroll","offset","gap","children","Direction","DEFAULT_SCROLL_STEP","NAV_ICON","prev","next","const","NavigationButtonProps","CarouselNavigationButton","handleClick","IndicatorItemProps","index","isActive","onSelect","CarouselIndicatorItem","undefined","Carousel","Render","props","ref","showNavigationButtons","showIndicator","snapType","snapAlign","slides","toArray","slideKeys","map","slide","i","key","scrollerRef","HTMLDivElement","store","scrollByStep","onItemResize","length","activeIndex","canPrev","canNext","subscribe","getSnapshot","scrollToItem","dispatch","keyboardProps","onKeyDown","e","preventDefault","continuePropagation","focusProps","scrollerFocusProps","isFocusVisible","scrollerFocusVisible","rootFocusProps","rootFocusVisible","within","gapStyle","_","displayName"],"sources":["../../../src/components/Carousel/index.tsx"],"sourcesContent":["import './index.css'\n\nimport {\n Children,\n forwardRef,\n isValidElement,\n memo,\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n type CSSProperties,\n type ReactNode,\n} from 'react'\nimport { mergeProps, useFocusRing, useKeyboard } from 'react-aria'\nimport { useClassNames } from '../../_lib/useClassNames'\nimport IconButton from '../IconButton'\nimport { CarouselItem as CarouselSlide } from './CarouselItem'\nimport {\n createCarouselStore,\n INITIAL_CAROUSEL_STATE,\n type CarouselState,\n} from './carouselStore'\nimport { useCarouselScroller } from './useCarouselScroller'\n\nconst getServerSnapshot = (): CarouselState => INITIAL_CAROUSEL_STATE\n\nexport type ScrollAlign = 'left' | 'center' | 'right'\n\nexport type ScrollSnapType = 'none' | 'proximity' | 'mandatory'\n\nexport type ScrollSnapAlign = 'center' | 'start'\n\nexport type ScrollSnap = Readonly<{\n type?: ScrollSnapType\n align?: ScrollSnapAlign\n}>\n\nexport type ScrollStepContext = Readonly<{\n clientWidth: number\n scrollWidth: number\n scrollLeft: number\n direction: 'prev' | 'next'\n}>\n\nexport type ScrollStep = number | ((ctx: ScrollStepContext) => number)\n\n// 命令的 API。ref 経由で初期位置へのリセットを公開する(react-sandbox 互換)。\nexport type CarouselHandlerRef = {\n resetScroll: () => void\n}\n\nexport type CarouselProps = Readonly<{\n className?: string\n hasGradient?: boolean\n fullWidth?: boolean\n navigationButtons?: boolean\n indicator?: boolean\n size?: 'S' | 'M'\n // 進む量。number は clientWidth に対する比率、function は進む px を直接返す。\n scrollStep?: ScrollStep\n // スクロールスナップ。未指定時は size 基準(M=none / S=mandatory)、align=center。\n // M の none は sandbox 同等に 0.75×表示幅ちょうど進む(スナップで着地を吸着しない)。\n scrollSnap?: ScrollSnap\n // react-sandbox 互換のコールバック。\n onScroll?: (left: number) => void\n onResize?: (width: number) => void\n onScrollStateChange?: (canScroll: boolean) => void\n defaultScroll?: { align?: ScrollAlign; offset?: number }\n // スライド間隔。number は px、string は CSS 値をそのまま使う。未指定は間隔なし。\n gap?: number | string\n // 1 直接子要素 = 1 スライド(react-sandbox 互換)。\n children: ReactNode\n}>\n\ntype Direction = 'prev' | 'next'\n\nconst DEFAULT_SCROLL_STEP = 0.75\n\nconst NAV_ICON = {\n prev: '24/Prev',\n next: '24/Next',\n} as const\n\ntype NavigationButtonProps = Readonly<{\n direction: Direction\n canScroll: boolean\n onScroll: (direction: Direction) => void\n}>\n\nconst CarouselNavigationButton = ({\n direction,\n canScroll,\n onScroll,\n}: NavigationButtonProps) => {\n const handleClick = useCallback(() => {\n onScroll(direction)\n }, [onScroll, direction])\n return (\n <IconButton\n variant=\"Overlay\"\n size=\"S\"\n icon={NAV_ICON[direction]}\n aria-label={direction === 'prev' ? 'Previous' : 'Next'}\n disabled={!canScroll}\n onClick={handleClick}\n className=\"charcoal-carousel__navigation__item\"\n data-direction={direction}\n data-hidden={!canScroll}\n />\n )\n}\n\ntype IndicatorItemProps = Readonly<{\n index: number\n isActive: boolean\n onSelect: (index: number) => void\n}>\n\nconst CarouselIndicatorItem = ({\n index,\n isActive,\n onSelect,\n}: IndicatorItemProps) => {\n const handleClick = useCallback(() => {\n onSelect(index)\n }, [onSelect, index])\n return (\n <button\n className=\"charcoal-carousel__indicator__item\"\n data-active={isActive}\n aria-current={isActive || undefined}\n aria-label={`Go to slide ${index + 1}`}\n onClick={handleClick}\n />\n )\n}\n\nconst Carousel = forwardRef<CarouselHandlerRef, CarouselProps>(function Render(\n {\n size = 'M',\n navigationButtons,\n indicator,\n hasGradient = false,\n fullWidth = false,\n scrollStep = DEFAULT_SCROLL_STEP,\n scrollSnap,\n onScroll,\n onResize,\n onScrollStateChange,\n defaultScroll: { align = 'left', offset = 0 } = {},\n gap,\n children,\n ...props\n }: CarouselProps,\n ref,\n) {\n const className = useClassNames('charcoal-carousel', props.className)\n const showNavigationButtons = navigationButtons ?? size === 'M'\n const showIndicator = indicator ?? size === 'S'\n const snapType = scrollSnap?.type ?? (size === 'S' ? 'mandatory' : 'none')\n const snapAlign = scrollSnap?.align ?? 'center'\n\n // 直接子要素 1 つを 1 スライドとして数える。key は子要素の key を引き継ぐ\n // (toArray が付与する接頭辞付き key。無ければ index)。\n const slides = Children.toArray(children)\n const slideKeys = slides.map((slide, i) =>\n isValidElement(slide) && slide.key != null ? slide.key : i,\n )\n\n const scrollerRef = useRef<HTMLDivElement>(null)\n const [store] = useState(createCarouselStore)\n\n const { scrollByStep, onItemResize, resetScroll } = useCarouselScroller(\n scrollerRef,\n store,\n slides.length,\n { align, offset, scrollStep, onScroll, onResize, onScrollStateChange },\n )\n\n useImperativeHandle(ref, () => ({ resetScroll }), [resetScroll])\n\n const { activeIndex, canPrev, canNext } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n getServerSnapshot,\n )\n\n const scrollToItem = useCallback(\n (index: number) => store.dispatch({ type: 'requestScroll', index }),\n [store],\n )\n\n // ←/→ でスクロール。コンテナにフォーカスがある時のみ。\n const { keyboardProps } = useKeyboard({\n onKeyDown: (e) => {\n if (e.key === 'ArrowRight') {\n e.preventDefault()\n scrollByStep('next')\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault()\n scrollByStep('prev')\n } else {\n e.continuePropagation()\n }\n },\n })\n\n const {\n focusProps: scrollerFocusProps,\n isFocusVisible: scrollerFocusVisible,\n } = useFocusRing()\n\n // ナビゲーションボタン表示用。クリックで残留したフォーカス(pointer 由来)では\n // 表示し続けないよう、キーボード由来のフォーカスのみを検知する。\n const { focusProps: rootFocusProps, isFocusVisible: rootFocusVisible } =\n useFocusRing({ within: true })\n\n // gap 宣言自体は index.css 側に置き、ここでは CSS 変数の値だけを注入する。\n const gapStyle = useMemo(\n () =>\n ({\n ...(gap != null && {\n '--charcoal-carousel-gap': typeof gap === 'number' ? `${gap}px` : gap,\n }),\n }) satisfies CSSProperties,\n [gap],\n )\n\n return (\n <div\n {...rootFocusProps}\n className={className}\n style={gapStyle}\n data-size={size}\n data-has-gradient={hasGradient}\n data-full-width={fullWidth}\n data-indicator={showIndicator}\n data-scroll-snap-type={snapType}\n data-scroll-snap-align={snapAlign}\n data-can-prev={canPrev}\n data-can-next={canNext}\n data-focus-visible-within={rootFocusVisible || undefined}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Carousel\"\n >\n {/* フォーカスリングは viewport に描く(理由は index.css の同セレクタ参照) */}\n <div\n className=\"charcoal-carousel__viewport\"\n data-focus-visible={scrollerFocusVisible || undefined}\n >\n <div\n {...mergeProps(scrollerFocusProps, keyboardProps)}\n ref={scrollerRef}\n className=\"charcoal-carousel__scroller\"\n tabIndex={0}\n >\n {slides.map((slide, i) => (\n <CarouselSlide\n key={slideKeys[i]}\n index={i}\n store={store}\n onResize={onItemResize}\n >\n {slide}\n </CarouselSlide>\n ))}\n </div>\n\n <div\n className=\"charcoal-carousel__navigation\"\n data-visible={showNavigationButtons}\n aria-hidden={!showNavigationButtons}\n >\n <CarouselNavigationButton\n direction=\"prev\"\n canScroll={canPrev}\n onScroll={scrollByStep}\n />\n <CarouselNavigationButton\n direction=\"next\"\n canScroll={canNext}\n onScroll={scrollByStep}\n />\n </div>\n </div>\n\n <div\n className=\"charcoal-carousel__indicator\"\n data-visible={showIndicator}\n aria-hidden={!showIndicator}\n >\n {slides.map((_, i) => (\n <CarouselIndicatorItem\n key={slideKeys[i]}\n index={i}\n isActive={i === activeIndex}\n onSelect={scrollToItem}\n />\n ))}\n </div>\n </div>\n )\n})\n\nCarousel.displayName = 'Carousel'\n\nexport default memo(Carousel)\n"],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ "use client";
2
+ import { useClassNames } from "../../_lib/useClassNames.js";
3
+ import IconButton from "../IconButton/index2.js";
4
+ /* empty css */
5
+ import { CarouselItem } from "./CarouselItem.js";
6
+ import { INITIAL_CAROUSEL_STATE, createCarouselStore } from "./carouselStore.js";
7
+ import { useCarouselScroller } from "./useCarouselScroller.js";
8
+ import { Children, forwardRef, isValidElement, memo, useCallback, useImperativeHandle, useMemo, useRef, useState, useSyncExternalStore } from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { mergeProps, useFocusRing, useKeyboard } from "react-aria";
11
+
12
+ //#region src/components/Carousel/index.tsx
13
+ const getServerSnapshot = () => INITIAL_CAROUSEL_STATE;
14
+ const DEFAULT_SCROLL_STEP = .75;
15
+ const NAV_ICON = {
16
+ prev: "24/Prev",
17
+ next: "24/Next"
18
+ };
19
+ const CarouselNavigationButton = ({ direction, canScroll, onScroll }) => {
20
+ const handleClick = useCallback(() => {
21
+ onScroll(direction);
22
+ }, [onScroll, direction]);
23
+ return /* @__PURE__ */ jsx(IconButton, {
24
+ variant: "Overlay",
25
+ size: "S",
26
+ icon: NAV_ICON[direction],
27
+ "aria-label": direction === "prev" ? "Previous" : "Next",
28
+ disabled: !canScroll,
29
+ onClick: handleClick,
30
+ className: "charcoal-carousel__navigation__item",
31
+ "data-direction": direction,
32
+ "data-hidden": !canScroll
33
+ });
34
+ };
35
+ const CarouselIndicatorItem = ({ index, isActive, onSelect }) => {
36
+ const handleClick = useCallback(() => {
37
+ onSelect(index);
38
+ }, [onSelect, index]);
39
+ return /* @__PURE__ */ jsx("button", {
40
+ className: "charcoal-carousel__indicator__item",
41
+ "data-active": isActive,
42
+ "aria-current": isActive || void 0,
43
+ "aria-label": `Go to slide ${index + 1}`,
44
+ onClick: handleClick
45
+ });
46
+ };
47
+ const Carousel = forwardRef(function Render({ size = "M", navigationButtons, indicator, hasGradient = false, fullWidth = false, scrollStep = DEFAULT_SCROLL_STEP, scrollSnap, onScroll, onResize, onScrollStateChange, defaultScroll: { align = "left", offset = 0 } = {}, gap, children, ...props }, ref) {
48
+ const className = useClassNames("charcoal-carousel", props.className);
49
+ const showNavigationButtons = navigationButtons ?? size === "M";
50
+ const showIndicator = indicator ?? size === "S";
51
+ const snapType = scrollSnap?.type ?? (size === "S" ? "mandatory" : "none");
52
+ const snapAlign = scrollSnap?.align ?? "center";
53
+ const slides = Children.toArray(children);
54
+ const slideKeys = slides.map((slide, i) => isValidElement(slide) && slide.key != null ? slide.key : i);
55
+ const scrollerRef = useRef(null);
56
+ const [store] = useState(createCarouselStore);
57
+ const { scrollByStep, onItemResize, resetScroll } = useCarouselScroller(scrollerRef, store, slides.length, {
58
+ align,
59
+ offset,
60
+ scrollStep,
61
+ onScroll,
62
+ onResize,
63
+ onScrollStateChange
64
+ });
65
+ useImperativeHandle(ref, () => ({ resetScroll }), [resetScroll]);
66
+ const { activeIndex, canPrev, canNext } = useSyncExternalStore(store.subscribe, store.getSnapshot, getServerSnapshot);
67
+ const scrollToItem = useCallback((index) => store.dispatch({
68
+ type: "requestScroll",
69
+ index
70
+ }), [store]);
71
+ const { keyboardProps } = useKeyboard({ onKeyDown: (e) => {
72
+ if (e.key === "ArrowRight") {
73
+ e.preventDefault();
74
+ scrollByStep("next");
75
+ } else if (e.key === "ArrowLeft") {
76
+ e.preventDefault();
77
+ scrollByStep("prev");
78
+ } else e.continuePropagation();
79
+ } });
80
+ const { focusProps: scrollerFocusProps, isFocusVisible: scrollerFocusVisible } = useFocusRing();
81
+ const { focusProps: rootFocusProps, isFocusVisible: rootFocusVisible } = useFocusRing({ within: true });
82
+ const gapStyle = useMemo(() => ({ ...gap != null && { "--charcoal-carousel-gap": typeof gap === "number" ? `${gap}px` : gap } }), [gap]);
83
+ return /* @__PURE__ */ jsxs("div", {
84
+ ...rootFocusProps,
85
+ className,
86
+ style: gapStyle,
87
+ "data-size": size,
88
+ "data-has-gradient": hasGradient,
89
+ "data-full-width": fullWidth,
90
+ "data-indicator": showIndicator,
91
+ "data-scroll-snap-type": snapType,
92
+ "data-scroll-snap-align": snapAlign,
93
+ "data-can-prev": canPrev,
94
+ "data-can-next": canNext,
95
+ "data-focus-visible-within": rootFocusVisible || void 0,
96
+ role: "region",
97
+ "aria-roledescription": "carousel",
98
+ "aria-label": "Carousel",
99
+ children: [/* @__PURE__ */ jsxs("div", {
100
+ className: "charcoal-carousel__viewport",
101
+ "data-focus-visible": scrollerFocusVisible || void 0,
102
+ children: [/* @__PURE__ */ jsx("div", {
103
+ ...mergeProps(scrollerFocusProps, keyboardProps),
104
+ ref: scrollerRef,
105
+ className: "charcoal-carousel__scroller",
106
+ tabIndex: 0,
107
+ children: slides.map((slide, i) => /* @__PURE__ */ jsx(CarouselItem, {
108
+ index: i,
109
+ store,
110
+ onResize: onItemResize,
111
+ children: slide
112
+ }, slideKeys[i]))
113
+ }), /* @__PURE__ */ jsxs("div", {
114
+ className: "charcoal-carousel__navigation",
115
+ "data-visible": showNavigationButtons,
116
+ "aria-hidden": !showNavigationButtons,
117
+ children: [/* @__PURE__ */ jsx(CarouselNavigationButton, {
118
+ direction: "prev",
119
+ canScroll: canPrev,
120
+ onScroll: scrollByStep
121
+ }), /* @__PURE__ */ jsx(CarouselNavigationButton, {
122
+ direction: "next",
123
+ canScroll: canNext,
124
+ onScroll: scrollByStep
125
+ })]
126
+ })]
127
+ }), /* @__PURE__ */ jsx("div", {
128
+ className: "charcoal-carousel__indicator",
129
+ "data-visible": showIndicator,
130
+ "aria-hidden": !showIndicator,
131
+ children: slides.map((_, i) => /* @__PURE__ */ jsx(CarouselIndicatorItem, {
132
+ index: i,
133
+ isActive: i === activeIndex,
134
+ onSelect: scrollToItem
135
+ }, slideKeys[i]))
136
+ })]
137
+ });
138
+ });
139
+ Carousel.displayName = "Carousel";
140
+ var Carousel_default = memo(Carousel);
141
+
142
+ //#endregion
143
+ export { Carousel_default as default };
144
+ //# sourceMappingURL=index2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index2.js","names":["Children","forwardRef","isValidElement","memo","useCallback","useImperativeHandle","useMemo","useRef","useState","useSyncExternalStore","CSSProperties","ReactNode","mergeProps","useFocusRing","useKeyboard","useClassNames","IconButton","CarouselItem","CarouselSlide","createCarouselStore","INITIAL_CAROUSEL_STATE","CarouselState","useCarouselScroller","getServerSnapshot","ScrollAlign","ScrollSnapType","ScrollSnapAlign","ScrollSnap","Readonly","type","align","ScrollStepContext","clientWidth","scrollWidth","scrollLeft","direction","ScrollStep","ctx","CarouselHandlerRef","resetScroll","CarouselProps","className","hasGradient","fullWidth","navigationButtons","indicator","size","scrollStep","scrollSnap","onScroll","left","onResize","width","onScrollStateChange","canScroll","defaultScroll","offset","gap","children","Direction","DEFAULT_SCROLL_STEP","NAV_ICON","prev","next","const","NavigationButtonProps","CarouselNavigationButton","handleClick","IndicatorItemProps","index","isActive","onSelect","CarouselIndicatorItem","undefined","Carousel","Render","props","ref","showNavigationButtons","showIndicator","snapType","snapAlign","slides","toArray","slideKeys","map","slide","i","key","scrollerRef","HTMLDivElement","store","scrollByStep","onItemResize","length","activeIndex","canPrev","canNext","subscribe","getSnapshot","scrollToItem","dispatch","keyboardProps","onKeyDown","e","preventDefault","continuePropagation","focusProps","scrollerFocusProps","isFocusVisible","scrollerFocusVisible","rootFocusProps","rootFocusVisible","within","gapStyle","_","displayName"],"sources":["../../../src/components/Carousel/index.tsx"],"sourcesContent":["import './index.css'\n\nimport {\n Children,\n forwardRef,\n isValidElement,\n memo,\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n type CSSProperties,\n type ReactNode,\n} from 'react'\nimport { mergeProps, useFocusRing, useKeyboard } from 'react-aria'\nimport { useClassNames } from '../../_lib/useClassNames'\nimport IconButton from '../IconButton'\nimport { CarouselItem as CarouselSlide } from './CarouselItem'\nimport {\n createCarouselStore,\n INITIAL_CAROUSEL_STATE,\n type CarouselState,\n} from './carouselStore'\nimport { useCarouselScroller } from './useCarouselScroller'\n\nconst getServerSnapshot = (): CarouselState => INITIAL_CAROUSEL_STATE\n\nexport type ScrollAlign = 'left' | 'center' | 'right'\n\nexport type ScrollSnapType = 'none' | 'proximity' | 'mandatory'\n\nexport type ScrollSnapAlign = 'center' | 'start'\n\nexport type ScrollSnap = Readonly<{\n type?: ScrollSnapType\n align?: ScrollSnapAlign\n}>\n\nexport type ScrollStepContext = Readonly<{\n clientWidth: number\n scrollWidth: number\n scrollLeft: number\n direction: 'prev' | 'next'\n}>\n\nexport type ScrollStep = number | ((ctx: ScrollStepContext) => number)\n\n// 命令的 API。ref 経由で初期位置へのリセットを公開する(react-sandbox 互換)。\nexport type CarouselHandlerRef = {\n resetScroll: () => void\n}\n\nexport type CarouselProps = Readonly<{\n className?: string\n hasGradient?: boolean\n fullWidth?: boolean\n navigationButtons?: boolean\n indicator?: boolean\n size?: 'S' | 'M'\n // 進む量。number は clientWidth に対する比率、function は進む px を直接返す。\n scrollStep?: ScrollStep\n // スクロールスナップ。未指定時は size 基準(M=none / S=mandatory)、align=center。\n // M の none は sandbox 同等に 0.75×表示幅ちょうど進む(スナップで着地を吸着しない)。\n scrollSnap?: ScrollSnap\n // react-sandbox 互換のコールバック。\n onScroll?: (left: number) => void\n onResize?: (width: number) => void\n onScrollStateChange?: (canScroll: boolean) => void\n defaultScroll?: { align?: ScrollAlign; offset?: number }\n // スライド間隔。number は px、string は CSS 値をそのまま使う。未指定は間隔なし。\n gap?: number | string\n // 1 直接子要素 = 1 スライド(react-sandbox 互換)。\n children: ReactNode\n}>\n\ntype Direction = 'prev' | 'next'\n\nconst DEFAULT_SCROLL_STEP = 0.75\n\nconst NAV_ICON = {\n prev: '24/Prev',\n next: '24/Next',\n} as const\n\ntype NavigationButtonProps = Readonly<{\n direction: Direction\n canScroll: boolean\n onScroll: (direction: Direction) => void\n}>\n\nconst CarouselNavigationButton = ({\n direction,\n canScroll,\n onScroll,\n}: NavigationButtonProps) => {\n const handleClick = useCallback(() => {\n onScroll(direction)\n }, [onScroll, direction])\n return (\n <IconButton\n variant=\"Overlay\"\n size=\"S\"\n icon={NAV_ICON[direction]}\n aria-label={direction === 'prev' ? 'Previous' : 'Next'}\n disabled={!canScroll}\n onClick={handleClick}\n className=\"charcoal-carousel__navigation__item\"\n data-direction={direction}\n data-hidden={!canScroll}\n />\n )\n}\n\ntype IndicatorItemProps = Readonly<{\n index: number\n isActive: boolean\n onSelect: (index: number) => void\n}>\n\nconst CarouselIndicatorItem = ({\n index,\n isActive,\n onSelect,\n}: IndicatorItemProps) => {\n const handleClick = useCallback(() => {\n onSelect(index)\n }, [onSelect, index])\n return (\n <button\n className=\"charcoal-carousel__indicator__item\"\n data-active={isActive}\n aria-current={isActive || undefined}\n aria-label={`Go to slide ${index + 1}`}\n onClick={handleClick}\n />\n )\n}\n\nconst Carousel = forwardRef<CarouselHandlerRef, CarouselProps>(function Render(\n {\n size = 'M',\n navigationButtons,\n indicator,\n hasGradient = false,\n fullWidth = false,\n scrollStep = DEFAULT_SCROLL_STEP,\n scrollSnap,\n onScroll,\n onResize,\n onScrollStateChange,\n defaultScroll: { align = 'left', offset = 0 } = {},\n gap,\n children,\n ...props\n }: CarouselProps,\n ref,\n) {\n const className = useClassNames('charcoal-carousel', props.className)\n const showNavigationButtons = navigationButtons ?? size === 'M'\n const showIndicator = indicator ?? size === 'S'\n const snapType = scrollSnap?.type ?? (size === 'S' ? 'mandatory' : 'none')\n const snapAlign = scrollSnap?.align ?? 'center'\n\n // 直接子要素 1 つを 1 スライドとして数える。key は子要素の key を引き継ぐ\n // (toArray が付与する接頭辞付き key。無ければ index)。\n const slides = Children.toArray(children)\n const slideKeys = slides.map((slide, i) =>\n isValidElement(slide) && slide.key != null ? slide.key : i,\n )\n\n const scrollerRef = useRef<HTMLDivElement>(null)\n const [store] = useState(createCarouselStore)\n\n const { scrollByStep, onItemResize, resetScroll } = useCarouselScroller(\n scrollerRef,\n store,\n slides.length,\n { align, offset, scrollStep, onScroll, onResize, onScrollStateChange },\n )\n\n useImperativeHandle(ref, () => ({ resetScroll }), [resetScroll])\n\n const { activeIndex, canPrev, canNext } = useSyncExternalStore(\n store.subscribe,\n store.getSnapshot,\n getServerSnapshot,\n )\n\n const scrollToItem = useCallback(\n (index: number) => store.dispatch({ type: 'requestScroll', index }),\n [store],\n )\n\n // ←/→ でスクロール。コンテナにフォーカスがある時のみ。\n const { keyboardProps } = useKeyboard({\n onKeyDown: (e) => {\n if (e.key === 'ArrowRight') {\n e.preventDefault()\n scrollByStep('next')\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault()\n scrollByStep('prev')\n } else {\n e.continuePropagation()\n }\n },\n })\n\n const {\n focusProps: scrollerFocusProps,\n isFocusVisible: scrollerFocusVisible,\n } = useFocusRing()\n\n // ナビゲーションボタン表示用。クリックで残留したフォーカス(pointer 由来)では\n // 表示し続けないよう、キーボード由来のフォーカスのみを検知する。\n const { focusProps: rootFocusProps, isFocusVisible: rootFocusVisible } =\n useFocusRing({ within: true })\n\n // gap 宣言自体は index.css 側に置き、ここでは CSS 変数の値だけを注入する。\n const gapStyle = useMemo(\n () =>\n ({\n ...(gap != null && {\n '--charcoal-carousel-gap': typeof gap === 'number' ? `${gap}px` : gap,\n }),\n }) satisfies CSSProperties,\n [gap],\n )\n\n return (\n <div\n {...rootFocusProps}\n className={className}\n style={gapStyle}\n data-size={size}\n data-has-gradient={hasGradient}\n data-full-width={fullWidth}\n data-indicator={showIndicator}\n data-scroll-snap-type={snapType}\n data-scroll-snap-align={snapAlign}\n data-can-prev={canPrev}\n data-can-next={canNext}\n data-focus-visible-within={rootFocusVisible || undefined}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Carousel\"\n >\n {/* フォーカスリングは viewport に描く(理由は index.css の同セレクタ参照) */}\n <div\n className=\"charcoal-carousel__viewport\"\n data-focus-visible={scrollerFocusVisible || undefined}\n >\n <div\n {...mergeProps(scrollerFocusProps, keyboardProps)}\n ref={scrollerRef}\n className=\"charcoal-carousel__scroller\"\n tabIndex={0}\n >\n {slides.map((slide, i) => (\n <CarouselSlide\n key={slideKeys[i]}\n index={i}\n store={store}\n onResize={onItemResize}\n >\n {slide}\n </CarouselSlide>\n ))}\n </div>\n\n <div\n className=\"charcoal-carousel__navigation\"\n data-visible={showNavigationButtons}\n aria-hidden={!showNavigationButtons}\n >\n <CarouselNavigationButton\n direction=\"prev\"\n canScroll={canPrev}\n onScroll={scrollByStep}\n />\n <CarouselNavigationButton\n direction=\"next\"\n canScroll={canNext}\n onScroll={scrollByStep}\n />\n </div>\n </div>\n\n <div\n className=\"charcoal-carousel__indicator\"\n data-visible={showIndicator}\n aria-hidden={!showIndicator}\n >\n {slides.map((_, i) => (\n <CarouselIndicatorItem\n key={slideKeys[i]}\n index={i}\n isActive={i === activeIndex}\n onSelect={scrollToItem}\n />\n ))}\n </div>\n </div>\n )\n})\n\nCarousel.displayName = 'Carousel'\n\nexport default memo(Carousel)\n"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ "use client";
2
+
3
+ //#region src/components/Carousel/intersectionObserver.ts
4
+ const CENTER_ROOT_MARGIN = "0px -50% 0px -50%";
5
+ const byRoot = /* @__PURE__ */ new Map();
6
+ /**
7
+ * `el` がその親(= scroller)の中央ラインに重なったら `onEnter` を呼ぶ。同一 root の
8
+ * IntersectionObserver を共有する singleton。返り値で監視解除(最後の1つで disconnect)。
9
+ * SSR / 非対応環境では no-op。
10
+ */
11
+ function observeCenter(el, onEnter) {
12
+ if (typeof window === "undefined" || typeof IntersectionObserver === "undefined") return () => void 0;
13
+ const root = el.parentElement;
14
+ if (!root) return () => void 0;
15
+ let entry = byRoot.get(root);
16
+ if (!entry) {
17
+ const callbacks = /* @__PURE__ */ new Map();
18
+ entry = {
19
+ observer: new IntersectionObserver((entries) => {
20
+ for (const e of entries) if (e.isIntersecting) callbacks.get(e.target)?.();
21
+ }, {
22
+ root,
23
+ rootMargin: CENTER_ROOT_MARGIN,
24
+ threshold: 0
25
+ }),
26
+ callbacks
27
+ };
28
+ byRoot.set(root, entry);
29
+ }
30
+ entry.callbacks.set(el, onEnter);
31
+ entry.observer.observe(el);
32
+ return () => {
33
+ const e = byRoot.get(root);
34
+ if (!e) return;
35
+ e.callbacks.delete(el);
36
+ e.observer.unobserve(el);
37
+ if (e.callbacks.size === 0) {
38
+ e.observer.disconnect();
39
+ byRoot.delete(root);
40
+ }
41
+ };
42
+ }
43
+
44
+ //#endregion
45
+ exports.observeCenter = observeCenter;
46
+ //# sourceMappingURL=intersectionObserver.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intersectionObserver.cjs","names":["CENTER_ROOT_MARGIN","CenterEntry","observer","IntersectionObserver","callbacks","Map","Element","byRoot","observeCenter","el","HTMLElement","onEnter","window","undefined","root","parentElement","entry","get","entries","e","isIntersecting","target","rootMargin","threshold","set","observe","delete","unobserve","size","disconnect"],"sources":["../../../src/components/Carousel/intersectionObserver.ts"],"sourcesContent":["// 中央検出(左右 50% を除外)。root は item の親(scroller)から導出する。\nconst CENTER_ROOT_MARGIN = '0px -50% 0px -50%'\n\ntype CenterEntry = {\n observer: IntersectionObserver\n callbacks: Map<Element, () => void>\n}\n\n// root(= el.parentElement)ごとに observer を1つ共有する。\nconst byRoot = new Map<Element, CenterEntry>()\n\n/**\n * `el` がその親(= scroller)の中央ラインに重なったら `onEnter` を呼ぶ。同一 root の\n * IntersectionObserver を共有する singleton。返り値で監視解除(最後の1つで disconnect)。\n * SSR / 非対応環境では no-op。\n */\nexport function observeCenter(\n el: HTMLElement,\n onEnter: () => void,\n): () => void {\n // window で SSR を弾く。polyfill が global に IntersectionObserver を生やしていても\n // サーバー上では observe しない。\n if (\n typeof window === 'undefined' ||\n typeof IntersectionObserver === 'undefined'\n )\n return () => undefined\n const root = el.parentElement\n if (!root) return () => undefined\n\n let entry = byRoot.get(root)\n if (!entry) {\n const callbacks = new Map<Element, () => void>()\n const observer = new IntersectionObserver(\n (entries) => {\n for (const e of entries) {\n if (e.isIntersecting) callbacks.get(e.target)?.()\n }\n },\n { root, rootMargin: CENTER_ROOT_MARGIN, threshold: 0 },\n )\n entry = { observer, callbacks }\n byRoot.set(root, entry)\n }\n entry.callbacks.set(el, onEnter)\n entry.observer.observe(el)\n\n return () => {\n const e = byRoot.get(root)\n if (!e) return\n e.callbacks.delete(el)\n e.observer.unobserve(el)\n if (e.callbacks.size === 0) {\n e.observer.disconnect()\n byRoot.delete(root)\n }\n }\n}\n"],"mappings":";;;AACA,MAAMA,qBAAqB;AAQ3B,MAAMO,yBAAS,IAAIF,KAA2B;;;;;;AAO9C,SAAgBG,cACdC,IACAE,SACY;CAGZ,IACE,OAAOC,WAAW,eAClB,OAAOT,yBAAyB,aAEhC,aAAaU;CACf,MAAMC,OAAOL,GAAGM;CAChB,IAAI,CAACD,MAAM,aAAaD;CAExB,IAAIG,QAAQT,OAAOU,IAAIH,KAAK;CAC5B,IAAI,CAACE,OAAO;EACV,MAAMZ,4BAAY,IAAIC,KAA0B;EAShDW,QAAQ;GAAEd,cARWC,sBAClBe,YAAY;IACX,KAAK,MAAMC,KAAKD,SACd,IAAIC,EAAEC,gBAAgBhB,UAAUa,IAAIE,EAAEE,OAAO,IAAI;MAGrD;IAAEP;IAAMQ,YAAYtB;IAAoBuB,WAAW;IACrD,CACkB;GAAEnB;GAAW;EAC/BG,OAAOiB,IAAIV,MAAME,MAAM;;CAEzBA,MAAMZ,UAAUoB,IAAIf,IAAIE,QAAQ;CAChCK,MAAMd,SAASuB,QAAQhB,GAAG;CAE1B,aAAa;EACX,MAAMU,IAAIZ,OAAOU,IAAIH,KAAK;EAC1B,IAAI,CAACK,GAAG;EACRA,EAAEf,UAAUsB,OAAOjB,GAAG;EACtBU,EAAEjB,SAASyB,UAAUlB,GAAG;EACxB,IAAIU,EAAEf,UAAUwB,SAAS,GAAG;GAC1BT,EAAEjB,SAAS2B,YAAY;GACvBtB,OAAOmB,OAAOZ,KAAK"}
@@ -0,0 +1,45 @@
1
+ "use client";
2
+ //#region src/components/Carousel/intersectionObserver.ts
3
+ const CENTER_ROOT_MARGIN = "0px -50% 0px -50%";
4
+ const byRoot = /* @__PURE__ */ new Map();
5
+ /**
6
+ * `el` がその親(= scroller)の中央ラインに重なったら `onEnter` を呼ぶ。同一 root の
7
+ * IntersectionObserver を共有する singleton。返り値で監視解除(最後の1つで disconnect)。
8
+ * SSR / 非対応環境では no-op。
9
+ */
10
+ function observeCenter(el, onEnter) {
11
+ if (typeof window === "undefined" || typeof IntersectionObserver === "undefined") return () => void 0;
12
+ const root = el.parentElement;
13
+ if (!root) return () => void 0;
14
+ let entry = byRoot.get(root);
15
+ if (!entry) {
16
+ const callbacks = /* @__PURE__ */ new Map();
17
+ entry = {
18
+ observer: new IntersectionObserver((entries) => {
19
+ for (const e of entries) if (e.isIntersecting) callbacks.get(e.target)?.();
20
+ }, {
21
+ root,
22
+ rootMargin: CENTER_ROOT_MARGIN,
23
+ threshold: 0
24
+ }),
25
+ callbacks
26
+ };
27
+ byRoot.set(root, entry);
28
+ }
29
+ entry.callbacks.set(el, onEnter);
30
+ entry.observer.observe(el);
31
+ return () => {
32
+ const e = byRoot.get(root);
33
+ if (!e) return;
34
+ e.callbacks.delete(el);
35
+ e.observer.unobserve(el);
36
+ if (e.callbacks.size === 0) {
37
+ e.observer.disconnect();
38
+ byRoot.delete(root);
39
+ }
40
+ };
41
+ }
42
+
43
+ //#endregion
44
+ export { observeCenter };
45
+ //# sourceMappingURL=intersectionObserver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intersectionObserver.js","names":["CENTER_ROOT_MARGIN","CenterEntry","observer","IntersectionObserver","callbacks","Map","Element","byRoot","observeCenter","el","HTMLElement","onEnter","window","undefined","root","parentElement","entry","get","entries","e","isIntersecting","target","rootMargin","threshold","set","observe","delete","unobserve","size","disconnect"],"sources":["../../../src/components/Carousel/intersectionObserver.ts"],"sourcesContent":["// 中央検出(左右 50% を除外)。root は item の親(scroller)から導出する。\nconst CENTER_ROOT_MARGIN = '0px -50% 0px -50%'\n\ntype CenterEntry = {\n observer: IntersectionObserver\n callbacks: Map<Element, () => void>\n}\n\n// root(= el.parentElement)ごとに observer を1つ共有する。\nconst byRoot = new Map<Element, CenterEntry>()\n\n/**\n * `el` がその親(= scroller)の中央ラインに重なったら `onEnter` を呼ぶ。同一 root の\n * IntersectionObserver を共有する singleton。返り値で監視解除(最後の1つで disconnect)。\n * SSR / 非対応環境では no-op。\n */\nexport function observeCenter(\n el: HTMLElement,\n onEnter: () => void,\n): () => void {\n // window で SSR を弾く。polyfill が global に IntersectionObserver を生やしていても\n // サーバー上では observe しない。\n if (\n typeof window === 'undefined' ||\n typeof IntersectionObserver === 'undefined'\n )\n return () => undefined\n const root = el.parentElement\n if (!root) return () => undefined\n\n let entry = byRoot.get(root)\n if (!entry) {\n const callbacks = new Map<Element, () => void>()\n const observer = new IntersectionObserver(\n (entries) => {\n for (const e of entries) {\n if (e.isIntersecting) callbacks.get(e.target)?.()\n }\n },\n { root, rootMargin: CENTER_ROOT_MARGIN, threshold: 0 },\n )\n entry = { observer, callbacks }\n byRoot.set(root, entry)\n }\n entry.callbacks.set(el, onEnter)\n entry.observer.observe(el)\n\n return () => {\n const e = byRoot.get(root)\n if (!e) return\n e.callbacks.delete(el)\n e.observer.unobserve(el)\n if (e.callbacks.size === 0) {\n e.observer.disconnect()\n byRoot.delete(root)\n }\n }\n}\n"],"mappings":";;AACA,MAAMA,qBAAqB;AAQ3B,MAAMO,yBAAS,IAAIF,KAA2B;;;;;;AAO9C,SAAgBG,cACdC,IACAE,SACY;CAGZ,IACE,OAAOC,WAAW,eAClB,OAAOT,yBAAyB,aAEhC,aAAaU;CACf,MAAMC,OAAOL,GAAGM;CAChB,IAAI,CAACD,MAAM,aAAaD;CAExB,IAAIG,QAAQT,OAAOU,IAAIH,KAAK;CAC5B,IAAI,CAACE,OAAO;EACV,MAAMZ,4BAAY,IAAIC,KAA0B;EAShDW,QAAQ;GAAEd,cARWC,sBAClBe,YAAY;IACX,KAAK,MAAMC,KAAKD,SACd,IAAIC,EAAEC,gBAAgBhB,UAAUa,IAAIE,EAAEE,OAAO,IAAI;MAGrD;IAAEP;IAAMQ,YAAYtB;IAAoBuB,WAAW;IACrD,CACkB;GAAEnB;GAAW;EAC/BG,OAAOiB,IAAIV,MAAME,MAAM;;CAEzBA,MAAMZ,UAAUoB,IAAIf,IAAIE,QAAQ;CAChCK,MAAMd,SAASuB,QAAQhB,GAAG;CAE1B,aAAa;EACX,MAAMU,IAAIZ,OAAOU,IAAIH,KAAK;EAC1B,IAAI,CAACK,GAAG;EACRA,EAAEf,UAAUsB,OAAOjB,GAAG;EACtBU,EAAEjB,SAASyB,UAAUlB,GAAG;EACxB,IAAIU,EAAEf,UAAUwB,SAAS,GAAG;GAC1BT,EAAEjB,SAAS2B,YAAY;GACvBtB,OAAOmB,OAAOZ,KAAK"}
@@ -0,0 +1,34 @@
1
+ "use client";
2
+
3
+ //#region src/components/Carousel/resizeObserver.ts
4
+ let observer = null;
5
+ const callbacks = /* @__PURE__ */ new Map();
6
+ function getObserver() {
7
+ if (typeof window === "undefined" || typeof ResizeObserver === "undefined") return null;
8
+ if (!observer) observer = new ResizeObserver((entries) => {
9
+ for (const e of entries) callbacks.get(e.target)?.();
10
+ });
11
+ return observer;
12
+ }
13
+ /**
14
+ * `el` のサイズ変化で `cb` を呼ぶ。全要素で単一の ResizeObserver を共有する singleton。
15
+ * 返り値で監視解除(最後の1つで disconnect)。SSR / 非対応環境では no-op。
16
+ */
17
+ function observeResize(el, cb) {
18
+ const obs = getObserver();
19
+ if (!obs) return () => void 0;
20
+ callbacks.set(el, cb);
21
+ obs.observe(el);
22
+ return () => {
23
+ callbacks.delete(el);
24
+ obs.unobserve(el);
25
+ if (callbacks.size === 0) {
26
+ obs.disconnect();
27
+ observer = null;
28
+ }
29
+ };
30
+ }
31
+
32
+ //#endregion
33
+ exports.observeResize = observeResize;
34
+ //# sourceMappingURL=resizeObserver.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resizeObserver.cjs","names":["observer","ResizeObserver","callbacks","Map","Element","getObserver","window","entries","e","get","target","observeResize","el","cb","obs","undefined","set","observe","delete","unobserve","size","disconnect"],"sources":["../../../src/components/Carousel/resizeObserver.ts"],"sourcesContent":["// 全 el で単一の ResizeObserver を共有する singleton。\nlet observer: ResizeObserver | null = null\nconst callbacks = new Map<Element, () => void>()\n\nfunction getObserver(): ResizeObserver | null {\n // window で SSR を弾く。polyfill が global に ResizeObserver を生やしていても\n // サーバー上では observe しない。\n if (typeof window === 'undefined' || typeof ResizeObserver === 'undefined')\n return null\n if (!observer) {\n observer = new ResizeObserver((entries) => {\n for (const e of entries) callbacks.get(e.target)?.()\n })\n }\n return observer\n}\n\n/**\n * `el` のサイズ変化で `cb` を呼ぶ。全要素で単一の ResizeObserver を共有する singleton。\n * 返り値で監視解除(最後の1つで disconnect)。SSR / 非対応環境では no-op。\n */\nexport function observeResize(el: Element, cb: () => void): () => void {\n const obs = getObserver()\n if (!obs) return () => undefined\n callbacks.set(el, cb)\n obs.observe(el)\n return () => {\n callbacks.delete(el)\n obs.unobserve(el)\n if (callbacks.size === 0) {\n obs.disconnect()\n observer = null\n }\n }\n}\n"],"mappings":";;;AACA,IAAIA,WAAkC;AACtC,MAAME,4BAAY,IAAIC,KAA0B;AAEhD,SAASE,cAAqC;CAG5C,IAAI,OAAOC,WAAW,eAAe,OAAOL,mBAAmB,aAC7D,OAAO;CACT,IAAI,CAACD,UACHA,WAAW,IAAIC,gBAAgBM,YAAY;EACzC,KAAK,MAAMC,KAAKD,SAASL,UAAUO,IAAID,EAAEE,OAAO,IAAI;GACpD;CAEJ,OAAOV;;;;;;AAOT,SAAgBW,cAAcC,IAAaC,IAA4B;CACrE,MAAMC,MAAMT,aAAa;CACzB,IAAI,CAACS,KAAK,aAAaC;CACvBb,UAAUc,IAAIJ,IAAIC,GAAG;CACrBC,IAAIG,QAAQL,GAAG;CACf,aAAa;EACXV,UAAUgB,OAAON,GAAG;EACpBE,IAAIK,UAAUP,GAAG;EACjB,IAAIV,UAAUkB,SAAS,GAAG;GACxBN,IAAIO,YAAY;GAChBrB,WAAW"}
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ //#region src/components/Carousel/resizeObserver.ts
3
+ let observer = null;
4
+ const callbacks = /* @__PURE__ */ new Map();
5
+ function getObserver() {
6
+ if (typeof window === "undefined" || typeof ResizeObserver === "undefined") return null;
7
+ if (!observer) observer = new ResizeObserver((entries) => {
8
+ for (const e of entries) callbacks.get(e.target)?.();
9
+ });
10
+ return observer;
11
+ }
12
+ /**
13
+ * `el` のサイズ変化で `cb` を呼ぶ。全要素で単一の ResizeObserver を共有する singleton。
14
+ * 返り値で監視解除(最後の1つで disconnect)。SSR / 非対応環境では no-op。
15
+ */
16
+ function observeResize(el, cb) {
17
+ const obs = getObserver();
18
+ if (!obs) return () => void 0;
19
+ callbacks.set(el, cb);
20
+ obs.observe(el);
21
+ return () => {
22
+ callbacks.delete(el);
23
+ obs.unobserve(el);
24
+ if (callbacks.size === 0) {
25
+ obs.disconnect();
26
+ observer = null;
27
+ }
28
+ };
29
+ }
30
+
31
+ //#endregion
32
+ export { observeResize };
33
+ //# sourceMappingURL=resizeObserver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resizeObserver.js","names":["observer","ResizeObserver","callbacks","Map","Element","getObserver","window","entries","e","get","target","observeResize","el","cb","obs","undefined","set","observe","delete","unobserve","size","disconnect"],"sources":["../../../src/components/Carousel/resizeObserver.ts"],"sourcesContent":["// 全 el で単一の ResizeObserver を共有する singleton。\nlet observer: ResizeObserver | null = null\nconst callbacks = new Map<Element, () => void>()\n\nfunction getObserver(): ResizeObserver | null {\n // window で SSR を弾く。polyfill が global に ResizeObserver を生やしていても\n // サーバー上では observe しない。\n if (typeof window === 'undefined' || typeof ResizeObserver === 'undefined')\n return null\n if (!observer) {\n observer = new ResizeObserver((entries) => {\n for (const e of entries) callbacks.get(e.target)?.()\n })\n }\n return observer\n}\n\n/**\n * `el` のサイズ変化で `cb` を呼ぶ。全要素で単一の ResizeObserver を共有する singleton。\n * 返り値で監視解除(最後の1つで disconnect)。SSR / 非対応環境では no-op。\n */\nexport function observeResize(el: Element, cb: () => void): () => void {\n const obs = getObserver()\n if (!obs) return () => undefined\n callbacks.set(el, cb)\n obs.observe(el)\n return () => {\n callbacks.delete(el)\n obs.unobserve(el)\n if (callbacks.size === 0) {\n obs.disconnect()\n observer = null\n }\n }\n}\n"],"mappings":";;AACA,IAAIA,WAAkC;AACtC,MAAME,4BAAY,IAAIC,KAA0B;AAEhD,SAASE,cAAqC;CAG5C,IAAI,OAAOC,WAAW,eAAe,OAAOL,mBAAmB,aAC7D,OAAO;CACT,IAAI,CAACD,UACHA,WAAW,IAAIC,gBAAgBM,YAAY;EACzC,KAAK,MAAMC,KAAKD,SAASL,UAAUO,IAAID,EAAEE,OAAO,IAAI;GACpD;CAEJ,OAAOV;;;;;;AAOT,SAAgBW,cAAcC,IAAaC,IAA4B;CACrE,MAAMC,MAAMT,aAAa;CACzB,IAAI,CAACS,KAAK,aAAaC;CACvBb,UAAUc,IAAIJ,IAAIC,GAAG;CACrBC,IAAIG,QAAQL,GAAG;CACf,aAAa;EACXV,UAAUgB,OAAON,GAAG;EACpBE,IAAIK,UAAUP,GAAG;EACjB,IAAIV,UAAUkB,SAAS,GAAG;GACxBN,IAAIO,YAAY;GAChBrB,WAAW"}
@@ -0,0 +1,24 @@
1
+ "use client";
2
+
3
+ //#region src/components/Carousel/store.ts
4
+ function createStore(reducer, initialState) {
5
+ let state = initialState;
6
+ const listeners = /* @__PURE__ */ new Set();
7
+ return {
8
+ dispatch(action) {
9
+ state = reducer(state, action);
10
+ for (const listener of listeners) listener();
11
+ },
12
+ subscribe(listener) {
13
+ listeners.add(listener);
14
+ return () => {
15
+ listeners.delete(listener);
16
+ };
17
+ },
18
+ getSnapshot: () => state
19
+ };
20
+ }
21
+
22
+ //#endregion
23
+ exports.createStore = createStore;
24
+ //# sourceMappingURL=store.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.cjs","names":["Store","Readonly","dispatch","action","Action","subscribe","listener","getSnapshot","State","createStore","reducer","state","initialState","listeners","Set","add","delete"],"sources":["../../../src/components/Carousel/store.ts"],"sourcesContent":["export type Store<State, Action> = Readonly<{\n dispatch: (action: Action) => void\n subscribe: (listener: () => void) => () => void\n getSnapshot: () => State\n}>\n\nexport function createStore<State, Action>(\n reducer: (state: State, action: Action) => State,\n initialState: State,\n): Store<State, Action> {\n let state = initialState\n const listeners = new Set<() => void>()\n\n return {\n dispatch(action) {\n state = reducer(state, action)\n for (const listener of listeners) listener()\n },\n subscribe(listener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n getSnapshot: () => state,\n }\n}\n"],"mappings":";;;AAMA,SAAgBS,YACdC,SACAE,cACsB;CACtB,IAAID,QAAQC;CACZ,MAAMC,4BAAY,IAAIC,KAAiB;CAEvC,OAAO;EACLZ,SAASC,QAAQ;GACfQ,QAAQD,QAAQC,OAAOR,OAAO;GAC9B,KAAK,MAAMG,YAAYO,WAAWP,UAAU;;EAE9CD,UAAUC,UAAU;GAClBO,UAAUE,IAAIT,SAAS;GACvB,aAAa;IACXO,UAAUG,OAAOV,SAAS;;;EAG9BC,mBAAmBI;EACpB"}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ //#region src/components/Carousel/store.ts
3
+ function createStore(reducer, initialState) {
4
+ let state = initialState;
5
+ const listeners = /* @__PURE__ */ new Set();
6
+ return {
7
+ dispatch(action) {
8
+ state = reducer(state, action);
9
+ for (const listener of listeners) listener();
10
+ },
11
+ subscribe(listener) {
12
+ listeners.add(listener);
13
+ return () => {
14
+ listeners.delete(listener);
15
+ };
16
+ },
17
+ getSnapshot: () => state
18
+ };
19
+ }
20
+
21
+ //#endregion
22
+ export { createStore };
23
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","names":["Store","Readonly","dispatch","action","Action","subscribe","listener","getSnapshot","State","createStore","reducer","state","initialState","listeners","Set","add","delete"],"sources":["../../../src/components/Carousel/store.ts"],"sourcesContent":["export type Store<State, Action> = Readonly<{\n dispatch: (action: Action) => void\n subscribe: (listener: () => void) => () => void\n getSnapshot: () => State\n}>\n\nexport function createStore<State, Action>(\n reducer: (state: State, action: Action) => State,\n initialState: State,\n): Store<State, Action> {\n let state = initialState\n const listeners = new Set<() => void>()\n\n return {\n dispatch(action) {\n state = reducer(state, action)\n for (const listener of listeners) listener()\n },\n subscribe(listener) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n getSnapshot: () => state,\n }\n}\n"],"mappings":";;AAMA,SAAgBS,YACdC,SACAE,cACsB;CACtB,IAAID,QAAQC;CACZ,MAAMC,4BAAY,IAAIC,KAAiB;CAEvC,OAAO;EACLZ,SAASC,QAAQ;GACfQ,QAAQD,QAAQC,OAAOR,OAAO;GAC9B,KAAK,MAAMG,YAAYO,WAAWP,UAAU;;EAE9CD,UAAUC,UAAU;GAClBO,UAAUE,IAAIT,SAAS;GACvB,aAAa;IACXO,UAAUG,OAAOV,SAAS;;;EAG9BC,mBAAmBI;EACpB"}