deepsea-components 2.8.5 → 3.0.1

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 (108) hide show
  1. package/dist/cjs/components/AutoFit.d.ts +25 -0
  2. package/dist/cjs/components/AutoFit.js +99 -0
  3. package/dist/cjs/components/AutoFit.js.map +7 -0
  4. package/dist/cjs/components/AutoScroll.js.map +2 -2
  5. package/dist/cjs/components/AutoSizeTextarea.d.ts +5 -0
  6. package/dist/cjs/components/AutoSizeTextarea.js +51 -0
  7. package/dist/cjs/components/AutoSizeTextarea.js.map +7 -0
  8. package/dist/cjs/components/CircleText.d.ts +25 -0
  9. package/dist/cjs/components/CircleText.js +48 -0
  10. package/dist/cjs/components/CircleText.js.map +7 -0
  11. package/dist/cjs/components/Flow.d.ts +57 -0
  12. package/dist/cjs/components/Flow.js +119 -0
  13. package/dist/cjs/components/Flow.js.map +7 -0
  14. package/dist/cjs/components/HlsPlayer.d.ts +6 -0
  15. package/dist/cjs/components/HlsPlayer.js +64 -0
  16. package/dist/cjs/components/HlsPlayer.js.map +7 -0
  17. package/dist/cjs/components/InputFile.d.ts +64 -0
  18. package/dist/cjs/components/InputFile.js +143 -0
  19. package/dist/cjs/components/InputFile.js.map +7 -0
  20. package/dist/cjs/components/LoopSwiper.d.ts +9 -0
  21. package/dist/cjs/components/LoopSwiper.js +116 -0
  22. package/dist/cjs/components/LoopSwiper.js.map +7 -0
  23. package/dist/cjs/components/Ring.d.ts +7 -0
  24. package/dist/cjs/components/Ring.js +37 -0
  25. package/dist/cjs/components/Ring.js.map +7 -0
  26. package/dist/cjs/components/Scroll.js.map +2 -2
  27. package/dist/cjs/components/SectionRing.d.ts +8 -0
  28. package/dist/cjs/components/SectionRing.js +50 -0
  29. package/dist/cjs/components/SectionRing.js.map +7 -0
  30. package/dist/cjs/components/Skeleton.d.ts +3 -0
  31. package/dist/cjs/components/Skeleton.js +61 -0
  32. package/dist/cjs/components/Skeleton.js.map +7 -0
  33. package/dist/cjs/components/TransitionBox.d.ts +10 -0
  34. package/dist/cjs/components/TransitionBox.js +45 -0
  35. package/dist/cjs/components/TransitionBox.js.map +7 -0
  36. package/dist/cjs/components/TransitionNum.d.ts +16 -0
  37. package/dist/cjs/components/TransitionNum.js +62 -0
  38. package/dist/cjs/components/TransitionNum.js.map +7 -0
  39. package/dist/cjs/components/Trapezium.d.ts +9 -0
  40. package/dist/cjs/components/Trapezium.js +44 -0
  41. package/dist/cjs/components/Trapezium.js.map +7 -0
  42. package/dist/cjs/index.d.ts +14 -265
  43. package/dist/cjs/index.js +28 -505
  44. package/dist/cjs/index.js.map +3 -3
  45. package/dist/esm/components/AutoFit.d.ts +25 -0
  46. package/dist/esm/components/AutoFit.js +87 -0
  47. package/dist/esm/components/AutoFit.js.map +1 -0
  48. package/dist/esm/components/AutoScroll.js.map +1 -1
  49. package/dist/esm/components/AutoSizeTextarea.d.ts +5 -0
  50. package/dist/esm/components/AutoSizeTextarea.js +45 -0
  51. package/dist/esm/components/AutoSizeTextarea.js.map +1 -0
  52. package/dist/esm/components/CircleText.d.ts +25 -0
  53. package/dist/esm/components/CircleText.js +49 -0
  54. package/dist/esm/components/CircleText.js.map +1 -0
  55. package/dist/esm/components/Flow.d.ts +57 -0
  56. package/dist/esm/components/Flow.js +130 -0
  57. package/dist/esm/components/Flow.js.map +1 -0
  58. package/dist/esm/components/HlsPlayer.d.ts +6 -0
  59. package/dist/esm/components/HlsPlayer.js +39 -0
  60. package/dist/esm/components/HlsPlayer.js.map +1 -0
  61. package/dist/esm/components/InputFile.d.ts +64 -0
  62. package/dist/esm/components/InputFile.js +167 -0
  63. package/dist/esm/components/InputFile.js.map +1 -0
  64. package/dist/esm/components/LoopSwiper.d.ts +9 -0
  65. package/dist/esm/components/LoopSwiper.js +122 -0
  66. package/dist/esm/components/LoopSwiper.js.map +1 -0
  67. package/dist/esm/components/Ring.d.ts +7 -0
  68. package/dist/esm/components/Ring.js +26 -0
  69. package/dist/esm/components/Ring.js.map +1 -0
  70. package/dist/esm/components/Scroll.js.map +1 -1
  71. package/dist/esm/components/SectionRing.d.ts +8 -0
  72. package/dist/esm/components/SectionRing.js +31 -0
  73. package/dist/esm/components/SectionRing.js.map +1 -0
  74. package/dist/esm/components/Skeleton.d.ts +3 -0
  75. package/dist/esm/components/Skeleton.js +36 -0
  76. package/dist/esm/components/Skeleton.js.map +1 -0
  77. package/dist/esm/components/TransitionBox.d.ts +10 -0
  78. package/dist/esm/components/TransitionBox.js +50 -0
  79. package/dist/esm/components/TransitionBox.js.map +1 -0
  80. package/dist/esm/components/TransitionNum.d.ts +16 -0
  81. package/dist/esm/components/TransitionNum.js +65 -0
  82. package/dist/esm/components/TransitionNum.js.map +1 -0
  83. package/dist/esm/components/Trapezium.d.ts +9 -0
  84. package/dist/esm/components/Trapezium.js +35 -0
  85. package/dist/esm/components/Trapezium.js.map +1 -0
  86. package/dist/esm/index.d.ts +14 -265
  87. package/dist/esm/index.js +14 -843
  88. package/dist/esm/index.js.map +1 -1
  89. package/package.json +4 -3
  90. package/src/components/AutoFit.tsx +95 -0
  91. package/src/components/AutoScroll.tsx +1 -0
  92. package/src/components/AutoSizeTextarea.tsx +31 -0
  93. package/src/components/CircleText.tsx +56 -0
  94. package/src/components/Flow.tsx +154 -0
  95. package/src/components/HlsPlayer.tsx +38 -0
  96. package/src/components/InputFile.tsx +193 -0
  97. package/src/components/LoopSwiper.tsx +101 -0
  98. package/src/components/Ring.tsx +19 -0
  99. package/src/components/Scroll.tsx +1 -0
  100. package/src/components/SectionRing.tsx +36 -0
  101. package/src/components/Skeleton.tsx +39 -0
  102. package/src/components/TransitionBox.tsx +36 -0
  103. package/src/components/TransitionNum.tsx +54 -0
  104. package/src/components/Trapezium.tsx +35 -0
  105. package/src/index.tsx +14 -862
  106. package/dist/cjs/skeleton.css +0 -18
  107. package/dist/esm/skeleton.css +0 -18
  108. package/src/skeleton.css +0 -18
