antd-solid 0.0.11 → 0.0.12
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/css/index.css +9 -5
- package/dist/index.esm.js +232 -135
- package/dist/index.umd.js +1 -1
- package/es/{Button.d.ts → Button/index.d.ts} +3 -2
- package/es/{Button.js → Button/index.js} +11 -9
- package/es/Button/index.scss.js +6 -0
- package/es/{Compact.js → Compact/index.js} +4 -4
- package/es/Drawer/index.js +2 -3
- package/es/Empty/index.d.ts +6 -2
- package/es/Empty/index.js +7 -2
- package/es/Input.js +3 -3
- package/es/InputNumber.js +1 -1
- package/es/Modal.d.ts +4 -5
- package/es/Modal.js +10 -9
- package/es/Popconfirm.js +1 -1
- package/es/Progress/index.d.ts +1 -2
- package/es/Progress/index.js +18 -8
- package/es/Radio.js +2 -2
- package/es/Result.js +1 -1
- package/es/Select.js +2 -2
- package/es/Spin.d.ts +1 -0
- package/es/Spin.js +12 -6
- package/es/Switch.js +1 -1
- package/es/Tabs.js +2 -2
- package/es/Timeline.js +1 -1
- package/es/Tree.js +2 -2
- package/es/Upload.d.ts +56 -10
- package/es/Upload.js +93 -3
- package/es/index.js +2 -2
- package/package.json +1 -1
- package/src/Button/index.scss +9 -0
- package/src/{Button.tsx → Button/index.tsx} +18 -9
- package/src/Compact/index.tsx +20 -0
- package/src/Drawer/index.tsx +1 -2
- package/src/Empty/index.tsx +11 -6
- package/src/Input.tsx +2 -2
- package/src/InputNumber.tsx +34 -20
- package/src/Modal.tsx +14 -13
- package/src/Progress/index.tsx +17 -9
- package/src/Radio.tsx +3 -3
- package/src/Result.tsx +1 -1
- package/src/Select.tsx +14 -4
- package/src/Spin.tsx +16 -5
- package/src/Switch.tsx +1 -1
- package/src/Tabs.tsx +2 -2
- package/src/Timeline.tsx +1 -1
- package/src/Tree.tsx +4 -3
- package/src/Upload.tsx +138 -5
- package/src/Compact.tsx +0 -15
- /package/es/{Compact.d.ts → Compact/index.d.ts} +0 -0
package/src/Input.tsx
CHANGED
|
@@ -34,7 +34,7 @@ const statusClassDict = {
|
|
|
34
34
|
cs(
|
|
35
35
|
'ant-[border:1px_solid_var(--ant-color-border)]',
|
|
36
36
|
!disabled &&
|
|
37
|
-
'hover:ant-border-[var(--
|
|
37
|
+
'hover:ant-border-[var(--ant-color-primary)] focus-within:ant-border-[var(--ant-color-primary)] focus-within:ant-[box-shadow:0_0_0_2px_rgba(5,145,255,0.1)]',
|
|
38
38
|
),
|
|
39
39
|
error: (disabled: boolean) =>
|
|
40
40
|
cs(
|
|
@@ -138,7 +138,7 @@ export function CommonInput<T extends HTMLInputElement | HTMLTextAreaElement = H
|
|
|
138
138
|
<Show when={hasPrefixOrSuffix()} fallback={inputJSX}>
|
|
139
139
|
<div
|
|
140
140
|
class={cs(
|
|
141
|
-
'ant-flex ant-items-center ant-w-full ant-relative ant-[--input-after-display:none] hover:ant-[--input-after-display:block] p:hover-child[input]:ant-border-[var(--
|
|
141
|
+
'ant-flex ant-items-center ant-w-full ant-relative ant-[--input-after-display:none] hover:ant-[--input-after-display:block] p:hover-child[input]:ant-border-[var(--ant-color-primary)]',
|
|
142
142
|
inputWrapClass(),
|
|
143
143
|
)}
|
|
144
144
|
>
|
package/src/InputNumber.tsx
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Component,
|
|
3
|
+
createEffect,
|
|
4
|
+
on,
|
|
5
|
+
splitProps,
|
|
6
|
+
untrack,
|
|
7
|
+
createSignal,
|
|
8
|
+
mergeProps,
|
|
9
|
+
} from 'solid-js'
|
|
2
10
|
import { CommonInput, type InputProps } from './Input'
|
|
3
11
|
import { clamp, isNil } from 'lodash-es'
|
|
4
12
|
import { dispatchEventHandlerUnion } from './utils/solid'
|
|
@@ -18,22 +26,20 @@ export interface InputNumberProps
|
|
|
18
26
|
const isEmptyValue = (value: number | string | null | undefined) => isNil(value) || value === ''
|
|
19
27
|
|
|
20
28
|
const actionBtnClass =
|
|
21
|
-
'ant-text-12px ant-flex ant-justify-center ant-items-center ant-h-1/2 ant-cursor-pointer ant-opacity-70 hover:ant-h-100% hover:ant-text-[var(--
|
|
29
|
+
'ant-text-12px ant-flex ant-justify-center ant-items-center ant-h-1/2 ant-cursor-pointer ant-opacity-70 hover:ant-h-100% hover:ant-text-[var(--ant-color-primary)] ant-transition-color ant-transition-height ant-transition-duration-500'
|
|
22
30
|
|
|
23
31
|
const InputNumber: Component<InputNumberProps> = _props => {
|
|
24
|
-
const props = mergeProps(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
'onBlur',
|
|
33
|
-
])
|
|
32
|
+
const props = mergeProps(
|
|
33
|
+
{
|
|
34
|
+
min: -Infinity,
|
|
35
|
+
max: Infinity,
|
|
36
|
+
},
|
|
37
|
+
_props,
|
|
38
|
+
)
|
|
39
|
+
const [_, inputProps] = splitProps(props, ['defaultValue', 'value', 'onChange', 'onBlur'])
|
|
34
40
|
|
|
35
41
|
const clampValue = (v: number) => untrack(() => clamp(v, props.min, props.max))
|
|
36
|
-
|
|
42
|
+
|
|
37
43
|
let prev: number | null = null
|
|
38
44
|
const updatePrev = (v: number | null) => {
|
|
39
45
|
if (prev === v) return
|
|
@@ -42,12 +48,20 @@ const InputNumber: Component<InputNumberProps> = _props => {
|
|
|
42
48
|
props.onChange?.(prev)
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
const [value, setValue] = createSignal<number | string | null | undefined>(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const [value, setValue] = createSignal<number | string | null | undefined>(
|
|
52
|
+
untrack(() => props.value ?? props.defaultValue),
|
|
53
|
+
)
|
|
54
|
+
createEffect(
|
|
55
|
+
on(
|
|
56
|
+
() => props.value,
|
|
57
|
+
() => {
|
|
58
|
+
setValue(props.value)
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
defer: true,
|
|
62
|
+
},
|
|
63
|
+
),
|
|
64
|
+
)
|
|
51
65
|
|
|
52
66
|
const add = (addon: number) => {
|
|
53
67
|
let newValue: number | null
|
|
@@ -104,7 +118,7 @@ const InputNumber: Component<InputNumberProps> = _props => {
|
|
|
104
118
|
|
|
105
119
|
let newValueNum: number | null = Number(newValue)
|
|
106
120
|
if (Number.isNaN(newValueNum)) return
|
|
107
|
-
|
|
121
|
+
|
|
108
122
|
if (isEmptyValue(newValue)) {
|
|
109
123
|
newValueNum = null
|
|
110
124
|
} else {
|
package/src/Modal.tsx
CHANGED
|
@@ -6,11 +6,6 @@ import cs from 'classnames'
|
|
|
6
6
|
export interface ModalInstance {
|
|
7
7
|
open: () => void
|
|
8
8
|
close: () => void
|
|
9
|
-
/**
|
|
10
|
-
* 与 close 相似,但关闭时会销毁 Modal 里的子元素
|
|
11
|
-
* @returns
|
|
12
|
-
*/
|
|
13
|
-
destroy: () => void
|
|
14
9
|
}
|
|
15
10
|
|
|
16
11
|
export interface ModalProps {
|
|
@@ -34,6 +29,10 @@ export interface ModalProps {
|
|
|
34
29
|
*/
|
|
35
30
|
closeIcon?: boolean
|
|
36
31
|
footer?: boolean | ((modal: ModalInstance) => JSXElement)
|
|
32
|
+
/**
|
|
33
|
+
* 关闭时销毁 Modal 里的子元素
|
|
34
|
+
*/
|
|
35
|
+
destroyOnClose?: boolean
|
|
37
36
|
/**
|
|
38
37
|
* 返回 true,会自动关闭 modal
|
|
39
38
|
*/
|
|
@@ -75,14 +74,16 @@ function Modal(_props: ModalProps) {
|
|
|
75
74
|
}
|
|
76
75
|
},
|
|
77
76
|
close() {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
77
|
+
untrack(() => {
|
|
78
|
+
if (props.destroyOnClose) {
|
|
79
|
+
setOpen(false)
|
|
80
|
+
} else {
|
|
81
|
+
setHide(true)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
cleanup()
|
|
85
|
+
props.afterClose?.()
|
|
86
|
+
})
|
|
86
87
|
},
|
|
87
88
|
}
|
|
88
89
|
untrack(() => {
|
package/src/Progress/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mergeProps, type Component, Switch, Match, Show } from 'solid-js'
|
|
1
|
+
import { mergeProps, type Component, Switch, Match, Show, createMemo } from 'solid-js'
|
|
2
2
|
import cs from 'classnames'
|
|
3
3
|
|
|
4
4
|
export interface ProgressProps {
|
|
@@ -9,9 +9,8 @@ export interface ProgressProps {
|
|
|
9
9
|
percent?: number
|
|
10
10
|
/**
|
|
11
11
|
* 状态
|
|
12
|
-
* 默认 'default'
|
|
13
12
|
*/
|
|
14
|
-
status?: '
|
|
13
|
+
status?: 'normal' | 'success' | 'error'
|
|
15
14
|
/**
|
|
16
15
|
* 'line' 类型进度条的高度
|
|
17
16
|
* 默认 8
|
|
@@ -28,13 +27,17 @@ const Progress: Component<ProgressProps> = _props => {
|
|
|
28
27
|
const props = mergeProps(
|
|
29
28
|
{
|
|
30
29
|
percent: 0,
|
|
31
|
-
status: 'default',
|
|
32
30
|
height: 8,
|
|
33
31
|
showInfo: true,
|
|
34
|
-
}
|
|
32
|
+
},
|
|
35
33
|
_props,
|
|
36
34
|
)
|
|
37
35
|
|
|
36
|
+
const status = createMemo(() => {
|
|
37
|
+
if (props.status) return props.status
|
|
38
|
+
return props.percent >= 100 ? 'success' : 'normal'
|
|
39
|
+
})
|
|
40
|
+
|
|
38
41
|
return (
|
|
39
42
|
<div
|
|
40
43
|
class="ant-flex ant-items-center"
|
|
@@ -45,22 +48,27 @@ const Progress: Component<ProgressProps> = _props => {
|
|
|
45
48
|
<div
|
|
46
49
|
class={cs(
|
|
47
50
|
'ant-w-full ant-bg-[var(--ant-progress-remaining-color)]',
|
|
48
|
-
'before:ant-content-empty before:ant-block before:ant-bg-[var(--
|
|
51
|
+
'before:ant-content-empty before:ant-block before:ant-bg-[var(--color)] before:ant-w-[var(--percent)] before:ant-h-full before:ant-rounded-inherit',
|
|
49
52
|
)}
|
|
50
53
|
style={{
|
|
51
54
|
height: `${props.height}px`,
|
|
52
55
|
'border-radius': `${props.height / 2}px`,
|
|
53
56
|
'--percent': `${props.percent}%`,
|
|
57
|
+
'--color': {
|
|
58
|
+
normal: 'var(--ant-color-primary)',
|
|
59
|
+
success: 'var(--ant-color-success)',
|
|
60
|
+
error: 'var(--ant-color-error)',
|
|
61
|
+
}[status()],
|
|
54
62
|
}}
|
|
55
63
|
/>
|
|
56
64
|
|
|
57
65
|
<Show when={props.showInfo}>
|
|
58
66
|
<span class="ant-shrink-0 ant-min-w-40px ant-ml-8px ant-text-center">
|
|
59
67
|
<Switch fallback={`${props.percent}%`}>
|
|
60
|
-
<Match when={
|
|
61
|
-
<span class="i-ant-design:check-circle-filled ant-text-[var(--
|
|
68
|
+
<Match when={status() === 'success'}>
|
|
69
|
+
<span class="i-ant-design:check-circle-filled ant-text-[var(--ant-color-success)]" />
|
|
62
70
|
</Match>
|
|
63
|
-
<Match when={
|
|
71
|
+
<Match when={status() === 'error'}>
|
|
64
72
|
<span class="i-ant-design:close-circle-filled ant-text-[var(--ant-color-error)]" />
|
|
65
73
|
</Match>
|
|
66
74
|
</Switch>
|
package/src/Radio.tsx
CHANGED
|
@@ -47,7 +47,7 @@ const Radio: Component<RadioProps> & {
|
|
|
47
47
|
<span
|
|
48
48
|
class={cs(
|
|
49
49
|
'ant-w-16px ant-h-16px ant-rounded-50% ant-[border:1px_solid_var(--ant-color-border)]',
|
|
50
|
-
checked() && 'ant-[border:5px_solid_var(--
|
|
50
|
+
checked() && 'ant-[border:5px_solid_var(--ant-color-primary)]',
|
|
51
51
|
)}
|
|
52
52
|
>
|
|
53
53
|
<input
|
|
@@ -77,9 +77,9 @@ Radio.Button = props => {
|
|
|
77
77
|
return (
|
|
78
78
|
<label
|
|
79
79
|
class={cs(
|
|
80
|
-
'ant-px-15px ant-[border:1px_solid_rgb(217,217,217)] first:ant-rounded-l-6px last:ant-rounded-r-6px ant-h-32px ant-inline-flex ant-items-center hover:ant-text-[var(--
|
|
80
|
+
'ant-px-15px ant-[border:1px_solid_rgb(217,217,217)] first:ant-rounded-l-6px last:ant-rounded-r-6px ant-h-32px ant-inline-flex ant-items-center hover:ant-text-[var(--ant-color-primary)] not[:last-child]:ant-border-r-transparent ant-cursor-pointer ant-flex-grow ant-justify-center',
|
|
81
81
|
checked() &&
|
|
82
|
-
'ant-text-[var(--
|
|
82
|
+
'ant-text-[var(--ant-color-primary)] ant-[border:1px_solid_var(--ant-color-primary)] !ant-border-r-[var(--ant-color-primary)]',
|
|
83
83
|
)}
|
|
84
84
|
>
|
|
85
85
|
<input
|
package/src/Result.tsx
CHANGED
|
@@ -12,7 +12,7 @@ export interface ResultProps extends ParentProps {
|
|
|
12
12
|
|
|
13
13
|
const statusIconMap = {
|
|
14
14
|
success: 'ant-text-#52c41a i-ant-design:check-circle-filled',
|
|
15
|
-
info: 'ant-text-[var(--
|
|
15
|
+
info: 'ant-text-[var(--ant-color-primary)] i-ant-design:exclamation-circle-filled',
|
|
16
16
|
warning: 'ant-text-#faad14 i-ant-design:warning-filled',
|
|
17
17
|
error: 'ant-text-#ff4d4f i-ant-design:close-circle-filled',
|
|
18
18
|
}
|
package/src/Select.tsx
CHANGED
|
@@ -33,7 +33,9 @@ const Select: Component<SelectProps> = props => {
|
|
|
33
33
|
|
|
34
34
|
const [value, setValue] = createControllableValue<Key | undefined>(props)
|
|
35
35
|
const selectedValue = createSelector(value)
|
|
36
|
-
const selectedOption = createMemo(() =>
|
|
36
|
+
const selectedOption = createMemo(() =>
|
|
37
|
+
!isNil(value()) ? props.options.find(option => option.value === value()) : undefined,
|
|
38
|
+
)
|
|
37
39
|
|
|
38
40
|
const [open, setOpen] = createSignal(false)
|
|
39
41
|
useClickAway(
|
|
@@ -63,7 +65,7 @@ const Select: Component<SelectProps> = props => {
|
|
|
63
65
|
<div
|
|
64
66
|
class={cs(
|
|
65
67
|
'ant-box-content ant-px-12px ant-py-5px ant-h-22px ant-leading-22px hover:ant-bg-[var(--hover-bg-color)]',
|
|
66
|
-
selectedValue(item.value) ? '!ant-bg-[var(--
|
|
68
|
+
selectedValue(item.value) ? '!ant-bg-[var(--ant-select-option-selected-bg)]' : '',
|
|
67
69
|
)}
|
|
68
70
|
onClick={() => {
|
|
69
71
|
setValue(item.value)
|
|
@@ -79,7 +81,10 @@ const Select: Component<SelectProps> = props => {
|
|
|
79
81
|
>
|
|
80
82
|
<div
|
|
81
83
|
ref={select!}
|
|
82
|
-
class={cs(
|
|
84
|
+
class={cs(
|
|
85
|
+
'ant-h-32px ant-leading-32px ant-rounded-6px ant-[border:1px_solid_var(--ant-color-border)] ant-px-11px focus:ant-[border-color:var(--ant-color-primary)]',
|
|
86
|
+
props.class,
|
|
87
|
+
)}
|
|
83
88
|
tabIndex="0"
|
|
84
89
|
onClick={e => {
|
|
85
90
|
setOpen(true)
|
|
@@ -109,7 +114,12 @@ const Select: Component<SelectProps> = props => {
|
|
|
109
114
|
</Show>
|
|
110
115
|
|
|
111
116
|
<div class="ant-absolute ant-top-0 ant-bottom-0 ant-right-0">
|
|
112
|
-
<Show
|
|
117
|
+
<Show
|
|
118
|
+
when={showClearBtn()}
|
|
119
|
+
fallback={
|
|
120
|
+
<span class="i-ant-design:down-outlined ant-text-[var(--ant-allow-color)]" />
|
|
121
|
+
}
|
|
122
|
+
>
|
|
113
123
|
<span
|
|
114
124
|
class="i-ant-design:close-circle-filled ant-cursor-pointer ant-text-[var(--ant-clear-color)] hover:ant-text-[var(--ant-clear-color-hover)]"
|
|
115
125
|
onClick={e => {
|
package/src/Spin.tsx
CHANGED
|
@@ -1,19 +1,30 @@
|
|
|
1
|
-
import { Show, type Component, type ParentProps } from 'solid-js'
|
|
1
|
+
import { Show, type Component, type ParentProps, mergeProps } from 'solid-js'
|
|
2
2
|
|
|
3
3
|
interface SpinProps extends ParentProps {
|
|
4
4
|
/**
|
|
5
5
|
* 是否为加载中状态
|
|
6
6
|
*/
|
|
7
7
|
spinning?: boolean
|
|
8
|
+
size?: number
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
const Spin: Component<SpinProps> =
|
|
11
|
+
const Spin: Component<SpinProps> = _props => {
|
|
12
|
+
const props = mergeProps(
|
|
13
|
+
{
|
|
14
|
+
size: 20,
|
|
15
|
+
},
|
|
16
|
+
_props,
|
|
17
|
+
)
|
|
18
|
+
|
|
11
19
|
return (
|
|
12
|
-
<div
|
|
20
|
+
<div>
|
|
13
21
|
{props.children}
|
|
14
22
|
<Show when={props.spinning}>
|
|
15
|
-
<div class="ant-
|
|
16
|
-
<span
|
|
23
|
+
<div class="ant-flex ant-items-center ant-justify-center ant-bg-[rgba(255,255,255,.5)]">
|
|
24
|
+
<span
|
|
25
|
+
class="i-ant-design:loading keyframes-spin ant-[animation:spin_1s_linear_infinite] ant-text-[var(--ant-color-primary)]"
|
|
26
|
+
style={{ 'font-size': `${props.size}px` }}
|
|
27
|
+
/>
|
|
17
28
|
</div>
|
|
18
29
|
</Show>
|
|
19
30
|
</div>
|
package/src/Switch.tsx
CHANGED
|
@@ -17,7 +17,7 @@ const Switch: Component<SwitchProps> = props => {
|
|
|
17
17
|
<button
|
|
18
18
|
class={cs(
|
|
19
19
|
'ant-w-44px ant-h-22px ant-rounded-100px ant-relative',
|
|
20
|
-
checked() ? 'ant-bg-[var(--
|
|
20
|
+
checked() ? 'ant-bg-[var(--ant-color-primary)]' : 'ant-bg-[rgba(0,0,0,0.45)]',
|
|
21
21
|
)}
|
|
22
22
|
onClick={() => setChecked(c => !c)}
|
|
23
23
|
>
|
package/src/Tabs.tsx
CHANGED
|
@@ -92,7 +92,7 @@ const Tabs: Component<TabsProps> = _props => {
|
|
|
92
92
|
class={cs(
|
|
93
93
|
'ant-py-12px ant-cursor-pointer',
|
|
94
94
|
props.navItemClass,
|
|
95
|
-
isSelectedItem(item.key) && 'ant-text-[var(--
|
|
95
|
+
isSelectedItem(item.key) && 'ant-text-[var(--ant-color-primary)] selected',
|
|
96
96
|
)}
|
|
97
97
|
onClick={() => {
|
|
98
98
|
setSelectedItem(item)
|
|
@@ -106,7 +106,7 @@ const Tabs: Component<TabsProps> = _props => {
|
|
|
106
106
|
|
|
107
107
|
<div
|
|
108
108
|
role={'selected-bar' as any}
|
|
109
|
-
class="ant-absolute ant-bottom-0 ant-bg-[var(--
|
|
109
|
+
class="ant-absolute ant-bottom-0 ant-bg-[var(--ant-color-primary)] ant-h-2px ant-transition-left"
|
|
110
110
|
style={selectedBarStyle()}
|
|
111
111
|
/>
|
|
112
112
|
</div>
|
package/src/Timeline.tsx
CHANGED
|
@@ -21,7 +21,7 @@ const Timeline: Component<TimelineProps> = props => {
|
|
|
21
21
|
{i() !== props.items.length - 1 && (
|
|
22
22
|
<div class="ant-absolute ant-top-[8px] ant-bottom-[-24px] ant-left-[4px] ant-w-[2px] ant-bg-[rgba(5,5,5,.06)]" />
|
|
23
23
|
)}
|
|
24
|
-
<div class="ant-w-[10px] ant-h-[10px] ant-border-solid ant-border-width-[3px] ant-border-[var(--
|
|
24
|
+
<div class="ant-w-[10px] ant-h-[10px] ant-border-solid ant-border-width-[3px] ant-border-[var(--ant-color-primary)] ant-bg-white ant-rounded-[50%] ant-mt-[8px]" />
|
|
25
25
|
<div class="ant-ml-[8px]">{item.children?.()}</div>
|
|
26
26
|
</div>
|
|
27
27
|
)}
|
package/src/Tree.tsx
CHANGED
|
@@ -98,7 +98,8 @@ function SingleLevelTree<T extends {} = {}>(props: SingleLevelTreeProps<T>) {
|
|
|
98
98
|
<div
|
|
99
99
|
class={cs(
|
|
100
100
|
'ant-flex ant-items-center ant-h-28px ant-pb-4px',
|
|
101
|
-
isDraggable(item()) &&
|
|
101
|
+
isDraggable(item()) &&
|
|
102
|
+
'ant-[border:1px_solid_var(--ant-color-primary)] ant-bg-white',
|
|
102
103
|
draggableNode() && 'child[]:ant-pointer-events-none',
|
|
103
104
|
)}
|
|
104
105
|
draggable={draggable}
|
|
@@ -168,9 +169,9 @@ function SingleLevelTree<T extends {} = {}>(props: SingleLevelTreeProps<T>) {
|
|
|
168
169
|
class={cs(
|
|
169
170
|
'ant-h-full ant-leading-24px hover:ant-bg-[var(--hover-bg-color)] ant-rounded-1 ant-px-1 ant-cursor-pointer ant-relative',
|
|
170
171
|
props.blockNode && 'w-full',
|
|
171
|
-
selectedNodes()?.includes(item()) && '!ant-bg-[var(--
|
|
172
|
+
selectedNodes()?.includes(item()) && '!ant-bg-[var(--ant-tree-node-selected-bg)]',
|
|
172
173
|
isTarget(item()) &&
|
|
173
|
-
"before:ant-content-[''] before:ant-inline-block before:ant-w-8px before:ant-h-8px before:ant-absolute before:ant-bottom-0 before:ant-left-0 before:-ant-translate-x-full before:ant-translate-y-1/2 before:ant-rounded-1/2 before:ant-[border:2px_solid_var(--
|
|
174
|
+
"before:ant-content-[''] before:ant-inline-block before:ant-w-8px before:ant-h-8px before:ant-absolute before:ant-bottom-0 before:ant-left-0 before:-ant-translate-x-full before:ant-translate-y-1/2 before:ant-rounded-1/2 before:ant-[border:2px_solid_var(--ant-color-primary)] after:ant-content-[''] after:ant-inline-block after:ant-h-2px after:ant-absolute after:ant-left-0 after:ant-right-0 after:ant-bottom--1px after:ant-bg-[var(--ant-color-primary)]",
|
|
174
175
|
)}
|
|
175
176
|
onClick={() => {
|
|
176
177
|
setSelectedNodes([item()])
|
package/src/Upload.tsx
CHANGED
|
@@ -1,10 +1,143 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { nanoid } from 'nanoid'
|
|
2
|
+
import { type Component, mergeProps, type ParentProps, createSignal, type Signal } from 'solid-js'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
interface UploadProgressEvent extends Partial<ProgressEvent> {
|
|
5
|
+
percent?: number
|
|
6
|
+
}
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
export interface UploadRequestOption<T = any> {
|
|
9
|
+
file: File
|
|
10
|
+
onProgress?: (event: UploadProgressEvent) => void
|
|
11
|
+
onError?: (event: Error) => void
|
|
12
|
+
onSuccess?: (body: T) => void
|
|
13
|
+
}
|
|
7
14
|
|
|
8
|
-
export
|
|
15
|
+
export interface UploadFile<T = any> {
|
|
16
|
+
/**
|
|
17
|
+
* 文件唯一标识
|
|
18
|
+
*/
|
|
19
|
+
id: string
|
|
20
|
+
/**
|
|
21
|
+
* 文件名
|
|
22
|
+
*/
|
|
23
|
+
name: string
|
|
24
|
+
/**
|
|
25
|
+
* MIME 类型
|
|
26
|
+
*/
|
|
27
|
+
type?: string
|
|
28
|
+
/**
|
|
29
|
+
* 文件大小
|
|
30
|
+
*/
|
|
31
|
+
size?: number
|
|
32
|
+
file?: File
|
|
33
|
+
response?: T
|
|
34
|
+
status?: 'pending' | 'uploading' | 'error' | 'finished'
|
|
35
|
+
percent?: number
|
|
36
|
+
/**
|
|
37
|
+
* 下载地址
|
|
38
|
+
*/
|
|
39
|
+
url?: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface UploadProps<T = any> extends ParentProps {
|
|
43
|
+
class?: string
|
|
44
|
+
accept?: string
|
|
45
|
+
/**
|
|
46
|
+
* 上传的地址
|
|
47
|
+
*/
|
|
48
|
+
action?: string
|
|
49
|
+
/**
|
|
50
|
+
* 上传请求的 http method
|
|
51
|
+
* 默认 'post'
|
|
52
|
+
*/
|
|
53
|
+
method?: string
|
|
54
|
+
customRequest?: (option: UploadRequestOption<T>) => void
|
|
55
|
+
onAdd?: (fileList: Array<Signal<T>>) => void
|
|
56
|
+
multiple?: boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function request(file: File, customRequest: UploadProps['customRequest']) {
|
|
60
|
+
const id = `upload-${nanoid()}`
|
|
61
|
+
// eslint-disable-next-line solid/reactivity
|
|
62
|
+
const uploadFileSignal = createSignal<UploadFile>({
|
|
63
|
+
id,
|
|
64
|
+
file,
|
|
65
|
+
name: file.name,
|
|
66
|
+
type: file.type,
|
|
67
|
+
size: file.size,
|
|
68
|
+
status: 'pending',
|
|
69
|
+
percent: 0,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const [, setUploadFile] = uploadFileSignal
|
|
73
|
+
|
|
74
|
+
customRequest?.({
|
|
75
|
+
file,
|
|
76
|
+
onProgress(event) {
|
|
77
|
+
setUploadFile(value => ({
|
|
78
|
+
...value,
|
|
79
|
+
status: 'uploading',
|
|
80
|
+
percent: event.percent ?? 0,
|
|
81
|
+
}))
|
|
82
|
+
},
|
|
83
|
+
onSuccess(response) {
|
|
84
|
+
setUploadFile(value => ({ ...value, status: 'finished', response }))
|
|
85
|
+
},
|
|
86
|
+
onError() {
|
|
87
|
+
setUploadFile(value => ({ ...value, status: 'error' }))
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
return uploadFileSignal
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const Upload: Component<UploadProps> & {
|
|
95
|
+
request: typeof request
|
|
96
|
+
} = _props => {
|
|
97
|
+
let input: HTMLInputElement | undefined
|
|
98
|
+
const props = mergeProps(
|
|
99
|
+
{
|
|
100
|
+
customRequest: ({ file, onSuccess, onError }) => {
|
|
101
|
+
if (!_props.action) return
|
|
102
|
+
|
|
103
|
+
const formData = new FormData()
|
|
104
|
+
formData.append('file', file)
|
|
105
|
+
fetch(_props.action, {
|
|
106
|
+
method: _props.method ?? 'post',
|
|
107
|
+
body: formData,
|
|
108
|
+
})
|
|
109
|
+
.then(onSuccess)
|
|
110
|
+
.catch(onError)
|
|
111
|
+
},
|
|
112
|
+
} as UploadProps,
|
|
113
|
+
_props,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<span class={props.class} onClick={() => input?.click()}>
|
|
118
|
+
{props.children}
|
|
119
|
+
|
|
120
|
+
<input
|
|
121
|
+
ref={input}
|
|
122
|
+
class="hidden"
|
|
123
|
+
type="file"
|
|
124
|
+
accept={props.accept}
|
|
125
|
+
multiple={props.multiple}
|
|
126
|
+
onInput={e => {
|
|
127
|
+
const fileList: Array<Signal<UploadFile>> = []
|
|
128
|
+
for (const file of e.target.files ?? []) {
|
|
129
|
+
const uploadFileSignal = request(file, props.customRequest)
|
|
130
|
+
fileList.push(uploadFileSignal)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
props.onAdd?.(fileList)
|
|
134
|
+
e.target.value = ''
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
137
|
+
</span>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
Upload.request = request
|
|
9
142
|
|
|
10
143
|
export default Upload
|
package/src/Compact.tsx
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type ParentProps } from 'solid-js'
|
|
2
|
-
|
|
3
|
-
interface CompactProps extends ParentProps {}
|
|
4
|
-
|
|
5
|
-
function Compact(props: CompactProps) {
|
|
6
|
-
return <div class="ant-compact ant-flex">{props.children}</div>
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
Compact.compactItemClass = 'p[.ant-compact]:ant-ml--1px'
|
|
10
|
-
Compact.compactItemRounded0Class = 'p[.ant-compact>*]:ant-rounded-0'
|
|
11
|
-
Compact.compactItemRoundedLeftClass = 'p[.ant-compact>:first-child]:ant-rounded-l-6px'
|
|
12
|
-
Compact.compactItemRoundedRightClass = 'p[.ant-compact>:last-child]:ant-rounded-r-6px'
|
|
13
|
-
Compact.compactItemZIndexClass = 'p[.ant-compact>*]:focus:ant-z-10 p[.ant-compact>*]:focus-within:ant-z-10'
|
|
14
|
-
|
|
15
|
-
export default Compact
|
|
File without changes
|