@expcat/tigercat-react 0.2.10 → 0.2.27

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 (83) hide show
  1. package/dist/{chunk-6DYS4PJT.mjs → chunk-2UVQIL26.mjs} +1 -1
  2. package/dist/chunk-4MMT4EJJ.mjs +78 -0
  3. package/dist/chunk-67EK62HG.mjs +65 -0
  4. package/dist/{chunk-VXHBQTZS.js → chunk-GY6D4XS3.js} +13 -5
  5. package/dist/chunk-GZPMLPRW.js +107 -0
  6. package/dist/{chunk-7JQ7LURS.mjs → chunk-H36CWHUP.mjs} +9 -4
  7. package/dist/chunk-HUZVBDHV.js +81 -0
  8. package/dist/chunk-JOHKSMJM.mjs +266 -0
  9. package/dist/{chunk-WEGU7O4J.mjs → chunk-KOLLAGRK.mjs} +1 -1
  10. package/dist/{chunk-IS7YOBR7.mjs → chunk-NDOYQK2R.mjs} +13 -5
  11. package/dist/{chunk-2DOPHSZP.js → chunk-OWUGXP6K.js} +8 -3
  12. package/dist/chunk-Q2GPRAF4.js +66 -0
  13. package/dist/{chunk-6PUSRC6S.js → chunk-T3GSXTDU.js} +2 -2
  14. package/dist/{chunk-UG3I4PCY.js → chunk-VR5OP4MO.js} +2 -2
  15. package/dist/chunk-X4F6NSI5.mjs +104 -0
  16. package/dist/chunk-Y6557RWE.mjs +62 -0
  17. package/dist/chunk-YIF5VX7K.mjs +158 -0
  18. package/dist/chunk-Z5DDULTA.js +72 -0
  19. package/dist/chunk-Z6G4HABF.js +272 -0
  20. package/dist/chunk-ZPWDDAFE.js +162 -0
  21. package/dist/components/Anchor.d.mts +38 -0
  22. package/dist/components/Anchor.d.ts +38 -0
  23. package/dist/components/Anchor.js +20 -0
  24. package/dist/components/Anchor.mjs +1 -0
  25. package/dist/components/AnchorLink.d.mts +23 -0
  26. package/dist/components/AnchorLink.d.ts +23 -0
  27. package/dist/components/AnchorLink.js +17 -0
  28. package/dist/components/AnchorLink.mjs +2 -0
  29. package/dist/components/AreaChart.js +5 -5
  30. package/dist/components/AreaChart.mjs +3 -3
  31. package/dist/components/BackTop.d.mts +21 -0
  32. package/dist/components/BackTop.d.ts +21 -0
  33. package/dist/components/BackTop.js +16 -0
  34. package/dist/components/BackTop.mjs +1 -0
  35. package/dist/components/BarChart.js +5 -5
  36. package/dist/components/BarChart.mjs +3 -3
  37. package/dist/components/Breadcrumb.d.mts +4 -0
  38. package/dist/components/Breadcrumb.d.ts +4 -0
  39. package/dist/components/Breadcrumb.js +3 -3
  40. package/dist/components/Breadcrumb.mjs +1 -1
  41. package/dist/components/BreadcrumbItem.js +3 -3
  42. package/dist/components/BreadcrumbItem.mjs +2 -2
  43. package/dist/components/Carousel.d.mts +26 -0
  44. package/dist/components/Carousel.d.ts +26 -0
  45. package/dist/components/Carousel.js +10 -0
  46. package/dist/components/Carousel.mjs +1 -0
  47. package/dist/components/Collapse.d.mts +29 -0
  48. package/dist/components/Collapse.d.ts +29 -0
  49. package/dist/components/Collapse.js +20 -0
  50. package/dist/components/Collapse.mjs +1 -0
  51. package/dist/components/CollapsePanel.d.mts +24 -0
  52. package/dist/components/CollapsePanel.d.ts +24 -0
  53. package/dist/components/CollapsePanel.js +17 -0
  54. package/dist/components/CollapsePanel.mjs +2 -0
  55. package/dist/components/DonutChart.js +5 -5
  56. package/dist/components/DonutChart.mjs +3 -3
  57. package/dist/components/LineChart.js +5 -5
  58. package/dist/components/LineChart.mjs +3 -3
  59. package/dist/components/Pagination.js +3 -3
  60. package/dist/components/Pagination.mjs +1 -1
  61. package/dist/components/PieChart.js +4 -4
  62. package/dist/components/PieChart.mjs +2 -2
  63. package/dist/components/RadarChart.js +4 -4
  64. package/dist/components/RadarChart.mjs +2 -2
  65. package/dist/components/ScatterChart.js +5 -5
  66. package/dist/components/ScatterChart.mjs +3 -3
  67. package/dist/index.d.mts +6 -0
  68. package/dist/index.d.ts +6 -0
  69. package/dist/index.js +142 -104
  70. package/dist/index.mjs +34 -28
  71. package/package.json +2 -2
  72. package/dist/{chunk-N32MAX4A.js → chunk-2VXA4YOP.js} +1 -1
  73. package/dist/{chunk-VBSK4TGO.mjs → chunk-2WLSB7K2.mjs} +2 -2
  74. package/dist/{chunk-CBALIFPW.mjs → chunk-324UKFG2.mjs} +2 -2
  75. package/dist/{chunk-YER7IQF4.mjs → chunk-5QKBBGIA.mjs} +1 -1
  76. package/dist/{chunk-OONM7FO7.js → chunk-67WZRMD6.js} +2 -2
  77. package/dist/{chunk-QI6WAP6Y.js → chunk-7SOL3UJ2.js} +2 -2
  78. package/dist/{chunk-KBGURVTD.mjs → chunk-AFFSBNYB.mjs} +2 -2
  79. package/dist/{chunk-LZNG2HGC.mjs → chunk-E6GLWHRL.mjs} +1 -1
  80. package/dist/{chunk-ZUUG3WOL.js → chunk-KKHKQP6Z.js} +1 -1
  81. package/dist/{chunk-EJLJYOO7.js → chunk-LWW2LXCP.js} +2 -2
  82. package/dist/{chunk-A2UW5OKX.mjs → chunk-RKBNIEGF.mjs} +2 -2
  83. package/dist/{chunk-42UKIFFQ.js → chunk-ZYF5GI2Q.js} +2 -2
