deepsea-components 2.8.5 → 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 (101) 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/InputFile.d.ts +64 -0
  15. package/dist/cjs/components/InputFile.js +143 -0
  16. package/dist/cjs/components/InputFile.js.map +7 -0
  17. package/dist/cjs/components/LoopSwiper.d.ts +9 -0
  18. package/dist/cjs/components/LoopSwiper.js +116 -0
  19. package/dist/cjs/components/LoopSwiper.js.map +7 -0
  20. package/dist/cjs/components/Ring.d.ts +7 -0
  21. package/dist/cjs/components/Ring.js +37 -0
  22. package/dist/cjs/components/Ring.js.map +7 -0
  23. package/dist/cjs/components/Scroll.js.map +2 -2
  24. package/dist/cjs/components/SectionRing.d.ts +8 -0
  25. package/dist/cjs/components/SectionRing.js +50 -0
  26. package/dist/cjs/components/SectionRing.js.map +7 -0
  27. package/dist/cjs/components/Skeleton.d.ts +3 -0
  28. package/dist/cjs/components/Skeleton.js +60 -0
  29. package/dist/cjs/components/Skeleton.js.map +7 -0
  30. package/dist/cjs/components/TransitionBox.d.ts +10 -0
  31. package/dist/cjs/components/TransitionBox.js +45 -0
  32. package/dist/cjs/components/TransitionBox.js.map +7 -0
  33. package/dist/cjs/components/TransitionNum.d.ts +16 -0
  34. package/dist/cjs/components/TransitionNum.js +62 -0
  35. package/dist/cjs/components/TransitionNum.js.map +7 -0
  36. package/dist/cjs/components/Trapezium.d.ts +9 -0
  37. package/dist/cjs/components/Trapezium.js +44 -0
  38. package/dist/cjs/components/Trapezium.js.map +7 -0
  39. package/dist/cjs/index.d.ts +13 -265
  40. package/dist/cjs/index.js +26 -505
  41. package/dist/cjs/index.js.map +3 -3
  42. package/dist/esm/components/AutoFit.d.ts +25 -0
  43. package/dist/esm/components/AutoFit.js +87 -0
  44. package/dist/esm/components/AutoFit.js.map +1 -0
  45. package/dist/esm/components/AutoScroll.js.map +1 -1
  46. package/dist/esm/components/AutoSizeTextarea.d.ts +5 -0
  47. package/dist/esm/components/AutoSizeTextarea.js +45 -0
  48. package/dist/esm/components/AutoSizeTextarea.js.map +1 -0
  49. package/dist/esm/components/CircleText.d.ts +25 -0
  50. package/dist/esm/components/CircleText.js +49 -0
  51. package/dist/esm/components/CircleText.js.map +1 -0
  52. package/dist/esm/components/Flow.d.ts +57 -0
  53. package/dist/esm/components/Flow.js +130 -0
  54. package/dist/esm/components/Flow.js.map +1 -0
  55. package/dist/esm/components/InputFile.d.ts +64 -0
  56. package/dist/esm/components/InputFile.js +167 -0
  57. package/dist/esm/components/InputFile.js.map +1 -0
  58. package/dist/esm/components/LoopSwiper.d.ts +9 -0
  59. package/dist/esm/components/LoopSwiper.js +122 -0
  60. package/dist/esm/components/LoopSwiper.js.map +1 -0
  61. package/dist/esm/components/Ring.d.ts +7 -0
  62. package/dist/esm/components/Ring.js +26 -0
  63. package/dist/esm/components/Ring.js.map +1 -0
  64. package/dist/esm/components/Scroll.js.map +1 -1
  65. package/dist/esm/components/SectionRing.d.ts +8 -0
  66. package/dist/esm/components/SectionRing.js +31 -0
  67. package/dist/esm/components/SectionRing.js.map +1 -0
  68. package/dist/esm/components/Skeleton.d.ts +3 -0
  69. package/dist/esm/components/Skeleton.js +35 -0
  70. package/dist/esm/components/Skeleton.js.map +1 -0
  71. package/dist/esm/components/TransitionBox.d.ts +10 -0
  72. package/dist/esm/components/TransitionBox.js +50 -0
  73. package/dist/esm/components/TransitionBox.js.map +1 -0
  74. package/dist/esm/components/TransitionNum.d.ts +16 -0
  75. package/dist/esm/components/TransitionNum.js +65 -0
  76. package/dist/esm/components/TransitionNum.js.map +1 -0
  77. package/dist/esm/components/Trapezium.d.ts +9 -0
  78. package/dist/esm/components/Trapezium.js +35 -0
  79. package/dist/esm/components/Trapezium.js.map +1 -0
  80. package/dist/esm/index.d.ts +13 -265
  81. package/dist/esm/index.js +13 -843
  82. package/dist/esm/index.js.map +1 -1
  83. package/package.json +3 -3
  84. package/src/components/AutoFit.tsx +95 -0
  85. package/src/components/AutoScroll.tsx +1 -0
  86. package/src/components/AutoSizeTextarea.tsx +31 -0
  87. package/src/components/CircleText.tsx +56 -0
  88. package/src/components/Flow.tsx +154 -0
  89. package/src/components/InputFile.tsx +193 -0
  90. package/src/components/LoopSwiper.tsx +101 -0
  91. package/src/components/Ring.tsx +19 -0
  92. package/src/components/Scroll.tsx +1 -0
  93. package/src/components/SectionRing.tsx +36 -0
  94. package/src/components/Skeleton.tsx +38 -0
  95. package/src/components/TransitionBox.tsx +36 -0
  96. package/src/components/TransitionNum.tsx +54 -0
  97. package/src/components/Trapezium.tsx +35 -0
  98. package/src/index.tsx +13 -862
  99. package/dist/cjs/skeleton.css +0 -18
  100. package/dist/esm/skeleton.css +0 -18
  101. package/src/skeleton.css +0 -18
