x-ui-design 1.0.31-gamma.1 → 1.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/.github/workflows/x-ui-design.yml +14 -0
  2. package/README.md +22 -1
  3. package/compile.sh +15 -0
  4. package/dist/{components → esm/types/components}/DatePicker/DatePicker.d.ts +2 -1
  5. package/dist/{components → esm/types/components}/DatePicker/RangePicker/RangePicker.d.ts +2 -1
  6. package/dist/{components → esm/types/components}/Dropdown/Dropdown.d.ts +2 -1
  7. package/dist/{components → esm/types/components}/Empty/Empty.d.ts +2 -1
  8. package/dist/{components → esm/types/components}/Form/Item/Item.d.ts +2 -1
  9. package/dist/esm/types/components/Icons/Icons.d.ts +19 -0
  10. package/dist/{components → esm/types/components}/Input/Input.d.ts +2 -1
  11. package/dist/{components → esm/types/components}/Input/Textarea/Textarea.d.ts +2 -1
  12. package/dist/{components → esm/types/components}/Popover/Popover.d.ts +2 -1
  13. package/dist/{components → esm/types/components}/Radio/Button/Button.d.ts +2 -1
  14. package/dist/{components → esm/types/components}/Radio/Group/Group.d.ts +2 -1
  15. package/dist/{components → esm/types/components}/Radio/Radio.d.ts +2 -1
  16. package/dist/{components → esm/types/components}/Result/Result.d.ts +2 -1
  17. package/dist/{components → esm/types/components}/Switch/Switch.d.ts +2 -1
  18. package/dist/{components → esm/types/components}/Upload/Upload.d.ts +2 -1
  19. package/dist/esm/types/index.d.ts +50 -0
  20. package/dist/{types → esm/types/types}/input.d.ts +2 -2
  21. package/dist/index.d.ts +144 -1
  22. package/dist/index.esm.js +4233 -3792
  23. package/dist/index.esm.js.map +1 -1
  24. package/dist/index.js +4338 -3897
  25. package/dist/index.js.map +1 -1
  26. package/eslint.config.mjs +16 -0
  27. package/lib/components/Button/Button.tsx +136 -0
  28. package/lib/components/Button/index.ts +1 -0
  29. package/lib/components/Button/style.css +197 -0
  30. package/lib/components/Checkbox/Checkbox.tsx +131 -0
  31. package/lib/components/Checkbox/index.ts +1 -0
  32. package/lib/components/Checkbox/style.css +95 -0
  33. package/lib/components/ConditionalWrapper/index.tsx +12 -0
  34. package/lib/components/DatePicker/DatePicker.tsx +526 -0
  35. package/lib/components/DatePicker/RangePicker/RangePicker.tsx +500 -0
  36. package/lib/components/DatePicker/RangePicker/index.ts +1 -0
  37. package/lib/components/DatePicker/RangePicker/style.css +434 -0
  38. package/lib/components/DatePicker/TimePicker/TimePicker.tsx +497 -0
  39. package/lib/components/DatePicker/TimePicker/index.ts +1 -0
  40. package/lib/components/DatePicker/TimePicker/style.css +197 -0
  41. package/lib/components/DatePicker/index.ts +1 -0
  42. package/lib/components/DatePicker/style.css +318 -0
  43. package/lib/components/Dropdown/Dropdown.tsx +234 -0
  44. package/lib/components/Dropdown/index.ts +1 -0
  45. package/lib/components/Dropdown/style.css +124 -0
  46. package/lib/components/Empty/Empty.tsx +45 -0
  47. package/lib/components/Empty/index.ts +1 -0
  48. package/lib/components/Empty/style.css +13 -0
  49. package/lib/components/Form/Form.tsx +130 -0
  50. package/lib/components/Form/Item/Item.tsx +294 -0
  51. package/lib/components/Form/Item/index.ts +1 -0
  52. package/lib/components/Form/Item/style.css +61 -0
  53. package/lib/components/Form/index.ts +1 -0
  54. package/lib/components/Icons/Icons.tsx +433 -0
  55. package/lib/components/Icons/index.ts +15 -0
  56. package/lib/components/Input/Input.tsx +218 -0
  57. package/lib/components/Input/Textarea/Textarea.tsx +110 -0
  58. package/lib/components/Input/Textarea/index.ts +1 -0
  59. package/lib/components/Input/Textarea/style.css +104 -0
  60. package/lib/components/Input/index.ts +1 -0
  61. package/lib/components/Input/style.css +137 -0
  62. package/lib/components/Menu/Item/Item.tsx +65 -0
  63. package/lib/components/Menu/Menu.tsx +261 -0
  64. package/lib/components/Menu/SubMenu/SubMenu.tsx +68 -0
  65. package/lib/components/Menu/index.css +145 -0
  66. package/lib/components/Menu/index.ts +1 -0
  67. package/lib/components/Popover/Popover.tsx +135 -0
  68. package/lib/components/Popover/index.ts +1 -0
  69. package/lib/components/Popover/style.css +82 -0
  70. package/lib/components/Radio/Button/Button.tsx +42 -0
  71. package/lib/components/Radio/Button/index.ts +1 -0
  72. package/lib/components/Radio/Button/style.css +43 -0
  73. package/lib/components/Radio/Group/Group.tsx +105 -0
  74. package/lib/components/Radio/Group/index.ts +1 -0
  75. package/lib/components/Radio/Group/style.css +53 -0
  76. package/lib/components/Radio/Radio.tsx +83 -0
  77. package/lib/components/Radio/index.ts +1 -0
  78. package/lib/components/Radio/style.css +73 -0
  79. package/lib/components/Result/Result.tsx +39 -0
  80. package/lib/components/Result/index.ts +1 -0
  81. package/lib/components/Result/style.css +173 -0
  82. package/lib/components/Select/Option/Option.tsx +49 -0
  83. package/lib/components/Select/Option/index.ts +1 -0
  84. package/lib/components/Select/Option/style.css +50 -0
  85. package/lib/components/Select/Select.tsx +935 -0
  86. package/lib/components/Select/Tag/Tag.tsx +43 -0
  87. package/lib/components/Select/Tag/index.ts +1 -0
  88. package/lib/components/Select/Tag/style.css +87 -0
  89. package/lib/components/Select/index.ts +1 -0
  90. package/lib/components/Select/style.css +186 -0
  91. package/lib/components/Skeleton/Avatar/Avatar.tsx +61 -0
  92. package/lib/components/Skeleton/Avatar/index.ts +1 -0
  93. package/lib/components/Skeleton/Avatar/style.css +27 -0
  94. package/lib/components/Skeleton/Button/Button.tsx +44 -0
  95. package/lib/components/Skeleton/Button/index.ts +1 -0
  96. package/lib/components/Skeleton/Button/style.css +50 -0
  97. package/lib/components/Skeleton/Image/Image.tsx +45 -0
  98. package/lib/components/Skeleton/Image/index.ts +1 -0
  99. package/lib/components/Skeleton/Image/style.css +23 -0
  100. package/lib/components/Skeleton/Input/Input.tsx +42 -0
  101. package/lib/components/Skeleton/Input/index.ts +1 -0
  102. package/lib/components/Skeleton/Input/style.css +56 -0
  103. package/lib/components/Skeleton/Skeleton.tsx +97 -0
  104. package/lib/components/Skeleton/index.ts +1 -0
  105. package/lib/components/Skeleton/style.css +84 -0
  106. package/lib/components/Switch/Switch.tsx +68 -0
  107. package/lib/components/Switch/index.css +50 -0
  108. package/lib/components/Switch/index.ts +1 -0
  109. package/lib/components/Upload/Upload.tsx +291 -0
  110. package/lib/components/Upload/index.ts +1 -0
  111. package/lib/components/Upload/style.css +151 -0
  112. package/lib/global.d.ts +1 -0
  113. package/lib/helpers/flatten.ts +26 -0
  114. package/lib/helpers/index.ts +52 -0
  115. package/lib/helpers/mask.ts +52 -0
  116. package/lib/hooks/useForm.ts +548 -0
  117. package/lib/hooks/usePosition.ts +206 -0
  118. package/lib/hooks/useWatch.ts +41 -0
  119. package/lib/hooks/useWatchError.ts +20 -0
  120. package/lib/index.ts +184 -0
  121. package/lib/styles/global.css +57 -0
  122. package/lib/types/button.ts +83 -0
  123. package/lib/types/checkbox.ts +32 -0
  124. package/lib/types/datepicker.ts +165 -0
  125. package/lib/types/dropdown.ts +41 -0
  126. package/lib/types/empty.ts +8 -0
  127. package/lib/types/form.ts +179 -0
  128. package/lib/types/index.ts +38 -0
  129. package/lib/types/input.ts +72 -0
  130. package/lib/types/menu.ts +55 -0
  131. package/lib/types/popover.ts +16 -0
  132. package/lib/types/radio.ts +69 -0
  133. package/lib/types/result.ts +22 -0
  134. package/lib/types/select.ts +126 -0
  135. package/lib/types/skeleton.ts +62 -0
  136. package/lib/types/switch.ts +22 -0
  137. package/lib/types/upload.ts +67 -0
  138. package/lib/utils/index.ts +37 -0
  139. package/lib/utils/lazy.ts +17 -0
  140. package/next.config.ts +7 -0
  141. package/package.json +18 -20
  142. package/rollup.config.js +71 -0
  143. package/src/app/favicon.ico +0 -0
  144. package/src/app/globals.css +48 -0
  145. package/src/app/layout.d.ts +5 -0
  146. package/src/app/layout.tsx +16 -0
  147. package/src/app/page.d.ts +1 -0
  148. package/src/app/page.tsx +22 -0
  149. package/tsconfig.json +46 -0
  150. package/dist/components/Icons/Icons.d.ts +0 -18
  151. /package/dist/{components → esm/types/components}/Button/Button.d.ts +0 -0
  152. /package/dist/{components → esm/types/components}/Button/index.d.ts +0 -0
  153. /package/dist/{components → esm/types/components}/Checkbox/Checkbox.d.ts +0 -0
  154. /package/dist/{components → esm/types/components}/Checkbox/index.d.ts +0 -0
  155. /package/dist/{components → esm/types/components}/ConditionalWrapper/index.d.ts +0 -0
  156. /package/dist/{components → esm/types/components}/DatePicker/RangePicker/index.d.ts +0 -0
  157. /package/dist/{components → esm/types/components}/DatePicker/TimePicker/TimePicker.d.ts +0 -0
  158. /package/dist/{components → esm/types/components}/DatePicker/TimePicker/index.d.ts +0 -0
  159. /package/dist/{components → esm/types/components}/DatePicker/index.d.ts +0 -0
  160. /package/dist/{components → esm/types/components}/Dropdown/index.d.ts +0 -0
  161. /package/dist/{components → esm/types/components}/Empty/index.d.ts +0 -0
  162. /package/dist/{components → esm/types/components}/Form/Form.d.ts +0 -0
  163. /package/dist/{components → esm/types/components}/Form/Item/index.d.ts +0 -0
  164. /package/dist/{components → esm/types/components}/Form/index.d.ts +0 -0
  165. /package/dist/{components → esm/types/components}/Icons/index.d.ts +0 -0
  166. /package/dist/{components → esm/types/components}/Input/Textarea/index.d.ts +0 -0
  167. /package/dist/{components → esm/types/components}/Input/index.d.ts +0 -0
  168. /package/dist/{components → esm/types/components}/Menu/Item/Item.d.ts +0 -0
  169. /package/dist/{components → esm/types/components}/Menu/Menu.d.ts +0 -0
  170. /package/dist/{components → esm/types/components}/Menu/SubMenu/SubMenu.d.ts +0 -0
  171. /package/dist/{components → esm/types/components}/Menu/index.d.ts +0 -0
  172. /package/dist/{components → esm/types/components}/Popover/index.d.ts +0 -0
  173. /package/dist/{components → esm/types/components}/Radio/Button/index.d.ts +0 -0
  174. /package/dist/{components → esm/types/components}/Radio/Group/index.d.ts +0 -0
  175. /package/dist/{components → esm/types/components}/Radio/index.d.ts +0 -0
  176. /package/dist/{components → esm/types/components}/Result/index.d.ts +0 -0
  177. /package/dist/{components → esm/types/components}/Select/Option/Option.d.ts +0 -0
  178. /package/dist/{components → esm/types/components}/Select/Option/index.d.ts +0 -0
  179. /package/dist/{components → esm/types/components}/Select/Select.d.ts +0 -0
  180. /package/dist/{components → esm/types/components}/Select/Tag/Tag.d.ts +0 -0
  181. /package/dist/{components → esm/types/components}/Select/Tag/index.d.ts +0 -0
  182. /package/dist/{components → esm/types/components}/Select/index.d.ts +0 -0
  183. /package/dist/{components → esm/types/components}/Skeleton/Avatar/Avatar.d.ts +0 -0
  184. /package/dist/{components → esm/types/components}/Skeleton/Avatar/index.d.ts +0 -0
  185. /package/dist/{components → esm/types/components}/Skeleton/Button/Button.d.ts +0 -0
  186. /package/dist/{components → esm/types/components}/Skeleton/Button/index.d.ts +0 -0
  187. /package/dist/{components → esm/types/components}/Skeleton/Image/Image.d.ts +0 -0
  188. /package/dist/{components → esm/types/components}/Skeleton/Image/index.d.ts +0 -0
  189. /package/dist/{components → esm/types/components}/Skeleton/Input/Input.d.ts +0 -0
  190. /package/dist/{components → esm/types/components}/Skeleton/Input/index.d.ts +0 -0
  191. /package/dist/{components → esm/types/components}/Skeleton/Skeleton.d.ts +0 -0
  192. /package/dist/{components → esm/types/components}/Skeleton/index.d.ts +0 -0
  193. /package/dist/{components → esm/types/components}/Switch/index.d.ts +0 -0
  194. /package/dist/{components → esm/types/components}/Upload/index.d.ts +0 -0
  195. /package/dist/{helpers → esm/types/helpers}/flatten.d.ts +0 -0
  196. /package/dist/{helpers → esm/types/helpers}/index.d.ts +0 -0
  197. /package/dist/{helpers → esm/types/helpers}/mask.d.ts +0 -0
  198. /package/dist/{hooks → esm/types/hooks}/useForm.d.ts +0 -0
  199. /package/dist/{hooks → esm/types/hooks}/usePosition.d.ts +0 -0
  200. /package/dist/{hooks → esm/types/hooks}/useWatch.d.ts +0 -0
  201. /package/dist/{hooks → esm/types/hooks}/useWatchError.d.ts +0 -0
  202. /package/dist/{types → esm/types/types}/button.d.ts +0 -0
  203. /package/dist/{types → esm/types/types}/checkbox.d.ts +0 -0
  204. /package/dist/{types → esm/types/types}/datepicker.d.ts +0 -0
  205. /package/dist/{types → esm/types/types}/dropdown.d.ts +0 -0
  206. /package/dist/{types → esm/types/types}/empty.d.ts +0 -0
  207. /package/dist/{types → esm/types/types}/form.d.ts +0 -0
  208. /package/dist/{types → esm/types/types}/index.d.ts +0 -0
  209. /package/dist/{types → esm/types/types}/menu.d.ts +0 -0
  210. /package/dist/{types → esm/types/types}/popover.d.ts +0 -0
  211. /package/dist/{types → esm/types/types}/radio.d.ts +0 -0
  212. /package/dist/{types → esm/types/types}/result.d.ts +0 -0
  213. /package/dist/{types → esm/types/types}/select.d.ts +0 -0
  214. /package/dist/{types → esm/types/types}/skeleton.d.ts +0 -0
  215. /package/dist/{types → esm/types/types}/switch.d.ts +0 -0
  216. /package/dist/{types → esm/types/types}/upload.d.ts +0 -0
  217. /package/dist/{utils → esm/types/utils}/index.d.ts +0 -0
  218. /package/dist/{utils → esm/types/utils}/lazy.d.ts +0 -0