@@ -0,0 +1,130 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ export function getGapRange(gap) {
6
+ if (typeof gap === "number") return [gap, gap];
7
+ if (Array.isArray(gap)) return [gap[0] || 0, gap[1]];
8
+ return [0, null];
9
+ }
10
+ export function getGapCountAndSize(width, itemWidth, minGap, maxGap) {
11
+ const count = Math.floor((width + minGap) / (itemWidth + minGap)) || 1;
12
+ if (count === 1) return [count, 0];
13
+ const averageGap = (width - itemWidth * count) / (count - 1);
14
+ if (averageGap < minGap) return [count, minGap];
15
+ if (maxGap !== null && averageGap > maxGap) return [count, maxGap];
16
+ return [count, averageGap];
17
+ }
18
+ /** 自适应浮动组件 */
19
+ export function Flow(props) {
20
+ const {
21
+ itemWidth,
22
+ itemHeight,
23
+ columnGap,
24
+ rowGap = 0,
25
+ maxRows,
26
+ data,
27
+ render,
28
+ keyExactor,
29
+ className,
30
+ style,
31
+ containerClassName,
32
+ containerStyle,
33
+ throttle,
34
+ transitionDuration,
35
+ onSizeChange,
36
+ ...rest
37
+ } = props;
38
+ const [minColumnGap, maxColumnGap] = getGapRange(columnGap);
39
+ const [width, setWidth] = useState(0);
40
+ const [columnCount, setColumnCount] = useState(1);
41
+ const [columnGapSize, setColumnGapSize] = useState(minColumnGap);
42
+ const [showItems, setShowItems] = useState(false);
43
+ const ele = useRef(null);
44
+ const contentRows = Math.ceil(data.length / columnCount);
45
+ const contentShownRows = typeof maxRows === "number" ? Math.min(contentRows, maxRows) : contentRows;
46
+ const height = contentShownRows > 0 ? contentShownRows * (itemHeight + rowGap) - rowGap : 0;
47
+ function getPosition(index) {
48
+ const y = Math.floor(index / columnCount);
49
+ const x = index - y * columnCount;
50
+ return {
51
+ left: x * (itemWidth + columnGapSize),
52
+ top: y * (itemHeight + rowGap)
53
+ };
54
+ }
55
+ function getHidden(index) {
56
+ if (typeof maxRows !== "number") return false;
57
+ return index >= maxRows * columnCount;
58
+ }
59
+ useEffect(() => {
60
+ let timeout;
61
+ const observer = new ResizeObserver(entries => {
62
+ clearTimeout(timeout);
63
+ function task() {
64
+ const {
65
+ width
66
+ } = entries[0].contentRect;
67
+ const [newColumnCount, newColumnGapSize] = getGapCountAndSize(width, itemWidth, minColumnGap, maxColumnGap);
68
+ setShowItems(true);
69
+ setWidth(width);
70
+ setColumnCount(newColumnCount);
71
+ setColumnGapSize(newColumnGapSize);
72
+ }
73
+ if (throttle === null) {
74
+ task();
75
+ } else {
76
+ timeout = window.setTimeout(task, throttle || 200);
77
+ }
78
+ });
79
+ observer.observe(ele.current);
80
+ return () => {
81
+ observer.disconnect();
82
+ };
83
+ }, [itemWidth, throttle, columnGap]);
84
+ useEffect(() => {
85
+ onSizeChange?.({
86
+ width,
87
+ height,
88
+ itemWidth,
89
+ itemHeight,
90
+ columnGap: columnGapSize,
91
+ columnCount,
92
+ rowGap,
93
+ rowCount: contentShownRows,
94
+ overflow: data.length > contentShownRows * columnCount,
95
+ itemCount: data.length,
96
+ maxRows: maxRows ?? null
97
+ });
98
+ }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows]);
99
+ return /*#__PURE__*/_jsx("div", {
100
+ ref: ele,
101
+ className: className,
102
+ style: {
103
+ position: "relative",
104
+ boxSizing: "border-box",
105
+ height,
106
+ ...style
107
+ },
108
+ ...rest,
109
+ children: showItems && data.map((item, index) => /*#__PURE__*/_jsx("div", {
110
+ className: containerClassName,
111
+ style: {
112
+ position: "absolute",
113
+ width: itemWidth,
114
+ height: itemHeight,
115
+ transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : undefined,
116
+ ...getPosition(index)
117
+ },
118
+ children: /*#__PURE__*/_jsx("div", {
119
+ style: {
120
+ width: itemWidth,
121
+ height: itemHeight,
122
+ display: maxRows && index >= maxRows * columnCount ? "none" : "block",
123
+ ...containerStyle
124
+ },
125
+ children: render(item, index, getHidden(index))
126
+ })
127
+ }, keyExactor ? keyExactor(item, index) : index))
128
+ });
129
+ }
130
+ //# sourceMappingURL=Flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useEffect","useRef","useState","jsx","_jsx","getGapRange","gap","Array","isArray","getGapCountAndSize","width","itemWidth","minGap","maxGap","count","Math","floor","averageGap","Flow","props","itemHeight","columnGap","rowGap","maxRows","data","render","keyExactor","className","style","containerClassName","containerStyle","throttle","transitionDuration","onSizeChange","rest","minColumnGap","maxColumnGap","setWidth","columnCount","setColumnCount","columnGapSize","setColumnGapSize","showItems","setShowItems","ele","contentRows","ceil","length","contentShownRows","min","height","getPosition","index","y","x","left","top","getHidden","timeout","observer","ResizeObserver","entries","clearTimeout","task","contentRect","newColumnCount","newColumnGapSize","window","setTimeout","observe","current","disconnect","rowCount","overflow","itemCount","ref","position","boxSizing","children","map","item","transition","undefined","display"],"sources":["../../../src/components/Flow.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { CSSProperties, HTMLAttributes, ReactNode, useEffect, useRef, useState } from \"react\"\r\n\r\nexport interface FlowSizeData {\r\n /** 容器宽度 */\r\n width: number\r\n /** 容器高度 */\r\n height: number\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap: number\r\n /** 列数 */\r\n columnCount: number\r\n /** 行间距 */\r\n rowGap: number\r\n /** 行数 */\r\n rowCount: number\r\n /** 元素格数 */\r\n itemCount: number\r\n /** 最大行数 */\r\n maxRows: number | null\r\n /** 是否有元素被隐藏 */\r\n overflow: boolean\r\n}\r\n\r\nexport interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\r\n /** 元素宽度 */\r\n itemWidth: number\r\n /** 元素高度 */\r\n itemHeight: number\r\n /** 列间距 */\r\n columnGap?: number | null | (number | null)[]\r\n /** 行间距 */\r\n rowGap?: number\r\n /** 最大行数 */\r\n maxRows?: number | null\r\n /** 源数据 */\r\n data: T[]\r\n /** 渲染 */\r\n render: (item: T, index: number, hidden: boolean) => ReactNode\r\n /** key释放器,默认为 index */\r\n keyExactor?: (item: T, index: number) => string | number\r\n /** 容器类名 */\r\n containerClassName?: string\r\n /** 容器样式 */\r\n containerStyle?: CSSProperties\r\n /** 节流时间,单位毫秒,默认200ms,传入 null 不节流 */\r\n throttle?: number | null\r\n /** 动画时间,单位毫秒,默认400ms,传入 null 不展示动画 */\r\n transitionDuration?: number | null\r\n /** 变化的回调函数 */\r\n onSizeChange?: (sizeData: FlowSizeData) => void\r\n}\r\n\r\nexport function getGapRange(gap?: undefined | number | null | (number | null)[]): [number, number | null] {\r\n if (typeof gap === \"number\") return [gap, gap]\r\n if (Array.isArray(gap)) return [gap[0] || 0, gap[1]]\r\n return [0, null]\r\n}\r\n\r\nexport function getGapCountAndSize(width: number, itemWidth: number, minGap: number, maxGap: number | null): [number, number] {\r\n const count = Math.floor((width + minGap) / (itemWidth + minGap)) || 1\r\n if (count === 1) return [count, 0]\r\n const averageGap = (width - itemWidth * count) / (count - 1)\r\n if (averageGap < minGap) return [count, minGap]\r\n if (maxGap !== null && averageGap > maxGap) return [count, maxGap]\r\n return [count, averageGap]\r\n}\r\n\r\ninterface Position {\r\n left: number\r\n top: number\r\n}\r\n\r\n/** 自适应浮动组件 */\r\nexport function Flow<T>(props: FlowProps<T>) {\r\n const { itemWidth, itemHeight, columnGap, rowGap = 0, maxRows, data, render, keyExactor, className, style, containerClassName, containerStyle, throttle, transitionDuration, onSizeChange, ...rest } = props\r\n const [minColumnGap, maxColumnGap] = getGapRange(columnGap)\r\n const [width, setWidth] = useState(0)\r\n const [columnCount, setColumnCount] = useState(1)\r\n const [columnGapSize, setColumnGapSize] = useState(minColumnGap)\r\n const [showItems, setShowItems] = useState(false)\r\n const ele = useRef<HTMLDivElement>(null)\r\n const contentRows = Math.ceil(data.length / columnCount)\r\n const contentShownRows = typeof maxRows === \"number\" ? Math.min(contentRows, maxRows) : contentRows\r\n const height = contentShownRows > 0 ? contentShownRows * (itemHeight + rowGap) - rowGap : 0\r\n\r\n function getPosition(index: number): Position {\r\n const y = Math.floor(index / columnCount)\r\n const x = index - y * columnCount\r\n return {\r\n left: x * (itemWidth + columnGapSize),\r\n top: y * (itemHeight + rowGap)\r\n }\r\n }\r\n\r\n function getHidden(index: number) {\r\n if (typeof maxRows !== \"number\") return false\r\n return index >= maxRows * columnCount\r\n }\r\n\r\n useEffect(() => {\r\n let timeout: number\r\n const observer = new ResizeObserver(entries => {\r\n clearTimeout(timeout)\r\n function task() {\r\n const { width } = entries[0].contentRect\r\n const [newColumnCount, newColumnGapSize] = getGapCountAndSize(width, itemWidth, minColumnGap, maxColumnGap)\r\n setShowItems(true)\r\n setWidth(width)\r\n setColumnCount(newColumnCount)\r\n setColumnGapSize(newColumnGapSize)\r\n }\r\n if (throttle === null) {\r\n task()\r\n } else {\r\n timeout = window.setTimeout(task, throttle || 200)\r\n }\r\n })\r\n observer.observe(ele.current!)\r\n\r\n return () => {\r\n observer.disconnect()\r\n }\r\n }, [itemWidth, throttle, columnGap])\r\n\r\n useEffect(() => {\r\n onSizeChange?.({ width, height, itemWidth, itemHeight, columnGap: columnGapSize, columnCount, rowGap, rowCount: contentShownRows, overflow: data.length > contentShownRows * columnCount, itemCount: data.length, maxRows: maxRows ?? null })\r\n }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows])\r\n\r\n return (\r\n <div ref={ele} className={className} style={{ position: \"relative\", boxSizing: \"border-box\", height, ...style }} {...rest}>\r\n {showItems &&\r\n data.map((item, index) => (\r\n <div\r\n key={keyExactor ? keyExactor(item, index) : index}\r\n className={containerClassName}\r\n style={{\r\n position: \"absolute\",\r\n width: itemWidth,\r\n height: itemHeight,\r\n transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : undefined,\r\n ...getPosition(index)\r\n }}>\r\n <div style={{ width: itemWidth, height: itemHeight, display: maxRows && index >= maxRows * columnCount ? \"none\" : \"block\", ...containerStyle }}>{render(item, index, getHidden(index))}</div>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { MediaHTMLAttributes } from "react";
2
+ export interface HlsPlayerProps extends Omit<MediaHTMLAttributes<HTMLVideoElement>, "src"> {
3
+ src: string;
4
+ }
5
+ declare const HlsPlayer: import("react").ForwardRefExoticComponent<HlsPlayerProps & import("react").RefAttributes<HTMLVideoElement>>;
6
+ export default HlsPlayer;
@@ -0,0 +1,39 @@
1
+ "use client";
2
+
3
+ import Hls from "hls.js";
4
+ import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const HlsPlayer = /*#__PURE__*/forwardRef((props, ref) => {
7
+ const {
8
+ src,
9
+ ...rest
10
+ } = props;
11
+ const video = useRef(null);
12
+ useImperativeHandle(ref, () => video.current, []);
13
+ useEffect(() => {
14
+ const {
15
+ current: player
16
+ } = video;
17
+ if (!player || !src) return;
18
+ if (player.canPlayType("application/vnd.apple.mpegurl")) {
19
+ player.src = src;
20
+ player.play();
21
+ return;
22
+ }
23
+ if (Hls.isSupported()) {
24
+ const hls = new Hls();
25
+ hls.loadSource(src);
26
+ hls.attachMedia(player);
27
+ player.play();
28
+ return () => {
29
+ hls.destroy();
30
+ };
31
+ }
32
+ }, [src]);
33
+ return /*#__PURE__*/_jsx("video", {
34
+ ref: video,
35
+ ...rest
36
+ });
37
+ });
38
+ export default HlsPlayer;
39
+ //# sourceMappingURL=HlsPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Hls","forwardRef","useEffect","useImperativeHandle","useRef","jsx","_jsx","HlsPlayer","props","ref","src","rest","video","current","player","canPlayType","play","isSupported","hls","loadSource","attachMedia","destroy"],"sources":["../../../src/components/HlsPlayer.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport Hls from \"hls.js\"\r\nimport { MediaHTMLAttributes, forwardRef, useEffect, useImperativeHandle, useRef } from \"react\"\r\n\r\nexport interface HlsPlayerProps extends Omit<MediaHTMLAttributes<HTMLVideoElement>, \"src\"> {\r\n src: string\r\n}\r\n\r\nconst HlsPlayer = forwardRef<HTMLVideoElement, HlsPlayerProps>((props, ref) => {\r\n const { src, ...rest } = props\r\n const video = useRef<HTMLVideoElement>(null)\r\n\r\n useImperativeHandle(ref, () => video.current!, [])\r\n\r\n useEffect(() => {\r\n const { current: player } = video\r\n if (!player || !src) return\r\n if (player.canPlayType(\"application/vnd.apple.mpegurl\")) {\r\n player.src = src\r\n player.play()\r\n return\r\n }\r\n if (Hls.isSupported()) {\r\n const hls = new Hls()\r\n hls.loadSource(src)\r\n hls.attachMedia(player)\r\n player.play()\r\n return () => {\r\n hls.destroy()\r\n }\r\n }\r\n }, [src])\r\n\r\n return <video ref={video} {...rest} />\r\n})\r\n\r\nexport default HlsPlayer\r\n"],"mappings":"AAAA,YAAY;;AAEZ,OAAOA,GAAG,MAAM,QAAQ;AACxB,SAA8BC,UAAU,EAAEC,SAAS,EAAEC,mBAAmB,EAAEC,MAAM,QAAQ,OAAO;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAM/F,MAAMC,SAAS,gBAAGN,UAAU,CAAmC,CAACO,KAAK,EAAEC,GAAG,KAAK;EAC3E,MAAM;IAAEC,GAAG;IAAE,GAAGC;EAAK,CAAC,GAAGH,KAAK;EAC9B,MAAMI,KAAK,GAAGR,MAAM,CAAmB,IAAI,CAAC;EAE5CD,mBAAmB,CAACM,GAAG,EAAE,MAAMG,KAAK,CAACC,OAAQ,EAAE,EAAE,CAAC;EAElDX,SAAS,CAAC,MAAM;IACZ,MAAM;MAAEW,OAAO,EAAEC;IAAO,CAAC,GAAGF,KAAK;IACjC,IAAI,CAACE,MAAM,IAAI,CAACJ,GAAG,EAAE;IACrB,IAAII,MAAM,CAACC,WAAW,CAAC,+BAA+B,CAAC,EAAE;MACrDD,MAAM,CAACJ,GAAG,GAAGA,GAAG;MAChBI,MAAM,CAACE,IAAI,CAAC,CAAC;MACb;IACJ;IACA,IAAIhB,GAAG,CAACiB,WAAW,CAAC,CAAC,EAAE;MACnB,MAAMC,GAAG,GAAG,IAAIlB,GAAG,CAAC,CAAC;MACrBkB,GAAG,CAACC,UAAU,CAACT,GAAG,CAAC;MACnBQ,GAAG,CAACE,WAAW,CAACN,MAAM,CAAC;MACvBA,MAAM,CAACE,IAAI,CAAC,CAAC;MACb,OAAO,MAAM;QACTE,GAAG,CAACG,OAAO,CAAC,CAAC;MACjB,CAAC;IACL;EACJ,CAAC,EAAE,CAACX,GAAG,CAAC,CAAC;EAET,oBAAOJ,IAAA;IAAOG,GAAG,EAAEG,KAAM;IAAA,GAAKD;EAAI,CAAG,CAAC;AAC1C,CAAC,CAAC;AAEF,eAAeJ,SAAS"}
@@ -0,0 +1,64 @@
1
+ import { ButtonHTMLAttributes, InputHTMLAttributes } from "react";
2
+ export interface InputFileDataTypes {
3
+ base64: string;
4
+ text: string;
5
+ arrayBuffer: ArrayBuffer;
6
+ binary: string;
7
+ file: File;
8
+ }
9
+ export type InputFileDataType = keyof InputFileDataTypes;
10
+ export interface InputFileData<T> {
11
+ result: T;
12
+ file: File;
13
+ }
14
+ export type InputFileProps = ({
15
+ multiple?: false;
16
+ type: "base64" | "text" | "binary";
17
+ onChange?: (data: InputFileData<string>) => void;
18
+ } | {
19
+ multiple?: false;
20
+ type: "arrayBuffer";
21
+ onChange?: (data: InputFileData<ArrayBuffer>) => void;
22
+ } | {
23
+ multiple?: false;
24
+ type?: "file";
25
+ onChange?: (data: InputFileData<File>) => void;
26
+ } | {
27
+ multiple: true;
28
+ type: "base64" | "text" | "binary";
29
+ onChange?: (data: InputFileData<string>[]) => void;
30
+ } | {
31
+ multiple: true;
32
+ type: "arrayBuffer";
33
+ onChange?: (data: InputFileData<ArrayBuffer>[]) => void;
34
+ } | {
35
+ multiple: true;
36
+ type?: "file";
37
+ onChange?: (data: InputFileData<File>[]) => void;
38
+ }) & Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "multiple" | "type"> & {
39
+ /** 是否在捕获文件后清除 input 上的文件,默认为 false,主要区别在于如果不清除,连续两次选择同样的文件不会触发 onChange 事件,如果用于 form 表单,请设置为 flase */
40
+ clearAfterChange?: boolean;
41
+ };
42
+ export declare function getFileData<T extends InputFileDataType>(file: File, type: T): Promise<InputFileDataTypes[T]>;
43
+ /** 专用于读取文件的组件 */
44
+ export declare const InputFile: import("react").ForwardRefExoticComponent<InputFileProps & import("react").RefAttributes<HTMLInputElement>>;
45
+ export type InputFileButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
46
+ input: InputFileProps;
47
+ };
48
+ /** 专用于读取文件的 button 组件 */
49
+ export declare const InputFileButton: import("react").ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & {
50
+ input: InputFileProps;
51
+ } & import("react").RefAttributes<HTMLButtonElement>>;
52
+ export interface ImportExcelProps extends Omit<InputFileProps, "multiple" | "onChange" | "accept" | "type"> {
53
+ onChange?: (data: Record<string, string>[]) => void;
54
+ }
55
+ /** 专门用于读取 excel 的组件 */
56
+ export declare const ImportExcel: import("react").ForwardRefExoticComponent<ImportExcelProps & import("react").RefAttributes<HTMLInputElement>>;
57
+ /** 手动导出 excel */
58
+ export declare function exportExcel(data: Record<string, string>[], name: string): void;
59
+ export interface ExportExcelProps extends ButtonHTMLAttributes<HTMLButtonElement> {
60
+ data: Record<string, string>[];
61
+ fileName: string;
62
+ }
63
+ /** 导出 excel 的 button 组件 */
64
+ export declare const ExportExcel: import("react").ForwardRefExoticComponent<ExportExcelProps & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,167 @@
1
+ "use client";
2
+
3
+ import { Fragment, forwardRef, useRef, useState } from "react";
4
+ import { read, utils, writeFile } from "xlsx";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ export async function getFileData(file, type) {
8
+ const fileReader = new FileReader();
9
+ switch (type) {
10
+ case "arrayBuffer":
11
+ fileReader.readAsArrayBuffer(file);
12
+ break;
13
+ case "binary":
14
+ fileReader.readAsBinaryString(file);
15
+ break;
16
+ case "base64":
17
+ fileReader.readAsDataURL(file);
18
+ break;
19
+ case "text":
20
+ fileReader.readAsText(file);
21
+ break;
22
+ default:
23
+ return file;
24
+ }
25
+ return new Promise(resolve => {
26
+ fileReader.addEventListener("load", () => {
27
+ resolve(fileReader.result);
28
+ });
29
+ });
30
+ }
31
+
32
+ /** 专用于读取文件的组件 */
33
+ export const InputFile = /*#__PURE__*/forwardRef((props, ref) => {
34
+ const {
35
+ multiple = false,
36
+ type = "file",
37
+ onChange,
38
+ disabled: inputDisabled,
39
+ clearAfterChange,
40
+ ...rest
41
+ } = props;
42
+ const [disabled, setDisabled] = useState(false);
43
+ async function onInputChange(e) {
44
+ const input = e.target;
45
+ const {
46
+ files
47
+ } = input;
48
+ if (!files || files.length === 0) return;
49
+ setDisabled(true);
50
+ try {
51
+ if (multiple) {
52
+ const result = [];
53
+ for (const file of Array.from(files)) {
54
+ result.push({
55
+ result: await getFileData(file, type),
56
+ file
57
+ });
58
+ }
59
+ onChange?.(result);
60
+ } else {
61
+ onChange?.({
62
+ result: await getFileData(files[0], type),
63
+ file: files[0]
64
+ });
65
+ }
66
+ setDisabled(false);
67
+ if (clearAfterChange) input.value = "";
68
+ } catch (error) {
69
+ setDisabled(false);
70
+ if (clearAfterChange) input.value = "";
71
+ throw error;
72
+ }
73
+ }
74
+ return /*#__PURE__*/_jsx("input", {
75
+ ref: ref,
76
+ disabled: disabled || inputDisabled,
77
+ type: "file",
78
+ multiple: multiple,
79
+ onChange: onInputChange,
80
+ ...rest
81
+ });
82
+ });
83
+ /** 专用于读取文件的 button 组件 */
84
+ export const InputFileButton = /*#__PURE__*/forwardRef((props, ref) => {
85
+ const {
86
+ onClick,
87
+ input: inputProps,
88
+ ...rest
89
+ } = props;
90
+ const {
91
+ style,
92
+ ...restInputProps
93
+ } = inputProps;
94
+ const input = useRef(null);
95
+ function onBtnClick(e) {
96
+ input.current?.click();
97
+ onClick?.(e);
98
+ }
99
+ return /*#__PURE__*/_jsxs(Fragment, {
100
+ children: [/*#__PURE__*/_jsx(InputFile, {
101
+ ref: input,
102
+ style: {
103
+ display: "none",
104
+ ...style
105
+ },
106
+ ...restInputProps
107
+ }), /*#__PURE__*/_jsx("button", {
108
+ ref: ref,
109
+ type: "button",
110
+ onClick: onBtnClick,
111
+ ...rest
112
+ })]
113
+ });
114
+ });
115
+ /** 专门用于读取 excel 的组件 */
116
+ export const ImportExcel = /*#__PURE__*/forwardRef((props, ref) => {
117
+ const {
118
+ onChange,
119
+ ...rest
120
+ } = props;
121
+ function onInputChange(data) {
122
+ const wb = read(data.result);
123
+ const result = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
124
+ if (typeof result === "object") {
125
+ const $ = result.map(it => {
126
+ const _ = {};
127
+ Object.keys(it).filter(key => key !== "__rowNum__").forEach(key => _[key] = String(it[key]));
128
+ return _;
129
+ });
130
+ onChange?.($);
131
+ }
132
+ }
133
+ return /*#__PURE__*/_jsx(InputFile, {
134
+ ref: ref,
135
+ accept: ".xlsx",
136
+ type: "arrayBuffer",
137
+ onChange: onInputChange,
138
+ ...rest
139
+ });
140
+ });
141
+
142
+ /** 手动导出 excel */
143
+ export function exportExcel(data, name) {
144
+ const workSheet = utils.json_to_sheet(data);
145
+ const workBook = utils.book_new();
146
+ utils.book_append_sheet(workBook, workSheet);
147
+ writeFile(workBook, `${name}${name.endsWith(".xlsx") ? "" : ".xlsx"}`);
148
+ }
149
+ /** 导出 excel 的 button 组件 */
150
+ export const ExportExcel = /*#__PURE__*/forwardRef((props, ref) => {
151
+ const {
152
+ data,
153
+ fileName,
154
+ onClick,
155
+ ...rest
156
+ } = props;
157
+ function onButtonClick(e) {
158
+ exportExcel(data, fileName);
159
+ onClick?.(e);
160
+ }
161
+ return /*#__PURE__*/_jsx("button", {
162
+ ref: ref,
163
+ onClick: onButtonClick,
164
+ ...rest
165
+ });
166
+ });
167
+ //# sourceMappingURL=InputFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Fragment","forwardRef","useRef","useState","read","utils","writeFile","jsx","_jsx","jsxs","_jsxs","getFileData","file","type","fileReader","FileReader","readAsArrayBuffer","readAsBinaryString","readAsDataURL","readAsText","Promise","resolve","addEventListener","result","InputFile","props","ref","multiple","onChange","disabled","inputDisabled","clearAfterChange","rest","setDisabled","onInputChange","e","input","target","files","length","Array","from","push","value","error","InputFileButton","onClick","inputProps","style","restInputProps","onBtnClick","current","click","children","display","ImportExcel","data","wb","sheet_to_json","Sheets","SheetNames","$","map","it","_","Object","keys","filter","key","forEach","String","accept","exportExcel","name","workSheet","json_to_sheet","workBook","book_new","book_append_sheet","endsWith","ExportExcel","fileName","onButtonClick"],"sources":["../../../src/components/InputFile.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { ButtonHTMLAttributes, ChangeEvent, Fragment, InputHTMLAttributes, MouseEvent as ReactMouseEvent, forwardRef, useRef, useState } from \"react\"\r\nimport { read, utils, writeFile } from \"xlsx\"\r\n\r\nexport interface InputFileDataTypes {\r\n base64: string\r\n text: string\r\n arrayBuffer: ArrayBuffer\r\n binary: string\r\n file: File\r\n}\r\n\r\nexport type InputFileDataType = keyof InputFileDataTypes\r\n\r\nexport interface InputFileData<T> {\r\n result: T\r\n file: File\r\n}\r\n\r\nexport type InputFileProps = (\r\n | {\r\n multiple?: false\r\n type: \"base64\" | \"text\" | \"binary\"\r\n onChange?: (data: InputFileData<string>) => void\r\n }\r\n | {\r\n multiple?: false\r\n type: \"arrayBuffer\"\r\n onChange?: (data: InputFileData<ArrayBuffer>) => void\r\n }\r\n | {\r\n multiple?: false\r\n type?: \"file\"\r\n onChange?: (data: InputFileData<File>) => void\r\n }\r\n | {\r\n multiple: true\r\n type: \"base64\" | \"text\" | \"binary\"\r\n onChange?: (data: InputFileData<string>[]) => void\r\n }\r\n | {\r\n multiple: true\r\n type: \"arrayBuffer\"\r\n onChange?: (data: InputFileData<ArrayBuffer>[]) => void\r\n }\r\n | {\r\n multiple: true\r\n type?: \"file\"\r\n onChange?: (data: InputFileData<File>[]) => void\r\n }\r\n) &\r\n Omit<InputHTMLAttributes<HTMLInputElement>, \"onChange\" | \"multiple\" | \"type\"> & {\r\n /** 是否在捕获文件后清除 input 上的文件,默认为 false,主要区别在于如果不清除,连续两次选择同样的文件不会触发 onChange 事件,如果用于 form 表单,请设置为 flase */\r\n clearAfterChange?: boolean\r\n }\r\n\r\nexport async function getFileData<T extends InputFileDataType>(file: File, type: T): Promise<InputFileDataTypes[T]> {\r\n const fileReader = new FileReader()\r\n switch (type) {\r\n case \"arrayBuffer\":\r\n fileReader.readAsArrayBuffer(file)\r\n break\r\n case \"binary\":\r\n fileReader.readAsBinaryString(file)\r\n break\r\n case \"base64\":\r\n fileReader.readAsDataURL(file)\r\n break\r\n case \"text\":\r\n fileReader.readAsText(file)\r\n break\r\n default:\r\n return file as any\r\n }\r\n return new Promise(resolve => {\r\n fileReader.addEventListener(\"load\", () => {\r\n resolve(fileReader.result as any)\r\n })\r\n })\r\n}\r\n\r\n/** 专用于读取文件的组件 */\r\nexport const InputFile = forwardRef<HTMLInputElement, InputFileProps>((props, ref) => {\r\n const { multiple = false, type = \"file\", onChange, disabled: inputDisabled, clearAfterChange, ...rest } = props\r\n const [disabled, setDisabled] = useState(false)\r\n\r\n async function onInputChange(e: ChangeEvent<HTMLInputElement>) {\r\n const input = e.target\r\n const { files } = input\r\n if (!files || files.length === 0) return\r\n setDisabled(true)\r\n try {\r\n if (multiple) {\r\n const result: any[] = []\r\n for (const file of Array.from(files)) {\r\n result.push({\r\n result: await getFileData(file, type),\r\n file\r\n })\r\n }\r\n onChange?.(result as any)\r\n } else {\r\n onChange?.({\r\n result: await getFileData(files[0], type),\r\n file: files[0]\r\n } as any)\r\n }\r\n setDisabled(false)\r\n if (clearAfterChange) input.value = \"\"\r\n } catch (error) {\r\n setDisabled(false)\r\n if (clearAfterChange) input.value = \"\"\r\n throw error\r\n }\r\n }\r\n\r\n return <input ref={ref} disabled={disabled || inputDisabled} type=\"file\" multiple={multiple} onChange={onInputChange} {...rest} />\r\n})\r\n\r\nexport type InputFileButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\r\n input: InputFileProps\r\n}\r\n\r\n/** 专用于读取文件的 button 组件 */\r\nexport const InputFileButton = forwardRef<HTMLButtonElement, InputFileButtonProps>((props, ref) => {\r\n const { onClick, input: inputProps, ...rest } = props\r\n const { style, ...restInputProps } = inputProps\r\n const input = useRef<HTMLInputElement>(null)\r\n\r\n function onBtnClick(e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) {\r\n input.current?.click()\r\n onClick?.(e)\r\n }\r\n\r\n return (\r\n <Fragment>\r\n <InputFile ref={input} style={{ display: \"none\", ...style }} {...restInputProps} />\r\n <button ref={ref} type=\"button\" onClick={onBtnClick} {...rest} />\r\n </Fragment>\r\n )\r\n})\r\n\r\nexport interface ImportExcelProps extends Omit<InputFileProps, \"multiple\" | \"onChange\" | \"accept\" | \"type\"> {\r\n onChange?: (data: Record<string, string>[]) => void\r\n}\r\n\r\n/** 专门用于读取 excel 的组件 */\r\nexport const ImportExcel = forwardRef<HTMLInputElement, ImportExcelProps>((props, ref) => {\r\n const { onChange, ...rest } = props\r\n\r\n function onInputChange(data: InputFileData<ArrayBuffer>) {\r\n const wb = read(data.result)\r\n const result = utils.sheet_to_json<any>(wb.Sheets[wb.SheetNames[0]])\r\n if (typeof result === \"object\") {\r\n const $ = result.map(it => {\r\n const _: Record<string, string> = {}\r\n Object.keys(it)\r\n .filter(key => key !== \"__rowNum__\")\r\n .forEach(key => (_[key] = String(it[key])))\r\n return _\r\n })\r\n onChange?.($)\r\n }\r\n }\r\n\r\n return <InputFile ref={ref} accept=\".xlsx\" type=\"arrayBuffer\" onChange={onInputChange} {...rest} />\r\n})\r\n\r\n/** 手动导出 excel */\r\nexport function exportExcel(data: Record<string, string>[], name: string) {\r\n const workSheet = utils.json_to_sheet(data)\r\n const workBook = utils.book_new()\r\n utils.book_append_sheet(workBook, workSheet)\r\n writeFile(workBook, `${name}${name.endsWith(\".xlsx\") ? \"\" : \".xlsx\"}`)\r\n}\r\n\r\nexport interface ExportExcelProps extends ButtonHTMLAttributes<HTMLButtonElement> {\r\n data: Record<string, string>[]\r\n fileName: string\r\n}\r\n\r\n/** 导出 excel 的 button 组件 */\r\nexport const ExportExcel = forwardRef<HTMLButtonElement, ExportExcelProps>((props, ref) => {\r\n const { data, fileName, onClick, ...rest } = props\r\n\r\n function onButtonClick(e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) {\r\n exportExcel(data, fileName)\r\n onClick?.(e)\r\n }\r\n\r\n return <button ref={ref} onClick={onButtonClick} {...rest} />\r\n})\r\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { CSSProperties, HTMLAttributes } from "react";
2
+ export interface LoopSwiperProps extends HTMLAttributes<HTMLDivElement> {
3
+ direction?: "horizontal" | "vertical";
4
+ reverse?: boolean;
5
+ period: number;
6
+ gap?: CSSProperties["gap"];
7
+ }
8
+ /** 循环播放组件 */
9
+ export declare const LoopSwiper: import("react").ForwardRefExoticComponent<LoopSwiperProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,122 @@
1
+ "use client";
2
+
3
+ import { css } from "@emotion/css";
4
+ import { clsx } from "deepsea-tools";
5
+ import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ import { jsxs as _jsxs } from "react/jsx-runtime";
8
+ /** 循环播放组件 */
9
+ export const LoopSwiper = /*#__PURE__*/forwardRef((props, ref) => {
10
+ const {
11
+ className,
12
+ style,
13
+ children,
14
+ direction,
15
+ period,
16
+ reverse,
17
+ gap,
18
+ ...rest
19
+ } = props;
20
+ const wrapper = useRef(null);
21
+ const container = useRef(null);
22
+ const [swiper, setSwiper] = useState(false);
23
+ const directionRef = useRef(direction);
24
+ directionRef.current = direction;
25
+ const flexDirection = direction === "vertical" ? reverse ? "column-reverse" : "column" : reverse ? "row-reverse" : "row";
26
+ const animationName = swiper ? direction === "vertical" ? reverse ? "deepsea-reverse-vertical-loop-swipe" : "deepsea-vertical-loop-swipe" : reverse ? "deepsea-reverse-horizontal-loop-swipe" : "deepsea-horizontal-loop-swipe" : "none";
27
+ const animationDuration = `${period}ms`;
28
+ const animationTimingFunction = "linear";
29
+ const animationIterationCount = "infinite";
30
+ useImperativeHandle(ref, () => wrapper.current, []);
31
+ useEffect(() => {
32
+ const wrapperEle = wrapper.current;
33
+ const containerEle = container.current;
34
+ let wrapperWidth = 0;
35
+ let wrapperHeight = 0;
36
+ let containerWidth = 0;
37
+ let containerHeight = 0;
38
+ const observer = new ResizeObserver(entries => {
39
+ entries.forEach(entry => {
40
+ if (entry.target === wrapperEle) {
41
+ wrapperWidth = entry.contentRect.width;
42
+ wrapperHeight = entry.contentRect.height;
43
+ } else if (entry.target === containerEle) {
44
+ containerWidth = entry.contentRect.width;
45
+ containerHeight = entry.contentRect.height;
46
+ }
47
+ });
48
+ setSwiper(directionRef.current === "vertical" ? containerHeight > wrapperHeight : containerWidth > wrapperWidth);
49
+ });
50
+ observer.observe(wrapperEle);
51
+ observer.observe(containerEle);
52
+ }, []);
53
+ return /*#__PURE__*/_jsxs("div", {
54
+ ref: wrapper,
55
+ className: clsx(css`
56
+ @keyframes deepsea-horizontal-loop-swipe {
57
+ from {
58
+ transform: translateX(0);
59
+ }
60
+ to {
61
+ transform: translateX(-100%);
62
+ }
63
+ }
64
+ @keyframes deepsea-reverse-horizontal-loop-swipe {
65
+ from {
66
+ transform: translateX(0);
67
+ }
68
+ to {
69
+ transform: translateX(100%);
70
+ }
71
+ }
72
+ @keyframes deepsea-vertical-loop-swipe {
73
+ from {
74
+ transform: translateY(0);
75
+ }
76
+ to {
77
+ transform: translateY(-100%);
78
+ }
79
+ }
80
+ @keyframes deepsea-reverse-vertical-loop-swipe {
81
+ from {
82
+ transform: translateY(0);
83
+ }
84
+ to {
85
+ transform: translateY(100%);
86
+ }
87
+ }
88
+ `, className),
89
+ style: {
90
+ display: "flex",
91
+ flexDirection,
92
+ gap,
93
+ ...style
94
+ },
95
+ ...rest,
96
+ children: [/*#__PURE__*/_jsx("div", {
97
+ ref: container,
98
+ style: {
99
+ display: "flex",
100
+ flexDirection,
101
+ gap,
102
+ animationName,
103
+ animationTimingFunction,
104
+ animationDuration,
105
+ animationIterationCount
106
+ },
107
+ children: children
108
+ }), /*#__PURE__*/_jsx("div", {
109
+ style: {
110
+ display: swiper ? "flex" : "none",
111
+ flexDirection,
112
+ gap,
113
+ animationName,
114
+ animationTimingFunction,
115
+ animationDuration,
116
+ animationIterationCount
117
+ },
118
+ children: children
119
+ })]
120
+ });
121
+ });
122
+ //# sourceMappingURL=LoopSwiper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["css","clsx","forwardRef","useEffect","useImperativeHandle","useRef","useState","jsx","_jsx","jsxs","_jsxs","LoopSwiper","props","ref","className","style","children","direction","period","reverse","gap","rest","wrapper","container","swiper","setSwiper","directionRef","current","flexDirection","animationName","animationDuration","animationTimingFunction","animationIterationCount","wrapperEle","containerEle","wrapperWidth","wrapperHeight","containerWidth","containerHeight","observer","ResizeObserver","entries","forEach","entry","target","contentRect","width","height","observe","display"],"sources":["../../../src/components/LoopSwiper.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { CSSProperties, forwardRef, HTMLAttributes, useEffect, useImperativeHandle, useRef, useState } from \"react\"\r\n\r\nexport interface LoopSwiperProps extends HTMLAttributes<HTMLDivElement> {\r\n direction?: \"horizontal\" | \"vertical\"\r\n reverse?: boolean\r\n period: number\r\n gap?: CSSProperties[\"gap\"]\r\n}\r\n\r\n/** 循环播放组件 */\r\nexport const LoopSwiper = forwardRef<HTMLDivElement, LoopSwiperProps>((props, ref) => {\r\n const { className, style, children, direction, period, reverse, gap, ...rest } = props\r\n const wrapper = useRef<HTMLDivElement>(null)\r\n const container = useRef<HTMLDivElement>(null)\r\n const [swiper, setSwiper] = useState(false)\r\n const directionRef = useRef(direction)\r\n directionRef.current = direction\r\n const flexDirection: CSSProperties[\"flexDirection\"] = direction === \"vertical\" ? (reverse ? \"column-reverse\" : \"column\") : reverse ? \"row-reverse\" : \"row\"\r\n const animationName = swiper ? (direction === \"vertical\" ? (reverse ? \"deepsea-reverse-vertical-loop-swipe\" : \"deepsea-vertical-loop-swipe\") : reverse ? \"deepsea-reverse-horizontal-loop-swipe\" : \"deepsea-horizontal-loop-swipe\") : \"none\"\r\n const animationDuration = `${period}ms`\r\n const animationTimingFunction = \"linear\"\r\n const animationIterationCount = \"infinite\"\r\n\r\n useImperativeHandle(ref, () => wrapper.current!, [])\r\n\r\n useEffect(() => {\r\n const wrapperEle = wrapper.current!\r\n const containerEle = container.current!\r\n let wrapperWidth = 0\r\n let wrapperHeight = 0\r\n let containerWidth = 0\r\n let containerHeight = 0\r\n const observer = new ResizeObserver(entries => {\r\n entries.forEach(entry => {\r\n if (entry.target === wrapperEle) {\r\n wrapperWidth = entry.contentRect.width\r\n wrapperHeight = entry.contentRect.height\r\n } else if (entry.target === containerEle) {\r\n containerWidth = entry.contentRect.width\r\n containerHeight = entry.contentRect.height\r\n }\r\n })\r\n setSwiper(directionRef.current === \"vertical\" ? containerHeight > wrapperHeight : containerWidth > wrapperWidth)\r\n })\r\n observer.observe(wrapperEle)\r\n observer.observe(containerEle)\r\n }, [])\r\n\r\n return (\r\n <div\r\n ref={wrapper}\r\n className={clsx(\r\n css`\r\n @keyframes deepsea-horizontal-loop-swipe {\r\n from {\r\n transform: translateX(0);\r\n }\r\n to {\r\n transform: translateX(-100%);\r\n }\r\n }\r\n @keyframes deepsea-reverse-horizontal-loop-swipe {\r\n from {\r\n transform: translateX(0);\r\n }\r\n to {\r\n transform: translateX(100%);\r\n }\r\n }\r\n @keyframes deepsea-vertical-loop-swipe {\r\n from {\r\n transform: translateY(0);\r\n }\r\n to {\r\n transform: translateY(-100%);\r\n }\r\n }\r\n @keyframes deepsea-reverse-vertical-loop-swipe {\r\n from {\r\n transform: translateY(0);\r\n }\r\n to {\r\n transform: translateY(100%);\r\n }\r\n }\r\n `,\r\n className\r\n )}\r\n style={{ display: \"flex\", flexDirection, gap, ...style }}\r\n {...rest}>\r\n <div ref={container} style={{ display: \"flex\", flexDirection, gap, animationName, animationTimingFunction, animationDuration, animationIterationCount }}>\r\n {children}\r\n </div>\r\n <div style={{ display: swiper ? \"flex\" : \"none\", flexDirection, gap, animationName, animationTimingFunction, animationDuration, animationIterationCount }}>{children}</div>\r\n </div>\r\n )\r\n})\r\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { HTMLAttributes } from "react";
2
+ export interface RingProps extends HTMLAttributes<HTMLDivElement> {
3
+ outerWidth: number;
4
+ innerWidth: number;
5
+ }
6
+ /** 环形组件 */
7
+ export declare const Ring: import("react").ForwardRefExoticComponent<RingProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,26 @@
1
+ "use client";
2
+
3
+ import { forwardRef } from "react";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ /** 环形组件 */
6
+ export const Ring = /*#__PURE__*/forwardRef((props, ref) => {
7
+ const {
8
+ outerWidth,
9
+ innerWidth,
10
+ style,
11
+ ...rest
12
+ } = props;
13
+ const outerRadius = outerWidth / 2;
14
+ const innerRadius = innerWidth / 2;
15
+ return /*#__PURE__*/_jsx("div", {
16
+ ref: ref,
17
+ style: {
18
+ ...style,
19
+ width: `${outerWidth}px`,
20
+ height: `${outerWidth}px`,
21
+ clipPath: `path("M0,${outerRadius} a${outerRadius},${outerRadius},0,1,0,${outerWidth},0 a${outerRadius},${outerRadius},0,1,0,-${outerWidth},0 l${outerRadius - innerRadius},0 a${innerRadius},${innerRadius},0,0,1,${innerRadius * 2},0 a${innerRadius},${innerRadius},0,0,1,-${innerRadius * 2},0 Z")`
22
+ },
23
+ ...rest
24
+ });
25
+ });
26
+ //# sourceMappingURL=Ring.js.map