@@ -1,4 +1,4 @@
1
- import { PieChart } from './chunk-LZNG2HGC.mjs';
1
+ import { PieChart } from './chunk-E6GLWHRL.mjs';
2
2
  import { useMemo } from 'react';
3
3
  import { getChartInnerRect, classNames } from '@expcat/tigercat-core';
4
4
  import { jsx } from 'react/jsx-runtime';
@@ -0,0 +1,78 @@
1
+ import { useState, useCallback, useEffect, useMemo } from 'react';
2
+ import { getScrollTop, scrollToTop, classNames, backTopButtonClasses, backTopContainerClasses, backTopVisibleClasses, backTopHiddenClasses, backTopIconPath } from '@expcat/tigercat-core';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ // src/components/BackTop.tsx
6
+ var DefaultIcon = () => /* @__PURE__ */ jsx(
7
+ "svg",
8
+ {
9
+ xmlns: "http://www.w3.org/2000/svg",
10
+ fill: "none",
11
+ viewBox: "0 0 24 24",
12
+ stroke: "currentColor",
13
+ strokeWidth: 2,
14
+ className: "h-5 w-5",
15
+ "aria-hidden": "true",
16
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: backTopIconPath })
17
+ }
18
+ );
19
+ var BackTop = ({
20
+ visibilityHeight = 400,
21
+ target = () => window,
22
+ duration = 450,
23
+ onClick,
24
+ children,
25
+ className,
26
+ "aria-label": ariaLabel = "Back to top",
27
+ ...props
28
+ }) => {
29
+ const [visible, setVisible] = useState(false);
30
+ const handleScroll = useCallback(() => {
31
+ const targetElement = target();
32
+ if (!targetElement) return;
33
+ const scrollTop = getScrollTop(targetElement);
34
+ setVisible(scrollTop >= visibilityHeight);
35
+ }, [target, visibilityHeight]);
36
+ const handleClick = useCallback(
37
+ (event) => {
38
+ const targetElement = target();
39
+ if (targetElement) {
40
+ scrollToTop(targetElement, duration);
41
+ }
42
+ onClick?.(event);
43
+ },
44
+ [target, duration, onClick]
45
+ );
46
+ useEffect(() => {
47
+ const targetElement = target();
48
+ if (!targetElement) return;
49
+ targetElement.addEventListener("scroll", handleScroll, { passive: true });
50
+ handleScroll();
51
+ return () => {
52
+ targetElement.removeEventListener("scroll", handleScroll);
53
+ };
54
+ }, [target, handleScroll]);
55
+ const buttonClasses = useMemo(() => {
56
+ const targetElement = target();
57
+ const positionClasses = !targetElement || targetElement === window ? backTopButtonClasses : backTopContainerClasses;
58
+ return classNames(
59
+ positionClasses,
60
+ visible ? backTopVisibleClasses : backTopHiddenClasses,
61
+ className
62
+ );
63
+ }, [target, visible, className]);
64
+ return /* @__PURE__ */ jsx(
65
+ "button",
66
+ {
67
+ type: "button",
68
+ className: buttonClasses,
69
+ "aria-label": ariaLabel,
70
+ onClick: handleClick,
71
+ ...props,
72
+ children: children || /* @__PURE__ */ jsx(DefaultIcon, {})
73
+ }
74
+ );
75
+ };
76
+ var BackTop_default = BackTop;
77
+
78
+ export { BackTop, BackTop_default };
@@ -0,0 +1,65 @@
1
+ import { useAnchorContext } from './chunk-YIF5VX7K.mjs';
2
+ import React, { useEffect, useMemo } from 'react';
3
+ import { classNames, getAnchorLinkClasses } from '@expcat/tigercat-core';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var AnchorLink = ({
7
+ href,
8
+ title,
9
+ target,
10
+ className,
11
+ children,
12
+ ...props
13
+ }) => {
14
+ const anchorContext = useAnchorContext();
15
+ useEffect(() => {
16
+ anchorContext?.registerLink(href);
17
+ return () => {
18
+ anchorContext?.unregisterLink(href);
19
+ };
20
+ }, [href, anchorContext]);
21
+ const handleClick = (event) => {
22
+ event.preventDefault();
23
+ anchorContext?.handleLinkClick(href, event);
24
+ };
25
+ const linkClasses = useMemo(() => {
26
+ const isActive = anchorContext?.activeLink === href;
27
+ return classNames(getAnchorLinkClasses(isActive, className));
28
+ }, [anchorContext?.activeLink, href, className]);
29
+ const hasNestedLinks = React.Children.toArray(children).some(
30
+ (child) => React.isValidElement(child) && child.type === AnchorLink
31
+ );
32
+ if (hasNestedLinks) {
33
+ return /* @__PURE__ */ jsxs("div", { className: "anchor-link-wrapper", children: [
34
+ /* @__PURE__ */ jsx(
35
+ "a",
36
+ {
37
+ href,
38
+ target,
39
+ className: linkClasses,
40
+ "data-anchor-href": href,
41
+ onClick: handleClick,
42
+ ...props,
43
+ children: title
44
+ }
45
+ ),
46
+ /* @__PURE__ */ jsx("div", { className: "pl-3 mt-1 space-y-1", children })
47
+ ] });
48
+ }
49
+ const content = children ?? title;
50
+ return /* @__PURE__ */ jsx(
51
+ "a",
52
+ {
53
+ href,
54
+ target,
55
+ className: linkClasses,
56
+ "data-anchor-href": href,
57
+ onClick: handleClick,
58
+ ...props,
59
+ children: content
60
+ }
61
+ );
62
+ };
63
+ var AnchorLink_default = AnchorLink;
64
+
65
+ export { AnchorLink, AnchorLink_default };
@@ -98,6 +98,18 @@ var Pagination = ({
98
98
  },
99
99
  [handleQuickJumperSubmit]
100
100
  );
