@ioca/react 1.5.12 → 1.5.14

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 (62) hide show
  1. package/lib/cjs/components/affix/affix.js +38 -29
  2. package/lib/cjs/components/affix/affix.js.map +1 -1
  3. package/lib/cjs/components/affix/totop.js +1 -1
  4. package/lib/cjs/components/affix/totop.js.map +1 -1
  5. package/lib/cjs/components/dropdown/dropdown.js +6 -3
  6. package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
  7. package/lib/cjs/components/dropdown/item.js +20 -4
  8. package/lib/cjs/components/dropdown/item.js.map +1 -1
  9. package/lib/cjs/components/editor/editor.js +27 -11
  10. package/lib/cjs/components/editor/editor.js.map +1 -1
  11. package/lib/cjs/components/loading/loading.js +4 -3
  12. package/lib/cjs/components/loading/loading.js.map +1 -1
  13. package/lib/cjs/components/popup/popup.js +7 -17
  14. package/lib/cjs/components/popup/popup.js.map +1 -1
  15. package/lib/cjs/components/progress/circle.js +3 -3
  16. package/lib/cjs/components/progress/circle.js.map +1 -1
  17. package/lib/cjs/components/scroll/index.js +10 -0
  18. package/lib/cjs/components/scroll/index.js.map +1 -0
  19. package/lib/cjs/components/scroll/scroll.js +78 -0
  20. package/lib/cjs/components/scroll/scroll.js.map +1 -0
  21. package/lib/cjs/components/upload/upload.js +5 -5
  22. package/lib/cjs/components/upload/upload.js.map +1 -1
  23. package/lib/cjs/index.js +2 -0
  24. package/lib/cjs/index.js.map +1 -1
  25. package/lib/css/colors.css +784 -784
  26. package/lib/css/index.css +1 -1
  27. package/lib/css/index.css.map +1 -1
  28. package/lib/es/components/affix/affix.js +39 -30
  29. package/lib/es/components/affix/affix.js.map +1 -1
  30. package/lib/es/components/affix/totop.js +1 -1
  31. package/lib/es/components/affix/totop.js.map +1 -1
  32. package/lib/es/components/dropdown/dropdown.js +7 -5
  33. package/lib/es/components/dropdown/dropdown.js.map +1 -1
  34. package/lib/es/components/dropdown/item.js +20 -4
  35. package/lib/es/components/dropdown/item.js.map +1 -1
  36. package/lib/es/components/editor/editor.js +27 -11
  37. package/lib/es/components/editor/editor.js.map +1 -1
  38. package/lib/es/components/loading/loading.js +4 -3
  39. package/lib/es/components/loading/loading.js.map +1 -1
  40. package/lib/es/components/popup/popup.js +7 -17
  41. package/lib/es/components/popup/popup.js.map +1 -1
  42. package/lib/es/components/progress/circle.js +3 -3
  43. package/lib/es/components/progress/circle.js.map +1 -1
  44. package/lib/es/components/scroll/index.js +6 -0
  45. package/lib/es/components/scroll/index.js.map +1 -0
  46. package/lib/es/components/scroll/scroll.js +70 -0
  47. package/lib/es/components/scroll/scroll.js.map +1 -0
  48. package/lib/es/components/upload/upload.js +7 -7
  49. package/lib/es/components/upload/upload.js.map +1 -1
  50. package/lib/es/index.js +1 -0
  51. package/lib/es/index.js.map +1 -1
  52. package/lib/index.js +174 -78
  53. package/lib/types/components/affix/totop.d.ts +7 -2
  54. package/lib/types/components/affix/type.d.ts +1 -1
  55. package/lib/types/components/dropdown/dropdown.d.ts +1 -1
  56. package/lib/types/components/editor/type.d.ts +1 -1
  57. package/lib/types/components/scroll/index.d.ts +5 -0
  58. package/lib/types/components/scroll/scroll.d.ts +6 -0
  59. package/lib/types/components/scroll/type.d.ts +7 -0
  60. package/lib/types/components/upload/type.d.ts +1 -0
  61. package/lib/types/index.d.ts +1 -0
  62. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { DriveFolderUploadOutlined, PlusSharp } from '@ricons/material';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { DriveFolderUploadOutlined } from '@ricons/material';
3
3
  import classNames from 'classnames';
4
4
  import { uid } from 'radash';
5
5
  import { useState, useMemo, useRef, useCallback } from 'react';
6
- import { SortableItem } from 'react-easy-sort';
7
6
  import { createPortal } from 'react-dom';
7
+ import { SortableItem } from 'react-easy-sort';
8
8
  import usePreview from '../../js/usePreview/index.js';
9
9
  import { arrayMove } from '../../js/utils.js';
10
10
  import Button from '../button/button.js';
@@ -33,7 +33,7 @@ const normalizeFiles = (files) => (files ?? []).map((item) => {
33
33
  };
34
34
  });
