@ioca/react 1.5.10 → 1.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/editor/editor.js +5 -0
- package/lib/cjs/components/editor/editor.js.map +1 -1
- package/lib/cjs/components/editor/memtion.js +45 -3
- package/lib/cjs/components/editor/memtion.js.map +1 -1
- package/lib/cjs/components/list/list.js +3 -3
- package/lib/cjs/components/list/list.js.map +1 -1
- package/lib/cjs/components/picker/colors/index.js +7 -3
- package/lib/cjs/components/picker/colors/index.js.map +1 -1
- package/lib/cjs/components/tabs/navs.js.map +1 -1
- package/lib/cjs/components/tabs/tabs.js.map +1 -1
- package/lib/cjs/components/upload/dropbox.js +54 -0
- package/lib/cjs/components/upload/dropbox.js.map +1 -0
- package/lib/cjs/components/upload/renderFile.js +33 -36
- package/lib/cjs/components/upload/renderFile.js.map +1 -1
- package/lib/cjs/components/upload/upload.js +106 -69
- package/lib/cjs/components/upload/upload.js.map +1 -1
- package/lib/cjs/js/usePreview/renderFile.js +1 -1
- package/lib/cjs/js/usePreview/renderFile.js.map +1 -1
- package/lib/css/index.css +1 -1
- package/lib/css/index.css.map +1 -1
- package/lib/es/components/editor/editor.js +5 -0
- package/lib/es/components/editor/editor.js.map +1 -1
- package/lib/es/components/editor/memtion.js +46 -4
- package/lib/es/components/editor/memtion.js.map +1 -1
- package/lib/es/components/list/list.js +4 -4
- package/lib/es/components/list/list.js.map +1 -1
- package/lib/es/components/picker/colors/index.js +6 -3
- package/lib/es/components/picker/colors/index.js.map +1 -1
- package/lib/es/components/tabs/navs.js.map +1 -1
- package/lib/es/components/tabs/tabs.js.map +1 -1
- package/lib/es/components/upload/dropbox.js +46 -0
- package/lib/es/components/upload/dropbox.js.map +1 -0
- package/lib/es/components/upload/renderFile.js +34 -37
- package/lib/es/components/upload/renderFile.js.map +1 -1
- package/lib/es/components/upload/upload.js +107 -70
- package/lib/es/components/upload/upload.js.map +1 -1
- package/lib/es/js/usePreview/renderFile.js +1 -1
- package/lib/es/js/usePreview/renderFile.js.map +1 -1
- package/lib/index.js +233 -115
- package/lib/types/components/list/item.d.ts +6 -0
- package/lib/types/components/list/list.d.ts +3 -5
- package/lib/types/components/picker/type.d.ts +4 -1
- package/lib/types/components/tabs/type.d.ts +1 -1
- package/lib/types/components/upload/type.d.ts +4 -8
- package/package.json +97 -97
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
|
-
import { debounce, uid, throttle
|
|
3
|
+
import { debounce, uid, throttle } from 'radash';
|
|
4
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,
|
|
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';
|
|
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';
|
|
@@ -1752,9 +1752,9 @@ const Item$4 = (props) => {
|
|
|
1752
1752
|
}), style: { alignItems: align, ...style }, ...restProps, children: [label !== undefined && (jsx("span", { className: 'i-list-item-label', children: label })), children] }));
|
|
1753
1753
|
};
|
|
1754
1754
|
|
|
1755
|
-
const List$1 = (props) => {
|
|
1755
|
+
const List$1 = forwardRef((props, ref) => {
|
|
1756
1756
|
const { label, type, border, className, children, ...restProps } = props;
|
|
1757
|
-
return (jsx("ul", { className: classNames("i-list", className), ...restProps, children: Children.map(children, (node, i) => {
|
|
1757
|
+
return (jsx("ul", { ref: ref, className: classNames("i-list", className), ...restProps, children: Children.map(children, (node, i) => {
|
|
1758
1758
|
const renderLabel = typeof label === "function" ? label(i) : label;
|
|
1759
1759
|
const { type, props: nodeProps } = node;
|
|
1760
1760
|
if (type === Item$4) {
|
|
@@ -1767,7 +1767,7 @@ const List$1 = (props) => {
|
|
|
1767
1767
|
}
|
|
1768
1768
|
return node;
|
|
1769
1769
|
}) }));
|
|
1770
|
-
};
|
|
1770
|
+
});
|
|
1771
1771
|
List$1.Item = Item$4;
|
|
1772
1772
|
|
|
1773
1773
|
const Content$2 = forwardRef((props, ref) => {
|
|
@@ -2605,15 +2605,56 @@ const removeAdjacentMemtionTag = (editor, key) => {
|
|
|
2605
2605
|
editor.focus();
|
|
2606
2606
|
return true;
|
|
2607
2607
|
};
|
|
2608
|
+
const makeRectSource = (rect) => {
|
|
2609
|
+
const { left, top, width, height } = rect;
|
|
2610
|
+
return {
|
|
2611
|
+
offsetParent: null,
|
|
2612
|
+
offsetLeft: left,
|
|
2613
|
+
offsetTop: top,
|
|
2614
|
+
getBoundingClientRect: () => ({
|
|
2615
|
+
left,
|
|
2616
|
+
top,
|
|
2617
|
+
right: left + width,
|
|
2618
|
+
bottom: top + height,
|
|
2619
|
+
width,
|
|
2620
|
+
height,
|
|
2621
|
+
x: left,
|
|
2622
|
+
y: top,
|
|
2623
|
+
toJSON: () => ({}),
|
|
2624
|
+
}),
|
|
2625
|
+
};
|
|
2626
|
+
};
|
|
2608
2627
|
const Memtion = (props) => {
|
|
2609
2628
|
const { visible, rect, options, activeIndex, onActiveChange, onSelect } = props;
|
|
2629
|
+
const containerRef = useRef(null);
|
|
2630
|
+
const [pos, setPos] = useState({ left: 0, top: 0 });
|
|
2631
|
+
const [ready, setReady] = useState(false);
|
|
2632
|
+
useLayoutEffect(() => {
|
|
2633
|
+
if (!visible || !rect || !options?.length) {
|
|
2634
|
+
setReady(false);
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
const el = containerRef.current;
|
|
2638
|
+
if (!el)
|
|
2639
|
+
return;
|
|
2640
|
+
const [left, top] = getPosition(makeRectSource(rect), el, {
|
|
2641
|
+
position: "bottom",
|
|
2642
|
+
gap: 4,
|
|
2643
|
+
offset: 0,
|
|
2644
|
+
align: "start",
|
|
2645
|
+
refWindow: true,
|
|
2646
|
+
});
|
|
2647
|
+
setPos({ left, top });
|
|
2648
|
+
setReady(true);
|
|
2649
|
+
}, [visible, rect, options]);
|
|
2610
2650
|
if (!visible || !rect || !options?.length) {
|
|
2611
2651
|
return null;
|
|
2612
2652
|
}
|
|
2613
|
-
const content = (jsx(List$1, { className: "i-editor-memtion", type: "option", style: {
|
|
2653
|
+
const content = (jsx(List$1, { ref: containerRef, className: "i-editor-memtion", type: "option", style: {
|
|
2614
2654
|
position: "fixed",
|
|
2615
|
-
|
|
2616
|
-
|
|
2655
|
+
left: pos.left,
|
|
2656
|
+
top: pos.top,
|
|
2657
|
+
opacity: ready ? 1 : 0,
|
|
2617
2658
|
}, children: options.map((option, i) => (jsx(List$1.Item, { type: "option", active: i === activeIndex, onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => onActiveChange?.(i), onClick: () => onSelect?.(option), children: option.label }, `${option.value}-${i}`))) }));
|
|
2618
2659
|
if (typeof document === "undefined") {
|
|
2619
2660
|
return content;
|
|
@@ -2732,6 +2773,8 @@ const Editor = (props) => {
|
|
|
2732
2773
|
};
|
|
2733
2774
|
const handleKeyDown = (e) => {
|
|
2734
2775
|
onKeyDown?.(e);
|
|
2776
|
+
if (e.defaultPrevented)
|
|
2777
|
+
return;
|
|
2735
2778
|
if (!isPlaintextMode &&
|
|
2736
2779
|
(e.key === "Backspace" || e.key === "Delete") &&
|
|
2737
2780
|
removeAdjacentMemtionTag(editorRef.current, e.key)) {
|
|
@@ -2772,6 +2815,9 @@ const Editor = (props) => {
|
|
|
2772
2815
|
exec(isRichMode ? "insertHTML" : "insertText", false, isRichMode ? "	" : "\t");
|
|
2773
2816
|
break;
|
|
2774
2817
|
case "Enter":
|
|
2818
|
+
if (e.shiftKey) {
|
|
2819
|
+
break;
|
|
2820
|
+
}
|
|
2775
2821
|
if (!onEnter)
|
|
2776
2822
|
break;
|
|
2777
2823
|
e.preventDefault();
|
|
@@ -3657,7 +3703,7 @@ function renderFile(props) {
|
|
|
3657
3703
|
case TFileType.VIDEO:
|
|
3658
3704
|
return jsx(Video, { ...props });
|
|
3659
3705
|
default:
|
|
3660
|
-
return (jsxs("div", { className:
|
|
3706
|
+
return (jsxs("div", { className: "i-preview-unknown", children: [jsx(Icon, { icon: jsx(FeedOutlined, {}), size: "3em" }), jsx("h5", { className: "mt-4", children: name || suffix })] }));
|
|
3661
3707
|
}
|
|
3662
3708
|
}
|
|
3663
3709
|
|
|
@@ -4615,7 +4661,7 @@ const Handle = (props) => {
|
|
|
4615
4661
|
};
|
|
4616
4662
|
|
|
4617
4663
|
function ColorPicker(props) {
|
|
4618
|
-
const { value, type = "HEX", disabledAlpha, children, usePanel, handle = "both", placeholder = "Colors", popupProps, onChange, label, required, ...restProps } = props;
|
|
4664
|
+
const { value, type = "HEX", disabledAlpha, children, usePanel, handle = "both", placeholder = "Colors", popupProps, onChange, label, required, className, style, ...restProps } = props;
|
|
4619
4665
|
const [colorType, setColorType] = useState(type);
|
|
4620
4666
|
const [colorValue, setColorValue] = useState(value);
|
|
4621
4667
|
const [syncValue, setSyncValue] = useState(value);
|
|
@@ -4659,9 +4705,11 @@ function ColorPicker(props) {
|
|
|
4659
4705
|
if (usePanel) {
|
|
4660
4706
|
return (jsx(InputContainer, { label: label, required: required, children: jsx(ColorsPanel, { ...restProps, value: value, onChange: onChange }) }));
|
|
4661
4707
|
}
|
|
4662
|
-
return (jsx(InputContainer, { label: label, required: required, children: jsx(Popup, { trigger: "click", touchable: true, position: "bottom", ...popupProps, visible: visible, content: jsx(ColorsPanel, { ...restProps, value: syncValue, disabledAlpha: disabledAlpha, panelRender: (panel) => {
|
|
4708
|
+
return (jsx(InputContainer, { label: label, required: required, className: classNames("i-colorpicker", className), style: style, children: jsx(Popup, { trigger: "click", touchable: true, position: "bottom", ...popupProps, visible: visible, content: jsx(ColorsPanel, { ...restProps, value: syncValue, disabledAlpha: disabledAlpha, panelRender: (panel) => {
|
|
4663
4709
|
return (jsxs(Fragment, { children: [panel, jsx(Footer, { value: colorValue, type: colorType, onTypeChange: handleTypeChange, onChange: handleValueChange, onOk: handleOk })] }));
|
|
4664
|
-
}, onChange: handleChange, onChangeComplete: handleComplete }), onVisibleChange: handleVisibleChange, children: children
|
|
4710
|
+
}, onChange: handleChange, onChangeComplete: handleComplete }), onVisibleChange: handleVisibleChange, children: typeof children === "function"
|
|
4711
|
+
? children({ type: colorType, value: colorValue })
|
|
4712
|
+
: (children ?? (jsx(Handle, { color: value, handle: handle, placeholder: placeholder }))) }) }));
|
|
4665
4713
|
}
|
|
4666
4714
|
|
|
4667
4715
|
const Dates = (props) => {
|
|
@@ -5991,155 +6039,225 @@ const Tree = (props) => {
|
|
|
5991
6039
|
return (jsx(TreeList, { data: data, selected: selectedKey, checked: checkedKeys, partofs: partofs, nodeProps: oNodeProps, onItemCheck: handleCheck, onItemSelect: handleSelect, ...restProps }));
|
|
5992
6040
|
};
|
|
5993
6041
|
|
|
5994
|
-
const
|
|
5995
|
-
const {
|
|
5996
|
-
const
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6042
|
+
const Dropbox = (props) => {
|
|
6043
|
+
const { multiple, accept, disabled, children, onChange, onDropFiles } = props;
|
|
6044
|
+
const [dragging, setDragging] = useState(false);
|
|
6045
|
+
const inputRef = useRef(null);
|
|
6046
|
+
const handleDragOver = (e) => {
|
|
6047
|
+
e.preventDefault();
|
|
6048
|
+
e.stopPropagation();
|
|
6049
|
+
};
|
|
6050
|
+
const handleDragEnter = (e) => {
|
|
6051
|
+
e.preventDefault();
|
|
6052
|
+
e.stopPropagation();
|
|
6053
|
+
if (!disabled)
|
|
6054
|
+
setDragging(true);
|
|
6002
6055
|
};
|
|
6056
|
+
const handleDragLeave = (e) => {
|
|
6057
|
+
e.preventDefault();
|
|
6058
|
+
e.stopPropagation();
|
|
6059
|
+
setDragging(false);
|
|
6060
|
+
};
|
|
6061
|
+
const handleDrop = (e) => {
|
|
6062
|
+
e.preventDefault();
|
|
6063
|
+
e.stopPropagation();
|
|
6064
|
+
setDragging(false);
|
|
6065
|
+
if (disabled)
|
|
6066
|
+
return;
|
|
6067
|
+
const files = Array.from(e.dataTransfer.files);
|
|
6068
|
+
if (files.length)
|
|
6069
|
+
onDropFiles(files);
|
|
6070
|
+
};
|
|
6071
|
+
const handleClick = () => {
|
|
6072
|
+
if (!disabled)
|
|
6073
|
+
inputRef.current?.click();
|
|
6074
|
+
};
|
|
6075
|
+
return (jsxs("div", { className: classNames("i-upload-dropbox", dragging && "i-upload-dropbox-active"), onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDrop: handleDrop, onClick: handleClick, children: [jsx("input", { ref: inputRef, type: "file", className: "i-input-file-hidden", multiple: multiple, accept: accept, disabled: disabled, onChange: onChange }), typeof children === "function"
|
|
6076
|
+
? children(dragging)
|
|
6077
|
+
: children || (jsx(Icon, { icon: dragging ? (jsx(MoveToInboxTwotone, {})) : (jsx(OutboxTwotone, {})), size: "2em" }))] }));
|
|
6078
|
+
};
|
|
6079
|
+
|
|
6080
|
+
const ListContainer = memo((props) => {
|
|
6081
|
+
const { sortable, onSortEnd, children, ...restProps } = props;
|
|
6003
6082
|
if (!sortable) {
|
|
6004
|
-
return jsx("div", {
|
|
6083
|
+
return (jsx("div", { className: "i-upload-list", onClick: (e) => {
|
|
6084
|
+
e.stopPropagation();
|
|
6085
|
+
e.preventDefault();
|
|
6086
|
+
}, ...restProps, children: children }));
|
|
6005
6087
|
}
|
|
6006
|
-
return (jsx(SortableContainer, { draggedItemClassName:
|
|
6007
|
-
};
|
|
6008
|
-
const
|
|
6088
|
+
return (jsx(SortableContainer, { draggedItemClassName: "i-upload-item-dragged", onSortEnd: onSortEnd, className: "i-upload-list", ...restProps, children: children }));
|
|
6089
|
+
});
|
|
6090
|
+
const CloseBtn = memo(({ index, onRemove }) => (jsx(Helpericon, { active: true, className: "i-upload-delete", onClick: (e) => {
|
|
6091
|
+
e.stopPropagation();
|
|
6092
|
+
e.preventDefault();
|
|
6093
|
+
onRemove(index);
|
|
6094
|
+
} })));
|
|
6095
|
+
const FileListItem = memo((props) => {
|
|
6009
6096
|
const { ref, mode, index, file, renderItem, onRemove, onPreview } = props;
|
|
6010
6097
|
if (!file)
|
|
6011
|
-
return
|
|
6012
|
-
const {
|
|
6098
|
+
return null;
|
|
6099
|
+
const { name, size, url, src } = file;
|
|
6013
6100
|
const type = getFileType(name, file.type);
|
|
6101
|
+
const handleClick = useCallback(() => {
|
|
6102
|
+
onPreview?.(index);
|
|
6103
|
+
}, [onPreview, index]);
|
|
6014
6104
|
if (renderItem) {
|
|
6015
6105
|
return renderItem(file, index);
|
|
6016
6106
|
}
|
|
6017
|
-
const
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6107
|
+
const node = useMemo(() => {
|
|
6108
|
+
switch (type) {
|
|
6109
|
+
case TFileType.IMAGE:
|
|
6110
|
+
return (jsx(MemoImage, { lazyload: true, src: url || src, fit: "cover", onMouseDown: (e) => e.preventDefault() }));
|
|
6111
|
+
case TFileType.VIDEO:
|
|
6112
|
+
return jsx("video", { src: url || src, preload: "none" });
|
|
6113
|
+
default:
|
|
6114
|
+
return (jsxs(Fragment, { children: [jsx(Icon, { icon: jsx(FilePresentOutlined, {}), size: "1.5em" }), jsx("span", { className: "i-upload-file-name", children: name })] }));
|
|
6115
|
+
}
|
|
6116
|
+
}, [type, url, src, name]);
|
|
6022
6117
|
switch (mode) {
|
|
6023
6118
|
case "card":
|
|
6024
|
-
|
|
6025
|
-
switch (type) {
|
|
6026
|
-
case TFileType.IMAGE:
|
|
6027
|
-
node = (jsx(MemoImage, { lazyload: true, src: url || src, fit: 'cover', onMouseDown: (e) => e.preventDefault() }));
|
|
6028
|
-
break;
|
|
6029
|
-
case TFileType.VIDEO:
|
|
6030
|
-
node = jsx("video", { src: url || src, preload: 'none' });
|
|
6031
|
-
break;
|
|
6032
|
-
default:
|
|
6033
|
-
node = (jsxs(Fragment, { children: [jsx(Icon, { icon: jsx(ListAltRound, {}) }), jsx("span", { className: 'i-upload-file-name', children: title(name) })] }));
|
|
6034
|
-
break;
|
|
6035
|
-
}
|
|
6036
|
-
return (jsxs("div", { ref: ref, title: name, className: 'i-upload-item-card', onClick: () => onPreview?.(index), children: [node, CloseBtn] }));
|
|
6119
|
+
return (jsxs("div", { ref: ref, className: "i-upload-item-card", onClick: handleClick, children: [node, jsx(CloseBtn, { index: index, onRemove: onRemove }), name && (jsx("span", { className: "px-12 py-8 i-upload-tip", children: name }))] }));
|
|
6037
6120
|
default:
|
|
6038
|
-
return (jsxs("div", { ref: ref, className:
|
|
6121
|
+
return (jsxs("div", { ref: ref, className: "i-upload-item", onClick: handleClick, children: [jsx("span", { children: name }), jsx("i", { className: "i-upload-size", children: formatBytes(size ?? 0) }), jsx(CloseBtn, { index: index, onRemove: onRemove })] }));
|
|
6039
6122
|
}
|
|
6040
|
-
};
|
|
6123
|
+
});
|
|
6041
6124
|
|
|
6125
|
+
const normalizeFiles = (files) => (files ?? []).map((item) => {
|
|
6126
|
+
const file = item;
|
|
6127
|
+
if (item instanceof File) {
|
|
6128
|
+
const src = file.src ?? URL.createObjectURL(item);
|
|
6129
|
+
Object.assign(item, {
|
|
6130
|
+
id: file.id ?? uid(7),
|
|
6131
|
+
src,
|
|
6132
|
+
url: file.url ?? src,
|
|
6133
|
+
});
|
|
6134
|
+
return item;
|
|
6135
|
+
}
|
|
6136
|
+
const src = file.src ?? file.name;
|
|
6137
|
+
return {
|
|
6138
|
+
...file,
|
|
6139
|
+
id: file.id ?? uid(7),
|
|
6140
|
+
src,
|
|
6141
|
+
url: file.url ?? src,
|
|
6142
|
+
};
|
|
6143
|
+
});
|
|
6042
6144
|
const Upload = (props) => {
|
|
6043
|
-
const {
|
|
6044
|
-
const [
|
|
6045
|
-
const
|
|
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;
|
|
6146
|
+
const [internalFileList, setInternalFileList] = useState([]);
|
|
6147
|
+
const isControlled = useMemo(() => value !== undefined || files !== undefined, [value, files]);
|
|
6148
|
+
const fileList = isControlled
|
|
6149
|
+
? normalizeFiles(value ?? files ?? [])
|
|
6150
|
+
: internalFileList;
|
|
6151
|
+
const uploadMessage = message;
|
|
6046
6152
|
const inputRef = useRef(null);
|
|
6047
6153
|
const preview = usePreview();
|
|
6048
|
-
const defBtnProps =
|
|
6154
|
+
const defBtnProps = useMemo(() => ({
|
|
6049
6155
|
children: (jsxs(Fragment, { children: [jsx(Icon, { icon: jsx(DriveFolderUploadOutlined, {}) }), " \u4E0A\u4F20"] })),
|
|
6050
|
-
|
|
6156
|
+
...defaultButtonProps,
|
|
6157
|
+
}), [defaultButtonProps]);
|
|
6051
6158
|
const trigger = useMemo(() => {
|
|
6052
6159
|
if (children)
|
|
6053
6160
|
return children;
|
|
6054
6161
|
switch (mode) {
|
|
6055
6162
|
case "card":
|
|
6056
|
-
return (jsx(Button, { className:
|
|
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, {}) }) }));
|
|
6057
6164
|
default:
|
|
6058
6165
|
return (jsx(Button, { ...defBtnProps, className: classNames("i-upload-btn", defBtnProps.className), disabled: disabled }));
|
|
6059
6166
|
}
|
|
6060
|
-
}, [mode, children]);
|
|
6061
|
-
const
|
|
6062
|
-
|
|
6167
|
+
}, [mode, children, disabled, defBtnProps]);
|
|
6168
|
+
const handleUpload = useCallback(async (files) => {
|
|
6169
|
+
if (!uploader)
|
|
6170
|
+
return;
|
|
6171
|
+
const shouldUploadFiles = files.filter(shouldUpload);
|
|
6172
|
+
const result = await Promise.all(shouldUploadFiles.map(uploader));
|
|
6173
|
+
return onUpload?.(result);
|
|
6174
|
+
}, [uploader, shouldUpload, onUpload]);
|
|
6175
|
+
const processFiles = useCallback((inputFiles) => {
|
|
6063
6176
|
const before = fileList;
|
|
6064
6177
|
const changed = [];
|
|
6065
|
-
|
|
6066
|
-
const { id, name, size, type } =
|
|
6067
|
-
const same = before.
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
Object.assign(f, {
|
|
6178
|
+
inputFiles.forEach((file) => {
|
|
6179
|
+
const { id, name, size, type } = file;
|
|
6180
|
+
const same = before.some((pf) => pf.name === name &&
|
|
6181
|
+
pf.size === size &&
|
|
6182
|
+
pf.type === type);
|
|
6183
|
+
const src = URL.createObjectURL(file);
|
|
6184
|
+
Object.assign(file, {
|
|
6073
6185
|
id: id ?? uid(7),
|
|
6074
|
-
src: src ??
|
|
6075
|
-
url: src ??
|
|
6186
|
+
src: src ?? file.name,
|
|
6187
|
+
url: src ?? file.name,
|
|
6076
6188
|
});
|
|
6077
|
-
!same
|
|
6189
|
+
if (!same)
|
|
6190
|
+
changed.push(file);
|
|
6078
6191
|
});
|
|
6079
6192
|
const after = [...before, ...changed];
|
|
6080
6193
|
const last = after.at(-1);
|
|
6081
|
-
const nextFiles = multiple
|
|
6082
|
-
|
|
6083
|
-
|
|
6194
|
+
const nextFiles = multiple
|
|
6195
|
+
? after.slice(0, limit)
|
|
6196
|
+
: last
|
|
6197
|
+
? [last]
|
|
6198
|
+
: [];
|
|
6199
|
+
return { nextFiles, changed };
|
|
6200
|
+
}, [fileList, multiple, limit]);
|
|
6201
|
+
const applyFiles = useCallback((nextFiles, changed, e) => {
|
|
6202
|
+
if (!isControlled)
|
|
6203
|
+
setInternalFileList(nextFiles);
|
|
6084
6204
|
onFilesChange?.(nextFiles, changed, e);
|
|
6085
6205
|
onChange?.(nextFiles, e);
|
|
6086
6206
|
handleUpload(changed);
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
const
|
|
6207
|
+
}, [isControlled, onFilesChange, onChange, handleUpload]);
|
|
6208
|
+
const handleChange = useCallback((e) => {
|
|
6209
|
+
const inputFiles = Array.from(e.target.files || []);
|
|
6210
|
+
const { nextFiles, changed } = processFiles(inputFiles);
|
|
6211
|
+
applyFiles(nextFiles, changed, e);
|
|
6212
|
+
if (inputRef.current)
|
|
6213
|
+
inputRef.current.value = "";
|
|
6214
|
+
}, [processFiles, applyFiles]);
|
|
6215
|
+
const handleDropFiles = useCallback((files) => {
|
|
6216
|
+
const { nextFiles, changed } = processFiles(files);
|
|
6217
|
+
applyFiles(nextFiles, changed);
|
|
6218
|
+
}, [processFiles, applyFiles]);
|
|
6219
|
+
const handleRemove = useCallback((i) => {
|
|
6220
|
+
const files = [...fileList];
|
|
6091
6221
|
const changed = files.splice(i, 1);
|
|
6092
6222
|
URL.revokeObjectURL(changed[0]?.src || "");
|
|
6093
|
-
|
|
6223
|
+
if (!isControlled)
|
|
6224
|
+
setInternalFileList(files);
|
|
6094
6225
|
onFilesChange?.(files, changed);
|
|
6095
6226
|
onChange?.(files);
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
const setFileList = (files) => {
|
|
6109
|
-
if (!files)
|
|
6110
|
-
return;
|
|
6111
|
-
setFileListState(files.map((f) => {
|
|
6112
|
-
const file = f;
|
|
6113
|
-
return { ...file, id: file.id ?? uid(7) };
|
|
6114
|
-
}));
|
|
6115
|
-
};
|
|
6116
|
-
const handleSortEnd = (before, after) => {
|
|
6117
|
-
const [...files] = fileList;
|
|
6227
|
+
onRemove?.(changed[0]);
|
|
6228
|
+
if (inputRef.current)
|
|
6229
|
+
inputRef.current.value = "";
|
|
6230
|
+
}, [fileList, isControlled, onFilesChange, onChange, onRemove]);
|
|
6231
|
+
const handlePreview = useCallback((i) => {
|
|
6232
|
+
preview({
|
|
6233
|
+
items: fileList,
|
|
6234
|
+
initial: i,
|
|
6235
|
+
});
|
|
6236
|
+
}, [fileList, preview]);
|
|
6237
|
+
const handleSortEnd = useCallback((before, after) => {
|
|
6238
|
+
const files = [...fileList];
|
|
6118
6239
|
const nextFiles = arrayMove(files, before, after);
|
|
6119
|
-
|
|
6240
|
+
if (!isControlled)
|
|
6241
|
+
setInternalFileList(nextFiles);
|
|
6242
|
+
onFilesChange?.(nextFiles, []);
|
|
6120
6243
|
onChange?.(nextFiles);
|
|
6121
|
-
};
|
|
6122
|
-
|
|
6123
|
-
setUploadMessage(message);
|
|
6124
|
-
}, [status, message]);
|
|
6125
|
-
useEffect(() => {
|
|
6126
|
-
setFileListState(value?.filter?.((file) => !!file.id) ?? []);
|
|
6127
|
-
}, [value]);
|
|
6128
|
-
useEffect(() => {
|
|
6129
|
-
setFileList(initialFiles);
|
|
6130
|
-
}, []);
|
|
6131
|
-
useImperativeHandle(ref, () => ({
|
|
6132
|
-
getFileList: () => fileList,
|
|
6133
|
-
setFileList,
|
|
6134
|
-
}), [fileList]);
|
|
6135
|
-
return (jsx(InputContainer, { as: 'div', label: label, labelInline: labelInline, className: classNames("i-input-label-file", className), style: style, children: jsxs("div", { className: classNames("i-upload-inner", {
|
|
6244
|
+
}, [fileList, isControlled, onFilesChange, onChange]);
|
|
6245
|
+
return (jsx(InputContainer, { as: "div", label: label, labelInline: labelInline, className: classNames("i-input-label-file", className), style: style, children: jsxs("div", { className: classNames("i-upload-inner", {
|
|
6136
6246
|
[`i-upload-${mode}`]: mode !== "default",
|
|
6137
6247
|
}), style: { ["--upload-card-size"]: cardSize }, children: [jsx(ListContainer, { sortable: sortable, onSortEnd: handleSortEnd, children: fileList.map((file, i) => {
|
|
6138
|
-
const
|
|
6248
|
+
const f = file;
|
|
6249
|
+
const key = f.id ?? i;
|
|
6250
|
+
const node = (jsx(FileListItem, { index: i, file: f, mode: mode, renderItem: renderItem, onRemove: handleRemove, onPreview: handlePreview }, key));
|
|
6139
6251
|
if (!sortable)
|
|
6140
6252
|
return node;
|
|
6141
|
-
return jsx(SortableItem, { children: node },
|
|
6142
|
-
}) }), uploadMessage && (jsx("span", { className:
|
|
6253
|
+
return jsx(SortableItem, { children: node }, key);
|
|
6254
|
+
}) }), uploadMessage && (jsx("span", { className: "i-upload-message", children: uploadMessage })), fileList.length < limit &&
|
|
6255
|
+
(droppable ? ((() => {
|
|
6256
|
+
const node = (jsx(Dropbox, { multiple: multiple, accept: restProps.accept, disabled: disabled, onChange: handleChange, onDropFiles: handleDropFiles, children: dropbox }));
|
|
6257
|
+
return getDropboxContainer
|
|
6258
|
+
? createPortal(node, getDropboxContainer())
|
|
6259
|
+
: node;
|
|
6260
|
+
})()) : (jsxs("label", { children: [jsx("input", { ...restProps, disabled: disabled, ref: inputRef, type: "file", className: "i-input-file-hidden", multiple: multiple, onChange: handleChange }), trigger] })))] }) }));
|
|
6143
6261
|
};
|
|
6144
6262
|
|
|
6145
6263
|
const stores = new Map();
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
1
|
+
import Item from './item.js';
|
|
3
2
|
|
|
4
|
-
declare const List: {
|
|
5
|
-
|
|
6
|
-
Item: (props: IListItem) => react_jsx_runtime.JSX.Element;
|
|
3
|
+
declare const List: typeof List & {
|
|
4
|
+
Item: typeof Item;
|
|
7
5
|
};
|
|
8
6
|
|
|
9
7
|
export { List as default };
|
|
@@ -32,7 +32,10 @@ interface IColorPicker extends Omit<ColorPickerProps, "value" | "onChange"> {
|
|
|
32
32
|
label?: ReactNode;
|
|
33
33
|
required?: boolean;
|
|
34
34
|
type?: "HEX" | "RGB" | "HSB";
|
|
35
|
-
children?: ReactNode
|
|
35
|
+
children?: ReactNode | ((params: {
|
|
36
|
+
type: string;
|
|
37
|
+
value: any;
|
|
38
|
+
}) => ReactNode);
|
|
36
39
|
popupProps?: IPopup;
|
|
37
40
|
usePanel?: boolean;
|
|
38
41
|
handle?: "text" | "square" | "both";
|
|
@@ -34,7 +34,7 @@ interface RefTabs {
|
|
|
34
34
|
open: (key: string) => void;
|
|
35
35
|
close: (key: string) => void;
|
|
36
36
|
add: (tab: ITabItem, position?: number) => void;
|
|
37
|
-
navs: RefObject<HTMLDivElement>;
|
|
37
|
+
navs: RefObject<HTMLDivElement | null>;
|
|
38
38
|
}
|
|
39
39
|
interface CompositionTabs extends ForwardRefExoticComponent<ITabs> {
|
|
40
40
|
Item: typeof Item;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { InputHTMLAttributes,
|
|
1
|
+
import { InputHTMLAttributes, ReactNode, ChangeEvent } from 'react';
|
|
2
2
|
import { BaseInput } from '../../type/index.js';
|
|
3
3
|
import { IButton } from '../button/type.js';
|
|
4
4
|
|
|
5
5
|
interface IUpload extends Omit<BaseInput, "ref">, Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "onChange"> {
|
|
6
|
-
ref?: RefObject<RefUpload | null>;
|
|
7
6
|
files?: IFile[];
|
|
8
|
-
initialFiles?: IFile[] | File[];
|
|
9
7
|
accept?: string;
|
|
10
8
|
multiple?: boolean;
|
|
11
9
|
directory?: boolean;
|
|
@@ -13,6 +11,8 @@ interface IUpload extends Omit<BaseInput, "ref">, Omit<InputHTMLAttributes<HTMLI
|
|
|
13
11
|
sortable?: boolean;
|
|
14
12
|
mode?: "default" | "card";
|
|
15
13
|
droppable?: boolean;
|
|
14
|
+
dropbox?: (dragging?: boolean) => ReactNode;
|
|
15
|
+
getDropboxContainer?: () => HTMLElement;
|
|
16
16
|
cardSize?: string;
|
|
17
17
|
defaultButtonProps?: IButton;
|
|
18
18
|
shouldUpload?: (file: IFile) => boolean;
|
|
@@ -29,9 +29,5 @@ interface IFile extends File {
|
|
|
29
29
|
url?: string;
|
|
30
30
|
[key: string]: any;
|
|
31
31
|
}
|
|
32
|
-
interface RefUpload {
|
|
33
|
-
getFileList: () => IFile[];
|
|
34
|
-
setFileList: (files?: IFile[] | File[]) => void;
|
|
35
|
-
}
|
|
36
32
|
|
|
37
|
-
export type { IFile, IUpload
|
|
33
|
+
export type { IFile, IUpload };
|