deepsea-components 5.15.21 → 5.15.23
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.
- package/README.md +23 -23
- package/dist/components/AutoFit.cjs +7 -7
- package/dist/components/AutoFit.js +7 -7
- package/dist/components/AutoScroll.cjs +7 -7
- package/dist/components/AutoScroll.js +7 -7
- package/dist/components/AutoSizeTextarea.cjs +4 -4
- package/dist/components/AutoSizeTextarea.js +4 -4
- package/dist/components/Flow.cjs +16 -16
- package/dist/components/Flow.js +16 -16
- package/dist/components/FormLabel.cjs +1 -1
- package/dist/components/FormLabel.js +1 -1
- package/dist/components/InfiniteScroll.cjs +13 -13
- package/dist/components/InfiniteScroll.js +13 -13
- package/dist/components/LoopSwiper.cjs +33 -33
- package/dist/components/LoopSwiper.js +33 -33
- package/dist/components/Scroll.cjs +13 -13
- package/dist/components/Scroll.js +13 -13
- package/dist/components/ScrollMask.module.cjs +2 -2
- package/dist/components/ScrollMask.module.js +2 -2
- package/dist/components/Skeleton.cjs +17 -17
- package/dist/components/Skeleton.js +17 -17
- package/dist/components/TransitionNum.cjs +1 -1
- package/dist/components/TransitionNum.js +1 -1
- package/dist/components/Trapezium.cjs +4 -4
- package/dist/components/Trapezium.js +4 -4
- package/package.json +4 -3
- package/src/components/AutoFit.tsx +104 -104
- package/src/components/AutoScroll.tsx +150 -150
- package/src/components/AutoSizeTextarea.tsx +50 -50
- package/src/components/CircleText.tsx +81 -81
- package/src/components/CopyButton.tsx +31 -31
- package/src/components/Echart.tsx +69 -69
- package/src/components/Flow.tsx +271 -271
- package/src/components/FormLabel.tsx +41 -41
- package/src/components/HlsPlayer.tsx +34 -34
- package/src/components/IconFileType.tsx +162 -162
- package/src/components/InfiniteScroll.tsx +163 -163
- package/src/components/InputFile.tsx +93 -93
- package/src/components/InputFileButton.tsx +122 -122
- package/src/components/LoopSwiper.tsx +125 -125
- package/src/components/ReadExcel.tsx +13 -13
- package/src/components/ReadSheet.tsx +17 -17
- package/src/components/Ring.tsx +30 -30
- package/src/components/Scroll.tsx +97 -97
- package/src/components/ScrollMask.module.css +87 -87
- package/src/components/ScrollMask.tsx +68 -68
- package/src/components/SectionRing.tsx +40 -40
- package/src/components/Skeleton.tsx +45 -45
- package/src/components/Title.tsx +27 -27
- package/src/components/TransitionBox.tsx +44 -44
- package/src/components/TransitionNum.tsx +54 -54
- package/src/components/Trapezium.tsx +60 -60
- package/src/components/Unify.tsx +38 -38
- package/src/components/WriteExcel.tsx +13 -13
- package/src/components/WriteSheet.tsx +25 -25
- package/src/utils/getReactVersion.ts +7 -7
- package/src/utils/index.ts +33 -33
- package/tsconfig.json +16 -16
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { css } from "@emotion/css"
|
|
4
|
-
import { clsx } from "deepsea-tools"
|
|
5
|
-
import { HTMLAttributes, forwardRef } from "react"
|
|
6
|
-
|
|
7
|
-
export interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {
|
|
8
|
-
loading?: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>((props, ref) => {
|
|
12
|
-
const { className, children, loading = children === undefined || children === null, ...rest } = props
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<div
|
|
16
|
-
ref={ref}
|
|
17
|
-
className={clsx(
|
|
18
|
-
css`
|
|
19
|
-
@keyframes shimmer {
|
|
20
|
-
0% {
|
|
21
|
-
background-position: -400px 0px;
|
|
22
|
-
}
|
|
23
|
-
100% {
|
|
24
|
-
background-position: 400px 0px;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
`,
|
|
28
|
-
loading &&
|
|
29
|
-
css`
|
|
30
|
-
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.067) 8%, rgba(0, 0, 0, 0.133) 18%, rgba(0, 0, 0, 0.067) 33%);
|
|
31
|
-
animation-duration: 1s;
|
|
32
|
-
animation-fill-mode: forwards;
|
|
33
|
-
animation-iteration-count: infinite;
|
|
34
|
-
animation-name: shimmer;
|
|
35
|
-
animation-timing-function: linear;
|
|
36
|
-
background-size: 800px 104px;
|
|
37
|
-
`,
|
|
38
|
-
className,
|
|
39
|
-
)}
|
|
40
|
-
{...rest}
|
|
41
|
-
>
|
|
42
|
-
{children}
|
|
43
|
-
</div>
|
|
44
|
-
)
|
|
45
|
-
})
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { css } from "@emotion/css"
|
|
4
|
+
import { clsx } from "deepsea-tools"
|
|
5
|
+
import { HTMLAttributes, forwardRef } from "react"
|
|
6
|
+
|
|
7
|
+
export interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
loading?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>((props, ref) => {
|
|
12
|
+
const { className, children, loading = children === undefined || children === null, ...rest } = props
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div
|
|
16
|
+
ref={ref}
|
|
17
|
+
className={clsx(
|
|
18
|
+
css`
|
|
19
|
+
@keyframes shimmer {
|
|
20
|
+
0% {
|
|
21
|
+
background-position: -400px 0px;
|
|
22
|
+
}
|
|
23
|
+
100% {
|
|
24
|
+
background-position: 400px 0px;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`,
|
|
28
|
+
loading &&
|
|
29
|
+
css`
|
|
30
|
+
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.067) 8%, rgba(0, 0, 0, 0.133) 18%, rgba(0, 0, 0, 0.067) 33%);
|
|
31
|
+
animation-duration: 1s;
|
|
32
|
+
animation-fill-mode: forwards;
|
|
33
|
+
animation-iteration-count: infinite;
|
|
34
|
+
animation-name: shimmer;
|
|
35
|
+
animation-timing-function: linear;
|
|
36
|
+
background-size: 800px 104px;
|
|
37
|
+
`,
|
|
38
|
+
className,
|
|
39
|
+
)}
|
|
40
|
+
{...rest}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</div>
|
|
44
|
+
)
|
|
45
|
+
})
|
package/src/components/Title.tsx
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { isBrowser } from "deepsea-tools"
|
|
4
|
-
import { ComponentPropsWithoutRef, forwardRef, useImperativeHandle, useLayoutEffect, useRef } from "react"
|
|
5
|
-
import { createPortal } from "react-dom"
|
|
6
|
-
|
|
7
|
-
import { getReactVersion } from "@/utils/getReactVersion"
|
|
8
|
-
|
|
9
|
-
export type TitleProps = ComponentPropsWithoutRef<"title">
|
|
10
|
-
|
|
11
|
-
const [major] = getReactVersion()
|
|
12
|
-
|
|
13
|
-
export const Title = forwardRef<HTMLTitleElement, TitleProps>((props, ref) => {
|
|
14
|
-
if (major >= 19) return <title ref={ref} {...props} />
|
|
15
|
-
|
|
16
|
-
const ele = useRef<HTMLTitleElement>(null)
|
|
17
|
-
|
|
18
|
-
useImperativeHandle(ref, () => ele.current as HTMLTitleElement, [ele.current])
|
|
19
|
-
|
|
20
|
-
useLayoutEffect(() => {
|
|
21
|
-
const title = document.head.querySelector("title")
|
|
22
|
-
if (title === ele.current) return
|
|
23
|
-
document.head.insertBefore(ele.current as HTMLTitleElement, title)
|
|
24
|
-
}, [])
|
|
25
|
-
|
|
26
|
-
return isBrowser && createPortal(<title ref={ele} {...props} />, document.head)
|
|
27
|
-
})
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { isBrowser } from "deepsea-tools"
|
|
4
|
+
import { ComponentPropsWithoutRef, forwardRef, useImperativeHandle, useLayoutEffect, useRef } from "react"
|
|
5
|
+
import { createPortal } from "react-dom"
|
|
6
|
+
|
|
7
|
+
import { getReactVersion } from "@/utils/getReactVersion"
|
|
8
|
+
|
|
9
|
+
export type TitleProps = ComponentPropsWithoutRef<"title">
|
|
10
|
+
|
|
11
|
+
const [major] = getReactVersion()
|
|
12
|
+
|
|
13
|
+
export const Title = forwardRef<HTMLTitleElement, TitleProps>((props, ref) => {
|
|
14
|
+
if (major >= 19) return <title ref={ref} {...props} />
|
|
15
|
+
|
|
16
|
+
const ele = useRef<HTMLTitleElement>(null)
|
|
17
|
+
|
|
18
|
+
useImperativeHandle(ref, () => ele.current as HTMLTitleElement, [ele.current])
|
|
19
|
+
|
|
20
|
+
useLayoutEffect(() => {
|
|
21
|
+
const title = document.head.querySelector("title")
|
|
22
|
+
if (title === ele.current) return
|
|
23
|
+
document.head.insertBefore(ele.current as HTMLTitleElement, title)
|
|
24
|
+
}, [])
|
|
25
|
+
|
|
26
|
+
return isBrowser && createPortal(<title ref={ele} {...props} />, document.head)
|
|
27
|
+
})
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { CSSProperties, FC, HTMLAttributes, forwardRef, useEffect, useRef, useState } from "react"
|
|
4
|
-
import { useSize } from "soda-hooks"
|
|
5
|
-
|
|
6
|
-
export interface TransitionBoxProps extends HTMLAttributes<HTMLDivElement> {
|
|
7
|
-
containerClassName?: string
|
|
8
|
-
containerStyle?: CSSProperties
|
|
9
|
-
vertical?: boolean
|
|
10
|
-
horizontal?: boolean
|
|
11
|
-
time?: number
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** 尺寸渐变的组件 */
|
|
15
|
-
export const TransitionBox: FC<TransitionBoxProps> = forwardRef<HTMLDivElement, TransitionBoxProps>((props, ref) => {
|
|
16
|
-
const { style, containerClassName, containerStyle, children, vertical = true, horizontal = true, time = 3000, ...rest } = props
|
|
17
|
-
const container = useRef<HTMLDivElement>(null)
|
|
18
|
-
const size = useSize(container)
|
|
19
|
-
const width = size?.width ?? 0
|
|
20
|
-
const height = size?.height ?? 0
|
|
21
|
-
const [count, setCount] = useState(0)
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
setCount(count => Math.min(count + 1, 3))
|
|
25
|
-
}, [width, height])
|
|
26
|
-
|
|
27
|
-
const outerStyle: CSSProperties = {
|
|
28
|
-
transitionProperty: count === 3 ? [horizontal && "width", vertical && "height"].filter(Boolean).join(", ") : undefined,
|
|
29
|
-
transitionDuration: count === 3 ? `${time}ms` : undefined,
|
|
30
|
-
width,
|
|
31
|
-
height,
|
|
32
|
-
overflow: "hidden",
|
|
33
|
-
position: "relative",
|
|
34
|
-
...style,
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div ref={ref} style={outerStyle} {...rest}>
|
|
39
|
-
<div className={containerClassName} style={{ position: "absolute", ...containerStyle }} ref={container}>
|
|
40
|
-
{children}
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
)
|
|
44
|
-
})
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { CSSProperties, FC, HTMLAttributes, forwardRef, useEffect, useRef, useState } from "react"
|
|
4
|
+
import { useSize } from "soda-hooks"
|
|
5
|
+
|
|
6
|
+
export interface TransitionBoxProps extends HTMLAttributes<HTMLDivElement> {
|
|
7
|
+
containerClassName?: string
|
|
8
|
+
containerStyle?: CSSProperties
|
|
9
|
+
vertical?: boolean
|
|
10
|
+
horizontal?: boolean
|
|
11
|
+
time?: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** 尺寸渐变的组件 */
|
|
15
|
+
export const TransitionBox: FC<TransitionBoxProps> = forwardRef<HTMLDivElement, TransitionBoxProps>((props, ref) => {
|
|
16
|
+
const { style, containerClassName, containerStyle, children, vertical = true, horizontal = true, time = 3000, ...rest } = props
|
|
17
|
+
const container = useRef<HTMLDivElement>(null)
|
|
18
|
+
const size = useSize(container)
|
|
19
|
+
const width = size?.width ?? 0
|
|
20
|
+
const height = size?.height ?? 0
|
|
21
|
+
const [count, setCount] = useState(0)
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
setCount(count => Math.min(count + 1, 3))
|
|
25
|
+
}, [width, height])
|
|
26
|
+
|
|
27
|
+
const outerStyle: CSSProperties = {
|
|
28
|
+
transitionProperty: count === 3 ? [horizontal && "width", vertical && "height"].filter(Boolean).join(", ") : undefined,
|
|
29
|
+
transitionDuration: count === 3 ? `${time}ms` : undefined,
|
|
30
|
+
width,
|
|
31
|
+
height,
|
|
32
|
+
overflow: "hidden",
|
|
33
|
+
position: "relative",
|
|
34
|
+
...style,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div ref={ref} style={outerStyle} {...rest}>
|
|
39
|
+
<div className={containerClassName} style={{ position: "absolute", ...containerStyle }} ref={container}>
|
|
40
|
+
{children}
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
)
|
|
44
|
+
})
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { setFrameInterval } from "deepsea-tools"
|
|
4
|
-
import { ForwardedRef, HTMLAttributes, forwardRef, useEffect, useImperativeHandle, useRef } from "react"
|
|
5
|
-
|
|
6
|
-
export interface TransitionNumProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
7
|
-
/** 当前数字 */
|
|
8
|
-
children: number
|
|
9
|
-
/** 变换周期,单位帧 */
|
|
10
|
-
period: number
|
|
11
|
-
/** 数字转换为字符串的方法 */
|
|
12
|
-
numToStr?: (num: number) => string
|
|
13
|
-
/** 实例 */
|
|
14
|
-
ins?: ForwardedRef<TransitionNumIns>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface TransitionNumIns {
|
|
18
|
-
get(): number
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** 渐变数字组件 */
|
|
22
|
-
export const TransitionNum = forwardRef<HTMLDivElement, TransitionNumProps>((props, ref) => {
|
|
23
|
-
const { children: num, period, numToStr, ins, ...rest } = props
|
|
24
|
-
if (!Number.isInteger(num) || !Number.isInteger(period) || period <= 0) {
|
|
25
|
-
throw new RangeError("目标数字必须是整数,周期必须是正整数")
|
|
26
|
-
}
|
|
27
|
-
const ele = useRef<HTMLDivElement>(null)
|
|
28
|
-
const cache = useRef({ num, period, numToStr, show: num })
|
|
29
|
-
cache.current = { ...cache.current, num, period, numToStr }
|
|
30
|
-
|
|
31
|
-
useImperativeHandle(ref, () => ele.current!, [])
|
|
32
|
-
useImperativeHandle(ins, () => ({ get: () => cache.current.show }), [])
|
|
33
|
-
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
const { num, period, show, numToStr } = cache.current
|
|
36
|
-
ele.current!.innerText = (numToStr || String)(show)
|
|
37
|
-
if (num === show) return
|
|
38
|
-
const div = ele.current!
|
|
39
|
-
const speed = (num - show) / period
|
|
40
|
-
const cancel = setFrameInterval(() => {
|
|
41
|
-
const { num, numToStr } = cache.current
|
|
42
|
-
cache.current.show += speed
|
|
43
|
-
if ((speed > 0 && cache.current.show > num) || (speed < 0 && cache.current.show < num)) {
|
|
44
|
-
cancel()
|
|
45
|
-
cache.current.show = num
|
|
46
|
-
}
|
|
47
|
-
div.innerText = (numToStr || String)(speed > 0 ? Math.floor(cache.current.show) : Math.ceil(cache.current.show))
|
|
48
|
-
}, 1)
|
|
49
|
-
|
|
50
|
-
return cancel
|
|
51
|
-
}, [num])
|
|
52
|
-
|
|
53
|
-
return <div ref={ele} {...rest} />
|
|
54
|
-
})
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { setFrameInterval } from "deepsea-tools"
|
|
4
|
+
import { ForwardedRef, HTMLAttributes, forwardRef, useEffect, useImperativeHandle, useRef } from "react"
|
|
5
|
+
|
|
6
|
+
export interface TransitionNumProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
7
|
+
/** 当前数字 */
|
|
8
|
+
children: number
|
|
9
|
+
/** 变换周期,单位帧 */
|
|
10
|
+
period: number
|
|
11
|
+
/** 数字转换为字符串的方法 */
|
|
12
|
+
numToStr?: (num: number) => string
|
|
13
|
+
/** 实例 */
|
|
14
|
+
ins?: ForwardedRef<TransitionNumIns>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TransitionNumIns {
|
|
18
|
+
get(): number
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** 渐变数字组件 */
|
|
22
|
+
export const TransitionNum = forwardRef<HTMLDivElement, TransitionNumProps>((props, ref) => {
|
|
23
|
+
const { children: num, period, numToStr, ins, ...rest } = props
|
|
24
|
+
if (!Number.isInteger(num) || !Number.isInteger(period) || period <= 0) {
|
|
25
|
+
throw new RangeError("目标数字必须是整数,周期必须是正整数")
|
|
26
|
+
}
|
|
27
|
+
const ele = useRef<HTMLDivElement>(null)
|
|
28
|
+
const cache = useRef({ num, period, numToStr, show: num })
|
|
29
|
+
cache.current = { ...cache.current, num, period, numToStr }
|
|
30
|
+
|
|
31
|
+
useImperativeHandle(ref, () => ele.current!, [])
|
|
32
|
+
useImperativeHandle(ins, () => ({ get: () => cache.current.show }), [])
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const { num, period, show, numToStr } = cache.current
|
|
36
|
+
ele.current!.innerText = (numToStr || String)(show)
|
|
37
|
+
if (num === show) return
|
|
38
|
+
const div = ele.current!
|
|
39
|
+
const speed = (num - show) / period
|
|
40
|
+
const cancel = setFrameInterval(() => {
|
|
41
|
+
const { num, numToStr } = cache.current
|
|
42
|
+
cache.current.show += speed
|
|
43
|
+
if ((speed > 0 && cache.current.show > num) || (speed < 0 && cache.current.show < num)) {
|
|
44
|
+
cancel()
|
|
45
|
+
cache.current.show = num
|
|
46
|
+
}
|
|
47
|
+
div.innerText = (numToStr || String)(speed > 0 ? Math.floor(cache.current.show) : Math.ceil(cache.current.show))
|
|
48
|
+
}, 1)
|
|
49
|
+
|
|
50
|
+
return cancel
|
|
51
|
+
}, [num])
|
|
52
|
+
|
|
53
|
+
return <div ref={ele} {...rest} />
|
|
54
|
+
})
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { css } from "@emotion/css"
|
|
4
|
-
import { clsx } from "deepsea-tools"
|
|
5
|
-
import { HTMLAttributes, forwardRef } from "react"
|
|
6
|
-
|
|
7
|
-
import { px, transformCSSVariable } from "@/utils"
|
|
8
|
-
|
|
9
|
-
export interface TrapeziumProps extends HTMLAttributes<HTMLDivElement> {
|
|
10
|
-
top: number
|
|
11
|
-
bottom: number
|
|
12
|
-
height: number
|
|
13
|
-
borderRadius: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** 梯形组件 */
|
|
17
|
-
export const Trapezium = forwardRef<HTMLDivElement, TrapeziumProps>((props, ref) => {
|
|
18
|
-
const { top, bottom, height, borderRadius, className, style, ...rest } = props
|
|
19
|
-
|
|
20
|
-
const diff = (bottom - top) / 2
|
|
21
|
-
|
|
22
|
-
const a = Math.atan(height / diff) / 2
|
|
23
|
-
|
|
24
|
-
const b = borderRadius / Math.tan(a)
|
|
25
|
-
|
|
26
|
-
const c = b * Math.cos(a * 2)
|
|
27
|
-
|
|
28
|
-
const d = b * Math.sin(a * 2)
|
|
29
|
-
|
|
30
|
-
const e = Math.PI / 2 - a
|
|
31
|
-
|
|
32
|
-
const f = borderRadius / Math.tan(e)
|
|
33
|
-
|
|
34
|
-
const g = f * Math.cos(a * 2)
|
|
35
|
-
|
|
36
|
-
const h = f * Math.sin(a * 2)
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<div
|
|
40
|
-
ref={ref}
|
|
41
|
-
className={clsx(
|
|
42
|
-
css`
|
|
43
|
-
width: var(--width);
|
|
44
|
-
height: var(--height);
|
|
45
|
-
clip-path: var(--clip-path);
|
|
46
|
-
`,
|
|
47
|
-
className,
|
|
48
|
-
)}
|
|
49
|
-
style={transformCSSVariable(
|
|
50
|
-
{
|
|
51
|
-
width: px(bottom),
|
|
52
|
-
height: px(height),
|
|
53
|
-
clipath: `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")`,
|
|
54
|
-
},
|
|
55
|
-
style,
|
|
56
|
-
)}
|
|
57
|
-
{...rest}
|
|
58
|
-
/>
|
|
59
|
-
)
|
|
60
|
-
})
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { css } from "@emotion/css"
|
|
4
|
+
import { clsx } from "deepsea-tools"
|
|
5
|
+
import { HTMLAttributes, forwardRef } from "react"
|
|
6
|
+
|
|
7
|
+
import { px, transformCSSVariable } from "@/utils"
|
|
8
|
+
|
|
9
|
+
export interface TrapeziumProps extends HTMLAttributes<HTMLDivElement> {
|
|
10
|
+
top: number
|
|
11
|
+
bottom: number
|
|
12
|
+
height: number
|
|
13
|
+
borderRadius: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** 梯形组件 */
|
|
17
|
+
export const Trapezium = forwardRef<HTMLDivElement, TrapeziumProps>((props, ref) => {
|
|
18
|
+
const { top, bottom, height, borderRadius, className, style, ...rest } = props
|
|
19
|
+
|
|
20
|
+
const diff = (bottom - top) / 2
|
|
21
|
+
|
|
22
|
+
const a = Math.atan(height / diff) / 2
|
|
23
|
+
|
|
24
|
+
const b = borderRadius / Math.tan(a)
|
|
25
|
+
|
|
26
|
+
const c = b * Math.cos(a * 2)
|
|
27
|
+
|
|
28
|
+
const d = b * Math.sin(a * 2)
|
|
29
|
+
|
|
30
|
+
const e = Math.PI / 2 - a
|
|
31
|
+
|
|
32
|
+
const f = borderRadius / Math.tan(e)
|
|
33
|
+
|
|
34
|
+
const g = f * Math.cos(a * 2)
|
|
35
|
+
|
|
36
|
+
const h = f * Math.sin(a * 2)
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div
|
|
40
|
+
ref={ref}
|
|
41
|
+
className={clsx(
|
|
42
|
+
css`
|
|
43
|
+
width: var(--width);
|
|
44
|
+
height: var(--height);
|
|
45
|
+
clip-path: var(--clip-path);
|
|
46
|
+
`,
|
|
47
|
+
className,
|
|
48
|
+
)}
|
|
49
|
+
style={transformCSSVariable(
|
|
50
|
+
{
|
|
51
|
+
width: px(bottom),
|
|
52
|
+
height: px(height),
|
|
53
|
+
clipath: `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")`,
|
|
54
|
+
},
|
|
55
|
+
style,
|
|
56
|
+
)}
|
|
57
|
+
{...rest}
|
|
58
|
+
/>
|
|
59
|
+
)
|
|
60
|
+
})
|
package/src/components/Unify.tsx
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { clsx } from "deepsea-tools"
|
|
4
|
-
import { CSSProperties, ComponentProps, FC, JSX, JSXElementConstructor, ReactNode, createContext, createElement, useContext } from "react"
|
|
5
|
-
|
|
6
|
-
export interface UnifyConfig {
|
|
7
|
-
className?: string
|
|
8
|
-
style?: CSSProperties
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const UnifyConfigContext = createContext<UnifyConfig>({})
|
|
12
|
-
|
|
13
|
-
export interface UnifyConfigProviderProps extends UnifyConfig {
|
|
14
|
-
children?: ReactNode
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const UnifyConfigProvider: FC<UnifyConfigProviderProps> = ({ className, style, children }) => {
|
|
18
|
-
const { className: _className, style: _style } = useContext(UnifyConfigContext)
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<UnifyConfigContext.Provider value={{ className: clsx(_className, className), style: { ..._style, ...style } }}>{children}</UnifyConfigContext.Provider>
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type UnifyProps<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "div"> = Omit<ComponentProps<AS>, "as"> & {
|
|
26
|
-
as?: AS
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function Unify<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "div">(props: UnifyProps<AS>) {
|
|
30
|
-
const { as = "div", className, style, ...rest } = props
|
|
31
|
-
const { className: _className, style: _style } = useContext(UnifyConfigContext)
|
|
32
|
-
|
|
33
|
-
return createElement(as, {
|
|
34
|
-
className: clsx(_className, className),
|
|
35
|
-
style: { ..._style, ...style },
|
|
36
|
-
...rest,
|
|
37
|
-
}) as ReactNode
|
|
38
|
-
}
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { clsx } from "deepsea-tools"
|
|
4
|
+
import { CSSProperties, ComponentProps, FC, JSX, JSXElementConstructor, ReactNode, createContext, createElement, useContext } from "react"
|
|
5
|
+
|
|
6
|
+
export interface UnifyConfig {
|
|
7
|
+
className?: string
|
|
8
|
+
style?: CSSProperties
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const UnifyConfigContext = createContext<UnifyConfig>({})
|
|
12
|
+
|
|
13
|
+
export interface UnifyConfigProviderProps extends UnifyConfig {
|
|
14
|
+
children?: ReactNode
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const UnifyConfigProvider: FC<UnifyConfigProviderProps> = ({ className, style, children }) => {
|
|
18
|
+
const { className: _className, style: _style } = useContext(UnifyConfigContext)
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<UnifyConfigContext.Provider value={{ className: clsx(_className, className), style: { ..._style, ...style } }}>{children}</UnifyConfigContext.Provider>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type UnifyProps<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "div"> = Omit<ComponentProps<AS>, "as"> & {
|
|
26
|
+
as?: AS
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function Unify<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "div">(props: UnifyProps<AS>) {
|
|
30
|
+
const { as = "div", className, style, ...rest } = props
|
|
31
|
+
const { className: _className, style: _style } = useContext(UnifyConfigContext)
|
|
32
|
+
|
|
33
|
+
return createElement(as, {
|
|
34
|
+
className: clsx(_className, className),
|
|
35
|
+
style: { ..._style, ...style },
|
|
36
|
+
...rest,
|
|
37
|
+
}) as ReactNode
|
|
38
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { WriteSheet, WriteSheetProps } from "./WriteSheet"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @deprecated 请使用 WriteSheetProps 代替
|
|
7
|
-
*/
|
|
8
|
-
export type WriteExcelProps = WriteSheetProps
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @deprecated 请使用 WriteSheet 代替
|
|
12
|
-
*/
|
|
13
|
-
export const WriteExcel = WriteSheet
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { WriteSheet, WriteSheetProps } from "./WriteSheet"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated 请使用 WriteSheetProps 代替
|
|
7
|
+
*/
|
|
8
|
+
export type WriteExcelProps = WriteSheetProps
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated 请使用 WriteSheet 代替
|
|
12
|
+
*/
|
|
13
|
+
export const WriteExcel = WriteSheet
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import { WriteSheetParams, writeSheet } from "deepsea-tools"
|
|
4
|
-
import { ComponentProps, JSX, JSXElementConstructor, MouseEvent as ReactMouseEvent, createElement } from "react"
|
|
5
|
-
|
|
6
|
-
export type WriteSheetProps<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "button"> = Omit<ComponentProps<AS>, "as" | "excel"> & {
|
|
7
|
-
as?: AS
|
|
8
|
-
excel?: WriteSheetParams
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/** 导出 excel 的 button 组件 */
|
|
12
|
-
export function WriteSheet<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "button">(props: WriteSheetProps<AS>) {
|
|
13
|
-
const { as, excel, onClick: _onClick, ...rest } = props
|
|
14
|
-
|
|
15
|
-
function onClick(e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) {
|
|
16
|
-
_onClick?.(e)
|
|
17
|
-
if (!excel) return
|
|
18
|
-
writeSheet(excel)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return createElement(as ?? "button", {
|
|
22
|
-
onClick,
|
|
23
|
-
...rest,
|
|
24
|
-
})
|
|
25
|
-
}
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { WriteSheetParams, writeSheet } from "deepsea-tools"
|
|
4
|
+
import { ComponentProps, JSX, JSXElementConstructor, MouseEvent as ReactMouseEvent, createElement } from "react"
|
|
5
|
+
|
|
6
|
+
export type WriteSheetProps<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "button"> = Omit<ComponentProps<AS>, "as" | "excel"> & {
|
|
7
|
+
as?: AS
|
|
8
|
+
excel?: WriteSheetParams
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** 导出 excel 的 button 组件 */
|
|
12
|
+
export function WriteSheet<AS extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "button">(props: WriteSheetProps<AS>) {
|
|
13
|
+
const { as, excel, onClick: _onClick, ...rest } = props
|
|
14
|
+
|
|
15
|
+
function onClick(e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) {
|
|
16
|
+
_onClick?.(e)
|
|
17
|
+
if (!excel) return
|
|
18
|
+
writeSheet(excel)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return createElement(as ?? "button", {
|
|
22
|
+
onClick,
|
|
23
|
+
...rest,
|
|
24
|
+
})
|
|
25
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { version } from "react"
|
|
2
|
-
|
|
3
|
-
const reg = /(\d+)\.(\d+)\.(\d+)/
|
|
4
|
-
|
|
5
|
-
export function getReactVersion() {
|
|
6
|
-
return version.match(reg)!.slice(1).map(Number)
|
|
7
|
-
}
|
|
1
|
+
import { version } from "react"
|
|
2
|
+
|
|
3
|
+
const reg = /(\d+)\.(\d+)\.(\d+)/
|
|
4
|
+
|
|
5
|
+
export function getReactVersion() {
|
|
6
|
+
return version.match(reg)!.slice(1).map(Number)
|
|
7
|
+
}
|