@wzyjs/uis 0.3.29 → 0.3.31

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 (222) hide show
  1. package/dist/advanced/Com2Canvas/index.d.ts +8 -0
  2. package/dist/advanced/Com2Canvas/index.js +39 -0
  3. package/dist/advanced/Crud/components/CardList/index.d.ts +2 -0
  4. package/dist/advanced/Crud/components/CardList/index.js +90 -0
  5. package/dist/advanced/Crud/components/CreateUpdate/index.d.ts +2 -0
  6. package/dist/advanced/Crud/components/CreateUpdate/index.js +78 -0
  7. package/dist/advanced/Crud/components/ListTabs/index.d.ts +8 -0
  8. package/dist/advanced/Crud/components/ListTabs/index.js +7 -0
  9. package/dist/advanced/Crud/components/Provider/index.d.ts +7 -0
  10. package/dist/advanced/Crud/components/Provider/index.js +42 -0
  11. package/dist/advanced/Crud/components/QuickFilters/index.d.ts +8 -0
  12. package/dist/advanced/Crud/components/QuickFilters/index.js +20 -0
  13. package/dist/advanced/Crud/components/Remove/index.d.ts +2 -0
  14. package/dist/advanced/Crud/components/Remove/index.js +18 -0
  15. package/dist/advanced/Crud/components/index.d.ts +6 -0
  16. package/dist/advanced/Crud/components/index.js +6 -0
  17. package/dist/advanced/Crud/hooks/index.d.ts +5 -0
  18. package/dist/advanced/Crud/hooks/index.js +5 -0
  19. package/dist/advanced/Crud/hooks/useColumns.d.ts +11 -0
  20. package/dist/advanced/Crud/hooks/useColumns.js +111 -0
  21. package/dist/advanced/Crud/hooks/useList.d.ts +12 -0
  22. package/dist/advanced/Crud/hooks/useList.js +53 -0
  23. package/dist/advanced/Crud/hooks/useListFilters.d.ts +11 -0
  24. package/dist/advanced/Crud/hooks/useListFilters.js +159 -0
  25. package/dist/advanced/Crud/hooks/useOrderable.d.ts +15 -0
  26. package/dist/advanced/Crud/hooks/useOrderable.js +75 -0
  27. package/dist/advanced/Crud/hooks/useRequest.d.ts +13 -0
  28. package/dist/advanced/Crud/hooks/useRequest.js +27 -0
  29. package/dist/advanced/Crud/index.d.ts +3 -0
  30. package/dist/advanced/Crud/index.js +46 -0
  31. package/dist/advanced/Crud/types/index.d.ts +176 -0
  32. package/dist/advanced/Crud/types/index.js +1 -0
  33. package/dist/advanced/Crud/utils/index.d.ts +7 -0
  34. package/dist/advanced/Crud/utils/index.js +80 -0
  35. package/dist/advanced/Crud/utils/query.d.ts +3 -0
  36. package/dist/advanced/Crud/utils/query.js +34 -0
  37. package/dist/advanced/MindMap/context.d.ts +12 -0
  38. package/dist/advanced/MindMap/context.js +12 -0
  39. package/dist/advanced/MindMap/hooks/useAlignmentSnap.d.ts +15 -0
  40. package/dist/advanced/MindMap/hooks/useAlignmentSnap.js +164 -0
  41. package/dist/advanced/MindMap/hooks/useCopyPaste.d.ts +11 -0
  42. package/dist/advanced/MindMap/hooks/useCopyPaste.js +209 -0
  43. package/dist/advanced/MindMap/hooks/useDropToReparent.d.ts +21 -0
  44. package/dist/advanced/MindMap/hooks/useDropToReparent.js +216 -0
  45. package/dist/advanced/MindMap/hooks/useExpandCollapse.d.ts +18 -0
  46. package/dist/advanced/MindMap/hooks/useExpandCollapse.js +108 -0
  47. package/dist/advanced/MindMap/hooks/useMoveDescendants.d.ts +12 -0
  48. package/dist/advanced/MindMap/hooks/useMoveDescendants.js +98 -0
  49. package/dist/advanced/MindMap/hooks/useUndoRedo.d.ts +14 -0
  50. package/dist/advanced/MindMap/hooks/useUndoRedo.js +181 -0
  51. package/dist/advanced/MindMap/index.d.ts +29 -0
  52. package/dist/advanced/MindMap/index.js +52 -0
  53. package/dist/advanced/index.d.ts +5 -0
  54. package/dist/advanced/index.js +5 -0
  55. package/dist/antd/index.d.ts +6 -0
  56. package/dist/antd/index.js +5 -0
  57. package/dist/buttons/ButtonGroup/index.d.ts +8 -0
  58. package/dist/buttons/ButtonGroup/index.js +13 -0
  59. package/dist/buttons/ConfirmButton/index.d.ts +5 -0
  60. package/dist/buttons/ConfirmButton/index.js +9 -0
  61. package/dist/buttons/CopyButton/index.d.ts +6 -0
  62. package/dist/buttons/CopyButton/index.js +26 -0
  63. package/dist/buttons/DrawerButton/index.d.ts +6 -0
  64. package/dist/buttons/DrawerButton/index.js +13 -0
  65. package/dist/buttons/ProgressButton/index.css +63 -0
  66. package/dist/buttons/ProgressButton/index.d.ts +17 -0
  67. package/dist/buttons/ProgressButton/index.js +31 -0
  68. package/dist/buttons/SectorButton/index.d.ts +20 -0
  69. package/dist/buttons/SectorButton/index.js +130 -0
  70. package/dist/buttons/index.d.ts +6 -0
  71. package/dist/buttons/index.js +6 -0
  72. package/dist/display/CodeView/index.d.ts +26 -0
  73. package/dist/display/CodeView/index.js +60 -0
  74. package/dist/display/EnumTag/index.d.ts +12 -0
  75. package/dist/display/EnumTag/index.js +10 -0
  76. package/dist/display/HtmlDataRenderer/index.d.ts +6 -0
  77. package/dist/display/HtmlDataRenderer/index.js +15 -0
  78. package/dist/display/HtmlView/index.d.ts +6 -0
  79. package/dist/display/HtmlView/index.js +6 -0
  80. package/dist/display/IframePro/index.d.ts +8 -0
  81. package/dist/display/IframePro/index.js +24 -0
  82. package/dist/display/JsonSchemaRenderer/index.d.ts +11 -0
  83. package/dist/display/JsonSchemaRenderer/index.js +62 -0
  84. package/dist/display/JsonView/index.d.ts +3 -0
  85. package/dist/display/JsonView/index.js +7 -0
  86. package/dist/display/MarkdownView/index.d.ts +7 -0
  87. package/dist/display/MarkdownView/index.js +80 -0
  88. package/dist/display/MarkdownView/style.d.ts +1 -0
  89. package/{src/components/Markdown/style.ts → dist/display/MarkdownView/style.js} +1 -1
  90. package/dist/display/VideoPro/index.d.ts +9 -0
  91. package/dist/display/VideoPro/index.js +15 -0
  92. package/dist/display/index.d.ts +9 -0
  93. package/dist/display/index.js +9 -0
  94. package/dist/inputs/CheckboxButton/index.css +22 -0
  95. package/dist/inputs/CheckboxButton/index.d.ts +12 -0
  96. package/dist/inputs/CheckboxButton/index.js +9 -0
  97. package/dist/inputs/DateSwitcher/index.css +10 -0
  98. package/dist/inputs/DateSwitcher/index.d.ts +8 -0
  99. package/dist/inputs/DateSwitcher/index.js +29 -0
  100. package/dist/inputs/FetchSelect/index.d.ts +3 -0
  101. package/dist/inputs/FetchSelect/index.js +121 -0
  102. package/dist/inputs/FetchSelect/types.d.ts +33 -0
  103. package/dist/inputs/FetchSelect/types.js +1 -0
  104. package/dist/inputs/FetchSelect/utils.d.ts +21 -0
  105. package/dist/inputs/FetchSelect/utils.js +67 -0
  106. package/dist/inputs/FileUploader/index.d.ts +22 -0
  107. package/dist/inputs/FileUploader/index.js +79 -0
  108. package/dist/inputs/IconSelect/index.d.ts +89 -0
  109. package/dist/inputs/IconSelect/index.js +54 -0
  110. package/dist/inputs/ImageUploader/index.d.ts +12 -0
  111. package/dist/inputs/ImageUploader/index.js +192 -0
  112. package/dist/inputs/RadioButton/index.d.ts +15 -0
  113. package/dist/inputs/RadioButton/index.js +11 -0
  114. package/dist/inputs/RangeInput/index.d.ts +8 -0
  115. package/dist/inputs/RangeInput/index.js +17 -0
  116. package/dist/inputs/TextInput/index.d.ts +6 -0
  117. package/dist/inputs/TextInput/index.js +30 -0
  118. package/dist/inputs/index.d.ts +9 -0
  119. package/dist/inputs/index.js +9 -0
  120. package/dist/layout/DragSort/index.d.ts +16 -0
  121. package/dist/layout/DragSort/index.js +12 -0
  122. package/dist/layout/FoldCard/index.d.ts +9 -0
  123. package/dist/layout/FoldCard/index.js +69 -0
  124. package/dist/layout/PageBase/index.d.ts +6 -0
  125. package/dist/layout/PageBase/index.js +6 -0
  126. package/dist/layout/ResizableGridLayout/index.d.ts +11 -0
  127. package/dist/layout/ResizableGridLayout/index.js +13 -0
  128. package/dist/layout/SideMenu/index.d.ts +27 -0
  129. package/dist/layout/SideMenu/index.js +40 -0
  130. package/dist/layout/TabsPro/index.d.ts +9 -0
  131. package/dist/layout/TabsPro/index.js +87 -0
  132. package/dist/layout/index.d.ts +6 -0
  133. package/dist/layout/index.js +6 -0
  134. package/dist/web.css +363 -0
  135. package/dist/web.d.ts +7 -0
  136. package/dist/web.js +7 -0
  137. package/package.json +34 -12
  138. package/src/antd/form/CheckboxButton/index.module.scss +0 -24
  139. package/src/antd/form/CheckboxButton/index.tsx +0 -31
  140. package/src/antd/form/FileUploader/index.tsx +0 -163
  141. package/src/antd/form/RadioButton/index.tsx +0 -32
  142. package/src/antd/form/Upload/index.tsx +0 -65
  143. package/src/antd/form/UploadImage/index.tsx +0 -338
  144. package/src/antd/form/index.ts +0 -6
  145. package/src/antd/index.ts +0 -46
  146. package/src/antd/pro/FoldCard/index.tsx +0 -131
  147. package/src/antd/pro/RangeInput/index.tsx +0 -46
  148. package/src/antd/pro/Tabs/index.tsx +0 -135
  149. package/src/antd/pro/Typography/components/String.tsx +0 -72
  150. package/src/antd/pro/Typography/index.tsx +0 -9
  151. package/src/antd/pro/buttons/ButtonGroup.tsx +0 -26
  152. package/src/antd/pro/buttons/ConfirmButton.tsx +0 -24
  153. package/src/antd/pro/buttons/CopyButton.tsx +0 -47
  154. package/src/antd/pro/buttons/DrawerButton.tsx +0 -37
  155. package/src/antd/pro/buttons/index.tsx +0 -4
  156. package/src/antd/pro/index.ts +0 -5
  157. package/src/components/BottomBar/index.tsx +0 -28
  158. package/src/components/CodeView/index.tsx +0 -85
  159. package/src/components/Collapse/index.tsx +0 -26
  160. package/src/components/Com2Canvas/index.tsx +0 -60
  161. package/src/components/CompileHtml/index.tsx +0 -26
  162. package/src/components/Crud/components/CardList/index.tsx +0 -174
  163. package/src/components/Crud/components/CreateUpdate/index.tsx +0 -179
  164. package/src/components/Crud/components/Provider/index.tsx +0 -83
  165. package/src/components/Crud/components/Remove/index.tsx +0 -56
  166. package/src/components/Crud/components/index.ts +0 -4
  167. package/src/components/Crud/hooks/index.ts +0 -4
  168. package/src/components/Crud/hooks/useColumns.tsx +0 -169
  169. package/src/components/Crud/hooks/useList.ts +0 -65
  170. package/src/components/Crud/hooks/useOrderable.tsx +0 -107
  171. package/src/components/Crud/hooks/useRequest.ts +0 -41
  172. package/src/components/Crud/index.tsx +0 -91
  173. package/src/components/Crud/types/index.ts +0 -188
  174. package/src/components/Crud/utils/index.ts +0 -87
  175. package/src/components/DateSwitcher/index.module.scss +0 -10
  176. package/src/components/DateSwitcher/index.tsx +0 -75
  177. package/src/components/DownloadLink/index.tsx +0 -36
  178. package/src/components/DragSort/index.tsx +0 -77
  179. package/src/components/DynamicSelect/index.tsx +0 -76
  180. package/src/components/DynamicSelect/types.ts +0 -8
  181. package/src/components/DynamicSelect/utils.ts +0 -47
  182. package/src/components/EnumTag/index.tsx +0 -24
  183. package/src/components/FetchSelect/index.tsx +0 -57
  184. package/src/components/FormPro/index.tsx +0 -28
  185. package/src/components/GroupLayout/index.tsx +0 -45
  186. package/src/components/HtmlPro/index.tsx +0 -18
  187. package/src/components/IframePro/index.tsx +0 -52
  188. package/src/components/JsonRenderer/index.tsx +0 -114
  189. package/src/components/JsonView/index.tsx +0 -21
  190. package/src/components/Markdown/index.tsx +0 -152
  191. package/src/components/MindMap/context.tsx +0 -29
  192. package/src/components/MindMap/hooks/useAlignmentSnap.ts +0 -220
  193. package/src/components/MindMap/hooks/useCopyPaste.ts +0 -272
  194. package/src/components/MindMap/hooks/useDropToReparent.ts +0 -288
  195. package/src/components/MindMap/hooks/useExpandCollapse.ts +0 -146
  196. package/src/components/MindMap/hooks/useMoveDescendants.ts +0 -136
  197. package/src/components/MindMap/hooks/useUndoRedo.ts +0 -232
  198. package/src/components/MindMap/index.tsx +0 -117
  199. package/src/components/MultiImageDisplay/index.tsx +0 -63
  200. package/src/components/ProgressButton/index.module.scss +0 -65
  201. package/src/components/ProgressButton/index.tsx +0 -96
  202. package/src/components/SectorButton/index.tsx +0 -247
  203. package/src/components/TextInput/index.tsx +0 -61
  204. package/src/components/TimelineBar/components/CurrentWeekHighlight/index.tsx +0 -64
  205. package/src/components/TimelineBar/components/Guides/index.tsx +0 -61
  206. package/src/components/TimelineBar/components/Ticks/index.tsx +0 -56
  207. package/src/components/TimelineBar/components/TodayIndicator/index.tsx +0 -54
  208. package/src/components/TimelineBar/components/index.ts +0 -4
  209. package/src/components/TimelineBar/const.ts +0 -3
  210. package/src/components/TimelineBar/hooks/index.ts +0 -5
  211. package/src/components/TimelineBar/hooks/useHighlightRange.ts +0 -21
  212. package/src/components/TimelineBar/hooks/useMonthGuides.ts +0 -40
  213. package/src/components/TimelineBar/hooks/useTickValues.ts +0 -18
  214. package/src/components/TimelineBar/hooks/useVisibleRange.ts +0 -43
  215. package/src/components/TimelineBar/hooks/useWeekGuides.ts +0 -39
  216. package/src/components/TimelineBar/index.tsx +0 -63
  217. package/src/components/TimelineBar/utils.ts +0 -27
  218. package/src/components/Video/index.tsx +0 -37
  219. package/src/components/index.ts +0 -26
  220. package/src/rn.ts +0 -1
  221. package/src/rns/index.ts +0 -0
  222. package/src/web.ts +0 -2