101
+ const normalizedPageSizeOptions = react.useMemo(() => {
102
+ return pageSizeOptions.map((option) => {
103
+ if (typeof option === "number") {
104
+ return {
105
+ value: option,
106
+ label: `${option} ${labels.itemsPerPageText}`
107
+ };
108
+ }
109
+ const label = option.label ?? `${option.value} ${labels.itemsPerPageText}`;
110
+ return { value: option.value, label };
111
+ });
112
+ }, [pageSizeOptions, labels.itemsPerPageText]);
101
113
  const containerClasses = tigercatCore.getPaginationContainerClasses(align, className);
102
114
  const elements = [];
103
115
  if (showTotal) {
@@ -233,11 +245,7 @@ var Pagination = ({
233
245
  value: currentPageSize,
234
246
  onChange: (e) => handlePageSizeChange(parseInt(e.target.value, 10)),
235
247
  "aria-label": labels.itemsPerPageText,
236
- children: pageSizeOptions.map((sizeOption) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: sizeOption, children: [
237
- sizeOption,
238
- " ",
239
- labels.itemsPerPageText
240
- ] }, sizeOption))
248
+ children: normalizedPageSizeOptions.map((sizeOption) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: sizeOption.value, children: sizeOption.label }, sizeOption.value))
241
249
  },