@@ -0,0 +1,97 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { clsx, createArray } from '../../helpers';
3
+ import { SkeletonProps } from '../../types/skeleton';
4
+ import { prefixClsSkeleton } from '../../utils';
5
+ import { SkeletonButton } from './Button';
6
+ import { SkeletonAvatar } from './Avatar';
7
+ import { GET_AVATAR_SKELETON_PROPS } from './Avatar/Avatar';
8
+ import { SkeletonImage } from './Image';
9
+ import { SkeletonInput } from './Input';
10
+ import './style.css';
11
+
12
+ const PARAGRAPH_AVATAR_ROWS = 2;
13
+ const PARAGRAPH_DEFAULT_ROWS = 3;
14
+
15
+ const SkeletonComponent = ({
16
+ prefixCls = prefixClsSkeleton,
17
+ active,
18
+ className,
19
+ style,
20
+ avatar,
21
+ paragraph,
22
+ round,
23
+ title,
24
+ teamLogo = true
25
+ }: SkeletonProps): ReactElement => {
26
+ const GET_TITLE_SKELETON_PROPS =
27
+ typeof title !== 'boolean'
28
+ ? {
29
+ style: { width: title?.width, ...title?.style },
30
+ className: title?.className || ''
31
+ }
32
+ : {};
33
+
34
+ const PARAGRAPH_ROWS = avatar
35
+ ? PARAGRAPH_AVATAR_ROWS
36
+ : PARAGRAPH_DEFAULT_ROWS;
37
+
38
+ const HAS_PHARAGRAPH =
39
+ typeof paragraph === 'boolean' || !paragraph
40
+ ? PARAGRAPH_ROWS
41
+ : paragraph?.rows ?? PARAGRAPH_ROWS;
42
+
43
+ return (
44
+ <div
45
+ className={clsx([
46
+ prefixCls,
47
+ {
48
+ [`${prefixCls}__withAvatar`]: avatar,
49
+ [`${prefixCls}-active`]: active,
50
+ [`${prefixCls}-round`]: round
51
+ },
52
+ className
53
+ ])}
54
+ style={style}
55
+ >
56
+ {avatar && teamLogo && (
57
+ <div className={`${prefixCls}__header`}>
58
+ <SkeletonAvatar {...GET_AVATAR_SKELETON_PROPS(avatar)} />
59
+ </div>
60
+ )}
61
+
62
+ <div className={`${prefixCls}-content`}>
63
+ <h3
64
+ className={clsx([
65
+ `${prefixCls}-title ${GET_TITLE_SKELETON_PROPS.className}`,
66
+ { [`${prefixCls}-title-avatar`]: avatar }
67
+ ])}
68
+ style={GET_TITLE_SKELETON_PROPS.style}
69
+ />
70
+
71
+ {paragraph !== false && (
72
+ <ul
73
+ className={`${prefixCls}-paragraph`}
74
+ style={{
75
+ ...(typeof paragraph !== 'boolean' && paragraph
76
+ ? paragraph.style
77
+ : {})
78
+ }}
79
+ >
80
+ {createArray(HAS_PHARAGRAPH).map(key => (
81
+ <li key={key}></li>
82
+ ))}
83
+ </ul>
84
+ )}
85
+ </div>
86
+ </div>
87
+ );
88
+ };
89
+
90
+ const Skeleton = Object.assign(SkeletonComponent, {
91
+ Image: SkeletonImage,
92
+ Input: SkeletonInput,
93
+ Avatar: SkeletonAvatar,
94
+ Button: SkeletonButton
95
+ })
96
+
97
+ export default Skeleton
@@ -0,0 +1 @@
1
+ export { default as Skeleton } from './Skeleton'
@@ -0,0 +1,84 @@
1
+ @keyframes xUi-skeleton-loading {
2
+ 0% {
3
+ background-position: 100% 50%;
4
+ }
5
+ 100% {
6
+ background-position: 0 50%;
7
+ }
8
+ }
9
+
10
+ .xUi-skeleton {
11
+ width: 100%;
12
+ display: table;
13
+ }
14
+
15
+ .xUi-skeleton__withAvatar {
16
+ display: flex;
17
+ gap: 12px;
18
+ }
19
+
20
+ .xUi-skeleton-content {
21
+ width: 100%;
22
+ display: table-cell;
23
+ vertical-align: top;
24
+ }
25
+
26
+ .xUi-skeleton__header {
27
+ display: table-cell;
28
+ vertical-align: top;
29
+ }
30
+
31
+ .xUi-skeleton-title {
32
+ width: 38%;
33
+ height: 16px;
34
+ margin-top: 16px;
35
+ border-radius: 4px;
36
+ background: rgba(190, 190, 190, 0.2);
37
+ }
38
+
39
+ .xUi-skeleton-title-avatar {
40
+ width: 100%;
41
+ margin-top: 12px;
42
+ }
43
+
44
+ .xUi-skeleton-title + .xUi-skeleton-paragraph {
45
+ margin-top: 24px;
46
+ }
47
+
48
+ .xUi-skeleton-paragraph {
49
+ padding: 0;
50
+ }
51
+
52
+ .xUi-skeleton-paragraph li {
53
+ width: 100%;
54
+ height: 16px;
55
+ list-style: none;
56
+ border-radius: 4px;
57
+ background: rgba(190, 190, 190, 0.2);
58
+ }
59
+
60
+ .xUi-skeleton-paragraph li + li {
61
+ margin-top: 16px;
62
+ }
63
+
64
+ .xUi-skeleton-paragraph li:last-child:not(:first-child) {
65
+ width: 61%;
66
+ }
67
+
68
+ .xUi-skeleton-active .xUi-skeleton-title,
69
+ .xUi-skeleton-active .xUi-skeleton-paragraph > li {
70
+ background: linear-gradient(
71
+ 90deg,
72
+ rgba(190, 190, 190, 0.2) 25%,
73
+ rgba(129, 129, 129, 0.24) 37%,
74
+ rgba(190, 190, 190, 0.2) 63%
75
+ );
76
+ background-size: 400% 100%;
77
+ animation: xUi-skeleton-loading 1.4s ease infinite;
78
+ }
79
+
80
+ .xUi-skeleton-round .xUi-skeleton-title,
81
+ .xUi-skeleton-round .xUi-skeleton-content,
82
+ .xUi-skeleton-round .xUi-skeleton-paragraph > li {
83
+ border-radius: 100px;
84
+ }
@@ -0,0 +1,68 @@
1
+ import React, { MouseEvent, useEffect, useState } from 'react';
2
+ import { SyntheticBaseEvent } from '../../types';
3
+ import { SwitchProps } from '../../types/switch';
4
+ import { prefixClsSwitch, prefixClsSwitchV3 } from '../../utils';
5
+ import './index.css';
6
+
7
+ const Switch = ({
8
+ prefixCls = prefixClsSwitch,
9
+ prefixClsV3 = prefixClsSwitchV3,
10
+ checked,
11
+ onChange,
12
+ onClick,
13
+ disabled = false,
14
+ className = '',
15
+ style = {},
16
+ defaultChecked,
17
+ value,
18
+ controlled = false
19
+ }: SwitchProps) => {
20
+ const isChecked = checked !== undefined ? checked : defaultChecked || value;
21
+ const [internalChecked, setInternalChecked] = useState(isChecked);
22
+
23
+ const handleClick = (
24
+ e: MouseEvent<HTMLInputElement> & SyntheticBaseEvent
25
+ ) => {
26
+ e.stopPropagation();
27
+
28
+ if (disabled) {
29
+ return;
30
+ }
31
+
32
+ if (!controlled) {
33
+ setInternalChecked(!internalChecked);
34
+ e.target.value = !internalChecked;
35
+ } else {
36
+ e.target.value = !checked;
37
+ }
38
+
39
+ onClick?.(e.target.value);
40
+ onChange?.(e.target.value);
41
+ };
42
+
43
+ useEffect(() => {
44
+ if (checked !== undefined) {
45
+ setInternalChecked(checked);
46
+ }
47
+ }, [checked]);
48
+
49
+ return (
50
+ <div
51
+ tabIndex={0}
52
+ role="button"
53
+ className={`${prefixCls}-wrapper ${prefixClsV3}-wrapper ${className} ${disabled ? `${prefixCls}__disabled ${prefixClsV3}__disabled` : ''}`}
54
+ style={style}
55
+ >
56
+ <div
57
+ className={`${prefixCls} ${prefixClsV3} ${internalChecked ? `${prefixCls}__checked ${prefixClsV3}__checked` : ''}`}
58
+ onClick={handleClick}
59
+ >
60
+ <div className={`${prefixCls}__slider ${prefixClsV3}__slider`}></div>
61
+ </div>
62
+ </div>
63
+ );
64
+ };
65
+
66
+ Switch.displayName = 'Switch';
67
+
68
+ export default Switch
@@ -0,0 +1,50 @@
1
+ .xUi-switch {
2
+ border: 0;
3
+ border-radius: 100px;
4
+ box-sizing: border-box;
5
+ color: #000000d9;
6
+ cursor: pointer;
7
+ display: inline-block;
8
+ font-size: 14px;
9
+ font-variant: tabular-nums;
10
+ height: 22px;
11
+ list-style: none;
12
+ margin: 0;
13
+ min-width: 44px;
14
+ padding: 0;
15
+ position: relative;
16
+ transition: all 0.2s;
17
+ user-select: none;
18
+ vertical-align: middle;
19
+ background-color: var(--xui-color-disabled);
20
+ }
21
+
22
+ .xUi-switch-wrapper {
23
+ &:has([tabindex="0"]:focus-visible) {
24
+ border-color: var(--xui-primary-color);
25
+ }
26
+ }
27
+
28
+ .xUi-switch.xUi-switch__disabled {
29
+ opacity: 0.5;
30
+ pointer-events: none;
31
+ }
32
+
33
+ .xUi-switch .xUi-switch__slider {
34
+ position: absolute;
35
+ height: 18px;
36
+ left: 2px;
37
+ top: 2px;
38
+ width: 18px;
39
+ border-radius: 50%;
40
+ background-color: white;
41
+ transition: transform 0.3s;
42
+ }
43
+
44
+ .xUi-switch__checked .xUi-switch__slider {
45
+ transform: translateX(21px);
46
+ }
47
+
48
+ .xUi-switch__checked {
49
+ background-color: var(--xui-primary-color);
50
+ }
@@ -0,0 +1 @@
1
+ export { default as Switch } from './Switch'
@@ -0,0 +1,291 @@
1
+ 'use client';
2
+
3
+ import React, { useRef, useState } from 'react';
4
+ import { clsx } from '../../helpers';
5
+ import { RuleType } from '../../types';
6
+ import {
7
+ RcFile,
8
+ UploadChangeParam,
9
+ UploadFile,
10
+ UploadProps
11
+ } from '../../types/upload';
12
+ import { prefixClsUpload, prefixClsUploadV3 } from '../../utils';
13
+ import './style.css';
14
+ import { StampleIcon, TrashIcon } from '../Icons/Icons';
15
+
16
+ const IMAGE_SIZE = 40;
17
+ const IMAGE_PROGRESS_PERCENT = 100;
18
+
19
+ const Upload = ({
20
+ prefixCls = prefixClsUpload,
21
+ prefixClsV3 = prefixClsUploadV3,
22
+ multiple = false,
23
+ style,
24
+ className,
25
+ onChange,
26
+ action,
27
+ name = 'file',
28
+ method = 'POST',
29
+ headers,
30
+ directory,
31
+ beforeUpload,
32
+ rootClassName,
33
+ onRemove,
34
+ disabled,
35
+ withCredentials,
36
+ openFileDialogOnClick = true,
37
+ maxCount,
38
+ fileList: controlledFileList,
39
+ customRequest,
40
+ accept,
41
+ listType = 'text',
42
+ showUploadList = true,
43
+ children,
44
+ noStyle,
45
+ defaultFileList
46
+ }: UploadProps) => {
47
+ const uploadRef = useRef<HTMLInputElement>(null);
48
+ const [fileList, setFileList] = useState<UploadFile<RuleType>[]>(() =>
49
+ (controlledFileList || defaultFileList || []).map((file, idx) => ({
50
+ ...file,
51
+ uid: file.uid || `${Date.now()}-${idx}`,
52
+ status: file.status || 'done',
53
+ percent: file.percent || IMAGE_PROGRESS_PERCENT
54
+ }))
55
+ );
56
+
57
+ const updateFileList = (newList: UploadFile<RuleType>[]) => {
58
+ setFileList(newList);
59
+
60
+ if (onChange) {
61
+ onChange({
62
+ fileList: newList,
63
+ file: newList[0] || {}
64
+ } as UploadChangeParam);
65
+ }
66
+ };
67
+
68
+ const handleFileChange = async (
69
+ event: React.ChangeEvent<HTMLInputElement>
70
+ ) => {
71
+ const rawFiles: File[] = Array.from(event.target.files || []);
72
+ let uploadFiles: UploadFile<RuleType>[] = rawFiles.map((file, i) => ({
73
+ uid: `${Date.now()}-${i}`,
74
+ name: file.name,
75
+ size: file.size,
76
+ type: file.type,
77
+ status: 'uploading',
78
+ percent: 0,
79
+ originFileObj: file
80
+ }));
81
+
82
+ if (beforeUpload) {
83
+ const filtered: UploadFile<RuleType>[] = [];
84
+
85
+ for (let i = 0; i < uploadFiles.length; i++) {
86
+ const file = uploadFiles[i].originFileObj as RcFile;
87
+ const result = await beforeUpload(file, rawFiles);
88
+
89
+ if (result === false) {
90
+ continue;
91
+ }
92
+
93
+ filtered.push(uploadFiles[i]);
94
+ }
95
+
96
+ uploadFiles = filtered;
97
+ }
98
+
99
+ const newList = (
100
+ multiple ? [...fileList, ...uploadFiles] : uploadFiles
101
+ ).slice(0, maxCount);
102
+
103
+ updateFileList(newList);
104
+
105
+ uploadFiles.forEach(file => {
106
+ const rcFile = file.originFileObj as RcFile;
107
+
108
+ const updateProgress = (percent: number) => {
109
+ file.percent = percent;
110
+ updateFileList([...newList]);
111
+ };
112
+
113
+ const markSuccess = () => {
114
+ file.status = 'done';
115
+ file.percent = 100;
116
+ updateFileList([...newList]);
117
+ };
118
+
119
+ const markError = () => {
120
+ file.status = 'error';
121
+ updateFileList([...newList]);
122
+ };
123
+
124
+ if (customRequest) {
125
+ customRequest({
126
+ file: rcFile,
127
+ onSuccess: markSuccess,
128
+ onError: markError,
129
+ onProgress: event => {
130
+ const percent = Math.round(
131
+ (event.loaded / (event.total || event.loaded)) *
132
+ IMAGE_PROGRESS_PERCENT
133
+ );
134
+
135
+ updateProgress(percent);
136
+ }
137
+ });
138
+ } else if (typeof action === 'string') {
139
+ const formData = new FormData();
140
+ formData.append(name, rcFile);
141
+
142
+ fetch(action, {
143
+ method,
144
+ body: formData,
145
+ headers,
146
+ credentials: withCredentials ? 'include' : 'same-origin'
147
+ })
148
+ .then(res => {
149
+ if (!res.ok) {
150
+ throw new Error('Upload failed');
151
+ }
152
+
153
+ return res.json();
154
+ })
155
+ .then(markSuccess)
156
+ .catch(markError);
157
+ } else if (typeof action === 'function') {
158
+ action(rcFile);
159
+ markSuccess();
160
+ } else {
161
+ markSuccess();
162
+ }
163
+ });
164
+
165
+ if (uploadRef.current) {
166
+ uploadRef.current.value = '';
167
+ }
168
+ };
169
+
170
+ const handleRemove = (uid: string) => {
171
+ const filtered: UploadFile<RuleType>[] = [];
172
+
173
+ let removedFile: UploadFile<RuleType> | undefined = undefined;
174
+
175
+ fileList.forEach(file => {
176
+ if (file.uid !== uid) {
177
+ filtered.push(file);
178
+ } else {
179
+ removedFile = file;
180
+ }
181
+ });
182
+
183
+ updateFileList(filtered);
184
+
185
+ if (removedFile) {
186
+ onRemove?.(removedFile);
187
+ }
188
+ };
189
+
190
+ const handleClick = () => {
191
+ if (!disabled && openFileDialogOnClick && uploadRef.current) {
192
+ uploadRef.current.click();
193
+ }
194
+ };
195
+
196
+ return (
197
+ <div
198
+ className={clsx([
199
+ `${prefixCls}-wrapper ${prefixClsV3}-wrapper`,
200
+ className,
201
+ rootClassName,
202
+ {
203
+ noStyle: noStyle,
204
+ [`${prefixCls}-disabled`]: disabled,
205
+ [`${prefixClsV3}-disabled`]: disabled
206
+ }
207
+ ])}
208
+ style={style}
209
+ >
210
+ <span
211
+ className={clsx([`${prefixCls}`, `${prefixCls}-${listType}`, `${prefixClsV3}`, `${prefixClsV3}-${listType}`])}
212
+ onClick={handleClick}
213
+ >
214
+ {children}
215
+ <input
216
+ type="file"
217
+ ref={uploadRef}
218
+ accept={accept}
219
+ multiple={multiple}
220
+ onChange={handleFileChange}
221
+ className={`${prefixCls}-input ${prefixClsV3}-input`}
222
+ disabled={disabled}
223
+ {...(directory
224
+ ? {
225
+ directory: true,
226
+ webkitdirectory: true
227
+ }
228
+ : {})}
229
+ />
230
+ </span>
231
+
232
+ {showUploadList && fileList.length > 0 && (
233
+ <ul className={`${prefixCls}-list ${prefixCls}-list-${listType} ${prefixClsV3}-list ${prefixClsV3}-list-${listType}`}>
234
+ {fileList.map(file => (
235
+ <li
236
+ key={file.uid}
237
+ className={`${prefixCls}-item ${prefixCls}-item-${file.status} ${prefixClsV3}-item ${prefixClsV3}-item-${file.status}`}
238
+ >
239
+ <span
240
+ className={`${prefixCls}-remove ${prefixClsV3}-remove`}
241
+ onClick={() => handleRemove(file.uid)}
242
+ >
243
+ {listType === 'picture' && (file.originFileObj || file.url) ? (
244
+ // eslint-disable-next-line @next/next/no-img-element
245
+ <img
246
+ width={IMAGE_SIZE}
247
+ height={IMAGE_SIZE}
248
+ alt={file.name}
249
+ src={file.url || URL.createObjectURL(file.originFileObj)}
250
+ className={`${prefixCls}-item-thumbnail ${prefixClsV3}-item-thumbnail`}
251
+ />
252
+ ) : (
253
+ <StampleIcon />
254
+ )}
255
+ </span>
256
+ <div style={{ width: '100%' }}>
257
+ <div
258
+ className={`${prefixCls}-item-title ${prefixClsV3}-item-title`}
259
+ style={{
260
+ ...(file.status === 'uploading' ? { marginBottom: 12 } : {})
261
+ }}
262
+ >
263
+ <span
264
+ className={`${prefixCls}-item-remove-icon ${prefixClsV3}-item-remove-icon`}
265
+ onClick={() => handleRemove(file.uid)}
266
+ style={{ cursor: 'pointer', marginLeft: 'auto' }}
267
+ role="button"
268
+ aria-label="Remove file"
269
+ >
270
+ <TrashIcon />
271
+ </span>
272
+ </div>
273
+ {file.status === 'uploading' && (
274
+ <>
275
+ <div className={`${prefixCls}-item-progress-line ${prefixClsV3}-item-progress-line`} />
276
+ <div
277
+ className={`${prefixCls}-item-progress-line-percent ${prefixClsV3}-item-progress-line-percent`}
278
+ style={{ width: `${file.percent}%` }}
279
+ />
280
+ </>
281
+ )}
282
+ </div>
283
+ </li>
284
+ ))}
285
+ </ul>
286
+ )}
287
+ </div>
288
+ );
289
+ };
290
+
291
+ export default Upload;
@@ -0,0 +1 @@
1
+ export { default as Upload } from '../Upload/Upload'