deepsea-components 2.8.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) 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.d.ts +5 -0
  5. package/dist/cjs/components/AutoScroll.js +8 -6
  6. package/dist/cjs/components/AutoScroll.js.map +2 -2
  7. package/dist/cjs/components/AutoSizeTextarea.d.ts +5 -0
  8. package/dist/cjs/components/AutoSizeTextarea.js +51 -0
  9. package/dist/cjs/components/AutoSizeTextarea.js.map +7 -0
  10. package/dist/cjs/components/CircleText.d.ts +25 -0
  11. package/dist/cjs/components/CircleText.js +48 -0
  12. package/dist/cjs/components/CircleText.js.map +7 -0
  13. package/dist/cjs/components/Flow.d.ts +57 -0
  14. package/dist/cjs/components/Flow.js +119 -0
  15. package/dist/cjs/components/Flow.js.map +7 -0
  16. package/dist/cjs/components/InputFile.d.ts +64 -0
  17. package/dist/cjs/components/InputFile.js +143 -0
  18. package/dist/cjs/components/InputFile.js.map +7 -0
  19. package/dist/cjs/components/LoopSwiper.d.ts +9 -0
  20. package/dist/cjs/components/LoopSwiper.js +116 -0
  21. package/dist/cjs/components/LoopSwiper.js.map +7 -0
  22. package/dist/cjs/components/Ring.d.ts +7 -0
  23. package/dist/cjs/components/Ring.js +37 -0
  24. package/dist/cjs/components/Ring.js.map +7 -0
  25. package/dist/cjs/components/Scroll.js.map +2 -2
  26. package/dist/cjs/components/SectionRing.d.ts +8 -0
  27. package/dist/cjs/components/SectionRing.js +50 -0
  28. package/dist/cjs/components/SectionRing.js.map +7 -0
  29. package/dist/cjs/components/Skeleton.d.ts +3 -0
  30. package/dist/cjs/components/Skeleton.js +60 -0
  31. package/dist/cjs/components/Skeleton.js.map +7 -0
  32. package/dist/cjs/components/TransitionBox.d.ts +10 -0
  33. package/dist/cjs/components/TransitionBox.js +45 -0
  34. package/dist/cjs/components/TransitionBox.js.map +7 -0
  35. package/dist/cjs/components/TransitionNum.d.ts +16 -0
  36. package/dist/cjs/components/TransitionNum.js +62 -0
  37. package/dist/cjs/components/TransitionNum.js.map +7 -0
  38. package/dist/cjs/components/Trapezium.d.ts +9 -0
  39. package/dist/cjs/components/Trapezium.js +44 -0
  40. package/dist/cjs/components/Trapezium.js.map +7 -0
  41. package/dist/cjs/index.d.ts +13 -265
  42. package/dist/cjs/index.js +26 -505
  43. package/dist/cjs/index.js.map +3 -3
  44. package/dist/esm/components/AutoFit.d.ts +25 -0
  45. package/dist/esm/components/AutoFit.js +87 -0
  46. package/dist/esm/components/AutoFit.js.map +1 -0
  47. package/dist/esm/components/AutoScroll.d.ts +5 -0
  48. package/dist/esm/components/AutoScroll.js +8 -5
  49. package/dist/esm/components/AutoScroll.js.map +1 -1
  50. package/dist/esm/components/AutoSizeTextarea.d.ts +5 -0
  51. package/dist/esm/components/AutoSizeTextarea.js +45 -0
  52. package/dist/esm/components/AutoSizeTextarea.js.map +1 -0
  53. package/dist/esm/components/CircleText.d.ts +25 -0
  54. package/dist/esm/components/CircleText.js +49 -0
  55. package/dist/esm/components/CircleText.js.map +1 -0
  56. package/dist/esm/components/Flow.d.ts +57 -0
  57. package/dist/esm/components/Flow.js +130 -0
  58. package/dist/esm/components/Flow.js.map +1 -0
  59. package/dist/esm/components/InputFile.d.ts +64 -0
  60. package/dist/esm/components/InputFile.js +167 -0
  61. package/dist/esm/components/InputFile.js.map +1 -0
  62. package/dist/esm/components/LoopSwiper.d.ts +9 -0
  63. package/dist/esm/components/LoopSwiper.js +122 -0
  64. package/dist/esm/components/LoopSwiper.js.map +1 -0
  65. package/dist/esm/components/Ring.d.ts +7 -0
  66. package/dist/esm/components/Ring.js +26 -0
  67. package/dist/esm/components/Ring.js.map +1 -0
  68. package/dist/esm/components/Scroll.js.map +1 -1
  69. package/dist/esm/components/SectionRing.d.ts +8 -0
  70. package/dist/esm/components/SectionRing.js +31 -0
  71. package/dist/esm/components/SectionRing.js.map +1 -0
  72. package/dist/esm/components/Skeleton.d.ts +3 -0
  73. package/dist/esm/components/Skeleton.js +35 -0
  74. package/dist/esm/components/Skeleton.js.map +1 -0
  75. package/dist/esm/components/TransitionBox.d.ts +10 -0
  76. package/dist/esm/components/TransitionBox.js +50 -0
  77. package/dist/esm/components/TransitionBox.js.map +1 -0
  78. package/dist/esm/components/TransitionNum.d.ts +16 -0
  79. package/dist/esm/components/TransitionNum.js +65 -0
  80. package/dist/esm/components/TransitionNum.js.map +1 -0
  81. package/dist/esm/components/Trapezium.d.ts +9 -0
  82. package/dist/esm/components/Trapezium.js +35 -0
  83. package/dist/esm/components/Trapezium.js.map +1 -0
  84. package/dist/esm/index.d.ts +13 -265
  85. package/dist/esm/index.js +13 -843
  86. package/dist/esm/index.js.map +1 -1
  87. package/package.json +3 -3
  88. package/src/components/AutoFit.tsx +95 -0
  89. package/src/components/AutoScroll.tsx +18 -9
  90. package/src/components/AutoSizeTextarea.tsx +31 -0
  91. package/src/components/CircleText.tsx +56 -0
  92. package/src/components/Flow.tsx +154 -0
  93. package/src/components/InputFile.tsx +193 -0
  94. package/src/components/LoopSwiper.tsx +101 -0
  95. package/src/components/Ring.tsx +19 -0
  96. package/src/components/Scroll.tsx +1 -0
  97. package/src/components/SectionRing.tsx +36 -0
  98. package/src/components/Skeleton.tsx +38 -0
  99. package/src/components/TransitionBox.tsx +36 -0
  100. package/src/components/TransitionNum.tsx +54 -0
  101. package/src/components/Trapezium.tsx +35 -0
  102. package/src/index.tsx +13 -862
  103. package/dist/cjs/skeleton.css +0 -18
  104. package/dist/esm/skeleton.css +0 -18
  105. 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,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