242
250
  "size-changer"
243
251
  )
@@ -0,0 +1,107 @@
1
+ 'use strict';
2
+
3
+ var chunkQ2GPRAF4_js = require('./chunk-Q2GPRAF4.js');
4
+ var react = require('react');
5
+ var tigercatCore = require('@expcat/tigercat-core');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ var CollapsePanel = ({
9
+ panelKey,
10
+ header,
11
+ disabled = false,
12
+ showArrow = true,
13
+ className,
14
+ style,
15
+ extra,
16
+ children
17
+ }) => {
18
+ const collapseContext = chunkQ2GPRAF4_js.useCollapseContext();
19
+ if (!collapseContext) {
20
+ throw new Error("CollapsePanel must be used within a Collapse component");
21
+ }
22
+ const isActive = react.useMemo(() => {
23
+ return tigercatCore.isPanelActive(panelKey, collapseContext.activeKeys);
24
+ }, [panelKey, collapseContext.activeKeys]);
25
+ const panelClasses = react.useMemo(() => {
26
+ return tigercatCore.classNames(tigercatCore.getCollapsePanelClasses(collapseContext.ghost, className));
27
+ }, [collapseContext.ghost, className]);
28
+ const headerClasses = react.useMemo(() => {
29
+ return tigercatCore.getCollapsePanelHeaderClasses(isActive, disabled);
30
+ }, [isActive, disabled]);
31
+ const iconClasses = react.useMemo(() => {
32
+ return tigercatCore.getCollapseIconClasses(isActive, collapseContext.expandIconPosition);
33
+ }, [isActive, collapseContext.expandIconPosition]);
34
+ const handleClick = react.useCallback(() => {
35
+ if (!disabled) {
36
+ collapseContext.handlePanelClick(panelKey);
37
+ }
38
+ }, [disabled, collapseContext, panelKey]);
39
+ const handleKeyDown = react.useCallback(
40
+ (event) => {
41
+ if (disabled) {
42
+ return;
43
+ }
44
+ if (event.key === "Enter" || event.key === " ") {
45
+ event.preventDefault();
46
+ collapseContext.handlePanelClick(panelKey);
47
+ }
48
+ },
49
+ [disabled, collapseContext, panelKey]
50
+ );
51
+ const arrowIcon = /* @__PURE__ */ jsxRuntime.jsx(
52
+ "svg",
53
+ {
54
+ className: iconClasses,
55
+ width: "16",
56
+ height: "16",
57
+ viewBox: "0 0 16 16",
58
+ fill: "none",
59
+ xmlns: "http://www.w3.org/2000/svg",
60
+ children: /* @__PURE__ */ jsxRuntime.jsx(
61
+ "path",
62
+ {
63
+ d: "M6 12L10 8L6 4",
64
+ stroke: "currentColor",
65
+ strokeWidth: "2",
66
+ strokeLinecap: "round",
67
+ strokeLinejoin: "round"
68
+ }
69
+ )
70
+ }
71
+ );
72
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: panelClasses, style, children: [
73
+ /* @__PURE__ */ jsxRuntime.jsxs(
74
+ "div",
75
+ {
76
+ className: headerClasses,
77
+ role: "button",
78
+ tabIndex: disabled ? -1 : 0,
79
+ "aria-expanded": isActive,
80
+ "aria-disabled": disabled,
81
+ onClick: handleClick,
82
+ onKeyDown: handleKeyDown,
83
+ children: [
84
+ showArrow && collapseContext.expandIconPosition === "start" && arrowIcon,
85
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: tigercatCore.collapseHeaderTextClasses, children: header }),
86
+ extra && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto", children: extra }),
87
+ showArrow && collapseContext.expandIconPosition === "end" && arrowIcon
88
+ ]
89
+ }
90
+ ),
91
+ /* @__PURE__ */ jsxRuntime.jsx(
92
+ "div",
93
+ {
94
+ className: tigercatCore.collapsePanelContentWrapperClasses,
95
+ style: {
96
+ maxHeight: isActive ? "none" : "0",
97
+ opacity: isActive ? "1" : "0"
98
+ },
99
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: tigercatCore.collapsePanelContentBaseClasses, children })
100
+ }
101
+ )
102
+ ] });
103
+ };
104
+ var CollapsePanel_default = CollapsePanel;
105
+
106
+ exports.CollapsePanel = CollapsePanel;
107
+ exports.CollapsePanel_default = CollapsePanel_default;
@@ -1,6 +1,6 @@
1
1
  import React, { createContext, useContext } from 'react';