package/dist/esm/index.js CHANGED
@@ -1,845 +1,15 @@
1
- "use client";
2
-
3
- import { css } from "@emotion/css";
4
- import { clsx, drawArc, setFrameInterval } from "deepsea-tools";
5
- import { Fragment, forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
6
- import { read, utils, writeFile } from "xlsx";
7
- import { jsx as _jsx } from "react/jsx-runtime";
8
- import { jsxs as _jsxs } from "react/jsx-runtime";
9
- export * from "./components/Scroll";
1
+ export * from "./components/AutoFit";
10
2
  export * from "./components/AutoScroll";
11
- export async function getFileData(file, type) {
12
- const fileReader = new FileReader();
13
- switch (type) {
14
- case "arrayBuffer":
15
- fileReader.readAsArrayBuffer(file);
16
- break;
17
- case "binary":
18
- fileReader.readAsBinaryString(file);
19
- break;
20
- case "base64":
21
- fileReader.readAsDataURL(file);
22
- break;
23
- case "text":
24
- fileReader.readAsText(file);
25
- break;
26
- default:
27
- return file;
28
- }
29
- return new Promise(resolve => {
30
- fileReader.addEventListener("load", () => {
31
- resolve(fileReader.result);
32
- });
33
- });
34
- }
35
-
36
- /** 专用于读取文件的组件 */
37
- export const InputFile = /*#__PURE__*/forwardRef((props, ref) => {
38
- const {
39
- multiple = false,
40
- type = "file",
41
- onChange,
42
- disabled: inputDisabled,
43
- clearAfterChange,
44
- ...others
45
- } = props;
46
- const [disabled, setDisabled] = useState(false);
47
- async function onInputChange(e) {
48
- const input = e.target;
49
- const {
50
- files
51
- } = input;
52
- if (!files || files.length === 0) return;
53
- setDisabled(true);
54
- try {
55
- if (multiple) {
56
- const result = [];
57
- for (const file of Array.from(files)) {
58
- result.push({
59
- result: await getFileData(file, type),
60
- file
61
- });
62
- }
63
- onChange?.(result);
64
- } else {
65
- onChange?.({
66
- result: await getFileData(files[0], type),
67
- file: files[0]
68
- });
69
- }
70
- setDisabled(false);
71
- if (clearAfterChange) input.value = "";
72
- } catch (error) {
73
- setDisabled(false);
74
- if (clearAfterChange) input.value = "";
75
- throw error;
76
- }
77
- }
78
- return /*#__PURE__*/_jsx("input", {
79
- disabled: disabled && inputDisabled,
80
- ref: ref,
81
- type: "file",
82
- multiple: multiple,
83
- onChange: onInputChange,
84
- ...others
85
- });
86
- });
87
- /** 专用于读取文件的 button 组件 */
88
- export const InputFileButton = /*#__PURE__*/forwardRef((props, ref) => {
89
- const {
90
- onClick,
91
- children,
92
- input: inputProps,
93
- ...others
94
- } = props;
95
- const {
96
- style,
97
- ...otherInputProps
98
- } = inputProps;
99
- const input = useRef(null);
100
- function onBtnClick(e) {
101
- input.current?.click();
102
- onClick?.(e);
103
- }
104
- return /*#__PURE__*/_jsxs("button", {
105
- ref: ref,
106
- type: "button",
107
- onClick: onBtnClick,
108
- ...others,
109
- children: [/*#__PURE__*/_jsx(InputFile, {
110
- ref: input,
111
- style: {
112
- display: "none",
113
- ...style
114
- },
115
- ...otherInputProps
116
- }), children]
117
- });
118
- });
119
-
120
- /** 专门用于读取 excel 的组件 */
121
- export const ImportExcel = /*#__PURE__*/forwardRef((props, ref) => {
122
- const {
123
- onChange,
124
- ...others
125
- } = props;
126
- function onInputChange(data) {
127
- const wb = read(data.result);
128
- const result = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
129
- if (typeof result === "object") {
130
- const $ = result.map(it => {
131
- const _ = {};
132
- Object.keys(it).filter(key => key !== "__rowNum__").forEach(key => _[key] = String(it[key]));
133
- return _;
134
- });
135
- onChange?.($);
136
- }
137
- }
138
- return /*#__PURE__*/_jsx(InputFile, {
139
- ref: ref,
140
- accept: ".xlsx",
141
- type: "arrayBuffer",
142
- onChange: onInputChange,
143
- ...others
144
- });
145
- });
146
-
147
- /** 手动导出 excel */
148
- export function exportExcel(data, name) {
149
- const workSheet = utils.json_to_sheet(data);
150
- const workBook = utils.book_new();
151
- utils.book_append_sheet(workBook, workSheet);
152
- writeFile(workBook, `${name}${name.endsWith(".xlsx") ? "" : ".xlsx"}`);
153
- }
154
- /** 导出 excel 的 button 组件 */
155
- export const ExportExcel = /*#__PURE__*/forwardRef((props, ref) => {
156
- const {
157
- data,
158
- fileName,
159
- onClick,
160
- ...others
161
- } = props;
162
- function onButtonClick(e) {
163
- exportExcel(data, fileName);
164
- onClick?.(e);
165
- }
166
- return /*#__PURE__*/_jsx("button", {
167
- ref: ref,
168
- onClick: onButtonClick,
169
- ...others
170
- });
171
- });
172
- /** 尺寸渐变的组件 */
173
- export const TransitionBox = props => {
174
- const {
175
- style,
176
- containerClassName,
177
- containerStyle,
178
- children,
179
- vertical = true,
180
- horizontal = true,
181
- time = 3000,
182
- ...others
183
- } = props;
184
- const box = useRef(null);
185
- const [width, setWidth] = useState(0);
186
- const [height, setHeight] = useState(0);
187
- const [count, setCount] = useState(0);
188
- useEffect(() => {
189
- const observer = new ResizeObserver(entries => {
190
- const {
191
- width: currentWidth,
192
- height: currentHeight
193
- } = entries[0].contentRect;
194
- setWidth(currentWidth);
195
- setHeight(currentHeight);
196
- });
197
- observer.observe(box.current);
198
- return () => {
199
- observer.disconnect();
200
- };
201
- }, []);
202
- useEffect(() => {
203
- setCount(count => Math.min(count + 1, 3));
204
- }, [width, height]);
205
- const outerStyle = {
206
- transitionProperty: count === 3 ? [horizontal && "width", vertical && "height"].filter(Boolean).join(", ") : undefined,
207
- transitionDuration: count === 3 ? `${time}ms` : undefined,
208
- width,
209
- height,
210
- overflow: "hidden",
211
- position: "relative",
212
- ...style
213
- };
214
- return /*#__PURE__*/_jsx("div", {
215
- style: outerStyle,
216
- ...others,
217
- children: /*#__PURE__*/_jsx("div", {
218
- className: containerClassName,
219
- style: {
220
- position: "absolute",
221
- ...containerStyle
222
- },
223
- ref: box,
224
- children: children
225
- })
226
- });
227
- };
228
- /** 雷达组件 */
229
- export const SeaRadar = props => {
230
- const {
231
- unitRadius = 50,
232
- circleCount = 4,
233
- circleWidth = 1,
234
- circleColor,
235
- directionCount = 36,
236
- directionWidth = 1,
237
- directionColor,
238
- backgroundColor,
239
- scanColor,
240
- scanAngle = Math.PI / 6,
241
- period = 8,
242
- targets,
243
- showGraduationLine,
244
- showGraduationText,
245
- showCircle,
246
- showDirection
247
- } = props;
248
- const style = {
249
- "--unit-radius": `${unitRadius}px`,
250
- "--circle-count": circleCount,
251
- "--circle-width": `${circleWidth}px`,
252
- "--circle-color": circleColor,
253
- "--direction-count": directionCount,
254
- "--direction-width": `${directionWidth}px`,
255
- "--direction-color": directionColor,
256
- "--background-color": backgroundColor,
257
- "--scan-color": scanColor,
258
- "--period": `${period}s`
259
- };
260
- return /*#__PURE__*/_jsxs("div", {
261
- className: "sea-radar-wrapper",
262
- style: style,
263
- children: [Array(180).fill(0).map((_, index) => /*#__PURE__*/_jsx("div", {
264
- className: "sea-radar-little-graduation",
265
- style: {
266
- transform: `rotateZ(${2 * index}deg)`,
267
- display: showGraduationLine ? "block" : "none"
268
- }
269
- })), Array(36).fill(0).map((_, index) => /*#__PURE__*/_jsx("div", {
270
- className: "sea-radar-graduation",
271
- style: {
272
- transform: `rotateZ(${10 * index}deg)`,
273
- display: showGraduationLine ? "block" : "none"
274
- },
275
- children: /*#__PURE__*/_jsx("span", {
276
- className: "sea-radar-graduation-text",
277
- style: {
278
- display: showGraduationText ? "block" : "none"
279
- },
280
- children: String(index * 10).padStart(3, "0")
281
- })
282
- })), /*#__PURE__*/_jsxs("div", {
283
- className: "sea-radar",
284
- children: [/*#__PURE__*/_jsx("div", {
285
- className: "sea-radar-scan",
286
- style: {
287
- height: `${unitRadius * circleCount * Math.tan(scanAngle)}px`,
288
- clipPath: `polygon(0 0, 0 100%, 100% 100%)`
289
- }
290
- }), showCircle && Array(circleCount).fill(0).map((_, index) => /*#__PURE__*/_jsx("div", {
291
- className: "sea-radar-circle",
292
- style: {
293
- width: `${unitRadius * 2 * (index + 1)}px`,
294
- height: `${unitRadius * 2 * (index + 1)}px`
295
- }
296
- })), showDirection && Array(directionCount).fill(0).map((_, index) => /*#__PURE__*/_jsx("div", {
297
- className: "sea-radar-direction",
298
- style: {
299
- transform: `rotateZ(${360 / directionCount * index}deg)`
300
- }
301
- })), targets?.map(it => /*#__PURE__*/_jsx("div", {
302
- className: "sea-radar-target",
303
- style: {
304
- left: `${unitRadius * circleCount + it.radius * Math.cos(it.angle)}px`,
305
- bottom: `${unitRadius * circleCount + it.radius * Math.sin(it.angle)}px`
306
- },
307
- children: it.element
308
- }))]
309
- })]
310
- });
311
- };
312
- /** 忘了什么组件 */
313
- export const Ring = props => {
314
- const {
315
- outerWidth,
316
- innerWidth,
317
- style,
318
- ...leftProps
319
- } = props;
320
- const outerRadius = outerWidth / 2;
321
- const innerRadius = innerWidth / 2;
322
- return /*#__PURE__*/_jsx("div", {
323
- style: {
324
- ...style,
325
- width: `${outerWidth}px`,
326
- height: `${outerWidth}px`,
327
- 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")`
328
- },
329
- ...leftProps
330
- });
331
- };
332
- export function getGapRange(gap) {
333
- if (typeof gap === "number") return [gap, gap];
334
- if (Array.isArray(gap)) return [gap[0] || 0, gap[1]];
335
- return [0, null];
336
- }
337
- export function getGapCountAndSize(width, itemWidth, minGap, maxGap) {
338
- const count = Math.floor((width + minGap) / (itemWidth + minGap)) || 1;
339
- if (count === 1) return [count, 0];
340
- const averageGap = (width - itemWidth * count) / (count - 1);
341
- if (averageGap < minGap) return [count, minGap];
342
- if (maxGap !== null && averageGap > maxGap) return [count, maxGap];
343
- return [count, averageGap];
344
- }
345
-
346
- /** 自适应浮动组件 */
347
- export function Flow(props) {
348
- const {
349
- itemWidth,
350
- itemHeight,
351
- columnGap,
352
- rowGap = 0,
353
- maxRows,
354
- data,
355
- render,
356
- keyExactor,
357
- className,
358
- style,
359
- containerClassName,
360
- containerStyle,
361
- throttle,
362
- transitionDuration,
363
- onSizeChange,
364
- ...others
365
- } = props;
366
- const [minColumnGap, maxColumnGap] = getGapRange(columnGap);
367
- const [width, setWidth] = useState(0);
368
- const [columnCount, setColumnCount] = useState(1);
369
- const [columnGapSize, setColumnGapSize] = useState(minColumnGap);
370
- const [showItems, setShowItems] = useState(false);
371
- const ele = useRef(null);
372
- const contentRows = Math.ceil(data.length / columnCount);
373
- const contentShownRows = typeof maxRows === "number" ? Math.min(contentRows, maxRows) : contentRows;
374
- const height = contentShownRows > 0 ? contentShownRows * (itemHeight + rowGap) - rowGap : 0;
375
- function getPosition(index) {
376
- const y = Math.floor(index / columnCount);
377
- const x = index - y * columnCount;
378
- return {
379
- left: x * (itemWidth + columnGapSize),
380
- top: y * (itemHeight + rowGap)
381
- };
382
- }
383
- function getHidden(index) {
384
- if (typeof maxRows !== "number") return false;
385
- return index >= maxRows * columnCount;
386
- }
387
- useEffect(() => {
388
- let timeout;
389
- const observer = new ResizeObserver(entries => {
390
- clearTimeout(timeout);
391
- function task() {
392
- const {
393
- inlineSize: width
394
- } = entries[0].borderBoxSize[0];
395
- const [newColumnCount, newColumnGapSize] = getGapCountAndSize(width, itemWidth, minColumnGap, maxColumnGap);
396
- setShowItems(true);
397
- setWidth(width);
398
- setColumnCount(newColumnCount);
399
- setColumnGapSize(newColumnGapSize);
400
- }
401
- if (throttle === null) {
402
- task();
403
- } else {
404
- timeout = window.setTimeout(task, throttle || 200);
405
- }
406
- });
407
- observer.observe(ele.current);
408
- return () => {
409
- observer.disconnect();
410
- };
411
- }, [itemWidth, throttle, columnGap]);
412
- useEffect(() => {
413
- onSizeChange?.({
414
- width,
415
- height,
416
- itemWidth,
417
- itemHeight,
418
- columnGap: columnGapSize,
419
- columnCount,
420
- rowGap,
421
- rowCount: contentShownRows,
422
- overflow: data.length > contentShownRows * columnCount,
423
- itemCount: data.length,
424
- maxRows: maxRows ?? null
425
- });
426
- }, [width, height, columnGapSize, columnCount, rowGap, contentShownRows, data.length, itemWidth, itemHeight, maxRows]);
427
- return /*#__PURE__*/_jsx("div", {
428
- ref: ele,
429
- className: className,
430
- style: {
431
- position: "relative",
432
- boxSizing: "border-box",
433
- height,
434
- ...style
435
- },
436
- ...others,
437
- children: showItems && data.map((it, idx) => /*#__PURE__*/_jsx("div", {
438
- className: containerClassName,
439
- style: {
440
- position: "absolute",
441
- width: itemWidth,
442
- height: itemHeight,
443
- transition: transitionDuration !== null ? `all ${transitionDuration ?? 400}ms` : undefined,
444
- ...getPosition(idx)
445
- },
446
- children: /*#__PURE__*/_jsx("div", {
447
- style: {
448
- width: itemWidth,
449
- height: itemHeight,
450
- display: maxRows && idx >= maxRows * columnCount ? "none" : "block",
451
- ...containerStyle
452
- },
453
- children: render(it, idx, getHidden(idx))
454
- })
455
- }, keyExactor?.(it, idx) || idx))
456
- });
457
- }
458
- /** 梯形组件 */
459
- export const Trapezium = /*#__PURE__*/forwardRef((props, ref) => {
460
- const {
461
- top,
462
- bottom,
463
- height,
464
- borderRadius,
465
- style,
466
- ...other
467
- } = props;
468
- const diff = (bottom - top) / 2;
469
- const a = Math.atan(height / diff) / 2;
470
- const b = borderRadius / Math.tan(a);
471
- const c = b * Math.cos(a * 2);
472
- const d = b * Math.sin(a * 2);
473
- const e = Math.PI / 2 - a;
474
- const f = borderRadius / Math.tan(e);
475
- const g = f * Math.cos(a * 2);
476
- const h = f * Math.sin(a * 2);
477
- return /*#__PURE__*/_jsx("div", {
478
- ref: ref,
479
- style: {
480
- width: bottom,
481
- height,
482
- clipPath: `path("M ${diff + f} ${0} A ${borderRadius} ${borderRadius} 0 0 0 ${diff - g} ${h} L ${c} ${height - d} A ${borderRadius} ${borderRadius} 0 0 0 ${b} ${height} L ${bottom - b} ${height} A ${borderRadius} ${borderRadius} 0 0 0 ${bottom - c} ${height - d} L ${top + diff + g} ${h} A ${borderRadius} ${borderRadius} 0 0 0 ${top + diff - f} ${0} Z")`,
483
- ...style
484
- },
485
- ...other
486
- });
487
- });
488
- css`
489
- @keyframes deepsea-horizontal-loop-swipe {
490
- from {
491
- transform: translateX(0);
492
- }
493
- to {
494
- transform: translateX(-100%);
495
- }
496
- }
497
- @keyframes deepsea-reverse-horizontal-loop-swipe {
498
- from {
499
- transform: translateX(0);
500
- }
501
- to {
502
- transform: translateX(100%);
503
- }
504
- }
505
- @keyframes deepsea-vertical-loop-swipe {
506
- from {
507
- transform: translateY(0);
508
- }
509
- to {
510
- transform: translateY(-100%);
511
- }
512
- }
513
- @keyframes deepsea-reverse-vertical-loop-swipe {
514
- from {
515
- transform: translateY(0);
516
- }
517
- to {
518
- transform: translateY(100%);
519
- }
520
- }
521
- `;
522
-
523
- /** 循环播放组件 */
524
- export const LoopSwiper = /*#__PURE__*/forwardRef((props, ref) => {
525
- const {
526
- style,
527
- children,
528
- direction,
529
- period,
530
- reverse,
531
- gap,
532
- ...others
533
- } = props;
534
- const wrapper = useRef(null);
535
- const container = useRef(null);
536
- const [swiper, setSwiper] = useState(false);
537
- const directionRef = useRef(direction);
538
- directionRef.current = direction;
539
- const flexDirection = direction === "vertical" ? reverse ? "column-reverse" : "column" : reverse ? "row-reverse" : "row";
540
- 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";
541
- const animationDuration = `${period}ms`;
542
- const animationTimingFunction = "linear";
543
- const animationIterationCount = "infinite";
544
- useImperativeHandle(ref, () => wrapper.current);
545
- useEffect(() => {
546
- const wrapperEle = wrapper.current;
547
- const containerEle = container.current;
548
- let wrapperWidth = 0;
549
- let wrapperHeight = 0;
550
- let containerWidth = 0;
551
- let containerHeight = 0;
552
- const observer = new ResizeObserver(entries => {
553
- entries.forEach(entry => {
554
- if (entry.target === wrapperEle) {
555
- wrapperWidth = entry.contentRect.width;
556
- wrapperHeight = entry.contentRect.height;
557
- } else if (entry.target === containerEle) {
558
- containerWidth = entry.contentRect.width;
559
- containerHeight = entry.contentRect.height;
560
- }
561
- });
562
- setSwiper(directionRef.current === "vertical" ? containerHeight > wrapperHeight : containerWidth > wrapperWidth);
563
- });
564
- observer.observe(wrapperEle);
565
- observer.observe(containerEle);
566
- }, []);
567
- return /*#__PURE__*/_jsxs("div", {
568
- ref: wrapper,
569
- style: {
570
- display: "flex",
571
- flexDirection,
572
- gap,
573
- ...style
574
- },
575
- ...others,
576
- children: [/*#__PURE__*/_jsx("div", {
577
- ref: container,
578
- style: {
579
- display: "flex",
580
- flexDirection,
581
- gap,
582
- animationName,
583
- animationTimingFunction,
584
- animationDuration,
585
- animationIterationCount
586
- },
587
- children: children
588
- }), /*#__PURE__*/_jsx("div", {
589
- style: {
590
- display: swiper ? "flex" : "none",
591
- flexDirection,
592
- gap,
593
- animationName,
594
- animationTimingFunction,
595
- animationDuration,
596
- animationIterationCount
597
- },
598
- children: children
599
- })]
600
- });
601
- });
602
- export const SectionRing = props => {
603
- const {
604
- outerRadius: o,
605
- innerRadius: i,
606
- count: c,
607
- angel: a,
608
- style,
609
- ...others
610
- } = props;
611
- const s = Math.PI * 2 / c - a;
612
- function arc(radius, startAngle, endAngle, options = {}) {
613
- return drawArc(o, o, radius, startAngle, endAngle, options);
614
- }
615
- return /*#__PURE__*/_jsx("div", {
616
- style: {
617
- ...style,
618
- width: o * 2,
619
- height: o * 2,
620
- clipPath: `path("${Array(c).fill(0).map((it, idx) => `${arc(o, idx * (a + s), idx * (a + s) + a)} ${arc(i, idx * (a + s) + a, idx * (a + s), {
621
- line: true,
622
- anticlockwise: true
623
- })}`).join(" ")} Z")`
624
- },
625
- ...others
626
- });
627
- };
628
- /** 渐变数字组件 */
629
- export const TransitionNum = /*#__PURE__*/forwardRef((props, ref) => {
630
- const {
631
- children: num,
632
- period,
633
- numToStr,
634
- ...others
635
- } = props;
636
- if (!Number.isInteger(num) || !Number.isInteger(period) || period <= 0) {
637
- throw new RangeError("目标数字必须是整数,周期必须是正整数");
638
- }
639
- const ele = useRef(null);
640
- const cache = useRef({
641
- num,
642
- period,
643
- numToStr,
644
- show: num
645
- });
646
- cache.current = {
647
- ...cache.current,
648
- num,
649
- period,
650
- numToStr
651
- };
652
- useImperativeHandle(ref, () => ({
653
- get: () => cache.current.show
654
- }), []);
655
- useEffect(() => {
656
- const {
657
- num,
658
- period,
659
- show,
660
- numToStr
661
- } = cache.current;
662
- ele.current.innerText = (numToStr || String)(show);
663
- if (num === show) return;
664
- const div = ele.current;
665
- const speed = (num - show) / period;
666
- const cancel = setFrameInterval(() => {
667
- const {
668
- num,
669
- numToStr
670
- } = cache.current;
671
- cache.current.show += speed;
672
- if (speed > 0 && cache.current.show > num || speed < 0 && cache.current.show < num) {
673
- cancel();
674
- cache.current.show = num;
675
- }
676
- div.innerText = (numToStr || String)(speed > 0 ? Math.floor(cache.current.show) : Math.ceil(cache.current.show));
677
- }, 1);
678
- return cancel;
679
- }, [num]);
680
- return /*#__PURE__*/_jsx("div", {
681
- ref: ele,
682
- ...others
683
- });
684
- });
685
- /** 环形文字 */
686
- export const CircleText = props => {
687
- const {
688
- width,
689
- height,
690
- radius,
691
- startAngel = 0,
692
- gapAngel = 0,
693
- align = "center",
694
- style,
695
- direction = "outer",
696
- reverse = false,
697
- separator,
698
- children,
699
- ...others
700
- } = props;
701
- const unitAngle = Math.atan(width / 2 / radius) * 2;
702
- const totalAngle = (unitAngle + gapAngel) * children.length - gapAngel;
703
- const offsetAngle = align === "left" ? 0 : align === "right" ? totalAngle : totalAngle / 2;
704
- function getTransform(idx) {
705
- const angle = startAngel - idx * (unitAngle + gapAngel) + offsetAngle - unitAngle / 2;
706
- const x = (radius + height / 2) * Math.cos(angle) - width / 2;
707
- const y = (radius + height / 2) * Math.sin(angle) * -1 - height / 2;
708
- const z = Math.PI / 2 - angle + (direction === "inner" ? Math.PI : 0);
709
- return `translateX(${x}px) translateY(${y}px) rotateZ(${z / Math.PI * 180}deg)`;
710
- }
711
- const words = typeof separator === "function" ? separator(children) : children.split(separator ?? "");
712
- if (reverse) words.reverse();
713
- return /*#__PURE__*/_jsx(Fragment, {
714
- children: words.map((w, idx) => /*#__PURE__*/_jsx("span", {
715
- style: {
716
- position: "absolute",
717
- ...style,
718
- transform: getTransform(idx),
719
- textAlign: "center",
720
- width,
721
- lineHeight: `${height}px`,
722
- height: height
723
- },
724
- ...others,
725
- children: w
726
- }, idx))
727
- });
728
- };
729
- export const AutoSizeTextArea = /*#__PURE__*/forwardRef((props, ref) => {
730
- const {
731
- style = {},
732
- ...others
733
- } = props;
734
- const {
735
- height,
736
- resize,
737
- overflowY,
738
- ...otherStyle
739
- } = style;
740
- const ele = useRef(null);
741
- useImperativeHandle(ref, () => ele.current);
742
- useEffect(() => {
743
- const textarea = ele.current;
744
- function resizeTextarea() {
745
- textarea.style.height = "auto";
746
- textarea.style.height = `${textarea.scrollHeight + textarea.offsetHeight - textarea.clientHeight}px`;
747
- }
748
- textarea.addEventListener("input", resizeTextarea);
749
- textarea.addEventListener("change", resizeTextarea);
750
- return () => {
751
- textarea.removeEventListener("input", resizeTextarea);
752
- textarea.removeEventListener("change", resizeTextarea);
753
- };
754
- }, []);
755
- return /*#__PURE__*/_jsx("textarea", {
756
- ref: ele,
757
- style: {
758
- ...otherStyle,
759
- resize: "none",
760
- overflowY: "hidden"
761
- },
762
- ...others
763
- });
764
- });
765
- /**
766
- * 自适应缩放组件
767
- *
768
- * 注意:
769
- * 1. 父元素必须设置非 static 定位方式
770
- * 2. 父元素只能有且仅有一个子元素,那就是 AutoFit
771
- * 3. 不要设置 AutoFit 的 position、left、top、transform、width、height 属性
772
- * 4. 在第一次完成缩放前,无论 props 是什么,返回的都是 <div style={{ display: "none" }} />
773
- * 5. 元素的属性、事件、资源并不是立即加载的,会有一帧的延迟,在第一次完成缩放后才会显示
774
- */
775
- export const AutoFit = /*#__PURE__*/forwardRef((props, ref) => {
776
- const {
777
- width = 1920,
778
- height = 1080,
779
- direction,
780
- className,
781
- ...rest
782
- } = props;
783
- const ele = useRef(null);
784
- const [show, setShow] = useState(false);
785
- useImperativeHandle(ref, () => ele.current, [ele.current]);
786
- useLayoutEffect(() => {
787
- const element = ele.current;
788
- const parent = element?.parentElement;
789
- if (!element || !parent) return;
790
- function listener(entries) {
791
- const entry = entries[0];
792
- const {
793
- contentRect
794
- } = entry;
795
- if (direction === "horizontal") {
796
- const scale = contentRect.width / width;
797
- element?.style.setProperty("--transform", `scale(${scale})`);
798
- element?.style.setProperty("--width", `${width}px`);
799
- element?.style.setProperty("--height", `${contentRect.height / scale}px`);
800
- } else if (direction === "vertical") {
801
- const scale = contentRect.height / height;
802
- element?.style.setProperty("--transform", `scale(${scale})`);
803
- element?.style.setProperty("--width", `${contentRect.width / scale}px`);
804
- element?.style.setProperty("--height", `${height}px`);
805
- } else {
806
- const scale = Math.min(contentRect.width / width, contentRect.height / height);
807
- element?.style.setProperty("--transform", `translateX(${(contentRect.width - width * scale) / 2}px) translateY(${(contentRect.height - height * scale) / 2}px) scale(${scale})`);
808
- element?.style.setProperty("--width", `${width}px`);
809
- element?.style.setProperty("--height", `${height}px`);
810
- }
811
- setShow(true);
812
- }
813
- const observer = new ResizeObserver(listener);
814
- observer.observe(parent);
815
- return () => observer.disconnect();
816
- }, [ele.current?.parentElement, width, height, direction]);
817
- if (process.env.NODE_ENV === "development") {
818
- useEffect(() => {
819
- const parent = ele.current?.parentElement;
820
- if (!parent) return;
821
- const style = getComputedStyle(parent);
822
- if (style.position === "static") {
823
- console.warn("AutoFit 组件的父元素的 position 属性不应该是 static");
824
- }
825
- }, [ele.current?.parentElement]);
826
- }
827
- if (!show) return /*#__PURE__*/_jsx("div", {
828
- ref: ele,
829
- style: {
830
- display: "none"
831
- }
832
- });
833
- return /*#__PURE__*/_jsx("div", {
834
- ref: ele,
835
- className: clsx(css`
836
- position: absolute;
837
- transform: var(--transform);
838
- transform-origin: top left;
839
- width: var(--width);
840
- height: var(--height);
841
- `, className),
842
- ...rest
843
- });
844
- });
3
+ export * from "./components/AutoSizeTextarea";
4
+ export * from "./components/CircleText";
5
+ export * from "./components/Flow";
6
+ export * from "./components/InputFile";
7
+ export * from "./components/LoopSwiper";
8
+ export * from "./components/Ring";
9
+ export * from "./components/Scroll";
10
+ export * from "./components/SectionRing";
11
+ export * from "./components/Skeleton";
12
+ export * from "./components/TransitionBox";
13
+ export * from "./components/TransitionNum";
14
+ export * from "./components/Trapezium";
845
15
  //# sourceMappingURL=index.js.map