@@ -0,0 +1 @@
1
+ {"version":3,"names":["forwardRef","jsx","_jsx","Ring","props","ref","outerWidth","innerWidth","style","rest","outerRadius","innerRadius","width","height","clipPath"],"sources":["../../../src/components/Ring.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { forwardRef, HTMLAttributes } from \"react\"\r\n\r\nexport interface RingProps extends HTMLAttributes<HTMLDivElement> {\r\n outerWidth: number\r\n innerWidth: number\r\n}\r\n\r\n/** 环形组件 */\r\nexport const Ring = forwardRef<HTMLDivElement, RingProps>((props, ref) => {\r\n const { outerWidth, innerWidth, style, ...rest } = props\r\n\r\n const outerRadius = outerWidth / 2\r\n\r\n const innerRadius = innerWidth / 2\r\n\r\n return <div ref={ref} style={{ ...style, width: `${outerWidth}px`, height: `${outerWidth}px`, 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\")` }} {...rest} />\r\n})\r\n"],"mappings":"AAAA,YAAY;;AAEZ,SAASA,UAAU,QAAwB,OAAO;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAOlD;AACA,OAAO,MAAMC,IAAI,gBAAGH,UAAU,CAA4B,CAACI,KAAK,EAAEC,GAAG,KAAK;EACtE,MAAM;IAAEC,UAAU;IAAEC,UAAU;IAAEC,KAAK;IAAE,GAAGC;EAAK,CAAC,GAAGL,KAAK;EAExD,MAAMM,WAAW,GAAGJ,UAAU,GAAG,CAAC;EAElC,MAAMK,WAAW,GAAGJ,UAAU,GAAG,CAAC;EAElC,oBAAOL,IAAA;IAAKG,GAAG,EAAEA,GAAI;IAACG,KAAK,EAAE;MAAE,GAAGA,KAAK;MAAEI,KAAK,EAAG,GAAEN,UAAW,IAAG;MAAEO,MAAM,EAAG,GAAEP,UAAW,IAAG;MAAEQ,QAAQ,EAAG,YAAWJ,WAAY,KAAIA,WAAY,IAAGA,WAAY,UAASJ,UAAW,OAAMI,WAAY,IAAGA,WAAY,WAAUJ,UAAW,OAAMI,WAAW,GAAGC,WAAY,OAAMA,WAAY,IAAGA,WAAY,UAASA,WAAW,GAAG,CAAE,OAAMA,WAAY,IAAGA,WAAY,WAAUA,WAAW,GAAG,CAAE;IAAQ,CAAE;IAAA,GAAKF;EAAI,CAAG,CAAC;AACzZ,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"names":["css","clsx","forwardRef","useEffect","useImperativeHandle","useLayoutEffect","useRef","Scrollbar","jsx","_jsx","default","Scroll","props","ref","children","options","className","style","scrollbar","onScrollbar","rest","thumbWidth","thumbRadius","thumbColor","trackColor","scrollbarOptions","ele","bar","current","init","destroy","addListener","removeListener","undefined"],"sources":["../../../src/components/Scroll.tsx"],"sourcesContent":["\"use client\"\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { CSSProperties, ForwardedRef, forwardRef, HTMLAttributes, useEffect, useImperativeHandle, useLayoutEffect, useRef } from \"react\"\r\nimport Scrollbar from \"smooth-scrollbar\"\r\nimport type { ScrollbarOptions, ScrollListener } from \"smooth-scrollbar/interfaces\"\r\nexport { default as Scrollbar } from \"smooth-scrollbar\"\r\nexport * from \"smooth-scrollbar/interfaces\"\r\n\r\nexport interface ScrollOptions extends Partial<ScrollbarOptions> {\r\n /** 滑块宽度 */\r\n thumbWidth?: number | string\r\n /** 滑块圆角大小 */\r\n thumbRadius?: number | string\r\n /** 滑块背景颜色 */\r\n thumbColor?: string\r\n /** 滚动条背景颜色 */\r\n trackColor?: string\r\n}\r\n\r\nexport interface ScrollProps extends HTMLAttributes<HTMLDivElement> {\r\n /** 滚动的配置 */\r\n options?: ScrollOptions\r\n /** 滚动条实例 */\r\n scrollbar?: ForwardedRef<Scrollbar>\r\n /** 滚动条滚动事件 */\r\n onScrollbar?: ScrollListener\r\n}\r\n\r\nexport const Scroll = forwardRef<HTMLDivElement, ScrollProps>((props, ref) => {\r\n const { children, options, className, style, scrollbar, onScrollbar, ...rest } = props\r\n const { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = options || {}\r\n const ele = useRef<HTMLDivElement>(null)\r\n const bar = useRef<Scrollbar | null>(null)\r\n\r\n useLayoutEffect(() => {\r\n bar.current = Scrollbar.init(ele.current!, scrollbarOptions)\r\n return () => bar.current?.destroy()\r\n }, [])\r\n\r\n useImperativeHandle(ref, () => ele.current!, [])\r\n\r\n useImperativeHandle(scrollbar, () => bar.current!, [])\r\n\r\n useEffect(() => {\r\n if (!onScrollbar) return\r\n bar.current?.addListener(onScrollbar)\r\n return () => bar.current?.removeListener(onScrollbar)\r\n }, [onScrollbar])\r\n\r\n return (\r\n <div\r\n ref={ele}\r\n className={clsx(\r\n css`\r\n .scrollbar-track.scrollbar-track-x {\r\n ${thumbWidth !== undefined ? \"height: var(--thumb-width);\" : \"\"}\r\n ${trackColor !== undefined ? \"background-color: var(--track-color);\" : \"\"}\r\n }\r\n\r\n .scrollbar-thumb.scrollbar-thumb-x {\r\n ${thumbWidth !== undefined ? \"height: var(--thumb-width);\" : \"\"}\r\n ${thumbRadius !== undefined ? \"border-radius: var(--thumb-radius);\" : \"\"}\r\n ${thumbColor !== undefined ? \"background-color: var(--thumb-color);\" : \"\"}\r\n }\r\n\r\n .scrollbar-track.scrollbar-track-y {\r\n ${thumbWidth !== undefined ? \"width: var(--thumb-width);\" : \"\"}\r\n ${trackColor !== undefined ? \"background-color: var(--track-color);\" : \"\"}\r\n }\r\n\r\n .scrollbar-thumb.scrollbar-thumb-y {\r\n ${thumbWidth !== undefined ? \"width: var(--thumb-width);\" : \"\"}\r\n ${thumbRadius !== undefined ? \"border-radius: var(--thumb-radius);\" : \"\"}\r\n ${thumbColor !== undefined ? \"background-color: var(--thumb-color);\" : \"\"}\r\n }\r\n `,\r\n className\r\n )}\r\n style={\r\n {\r\n \"--thumb-width\": typeof thumbWidth === \"number\" ? `${thumbWidth}px` : thumbWidth,\r\n \"--thumb-radius\": typeof thumbRadius === \"number\" ? `${thumbRadius}px` : thumbRadius,\r\n \"--thumb-color\": thumbColor,\r\n \"--track-color\": trackColor,\r\n ...style\r\n } as CSSProperties\r\n }\r\n {...rest}>\r\n {children}\r\n </div>\r\n )\r\n})\r\n"],"mappings":"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"}
1
+ {"version":3,"names":["css","clsx","forwardRef","useEffect","useImperativeHandle","useLayoutEffect","useRef","Scrollbar","jsx","_jsx","default","Scroll","props","ref","children","options","className","style","scrollbar","onScrollbar","rest","thumbWidth","thumbRadius","thumbColor","trackColor","scrollbarOptions","ele","bar","current","init","destroy","addListener","removeListener","undefined"],"sources":["../../../src/components/Scroll.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { css } from \"@emotion/css\"\r\nimport { clsx } from \"deepsea-tools\"\r\nimport { CSSProperties, ForwardedRef, forwardRef, HTMLAttributes, useEffect, useImperativeHandle, useLayoutEffect, useRef } from \"react\"\r\nimport Scrollbar from \"smooth-scrollbar\"\r\nimport type { ScrollbarOptions, ScrollListener } from \"smooth-scrollbar/interfaces\"\r\nexport { default as Scrollbar } from \"smooth-scrollbar\"\r\nexport * from \"smooth-scrollbar/interfaces\"\r\n\r\nexport interface ScrollOptions extends Partial<ScrollbarOptions> {\r\n /** 滑块宽度 */\r\n thumbWidth?: number | string\r\n /** 滑块圆角大小 */\r\n thumbRadius?: number | string\r\n /** 滑块背景颜色 */\r\n thumbColor?: string\r\n /** 滚动条背景颜色 */\r\n trackColor?: string\r\n}\r\n\r\nexport interface ScrollProps extends HTMLAttributes<HTMLDivElement> {\r\n /** 滚动的配置 */\r\n options?: ScrollOptions\r\n /** 滚动条实例 */\r\n scrollbar?: ForwardedRef<Scrollbar>\r\n /** 滚动条滚动事件 */\r\n onScrollbar?: ScrollListener\r\n}\r\n\r\nexport const Scroll = forwardRef<HTMLDivElement, ScrollProps>((props, ref) => {\r\n const { children, options, className, style, scrollbar, onScrollbar, ...rest } = props\r\n const { thumbWidth, thumbRadius, thumbColor, trackColor, ...scrollbarOptions } = options || {}\r\n const ele = useRef<HTMLDivElement>(null)\r\n const bar = useRef<Scrollbar | null>(null)\r\n\r\n useLayoutEffect(() => {\r\n bar.current = Scrollbar.init(ele.current!, scrollbarOptions)\r\n return () => bar.current?.destroy()\r\n }, [])\r\n\r\n useImperativeHandle(ref, () => ele.current!, [])\r\n\r\n useImperativeHandle(scrollbar, () => bar.current!, [])\r\n\r\n useEffect(() => {\r\n if (!onScrollbar) return\r\n bar.current?.addListener(onScrollbar)\r\n return () => bar.current?.removeListener(onScrollbar)\r\n }, [onScrollbar])\r\n\r\n return (\r\n <div\r\n ref={ele}\r\n className={clsx(\r\n css`\r\n .scrollbar-track.scrollbar-track-x {\r\n ${thumbWidth !== undefined ? \"height: var(--thumb-width);\" : \"\"}\r\n ${trackColor !== undefined ? \"background-color: var(--track-color);\" : \"\"}\r\n }\r\n\r\n .scrollbar-thumb.scrollbar-thumb-x {\r\n ${thumbWidth !== undefined ? \"height: var(--thumb-width);\" : \"\"}\r\n ${thumbRadius !== undefined ? \"border-radius: var(--thumb-radius);\" : \"\"}\r\n ${thumbColor !== undefined ? \"background-color: var(--thumb-color);\" : \"\"}\r\n }\r\n\r\n .scrollbar-track.scrollbar-track-y {\r\n ${thumbWidth !== undefined ? \"width: var(--thumb-width);\" : \"\"}\r\n ${trackColor !== undefined ? \"background-color: var(--track-color);\" : \"\"}\r\n }\r\n\r\n .scrollbar-thumb.scrollbar-thumb-y {\r\n ${thumbWidth !== undefined ? \"width: var(--thumb-width);\" : \"\"}\r\n ${thumbRadius !== undefined ? \"border-radius: var(--thumb-radius);\" : \"\"}\r\n ${thumbColor !== undefined ? \"background-color: var(--thumb-color);\" : \"\"}\r\n }\r\n `,\r\n className\r\n )}\r\n style={\r\n {\r\n \"--thumb-width\": typeof thumbWidth === \"number\" ? `${thumbWidth}px` : thumbWidth,\r\n \"--thumb-radius\": typeof thumbRadius === \"number\" ? `${thumbRadius}px` : thumbRadius,\r\n \"--thumb-color\": thumbColor,\r\n \"--track-color\": trackColor,\r\n ...style\r\n } as CSSProperties\r\n }\r\n {...rest}>\r\n {children}\r\n </div>\r\n )\r\n})\r\n"],"mappings":"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"}