@spark-ui/components 12.1.0 → 12.1.2

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.
@@ -164,6 +164,9 @@ interface CarouselAPI extends AnatomyPropsSetters {
164
164
  snapStop: UseCarouselProps['snapStop'];
165
165
  scrollBehavior: UseCarouselProps['scrollBehavior'];
166
166
  maxDots: number;
167
+ registerSlide: (element: HTMLElement | null, callback: (isVisible: boolean) => void) => void;
168
+ unregisterSlide: (element: HTMLElement | null) => void;
169
+ isSlideVisible: (element: HTMLElement | null) => boolean;
167
170
  }
168
171
 
169
172
  interface Props$4 extends UseCarouselProps, ComponentProps<'div'> {
@@ -26,28 +26,109 @@ module.exports = __toCommonJS(carousel_exports);
26
26
 
27
27
  // src/carousel/Carousel.tsx
28
28
  var import_class_variance_authority = require("class-variance-authority");
29
- var import_react7 = require("react");
29
+ var import_react8 = require("react");
30
30
 
31
31
  // src/carousel/useCarousel.ts
32
- var import_react6 = require("react");
32
+ var import_react7 = require("react");
33
33
 
34
- // src/carousel/useEvent.ts
34
+ // src/carousel/useCarouselVisibility.ts
35
35
  var import_react = require("react");
36
+ function useCarouselVisibility(carouselRef) {
37
+ const slideVisibilityMap = (0, import_react.useRef)(/* @__PURE__ */ new Map());
38
+ const visibilityObserverRef = (0, import_react.useRef)(null);
39
+ const visibilityCallbacksRef = (0, import_react.useRef)(/* @__PURE__ */ new Map());
40
+ const createObserverCallback = (0, import_react.useCallback)(() => {
41
+ return (entries) => {
42
+ entries.forEach((entry) => {
43
+ const isVisible = entry.isIntersecting;
44
+ const element = entry.target;
45
+ slideVisibilityMap.current.set(element, isVisible);
46
+ const callback = visibilityCallbacksRef.current.get(element);
47
+ if (callback) {
48
+ callback(isVisible);
49
+ }
50
+ });
51
+ };
52
+ }, []);
53
+ const getOrCreateObserver = (0, import_react.useCallback)(() => {
54
+ if (visibilityObserverRef.current) {
55
+ return visibilityObserverRef.current;
56
+ }
57
+ const container = carouselRef.current;
58
+ if (!container) return null;
59
+ const observer = new IntersectionObserver(createObserverCallback(), {
60
+ root: container,
61
+ threshold: 0.2
62
+ });
63
+ visibilityObserverRef.current = observer;
64
+ return observer;
65
+ }, [carouselRef, createObserverCallback]);
66
+ (0, import_react.useEffect)(() => {
67
+ const observer = getOrCreateObserver();
68
+ const visibilityMap = slideVisibilityMap.current;
69
+ const callbacksMap = visibilityCallbacksRef.current;
70
+ return () => {
71
+ if (observer) {
72
+ observer.disconnect();
73
+ visibilityMap.clear();
74
+ callbacksMap.clear();
75
+ visibilityObserverRef.current = null;
76
+ }
77
+ };
78
+ }, [getOrCreateObserver]);
79
+ const registerSlide = (0, import_react.useCallback)(
80
+ (element, callback) => {
81
+ if (!element) return;
82
+ const observer = getOrCreateObserver();
83
+ if (!observer) {
84
+ setTimeout(() => registerSlide(element, callback), 0);
85
+ return;
86
+ }
87
+ const initialVisible = slideVisibilityMap.current.get(element) ?? true;
88
+ slideVisibilityMap.current.set(element, initialVisible);
89
+ visibilityCallbacksRef.current.set(element, callback);
90
+ observer.observe(element);
91
+ callback(initialVisible);
92
+ },
93
+ [getOrCreateObserver]
94
+ );
95
+ const unregisterSlide = (0, import_react.useCallback)((element) => {
96
+ if (!element) return;
97
+ const observer = visibilityObserverRef.current;
98
+ if (observer) {
99
+ observer.unobserve(element);
100
+ }
101
+ slideVisibilityMap.current.delete(element);
102
+ visibilityCallbacksRef.current.delete(element);
103
+ }, []);
104
+ const isSlideVisible = (0, import_react.useCallback)((element) => {
105
+ if (!element) return true;
106
+ return slideVisibilityMap.current.get(element) ?? true;
107
+ }, []);
108
+ return {
109
+ registerSlide,
110
+ unregisterSlide,
111
+ isSlideVisible
112
+ };
113
+ }
114
+
115
+ // src/carousel/useEvent.ts
116
+ var import_react2 = require("react");
36
117
  function useEvent(callback) {
37
- const ref = (0, import_react.useRef)(() => {
118
+ const ref = (0, import_react2.useRef)(() => {
38
119
  throw new Error("Cannot call an event handler while rendering.");
39
120
  });
40
- (0, import_react.useLayoutEffect)(() => {
121
+ (0, import_react2.useLayoutEffect)(() => {
41
122
  ref.current = callback;
42
123
  });
43
- return (0, import_react.useCallback)((...args) => ref.current?.(...args), []);
124
+ return (0, import_react2.useCallback)((...args) => ref.current?.(...args), []);
44
125
  }
45
126
 
46
127
  // src/carousel/useIsMounted.ts
47
- var import_react2 = require("react");
128
+ var import_react3 = require("react");
48
129
  var useIsMounted = () => {
49
- const isMounted = (0, import_react2.useRef)(false);
50
- (0, import_react2.useEffect)(() => {
130
+ const isMounted = (0, import_react3.useRef)(false);
131
+ (0, import_react3.useEffect)(() => {
51
132
  isMounted.current = true;
52
133
  return () => {
53
134
  isMounted.current = false;
@@ -57,11 +138,11 @@ var useIsMounted = () => {
57
138
  };
58
139
 
59
140
  // src/carousel/useScrollEnd.ts
60
- var import_react3 = require("react");
141
+ var import_react4 = require("react");
61
142
  function useScrollEnd(scrollRef, callback) {
62
- const scrollLeft = (0, import_react3.useRef)(0);
63
- const safariTimeout = (0, import_react3.useRef)(null);
64
- (0, import_react3.useEffect)(() => {
143
+ const scrollLeft = (0, import_react4.useRef)(0);
144
+ const safariTimeout = (0, import_react4.useRef)(null);
145
+ (0, import_react4.useEffect)(() => {
65
146
  const element = scrollRef.current;
66
147
  if (!element) return;
67
148
  const supportsScrollend = "onscrollend" in window;
@@ -100,12 +181,12 @@ function useScrollEnd(scrollRef, callback) {
100
181
  }
101
182
 
102
183
  // src/carousel/useSnapPoints.ts
103
- var import_react5 = require("react");
184
+ var import_react6 = require("react");
104
185
 
105
186
  // src/carousel/useResizeObserver.ts
106
- var import_react4 = require("react");
187
+ var import_react5 = require("react");
107
188
  function useResizeObserver(ref, callback) {
108
- (0, import_react4.useLayoutEffect)(() => {
189
+ (0, import_react5.useLayoutEffect)(() => {
109
190
  const element = ref.current;
110
191
  if (!element) return;
111
192
  const observer = new ResizeObserver((entries) => {
@@ -199,8 +280,8 @@ function useSnapPoints(initialSnapPoints = [], {
199
280
  slidesPerMove,
200
281
  slidesPerPage
201
282
  }) {
202
- const [pageSnapPoints, setPageSnapPoints] = (0, import_react5.useState)(initialSnapPoints);
203
- const stableSnapPoints = (0, import_react5.useMemo)(() => pageSnapPoints, [pageSnapPoints]);
283
+ const [pageSnapPoints, setPageSnapPoints] = (0, import_react6.useState)(initialSnapPoints);
284
+ const stableSnapPoints = (0, import_react6.useMemo)(() => pageSnapPoints, [pageSnapPoints]);
204
285
  useResizeObserver(carouselRef, () => {
205
286
  const newSnapPoints = getSnapPositions({
206
287
  slidesPerMove,
@@ -233,23 +314,24 @@ var useCarousel = ({
233
314
  page: controlledPage,
234
315
  onPageChange: onPageChangeProp
235
316
  }) => {
236
- const carouselId = (0, import_react6.useId)();
237
- const [pageState, setPageState] = (0, import_react6.useState)(defaultPage || controlledPage || 0);
238
- const carouselRef = (0, import_react6.useRef)(null);
239
- const pageIndicatorsRefs = (0, import_react6.useRef)([]);
317
+ const carouselId = (0, import_react7.useId)();
318
+ const [pageState, setPageState] = (0, import_react7.useState)(defaultPage || controlledPage || 0);
319
+ const carouselRef = (0, import_react7.useRef)(null);
320
+ const pageIndicatorsRefs = (0, import_react7.useRef)([]);
240
321
  const isMountedRef = useIsMounted();
241
322
  const isMounted = isMountedRef.current;
242
323
  const onPageChange = useEvent(onPageChangeProp);
324
+ const { registerSlide, unregisterSlide, isSlideVisible } = useCarouselVisibility(carouselRef);
243
325
  const [pageSnapPoints] = useSnapPoints([], {
244
326
  carouselRef,
245
327
  slidesPerMove,
246
328
  slidesPerPage
247
329
  });
248
- const canScrollPrev = (0, import_react6.useRef)(loop || pageState > 0);
249
- const canScrollNext = (0, import_react6.useRef)(loop || pageState < pageSnapPoints.length - 1);
330
+ const canScrollPrev = (0, import_react7.useRef)(loop || pageState > 0);
331
+ const canScrollNext = (0, import_react7.useRef)(loop || pageState < pageSnapPoints.length - 1);
250
332
  canScrollPrev.current = loop || pageState > 0;
251
333
  canScrollNext.current = loop || pageState < pageSnapPoints.length - 1;
252
- const handlePageChange = (0, import_react6.useCallback)(
334
+ const handlePageChange = (0, import_react7.useCallback)(
253
335
  (page) => {
254
336
  if (page !== pageState) {
255
337
  setPageState(page);
@@ -258,7 +340,7 @@ var useCarousel = ({
258
340
  },
259
341
  [onPageChange, pageState]
260
342
  );
261
- const scrollTo = (0, import_react6.useCallback)(
343
+ const scrollTo = (0, import_react7.useCallback)(
262
344
  (page, behavior) => {
263
345
  if (carouselRef.current) {
264
346
  carouselRef.current.scrollTo({
@@ -270,7 +352,7 @@ var useCarousel = ({
270
352
  },
271
353
  [handlePageChange, pageSnapPoints]
272
354
  );
273
- const scrollPrev = (0, import_react6.useCallback)(
355
+ const scrollPrev = (0, import_react7.useCallback)(
274
356
  (cb) => {
275
357
  if (canScrollPrev) {
276
358
  const targetPage = loop && pageState === 0 ? pageSnapPoints.length - 1 : Math.max(pageState - 1, 0);
@@ -280,7 +362,7 @@ var useCarousel = ({
280
362
  },
281
363
  [loop, pageSnapPoints, pageState, scrollBehavior, scrollTo]
282
364
  );
283
- const scrollNext = (0, import_react6.useCallback)(
365
+ const scrollNext = (0, import_react7.useCallback)(
284
366
  (cb) => {
285
367
  if (canScrollNext) {
286
368
  const targetPage = loop && pageState === pageSnapPoints.length - 1 ? 0 : Math.min(pageState + 1, pageSnapPoints.length - 1);
@@ -290,12 +372,12 @@ var useCarousel = ({
290
372
  },
291
373
  [loop, pageSnapPoints, pageState, scrollBehavior, scrollTo]
292
374
  );
293
- (0, import_react6.useEffect)(() => {
375
+ (0, import_react7.useEffect)(() => {
294
376
  if (controlledPage != null) {
295
377
  scrollTo(controlledPage, scrollBehavior);
296
378
  }
297
379
  }, [controlledPage, scrollBehavior, scrollTo]);
298
- (0, import_react6.useLayoutEffect)(() => {
380
+ (0, import_react7.useLayoutEffect)(() => {
299
381
  if (defaultPage != null && !isMounted && carouselRef.current) {
300
382
  const snapPositions = getSnapPositions({
301
383
  container: carouselRef.current,
@@ -308,7 +390,7 @@ var useCarousel = ({
308
390
  });
309
391
  }
310
392
  }, [defaultPage, isMounted, slidesPerMove, slidesPerPage]);
311
- const syncPageStateWithScrollPosition = (0, import_react6.useCallback)(() => {
393
+ const syncPageStateWithScrollPosition = (0, import_react7.useCallback)(() => {
312
394
  if (!carouselRef.current || pageSnapPoints.length === 0) return;
313
395
  const { scrollLeft } = carouselRef.current;
314
396
  const distances = pageSnapPoints.map((pagePosition) => Math.abs(scrollLeft - pagePosition));
@@ -340,6 +422,10 @@ var useCarousel = ({
340
422
  scrollTo,
341
423
  scrollPrev,
342
424
  scrollNext,
425
+ // visibility management
426
+ registerSlide,
427
+ unregisterSlide,
428
+ isSlideVisible,
343
429
  // anatomy
344
430
  getRootProps: () => ({
345
431
  id: `carousel::${carouselId}:`,
@@ -477,7 +563,7 @@ var useCarousel = ({
477
563
 
478
564
  // src/carousel/Carousel.tsx
479
565
  var import_jsx_runtime = require("react/jsx-runtime");
480
- var CarouselContext = (0, import_react7.createContext)(null);
566
+ var CarouselContext = (0, import_react8.createContext)(null);
481
567
  var Carousel = ({
482
568
  className,
483
569
  snapType = "mandatory",
@@ -531,7 +617,7 @@ var Carousel = ({
531
617
  };
532
618
  Carousel.displayName = "Carousel";
533
619
  var useCarouselContext = () => {
534
- const context = (0, import_react7.useContext)(CarouselContext);
620
+ const context = (0, import_react8.useContext)(CarouselContext);
535
621
  if (!context) {
536
622
  throw Error("useCarouselContext must be used within a Carousel provider");
537
623
  }
@@ -563,11 +649,11 @@ CarouselControls.displayName = "Carousel.Controls";
563
649
  var import_ArrowVerticalRight = require("@spark-ui/icons/ArrowVerticalRight");
564
650
 
565
651
  // src/icon/Icon.tsx
566
- var import_react9 = require("react");
652
+ var import_react10 = require("react");
567
653
 
568
654
  // src/slot/Slot.tsx
569
655
  var import_radix_ui = require("radix-ui");
570
- var import_react8 = require("react");
656
+ var import_react9 = require("react");
571
657
  var import_jsx_runtime3 = require("react/jsx-runtime");
572
658
  var Slottable = import_radix_ui.Slot.Slottable;
573
659
  var Slot = ({ ref, ...props }) => {
@@ -575,7 +661,7 @@ var Slot = ({ ref, ...props }) => {
575
661
  };
576
662
  var wrapPolymorphicSlot = (asChild, children, callback) => {
577
663
  if (!asChild) return callback(children);
578
- return (0, import_react8.isValidElement)(children) ? (0, import_react8.cloneElement)(
664
+ return (0, import_react9.isValidElement)(children) ? (0, import_react9.cloneElement)(
579
665
  children,
580
666
  void 0,
581
667
  callback(children.props.children)
@@ -653,9 +739,9 @@ var Icon = ({
653
739
  children,
654
740
  ...others
655
741
  }) => {
656
- const child = import_react9.Children.only(children);
742
+ const child = import_react10.Children.only(children);
657
743
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
658
- (0, import_react9.cloneElement)(child, {
744
+ (0, import_react10.cloneElement)(child, {
659
745
  className: iconStyles({ className, size, intent }),
660
746
  "data-spark-component": "icon",
661
747
  "aria-hidden": "true",
@@ -669,7 +755,7 @@ Icon.displayName = "Icon";
669
755
 
670
756
  // src/button/Button.tsx
671
757
  var import_class_variance_authority6 = require("class-variance-authority");
672
- var import_react10 = require("react");
758
+ var import_react11 = require("react");
673
759
 
674
760
  // src/spinner/Spinner.styles.tsx
675
761
  var import_internal_utils2 = require("@spark-ui/internal-utils");
@@ -1474,7 +1560,7 @@ var Button = ({
1474
1560
  }) => {
1475
1561
  const Component = asChild ? Slot : "button";
1476
1562
  const shouldNotInteract = !!disabled || isLoading;
1477
- const disabledEventHandlers = (0, import_react10.useMemo)(() => {
1563
+ const disabledEventHandlers = (0, import_react11.useMemo)(() => {
1478
1564
  const result = {};
1479
1565
  if (shouldNotInteract) {
1480
1566
  blockedEventHandlers.forEach((eventHandler) => result[eventHandler] = void 0);
@@ -1597,7 +1683,7 @@ CarouselNextButton.displayName = "Carousel.NextButton";
1597
1683
 
1598
1684
  // src/carousel/CarouselPageIndicator.tsx
1599
1685
  var import_class_variance_authority8 = require("class-variance-authority");
1600
- var import_react11 = require("react");
1686
+ var import_react12 = require("react");
1601
1687
  var import_jsx_runtime10 = require("react/jsx-runtime");
1602
1688
  var CarouselPageIndicator = ({
1603
1689
  children,
@@ -1608,8 +1694,8 @@ var CarouselPageIndicator = ({
1608
1694
  intent = "basic"
1609
1695
  }) => {
1610
1696
  const ctx = useCarouselContext();
1611
- const ref = (0, import_react11.useRef)(null);
1612
- (0, import_react11.useEffect)(() => {
1697
+ const ref = (0, import_react12.useRef)(null);
1698
+ (0, import_react12.useEffect)(() => {
1613
1699
  if (ctx.pageIndicatorsRefs.current) {
1614
1700
  ctx.pageIndicatorsRefs.current[index] = ref.current;
1615
1701
  }
@@ -1695,27 +1781,22 @@ CarouselPrevButton.displayName = "Carousel.PrevButton";
1695
1781
 
1696
1782
  // src/carousel/CarouselSlide.tsx
1697
1783
  var import_class_variance_authority10 = require("class-variance-authority");
1698
- var import_react13 = require("react");
1784
+ var import_react14 = require("react");
1699
1785
 
1700
1786
  // src/carousel/useIsVisible.ts
1701
- var import_react12 = require("react");
1702
- function useIsVisible(elementRef, parentRef) {
1703
- const [isVisible, setIsVisible] = (0, import_react12.useState)(true);
1704
- (0, import_react12.useLayoutEffect)(() => {
1787
+ var import_react13 = require("react");
1788
+ function useIsVisible(elementRef, _parentRef) {
1789
+ const [isVisible, setIsVisible] = (0, import_react13.useState)(true);
1790
+ const ctx = useCarouselContext();
1791
+ (0, import_react13.useEffect)(() => {
1705
1792
  const el = elementRef.current;
1706
- const parent = parentRef.current;
1707
- if (!parent || !el) return;
1708
- const observer = new IntersectionObserver(
1709
- ([entry]) => {
1710
- if (entry) {
1711
- setIsVisible(entry.isIntersecting);
1712
- }
1713
- },
1714
- { root: parent, threshold: 0.2 }
1715
- );
1716
- observer.observe(el);
1717
- return () => observer.disconnect();
1718
- });
1793
+ if (!el) return;
1794
+ const { registerSlide, unregisterSlide } = ctx;
1795
+ registerSlide(el, setIsVisible);
1796
+ return () => {
1797
+ unregisterSlide(el);
1798
+ };
1799
+ }, [elementRef]);
1719
1800
  return isVisible;
1720
1801
  }
1721
1802
 
@@ -1728,7 +1809,7 @@ var CarouselSlide = ({
1728
1809
  className = "",
1729
1810
  ...props
1730
1811
  }) => {
1731
- const itemRef = (0, import_react13.useRef)(null);
1812
+ const itemRef = (0, import_react14.useRef)(null);
1732
1813
  const ctx = useCarouselContext();
1733
1814
  const isVisible = useIsVisible(itemRef, ctx.ref);
1734
1815
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
@@ -1749,11 +1830,11 @@ CarouselSlide.displayName = "Carousel.Slide";
1749
1830
 
1750
1831
  // src/carousel/CarouselSlides.tsx
1751
1832
  var import_class_variance_authority11 = require("class-variance-authority");
1752
- var import_react14 = require("react");
1833
+ var import_react15 = require("react");
1753
1834
  var import_jsx_runtime14 = require("react/jsx-runtime");
1754
1835
  var CarouselSlides = ({ children, className = "" }) => {
1755
1836
  const ctx = useCarouselContext();
1756
- const childrenElements = import_react14.Children.toArray(children);
1837
+ const childrenElements = import_react15.Children.toArray(children);
1757
1838
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1758
1839
  "div",
1759
1840
  {
@@ -1765,7 +1846,7 @@ var CarouselSlides = ({ children, className = "" }) => {
1765
1846
  className
1766
1847
  ),
1767
1848
  children: childrenElements.map(
1768
- (child, index) => (0, import_react14.isValidElement)(child) ? (0, import_react14.cloneElement)(child, {
1849
+ (child, index) => (0, import_react15.isValidElement)(child) ? (0, import_react15.cloneElement)(child, {
1769
1850
  index,
1770
1851
  totalSlides: childrenElements.length
1771
1852
  }) : child