@@ -1,163 +0,0 @@
1
- 'use client'
2
-
3
- import { useState, type ReactElement } from 'react'
4
-
5
- import { Upload, Button, } from 'antd'
6
- import { UploadOutlined, InboxOutlined } from '@ant-design/icons'
7
-
8
- import type { UploadProps, UploadFile as AntUploadFile } from 'antd'
9
-
10
- export interface FileUploaderProps {
11
- value?: AntUploadFile[]
12
- onChange?: (fileList: AntUploadFile[]) => void
13
-
14
- // 模式
15
- mode?: 'file' | 'http' // http 暂未实现
16
-
17
- // 限制
18
- accept?: string
19
- multiple?: boolean
20
- maxCount?: number
21
-
22
- // 展示
23
- trigger?: 'button' | 'dragger' | ReactElement
24
- listType?: UploadProps['listType']
25
-
26
- // 校验
27
- beforeUpload?: (file: AntUploadFile) => boolean | Promise<void>
28
-
29
- // 上传行为
30
- immediateUpload?: boolean
31
- action?: string
32
- data?: Record<string, unknown> | ((file: AntUploadFile) => Record<string, unknown>)
33
- headers?: UploadProps['headers']
34
- withCredentials?: boolean
35
-
36
- disabled?: boolean
37
- showUploadList?: boolean
38
- onUploadChange?: UploadProps['onChange']
39
- }
40
-
41
- export const FileUploader = (props: FileUploaderProps) => {
42
- const {
43
- value,
44
- onChange,
45
- mode = 'file',
46
- accept,
47
- multiple = true,
48
- maxCount,
49
- trigger = 'dragger',
50
- listType = 'text',
51
- beforeUpload,
52
- immediateUpload = false,
53
- action = '/api/file/upload',
54
- data,
55
- headers,
56
- withCredentials,
57
- disabled,
58
- showUploadList = trigger === 'dragger',
59
- onUploadChange,
60
- } = props
61
-
62
- const [internalFileList, setInternalFileList] = useState<AntUploadFile[]>([])
63
-
64
- const fileList = value || internalFileList
65
-
66
- const handleChange: UploadProps['onChange'] = (info) => {
67
- let newFileList = [...info.fileList]
68
-
69
- // 限制数量
70
- if (maxCount && newFileList.length > maxCount) {
71
- newFileList = newFileList.slice(-maxCount)
72
- }
73
-
74
- // 如果不是立即上传模式,我们需要手动管理状态
75
- if (!immediateUpload) {
76
- // 这里的逻辑主要依赖 beforeUpload 返回 false 来阻止上传
77
- // 但 onChange 依然会被触发
78
- }
79
-
80
- // 更新状态
81
- if (!value) {
82
- setInternalFileList(newFileList)
83
- }
84
-
85
- // 通知外部
86
- onChange?.(newFileList)
87
- onUploadChange?.(info)
88
- }
89
-
90
- const handleBeforeUpload = async (file: AntUploadFile) => {
91
- // 1. 外部校验
92
- if (beforeUpload) {
93
- const result = await beforeUpload(file)
94
- if (result === false) {
95
- return Upload.LIST_IGNORE
96
- }
97
- }
98
-
99
- // 2. 立即上传模式
100
- if (immediateUpload) {
101
- return true
102
- }
103
-
104
- // 3. 非立即上传模式,阻止默认上传行为,但添加到列表
105
- return false
106
- }
107
-
108
- const uploadProps: UploadProps = {
109
- fileList,
110
- accept,
111
- multiple,
112
- maxCount,
113
- listType,
114
- disabled,
115
- showUploadList,
116
- beforeUpload: handleBeforeUpload as UploadProps['beforeUpload'],
117
- onChange: handleChange,
118
- onDrop: (e: unknown) => {
119
- // console.log('Dropped files', e.dataTransfer.files)
120
- },
121
- }
122
-
123
- // 立即上传相关配置
124
- if (immediateUpload) {
125
- uploadProps.action = action
126
- uploadProps.data = data
127
- uploadProps.headers = headers
128
- uploadProps.withCredentials = withCredentials
129
- } else {
130
- // 非立即上传模式,不需要 action
131
- uploadProps.customRequest = () => undefined // 覆盖默认上传行为,防止自动上传尝试
132
- }
133
-
134
- if (mode === 'http') {
135
- return <div>HTTP 输入模式暂未支持</div>
136
- }
137
-
138
- if (trigger === 'button') {
139
- return (
140
- <Upload {...uploadProps}>
141
- <Button type="primary" icon={<UploadOutlined />}>
142
- 上传文件
143
- </Button>
144
- </Upload>
145
- )
146
- }
147
-
148
- if (trigger === 'dragger') {
149
- return (
150
- <Upload.Dragger {...uploadProps}>
151
- <p className="ant-upload-drag-icon">
152
- <InboxOutlined />
153
- </p>
154
- <p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
155
- <p className="ant-upload-hint">
156
- 支持单个或批量上传{maxCount ? `,最多 ${maxCount} 个文件` : ''}
157
- </p>
158
- </Upload.Dragger>
159
- )
160
- }
161
-
162
- return trigger
163
- }
@@ -1,32 +0,0 @@
1
- 'use client'
2
-
3
- import { CSSProperties } from 'react'
4
- import { Radio } from 'antd'
5
-
6
- interface FilterButtonProps<V> {
7
- options: { label: string; value: V }[]
8
- value?: V
9
- buttonStyle?: 'outline' | 'solid'
10
- onChange?: (value: V) => void
11
- style?: CSSProperties
12
- disabled?: boolean
13
- }
14
-
15
- export const RadioButton = <V = string | number | boolean | null>(props: FilterButtonProps<V>) => {
16
- const { value, options, buttonStyle = 'outline', disabled, style, onChange } = props
17
-
18
- return (
19
- <Radio.Group
20
- optionType='button'
21
- buttonStyle={buttonStyle}
22
- value={value}
23
- style={style}
24
- disabled={disabled}
25
- onChange={e => onChange?.(e.target.value as V)}
26
- >
27
- {options.filter(item => item.label).map(item => (
28
- <Radio key={String(item.value)} value={item.value}>{item.label}</Radio>
29
- ))}
30
- </Radio.Group>
31
- )
32
- }
@@ -1,65 +0,0 @@
1
- 'use client'
2
-
3
- import { Upload } from 'antd'
4
- import { InboxOutlined } from '@ant-design/icons'
5
- import { generateUniqueFileName } from '@wzyjs/utils/web'
6
-
7
- interface item {
8
- name: string
9
- url: string
10
- status: string
11
- }
12
-
13
- interface UploadFormItemProps {
14
- oss: any
15
- multiple?: boolean,
16
- mode?: 'image' | 'video'
17
- value?: item[]
18
- onChange?: (value: item[]) => void
19
- }
20
-
21
- export const UploadFormItem = (props: UploadFormItemProps) => {
22
- const { oss, mode = 'image', multiple = true, onChange } = props
23
-
24
- const accept = mode === 'image' ? '.jpg,.png,.jpeg' : '.mp4,.mov'
25
-
26
- const onUpload = async (info: any) => {
27
- onChange?.(info.fileList.map((item: any) => ({
28
- name: item?.response.name,
29
- url: item?.response.url,
30
- })))
31
- }
32
-
33
- const customRequest = async ({ file, onSuccess }: any) => {
34
- const newName = generateUniqueFileName(file.name)
35
- const result = await oss.put(newName, file, {
36
- headers: {
37
- 'Cache-Control': 'public, max-age=31536000, immutable', // 设置缓存时间为365天
38
- },
39
- })
40
- onSuccess(result)
41
- }
42
-
43
- return (
44
- <Upload.Dragger
45
- multiple={multiple}
46
- accept={accept}
47
- listType='picture-card'
48
- onChange={onUpload}
49
- customRequest={customRequest}
50
- >
51
- <p className='ant-upload-drag-icon'>
52
- <InboxOutlined />
53
- </p>
54
- <p className='ant-upload-text'>
55
- <span>点击或拖拽文件到这里以上传</span>
56
- </p>
57
- {mode === 'image' && (
58
- <p className='ant-upload-hint'>支持上传多张 JPG 或者 PNG 格式的照片</p>
59
- )}
60
- {mode === 'video' && (
61
- <p className='ant-upload-hint'>支持上传多个 MP4 或者 MOV 格式的视频</p>
62
- )}
63
- </Upload.Dragger>
64
- )
65
- }
@@ -1,338 +0,0 @@
1
- 'use client'
2
-
3
- import React, { useEffect, useRef, useState } from 'react'
4
- import { Alert, Button, Modal, Popover, Space, Typography } from 'antd'
5
- import { DeleteOutlined, PlusOutlined } from '@ant-design/icons'
6
-
7
- interface UploadImageProps {
8
- value?: string[];
9
- onChange?: (value: string[]) => void;
10
- maxImages?: number;
11
- enablePreview?: boolean;
12
- enableDragDrop?: boolean;
13
- enableFileSelect?: boolean;
14
- enablePaste?: boolean;
15
- enablePasteTip?: boolean;
16
- }
17
-
18
- export const UploadImage = (props: UploadImageProps) => {
19
- const {
20
- value = [],
21
- onChange,
22
- maxImages = 10,
23
- enablePreview = false,
24
- enableDragDrop = false,
25
- enableFileSelect = false,
26
- enablePaste = true,
27
- enablePasteTip = false,
28
- } = props
29
-
30
- const [isDragging, setIsDragging] = useState(false)
31
- const fileInputRef = useRef<HTMLInputElement>(null)
32
-
33
- useEffect(() => {
34
- if (!enablePaste) return
35
-
36
- const handlePaste = (event: ClipboardEvent) => {
37
- if (event.clipboardData && event.clipboardData.items) {
38
- const items = event.clipboardData.items
39
- for (let i = 0; i < items.length; i++) {
40
- const item = items[i]
41
- if (item && item.type.indexOf('image') !== -1) {
42
- const file = item.getAsFile()
43
- if (file) {
44
- convertToBase64(file)
45
- }
46
- }
47
- }
48
- }
49
- }
50
-
51
- document.addEventListener('paste', handlePaste)
52
- return () => {
53
- document.removeEventListener('paste', handlePaste)
54
- }
55
- }, [value, enablePaste])
56
-
57
- const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
58
- if (!enableDragDrop) return
59
- e.preventDefault()
60
- e.stopPropagation()
61
- setIsDragging(true)
62
- }
63
-
64
- const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {
65
- if (!enableDragDrop) return
66
- e.preventDefault()
67
- e.stopPropagation()
68
- setIsDragging(false)
69
- }
70
-
71
- const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
72
- if (!enableDragDrop) return
73
- e.preventDefault()
74
- e.stopPropagation()
75
- setIsDragging(false)
76
-
77
- if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
78
- const fileList = Array.from(e.dataTransfer.files)
79
- fileList.forEach((file) => {
80
- if (file.type.match('image.*')) {
81
- convertToBase64(file)
82
- }
83
- })
84
- }
85
- }
86
-
87
- const handleClick = () => {
88
- if (!enableFileSelect) return
89
- fileInputRef.current?.click()
90
- }
91
-
92
- const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
93
- if (!enableFileSelect) return
94
- if (e.target.files && e.target.files.length > 0) {
95
- const fileList = Array.from(e.target.files)
96
- fileList.forEach((file) => {
97
- if (file.type.match('image.*')) {
98
- convertToBase64(file)
99
- }
100
- })
101
- }
102
- }
103
-
104
- const handlePasteButton = () => {
105
- if (!enablePaste) return
106
- navigator.clipboard.read().then((clipboardItems) => {
107
- for (const clipboardItem of clipboardItems) {
108
- for (const type of clipboardItem.types) {
109
- if (type.startsWith('image/')) {
110
- clipboardItem.getType(type).then((blob) => {
111
- convertToBase64(blob)
112
- })
113
- }
114
- }
115
- }
116
- }).catch(error => {
117
- console.error('读取剪贴板失败:', error)
118
- alert('读取剪贴板失败。请尝试使用 Ctrl+V 粘贴或手动上传图片。')
119
- })
120
- }
121
-
122
- const convertToBase64 = (file: File | Blob) => {
123
- if (value.length >= maxImages) {
124
- alert(`最多允许上传 ${maxImages} 张图片。`)
125
- return
126
- }
127
-
128
- compressImage(file).then(compressedFile => {
129
- const reader = new FileReader()
130
- reader.onloadend = () => {
131
- const base64String = reader.result as string
132
- if (!value.includes(base64String)) {
133
- onChange?.([...value, base64String])
134
- }
135
- }
136
- reader.readAsDataURL(compressedFile)
137
- })
138
- }
139
-
140
- const compressImage = (file: File | Blob): Promise<Blob> => {
141
- return new Promise((resolve) => {
142
- const originalSize = file.size / 1024
143
-
144
- const img = new Image()
145
- img.src = URL.createObjectURL(file)
146
-
147
- img.onload = () => {
148
- URL.revokeObjectURL(img.src)
149
-
150
- const canvas = document.createElement('canvas')
151
- let width = img.width
152
- let height = img.height
153
-
154
- // 计算压缩比例,保持宽高比
155
- const maxWidth = 1200
156
- const maxHeight = 1200
157
-
158
- if (width > maxWidth || height > maxHeight) {
159
- const ratio = Math.min(maxWidth / width, maxHeight / height)
160
- width = width * ratio
161
- height = height * ratio
162
- }
163
-
164
- canvas.width = width
165
- canvas.height = height
166
-
167
- const ctx = canvas.getContext('2d')
168
- if (!ctx) {
169
- resolve(file as Blob)
170
- return
171
- }
172
- ctx.drawImage(img, 0, 0, width, height)
173
-
174
- // 转换为blob,压缩质量为0.8
175
- canvas.toBlob(
176
- (blob) => {
177
- if (!blob) {
178
- resolve(file as Blob)
179
- return
180
- }
181
- // 获取压缩后的图片大小
182
- const compressedSize = blob.size / 1024
183
- console.log(`原始图片: ${originalSize.toFixed(2)} KB => ${compressedSize.toFixed(2)} KB`)
184
- console.log(`压缩到了: ${((compressedSize / originalSize) * 100).toFixed(2)}%`)
185
- resolve(blob)
186
- },
187
- 'image/jpeg',
188
- 0.8,
189
- )
190
- }
191
- })
192
- }
193
-
194
- const handleRemoveImage = (index: number) => {
195
- Modal.confirm({
196
- title: '确认删除',
197
- content: '您确定要删除这张图片吗?',
198
- okText: '确定',
199
- cancelText: '取消',
200
- onOk: () => {
201
- const newImages = [...value]
202
- newImages.splice(index, 1)
203
- onChange?.(newImages)
204
- },
205
- })
206
- }
207
-
208
- return (
209
- <div className='w-full space-y-4'>
210
- <div className='flex flex-wrap gap-3'>
211
- {value.map((image, index) => {
212
- const imageNode = (
213
- <div
214
- className='rounded border overflow-hidden relative group bg-white'
215
- style={{ maxWidth: 200 }}
216
- >
217
- <img
218
- src={image}
219
- alt={`图片 ${index + 1}`}
220
- className='object-contain'
221
- style={{ maxWidth: '100%', height: 'auto', display: 'block' }}
222
- />
223
- <Button
224
- type='text'
225
- icon={<DeleteOutlined />}
226
- onClick={(e) => {
227
- e.stopPropagation()
228
- handleRemoveImage(index)
229
- }}
230
- style={{ position: 'absolute', top: 0, right: 0 }}
231
- className='absolute top-0 right-0 bg-black/40 text-white border-none hover:bg-black/60'
232
- size='small'
233
- />
234
- </div>
235
- )
236
-
237
- if (!enablePreview) {
238
- return (
239
- <div key={index} className='relative'>
240
- {imageNode}
241
- </div>
242
- )
243
- }
244
-
245
- return (
246
- <div key={index} className='relative'>
247
- <Popover
248
- trigger='hover'
249
- placement='top'
250
- content={(
251
- <img
252
- src={image}
253
- alt={`预览图片 ${index + 1}`}
254
- style={{
255
- maxWidth: '400px',
256
- height: 'auto',
257
- objectFit: 'contain',
258
- }}
259
- />
260
- )}
261
- >
262
- {imageNode}
263
- </Popover>
264
- </div>
265
- )
266
- })}
267
-
268
- {value.length < maxImages && (
269
- <Space style={{ width: '100%' }}>
270
- {enableFileSelect && (
271
- <div
272
- className={`border-2 border-dashed rounded flex flex-col items-center justify-center cursor-pointer transition-colors ${
273
- isDragging && enableDragDrop ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-blue-500'
274
- }`}
275
- onDragOver={enableDragDrop ? handleDragOver : undefined}
276
- onDragLeave={enableDragDrop ? handleDragLeave : undefined}
277
- onDrop={enableDragDrop ? handleDrop : undefined}
278
- onClick={handleClick}
279
- style={{ width: '50px', height: '50px' }}
280
- >
281
- <PlusOutlined style={{ fontSize: '24px', color: '#8c8c8c' }} />
282
- <Typography.Text type='secondary' className='m-2'>上传</Typography.Text>
283
- </div>
284
- )}
285
-
286
- {enablePaste && (
287
- <div
288
- style={{ width: '50px', height: '50px' }}
289
- className={`border-2 border-dashed rounded flex flex-col items-center justify-center cursor-pointer transition-colors ${
290
- isDragging ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-blue-500'
291
- }`}
292
- onClick={handlePasteButton}
293
- >
294
- <PlusOutlined style={{ fontSize: '24px', color: '#8c8c8c' }} />
295
- <Typography.Text type='secondary' className='m-2'>粘贴</Typography.Text>
296
- </div>
297
- )}
298
- </Space>
299
- )}
300
- </div>
301
-
302
- {enableFileSelect && (
303
- <input
304
- type='file'
305
- ref={fileInputRef}
306
- onChange={handleFileChange}
307
- accept='image/*'
308
- multiple
309
- style={{ display: 'none' }}
310
- />
311
- )}
312
-
313
- {(enablePasteTip && enablePaste) && (
314
- <Alert
315
- type='info'
316
- showIcon
317
- message={
318
- <Typography.Text type='secondary'>
319
- 提示:您也可以在任意位置按下 <kbd style={{
320
- padding: '0.1rem 0.4rem',
321
- background: '#f5f5f5',
322
- border: '1px solid #d9d9d9',
323
- borderRadius: '3px',
324
- fontSize: '12px',
325
- }}>Ctrl</kbd> + <kbd style={{
326
- padding: '0.1rem 0.4rem',
327
- background: '#f5f5f5',
328
- border: '1px solid #d9d9d9',
329
- borderRadius: '3px',
330
- fontSize: '12px',
331
- }}>V</kbd> 从剪贴板粘贴图片
332
- </Typography.Text>
333
- }
334
- />
335
- )}
336
- </div>
337
- )
338
- }
@@ -1,6 +0,0 @@
1
- export * from './Upload'
2
- export * from './UploadImage'
3
- export * from './FileUploader'
4
-
5
- export * from './CheckboxButton'
6
- export * from './RadioButton'
package/src/antd/index.ts DELETED
@@ -1,46 +0,0 @@
1
- export * from 'antd'
2
-
3
- export * from '@ant-design/icons'
4
-
5
- export { default as zh_CN } from 'antd/locale/zh_CN'
6
-
7
- export { AntdRegistry } from '@ant-design/nextjs-registry'
8
-
9
- export {
10
- PageLoading,
11
- PageHeader,
12
-
13
- ProCard,
14
- ProList,
15
- ProTable,
16
- ProDescriptions,
17
-
18
- ProForm,
19
- ProFormList,
20
- ProFormText,
21
- ProFormCaptcha,
22
- ProFormCheckbox,
23
- ProFormSelect,
24
- ProFormUploadButton,
25
- LoginForm,
26
- BetaSchemaForm,
27
- StepsForm,
28
-
29
- CheckCard,
30
- EditableProTable,
31
- DragSortTable,
32
-
33
- ProProvider,
34
- } from '@ant-design/pro-components'
35
-
36
- export type {
37
- ProTableProps,
38
- ProFormProps,
39
- ProColumns,
40
- ProLayoutProps,
41
- ProFormInstance,
42
- ActionType,
43
- } from '@ant-design/pro-components'
44
-
45
- export * from './pro'
46
- export * from './form'