x-ui-design 0.2.32 → 0.2.37
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/lib/components/Button/Button.client.tsx +1 -1
- package/lib/components/Button/Button.tsx +1 -1
- package/lib/components/Checkbox/Checkbox.client.tsx +73 -50
- package/lib/components/Checkbox/Checkbox.tsx +5 -75
- package/lib/components/Checkbox/index.ts +1 -1
- package/lib/index.ts +0 -9
- package/lib/types/checkbox.ts +1 -1
- package/package.json +1 -1
- package/src/app/page.tsx +1 -6
- package/src/components/Checkbox/Checkbox.tsx +115 -0
- package/src/components/Checkbox/index.ts +1 -0
- package/src/components/Checkbox/style.css +91 -0
- package/{lib → src}/components/Empty/Empty.tsx +4 -5
- package/src/components/Empty/index.ts +1 -0
- package/{lib/components/Form/Form.client.tsx → src/components/Form/Form.tsx} +13 -12
- package/{lib/components/Form/Item/FormItem.client.tsx → src/components/Form/Item/Item.tsx} +24 -10
- package/src/components/Form/Item/index.ts +1 -0
- package/{lib → src}/hooks/useForm.ts +2 -2
- package/{lib → src}/hooks/useWatch.ts +3 -3
- package/src/types/checkbox.ts +28 -0
- package/{lib → src}/types/empty.ts +1 -1
- package/{lib → src}/types/form.ts +2 -1
- package/src/types/index.ts +27 -0
- package/{lib → src}/types/upload.ts +3 -4
- package/lib/components/Empty/Empty.client.tsx +0 -12
- package/lib/components/Empty/index.ts +0 -1
- package/lib/components/Form/Form.tsx +0 -32
- package/lib/components/Form/Item/FormItem.tsx +0 -42
- package/lib/components/Form/Item/index.ts +0 -1
- /package/{lib → src}/components/Empty/style.css +0 -0
- /package/{lib → src}/components/Form/Item/style.css +0 -0
- /package/{lib → src}/components/Form/index.ts +0 -0
- /package/{lib → src}/types/datepicker.ts +0 -0
- /package/{lib → src}/types/input.ts +0 -0
- /package/{lib → src}/types/radio.ts +0 -0
- /package/{lib → src}/types/select.ts +0 -0
- /package/{lib → src}/types/skeleton.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import Button from './Button';
|
|
5
5
|
import { ButtonProps } from '../../types/button';
|
|
6
6
|
import { prefixClsButton } from '../../utils';
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
ForwardedRef,
|
|
5
|
+
forwardRef,
|
|
6
|
+
MouseEvent,
|
|
7
|
+
ReactElement,
|
|
8
|
+
useEffect,
|
|
9
|
+
useState
|
|
10
|
+
} from 'react';
|
|
11
|
+
import { SyntheticBaseEvent } from '../../types';
|
|
5
12
|
import { CheckboxProps } from '../../types/checkbox';
|
|
13
|
+
import { clsx } from '../../../lib/helpers';
|
|
14
|
+
import { prefixClsCheckbox } from '../../utils';
|
|
15
|
+
import './style.css';
|
|
6
16
|
|
|
7
17
|
const CheckboxClient = forwardRef<HTMLDivElement, CheckboxProps>(
|
|
8
18
|
(
|
|
9
19
|
{
|
|
10
|
-
prefixCls,
|
|
11
|
-
className,
|
|
20
|
+
prefixCls = prefixClsCheckbox,
|
|
21
|
+
className = '',
|
|
12
22
|
defaultChecked = false,
|
|
13
23
|
checked,
|
|
14
24
|
style,
|
|
@@ -30,70 +40,83 @@ const CheckboxClient = forwardRef<HTMLDivElement, CheckboxProps>(
|
|
|
30
40
|
noStyle
|
|
31
41
|
},
|
|
32
42
|
ref: ForwardedRef<HTMLDivElement>
|
|
33
|
-
) => {
|
|
43
|
+
): ReactElement => {
|
|
44
|
+
const isControlled = checked !== undefined;
|
|
34
45
|
const [internalChecked, setInternalChecked] = useState(
|
|
35
|
-
|
|
46
|
+
isControlled ? checked : defaultChecked || value
|
|
36
47
|
);
|
|
37
48
|
|
|
38
|
-
const
|
|
49
|
+
const currentChecked = isControlled ? checked : internalChecked;
|
|
50
|
+
|
|
51
|
+
const handleClick = (
|
|
52
|
+
e: MouseEvent<HTMLInputElement> & SyntheticBaseEvent
|
|
53
|
+
) => {
|
|
39
54
|
e.stopPropagation();
|
|
40
55
|
|
|
41
56
|
if (disabled) {
|
|
42
57
|
return;
|
|
43
58
|
}
|
|
44
59
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (onClick) {
|
|
49
|
-
onClick(e);
|
|
60
|
+
if (!isControlled) {
|
|
61
|
+
setInternalChecked(!currentChecked);
|
|
50
62
|
}
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
target: {
|
|
57
|
-
...e.target,
|
|
58
|
-
value: newChecked,
|
|
59
|
-
checked: newChecked
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
onChange(syntheticEvent);
|
|
63
|
-
}
|
|
64
|
+
e.target.value = !currentChecked;
|
|
65
|
+
|
|
66
|
+
onClick?.(e);
|
|
67
|
+
onChange?.(e);
|
|
64
68
|
};
|
|
65
69
|
|
|
66
70
|
useEffect(() => {
|
|
67
|
-
if (
|
|
71
|
+
if (isControlled) {
|
|
68
72
|
setInternalChecked(checked);
|
|
69
73
|
}
|
|
70
|
-
}, [checked]);
|
|
74
|
+
}, [checked, isControlled]);
|
|
71
75
|
|
|
72
76
|
return (
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
77
|
+
<div className={`${prefixCls}-wrapper`}>
|
|
78
|
+
<div
|
|
79
|
+
ref={ref}
|
|
80
|
+
style={style}
|
|
81
|
+
onClick={(e) => {
|
|
82
|
+
handleClick(e);
|
|
83
|
+
}}
|
|
84
|
+
className={clsx([
|
|
85
|
+
prefixCls,
|
|
86
|
+
className,
|
|
87
|
+
{
|
|
88
|
+
noStyle: noStyle,
|
|
89
|
+
[`${prefixCls}-disabled`]: disabled,
|
|
90
|
+
[`${prefixCls}-checked`]: currentChecked
|
|
91
|
+
}
|
|
92
|
+
])}
|
|
93
|
+
>
|
|
94
|
+
<input
|
|
95
|
+
id={id}
|
|
96
|
+
type={type}
|
|
97
|
+
name={name}
|
|
98
|
+
disabled={disabled}
|
|
99
|
+
checked={currentChecked}
|
|
100
|
+
tabIndex={tabIndex}
|
|
101
|
+
required={required}
|
|
102
|
+
autoFocus={autoFocus}
|
|
103
|
+
onKeyDown={onKeyDown}
|
|
104
|
+
onKeyPress={onKeyPress}
|
|
105
|
+
onMouseEnter={onMouseEnter}
|
|
106
|
+
onMouseLeave={onMouseLeave}
|
|
107
|
+
readOnly
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
<span className={`${prefixCls}-box`}>
|
|
111
|
+
<span
|
|
112
|
+
className={`${prefixCls}-check`}
|
|
113
|
+
style={{ opacity: Number(currentChecked) }}
|
|
114
|
+
/>
|
|
115
|
+
</span>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
{children && <span className={`${prefixCls}-label`}>{children}</span>}
|
|
119
|
+
</div>
|
|
97
120
|
);
|
|
98
121
|
}
|
|
99
122
|
);
|
|
@@ -1,77 +1,7 @@
|
|
|
1
|
-
import React, { ReactElement } from 'react';
|
|
2
1
|
import { CheckboxProps } from '../../types/checkbox';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import CheckboxClient from './Checkbox.client';
|
|
3
|
+
import './style.css';
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
defaultChecked = false,
|
|
10
|
-
checked,
|
|
11
|
-
style,
|
|
12
|
-
disabled = false,
|
|
13
|
-
onChange,
|
|
14
|
-
onClick,
|
|
15
|
-
onMouseEnter,
|
|
16
|
-
onMouseLeave,
|
|
17
|
-
onKeyPress,
|
|
18
|
-
onKeyDown,
|
|
19
|
-
tabIndex,
|
|
20
|
-
name,
|
|
21
|
-
children,
|
|
22
|
-
id,
|
|
23
|
-
autoFocus,
|
|
24
|
-
type = 'checkbox',
|
|
25
|
-
value = false,
|
|
26
|
-
required = false,
|
|
27
|
-
noStyle
|
|
28
|
-
}: CheckboxProps): ReactElement => {
|
|
29
|
-
const isChecked = checked !== undefined ? checked : defaultChecked || value;
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<div className={`${prefixCls}-wrapper`}>
|
|
33
|
-
<div
|
|
34
|
-
style={style}
|
|
35
|
-
className={clsx([
|
|
36
|
-
prefixCls,
|
|
37
|
-
className,
|
|
38
|
-
{
|
|
39
|
-
noStyle: noStyle,
|
|
40
|
-
[`${prefixCls}-disabled`]: disabled,
|
|
41
|
-
[`${prefixCls}-checked`]: isChecked
|
|
42
|
-
}
|
|
43
|
-
])}
|
|
44
|
-
>
|
|
45
|
-
<input
|
|
46
|
-
id={id}
|
|
47
|
-
type={type}
|
|
48
|
-
name={name}
|
|
49
|
-
checked={isChecked}
|
|
50
|
-
disabled={disabled}
|
|
51
|
-
tabIndex={tabIndex}
|
|
52
|
-
required={required}
|
|
53
|
-
autoFocus={autoFocus}
|
|
54
|
-
onClick={onClick}
|
|
55
|
-
onKeyDown={onKeyDown}
|
|
56
|
-
onKeyPress={onKeyPress}
|
|
57
|
-
onMouseEnter={onMouseEnter}
|
|
58
|
-
onMouseLeave={onMouseLeave}
|
|
59
|
-
onChange={(e) => onChange?.(e)}
|
|
60
|
-
/>
|
|
61
|
-
|
|
62
|
-
<span className={`${prefixCls}-box`}>
|
|
63
|
-
<span
|
|
64
|
-
className={`${prefixCls}-check`}
|
|
65
|
-
style={{ opacity: Number(isChecked) }}
|
|
66
|
-
/>
|
|
67
|
-
</span>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
{children && <span className={`${prefixCls}-label`}>{children}</span>}
|
|
71
|
-
</div>
|
|
72
|
-
);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
Checkbox.displayName = 'Checkbox';
|
|
76
|
-
|
|
77
|
-
export default Checkbox;
|
|
5
|
+
export default function CheckboxServer(props: CheckboxProps) {
|
|
6
|
+
return <CheckboxClient {...props} />;
|
|
7
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as Checkbox } from '
|
|
1
|
+
export { default as Checkbox } from '@/components/Checkbox/Checkbox'
|
package/lib/index.ts
CHANGED
|
@@ -2,13 +2,4 @@
|
|
|
2
2
|
import './styles/global.css';
|
|
3
3
|
|
|
4
4
|
// Components
|
|
5
|
-
// export { default as Form } from "./components/Form/Form";
|
|
6
|
-
// export { default as FormItem } from "./components/Form/Item/FormItem";
|
|
7
|
-
|
|
8
|
-
export { default as Empty } from "./components/Empty/Empty";
|
|
9
5
|
export { default as Button } from "./components/Button/Button";
|
|
10
|
-
export { default as Checkbox } from "./components/Checkbox/Checkbox";
|
|
11
|
-
|
|
12
|
-
// Hooks
|
|
13
|
-
// export { useForm } from './hooks/useForm';
|
|
14
|
-
// export { useWatch } from './hooks/useWatch';
|
package/lib/types/checkbox.ts
CHANGED
package/package.json
CHANGED
package/src/app/page.tsx
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { Button } from "../../lib/components/Button"
|
|
4
3
|
import { Checkbox } from "../../lib/components/Checkbox"
|
|
5
4
|
|
|
6
5
|
export default function Home() {
|
|
7
6
|
return (
|
|
8
7
|
<>
|
|
9
|
-
<
|
|
10
|
-
<Checkbox
|
|
11
|
-
onChange={e => console.log(e)}>
|
|
12
|
-
Checkbox
|
|
13
|
-
</Checkbox>
|
|
8
|
+
<Checkbox>Checkbox</Checkbox>
|
|
14
9
|
</>
|
|
15
10
|
)
|
|
16
11
|
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ForwardedRef,
|
|
5
|
+
forwardRef,
|
|
6
|
+
MouseEvent,
|
|
7
|
+
ReactElement,
|
|
8
|
+
useEffect,
|
|
9
|
+
useState
|
|
10
|
+
} from 'react';
|
|
11
|
+
import { clsx } from '../../../lib/helpers';
|
|
12
|
+
import { SyntheticBaseEvent } from '../../types';
|
|
13
|
+
import { CheckboxProps } from '../../types/checkbox';
|
|
14
|
+
import { prefixClsCheckbox } from '../../../lib/utils';
|
|
15
|
+
import './style.css';
|
|
16
|
+
|
|
17
|
+
const Checkbox = forwardRef<HTMLDivElement, CheckboxProps>(
|
|
18
|
+
(
|
|
19
|
+
{
|
|
20
|
+
prefixCls = prefixClsCheckbox,
|
|
21
|
+
className = '',
|
|
22
|
+
defaultChecked = false,
|
|
23
|
+
checked,
|
|
24
|
+
style,
|
|
25
|
+
disabled = false,
|
|
26
|
+
onChange,
|
|
27
|
+
onClick,
|
|
28
|
+
onMouseEnter,
|
|
29
|
+
onMouseLeave,
|
|
30
|
+
onKeyPress,
|
|
31
|
+
onKeyDown,
|
|
32
|
+
tabIndex,
|
|
33
|
+
name,
|
|
34
|
+
children,
|
|
35
|
+
id,
|
|
36
|
+
autoFocus,
|
|
37
|
+
type = 'checkbox',
|
|
38
|
+
value = false,
|
|
39
|
+
required = false,
|
|
40
|
+
noStyle
|
|
41
|
+
},
|
|
42
|
+
ref: ForwardedRef<HTMLDivElement>
|
|
43
|
+
): ReactElement => {
|
|
44
|
+
const isChecked = checked !== undefined ? checked : defaultChecked || value;
|
|
45
|
+
const [internalChecked, setInternalChecked] = useState(isChecked);
|
|
46
|
+
|
|
47
|
+
const handleClick = (
|
|
48
|
+
e: MouseEvent<HTMLInputElement> & SyntheticBaseEvent
|
|
49
|
+
) => {
|
|
50
|
+
e.stopPropagation();
|
|
51
|
+
|
|
52
|
+
if (disabled) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setInternalChecked(!internalChecked);
|
|
57
|
+
e.target.value = !internalChecked;
|
|
58
|
+
|
|
59
|
+
onClick?.(e);
|
|
60
|
+
onChange?.(e);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (checked !== undefined) {
|
|
65
|
+
setInternalChecked(checked);
|
|
66
|
+
}
|
|
67
|
+
}, [checked]);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div className={`${prefixCls}-wrapper`}>
|
|
71
|
+
<div
|
|
72
|
+
ref={ref}
|
|
73
|
+
style={style}
|
|
74
|
+
onClick={handleClick}
|
|
75
|
+
className={clsx([
|
|
76
|
+
prefixCls,
|
|
77
|
+
className,
|
|
78
|
+
{
|
|
79
|
+
noStyle: noStyle,
|
|
80
|
+
[`${prefixCls}-disabled`]: disabled,
|
|
81
|
+
[`${prefixCls}-checked`]: internalChecked
|
|
82
|
+
}
|
|
83
|
+
])}
|
|
84
|
+
>
|
|
85
|
+
<input
|
|
86
|
+
id={id}
|
|
87
|
+
type={type}
|
|
88
|
+
name={name}
|
|
89
|
+
disabled={disabled}
|
|
90
|
+
tabIndex={tabIndex}
|
|
91
|
+
required={required}
|
|
92
|
+
autoFocus={autoFocus}
|
|
93
|
+
onKeyDown={onKeyDown}
|
|
94
|
+
onKeyPress={onKeyPress}
|
|
95
|
+
onMouseEnter={onMouseEnter}
|
|
96
|
+
onMouseLeave={onMouseLeave}
|
|
97
|
+
/>
|
|
98
|
+
|
|
99
|
+
<span className={`${prefixCls}-box`}>
|
|
100
|
+
<span
|
|
101
|
+
className={`${prefixCls}-check`}
|
|
102
|
+
style={{ opacity: Number(internalChecked) }}
|
|
103
|
+
/>
|
|
104
|
+
</span>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
{children && <span className={`${prefixCls}-label`}>{children}</span>}
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
Checkbox.displayName = 'Checkbox';
|
|
114
|
+
|
|
115
|
+
export default Checkbox;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Checkbox } from '@/components/Checkbox/Checkbox'
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
.xUi-checkbox-wrapper {
|
|
2
|
+
cursor: pointer;
|
|
3
|
+
font-size: var(--xui-font-size-md);
|
|
4
|
+
align-items: center;
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
color: var(--xui-main-color);
|
|
7
|
+
margin: 16px 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.xUi-checkbox {
|
|
11
|
+
width: 14px;
|
|
12
|
+
height: 14px;
|
|
13
|
+
position: relative;
|
|
14
|
+
border-radius: var(--xui-border-radius-sm);
|
|
15
|
+
transition: all 0.3s;
|
|
16
|
+
display: inline-block;
|
|
17
|
+
background-color: transparent;
|
|
18
|
+
border: 1px solid var(--xui-border-color);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.xUi-checkbox.xUi-checkbox-checked {
|
|
22
|
+
border-color: var(--xui-primary-color);
|
|
23
|
+
background-color: #f0f5ff;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.xUi-checkbox input {
|
|
27
|
+
inset: 0;
|
|
28
|
+
opacity: 0;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
position: absolute;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.xUi-checkbox-inner {
|
|
34
|
+
top: 50%;
|
|
35
|
+
left: 50%;
|
|
36
|
+
width: 10px;
|
|
37
|
+
height: 6px;
|
|
38
|
+
border-top: 0;
|
|
39
|
+
border-left: 0;
|
|
40
|
+
position: absolute;
|
|
41
|
+
border: 2px solid var(--xui-background-color);
|
|
42
|
+
transform: rotate(45deg) scale(0);
|
|
43
|
+
transition: transform 0.2s ease-in-out;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.xUi-checkbox-check {
|
|
47
|
+
width: 100%;
|
|
48
|
+
height: 100%;
|
|
49
|
+
display: block;
|
|
50
|
+
position: relative;
|
|
51
|
+
transition: 0.1s ease;
|
|
52
|
+
border-color: var(--xui-primary-color);
|
|
53
|
+
background-color: var(--xui-primary-color);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.xUi-checkbox-check::after {
|
|
57
|
+
top: 1px;
|
|
58
|
+
left: 3px;
|
|
59
|
+
width: 5px;
|
|
60
|
+
height: 8px;
|
|
61
|
+
content: "";
|
|
62
|
+
position: absolute;
|
|
63
|
+
border: solid white;
|
|
64
|
+
transform: rotate(45deg);
|
|
65
|
+
border-width: 0 2px 2px 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.xUi-checkbox-disabled,
|
|
69
|
+
.xUi-checkbox-disabled .xUi-checkbox-check {
|
|
70
|
+
opacity: 0.5;
|
|
71
|
+
cursor: not-allowed;
|
|
72
|
+
background-color: var(--xui-color-disabled);
|
|
73
|
+
border-color: var(--xui-border-color) !important;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.xUi-checkbox-label {
|
|
77
|
+
margin-left: 8px;
|
|
78
|
+
user-select: none;
|
|
79
|
+
font-size: 14px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.xUi-checkbox:hover:not(.disabled),
|
|
83
|
+
.xUi-checkbox:focus:not(.disabled) {
|
|
84
|
+
border-color: var(--xui-primary-color);
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.xUi-checkbox.disabled {
|
|
89
|
+
opacity: 0.5;
|
|
90
|
+
cursor: not-allowed;
|
|
91
|
+
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { EmptyProps } from '../../types/empty';
|
|
1
|
+
import { EmptyContentProps } from '../../types/empty';
|
|
3
2
|
import { prefixClsEmpty } from '../../utils';
|
|
4
3
|
import './style.css';
|
|
5
4
|
|
|
6
|
-
const
|
|
5
|
+
const EmptyContent = ({
|
|
7
6
|
icon,
|
|
8
7
|
style = {},
|
|
9
8
|
className = '',
|
|
10
9
|
title = 'No Data',
|
|
11
10
|
description = 'No data',
|
|
12
11
|
prefixCls = prefixClsEmpty
|
|
13
|
-
}:
|
|
12
|
+
}: EmptyContentProps) => (
|
|
14
13
|
<div
|
|
15
14
|
style={style}
|
|
16
15
|
className={`${prefixCls} ${prefixCls}-normal ${prefixCls}-small ${className}`}
|
|
@@ -41,4 +40,4 @@ const Empty = ({
|
|
|
41
40
|
</div>
|
|
42
41
|
);
|
|
43
42
|
|
|
44
|
-
export default
|
|
43
|
+
export default EmptyContent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Empty } from '@/components/Empty/Empty'
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import {
|
|
4
4
|
Children,
|
|
5
|
+
createContext,
|
|
5
6
|
FC,
|
|
6
7
|
Fragment,
|
|
7
8
|
isValidElement,
|
|
@@ -10,15 +11,18 @@ import React, {
|
|
|
10
11
|
useMemo,
|
|
11
12
|
useRef
|
|
12
13
|
} from 'react';
|
|
13
|
-
import { useForm } from '
|
|
14
|
-
import { FormProps } from '../../types/form';
|
|
15
|
-
import {
|
|
14
|
+
import { useForm } from '@/hooks/useForm';
|
|
15
|
+
import { FormInstance, FormItemProps, FormProps } from '../../types/form';
|
|
16
|
+
import { prefixClsForm } from '../../../lib/utils';
|
|
17
|
+
import FormItem from './Item/Item';
|
|
16
18
|
|
|
17
|
-
const
|
|
19
|
+
export const FormContext = createContext<FormInstance | null>(null);
|
|
20
|
+
|
|
21
|
+
const Form: FC<FormProps> & { Item: FC<FormItemProps> } = ({
|
|
18
22
|
children,
|
|
19
23
|
form,
|
|
20
24
|
style = {},
|
|
21
|
-
prefixCls,
|
|
25
|
+
prefixCls = prefixClsForm,
|
|
22
26
|
className = '',
|
|
23
27
|
onFinish,
|
|
24
28
|
onFinishFailed,
|
|
@@ -26,7 +30,6 @@ const FormClient: FC<FormProps> = ({
|
|
|
26
30
|
onValuesChange,
|
|
27
31
|
onFieldsChange,
|
|
28
32
|
layout = 'horizontal',
|
|
29
|
-
onSubmitCapture,
|
|
30
33
|
...rest
|
|
31
34
|
}) => {
|
|
32
35
|
const internalForm = useForm(initialValues, onFieldsChange, onValuesChange);
|
|
@@ -65,11 +68,7 @@ const FormClient: FC<FormProps> = ({
|
|
|
65
68
|
style={style}
|
|
66
69
|
ref={formRef}
|
|
67
70
|
onSubmit={handleSubmit}
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
69
|
-
// @ts-expect-error
|
|
70
|
-
onSubmitCapture={onSubmitCapture}
|
|
71
71
|
className={`${prefixCls} ${className}`}
|
|
72
|
-
{...rest}
|
|
73
72
|
>
|
|
74
73
|
{Children.map(childrenList, child => {
|
|
75
74
|
if (isValidElement(child) && child.type !== Fragment) {
|
|
@@ -94,4 +93,6 @@ const FormClient: FC<FormProps> = ({
|
|
|
94
93
|
);
|
|
95
94
|
};
|
|
96
95
|
|
|
97
|
-
|
|
96
|
+
Form.Item = FormItem;
|
|
97
|
+
|
|
98
|
+
export default Form;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import {
|
|
4
4
|
Children,
|
|
5
5
|
Fragment,
|
|
6
6
|
isValidElement,
|
|
@@ -10,20 +10,20 @@ import React, {
|
|
|
10
10
|
useRef,
|
|
11
11
|
useState
|
|
12
12
|
} from 'react';
|
|
13
|
-
import { clsx } from '
|
|
13
|
+
import { clsx } from '../../../../lib/helpers';
|
|
14
14
|
import { RuleType, SyntheticBaseEvent } from '../../../types';
|
|
15
15
|
import {
|
|
16
16
|
FormItemChildComponentProps,
|
|
17
17
|
FormItemProps
|
|
18
18
|
} from '../../../types/form';
|
|
19
19
|
import { OptionProps } from '../../../types/select';
|
|
20
|
-
import { prefixClsFormItem } from '
|
|
20
|
+
import { prefixClsFormItem } from '../../../../lib/utils';
|
|
21
21
|
import './style.css';
|
|
22
22
|
import { FormContext } from '../Form';
|
|
23
23
|
|
|
24
24
|
const REF_CLIENT_HEIGHT = 24;
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const FormItem = ({
|
|
27
27
|
prefixCls = prefixClsFormItem,
|
|
28
28
|
name,
|
|
29
29
|
label,
|
|
@@ -39,6 +39,7 @@ const FormItemClient = ({
|
|
|
39
39
|
...props
|
|
40
40
|
}: FormItemProps) => {
|
|
41
41
|
const formContext = useContext(FormContext);
|
|
42
|
+
|
|
42
43
|
const errorRef = useRef<HTMLSpanElement>(null);
|
|
43
44
|
|
|
44
45
|
if (!formContext) {
|
|
@@ -86,7 +87,10 @@ const FormItemClient = ({
|
|
|
86
87
|
}, [dependencies, name]);
|
|
87
88
|
|
|
88
89
|
useEffect(() => {
|
|
89
|
-
if (
|
|
90
|
+
if (
|
|
91
|
+
errorRef.current &&
|
|
92
|
+
errorRef.current?.clientHeight >= REF_CLIENT_HEIGHT
|
|
93
|
+
) {
|
|
90
94
|
errorRef.current.style.position = 'relative';
|
|
91
95
|
errorRef.current.style.marginTop = '-16px';
|
|
92
96
|
}
|
|
@@ -115,13 +119,15 @@ const FormItemClient = ({
|
|
|
115
119
|
<label className={`${prefixCls}-label`} htmlFor={name}>
|
|
116
120
|
{label || name}:
|
|
117
121
|
{isRequired && <span className={`${prefixCls}-required`}>*</span>}
|
|
122
|
+
{/* @Todo need to add Tooltip like Ant design */}
|
|
118
123
|
</label>
|
|
119
124
|
)}
|
|
120
125
|
|
|
121
126
|
{Children.map(childrenList, (child, key) => {
|
|
122
127
|
if (isValidElement(child) && child.type !== Fragment) {
|
|
123
128
|
const { value, ...childProps } = child.props;
|
|
124
|
-
const fieldValue =
|
|
129
|
+
const fieldValue =
|
|
130
|
+
getFieldValue(valuePropName || name) ?? initialValue;
|
|
125
131
|
|
|
126
132
|
return (
|
|
127
133
|
<FormItemChildComponent
|
|
@@ -168,11 +174,15 @@ const FormItemChildComponent = ({
|
|
|
168
174
|
...props
|
|
169
175
|
}: FormItemChildComponentProps) => {
|
|
170
176
|
const formContext = useContext(FormContext);
|
|
177
|
+
|
|
171
178
|
const [wasNormalize, setWasNormalize] = useState(false);
|
|
179
|
+
|
|
172
180
|
const { getFieldsValue } = formContext || {};
|
|
173
181
|
|
|
174
182
|
const handleChange = (e: SyntheticBaseEvent, option?: OptionProps) => {
|
|
175
|
-
let rawValue: RuleType | SyntheticBaseEvent = e?.target
|
|
183
|
+
let rawValue: RuleType | SyntheticBaseEvent = e?.target
|
|
184
|
+
? e.target.value
|
|
185
|
+
: e;
|
|
176
186
|
|
|
177
187
|
if (normalize) {
|
|
178
188
|
const prevValue = fieldValue ?? props.value;
|
|
@@ -182,10 +192,14 @@ const FormItemChildComponent = ({
|
|
|
182
192
|
|
|
183
193
|
if (rawValue === prevValue) {
|
|
184
194
|
e.target.value = rawValue;
|
|
195
|
+
|
|
185
196
|
setWasNormalize(prev => !prev);
|
|
186
197
|
|
|
187
198
|
const timeout = setTimeout(() => {
|
|
188
|
-
(
|
|
199
|
+
(
|
|
200
|
+
document.querySelector(`[name='${name}']`) as HTMLInputElement
|
|
201
|
+
)?.focus();
|
|
202
|
+
|
|
189
203
|
clearTimeout(timeout);
|
|
190
204
|
}, 0);
|
|
191
205
|
|
|
@@ -209,6 +223,6 @@ const FormItemChildComponent = ({
|
|
|
209
223
|
);
|
|
210
224
|
};
|
|
211
225
|
|
|
212
|
-
|
|
226
|
+
FormItem.displayName = 'FormItem';
|
|
213
227
|
|
|
214
|
-
export default
|
|
228
|
+
export default FormItem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Item } from './Item'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useRef, useState } from 'react';
|
|
4
|
-
import { RuleTypes } from '
|
|
4
|
+
import { RuleTypes } from '../../src/types';
|
|
5
5
|
import type {
|
|
6
6
|
FieldData,
|
|
7
7
|
FieldError,
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
FormInstance,
|
|
10
10
|
RuleObject,
|
|
11
11
|
RuleRender
|
|
12
|
-
} from '
|
|
12
|
+
} from '../../src/types/form';
|
|
13
13
|
|
|
14
14
|
const useForm = (
|
|
15
15
|
initialValues: Record<string, RuleTypes> = {},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useContext, useEffect, useState } from 'react';
|
|
2
|
-
import { FormContext } from '
|
|
3
|
-
import { RuleType } from '
|
|
4
|
-
import { FormInstance } from '
|
|
2
|
+
import { FormContext } from '@/components/Form/Form';
|
|
3
|
+
import { RuleType } from '../../src/types';
|
|
4
|
+
import { FormInstance } from '../../src/types/form';
|
|
5
5
|
|
|
6
6
|
type UseWatchProps = {
|
|
7
7
|
name?: string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KeyboardEventHandler,
|
|
3
|
+
MouseEvent,
|
|
4
|
+
MouseEventHandler,
|
|
5
|
+
ReactNode
|
|
6
|
+
} from 'react';
|
|
7
|
+
import { DefaultProps, TargetProps } from '../../lib/types';
|
|
8
|
+
|
|
9
|
+
export type CheckboxProps = DefaultProps & {
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
onChange?: (e: MouseEvent<HTMLInputElement> & TargetProps) => void;
|
|
12
|
+
onClick?: MouseEventHandler<HTMLElement>;
|
|
13
|
+
onMouseEnter?: MouseEventHandler<HTMLElement>;
|
|
14
|
+
onMouseLeave?: MouseEventHandler<HTMLElement>;
|
|
15
|
+
onKeyPress?: KeyboardEventHandler<HTMLElement>;
|
|
16
|
+
onKeyDown?: KeyboardEventHandler<HTMLElement>;
|
|
17
|
+
value?: boolean;
|
|
18
|
+
tabIndex?: number;
|
|
19
|
+
name?: string;
|
|
20
|
+
children?: ReactNode;
|
|
21
|
+
id?: string;
|
|
22
|
+
autoFocus?: boolean;
|
|
23
|
+
type?: string;
|
|
24
|
+
skipGroup?: boolean;
|
|
25
|
+
required?: boolean;
|
|
26
|
+
defaultChecked?: boolean;
|
|
27
|
+
checked?: boolean;
|
|
28
|
+
};
|
|
@@ -46,6 +46,7 @@ export interface FieldError {
|
|
|
46
46
|
type FormLayoutTypes = 'horizontal' | 'vertical' | 'inline';
|
|
47
47
|
|
|
48
48
|
export type FormProps = DefaultProps & {
|
|
49
|
+
colon?: boolean;
|
|
49
50
|
name?: string;
|
|
50
51
|
layout?: FormLayoutTypes;
|
|
51
52
|
form?: FormInstance;
|
|
@@ -88,7 +89,7 @@ export type FormItemProps = DefaultProps & {
|
|
|
88
89
|
};
|
|
89
90
|
|
|
90
91
|
export interface FormItemChildComponentProps {
|
|
91
|
-
child: ReactElement;
|
|
92
|
+
child: React.ReactElement;
|
|
92
93
|
name: string;
|
|
93
94
|
error: boolean;
|
|
94
95
|
fieldValue: RuleTypes;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CSSProperties, MouseEvent } from 'react';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export type RuleType = any;
|
|
5
|
+
export type RuleTypes = RuleType | RuleType[];
|
|
6
|
+
export type SizeType = 'small' | 'middle' | 'large';
|
|
7
|
+
export type MouseEventHandlerSelect = MouseEvent<HTMLDivElement> & TargetProps;
|
|
8
|
+
export interface DefaultProps {
|
|
9
|
+
prefixCls?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
style?: CSSProperties;
|
|
12
|
+
noStyle?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type TargetProps = {
|
|
16
|
+
target: {
|
|
17
|
+
value: RuleType;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type SyntheticBaseEvent = {
|
|
22
|
+
target: EventTarget & {
|
|
23
|
+
value: RuleType;
|
|
24
|
+
};
|
|
25
|
+
nativeEvent?: Event & { data?: string | null };
|
|
26
|
+
currentTarget: EventTarget;
|
|
27
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CSSProperties, DragEvent, ReactNode } from 'react';
|
|
2
1
|
import { DefaultProps, RuleType } from '.';
|
|
3
2
|
|
|
4
3
|
export interface RcFile extends File {
|
|
@@ -44,7 +43,7 @@ export type UploadProps = DefaultProps & {
|
|
|
44
43
|
accept?: string;
|
|
45
44
|
beforeUpload?: (file: RcFile, fileList: File[]) => boolean | Promise<boolean>;
|
|
46
45
|
onChange?: (info: UploadChangeParam) => void;
|
|
47
|
-
onDrop?: (event: DragEvent<HTMLDivElement>) => void;
|
|
46
|
+
onDrop?: (event: React.DragEvent<HTMLDivElement>) => void;
|
|
48
47
|
listType?: string;
|
|
49
48
|
className?: string;
|
|
50
49
|
rootClassName?: string;
|
|
@@ -54,7 +53,7 @@ export type UploadProps = DefaultProps & {
|
|
|
54
53
|
file: UploadFile<RuleType>
|
|
55
54
|
) => void | boolean | Promise<void | boolean>;
|
|
56
55
|
disabled?: boolean;
|
|
57
|
-
style?: CSSProperties;
|
|
56
|
+
style?: React.CSSProperties;
|
|
58
57
|
customRequest?: (options: {
|
|
59
58
|
file: RcFile;
|
|
60
59
|
onSuccess: (response: RuleType) => void;
|
|
@@ -64,5 +63,5 @@ export type UploadProps = DefaultProps & {
|
|
|
64
63
|
withCredentials?: boolean;
|
|
65
64
|
openFileDialogOnClick?: boolean;
|
|
66
65
|
maxCount?: number;
|
|
67
|
-
children?: ReactNode;
|
|
66
|
+
children?: React.ReactNode;
|
|
68
67
|
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { EmptyProps } from '../../types/empty';
|
|
5
|
-
import Empty from './Empty';
|
|
6
|
-
import './style.css';
|
|
7
|
-
|
|
8
|
-
const EmptyClient = (props: EmptyProps) => (
|
|
9
|
-
<Empty {...props} />
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
export default EmptyClient;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as Empty } from './Empty'
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import React, { createContext, FC } from 'react';
|
|
2
|
-
import { FormInstance, FormItemProps, FormProps } from '../../types/form';
|
|
3
|
-
import { prefixClsForm } from '../../utils';
|
|
4
|
-
import FormItem from './Item/FormItem';
|
|
5
|
-
import FormClient from './Form.client';
|
|
6
|
-
|
|
7
|
-
export const FormContext = createContext<FormInstance | null>(null);
|
|
8
|
-
|
|
9
|
-
const Form: FC<FormProps> & { Item: FC<FormItemProps> } = ({
|
|
10
|
-
children,
|
|
11
|
-
style = {},
|
|
12
|
-
prefixCls = prefixClsForm,
|
|
13
|
-
className = '',
|
|
14
|
-
layout = 'horizontal',
|
|
15
|
-
...rest
|
|
16
|
-
}) => {
|
|
17
|
-
return (
|
|
18
|
-
<FormClient
|
|
19
|
-
style={style}
|
|
20
|
-
prefixCls={prefixCls}
|
|
21
|
-
className={className}
|
|
22
|
-
layout={layout}
|
|
23
|
-
{...rest}
|
|
24
|
-
>
|
|
25
|
-
{children}
|
|
26
|
-
</FormClient>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
Form.Item = FormItem;
|
|
31
|
-
|
|
32
|
-
export default Form;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { FormItemProps } from '../../../types/form';
|
|
2
|
-
import { prefixClsFormItem } from '../../../utils';
|
|
3
|
-
import FormItemClient from './FormItem.client';
|
|
4
|
-
|
|
5
|
-
const FormItem = ({
|
|
6
|
-
prefixCls = prefixClsFormItem,
|
|
7
|
-
name,
|
|
8
|
-
label,
|
|
9
|
-
rules = [],
|
|
10
|
-
children,
|
|
11
|
-
className = '',
|
|
12
|
-
layout = 'vertical',
|
|
13
|
-
style = {},
|
|
14
|
-
valuePropName,
|
|
15
|
-
dependencies = [],
|
|
16
|
-
initialValue,
|
|
17
|
-
feedbackIcons,
|
|
18
|
-
...props
|
|
19
|
-
}: FormItemProps) => {
|
|
20
|
-
return (
|
|
21
|
-
<FormItemClient
|
|
22
|
-
prefixCls={prefixCls}
|
|
23
|
-
name={name}
|
|
24
|
-
label={label}
|
|
25
|
-
rules={rules}
|
|
26
|
-
className={className}
|
|
27
|
-
layout={layout}
|
|
28
|
-
style={style}
|
|
29
|
-
valuePropName={valuePropName}
|
|
30
|
-
dependencies={dependencies}
|
|
31
|
-
initialValue={initialValue}
|
|
32
|
-
feedbackIcons={feedbackIcons}
|
|
33
|
-
{...props}
|
|
34
|
-
>
|
|
35
|
-
{children}
|
|
36
|
-
</FormItemClient>
|
|
37
|
-
);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
FormItem.displayName = 'FormItem';
|
|
41
|
-
|
|
42
|
-
export default FormItem;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as Item } from './FormItem'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|