deepsea-components 5.9.6 → 5.10.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.
- package/dist/cjs/components/Flow.d.ts +2 -2
- package/dist/cjs/components/Flow.js +1 -1
- package/dist/cjs/components/Flow.js.map +2 -2
- package/dist/cjs/components/ImportExcel.d.ts +4 -4
- package/dist/cjs/components/ImportExcel.js +4 -5
- package/dist/cjs/components/ImportExcel.js.map +2 -2
- package/dist/cjs/components/InputFile.d.ts +16 -43
- package/dist/cjs/components/InputFile.js +16 -75
- package/dist/cjs/components/InputFile.js.map +2 -2
- package/dist/cjs/components/InputFileButton.d.ts +10 -0
- package/dist/cjs/components/InputFileButton.js +109 -0
- package/dist/cjs/components/InputFileButton.js.map +7 -0
- package/dist/cjs/components/Unify.d.ts +1 -1
- package/dist/cjs/components/Unify.js.map +2 -2
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/esm/components/Flow.d.ts +2 -2
- package/dist/esm/components/Flow.js +1 -1
- package/dist/esm/components/Flow.js.map +1 -1
- package/dist/esm/components/ImportExcel.d.ts +4 -4
- package/dist/esm/components/ImportExcel.js +4 -8
- package/dist/esm/components/ImportExcel.js.map +1 -1
- package/dist/esm/components/InputFile.d.ts +16 -43
- package/dist/esm/components/InputFile.js +21 -104
- package/dist/esm/components/InputFile.js.map +1 -1
- package/dist/esm/components/InputFileButton.d.ts +10 -0
- package/dist/esm/components/InputFileButton.js +90 -0
- package/dist/esm/components/InputFileButton.js.map +1 -0
- package/dist/esm/components/Unify.d.ts +1 -1
- package/dist/esm/components/Unify.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +7 -7
- package/src/components/Flow.tsx +2 -2
- package/src/components/ImportExcel.tsx +7 -7
- package/src/components/InputFile.tsx +39 -128
- package/src/components/InputFileButton.tsx +102 -0
- package/src/components/Unify.tsx +1 -1
- package/src/index.ts +1 -0
package/src/components/Flow.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import { CSSProperties, HTMLAttributes, Key, ReactNode, RefObject, useEffect, useImperativeHandle, useRef, useState } from "react"
|
|
4
3
|
import { css } from "@emotion/css"
|
|
5
4
|
import { useSize } from "ahooks"
|
|
6
5
|
import { clsx } from "deepsea-tools"
|
|
6
|
+
import { CSSProperties, HTMLAttributes, Key, ReactNode, Ref, useEffect, useImperativeHandle, useRef, useState } from "react"
|
|
7
7
|
|
|
8
8
|
import { px, transformCSSVariable } from "@/utils"
|
|
9
9
|
|
|
@@ -77,7 +77,7 @@ export interface FlowProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, "chil
|
|
|
77
77
|
transitionDuration?: number
|
|
78
78
|
/** 变化的回调函数 */
|
|
79
79
|
onSizeChange?: (sizeData: FlowSizeData) => void
|
|
80
|
-
element?:
|
|
80
|
+
element?: Ref<HTMLDivElement>
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
export function getGapRange(gap?: undefined | number | "auto" | (number | "auto")[]): [number, number | "auto"] {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import { forwardRef } from "react"
|
|
4
3
|
import { readExcel } from "deepsea-tools"
|
|
4
|
+
import { FC } from "react"
|
|
5
5
|
|
|
6
6
|
import { InputFile, InputFileProps } from "./InputFile"
|
|
7
7
|
|
|
8
|
-
export interface ImportExcelProps extends Omit<InputFileProps, "multiple" | "
|
|
9
|
-
|
|
8
|
+
export interface ImportExcelProps extends Omit<InputFileProps<false, "arrayBuffer">, "multiple" | "accept" | "type" | "onValueChange"> {
|
|
9
|
+
onValueChange?: (data: Record<string, any>[]) => void
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/** 专门用于读取 excel 的组件 */
|
|
13
|
-
export const ImportExcel
|
|
14
|
-
const {
|
|
13
|
+
export const ImportExcel: FC<ImportExcelProps> = props => {
|
|
14
|
+
const { onValueChange, ...rest } = props
|
|
15
15
|
|
|
16
|
-
return <InputFile
|
|
17
|
-
}
|
|
16
|
+
return <InputFile accept=".xlsx" type="arrayBuffer" onValueChange={data => onValueChange?.(readExcel(data))} {...rest} />
|
|
17
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ChangeEvent, ComponentProps, ReactNode, useState } from "react"
|
|
4
4
|
|
|
5
|
-
export interface
|
|
5
|
+
export interface InputFileDataTypeMap {
|
|
6
6
|
base64: string
|
|
7
7
|
text: string
|
|
8
8
|
arrayBuffer: ArrayBuffer
|
|
@@ -10,51 +10,9 @@ export interface InputFileDataTypes {
|
|
|
10
10
|
file: File
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export type InputFileDataType = keyof
|
|
13
|
+
export type InputFileDataType = keyof InputFileDataTypeMap
|
|
14
14
|
|
|
15
|
-
export
|
|
16
|
-
result: T
|
|
17
|
-
file: File
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type InputFileProps = (
|
|
21
|
-
| {
|
|
22
|
-
multiple?: false
|
|
23
|
-
type: "base64" | "text" | "binary"
|
|
24
|
-
onChange?: (data: InputFileData<string>) => void
|
|
25
|
-
}
|
|
26
|
-
| {
|
|
27
|
-
multiple?: false
|
|
28
|
-
type: "arrayBuffer"
|
|
29
|
-
onChange?: (data: InputFileData<ArrayBuffer>) => void
|
|
30
|
-
}
|
|
31
|
-
| {
|
|
32
|
-
multiple?: false
|
|
33
|
-
type?: "file"
|
|
34
|
-
onChange?: (data: InputFileData<File>) => void
|
|
35
|
-
}
|
|
36
|
-
| {
|
|
37
|
-
multiple: true
|
|
38
|
-
type: "base64" | "text" | "binary"
|
|
39
|
-
onChange?: (data: InputFileData<string>[]) => void
|
|
40
|
-
}
|
|
41
|
-
| {
|
|
42
|
-
multiple: true
|
|
43
|
-
type: "arrayBuffer"
|
|
44
|
-
onChange?: (data: InputFileData<ArrayBuffer>[]) => void
|
|
45
|
-
}
|
|
46
|
-
| {
|
|
47
|
-
multiple: true
|
|
48
|
-
type?: "file"
|
|
49
|
-
onChange?: (data: InputFileData<File>[]) => void
|
|
50
|
-
}
|
|
51
|
-
) &
|
|
52
|
-
Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "multiple" | "type"> & {
|
|
53
|
-
/** 是否在捕获文件后清除 input 上的文件,默认为 false,主要区别在于如果不清除,连续两次选择同样的文件不会触发 onChange 事件,如果用于 form 表单,请设置为 flase */
|
|
54
|
-
clearAfterChange?: boolean
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export async function getFileData<T extends InputFileDataType>(file: File, type: T): Promise<InputFileDataTypes[T]> {
|
|
15
|
+
export async function getFileData<T extends InputFileDataType>(file: File, type: T): Promise<InputFileDataTypeMap[T]> {
|
|
58
16
|
const fileReader = new FileReader()
|
|
59
17
|
switch (type) {
|
|
60
18
|
case "arrayBuffer":
|
|
@@ -79,31 +37,51 @@ export async function getFileData<T extends InputFileDataType>(file: File, type:
|
|
|
79
37
|
})
|
|
80
38
|
}
|
|
81
39
|
|
|
40
|
+
export interface InputFileBaseProps extends Omit<ComponentProps<"input">, "multiple" | "type"> {}
|
|
41
|
+
|
|
42
|
+
export type FileType<Multiple extends boolean> = Multiple extends true ? File[] : File
|
|
43
|
+
export type ValueType<Multiple extends boolean, Type extends InputFileDataType> = Multiple extends true
|
|
44
|
+
? InputFileDataTypeMap[Type][]
|
|
45
|
+
: InputFileDataTypeMap[Type]
|
|
46
|
+
|
|
47
|
+
export interface InputFileExtraProps<Multiple extends boolean = false, Type extends InputFileDataType = "file"> {
|
|
48
|
+
multiple?: Multiple
|
|
49
|
+
type?: Type
|
|
50
|
+
onValueChange?: (data: ValueType<Multiple, Type>) => void
|
|
51
|
+
onFileChange?: (data: FileType<Multiple>) => void
|
|
52
|
+
/** 是否在捕获文件后清除 input 上的文件,默认为 false,主要区别在于如果不清除,连续两次选择同样的文件不会触发 onChange 事件,如果用于 form 表单,请设置为 flase */
|
|
53
|
+
clearAfterChange?: boolean
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface InputFileProps<Multiple extends boolean = false, Type extends InputFileDataType = "file">
|
|
57
|
+
extends InputFileBaseProps,
|
|
58
|
+
InputFileExtraProps<Multiple, Type> {}
|
|
59
|
+
|
|
82
60
|
/** 专用于读取文件的组件 */
|
|
83
|
-
export
|
|
84
|
-
const { multiple = false, type = "file", onChange, disabled:
|
|
61
|
+
export function InputFile<Multiple extends boolean = false, Type extends InputFileDataType = "file">(props: InputFileProps<Multiple, Type>): ReactNode {
|
|
62
|
+
const { multiple = false, type = "file", onChange: _onChange, disabled: _disabled, clearAfterChange, onValueChange, onFileChange, ...rest } = props
|
|
85
63
|
const [disabled, setDisabled] = useState(false)
|
|
86
64
|
|
|
87
|
-
async function
|
|
65
|
+
async function onChange(e: ChangeEvent<HTMLInputElement>) {
|
|
66
|
+
_onChange?.(e)
|
|
88
67
|
const input = e.target
|
|
89
68
|
const { files } = input
|
|
90
69
|
if (!files || files.length === 0) return
|
|
91
70
|
setDisabled(true)
|
|
92
71
|
try {
|
|
93
72
|
if (multiple) {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
})
|
|
73
|
+
const files2: File[] = Array.from(files)
|
|
74
|
+
const values: InputFileDataTypeMap[Type][] = []
|
|
75
|
+
for (const file of files2) {
|
|
76
|
+
const value = (await getFileData(file, type)) as InputFileDataTypeMap[Type]
|
|
77
|
+
values.push(value)
|
|
100
78
|
}
|
|
101
|
-
|
|
79
|
+
onFileChange?.(files2 as FileType<Multiple>)
|
|
80
|
+
onValueChange?.(values as ValueType<Multiple, Type>)
|
|
102
81
|
} else {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
} as any)
|
|
82
|
+
const file = files[0]
|
|
83
|
+
onFileChange?.(file as FileType<Multiple>)
|
|
84
|
+
onValueChange?.((await getFileData(file, type)) as ValueType<Multiple, Type>)
|
|
107
85
|
}
|
|
108
86
|
} finally {
|
|
109
87
|
if (clearAfterChange) input.value = ""
|
|
@@ -111,72 +89,5 @@ export const InputFile = forwardRef<HTMLInputElement, InputFileProps>((props, re
|
|
|
111
89
|
}
|
|
112
90
|
}
|
|
113
91
|
|
|
114
|
-
return <input
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
export type InputFileButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
118
|
-
input: InputFileProps
|
|
119
|
-
dragFile?: boolean
|
|
92
|
+
return <input disabled={disabled || _disabled} type="file" multiple={multiple} onChange={onChange} {...rest} />
|
|
120
93
|
}
|
|
121
|
-
|
|
122
|
-
/** 专用于读取文件的 button 组件 */
|
|
123
|
-
export const InputFileButton = forwardRef<HTMLButtonElement, InputFileButtonProps>((props, ref) => {
|
|
124
|
-
const { onClick: _onClick, input: inputProps, onDrop: _onDrop, onDragOver: _onDragOver, dragFile, disabled: _disabled, ...rest } = props
|
|
125
|
-
const { style, disabled: __disabled, multiple, onChange, type = "file", ...restInputProps } = inputProps
|
|
126
|
-
const [disabled, setDisabled] = useState(false)
|
|
127
|
-
const input = useRef<HTMLInputElement>(null)
|
|
128
|
-
|
|
129
|
-
function onClick(e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) {
|
|
130
|
-
input.current?.click()
|
|
131
|
-
_onClick?.(e)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async function onDrop(e: DragEvent<HTMLButtonElement>) {
|
|
135
|
-
_onDrop?.(e)
|
|
136
|
-
if (disabled || !dragFile) return
|
|
137
|
-
e.preventDefault()
|
|
138
|
-
const { files } = e.dataTransfer
|
|
139
|
-
if (!files || files.length === 0) return
|
|
140
|
-
setDisabled(true)
|
|
141
|
-
try {
|
|
142
|
-
if (multiple) {
|
|
143
|
-
const result: any[] = []
|
|
144
|
-
for (const file of Array.from(files)) {
|
|
145
|
-
result.push({
|
|
146
|
-
result: await getFileData(file, type),
|
|
147
|
-
file,
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
onChange?.(result as any)
|
|
151
|
-
} else {
|
|
152
|
-
onChange?.({
|
|
153
|
-
result: await getFileData(files[0], type),
|
|
154
|
-
file: files[0],
|
|
155
|
-
} as any)
|
|
156
|
-
}
|
|
157
|
-
} finally {
|
|
158
|
-
setDisabled(false)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function onDragOver(e: DragEvent<HTMLButtonElement>) {
|
|
163
|
-
_onDragOver?.(e)
|
|
164
|
-
if (disabled || !dragFile) return
|
|
165
|
-
e.preventDefault()
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return (
|
|
169
|
-
<Fragment>
|
|
170
|
-
<InputFile
|
|
171
|
-
ref={input}
|
|
172
|
-
disabled={disabled || _disabled || __disabled}
|
|
173
|
-
style={{ display: "none", ...style }}
|
|
174
|
-
multiple={multiple as any}
|
|
175
|
-
onChange={onChange as any}
|
|
176
|
-
type={type as any}
|
|
177
|
-
{...restInputProps}
|
|
178
|
-
/>
|
|
179
|
-
<button ref={ref} type="button" disabled={disabled || _disabled} onClick={onClick} onDrop={onDrop} onDragOver={onDragOver} {...rest} />
|
|
180
|
-
</Fragment>
|
|
181
|
-
)
|
|
182
|
-
})
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { ComponentProps, ComponentRef, createElement, DragEvent, Fragment, JSX, MouseEvent as ReactMouseEvent, useRef, useState } from "react"
|
|
4
|
+
import { FileType, getFileData, InputFile, InputFileBaseProps, InputFileDataType, InputFileDataTypeMap, InputFileExtraProps, ValueType } from "./InputFile"
|
|
5
|
+
|
|
6
|
+
export type InputFileButtonProps<
|
|
7
|
+
Multiple extends boolean = false,
|
|
8
|
+
Type extends InputFileDataType = "file",
|
|
9
|
+
AS extends keyof JSX.IntrinsicElements = "button",
|
|
10
|
+
> = Omit<ComponentProps<AS>, "type" | "disabled"> &
|
|
11
|
+
InputFileExtraProps<Multiple, Type> & {
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
inputProps?: InputFileBaseProps
|
|
14
|
+
dragFile?: boolean
|
|
15
|
+
as?: AS
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** 专用于读取文件的 button 组件 */
|
|
19
|
+
export function InputFileButton<Multiple extends boolean = false, Type extends InputFileDataType = "file", AS extends keyof JSX.IntrinsicElements = "button">(
|
|
20
|
+
props: InputFileButtonProps<Multiple, Type, AS>,
|
|
21
|
+
) {
|
|
22
|
+
const {
|
|
23
|
+
as = "button",
|
|
24
|
+
onClick: _onClick,
|
|
25
|
+
inputProps = {},
|
|
26
|
+
onDrop: _onDrop,
|
|
27
|
+
onDragOver: _onDragOver,
|
|
28
|
+
dragFile,
|
|
29
|
+
disabled: _disabled,
|
|
30
|
+
type = "file",
|
|
31
|
+
multiple,
|
|
32
|
+
onValueChange,
|
|
33
|
+
onFileChange,
|
|
34
|
+
clearAfterChange,
|
|
35
|
+
...rest
|
|
36
|
+
} = props
|
|
37
|
+
|
|
38
|
+
const { style, disabled: __disabled, ...restInputProps } = inputProps
|
|
39
|
+
const [disabled, setDisabled] = useState(false)
|
|
40
|
+
const input = useRef<HTMLInputElement>(null)
|
|
41
|
+
|
|
42
|
+
function onClick(e: ReactMouseEvent<ComponentRef<AS>, MouseEvent>) {
|
|
43
|
+
input.current?.click()
|
|
44
|
+
_onClick?.(e as any)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function onDrop(e: DragEvent<ComponentRef<AS>>) {
|
|
48
|
+
_onDrop?.(e as any)
|
|
49
|
+
if (disabled || !dragFile) return
|
|
50
|
+
e.preventDefault()
|
|
51
|
+
const { files } = e.dataTransfer
|
|
52
|
+
if (!files || files.length === 0) return
|
|
53
|
+
setDisabled(true)
|
|
54
|
+
try {
|
|
55
|
+
if (multiple) {
|
|
56
|
+
const files2: File[] = Array.from(files)
|
|
57
|
+
const values: InputFileDataTypeMap[Type][] = []
|
|
58
|
+
for (const file of files2) {
|
|
59
|
+
const value = (await getFileData(file, type)) as InputFileDataTypeMap[Type]
|
|
60
|
+
values.push(value)
|
|
61
|
+
}
|
|
62
|
+
onFileChange?.(files2 as FileType<Multiple>)
|
|
63
|
+
onValueChange?.(values as ValueType<Multiple, Type>)
|
|
64
|
+
} else {
|
|
65
|
+
const file = files[0]
|
|
66
|
+
onFileChange?.(file as FileType<Multiple>)
|
|
67
|
+
onValueChange?.((await getFileData(file, type)) as ValueType<Multiple, Type>)
|
|
68
|
+
}
|
|
69
|
+
} finally {
|
|
70
|
+
setDisabled(false)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function onDragOver(e: DragEvent<ComponentRef<AS>>) {
|
|
75
|
+
_onDragOver?.(e as any)
|
|
76
|
+
if (disabled || !dragFile) return
|
|
77
|
+
e.preventDefault()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<Fragment>
|
|
82
|
+
<InputFile<Multiple, Type>
|
|
83
|
+
disabled={disabled || _disabled || __disabled}
|
|
84
|
+
style={{ display: "none", ...style }}
|
|
85
|
+
multiple={multiple}
|
|
86
|
+
type={type as Type}
|
|
87
|
+
onValueChange={onValueChange}
|
|
88
|
+
onFileChange={onFileChange}
|
|
89
|
+
clearAfterChange={clearAfterChange}
|
|
90
|
+
{...restInputProps}
|
|
91
|
+
/>
|
|
92
|
+
{createElement(as, {
|
|
93
|
+
disabled: disabled || _disabled,
|
|
94
|
+
onClick,
|
|
95
|
+
onDrop,
|
|
96
|
+
onDragOver,
|
|
97
|
+
...rest,
|
|
98
|
+
})}
|
|
99
|
+
</Fragment>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
package/src/components/Unify.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import { CSSProperties, ComponentProps, FC, ReactNode, createContext, createElement, useContext } from "react"
|
|
3
|
+
import { CSSProperties, ComponentProps, FC, ReactNode, createContext, createElement, useContext, JSX } from "react"
|
|
4
4
|
import { clsx } from "deepsea-tools"
|
|
5
5
|
|
|
6
6
|
export interface UnifyConfig {
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from "@/components/HlsPlayer"
|
|
|
11
11
|
export * from "@/components/ImportExcel"
|
|
12
12
|
export * from "@/components/InfiniteScroll"
|
|
13
13
|
export * from "@/components/InputFile"
|
|
14
|
+
export * from "@/components/InputFileButton"
|
|
14
15
|
export * from "@/components/LoopSwiper"
|
|
15
16
|
export * from "@/components/Ring"
|
|
16
17
|
export * from "@/components/Scroll"
|