2
2
  import { classNames, breadcrumbContainerClasses } from '@expcat/tigercat-core';
3
- import { jsx } from 'react/jsx-runtime';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
4
 
5
5
  // src/components/Breadcrumb.tsx
6
6
  var BreadcrumbContext = createContext(null);
@@ -11,15 +11,20 @@ var Breadcrumb = ({
11
11
  separator = "/",
12
12
  className,
13
13
  style,
14
+ extra,
14
15
  children,
15
16
  ...props
16
17
  }) => {
18
+ const hasExtra = Boolean(extra);
17
19
  const containerClasses = React.useMemo(
18
- () => classNames(breadcrumbContainerClasses, className),
19
- [className]
20
+ () => classNames(breadcrumbContainerClasses, hasExtra && "w-full", className),
21
+ [className, hasExtra]
20
22
  );
21
23
  const contextValue = React.useMemo(() => ({ separator }), [separator]);
22
- return /* @__PURE__ */ jsx(BreadcrumbContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("nav", { className: containerClasses, "aria-label": "Breadcrumb", style, ...props, children: /* @__PURE__ */ jsx("ol", { className: "flex items-center flex-wrap gap-2", children }) }) });
24
+ return /* @__PURE__ */ jsx(BreadcrumbContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs("nav", { className: containerClasses, "aria-label": "Breadcrumb", style, ...props, children: [
25
+ /* @__PURE__ */ jsx("ol", { className: "flex items-center flex-wrap gap-2", children }),
26
+ hasExtra && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center", children: extra })
27
+ ] }) });
23
28
  };
24
29
 