35
35
  const Upload = (props) => {
36
- const { label, labelInline, value, files, placeholder, status = "normal", message, className, style, children, droppable, dropbox, getDropboxContainer, defaultButtonProps, mode = "default", cardSize = "3.2em", disabled, sortable, limit = props.multiple ? Infinity : 1, multiple, renderItem, shouldUpload = () => true, uploader, onChange, onFilesChange, onUpload, onRemove, ...restProps } = props;
36
+ const { label, labelInline, value, files, placeholder, status = "normal", message, icon = jsx(Icon, { icon: jsx(DriveFolderUploadOutlined, {}) }), className, style, children, droppable, dropbox, getDropboxContainer, defaultButtonProps, mode = "default", cardSize = "3.2em", disabled, sortable, limit = props.multiple ? Infinity : 1, multiple, renderItem, shouldUpload = () => true, uploader, onChange, onFilesChange, onUpload, onRemove, ...restProps } = props;
37
37
  const [internalFileList, setInternalFileList] = useState([]);
38
38
  const isControlled = useMemo(() => value !== undefined || files !== undefined, [value, files]);
39
39
  const fileList = isControlled
@@ -43,7 +43,7 @@ const Upload = (props) => {
43
43
  const inputRef = useRef(null);
44
44
  const preview = usePreview();
45
45
  const defBtnProps = useMemo(() => ({
46
- children: (jsxs(Fragment, { children: [jsx(Icon, { icon: jsx(DriveFolderUploadOutlined, {}) }), " \u4E0A\u4F20"] })),
46
+ children: jsxs(Fragment, { children: [icon, " \u4E0A\u4F20"] }),
47
47
  ...defaultButtonProps,
48
48
  }), [defaultButtonProps]);
49
49
  const trigger = useMemo(() => {
@@ -51,11 +51,11 @@ const Upload = (props) => {
51
51
  return children;
52
52
  switch (mode) {
53
53
  case "card":
54
- return (jsx(Button, { className: "i-upload-card-btn color-5", square: true, flat: true, outline: true, disabled: disabled, children: jsx(Icon, { icon: jsx(PlusSharp, {}) }) }));
54
+ return (jsx(Button, { className: "i-upload-card-btn color-5", square: true, flat: true, outline: true, disabled: disabled, children: icon }));
55
55
  default:
56
56
  return (jsx(Button, { ...defBtnProps, className: classNames("i-upload-btn", defBtnProps.className), disabled: disabled }));
57
57
  }
58
- }, [mode, children, disabled, defBtnProps]);
58
+ }, [mode, children, disabled, defBtnProps, icon]);
59
59
  const handleUpload = useCallback(async (files) => {
60
60
  if (!uploader)
61
61
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"upload.js","sources":["../../../../packages/components/upload/upload.tsx"],"sourcesContent":["import { DriveFolderUploadOutlined, PlusSharp } from \"@ricons/material\";\nimport classNames from \"classnames\";\nimport { uid } from \"radash\";\nimport {\n ChangeEvent,\n CSSProperties,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { SortableItem } from \"react-easy-sort\";\nimport { createPortal } from \"react-dom\";\nimport usePreview from \"../../js/usePreview\";\nimport { TPreviewItem } from \"../../js/usePreview/type\";\nimport { arrayMove } from \"../../js/utils\";\nimport Button from \"../button\";\nimport Icon from \"../icon\";\nimport InputContainer from \"../input/container\";\nimport Dropbox from \"./dropbox\";\nimport \"./index.css\";\nimport FileListItem, { ListContainer } from \"./renderFile\";\nimport { IFile, IUpload } from \"./type\";\n\nconst normalizeFiles = (files?: IFile[] | File[]) =>\n (files ?? []).map((item) => {\n const file = item as IFile;\n if (item instanceof File) {\n const src = file.src ?? URL.createObjectURL(item);\n Object.assign(item, {\n id: file.id ?? uid(7),\n src,\n url: file.url ?? src,\n });\n return item;\n }\n const src = file.src ?? file.name;\n return {\n ...(file as object),\n id: file.id ?? uid(7),\n src,\n url: file.url ?? src,\n } as IFile;\n });\n\nconst Upload = (props: IUpload) => {\n const {\n label,\n labelInline,\n value,\n files,\n placeholder,\n status = \"normal\",\n message,\n className,\n style,\n children,\n droppable,\n dropbox,\n getDropboxContainer,\n defaultButtonProps,\n mode = \"default\",\n cardSize = \"3.2em\",\n disabled,\n sortable,\n limit = props.multiple ? Infinity : 1,\n multiple,\n renderItem,\n shouldUpload = () => true,\n uploader,\n onChange,\n onFilesChange,\n onUpload,\n onRemove,\n ...restProps\n } = props;\n\n const [internalFileList, setInternalFileList] = useState<IFile[]>([]);\n const isControlled = useMemo(\n () => value !== undefined || files !== undefined,\n [value, files],\n );\n const fileList = isControlled\n ? normalizeFiles(value ?? files ?? [])\n : internalFileList;\n\n const uploadMessage = message;\n const inputRef = useRef<HTMLInputElement>(null);\n const preview = usePreview();\n const defBtnProps = useMemo(\n () => ({\n children: (\n <>\n <Icon icon={<DriveFolderUploadOutlined />} /> 上传\n </>\n ),\n ...defaultButtonProps,\n }),\n [defaultButtonProps],\n );\n\n const trigger = useMemo(() => {\n if (children) return children;\n\n switch (mode) {\n case \"card\":\n return (\n <Button\n className=\"i-upload-card-btn color-5\"\n square\n flat\n outline\n disabled={disabled}\n >\n <Icon icon={<PlusSharp />} />\n </Button>\n );\n default:\n return (\n <Button\n {...defBtnProps}\n className={classNames(\n \"i-upload-btn\",\n defBtnProps.className,\n )}\n disabled={disabled}\n />\n );\n }\n }, [mode, children, disabled, defBtnProps]);\n\n const handleUpload = useCallback(\n async (files: IFile[]) => {\n if (!uploader) return;\n\n const shouldUploadFiles = files.filter(shouldUpload);\n const result = await Promise.all(shouldUploadFiles.map(uploader));\n\n return onUpload?.(result);\n },\n [uploader, shouldUpload, onUpload],\n );\n\n const processFiles = useCallback(\n (inputFiles: IFile[]) => {\n const before = fileList;\n const changed: IFile[] = [];\n\n inputFiles.forEach((file) => {\n const { id, name, size, type } = file;\n const same = before.some(\n (pf) =>\n pf.name === name &&\n pf.size === size &&\n pf.type === type,\n );\n const src = URL.createObjectURL(file);\n\n Object.assign(file, {\n id: id ?? uid(7),\n src: src ?? file.name,\n url: src ?? file.name,\n });\n if (!same) changed.push(file);\n });\n\n const after = [...before, ...changed];\n const last = after.at(-1);\n const nextFiles: IFile[] = multiple\n ? (after.slice(0, limit) as IFile[])\n : last\n ? [last as IFile]\n : [];\n\n return { nextFiles, changed };\n },\n [fileList, multiple, limit],\n );\n\n const applyFiles = useCallback(\n (\n nextFiles: IFile[],\n changed: IFile[],\n e?: ChangeEvent<HTMLInputElement>,\n ) => {\n if (!isControlled) setInternalFileList(nextFiles as IFile[]);\n onFilesChange?.(nextFiles as IFile[], changed as IFile[], e);\n onChange?.(nextFiles, e);\n handleUpload(changed);\n },\n [isControlled, onFilesChange, onChange, handleUpload],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const inputFiles = Array.from(e.target.files || []) as IFile[];\n const { nextFiles, changed } = processFiles(inputFiles);\n\n applyFiles(nextFiles, changed, e);\n if (inputRef.current) inputRef.current.value = \"\";\n },\n [processFiles, applyFiles],\n );\n\n const handleDropFiles = useCallback(\n (files: File[]) => {\n const { nextFiles, changed } = processFiles(files as IFile[]);\n applyFiles(nextFiles, changed);\n },\n [processFiles, applyFiles],\n );\n\n const handleRemove = useCallback(\n (i: number) => {\n const files = [...fileList];\n const changed = files.splice(i, 1);\n URL.revokeObjectURL((changed[0] as IFile)?.src || \"\");\n\n if (!isControlled) setInternalFileList(files as IFile[]);\n onFilesChange?.(files as IFile[], changed as IFile[]);\n onChange?.(files);\n onRemove?.(changed[0] as IFile);\n\n if (inputRef.current) inputRef.current.value = \"\";\n },\n [fileList, isControlled, onFilesChange, onChange, onRemove],\n );\n\n const handlePreview = useCallback(\n (i: number) => {\n preview({\n items: fileList as unknown as TPreviewItem[],\n initial: i,\n });\n },\n [fileList, preview],\n );\n\n const handleSortEnd = useCallback(\n (before: number, after: number) => {\n const files = [...fileList];\n const nextFiles = arrayMove(files, before, after);\n if (!isControlled) setInternalFileList(nextFiles);\n onFilesChange?.(nextFiles, []);\n onChange?.(nextFiles);\n },\n [fileList, isControlled, onFilesChange, onChange],\n );\n\n return (\n <InputContainer\n as=\"div\"\n label={label}\n labelInline={labelInline}\n className={classNames(\"i-input-label-file\", className)}\n style={style}\n >\n <div\n className={classNames(\"i-upload-inner\", {\n [`i-upload-${mode}`]: mode !== \"default\",\n })}\n style={{ [\"--upload-card-size\"]: cardSize } as CSSProperties}\n >\n <ListContainer sortable={sortable} onSortEnd={handleSortEnd}>\n {fileList.map((file, i) => {\n const f = file as IFile;\n const key = f.id ?? i;\n const node = (\n <FileListItem\n key={key}\n index={i}\n file={f}\n mode={mode}\n renderItem={renderItem}\n onRemove={handleRemove}\n onPreview={handlePreview}\n />\n );\n\n if (!sortable) return node;\n\n return <SortableItem key={key}>{node}</SortableItem>;\n })}\n </ListContainer>\n\n {uploadMessage && (\n <span className=\"i-upload-message\">{uploadMessage}</span>\n )}\n\n {fileList.length < limit &&\n (droppable ? (\n (() => {\n const node = (\n <Dropbox\n multiple={multiple}\n accept={restProps.accept}\n disabled={disabled}\n onChange={handleChange}\n onDropFiles={handleDropFiles}\n >\n {dropbox}\n </Dropbox>\n );\n return getDropboxContainer\n ? createPortal(node, getDropboxContainer())\n : node;\n })()\n ) : (\n <label>\n <input\n {...restProps}\n disabled={disabled}\n ref={inputRef}\n type=\"file\"\n className=\"i-input-file-hidden\"\n multiple={multiple}\n onChange={handleChange}\n />\n {trigger}\n </label>\n ))}\n </div>\n </InputContainer>\n );\n};\n\nexport default Upload;\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"upload.js","sources":["../../../../packages/components/upload/upload.tsx"],"sourcesContent":["import { DriveFolderUploadOutlined } from \"@ricons/material\";\nimport classNames from \"classnames\";\nimport { uid } from \"radash\";\nimport {\n ChangeEvent,\n CSSProperties,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { SortableItem } from \"react-easy-sort\";\nimport usePreview from \"../../js/usePreview\";\nimport { TPreviewItem } from \"../../js/usePreview/type\";\nimport { arrayMove } from \"../../js/utils\";\nimport Button from \"../button\";\nimport Icon from \"../icon\";\nimport InputContainer from \"../input/container\";\nimport Dropbox from \"./dropbox\";\nimport \"./index.css\";\nimport FileListItem, { ListContainer } from \"./renderFile\";\nimport { IFile, IUpload } from \"./type\";\n\nconst normalizeFiles = (files?: IFile[] | File[]) =>\n (files ?? []).map((item) => {\n const file = item as IFile;\n if (item instanceof File) {\n const src = file.src ?? URL.createObjectURL(item);\n Object.assign(item, {\n id: file.id ?? uid(7),\n src,\n url: file.url ?? src,\n });\n return item;\n }\n const src = file.src ?? file.name;\n return {\n ...(file as object),\n id: file.id ?? uid(7),\n src,\n url: file.url ?? src,\n } as IFile;\n });\n\nconst Upload = (props: IUpload) => {\n const {\n label,\n labelInline,\n value,\n files,\n placeholder,\n status = \"normal\",\n message,\n icon = <Icon icon={<DriveFolderUploadOutlined />} />,\n className,\n style,\n children,\n droppable,\n dropbox,\n getDropboxContainer,\n defaultButtonProps,\n mode = \"default\",\n cardSize = \"3.2em\",\n disabled,\n sortable,\n limit = props.multiple ? Infinity : 1,\n multiple,\n renderItem,\n shouldUpload = () => true,\n uploader,\n onChange,\n onFilesChange,\n onUpload,\n onRemove,\n ...restProps\n } = props;\n\n const [internalFileList, setInternalFileList] = useState<IFile[]>([]);\n const isControlled = useMemo(\n () => value !== undefined || files !== undefined,\n [value, files],\n );\n const fileList = isControlled\n ? normalizeFiles(value ?? files ?? [])\n : internalFileList;\n\n const uploadMessage = message;\n const inputRef = useRef<HTMLInputElement>(null);\n const preview = usePreview();\n const defBtnProps = useMemo(\n () => ({\n children: <>{icon} 上传</>,\n ...defaultButtonProps,\n }),\n [defaultButtonProps],\n );\n\n const trigger = useMemo(() => {\n if (children) return children;\n\n switch (mode) {\n case \"card\":\n return (\n <Button\n className=\"i-upload-card-btn color-5\"\n square\n flat\n outline\n disabled={disabled}\n >\n {icon}\n </Button>\n );\n default:\n return (\n <Button\n {...defBtnProps}\n className={classNames(\n \"i-upload-btn\",\n defBtnProps.className,\n )}\n disabled={disabled}\n />\n );\n }\n }, [mode, children, disabled, defBtnProps, icon]);\n\n const handleUpload = useCallback(\n async (files: IFile[]) => {\n if (!uploader) return;\n\n const shouldUploadFiles = files.filter(shouldUpload);\n const result = await Promise.all(shouldUploadFiles.map(uploader));\n\n return onUpload?.(result);\n },\n [uploader, shouldUpload, onUpload],\n );\n\n const processFiles = useCallback(\n (inputFiles: IFile[]) => {\n const before = fileList;\n const changed: IFile[] = [];\n\n inputFiles.forEach((file) => {\n const { id, name, size, type } = file;\n const same = before.some(\n (pf) =>\n pf.name === name &&\n pf.size === size &&\n pf.type === type,\n );\n const src = URL.createObjectURL(file);\n\n Object.assign(file, {\n id: id ?? uid(7),\n src: src ?? file.name,\n url: src ?? file.name,\n });\n if (!same) changed.push(file);\n });\n\n const after = [...before, ...changed];\n const last = after.at(-1);\n const nextFiles: IFile[] = multiple\n ? (after.slice(0, limit) as IFile[])\n : last\n ? [last as IFile]\n : [];\n\n return { nextFiles, changed };\n },\n [fileList, multiple, limit],\n );\n\n const applyFiles = useCallback(\n (\n nextFiles: IFile[],\n changed: IFile[],\n e?: ChangeEvent<HTMLInputElement>,\n ) => {\n if (!isControlled) setInternalFileList(nextFiles as IFile[]);\n onFilesChange?.(nextFiles as IFile[], changed as IFile[], e);\n onChange?.(nextFiles, e);\n handleUpload(changed);\n },\n [isControlled, onFilesChange, onChange, handleUpload],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const inputFiles = Array.from(e.target.files || []) as IFile[];\n const { nextFiles, changed } = processFiles(inputFiles);\n\n applyFiles(nextFiles, changed, e);\n if (inputRef.current) inputRef.current.value = \"\";\n },\n [processFiles, applyFiles],\n );\n\n const handleDropFiles = useCallback(\n (files: File[]) => {\n const { nextFiles, changed } = processFiles(files as IFile[]);\n applyFiles(nextFiles, changed);\n },\n [processFiles, applyFiles],\n );\n\n const handleRemove = useCallback(\n (i: number) => {\n const files = [...fileList];\n const changed = files.splice(i, 1);\n URL.revokeObjectURL((changed[0] as IFile)?.src || \"\");\n\n if (!isControlled) setInternalFileList(files as IFile[]);\n onFilesChange?.(files as IFile[], changed as IFile[]);\n onChange?.(files);\n onRemove?.(changed[0] as IFile);\n\n if (inputRef.current) inputRef.current.value = \"\";\n },\n [fileList, isControlled, onFilesChange, onChange, onRemove],\n );\n\n const handlePreview = useCallback(\n (i: number) => {\n preview({\n items: fileList as unknown as TPreviewItem[],\n initial: i,\n });\n },\n [fileList, preview],\n );\n\n const handleSortEnd = useCallback(\n (before: number, after: number) => {\n const files = [...fileList];\n const nextFiles = arrayMove(files, before, after);\n if (!isControlled) setInternalFileList(nextFiles);\n onFilesChange?.(nextFiles, []);\n onChange?.(nextFiles);\n },\n [fileList, isControlled, onFilesChange, onChange],\n );\n\n return (\n <InputContainer\n as=\"div\"\n label={label}\n labelInline={labelInline}\n className={classNames(\"i-input-label-file\", className)}\n style={style}\n >\n <div\n className={classNames(\"i-upload-inner\", {\n [`i-upload-${mode}`]: mode !== \"default\",\n })}\n style={{ [\"--upload-card-size\"]: cardSize } as CSSProperties}\n >\n <ListContainer sortable={sortable} onSortEnd={handleSortEnd}>\n {fileList.map((file, i) => {\n const f = file as IFile;\n const key = f.id ?? i;\n const node = (\n <FileListItem\n key={key}\n index={i}\n file={f}\n mode={mode}\n renderItem={renderItem}\n onRemove={handleRemove}\n onPreview={handlePreview}\n />\n );\n\n if (!sortable) return node;\n\n return <SortableItem key={key}>{node}</SortableItem>;\n })}\n </ListContainer>\n\n {uploadMessage && (\n <span className=\"i-upload-message\">{uploadMessage}</span>\n )}\n\n {fileList.length < limit &&\n (droppable ? (\n (() => {\n const node = (\n <Dropbox\n multiple={multiple}\n accept={restProps.accept}\n disabled={disabled}\n onChange={handleChange}\n onDropFiles={handleDropFiles}\n >\n {dropbox}\n </Dropbox>\n );\n return getDropboxContainer\n ? createPortal(node, getDropboxContainer())\n : node;\n })()\n ) : (\n <label>\n <input\n {...restProps}\n disabled={disabled}\n ref={inputRef}\n type=\"file\"\n className=\"i-input-file-hidden\"\n multiple={multiple}\n onChange={handleChange}\n />\n {trigger}\n </label>\n ))}\n </div>\n </InputContainer>\n );\n};\n\nexport default Upload;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
package/lib/es/index.js CHANGED
@@ -28,6 +28,7 @@ export { default as Progress } from './components/progress/progress.js';
28
28
  export { default as Radio } from './components/radio/radio.js';
29
29
  export { default as Resizable } from './components/resizable/resizable.js';
30
30
  export { default as River } from './components/river/river.js';
31
+ export { default as Scroll } from './components/scroll/scroll.js';
31
32
  export { default as Select } from './components/select/select.js';
32
33
  export { default as Step } from './components/step/step.js';
33
34
  export { default as Swiper } from './components/swiper/swiper.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/lib/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import classNames from 'classnames';
3
3
  import { debounce, uid, throttle } from 'radash';
4
- import { useState, useRef, useEffect, useCallback, useMemo, Children, cloneElement, createElement, isValidElement, memo, Fragment as Fragment$1, useTransition, forwardRef, useLayoutEffect, createContext, useContext, useImperativeHandle } from 'react';
5
- import { SkipPreviousRound, CloseRound, MinusRound, PlusRound, InboxTwotone, UndoRound, RedoRound, FormatBoldRound, FormatItalicRound, FormatUnderlinedRound, StrikethroughSRound, ClearAllRound, PlayArrowRound, PauseRound, StopRound, VolumeDownRound, VolumeOffRound, FullscreenRound, FullscreenExitRound, FeedOutlined, AspectRatioRound, OpenInNewRound, FileDownloadOutlined, RotateRightRound, RotateLeftRound, KeyboardArrowLeftRound, KeyboardArrowRightRound, KeyboardDoubleArrowUpRound, SyncAltRound, VisibilityRound, VisibilityOffRound, MoreHorizRound, SearchRound, CheckRound, UnfoldMoreRound, CalendarMonthTwotone, AccessTimeRound, InfoOutlined, KeyboardArrowDownRound, MoveToInboxTwotone, OutboxTwotone, FilePresentOutlined, DriveFolderUploadOutlined, PlusSharp } from '@ricons/material';
4
+ import { useState, useRef, useEffect, useCallback, useMemo, Children, cloneElement, createElement, isValidElement, memo, Fragment as Fragment$1, useTransition, forwardRef, useLayoutEffect, useContext, createContext, useImperativeHandle } from 'react';
5
+ import { SkipPreviousRound, CloseRound, MinusRound, PlusRound, InboxTwotone, UndoRound, RedoRound, FormatBoldRound, FormatItalicRound, FormatUnderlinedRound, StrikethroughSRound, ClearAllRound, PlayArrowRound, PauseRound, StopRound, VolumeDownRound, VolumeOffRound, FullscreenRound, FullscreenExitRound, FeedOutlined, AspectRatioRound, OpenInNewRound, FileDownloadOutlined, RotateRightRound, RotateLeftRound, KeyboardArrowLeftRound, KeyboardArrowRightRound, KeyboardDoubleArrowUpRound, SyncAltRound, VisibilityRound, VisibilityOffRound, MoreHorizRound, SearchRound, CheckRound, UnfoldMoreRound, CalendarMonthTwotone, AccessTimeRound, InfoOutlined, KeyboardArrowDownRound, MoveToInboxTwotone, OutboxTwotone, FilePresentOutlined, DriveFolderUploadOutlined } from '@ricons/material';
6
6
  import { createRoot } from 'react-dom/client';
7
7
  import { getScrollbarSize, List as List$2 } from 'react-window';
8
8
  import { createPortal } from 'react-dom';
@@ -62,14 +62,15 @@ function createRipple() {
62
62
 
63
63
  const Loading = (props) => {
64
64
  const { icon, text, size, absolute, style, className, ...restProps } = props;
65
+ const iconSize = size != null
66
+ ? { fontSize: typeof size === "number" ? `${size}px` : size }
67
+ : undefined;
65
68
  return (jsxs("div", { className: classNames("i-loading-container", {
66
69
  absolute,
67
70
  }, className), style: {
68
71
  ...style,
69
72
  inset: absolute ? 0 : "unset",
70
- }, ...restProps, children: [icon ?? (jsx("svg", { width: '24', height: '24', stroke: '#000', viewBox: '0 0 24 24', xmlns: 'http://www.w3.org/2000/svg', className: 'i-loading-icon', style: {
71
- fontSize: size,
72
- }, children: jsx("circle", { cx: '12', cy: '12', r: '9.5', fill: 'none', strokeWidth: '3', strokeLinecap: 'round', strokeDasharray: 40, strokeDashoffset: 0 }) })), text] }));
73
+ }, ...restProps, children: [icon ?? jsx("span", { className: "i-loading-icon", style: iconSize }), text] }));
73
74
  };
74
75
 
75
76
  const os = window.navigator.platform;
@@ -494,53 +495,62 @@ const Icon = (props) => {
494
495
 
495
496
  function ToTop(props) {
496
497
  const { style, className, onClick } = props;
497
- return (jsx(Button, { square: true, className: classNames("i-affix-totop", className), style: { ...style }, onClick: onClick, children: jsx(Icon, { icon: jsx(SkipPreviousRound, {}), rotate: 90 }) }));
498
+ return (jsx(Button, { square: true, className: classNames("i-affix-totop", "i-affix-target", className), style: { ...style }, onClick: onClick, children: jsx(Icon, { icon: jsx(SkipPreviousRound, {}), rotate: 90 }) }));
498
499
  }
499
500
 
501
+ const defaultGetContainer = () => {
502
+ if (typeof window === "undefined")
503
+ return null;
504
+ return window;
505
+ };
500
506
  const Affix = (props) => {
501
- const { position = "fixed", left, top, right, bottom, offset, style, className, children, getContainer = () => {
502
- if (typeof document === "undefined")
503
- return null;
504
- return document.body;
505
- }, } = props;
506
- const [hidden, setHidden] = useState(false);
507
+ const { position = "fixed", left, top, right, bottom, offset, style, className, children, getContainer = defaultGetContainer, } = props;
508
+ const [hidden, setHidden] = useState(() => {
509
+ if (!offset)
510
+ return false;
511
+ if (typeof window === "undefined")
512
+ return false;
513
+ return (window.scrollY ?? 0) < offset;
514
+ });
515
+ const getContainerRef = useRef(getContainer);
516
+ getContainerRef.current = getContainer;
507
517
  const hijackChildren = useMemo(() => {
508
518
  return Children.map(children, (node) => {
509
- if (node.type === ToTop) {
510
- const { onClick } = node.props;
511
- return cloneElement(node, {
512
- key: node.key,
513
- ...node.props,
514
- onClick: (e) => {
515
- const container = getContainer();
516
- onClick?.(e);
517
- container?.scrollTo({
518
- top: 0,
519
- left: 0,
520
- behavior: "smooth",
521
- });
522
- },
523
- });
524
- }
525
- return node;
519
+ if (node.type !== ToTop)
520
+ return node;
521
+ const { onClick } = node.props;
522
+ return cloneElement(node, {
523
+ onClick: (e) => {
524
+ const container = getContainerRef.current();
525
+ onClick?.(e);
526
+ container?.scrollTo({
527
+ top: 0,
528
+ left: 0,
529
+ behavior: "smooth",
530
+ });
531
+ },
532
+ });
526
533
  });
527
- }, [children, getContainer]);
534
+ }, [children]);
528
535
  useEffect(() => {
529
- const container = getContainer();
536
+ const container = getContainerRef.current();
530
537
  if (!offset || !container)
531
538
  return;
539
+ const getScrollTop = () => container instanceof Window
540
+ ? container.scrollY
541
+ : container.scrollTop;
532
542
  const listener = debounce({ delay: 160 }, () => {
533
- const top = container.scrollTop;
534
- setHidden(top < offset);
543
+ setHidden(getScrollTop() < offset);
535
544
  });
536
545
  listener();
537
546
  container.addEventListener("scroll", listener);
538
547
  return () => {
548
+ listener.cancel();
539
549
  container.removeEventListener("scroll", listener);
540
550
  };
541
- }, [offset, getContainer]);
551
+ }, [offset]);
542
552
  return (jsx("div", { className: classNames("i-affix", className, {
543
- "i-affix-hidden": hidden,
553
+ "i-affix-visible": !hidden,
544
554
  }), style: {
545
555
  ...style,
546
556
  position,
@@ -1830,19 +1840,7 @@ function Popup(props) {
1830
1840
  const [show, setShow] = useState(false);
1831
1841
  const showRef = useRef(false);
1832
1842
  showRef.current = show;
1833
- const latestRef = useRef({
1834
- disabled,
1835
- trigger,
1836
- touchable,
1837
- showDelay,
1838
- hideDelay,
1839
- position,
1840
- gap,
1841
- offset,
1842
- align,
1843
- fitSize,
1844
- onVisibleChange,
1845
- });
1843
+ const latestRef = useRef({});
1846
1844
  latestRef.current = {
1847
1845
  disabled,
1848
1846
  trigger,
@@ -1896,9 +1894,8 @@ function Popup(props) {
1896
1894
  };
1897
1895
  const applyFitSize = () => {
1898
1896
  const o = latestRef.current;
1899
- const triggerEl = triggerRef.current;
1900
1897
  const contentEl = contentRef.current;
1901
- if (!triggerEl || !contentEl)
1898
+ if (!contentEl)
1902
1899
  return;
1903
1900
  const vertical = ["top", "bottom"].includes(o.position);
1904
1901
  const key = vertical ? "width" : "height";
@@ -1906,6 +1903,9 @@ function Popup(props) {
1906
1903
  contentEl.style[key] = "";
1907
1904
  return;
1908
1905
  }
1906
+ const triggerEl = triggerRef.current;
1907
+ if (!triggerEl)
1908
+ return;
1909
1909
  const size = triggerEl[vertical ? "offsetWidth" : "offsetHeight"];
1910
1910
  contentEl.style[key] =
1911
1911
  typeof size === "number" ? `${size}px` : "";
@@ -2142,8 +2142,8 @@ function Popup(props) {
2142
2142
  e.stopPropagation();
2143
2143
  setTriggerEl(e);
2144
2144
  pointRef.current = {
2145
- pageX: e.pageX,
2146
- pageY: e.pageY,
2145
+ pageX: e.clientX,
2146
+ pageY: e.clientY,
2147
2147
  };
2148
2148
  if (showRef.current) {
2149
2149
  ensureBaseStyle();
@@ -2300,22 +2300,38 @@ function Popup(props) {
2300
2300
 
2301
2301
  const { Item: ListItem } = List$1;
2302
2302
  const Item$3 = (props) => {
2303
- const { more, moreProps, onClick, ...restProps } = props;
2304
- const Li = (jsx(ListItem, { onClick: (e) => {
2303
+ const { more, moreProps, onClick, ref: itemRef, children, ...restProps } = props;
2304
+ const close = useContext(DropdownCloseCtx);
2305
+ const liRef = useRef(null);
2306
+ const [position, setPosition] = useState("right");
2307
+ const { position: morePosition, onVisibleChange: moreOnVisibleChange, width: moreWidth, ...restMoreProps } = moreProps ?? {};
2308
+ const effectivePosition = morePosition ?? position;
2309
+ const handleVisibleChange = (v) => {
2310
+ if (v && liRef.current) {
2311
+ const rect = liRef.current.getBoundingClientRect();
2312
+ setPosition(rect.left > window.innerWidth / 2 ? "left" : "right");
2313
+ }
2314
+ moreOnVisibleChange?.(v);
2315
+ };
2316
+ const Li = (jsx(ListItem, { ref: itemRef ?? liRef, onClick: (e) => {
2305
2317
  e.stopPropagation();
2318
+ if (!more)
2319
+ close?.();
2306
2320
  onClick?.(e);
2307
- }, ...restProps }));
2321
+ }, ...restProps, children: children }));
2308
2322
  if (!more)
2309
2323
  return Li;
2310
- return (jsx(Popup, { position: 'right', touchable: true, arrow: false, align: 'start', offset: 10, hideDelay: 240, ...moreProps, content: jsx(List$1, { className: 'i-dropdown-content', onClick: (e) => e.stopPropagation(), children: more }), children: Li }));
2324
+ return (jsx(Popup, { ...restMoreProps, position: effectivePosition, touchable: true, arrow: false, align: "start", offset: 11, hideDelay: 240, onVisibleChange: handleVisibleChange, content: jsx(List$1, { className: "i-dropdown-content", style: { minWidth: moreWidth }, onClick: (e) => e.stopPropagation(), children: more }), children: Li }));
2311
2325
  };
2312
2326
 
2327
+ const DropdownCloseCtx = createContext(null);
2313
2328
  const Dropdown = (props) => {
2314
2329
  const { visible, width, content, children, ...restProps } = props;
2315
2330
  const [active, setActive] = useState(visible);
2316
2331
  if (!content) {
2317
2332
  return children;
2318
2333
  }
2334
+ const close = () => setActive(false);
2319
2335
  const handleVisibleChange = (v) => {
2320
2336
  setActive(v);
2321
2337
  if (props.onVisibleChange) {
@@ -2325,9 +2341,9 @@ const Dropdown = (props) => {
2325
2341
  useEffect(() => {
2326
2342
  setActive(visible);
2327
2343
  }, [visible]);
2328
- return (jsx(Popup, { trigger: 'click', position: 'bottom', content: jsx(List$1, { className: 'i-dropdown-content', style: { minWidth: width }, children: typeof content === "function"
2329
- ? content(() => setActive(false))
2330
- : content }), ...restProps, touchable: true, visible: active, onVisibleChange: handleVisibleChange, children: children }));
2344
+ return (jsx(Popup, { trigger: 'click', position: 'bottom', content: jsx(DropdownCloseCtx.Provider, { value: close, children: jsx(List$1, { className: 'i-dropdown-content', style: { minWidth: width }, children: typeof content === "function"
2345
+ ? content(close)
2346
+ : content }) }), ...restProps, touchable: true, visible: active, onVisibleChange: handleVisibleChange, children: children }));
2331
2347
  };
2332
2348
  Dropdown.Item = Item$3;
2333
2349
 
@@ -2681,7 +2697,13 @@ const Editor = (props) => {
2681
2697
  const [memtionRect, setMemtionRect] = useState(null);
2682
2698
  const [memtionKeyword, setMemtionKeyword] = useState("");
2683
2699
  const [memtionActiveIndex, setMemtionActiveIndex] = useState(0);
2684
- const memtionOptions = useMemo(() => filterMemtionOptions(memtion?.options ?? [], memtionKeyword), [memtion?.options, memtionKeyword]);
2700
+ const [activeMemtionIndex, setActiveMemtionIndex] = useState(-1);
2701
+ const memtionOptions = useMemo(() => {
2702
+ if (activeMemtionIndex < 0 || !memtion?.length)
2703
+ return [];
2704
+ const active = memtion?.[activeMemtionIndex];
2705
+ return filterMemtionOptions(active?.options ?? [], memtionKeyword);
2706
+ }, [memtion, memtionKeyword, activeMemtionIndex]);
2685
2707
  const sanitizeValue = (nextValue) => {
2686
2708
  if (isPlaintextMode) {
2687
2709
  return nextValue === "\n" ? "" : nextValue;
@@ -2736,18 +2758,20 @@ const Editor = (props) => {
2736
2758
  setMemtionRect(null);
2737
2759
  setMemtionKeyword("");
2738
2760
  setMemtionActiveIndex(0);
2761
+ setActiveMemtionIndex(-1);
2739
2762
  };
2740
2763
  const syncEditorState = () => {
2741
2764
  selectionRef.current = null;
2742
2765
  hideMemtion();
2743
2766
  };
2744
2767
  const insertMemtion = (option) => {
2768
+ const activeMemtion = memtion?.[activeMemtionIndex];
2745
2769
  const replaceRange = getMemtionReplaceRange(memtionTriggerRangeRef.current, selectionRef.current);
2746
2770
  const range = insertMemtionOption({
2747
2771
  editor: editorRef.current,
2748
2772
  range: replaceRange,
2749
2773
  mode,
2750
- memtion,
2774
+ memtion: activeMemtion,
2751
2775
  option,
2752
2776
  sanitizeValue,
2753
2777
  });
@@ -2783,7 +2807,6 @@ const Editor = (props) => {
2783
2807
  editorRef.current?.dispatchEvent(new Event("input", { bubbles: true }));
2784
2808
  return;
2785
2809
  }
2786
- const memtionKey = memtion?.key ?? "@";
2787
2810
  if (memtionVisible && e.key === " ") {
2788
2811
  hideMemtion();
2789
2812
  }
@@ -2803,11 +2826,15 @@ const Editor = (props) => {
2803
2826
  return;
2804
2827
  }
2805
2828
  }
2806
- if (memtion && e.key === memtionKey) {
2807
- rememberSelection();
2808
- memtionTriggerRangeRef.current =
2809
- selectionRef.current?.cloneRange() ?? null;
2810
- pendingMemtionRef.current = true;
2829
+ if (memtion?.length) {
2830
+ const matchedIndex = memtion.findIndex((m) => e.key === m.key);
2831
+ if (matchedIndex >= 0) {
2832
+ rememberSelection();
2833
+ memtionTriggerRangeRef.current =
2834
+ selectionRef.current?.cloneRange() ?? null;
2835
+ pendingMemtionRef.current = true;
2836
+ setActiveMemtionIndex(matchedIndex);
2837
+ }
2811
2838
  }
2812
2839
  switch (e.key) {
2813
2840
  case "Tab":
@@ -2855,8 +2882,13 @@ const Editor = (props) => {
2855
2882
  setEditorValue(nextValue);
2856
2883
  }
2857
2884
  rememberSelection();
2858
- if (memtion && (pendingMemtionRef.current || memtionVisible)) {
2859
- const memtionKey = memtion?.key ?? "@";
2885
+ if (activeMemtionIndex >= 0 && (pendingMemtionRef.current || memtionVisible)) {
2886
+ const active = memtion?.[activeMemtionIndex];
2887
+ if (!active) {
2888
+ hideMemtion();
2889
+ return;
2890
+ }
2891
+ const memtionKey = active.key ?? "@";
2860
2892
  const memtionText = getMemtionText(memtionTriggerRangeRef.current, selectionRef.current);
2861
2893
  if (!memtionText.startsWith(memtionKey) || /\s/.test(memtionText)) {
2862
2894
  hideMemtion();
@@ -2911,7 +2943,7 @@ const Editor = (props) => {
2911
2943
  ...style,
2912
2944
  [autosize ? "minHeight" : "height"]: height,
2913
2945
  width,
2914
- }, children: [!hideControl && (jsx("div", { className: "i-editor-controls", children: controls })), memtion && (jsx(Memtion$1, { visible: memtionVisible, rect: memtionRect, options: memtionOptions, activeIndex: memtionActiveIndex, onActiveChange: setMemtionActiveIndex, onSelect: insertMemtion })), jsx("div", { ref: handleRef, className: "i-editor-content", "data-placeholder": placeholder, contentEditable: isPlaintextMode ? "plaintext-only" : true, onFocus: handleFocus, onBlur: handleBlur, onMouseUp: handleMouseUp, onPaste: handlePaste, onInput: handleInput, onKeyUp: handleKeyUp, onKeyDown: handleKeyDown, ...restProps })] }));
2946
+ }, children: [!hideControl && (jsx("div", { className: "i-editor-controls", children: controls })), memtion?.length && (jsx(Memtion$1, { visible: memtionVisible, rect: memtionRect, options: memtionOptions, activeIndex: memtionActiveIndex, onActiveChange: setMemtionActiveIndex, onSelect: insertMemtion })), jsx("div", { ref: handleRef, className: "i-editor-content", "data-placeholder": placeholder, contentEditable: isPlaintextMode ? "plaintext-only" : true, onFocus: handleFocus, onBlur: handleBlur, onMouseUp: handleMouseUp, onPaste: handlePaste, onInput: handleInput, onKeyUp: handleKeyUp, onKeyDown: handleKeyDown, ...restProps })] }));
2915
2947
  };
2916
2948
 
2917
2949
  const Flex = (props) => {
@@ -3438,9 +3470,9 @@ Text.HighLight = HighLight;
3438
3470
 
3439
3471
  function Circle(props) {
3440
3472
  const { value, circleSize = 40, lineWidth = 8 } = props;
3441
- return (jsxs("div", { className: 'i-progress-circle', children: [jsxs("svg", { width: circleSize, height: circleSize, children: [jsx("circle", { cx: circleSize / 2, cy: circleSize / 2, r: circleSize / 2 - lineWidth / 2, fill: 'none', stroke: 'var(--background-opacity-2)', strokeWidth: lineWidth }), jsx("circle", { cx: circleSize / 2, cy: circleSize / 2, r: circleSize / 2 - lineWidth / 2, fill: 'none', stroke: 'var(--color-main)', strokeWidth: lineWidth, strokeDasharray: 100, pathLength: 100, className: 'i-progress-circle-path', strokeLinecap: 'round', style: {
3442
- strokeDashoffset: `calc(100 - ${value})`,
3443
- } })] }), jsxs("span", { className: 'i-progress-circle-value', children: [jsx("span", { children: value }), jsx(Text, { size: '.81em', className: 'color-7', children: "%" })] })] }));
3473
+ return (jsxs("div", { className: "i-progress-circle", children: [jsxs("svg", { width: circleSize, height: circleSize, children: [jsx("circle", { cx: circleSize / 2, cy: circleSize / 2, r: circleSize / 2 - lineWidth / 2, fill: "none", stroke: "var(--color-main-0)", strokeWidth: lineWidth }), jsx("circle", { cx: circleSize / 2, cy: circleSize / 2, r: circleSize / 2 - lineWidth / 2, fill: "none", stroke: "var(--color-main)", strokeWidth: lineWidth, strokeDasharray: 100, pathLength: 100, className: "i-progress-circle-path", strokeLinecap: "round", style: {
3474
+ strokeDashoffset: 100 - (value ?? 0),
3475
+ } })] }), jsxs("span", { className: "i-progress-circle-value", children: [jsx("span", { children: value }), jsx(Text, { size: ".81em", className: "color-5", children: "%" })] })] }));
3444
3476
  }
3445
3477
 
3446
3478
  const Line = (props) => {
@@ -5222,6 +5254,70 @@ const River = (props) => {
5222
5254
  })] }) }));
5223
5255
  };
5224
5256
 
5257
+ const Scroll = (props) => {
5258
+ const { style, className, draggable, onScroll, children, ...restProps } = props;
5259
+ const scrollRef = useRef(null);
5260
+ const [dragging, setDragging] = useState(false);
5261
+ const dragState = useRef({ down: false, startX: 0, scrollLeft: 0 });
5262
+ useEffect(() => {
5263
+ const el = scrollRef.current;
5264
+ if (!el)
5265
+ return;
5266
+ const onWheel = (e) => {
5267
+ const canScroll = el.scrollWidth > el.clientWidth + 1;
5268
+ if (!canScroll)
5269
+ return;
5270
+ e.preventDefault();
5271
+ e.stopPropagation();
5272
+ const delta = Math.abs(e.deltaX) > Math.abs(e.deltaY)
5273
+ ? e.deltaX
5274
+ : e.deltaY;
5275
+ el.scrollLeft += delta;
5276
+ };
5277
+ const opts = {
5278
+ passive: false,
5279
+ capture: true,
5280
+ };
5281
+ el.addEventListener("wheel", onWheel, opts);
5282
+ return () => el.removeEventListener("wheel", onWheel, opts);
5283
+ }, []);
5284
+ useEffect(() => {
5285
+ if (!draggable)
5286
+ return;
5287
+ const handleMouseMove = (e) => {
5288
+ if (!dragState.current.down || !scrollRef.current)
5289
+ return;
5290
+ const x = e.clientX - dragState.current.startX;
5291
+ scrollRef.current.scrollLeft =
5292
+ dragState.current.scrollLeft - x;
5293
+ };
5294
+ const handleMouseUp = () => {
5295
+ dragState.current.down = false;
5296
+ setDragging(false);
5297
+ };
5298
+ document.addEventListener("mousemove", handleMouseMove);
5299
+ document.addEventListener("mouseup", handleMouseUp);
5300
+ return () => {
5301
+ document.removeEventListener("mousemove", handleMouseMove);
5302
+ document.removeEventListener("mouseup", handleMouseUp);
5303
+ };
5304
+ }, [draggable]);
5305
+ const handleMouseDown = (e) => {
5306
+ if (!draggable || !scrollRef.current)
5307
+ return;
5308
+ setDragging(true);
5309
+ dragState.current = {
5310
+ down: true,
5311
+ startX: e.clientX,
5312
+ scrollLeft: scrollRef.current.scrollLeft,
5313
+ };
5314
+ };
5315
+ return (jsx("div", { ref: scrollRef, className: classNames("i-scroll", className, {
5316
+ "i-scroll-draggable": draggable,
5317
+ "i-scroll-dragging": dragging,
5318
+ }), style: style, onScroll: onScroll, onMouseDown: handleMouseDown, ...restProps, children: children }));
5319
+ };
5320
+
5225
5321
  function Divider() {
5226
5322
  return jsx("i", { className: 'i-step-divider' });
5227
5323
  }
@@ -6142,7 +6238,7 @@ const normalizeFiles = (files) => (files ?? []).map((item) => {
6142
6238
  };
6143
6239
  });
6144
6240
  const Upload = (props) => {
6145
- const { label, labelInline, value, files, placeholder, status = "normal", message, className, style, children, droppable, dropbox, getDropboxContainer, defaultButtonProps, mode = "default", cardSize = "3.2em", disabled, sortable, limit = props.multiple ? Infinity : 1, multiple, renderItem, shouldUpload = () => true, uploader, onChange, onFilesChange, onUpload, onRemove, ...restProps } = props;
6241
+ const { label, labelInline, value, files, placeholder, status = "normal", message, icon = jsx(Icon, { icon: jsx(DriveFolderUploadOutlined, {}) }), className, style, children, droppable, dropbox, getDropboxContainer, defaultButtonProps, mode = "default", cardSize = "3.2em", disabled, sortable, limit = props.multiple ? Infinity : 1, multiple, renderItem, shouldUpload = () => true, uploader, onChange, onFilesChange, onUpload, onRemove, ...restProps } = props;
6146
6242
  const [internalFileList, setInternalFileList] = useState([]);
6147
6243
  const isControlled = useMemo(() => value !== undefined || files !== undefined, [value, files]);
6148
6244
  const fileList = isControlled
@@ -6152,7 +6248,7 @@ const Upload = (props) => {
6152
6248
  const inputRef = useRef(null);
6153
6249
  const preview = usePreview();
6154
6250
  const defBtnProps = useMemo(() => ({
6155
- children: (jsxs(Fragment, { children: [jsx(Icon, { icon: jsx(DriveFolderUploadOutlined, {}) }), " \u4E0A\u4F20"] })),
6251
+ children: jsxs(Fragment, { children: [icon, " \u4E0A\u4F20"] }),
6156
6252
  ...defaultButtonProps,
6157
6253
  }), [defaultButtonProps]);
6158
6254
  const trigger = useMemo(() => {
@@ -6160,11 +6256,11 @@ const Upload = (props) => {
6160
6256
  return children;
6161
6257
  switch (mode) {
6162
6258
  case "card":
6163
- return (jsx(Button, { className: "i-upload-card-btn color-5", square: true, flat: true, outline: true, disabled: disabled, children: jsx(Icon, { icon: jsx(PlusSharp, {}) }) }));
6259
+ return (jsx(Button, { className: "i-upload-card-btn color-5", square: true, flat: true, outline: true, disabled: disabled, children: icon }));
6164
6260
  default:
6165
6261
  return (jsx(Button, { ...defBtnProps, className: classNames("i-upload-btn", defBtnProps.className), disabled: disabled }));
6166
6262
  }
6167
- }, [mode, children, disabled, defBtnProps]);
6263
+ }, [mode, children, disabled, defBtnProps, icon]);
6168
6264
  const handleUpload = useCallback(async (files) => {
6169
6265
  if (!uploader)
6170
6266
  return;
@@ -6407,4 +6503,4 @@ const useTheme = (props) => {
6407
6503
  };
6408
6504
  };
6409
6505
 
6410
- export { Affix, Badge, Button, Card, Checkbox, Collapse, ColorPicker, Datagrid, Datepicker as DatePicker, Description, Drawer, Dropdown, Editor, Flex, Form, Icon, MemoImage as Image, Input, List$1 as List, Loading, message as Message, Modal, Pagination, Popconfirm, Popup, Progress, Radio, Resizable, River, Select, Step, Swiper, Tabs, Tag, Text, TimePicker, Tree, Upload, Video, usePreview, useTheme };
6506
+ export { Affix, Badge, Button, Card, Checkbox, Collapse, ColorPicker, Datagrid, Datepicker as DatePicker, Description, Drawer, Dropdown, Editor, Flex, Form, Icon, MemoImage as Image, Input, List$1 as List, Loading, message as Message, Modal, Pagination, Popconfirm, Popup, Progress, Radio, Resizable, River, Scroll, Select, Step, Swiper, Tabs, Tag, Text, TimePicker, Tree, Upload, Video, usePreview, useTheme };
@@ -1,6 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { IAffix } from './type.js';
2
+ import { CSSProperties, MouseEventHandler } from 'react';
3
3
 
4
- declare function ToTop(props: IAffix): react_jsx_runtime.JSX.Element;
4
+ interface IToTopProps {
5
+ style?: CSSProperties;
6
+ className?: string;
7
+ onClick?: MouseEventHandler<HTMLElement>;
8
+ }
9
+ declare function ToTop(props: IToTopProps): react_jsx_runtime.JSX.Element;
5
10
 
6
11
  export { ToTop as default };
@@ -7,7 +7,7 @@ interface IAffix extends HTMLAttributes<HTMLElement> {
7
7
  right?: string | number;
8
8
  bottom?: string | number;
9
9
  offset?: number;
10
- getContainer?: () => HTMLElement | null;
10
+ getContainer?: () => HTMLElement | Window | null;
11
11
  }
12
12
 
13
13
  export type { IAffix };
@@ -1,6 +1,6 @@
1
1
  import { IDropdown, IDropItem } from './type.js';
2
- import * as react from 'react';
3
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import * as react from 'react';
4
4
 
5
5
  declare const Dropdown: {
6
6
  (props: IDropdown): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode>>;
@@ -23,7 +23,7 @@ interface IEditor extends Omit<HTMLAttributes<HTMLDivElement>, "onInput" | "onCh
23
23
  mode?: "rich" | "plaintext" | "plaintextOnMemtion";
24
24
  hideControl?: boolean;
25
25
  addtionControls?: IEditorAddtionControl[];
26
- memtion?: IEditorMemtion;
26
+ memtion?: IEditorMemtion[];
27
27
  border?: boolean;
28
28
  onChange?: (value: string, e: SyntheticEvent<HTMLDivElement>) => void;
29
29
  onEnter?: (e: KeyboardEvent<HTMLDivElement>) => void;