25
30
  export { Breadcrumb, useBreadcrumbContext };
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var tigercatCore = require('@expcat/tigercat-core');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ // src/components/BackTop.tsx
8
+ var DefaultIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
9
+ "svg",
10
+ {
11
+ xmlns: "http://www.w3.org/2000/svg",
12
+ fill: "none",
13
+ viewBox: "0 0 24 24",
14
+ stroke: "currentColor",
15
+ strokeWidth: 2,
16
+ className: "h-5 w-5",
17
+ "aria-hidden": "true",
18
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: tigercatCore.backTopIconPath })
19
+ }
20
+ );
21
+ var BackTop = ({
22
+ visibilityHeight = 400,
23
+ target = () => window,
24
+ duration = 450,
25
+ onClick,
26
+ children,
27
+ className,
28
+ "aria-label": ariaLabel = "Back to top",
29
+ ...props
30
+ }) => {
31
+ const [visible, setVisible] = react.useState(false);
32
+ const handleScroll = react.useCallback(() => {
33
+ const targetElement = target();
34
+ if (!targetElement) return;
35
+ const scrollTop = tigercatCore.getScrollTop(targetElement);
36
+ setVisible(scrollTop >= visibilityHeight);
37
+ }, [target, visibilityHeight]);
38
+ const handleClick = react.useCallback(
39
+ (event) => {
40
+ const targetElement = target();
41
+ if (targetElement) {
42
+ tigercatCore.scrollToTop(targetElement, duration);
43
+ }
44
+ onClick?.(event);
45
+ },
46
+ [target, duration, onClick]
47
+ );
48
+ react.useEffect(() => {
49
+ const targetElement = target();
50
+ if (!targetElement) return;
51
+ targetElement.addEventListener("scroll", handleScroll, { passive: true });
52
+ handleScroll();
53
+ return () => {
54
+ targetElement.removeEventListener("scroll", handleScroll);
55
+ };
56
+ }, [target, handleScroll]);
57
+ const buttonClasses = react.useMemo(() => {
58
+ const targetElement = target();
59
+ const positionClasses = !targetElement || targetElement === window ? tigercatCore.backTopButtonClasses : tigercatCore.backTopContainerClasses;
60
+ return tigercatCore.classNames(
61
+ positionClasses,
62
+ visible ? tigercatCore.backTopVisibleClasses : tigercatCore.backTopHiddenClasses,
63
+ className
64
+ );
65
+ }, [target, visible, className]);
66
+ return /* @__PURE__ */ jsxRuntime.jsx(
67
+ "button",
68
+ {
69
+ type: "button",
70
+ className: buttonClasses,
71
+ "aria-label": ariaLabel,
72
+ onClick: handleClick,
73
+ ...props,
74
+ children: children || /* @__PURE__ */ jsxRuntime.jsx(DefaultIcon, {})
75
+ }
76
+ );
77
+ };
78
+ var BackTop_default = BackTop;
79
+
80
+ exports.BackTop = BackTop;
81
+ exports.BackTop_default = BackTop_default;
@@ -0,0 +1,266 @@
1
+ import React, { forwardRef, useState, useRef, useMemo, useCallback, useImperativeHandle, useEffect } from 'react';
2
+ import { classNames, getCarouselContainerClasses, carouselTrackFadeClasses, carouselTrackScrollClasses, getScrollTransform, carouselSlideBaseClasses, getCarouselDotsClasses, clampSlideIndex, getNextSlideIndex, getPrevSlideIndex, isPrevDisabled, isNextDisabled, getCarouselArrowClasses, carouselPrevArrowPath, carouselNextArrowPath, getCarouselDotClasses } from '@expcat/tigercat-core';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+
5
+ // src/components/Carousel.tsx
6
+ var Carousel = forwardRef(
7
+ ({
8
+ autoplay = false,
9
+ autoplaySpeed = 3e3,
10
+ dots = true,
11
+ dotPosition = "bottom",
12
+ effect = "scroll",
13
+ arrows = false,
14
+ infinite = true,
15
+ speed = 500,
16
+ initialSlide = 0,
17
+ pauseOnHover = true,
18
+ pauseOnFocus = true,
19
+ className,
20
+ style,
21
+ onChange,
22
+ onBeforeChange,
23
+ children
24
+ }, ref) => {
25
+ const [currentIndex, setCurrentIndex] = useState(initialSlide);
26
+ const [isPaused, setIsPaused] = useState(false);
27
+ const autoplayTimerRef = useRef(null);
28
+ const slides = useMemo(() => {
29
+ return React.Children.toArray(children).filter((child) => React.isValidElement(child));
30
+ }, [children]);
31
+ const slideCount = slides.length;
32
+ const containerClasses = useMemo(
33
+ () => classNames(getCarouselContainerClasses(className)),
34
+ [className]
35
+ );
36
+ const trackClasses = useMemo(() => {
37
+ if (effect === "fade") {
38
+ return carouselTrackFadeClasses;
39
+ }
40
+ return carouselTrackScrollClasses;
41
+ }, [effect]);
42
+ const trackStyle = useMemo(() => {
43
+ if (effect === "scroll") {
44
+ return {
45
+ transform: getScrollTransform(currentIndex),
46
+ transitionDuration: `${speed}ms`
47
+ };
48
+ }
49
+ return {};
50
+ }, [effect, currentIndex, speed]);
51
+ const getSlideClasses = useCallback(
52
+ (index) => {
53
+ const isActive = index === currentIndex;
54
+ if (effect === "fade") {
55
+ const positionClass = index === 0 ? "relative" : "absolute inset-0";
56
+ return classNames(
57
+ positionClass,
58
+ "w-full transition-opacity ease-in-out",
59
+ isActive ? "opacity-100 z-10" : "opacity-0 z-0"
60
+ );
61
+ }
62
+ return carouselSlideBaseClasses;
63
+ },
64
+ [effect, currentIndex]
65
+ );
66
+ const getSlideStyle = useCallback(() => {
67
+ return {
68
+ transitionDuration: `${speed}ms`
69
+ };
70
+ }, [speed]);
71
+ const dotsClasses = useMemo(() => {
72
+ return getCarouselDotsClasses(dotPosition);
73
+ }, [dotPosition]);
74
+ const goTo = useCallback(
75
+ (index) => {
76
+ const clampedIndex = clampSlideIndex(index, slideCount);
77
+ if (clampedIndex === currentIndex) return;
78
+ onBeforeChange?.(currentIndex, clampedIndex);
79
+ const prevIndex = currentIndex;
80
+ setCurrentIndex(clampedIndex);
81
+ onChange?.(clampedIndex, prevIndex);
82
+ },
83
+ [currentIndex, slideCount, onBeforeChange, onChange]
84
+ );
85
+ const next = useCallback(() => {
86
+ const nextIdx = getNextSlideIndex(currentIndex, slideCount, infinite);
87
+ if (nextIdx !== currentIndex) {
88
+ goTo(nextIdx);
89
+ }
90
+ }, [currentIndex, slideCount, infinite, goTo]);
91
+ const prev = useCallback(() => {
92
+ const prevIdx = getPrevSlideIndex(currentIndex, slideCount, infinite);
93
+ if (prevIdx !== currentIndex) {
94
+ goTo(prevIdx);
95
+ }
96
+ }, [currentIndex, slideCount, infinite, goTo]);
97
+ useImperativeHandle(
98
+ ref,
99
+ () => ({
100
+ next,
101
+ prev,
102
+ goTo
103
+ }),
104
+ [next, prev, goTo]
105
+ );
106
+ useEffect(() => {
107
+ if (autoplay && !isPaused) {
108
+ if (autoplayTimerRef.current) {
109
+ clearInterval(autoplayTimerRef.current);
110
+ }
111
+ autoplayTimerRef.current = setInterval(() => {
112
+ setCurrentIndex((prevIndex) => {
113
+ const nextIdx = getNextSlideIndex(prevIndex, slideCount, infinite);
114
+ if (nextIdx !== prevIndex) {
115
+ onBeforeChange?.(prevIndex, nextIdx);
116
+ onChange?.(nextIdx, prevIndex);
117
+ }
118
+ return nextIdx;
119
+ });
120
+ }, autoplaySpeed);
121
+ }
122
+ return () => {
123
+ if (autoplayTimerRef.current) {
124
+ clearInterval(autoplayTimerRef.current);
125
+ autoplayTimerRef.current = null;
126
+ }
127
+ };
128
+ }, [autoplay, autoplaySpeed, isPaused, slideCount, infinite, onChange, onBeforeChange]);
129
+ const handleMouseEnter = useCallback(() => {
130
+ if (pauseOnHover && autoplay) {
131
+ setIsPaused(true);
132
+ }
133
+ }, [pauseOnHover, autoplay]);
134
+ const handleMouseLeave = useCallback(() => {
135
+ if (pauseOnHover && autoplay) {
136
+ setIsPaused(false);
137
+ }
138
+ }, [pauseOnHover, autoplay]);
139
+ const handleFocus = useCallback(() => {
140
+ if (pauseOnFocus && autoplay) {
141
+ setIsPaused(true);
142
+ }
143
+ }, [pauseOnFocus, autoplay]);
144
+ const handleBlur = useCallback(() => {
145
+ if (pauseOnFocus && autoplay) {
146
+ setIsPaused(false);
147
+ }
148
+ }, [pauseOnFocus, autoplay]);
149
+ const isPrevArrowDisabled = useMemo(
150
+ () => isPrevDisabled(currentIndex, slideCount, infinite),
151
+ [currentIndex, slideCount, infinite]
152
+ );
153
+ const isNextArrowDisabled = useMemo(
154
+ () => isNextDisabled(currentIndex, slideCount, infinite),
155
+ [currentIndex, slideCount, infinite]
156
+ );
157
+ const renderArrows = () => {
158
+ if (!arrows) return null;
159
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
160
+ /* @__PURE__ */ jsx(
161
+ "button",
162
+ {
163
+ type: "button",
164
+ className: getCarouselArrowClasses("prev", isPrevArrowDisabled),
165
+ onClick: prev,
166
+ disabled: isPrevArrowDisabled,
167
+ "aria-label": "Previous slide",
168
+ children: /* @__PURE__ */ jsx(
169
+ "svg",
170
+ {
171
+ xmlns: "http://www.w3.org/2000/svg",
172
+ viewBox: "0 0 24 24",
173
+ fill: "none",
174
+ stroke: "currentColor",
175
+ strokeWidth: "2",
176
+ strokeLinecap: "round",
177
+ strokeLinejoin: "round",
178
+ className: "w-6 h-6",
179
+ children: /* @__PURE__ */ jsx("path", { d: carouselPrevArrowPath })
180
+ }
181
+ )
182
+ }
183
+ ),
184
+ /* @__PURE__ */ jsx(
185
+ "button",
186
+ {
187
+ type: "button",
188
+ className: getCarouselArrowClasses("next", isNextArrowDisabled),
189
+ onClick: next,
190
+ disabled: isNextArrowDisabled,
191
+ "aria-label": "Next slide",
192
+ children: /* @__PURE__ */ jsx(
193
+ "svg",
194
+ {
195
+ xmlns: "http://www.w3.org/2000/svg",
196
+ viewBox: "0 0 24 24",
197
+ fill: "none",
198
+ stroke: "currentColor",
199
+ strokeWidth: "2",
200
+ strokeLinecap: "round",
201
+ strokeLinejoin: "round",
202
+ className: "w-6 h-6",
203
+ children: /* @__PURE__ */ jsx("path", { d: carouselNextArrowPath })
204
+ }
205
+ )
206
+ }
207
+ )
208
+ ] });
209
+ };
210
+ const renderDots = () => {
211
+ if (!dots || slideCount <= 1) return null;
212
+ return /* @__PURE__ */ jsx("div", { className: dotsClasses, role: "tablist", "aria-label": "Carousel navigation", children: slides.map((_, index) => /* @__PURE__ */ jsx(
213
+ "button",
214
+ {
215
+ type: "button",
216
+ className: getCarouselDotClasses(index === currentIndex),
217
+ onClick: () => goTo(index),
218
+ "aria-label": `Go to slide ${index + 1}`,
219
+ "aria-current": index === currentIndex ? "true" : "false"
220
+ },
221
+ index
222
+ )) });
223
+ };
224
+ const renderSlides = () => {
225
+ const slideElements = slides.map((slide, index) => /* @__PURE__ */ jsx(
226
+ "div",
227
+ {
228
+ className: getSlideClasses(index),
229
+ style: effect === "fade" ? getSlideStyle() : void 0,
230
+ role: "group",
231
+ "aria-roledescription": "slide",
232
+ "aria-label": `Slide ${index + 1} of ${slideCount}`,
233
+ "aria-hidden": index !== currentIndex,
234
+ children: slide
235
+ },
236
+ index
237
+ ));
238
+ if (effect === "fade") {
239
+ return /* @__PURE__ */ jsx("div", { className: classNames(trackClasses, "h-full"), children: slideElements });
240
+ }
241
+ return /* @__PURE__ */ jsx("div", { className: trackClasses, style: trackStyle, children: slideElements });
242
+ };
243
+ return /* @__PURE__ */ jsxs(
244
+ "div",
245
+ {
246
+ className: containerClasses,
247
+ style,
248
+ role: "region",
249
+ "aria-roledescription": "carousel",
250
+ "aria-label": "Image carousel",
251
+ onMouseEnter: handleMouseEnter,
252
+ onMouseLeave: handleMouseLeave,
253
+ onFocus: handleFocus,
254
+ onBlur: handleBlur,
255
+ children: [
256
+ renderSlides(),
257
+ renderArrows(),
258
+ renderDots()
259
+ ]
260
+ }
261
+ );
262
+ }
263
+ );
264
+ Carousel.displayName = "Carousel";
265
+
266
+ export { Carousel };
@@ -1,4 +1,4 @@
1
- import { useBreadcrumbContext } from './chunk-7JQ7LURS.mjs';
1
+ import { useBreadcrumbContext } from './chunk-H36CWHUP.mjs';
2
2
  import { useMemo, useCallback } from 'react';
3
3
  import { getBreadcrumbItemClasses, getBreadcrumbLinkClasses, getBreadcrumbSeparatorClasses, getSeparatorContent } from '@expcat/tigercat-core';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';