@ioca/react 1.4.74 → 1.4.75
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/button/toggle.js +11 -18
- package/lib/cjs/components/button/toggle.js.map +1 -1
- package/lib/cjs/components/checkbox/checkbox.js +5 -8
- package/lib/cjs/components/checkbox/checkbox.js.map +1 -1
- package/lib/cjs/components/checkbox/item.js +15 -16
- package/lib/cjs/components/checkbox/item.js.map +1 -1
- package/lib/cjs/components/collapse/collapse.js +11 -13
- package/lib/cjs/components/collapse/collapse.js.map +1 -1
- package/lib/cjs/components/form/field.js +16 -20
- package/lib/cjs/components/form/field.js.map +1 -1
- package/lib/cjs/components/input/input.js +21 -18
- package/lib/cjs/components/input/input.js.map +1 -1
- package/lib/cjs/components/input/number.js +65 -19
- package/lib/cjs/components/input/number.js.map +1 -1
- package/lib/cjs/components/input/range.js +10 -13
- package/lib/cjs/components/input/range.js.map +1 -1
- package/lib/cjs/components/input/textarea.js +4 -7
- package/lib/cjs/components/input/textarea.js.map +1 -1
- package/lib/cjs/components/picker/colors/footer.js +7 -10
- package/lib/cjs/components/picker/colors/footer.js.map +1 -1
- package/lib/cjs/components/picker/colors/index.js +23 -21
- package/lib/cjs/components/picker/colors/index.js.map +1 -1
- package/lib/cjs/components/picker/dates/index.js +9 -12
- package/lib/cjs/components/picker/dates/index.js.map +1 -1
- package/lib/cjs/components/picker/dates/panel.js +29 -35
- package/lib/cjs/components/picker/dates/panel.js.map +1 -1
- package/lib/cjs/components/picker/time/index.js +8 -12
- package/lib/cjs/components/picker/time/index.js.map +1 -1
- package/lib/cjs/components/picker/time/panel.js +38 -21
- package/lib/cjs/components/picker/time/panel.js.map +1 -1
- package/lib/cjs/components/radio/radio.js +4 -7
- package/lib/cjs/components/radio/radio.js.map +1 -1
- package/lib/cjs/components/select/select.js +19 -24
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/tabs/tabs.js +61 -54
- package/lib/cjs/components/tabs/tabs.js.map +1 -1
- package/lib/cjs/components/tree/tree.js +24 -26
- package/lib/cjs/components/tree/tree.js.map +1 -1
- package/lib/cjs/components/upload/upload.js +26 -33
- package/lib/cjs/components/upload/upload.js.map +1 -1
- package/lib/css/index.css +1 -1
- package/lib/css/index.css.map +1 -1
- package/lib/es/components/button/toggle.js +12 -19
- package/lib/es/components/button/toggle.js.map +1 -1
- package/lib/es/components/checkbox/checkbox.js +6 -9
- package/lib/es/components/checkbox/checkbox.js.map +1 -1
- package/lib/es/components/checkbox/item.js +16 -17
- package/lib/es/components/checkbox/item.js.map +1 -1
- package/lib/es/components/collapse/collapse.js +12 -14
- package/lib/es/components/collapse/collapse.js.map +1 -1
- package/lib/es/components/form/field.js +17 -21
- package/lib/es/components/form/field.js.map +1 -1
- package/lib/es/components/input/input.js +22 -19
- package/lib/es/components/input/input.js.map +1 -1
- package/lib/es/components/input/number.js +67 -21
- package/lib/es/components/input/number.js.map +1 -1
- package/lib/es/components/input/range.js +11 -14
- package/lib/es/components/input/range.js.map +1 -1
- package/lib/es/components/input/textarea.js +5 -8
- package/lib/es/components/input/textarea.js.map +1 -1
- package/lib/es/components/picker/colors/footer.js +8 -11
- package/lib/es/components/picker/colors/footer.js.map +1 -1
- package/lib/es/components/picker/colors/index.js +24 -22
- package/lib/es/components/picker/colors/index.js.map +1 -1
- package/lib/es/components/picker/dates/index.js +9 -12
- package/lib/es/components/picker/dates/index.js.map +1 -1
- package/lib/es/components/picker/dates/panel.js +30 -36
- package/lib/es/components/picker/dates/panel.js.map +1 -1
- package/lib/es/components/picker/time/index.js +8 -12
- package/lib/es/components/picker/time/index.js.map +1 -1
- package/lib/es/components/picker/time/panel.js +39 -22
- package/lib/es/components/picker/time/panel.js.map +1 -1
- package/lib/es/components/radio/radio.js +5 -8
- package/lib/es/components/radio/radio.js.map +1 -1
- package/lib/es/components/select/select.js +19 -24
- package/lib/es/components/select/select.js.map +1 -1
- package/lib/es/components/tabs/tabs.js +63 -56
- package/lib/es/components/tabs/tabs.js.map +1 -1
- package/lib/es/components/tree/tree.js +25 -27
- package/lib/es/components/tree/tree.js.map +1 -1
- package/lib/es/components/upload/upload.js +27 -34
- package/lib/es/components/upload/upload.js.map +1 -1
- package/lib/index.js +406 -368
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -428,25 +428,21 @@ function Group(props) {
|
|
|
428
428
|
|
|
429
429
|
function Toggle(props) {
|
|
430
430
|
const { ref, active, activeClass, after, disabled, children, className, toggable, onClick, onToggle, ...restProps } = props;
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
done: true,
|
|
434
|
-
});
|
|
431
|
+
const [isActive, setIsActive] = useState(active);
|
|
432
|
+
const [done, setDone] = useState(true);
|
|
435
433
|
const toggle = async () => {
|
|
436
434
|
const hasAfter = !!after;
|
|
437
|
-
const nextActive = !
|
|
435
|
+
const nextActive = !isActive;
|
|
438
436
|
const canToggle = toggable ? await toggable() : true;
|
|
439
437
|
if (!canToggle)
|
|
440
438
|
return;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
done: !hasAfter,
|
|
444
|
-
});
|
|
439
|
+
setIsActive(nextActive);
|
|
440
|
+
setDone(!hasAfter);
|
|
445
441
|
onToggle?.(nextActive);
|
|
446
442
|
if (!hasAfter)
|
|
447
443
|
return;
|
|
448
444
|
setTimeout(() => {
|
|
449
|
-
|
|
445
|
+
setDone(true);
|
|
450
446
|
}, 16);
|
|
451
447
|
};
|
|
452
448
|
const handleClick = (e) => {
|
|
@@ -454,14 +450,12 @@ function Toggle(props) {
|
|
|
454
450
|
!disabled && toggle();
|
|
455
451
|
};
|
|
456
452
|
useEffect(() => {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
done: true,
|
|
460
|
-
});
|
|
453
|
+
setIsActive(active);
|
|
454
|
+
setDone(true);
|
|
461
455
|
}, [active]);
|
|
462
|
-
return (jsx(Button, { ref: ref, className: classNames(className, { [activeClass || ""]:
|
|
463
|
-
"i-btn-toggle-active":
|
|
464
|
-
}), children:
|
|
456
|
+
return (jsx(Button, { ref: ref, className: classNames(className, { [activeClass || ""]: isActive }, "i-btn-toggle"), ...restProps, onClick: handleClick, children: jsx("div", { className: classNames("i-btn-toggle-content", {
|
|
457
|
+
"i-btn-toggle-active": done,
|
|
458
|
+
}), children: isActive ? (after ?? children) : children }) }));
|
|
465
459
|
}
|
|
466
460
|
|
|
467
461
|
const formatClass = ({ outline, flat, loading, disabled, size = "normal", block, round, square, secondary, className, }) => classNames("i-btn", className, {
|
|
@@ -894,41 +888,39 @@ const arrayMove = (array, fromIndex, toIndex) => {
|
|
|
894
888
|
|
|
895
889
|
function CheckboxItem(props) {
|
|
896
890
|
const { type = "default", label, name, value = false, className, status = "normal", message, disabled, partof, optionValue, children, onChange, ...restProps } = props;
|
|
897
|
-
const
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
message,
|
|
901
|
-
});
|
|
891
|
+
const [checked, setChecked] = useState(value);
|
|
892
|
+
const [itemStatus, setItemStatus] = useState(status);
|
|
893
|
+
const [itemMessage, setItemMessage] = useState(message);
|
|
902
894
|
const isChildrenFn = typeof children === "function";
|
|
903
895
|
const handleChange = (e) => {
|
|
904
|
-
const
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
});
|
|
910
|
-
onChange?.(checked, e);
|
|
896
|
+
const next = e.target.checked;
|
|
897
|
+
setChecked(next);
|
|
898
|
+
setItemStatus(status);
|
|
899
|
+
setItemMessage(message);
|
|
900
|
+
onChange?.(next, e);
|
|
911
901
|
};
|
|
912
902
|
useEffect(() => {
|
|
913
|
-
|
|
903
|
+
setChecked(value);
|
|
914
904
|
}, [value]);
|
|
905
|
+
useEffect(() => {
|
|
906
|
+
setItemStatus(status);
|
|
907
|
+
setItemMessage(message);
|
|
908
|
+
}, [status, message]);
|
|
915
909
|
return (jsxs("label", { className: classNames("i-checkbox-item", {
|
|
916
|
-
[`i-checkbox-${
|
|
910
|
+
[`i-checkbox-${itemStatus}`]: itemStatus !== "normal",
|
|
917
911
|
disabled,
|
|
918
912
|
}, className), ...restProps, children: [jsx("input", { type: 'checkbox', name: name, className: classNames("i-checkbox-input", {
|
|
919
913
|
[`i-checkbox-${type}`]: !partof,
|
|
920
914
|
"i-checkbox-partof": partof,
|
|
921
|
-
}), checked:
|
|
915
|
+
}), checked: checked, disabled: disabled, onChange: handleChange }), isChildrenFn ? (children(checked, optionValue)) : (jsx("span", { className: 'i-checkbox-text', children: children || label })), itemMessage && (jsxs("span", { className: 'i-checkbox-message', children: ["*", itemMessage] }))] }));
|
|
922
916
|
}
|
|
923
917
|
|
|
924
918
|
function Checkbox(props) {
|
|
925
919
|
const { label, name, options = [], value = "", type = "default", optionInline = true, labelInline, disabled, status = "normal", message, required, className, renderItem, onChange, ...restProps } = props;
|
|
926
|
-
const
|
|
927
|
-
value,
|
|
928
|
-
});
|
|
920
|
+
const [selectedValues, setSelectedValues] = useState(value);
|
|
929
921
|
const formattedOptions = useMemo(() => formatOption(options), [options]);
|
|
930
922
|
const handleChange = (checked, opt, e) => {
|
|
931
|
-
const group = [...
|
|
923
|
+
const group = [...selectedValues];
|
|
932
924
|
const i = group.findIndex((item) => item === opt.value);
|
|
933
925
|
if (checked && i < 0) {
|
|
934
926
|
group.push(opt.value);
|
|
@@ -936,11 +928,11 @@ function Checkbox(props) {
|
|
|
936
928
|
else if (!checked && i > -1) {
|
|
937
929
|
group.splice(i, 1);
|
|
938
930
|
}
|
|
939
|
-
|
|
931
|
+
setSelectedValues(group);
|
|
940
932
|
onChange?.(group, opt, e);
|
|
941
933
|
};
|
|
942
934
|
useEffect(() => {
|
|
943
|
-
|
|
935
|
+
setSelectedValues(value);
|
|
944
936
|
}, [value]);
|
|
945
937
|
return (jsxs("div", { className: classNames("i-checkbox i-input-label", {
|
|
946
938
|
[`i-checkbox-${status}`]: status !== "normal",
|
|
@@ -949,7 +941,7 @@ function Checkbox(props) {
|
|
|
949
941
|
"i-options-block": !optionInline,
|
|
950
942
|
"i-checkbox-options-button": type === "button",
|
|
951
943
|
}), children: formattedOptions.map((option) => {
|
|
952
|
-
return (jsx(CheckboxItem, { name: name, value:
|
|
944
|
+
return (jsx(CheckboxItem, { name: name, value: selectedValues.includes(option.value), optionValue: option.value, type: type, disabled: disabled || option.disabled, onChange: (checked, e) => handleChange(checked, option, e), children: renderItem ?? option.label }, option.value));
|
|
953
945
|
}) })] }));
|
|
954
946
|
}
|
|
955
947
|
Checkbox.Item = CheckboxItem;
|
|
@@ -975,9 +967,7 @@ function Item$5(props) {
|
|
|
975
967
|
|
|
976
968
|
const Collapse = (props) => {
|
|
977
969
|
const { active, items, multiple, border, headerClickable, className, children, renderToggle = (active) => active ? jsx(MinusRound, {}) : jsx(PlusRound, {}), onCollapse, ...restProps } = props;
|
|
978
|
-
const
|
|
979
|
-
active,
|
|
980
|
-
});
|
|
970
|
+
const [activeKey, setActiveKey] = useState(active);
|
|
981
971
|
const collapses = useMemo(() => {
|
|
982
972
|
if (!items) {
|
|
983
973
|
if (!children)
|
|
@@ -1007,19 +997,20 @@ const Collapse = (props) => {
|
|
|
1007
997
|
if (disabled)
|
|
1008
998
|
return;
|
|
1009
999
|
if (!multiple) {
|
|
1010
|
-
|
|
1011
|
-
|
|
1000
|
+
const nextActive = activeKey === key ? undefined : key;
|
|
1001
|
+
setActiveKey(nextActive);
|
|
1002
|
+
onCollapse?.(key, nextActive !== undefined);
|
|
1012
1003
|
return;
|
|
1013
1004
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const i = state.active.findIndex((k) => k === key);
|
|
1005
|
+
const group = Array.isArray(activeKey) ? [...activeKey] : [];
|
|
1006
|
+
const i = group.findIndex((k) => k === key);
|
|
1017
1007
|
if (i > -1) {
|
|
1018
|
-
|
|
1008
|
+
group.splice(i, 1);
|
|
1019
1009
|
}
|
|
1020
1010
|
else {
|
|
1021
|
-
key !== undefined &&
|
|
1011
|
+
key !== undefined && group.push(key);
|
|
1022
1012
|
}
|
|
1013
|
+
setActiveKey(group);
|
|
1023
1014
|
onCollapse?.(key, i < 0);
|
|
1024
1015
|
};
|
|
1025
1016
|
return (jsx("div", { className: classNames("i-collapse", {
|
|
@@ -1027,8 +1018,8 @@ const Collapse = (props) => {
|
|
|
1027
1018
|
}, className), ...restProps, children: collapses.map((item) => {
|
|
1028
1019
|
const { key, title, content, disabled, className, ...restProps } = item;
|
|
1029
1020
|
const isActive = multiple
|
|
1030
|
-
? (
|
|
1031
|
-
:
|
|
1021
|
+
? (activeKey || []).includes(key)
|
|
1022
|
+
: activeKey === key;
|
|
1032
1023
|
return (jsxs("div", { className: classNames("i-collapse-item", className, {
|
|
1033
1024
|
"i-collapse-active": isActive,
|
|
1034
1025
|
"i-collapse-disabled": disabled,
|
|
@@ -1808,12 +1799,9 @@ const Context = createContext({});
|
|
|
1808
1799
|
|
|
1809
1800
|
function Field(props) {
|
|
1810
1801
|
const { name, required, children } = props;
|
|
1811
|
-
const
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
message: undefined,
|
|
1815
|
-
update: 0,
|
|
1816
|
-
});
|
|
1802
|
+
const [fieldValue, setFieldValue] = useState(undefined);
|
|
1803
|
+
const [fieldStatus, setFieldStatus] = useState("normal");
|
|
1804
|
+
const [fieldMessage, setFieldMessage] = useState(undefined);
|
|
1817
1805
|
const form = useContext(Context);
|
|
1818
1806
|
const { id } = form;
|
|
1819
1807
|
const handleChange = (v) => {
|
|
@@ -1830,33 +1818,33 @@ function Field(props) {
|
|
|
1830
1818
|
if (!isValidElement(node))
|
|
1831
1819
|
return null;
|
|
1832
1820
|
const { onChange } = node.props;
|
|
1833
|
-
const { value, status, message } = state;
|
|
1834
1821
|
return cloneElement(node, {
|
|
1835
|
-
value,
|
|
1836
|
-
status,
|
|
1837
|
-
message,
|
|
1822
|
+
value: fieldValue,
|
|
1823
|
+
status: fieldStatus,
|
|
1824
|
+
message: fieldMessage,
|
|
1838
1825
|
required,
|
|
1839
1826
|
onChange: (...args) => {
|
|
1840
1827
|
handleChange(args[0]);
|
|
1841
1828
|
onChange?.(...args);
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
message: undefined,
|
|
1845
|
-
});
|
|
1829
|
+
setFieldStatus("normal");
|
|
1830
|
+
setFieldMessage(undefined);
|
|
1846
1831
|
},
|
|
1847
1832
|
});
|
|
1848
1833
|
});
|
|
1849
|
-
}, [children,
|
|
1834
|
+
}, [children, fieldValue, fieldStatus, fieldMessage, required]);
|
|
1850
1835
|
useEffect(() => {
|
|
1851
1836
|
if (!name)
|
|
1852
1837
|
return;
|
|
1853
1838
|
PubSub.subscribe(`${id}:set:${name}`, (evt, v) => {
|
|
1854
|
-
|
|
1855
|
-
state.update += 1;
|
|
1839
|
+
setFieldValue(v);
|
|
1856
1840
|
});
|
|
1857
1841
|
PubSub.subscribe(`${id}:invalid:${name}`, (evt, v) => {
|
|
1858
|
-
|
|
1859
|
-
|
|
1842
|
+
if (v?.value !== undefined)
|
|
1843
|
+
setFieldValue(v.value);
|
|
1844
|
+
if (v?.status)
|
|
1845
|
+
setFieldStatus(v.status);
|
|
1846
|
+
if ("message" in (v ?? {}))
|
|
1847
|
+
setFieldMessage(v.message);
|
|
1860
1848
|
});
|
|
1861
1849
|
Promise.resolve().then(() => {
|
|
1862
1850
|
form.set(name, form.cacheData[name] ?? undefined);
|
|
@@ -2847,11 +2835,33 @@ function InputContainer(props) {
|
|
|
2847
2835
|
|
|
2848
2836
|
const Number$1 = (props) => {
|
|
2849
2837
|
const { ref, label, name, value = "", labelInline, step = 1, min = -Infinity, max = Infinity, thousand, precision, type, className, width, status = "normal", append, border, prepend, disabled, message, tip, hideControl, showMax, style, onChange, onEnter, onInput, onBlur, ...restProps } = props;
|
|
2850
|
-
const
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2838
|
+
const [inputValue, setInputValue] = useState(value === undefined || value === null ? "" : String(value));
|
|
2839
|
+
const formatOut = (num) => {
|
|
2840
|
+
const v = clamp(num, min, max);
|
|
2841
|
+
if (precision !== undefined)
|
|
2842
|
+
return formatNumber(v, { precision, thousand });
|
|
2843
|
+
const s = String(v);
|
|
2844
|
+
if (!thousand)
|
|
2845
|
+
return s;
|
|
2846
|
+
const negative = s.startsWith("-");
|
|
2847
|
+
const body = negative ? s.slice(1) : s;
|
|
2848
|
+
const [integer, decimal] = body.split(".");
|
|
2849
|
+
const withThousand = integer.replace(/\B(?=(\d{3})+(?!\d))/g, thousand);
|
|
2850
|
+
return decimal
|
|
2851
|
+
? `${negative ? "-" : ""}${withThousand}.${decimal}`
|
|
2852
|
+
: `${negative ? "-" : ""}${withThousand}`;
|
|
2853
|
+
};
|
|
2854
|
+
const sanitizeNumberInput = (raw) => {
|
|
2855
|
+
const hasMinus = raw.startsWith("-");
|
|
2856
|
+
let v = raw.replace(/[^\d.]/g, "");
|
|
2857
|
+
if (hasMinus)
|
|
2858
|
+
v = `-${v}`;
|
|
2859
|
+
const parts = v.split(".");
|
|
2860
|
+
if (parts.length > 1) {
|
|
2861
|
+
v = `${parts.shift()}.${parts.join("")}`;
|
|
2862
|
+
}
|
|
2863
|
+
return v;
|
|
2864
|
+
};
|
|
2855
2865
|
const formatInputValue = (v) => {
|
|
2856
2866
|
if (!v)
|
|
2857
2867
|
return "";
|
|
@@ -2863,32 +2873,57 @@ const Number$1 = (props) => {
|
|
|
2863
2873
|
};
|
|
2864
2874
|
const handleChange = (e) => {
|
|
2865
2875
|
const { value } = e.target;
|
|
2866
|
-
const v = formatInputValue(value
|
|
2867
|
-
const
|
|
2868
|
-
|
|
2869
|
-
|
|
2876
|
+
const v = sanitizeNumberInput(formatInputValue(value));
|
|
2877
|
+
const isIntermediate = v === "" || v === "-" || v === "." || v === "-." || v.endsWith(".");
|
|
2878
|
+
setInputValue(v);
|
|
2879
|
+
if (isIntermediate)
|
|
2880
|
+
return;
|
|
2881
|
+
const num = parseFloat(v);
|
|
2882
|
+
if (globalThis.Number.isNaN(num))
|
|
2883
|
+
return;
|
|
2884
|
+
onChange?.(clamp(num, min, max), e);
|
|
2885
|
+
if (precision !== undefined)
|
|
2886
|
+
setInputValue(formatOut(num));
|
|
2870
2887
|
};
|
|
2871
2888
|
const handleOperate = (param) => {
|
|
2872
|
-
const value = parseFloat(formatInputValue(
|
|
2873
|
-
const result =
|
|
2874
|
-
|
|
2875
|
-
onChange?.(result);
|
|
2889
|
+
const value = parseFloat(formatInputValue(inputValue)) || 0; // 确保值为数字,默认值为 0
|
|
2890
|
+
const result = value + param;
|
|
2891
|
+
setInputValue(formatOut(result));
|
|
2892
|
+
onChange?.(clamp(result, min, max));
|
|
2876
2893
|
};
|
|
2877
2894
|
const handleMax = () => {
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2895
|
+
setInputValue(formatOut(max));
|
|
2896
|
+
onChange?.(clamp(max, min, max));
|
|
2897
|
+
};
|
|
2898
|
+
const handleBlur = (e) => {
|
|
2899
|
+
onBlur?.(e);
|
|
2900
|
+
const v = sanitizeNumberInput(formatInputValue(inputValue));
|
|
2901
|
+
if (!v || v === "-" || v === "." || v === "-.") {
|
|
2902
|
+
setInputValue("");
|
|
2903
|
+
return;
|
|
2904
|
+
}
|
|
2905
|
+
const num = parseFloat(v);
|
|
2906
|
+
if (globalThis.Number.isNaN(num))
|
|
2907
|
+
return;
|
|
2908
|
+
const numValue = clamp(num, min, max);
|
|
2909
|
+
setInputValue(formatOut(numValue));
|
|
2910
|
+
onChange?.(numValue, e);
|
|
2881
2911
|
};
|
|
2882
2912
|
useEffect(() => {
|
|
2883
|
-
|
|
2913
|
+
setInputValue(value === undefined || value === null ? "" : String(value));
|
|
2884
2914
|
}, [value]);
|
|
2885
2915
|
const inputProps = {
|
|
2886
2916
|
ref,
|
|
2887
2917
|
name,
|
|
2888
2918
|
disabled,
|
|
2889
|
-
value:
|
|
2919
|
+
value: inputValue,
|
|
2890
2920
|
className: "i-input i-input-number",
|
|
2891
2921
|
onChange: handleChange,
|
|
2922
|
+
onKeyDown: (e) => {
|
|
2923
|
+
e.code === "Enter" && onEnter?.(e);
|
|
2924
|
+
},
|
|
2925
|
+
onInput,
|
|
2926
|
+
onBlur: handleBlur,
|
|
2892
2927
|
...restProps,
|
|
2893
2928
|
};
|
|
2894
2929
|
return (jsx(InputContainer, { label: label, labelInline: labelInline, className: className, style: { width, ...style }, tip: message ?? tip, status: status, children: jsxs("div", { className: classNames("i-input-item", {
|
|
@@ -2899,9 +2934,7 @@ const Number$1 = (props) => {
|
|
|
2899
2934
|
|
|
2900
2935
|
const Range = (props) => {
|
|
2901
2936
|
const { label, name, value, labelInline, min = -Infinity, max = Infinity, type, className, status = "normal", message, tip, append, prepend, step = 1, width, thousand, precision, hideControl, placeholder, border, autoSwitch, onChange, onBlur, style, ...restProps } = props;
|
|
2902
|
-
const
|
|
2903
|
-
value,
|
|
2904
|
-
});
|
|
2937
|
+
const [rangeValue, setRangeValue] = useState(value);
|
|
2905
2938
|
const getRangeNumber = (v) => clamp(v, min, max);
|
|
2906
2939
|
const getFormatNumber = (v) => formatNumber(v, { precision, thousand });
|
|
2907
2940
|
const formatInputValue = (v) => {
|
|
@@ -2914,31 +2947,31 @@ const Range = (props) => {
|
|
|
2914
2947
|
const handleChange = (e, i) => {
|
|
2915
2948
|
const { value } = e.target;
|
|
2916
2949
|
const v = formatInputValue(value.replace(/[^\d\.-]/g, ""));
|
|
2917
|
-
const range = Array.isArray(
|
|
2950
|
+
const range = Array.isArray(rangeValue) ? [...rangeValue] : [];
|
|
2918
2951
|
range[i] = v;
|
|
2919
|
-
|
|
2952
|
+
setRangeValue(range);
|
|
2920
2953
|
onChange?.(range, e);
|
|
2921
2954
|
};
|
|
2922
2955
|
const handleOperate = (e, param, i) => {
|
|
2923
2956
|
e.preventDefault();
|
|
2924
2957
|
e.stopPropagation();
|
|
2925
|
-
const range = Array.isArray(
|
|
2958
|
+
const range = Array.isArray(rangeValue) ? [...rangeValue] : [];
|
|
2926
2959
|
const value = formatInputValue(range[i]) ?? 0;
|
|
2927
2960
|
const result = getRangeNumber(+value + param);
|
|
2928
2961
|
range[i] = getFormatNumber(result);
|
|
2929
|
-
|
|
2962
|
+
setRangeValue(range);
|
|
2930
2963
|
onChange?.(range, e);
|
|
2931
2964
|
};
|
|
2932
2965
|
const handleSwitch = (e) => {
|
|
2933
2966
|
e?.preventDefault();
|
|
2934
2967
|
e?.stopPropagation();
|
|
2935
|
-
const range =
|
|
2968
|
+
const range = Array.isArray(rangeValue) ? [...rangeValue] : [];
|
|
2936
2969
|
[range[0], range[1]] = [range[1], range[0]];
|
|
2937
|
-
|
|
2970
|
+
setRangeValue(range);
|
|
2938
2971
|
onChange?.(range);
|
|
2939
2972
|
};
|
|
2940
2973
|
useEffect(() => {
|
|
2941
|
-
|
|
2974
|
+
setRangeValue(value);
|
|
2942
2975
|
}, [value]);
|
|
2943
2976
|
const inputProps = {
|
|
2944
2977
|
name,
|
|
@@ -2948,7 +2981,7 @@ const Range = (props) => {
|
|
|
2948
2981
|
const handleBlur = () => {
|
|
2949
2982
|
if (!autoSwitch)
|
|
2950
2983
|
return;
|
|
2951
|
-
const range = Array.isArray(
|
|
2984
|
+
const range = Array.isArray(rangeValue) ? rangeValue : [];
|
|
2952
2985
|
if (range.length < 2)
|
|
2953
2986
|
return;
|
|
2954
2987
|
const [left, right] = range.map(Number);
|
|
@@ -2959,18 +2992,16 @@ const Range = (props) => {
|
|
|
2959
2992
|
return (jsx(InputContainer, { label: label, labelInline: labelInline, className: className, style: { width, ...style }, tip: message ?? tip, status: status, children: jsxs("div", { className: classNames("i-input-item", {
|
|
2960
2993
|
[`i-input-${status}`]: status !== "normal",
|
|
2961
2994
|
"i-input-borderless": !border,
|
|
2962
|
-
}), children: [prepend && jsx("div", { className: 'i-input-prepend', children: prepend }), !hideControl && (jsx(Helpericon, { active: true, icon: jsx(MinusRound, {}), onClick: (e) => handleOperate(e, -step, 0) })), jsx("input", { value:
|
|
2995
|
+
}), children: [prepend && jsx("div", { className: 'i-input-prepend', children: prepend }), !hideControl && (jsx(Helpericon, { active: true, icon: jsx(MinusRound, {}), onClick: (e) => handleOperate(e, -step, 0) })), jsx("input", { value: rangeValue?.[0] || "", placeholder: placeholder?.[0], ...inputProps, onBlur: handleBlur, onChange: (e) => handleChange(e, 0) }), !hideControl && (jsx(Helpericon, { active: true, icon: jsx(PlusRound, {}), onClick: (e) => handleOperate(e, step, 0) })), jsx(Helpericon, { active: true, icon: jsx(SyncAltRound, {}), style: { margin: 0 }, onClick: handleSwitch }), !hideControl && (jsx(Helpericon, { active: true, icon: jsx(MinusRound, {}), onClick: (e) => handleOperate(e, -step, 1) })), jsx("input", { value: rangeValue?.[1] || "", placeholder: placeholder?.[1], ...inputProps, onBlur: handleBlur, onChange: (e) => handleChange(e, 1) }), !hideControl && (jsx(Helpericon, { active: true, icon: jsx(PlusRound, {}), onClick: (e) => handleOperate(e, step, 1) })), append && jsx("div", { className: 'i-input-append', children: append })] }) }));
|
|
2963
2996
|
};
|
|
2964
2997
|
|
|
2965
2998
|
const Textarea = (props) => {
|
|
2966
2999
|
const { ref, label, name, value = "", labelInline, className, status = "normal", message, tip, autoSize, border, width, style, onChange, onEnter, ...restProps } = props;
|
|
2967
|
-
const
|
|
2968
|
-
value,
|
|
2969
|
-
});
|
|
3000
|
+
const [textareaValue, setTextareaValue] = useState(value);
|
|
2970
3001
|
const refTextarea = useRef(null);
|
|
2971
3002
|
const handleChange = (e) => {
|
|
2972
3003
|
const v = e.target.value;
|
|
2973
|
-
|
|
3004
|
+
setTextareaValue(v);
|
|
2974
3005
|
const ta = refTextarea.current;
|
|
2975
3006
|
if (autoSize && ta) {
|
|
2976
3007
|
ta.style.height = `${ta.scrollHeight}px`;
|
|
@@ -2984,7 +3015,7 @@ const Textarea = (props) => {
|
|
|
2984
3015
|
onEnter?.(e);
|
|
2985
3016
|
};
|
|
2986
3017
|
useEffect(() => {
|
|
2987
|
-
|
|
3018
|
+
setTextareaValue(value);
|
|
2988
3019
|
}, [value]);
|
|
2989
3020
|
useImperativeHandle(ref, () => {
|
|
2990
3021
|
return {
|
|
@@ -2994,7 +3025,7 @@ const Textarea = (props) => {
|
|
|
2994
3025
|
const inputProps = {
|
|
2995
3026
|
ref: refTextarea,
|
|
2996
3027
|
name,
|
|
2997
|
-
value:
|
|
3028
|
+
value: textareaValue,
|
|
2998
3029
|
className: "i-input i-textarea",
|
|
2999
3030
|
onChange: handleChange,
|
|
3000
3031
|
onKeyDown: handleKeydown,
|
|
@@ -3008,14 +3039,12 @@ const Textarea = (props) => {
|
|
|
3008
3039
|
|
|
3009
3040
|
const Input = ((props) => {
|
|
3010
3041
|
const { ref, type = "text", label, name, value = "", prepend, append, labelInline, className, status = "normal", message, tip, clear, width, hideVisible, border, underline, required, maxLength, onChange, onEnter, onClear, style, ...restProps } = props;
|
|
3011
|
-
const
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
visible: false,
|
|
3015
|
-
});
|
|
3042
|
+
const [inputValue, setInputValue] = useState(value);
|
|
3043
|
+
const [inputType, setInputType] = useState(type);
|
|
3044
|
+
const [visible, setVisible] = useState(false);
|
|
3016
3045
|
const handleChange = (e) => {
|
|
3017
3046
|
const v = e.target.value;
|
|
3018
|
-
|
|
3047
|
+
setInputValue(v);
|
|
3019
3048
|
onChange?.(v, e);
|
|
3020
3049
|
};
|
|
3021
3050
|
const handleKeydown = (e) => {
|
|
@@ -3023,43 +3052,49 @@ const Input = ((props) => {
|
|
|
3023
3052
|
};
|
|
3024
3053
|
const handleHelperClick = () => {
|
|
3025
3054
|
if (type === "password" && !hideVisible) {
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3055
|
+
setVisible((v) => {
|
|
3056
|
+
const next = !v;
|
|
3057
|
+
setInputType(next ? "text" : "password");
|
|
3058
|
+
return next;
|
|
3029
3059
|
});
|
|
3030
3060
|
return;
|
|
3031
3061
|
}
|
|
3032
3062
|
const v = "";
|
|
3063
|
+
setInputValue(v);
|
|
3033
3064
|
onChange?.(v);
|
|
3034
3065
|
onClear?.();
|
|
3035
3066
|
};
|
|
3036
3067
|
const HelperIcon = useMemo(() => {
|
|
3037
3068
|
if (type === "password") {
|
|
3038
|
-
return
|
|
3069
|
+
return visible ? jsx(VisibilityRound, {}) : jsx(VisibilityOffRound, {});
|
|
3039
3070
|
}
|
|
3040
3071
|
return undefined;
|
|
3041
|
-
}, [
|
|
3072
|
+
}, [type, visible]);
|
|
3042
3073
|
useEffect(() => {
|
|
3043
|
-
|
|
3074
|
+
setInputValue(value);
|
|
3044
3075
|
}, [value]);
|
|
3045
3076
|
const inputProps = {
|
|
3046
3077
|
ref,
|
|
3047
|
-
type:
|
|
3078
|
+
type: inputType,
|
|
3048
3079
|
name,
|
|
3049
|
-
value:
|
|
3080
|
+
value: inputValue,
|
|
3050
3081
|
maxLength,
|
|
3051
3082
|
className: classNames("i-input", `i-input-${type}`),
|
|
3052
3083
|
onChange: handleChange,
|
|
3053
3084
|
onKeyDown: handleKeydown,
|
|
3054
3085
|
...restProps,
|
|
3055
3086
|
};
|
|
3056
|
-
|
|
3057
|
-
|
|
3087
|
+
useEffect(() => {
|
|
3088
|
+
setInputType(type);
|
|
3089
|
+
setVisible(false);
|
|
3090
|
+
}, [type]);
|
|
3091
|
+
const clearable = clear && inputValue;
|
|
3092
|
+
const showHelper = type === "password" && !!inputValue;
|
|
3058
3093
|
return (jsx(InputContainer, { label: label, labelInline: labelInline, className: className, style: { width, ...style }, tip: message ?? tip, status: status, required: required, children: jsxs("div", { className: classNames("i-input-item", {
|
|
3059
3094
|
[`i-input-${status}`]: status !== "normal",
|
|
3060
3095
|
"i-input-borderless": !border,
|
|
3061
3096
|
"i-input-underline": underline,
|
|
3062
|
-
}), children: [prepend && jsx("div", { className: 'i-input-prepend', children: prepend }), jsx("input", { ...inputProps }), maxLength &&
|
|
3097
|
+
}), children: [prepend && jsx("div", { className: 'i-input-prepend', children: prepend }), jsx("input", { ...inputProps }), maxLength && inputValue?.length > 0 && (jsxs("span", { className: 'color-8 pr-4 font-sm', children: [inputValue.length, " / ", maxLength] })), jsx(Helpericon, { active: !!clearable || showHelper, icon: HelperIcon, onClick: handleHelperClick }), append && jsx("div", { className: 'i-input-append', children: append })] }) }));
|
|
3063
3098
|
});
|
|
3064
3099
|
Input.Textarea = Textarea;
|
|
3065
3100
|
Input.Number = Number$1;
|
|
@@ -3347,38 +3382,34 @@ const displayValue = (config) => {
|
|
|
3347
3382
|
|
|
3348
3383
|
const Select = (props) => {
|
|
3349
3384
|
const { ref, type = "text", name, label, value = "", placeholder, options = [], multiple, prepend, append, labelInline, style, className, message, status = "normal", hideClear, hideArrow, maxDisplay, border, filter, tip, filterPlaceholder = "...", popupProps, onSelect, onChange, ...restProps } = props;
|
|
3350
|
-
const
|
|
3351
|
-
|
|
3352
|
-
filterValue: "",
|
|
3353
|
-
value,
|
|
3354
|
-
loading: false,
|
|
3355
|
-
});
|
|
3385
|
+
const [filterValue, setFilterValue] = useState("");
|
|
3386
|
+
const [selectedValue, setSelectedValue] = useState(value);
|
|
3356
3387
|
const [active, setActive] = useState(false);
|
|
3357
3388
|
const formattedOptions = useMemo(() => formatOption(options), [options]);
|
|
3358
3389
|
const filterOptions = useMemo(() => {
|
|
3359
|
-
const
|
|
3390
|
+
const fv = filterValue;
|
|
3360
3391
|
if (!fv || !filter)
|
|
3361
3392
|
return formattedOptions;
|
|
3362
3393
|
const filterFn = typeof filter === "function"
|
|
3363
3394
|
? filter
|
|
3364
3395
|
: (opt) => opt.value.includes(fv) || opt.label.includes(fv);
|
|
3365
3396
|
return formattedOptions.filter(filterFn);
|
|
3366
|
-
}, [formattedOptions, filter,
|
|
3397
|
+
}, [formattedOptions, filter, filterValue]);
|
|
3367
3398
|
const changeValue = (v) => {
|
|
3368
|
-
|
|
3399
|
+
setSelectedValue(v);
|
|
3369
3400
|
onChange?.(v);
|
|
3370
3401
|
};
|
|
3371
3402
|
const displayLabel = useMemo(() => {
|
|
3372
3403
|
if (multiple) {
|
|
3373
3404
|
return "";
|
|
3374
3405
|
}
|
|
3375
|
-
const option = formattedOptions.find((opt) => opt.value ===
|
|
3376
|
-
return option ? option.label :
|
|
3377
|
-
}, [
|
|
3406
|
+
const option = formattedOptions.find((opt) => opt.value === selectedValue);
|
|
3407
|
+
return option ? option.label : selectedValue;
|
|
3408
|
+
}, [selectedValue, formattedOptions]);
|
|
3378
3409
|
const handleSelect = (value, option) => {
|
|
3379
3410
|
onSelect?.(value, option);
|
|
3380
3411
|
if (multiple) {
|
|
3381
|
-
const values = [...
|
|
3412
|
+
const values = [...selectedValue];
|
|
3382
3413
|
const i = values.findIndex((v) => v === value);
|
|
3383
3414
|
i > -1 ? values.splice(i, 1) : values.push(value);
|
|
3384
3415
|
changeValue(values);
|
|
@@ -3391,7 +3422,7 @@ const Select = (props) => {
|
|
|
3391
3422
|
setActive(visible);
|
|
3392
3423
|
if (!filter)
|
|
3393
3424
|
return;
|
|
3394
|
-
|
|
3425
|
+
setFilterValue("");
|
|
3395
3426
|
};
|
|
3396
3427
|
const handleHelperClick = (e) => {
|
|
3397
3428
|
e.stopPropagation();
|
|
@@ -3402,34 +3433,34 @@ const Select = (props) => {
|
|
|
3402
3433
|
};
|
|
3403
3434
|
const handleFilterChange = debounce({ delay: 400 }, (e) => {
|
|
3404
3435
|
const v = e.target.value;
|
|
3405
|
-
|
|
3436
|
+
setFilterValue(v);
|
|
3406
3437
|
});
|
|
3407
3438
|
const handleInputChange = (e) => {
|
|
3408
|
-
|
|
3439
|
+
setFilterValue(e.target.value);
|
|
3409
3440
|
};
|
|
3410
3441
|
useEffect(() => {
|
|
3411
|
-
|
|
3442
|
+
setSelectedValue(value);
|
|
3412
3443
|
}, [value]);
|
|
3413
3444
|
const hasValue = multiple
|
|
3414
|
-
?
|
|
3415
|
-
: !!
|
|
3445
|
+
? selectedValue.length > 0
|
|
3446
|
+
: !!selectedValue;
|
|
3416
3447
|
const clearable = !hideClear && active && hasValue;
|
|
3417
3448
|
const text = message ?? tip;
|
|
3418
3449
|
return (jsxs("label", { className: classNames("i-input-label", className, {
|
|
3419
3450
|
"i-input-inline": labelInline,
|
|
3420
|
-
}), style: style, children: [label && jsx("span", { className: 'i-input-label-text', children: label }), jsx(Popup, { position: 'bottom', arrow: false, fitSize: true, offset: 0, ...popupProps, visible: active, trigger: 'none', onVisibleChange: handleVisibleChange, content: jsx(Options, { options: filterOptions, value:
|
|
3451
|
+
}), style: style, children: [label && jsx("span", { className: 'i-input-label-text', children: label }), jsx(Popup, { position: 'bottom', arrow: false, fitSize: true, offset: 0, ...popupProps, visible: active, trigger: 'none', onVisibleChange: handleVisibleChange, content: jsx(Options, { options: filterOptions, value: selectedValue, multiple: multiple, filter: !!filter, filterPlaceholder: filterPlaceholder, onSelect: handleSelect, onFilter: handleFilterChange }), children: jsxs("div", { className: classNames("i-input-item", {
|
|
3421
3452
|
[`i-input-${status}`]: status !== "normal",
|
|
3422
3453
|
"i-input-borderless": !border,
|
|
3423
3454
|
"i-input-focus": active,
|
|
3424
|
-
}), onClick: () => setActive(true), children: [prepend, jsx("input", { ref: ref, type: 'hidden', value:
|
|
3455
|
+
}), onClick: () => setActive(true), children: [prepend, jsx("input", { ref: ref, type: 'hidden', value: selectedValue, ...restProps }), multiple ? (hasValue ? (jsx("div", { className: classNames("i-input i-select", {
|
|
3425
3456
|
"i-select-multiple": multiple,
|
|
3426
3457
|
}), children: displayValue({
|
|
3427
3458
|
options: formattedOptions,
|
|
3428
|
-
value:
|
|
3459
|
+
value: selectedValue,
|
|
3429
3460
|
multiple,
|
|
3430
3461
|
maxDisplay,
|
|
3431
3462
|
onSelect: handleSelect,
|
|
3432
|
-
}) })) : (jsx("input", { className: 'i-input i-select', placeholder: placeholder, readOnly: true }))) : null, !multiple && (jsx("input", { value: active ?
|
|
3463
|
+
}) })) : (jsx("input", { className: 'i-input i-select', placeholder: placeholder, readOnly: true }))) : null, !multiple && (jsx("input", { value: active ? filterValue : displayLabel, className: 'i-input i-select', placeholder: displayLabel || placeholder, onChange: handleInputChange, readOnly: !filter })), jsx(Helpericon, { active: !hideArrow, icon: clearable ? undefined : jsx(UnfoldMoreRound, {}), onClick: handleHelperClick }), append] }) }), text && jsx("span", { className: 'i-input-message', children: text })] }));
|
|
3433
3464
|
};
|
|
3434
3465
|
|
|
3435
3466
|
const ColorMethods = {
|
|
@@ -3439,23 +3470,21 @@ const ColorMethods = {
|
|
|
3439
3470
|
};
|
|
3440
3471
|
function Footer(props) {
|
|
3441
3472
|
const { value, type, onTypeChange, onChange, onOk } = props;
|
|
3442
|
-
const
|
|
3443
|
-
|
|
3444
|
-
type,
|
|
3445
|
-
});
|
|
3473
|
+
const [inputValue, setInputValue] = useState(value);
|
|
3474
|
+
const [colorType, setColorType] = useState(type);
|
|
3446
3475
|
const handleChange = (v) => {
|
|
3447
|
-
|
|
3476
|
+
setInputValue(v);
|
|
3448
3477
|
onChange(v);
|
|
3449
3478
|
};
|
|
3450
3479
|
const handleTypeChange = (t) => {
|
|
3451
|
-
|
|
3480
|
+
setColorType(t);
|
|
3452
3481
|
onTypeChange(t);
|
|
3453
3482
|
};
|
|
3454
3483
|
useEffect(() => {
|
|
3455
|
-
|
|
3456
|
-
|
|
3484
|
+
setInputValue(value);
|
|
3485
|
+
setColorType(type);
|
|
3457
3486
|
}, [value, type]);
|
|
3458
|
-
return (jsxs("div", { className: 'i-colorpicker-footer', children: [jsx(Select, { readOnly: true, hideClear: true, hideArrow: true, style: { width: "5.6em" }, options: ["RGB", "HEX", "HSB"], value:
|
|
3487
|
+
return (jsxs("div", { className: 'i-colorpicker-footer', children: [jsx(Select, { readOnly: true, hideClear: true, hideArrow: true, style: { width: "5.6em" }, options: ["RGB", "HEX", "HSB"], value: colorType, onChange: handleTypeChange }), jsx(Input, { placeholder: 'color', value: inputValue, onChange: handleChange }), jsx(Button, { square: true, onClick: onOk, children: jsx(Icon, { icon: jsx(CheckRound, {}) }) })] }));
|
|
3459
3488
|
}
|
|
3460
3489
|
|
|
3461
3490
|
const Handle = (props) => {
|
|
@@ -3465,48 +3494,51 @@ const Handle = (props) => {
|
|
|
3465
3494
|
|
|
3466
3495
|
function ColorPicker(props) {
|
|
3467
3496
|
const { value, type = "HEX", disabledAlpha, children, usePanel, handle = "both", placeholder = "Colors", popupProps, onChange, } = props;
|
|
3468
|
-
const
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
visible: popupProps?.visible,
|
|
3473
|
-
});
|
|
3497
|
+
const [colorType, setColorType] = useState(type);
|
|
3498
|
+
const [colorValue, setColorValue] = useState(value);
|
|
3499
|
+
const [syncValue, setSyncValue] = useState(value);
|
|
3500
|
+
const [visible, setVisible] = useState(popupProps?.visible);
|
|
3474
3501
|
const handleChange = (target) => {
|
|
3475
|
-
|
|
3502
|
+
setSyncValue(target);
|
|
3476
3503
|
};
|
|
3477
3504
|
const handleComplete = (target) => {
|
|
3478
|
-
const method = ColorMethods[
|
|
3505
|
+
const method = ColorMethods[colorType];
|
|
3479
3506
|
if (target.a !== 1) {
|
|
3480
3507
|
target.a = parseFloat(target.a.toFixed(3));
|
|
3481
3508
|
}
|
|
3482
|
-
|
|
3509
|
+
setColorValue(target[method]?.());
|
|
3483
3510
|
};
|
|
3484
3511
|
const handleVisibleChange = (v) => {
|
|
3485
|
-
|
|
3512
|
+
setVisible(v);
|
|
3486
3513
|
popupProps?.onVisibleChange?.(v);
|
|
3487
3514
|
};
|
|
3488
3515
|
const handleTypeChange = (t) => {
|
|
3489
3516
|
const method = ColorMethods[t];
|
|
3490
|
-
|
|
3491
|
-
|
|
3517
|
+
setColorType(t);
|
|
3518
|
+
setColorValue(syncValue?.[method]?.());
|
|
3492
3519
|
};
|
|
3493
3520
|
const handleValueChange = (v) => {
|
|
3494
|
-
|
|
3495
|
-
|
|
3521
|
+
setColorValue(v);
|
|
3522
|
+
setSyncValue(v);
|
|
3496
3523
|
};
|
|
3497
3524
|
const handleOk = () => {
|
|
3498
|
-
onChange?.(
|
|
3499
|
-
|
|
3525
|
+
onChange?.(colorValue);
|
|
3526
|
+
setVisible(false);
|
|
3500
3527
|
};
|
|
3501
3528
|
useEffect(() => {
|
|
3502
|
-
|
|
3503
|
-
|
|
3529
|
+
setSyncValue(value);
|
|
3530
|
+
setColorValue(value);
|
|
3504
3531
|
}, [value]);
|
|
3532
|
+
useEffect(() => {
|
|
3533
|
+
if (popupProps?.visible !== undefined) {
|
|
3534
|
+
setVisible(popupProps.visible);
|
|
3535
|
+
}
|
|
3536
|
+
}, [popupProps?.visible]);
|
|
3505
3537
|
if (usePanel) {
|
|
3506
3538
|
return jsx(ColorsPanel, { ...props });
|
|
3507
3539
|
}
|
|
3508
|
-
return (jsx(Popup, { trigger: 'click', touchable: true, position: 'bottom', ...popupProps, visible:
|
|
3509
|
-
return (jsxs(Fragment, { children: [panel, jsx(Footer, { value:
|
|
3540
|
+
return (jsx(Popup, { trigger: 'click', touchable: true, position: 'bottom', ...popupProps, visible: visible, content: jsx(ColorsPanel, { value: syncValue, disabledAlpha: disabledAlpha, panelRender: (panel) => {
|
|
3541
|
+
return (jsxs(Fragment, { children: [panel, jsx(Footer, { value: colorValue, type: colorType, onTypeChange: handleTypeChange, onChange: handleValueChange, onOk: handleOk })] }));
|
|
3510
3542
|
}, onChange: handleChange, onChangeComplete: handleComplete }), onVisibleChange: handleVisibleChange, children: children ?? (jsx(Handle, { color: value, handle: handle, placeholder: placeholder })) }));
|
|
3511
3543
|
}
|
|
3512
3544
|
|
|
@@ -3556,61 +3588,56 @@ const YearMonth = (props) => {
|
|
|
3556
3588
|
};
|
|
3557
3589
|
const Panel$1 = (props) => {
|
|
3558
3590
|
const { value, unitYear, unitMonth, renderDate, renderMonth = (m) => m, renderYear = (y) => y, disabledDate, onDateClick, } = props;
|
|
3559
|
-
const
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
selectable: false,
|
|
3565
|
-
});
|
|
3591
|
+
const [today, setToday] = useState(value);
|
|
3592
|
+
const [month, setMonth] = useState(value || dayjs());
|
|
3593
|
+
const [selectedYear, setSelectedYear] = useState(dayjs());
|
|
3594
|
+
const [years, setYears] = useState([]);
|
|
3595
|
+
const [selectable, setSelectable] = useState(false);
|
|
3566
3596
|
const $years = useRef(null);
|
|
3567
3597
|
const handleOperateMonth = (next) => {
|
|
3568
|
-
|
|
3598
|
+
setMonth((m) => m[next ? "add" : "subtract"](1, "month"));
|
|
3569
3599
|
};
|
|
3570
3600
|
const handleChangeDate = (date) => {
|
|
3571
|
-
if (date.isSame(
|
|
3601
|
+
if (date.isSame(today, "day"))
|
|
3572
3602
|
return;
|
|
3573
|
-
if (!date.isSame(
|
|
3574
|
-
|
|
3603
|
+
if (!date.isSame(month, "month")) {
|
|
3604
|
+
setMonth(date);
|
|
3575
3605
|
}
|
|
3576
|
-
|
|
3606
|
+
setToday(date);
|
|
3577
3607
|
onDateClick?.(date);
|
|
3578
3608
|
};
|
|
3579
3609
|
const handleChangeMonth = (month) => {
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
.month(month - 1);
|
|
3583
|
-
state.selectable = false;
|
|
3610
|
+
setMonth((m) => m.year(selectedYear.year()).month(month - 1));
|
|
3611
|
+
setSelectable(false);
|
|
3584
3612
|
};
|
|
3585
3613
|
const getMoreYears = throttle({ interval: 100 }, (e) => {
|
|
3586
3614
|
const isUp = e.deltaY < 0;
|
|
3587
|
-
|
|
3615
|
+
setYears((ys) => ys.map((y) => y + (isUp ? -1 : 1)));
|
|
3588
3616
|
});
|
|
3589
3617
|
useEffect(() => {
|
|
3590
|
-
if (!
|
|
3618
|
+
if (!selectable)
|
|
3591
3619
|
return;
|
|
3592
|
-
|
|
3593
|
-
const y =
|
|
3594
|
-
const
|
|
3595
|
-
|
|
3596
|
-
}, [
|
|
3620
|
+
setSelectedYear(month);
|
|
3621
|
+
const y = month.year();
|
|
3622
|
+
const nextYears = Array.from({ length: 7 }).map((_, i) => y - 3 + i);
|
|
3623
|
+
setYears([...nextYears]);
|
|
3624
|
+
}, [selectable, month]);
|
|
3597
3625
|
useEffect(() => {
|
|
3598
|
-
|
|
3599
|
-
|
|
3626
|
+
setToday(value);
|
|
3627
|
+
setMonth(value || dayjs());
|
|
3600
3628
|
}, [value]);
|
|
3601
|
-
return (jsxs("div", { className: 'i-datepicker', children: [jsxs("div", { className: 'i-datepicker-units', children: [jsx(YearMonth, { value:
|
|
3602
|
-
"i-datepicker-active":
|
|
3629
|
+
return (jsxs("div", { className: 'i-datepicker', children: [jsxs("div", { className: 'i-datepicker-units', children: [jsx(YearMonth, { value: month, unitYear: unitYear, unitMonth: unitMonth, renderMonth: renderMonth, renderYear: renderYear, onClick: () => setSelectable(true) }), jsx("a", { className: 'ml-auto i-datepicker-action', "data-ripple": true, onClick: () => handleOperateMonth(false), children: jsx(Icon, { icon: jsx(KeyboardArrowLeftRound, {}) }) }), jsx("a", { className: 'i-datepicker-action', "data-ripple": true, onClick: () => handleOperateMonth(true), children: jsx(Icon, { icon: jsx(KeyboardArrowRightRound, {}) }) })] }), jsxs("div", { className: classNames("i-datepicker-ym", {
|
|
3630
|
+
"i-datepicker-active": selectable,
|
|
3603
3631
|
}), children: [jsx(Helpericon, { active: true, className: 'i-datepicker-close', onClick: (e) => {
|
|
3604
3632
|
e.stopPropagation();
|
|
3605
|
-
|
|
3606
|
-
} }), jsx("div", { ref: $years, className: 'i-datepicker-years', onWheel: getMoreYears, children:
|
|
3607
|
-
"i-datepicker-active": y ===
|
|
3608
|
-
}), onClick: () => (
|
|
3609
|
-
state.selectedYear.year(y)), children: renderYear(y) }, y))) }), jsx("div", { className: 'i-datepicker-months', children: MONTHS.map((m) => {
|
|
3633
|
+
setSelectable(false);
|
|
3634
|
+
} }), jsx("div", { ref: $years, className: 'i-datepicker-years', onWheel: getMoreYears, children: years.map((y) => (jsx("a", { className: classNames("i-datepicker-year", {
|
|
3635
|
+
"i-datepicker-active": y === selectedYear.year(),
|
|
3636
|
+
}), onClick: () => setSelectedYear((sy) => sy.year(y)), children: renderYear(y) }, y))) }), jsx("div", { className: 'i-datepicker-months', children: MONTHS.map((m) => {
|
|
3610
3637
|
return (jsx("a", { className: classNames("i-datepicker-month", {
|
|
3611
|
-
"i-datepicker-active": m ===
|
|
3638
|
+
"i-datepicker-active": m === month.month() + 1,
|
|
3612
3639
|
}), onClick: () => handleChangeMonth(m), children: renderMonth(m) }, m));
|
|
3613
|
-
}) })] }), jsx(Dates, { value:
|
|
3640
|
+
}) })] }), jsx(Dates, { value: today, month: month, disabledDate: disabledDate, onDateClick: handleChangeDate, renderDate: renderDate })] }));
|
|
3614
3641
|
};
|
|
3615
3642
|
|
|
3616
3643
|
dayjs.extend(customParseFormat);
|
|
@@ -3618,29 +3645,27 @@ const FORMATTYPES = ["YYYY-MM-DD", "YYYY-M-D", "YYYY/MM/DD", "YYYY/M/D"];
|
|
|
3618
3645
|
const FORMAT$1 = "YYYY-MM-DD";
|
|
3619
3646
|
const Datepicker = (props) => {
|
|
3620
3647
|
const { name, value, weeks, format = FORMAT$1, placeholder = props.format ?? FORMAT$1, className, renderDate, renderMonth, renderYear, popupProps, disabledDate, onDateClick, onChange, onBlur, ...restProps } = props;
|
|
3621
|
-
const
|
|
3622
|
-
value,
|
|
3623
|
-
});
|
|
3648
|
+
const [inputValue, setInputValue] = useState(value);
|
|
3624
3649
|
const [active, setActive] = useState(false);
|
|
3625
3650
|
const dayJsValue = useMemo(() => {
|
|
3626
|
-
if (!
|
|
3651
|
+
if (!inputValue)
|
|
3627
3652
|
return null;
|
|
3628
|
-
const date = dayjs(
|
|
3653
|
+
const date = dayjs(inputValue, format, true);
|
|
3629
3654
|
if (date.isValid())
|
|
3630
3655
|
return date;
|
|
3631
3656
|
return null;
|
|
3632
|
-
}, [
|
|
3657
|
+
}, [inputValue, format]);
|
|
3633
3658
|
const handleDateClick = (date) => {
|
|
3634
3659
|
handleChange(date.format(format));
|
|
3635
3660
|
};
|
|
3636
3661
|
const handleChange = (v) => {
|
|
3637
|
-
|
|
3662
|
+
setInputValue(v);
|
|
3638
3663
|
onChange?.(v);
|
|
3639
3664
|
};
|
|
3640
3665
|
const handleSetDate = () => {
|
|
3641
|
-
if (!
|
|
3666
|
+
if (!inputValue)
|
|
3642
3667
|
return;
|
|
3643
|
-
const date = dayjs(
|
|
3668
|
+
const date = dayjs(inputValue, FORMATTYPES, true);
|
|
3644
3669
|
if (date.isValid()) {
|
|
3645
3670
|
handleChange(date.format(format));
|
|
3646
3671
|
return;
|
|
@@ -3656,9 +3681,9 @@ const Datepicker = (props) => {
|
|
|
3656
3681
|
setActive(v);
|
|
3657
3682
|
};
|
|
3658
3683
|
useEffect(() => {
|
|
3659
|
-
|
|
3684
|
+
setInputValue(value);
|
|
3660
3685
|
}, [value]);
|
|
3661
|
-
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start', onVisibleChange: handleVisibleChange, watchResize: true, content: jsx(Panel$1, { value: dayJsValue, weeks: weeks, renderDate: renderDate, renderMonth: renderMonth, renderYear: renderYear, disabledDate: disabledDate, onDateClick: handleDateClick }), ...popupProps, children: jsx(Input, { value:
|
|
3686
|
+
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start', onVisibleChange: handleVisibleChange, watchResize: true, content: jsx(Panel$1, { value: dayJsValue, weeks: weeks, renderDate: renderDate, renderMonth: renderMonth, renderYear: renderYear, disabledDate: disabledDate, onDateClick: handleDateClick }), ...popupProps, children: jsx(Input, { value: inputValue, append: jsx(Icon, { icon: jsx(CalendarMonthTwotone, {}), className: 'i-datepicker-icon', size: '1em' }), placeholder: placeholder, onChange: handleChange, onBlur: handleBlur, onEnter: handleSetDate, className: classNames("i-datepicker-label", className), ...restProps }) }));
|
|
3662
3687
|
};
|
|
3663
3688
|
|
|
3664
3689
|
function Items(props) {
|
|
@@ -3681,12 +3706,10 @@ const UnitMaps = {
|
|
|
3681
3706
|
};
|
|
3682
3707
|
function Panel(props) {
|
|
3683
3708
|
const { value, stepH = 1, stepM = 1, stepS = 1, format, periods, renderItem, onChange, onFallback, } = props;
|
|
3684
|
-
const
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
second: undefined,
|
|
3689
|
-
});
|
|
3709
|
+
const [period, setPeriod] = useState(undefined);
|
|
3710
|
+
const [hour, setHour] = useState(undefined);
|
|
3711
|
+
const [minute, setMinute] = useState(undefined);
|
|
3712
|
+
const [second, setSecond] = useState(undefined);
|
|
3690
3713
|
const [hours, minutes, seconds] = useMemo(() => {
|
|
3691
3714
|
const hasH = format.includes("h");
|
|
3692
3715
|
const hasM = format.includes("m");
|
|
@@ -3702,29 +3725,45 @@ function Panel(props) {
|
|
|
3702
3725
|
: [];
|
|
3703
3726
|
return [hours, minutes, seconds];
|
|
3704
3727
|
}, [stepH, stepM, stepS, format, periods]);
|
|
3705
|
-
const updateValue = () => {
|
|
3728
|
+
const updateValue = (next) => {
|
|
3729
|
+
const nextPeriod = next?.period ?? period;
|
|
3730
|
+
const nextHour = next?.hour ?? hour;
|
|
3731
|
+
const nextMinute = next?.minute ?? minute;
|
|
3732
|
+
const nextSecond = next?.second ?? second;
|
|
3706
3733
|
const reg = /(hh|h){1}|(mm|m){1}|(ss|s){1}/gi;
|
|
3707
3734
|
let result = format.replace(reg, (pattern) => {
|
|
3708
3735
|
const p = pattern.toLowerCase();
|
|
3709
3736
|
const u = UnitMaps[p];
|
|
3710
|
-
const n =
|
|
3737
|
+
const n = u === "hour"
|
|
3738
|
+
? (nextHour ?? 0)
|
|
3739
|
+
: u === "minute"
|
|
3740
|
+
? (nextMinute ?? 0)
|
|
3741
|
+
: (nextSecond ?? 0);
|
|
3711
3742
|
return p.length > 1 && n < 10 ? `0${n ?? 0}` : n ?? 0;
|
|
3712
3743
|
});
|
|
3713
3744
|
if (periods && hours.length > 0) {
|
|
3714
|
-
result = `${
|
|
3745
|
+
result = `${nextPeriod ?? periods[0]} ${result}`;
|
|
3715
3746
|
}
|
|
3716
3747
|
onChange(result);
|
|
3717
3748
|
};
|
|
3718
3749
|
const handleSetTime = (v, unit) => {
|
|
3719
|
-
|
|
3720
|
-
|
|
3750
|
+
const next = { period, hour, minute, second, [unit]: v };
|
|
3751
|
+
if (unit === "period")
|
|
3752
|
+
setPeriod(v);
|
|
3753
|
+
if (unit === "hour")
|
|
3754
|
+
setHour(v);
|
|
3755
|
+
if (unit === "minute")
|
|
3756
|
+
setMinute(v);
|
|
3757
|
+
if (unit === "second")
|
|
3758
|
+
setSecond(v);
|
|
3759
|
+
updateValue(next);
|
|
3721
3760
|
};
|
|
3722
3761
|
useEffect(() => {
|
|
3723
3762
|
let time = value ?? "";
|
|
3724
3763
|
if (periods && hours.length > 0 && value) {
|
|
3725
3764
|
const [p, t] = value.split(" ");
|
|
3726
3765
|
time = t ?? "";
|
|
3727
|
-
|
|
3766
|
+
setPeriod(periods.includes(p) ? p : undefined);
|
|
3728
3767
|
}
|
|
3729
3768
|
const nums = time.match(/\d+/g) ?? [];
|
|
3730
3769
|
if (!nums.length) {
|
|
@@ -3732,40 +3771,41 @@ function Panel(props) {
|
|
|
3732
3771
|
return;
|
|
3733
3772
|
}
|
|
3734
3773
|
let i = 0;
|
|
3774
|
+
const parsed = {
|
|
3775
|
+
hour: undefined,
|
|
3776
|
+
minute: undefined,
|
|
3777
|
+
second: undefined,
|
|
3778
|
+
};
|
|
3735
3779
|
const r = format.replace(/(hh|h)+|(mm|m)+|(ss|s)+/gi, (p) => {
|
|
3736
3780
|
const n = nums[i++] ?? 0;
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
o = Math.min(periods ? 11 : 23, n);
|
|
3740
|
-
}
|
|
3741
|
-
o = Math.min(59, n);
|
|
3742
|
-
state[UnitMaps[p]] = o;
|
|
3781
|
+
const o = Math.min(59, n);
|
|
3782
|
+
parsed[UnitMaps[p]] = o;
|
|
3743
3783
|
return p.length > 1 && o < 10 ? `0${o}` : o;
|
|
3744
3784
|
});
|
|
3785
|
+
setHour(parsed.hour);
|
|
3786
|
+
setMinute(parsed.minute);
|
|
3787
|
+
setSecond(parsed.second);
|
|
3745
3788
|
onFallback(r);
|
|
3746
|
-
}, [value]);
|
|
3747
|
-
return (jsxs("div", { className: 'i-timepicker', children: [hours.length > 0 && (jsxs(Fragment, { children: [periods && (jsx("div", { className: 'i-timepicker-list', children: jsx(Items, { items: periods, active:
|
|
3789
|
+
}, [value, format, hours.length, periods]);
|
|
3790
|
+
return (jsxs("div", { className: 'i-timepicker', children: [hours.length > 0 && (jsxs(Fragment, { children: [periods && (jsx("div", { className: 'i-timepicker-list', children: jsx(Items, { items: periods, active: period, onClick: (p) => handleSetTime(p, "period") }) })), jsx("div", { className: 'i-timepicker-list', children: jsx(Items, { items: hours, active: hour, unit: 'hour', renderItem: renderItem, onClick: (h) => handleSetTime(h, "hour") }) })] })), minutes.length > 0 && (jsx("div", { className: 'i-timepicker-list', children: jsx(Items, { items: minutes, active: minute, unit: 'minute', renderItem: renderItem, onClick: (m) => handleSetTime(m, "minute") }) })), seconds.length > 0 && (jsx("div", { className: 'i-timepicker-list', children: jsx(Items, { items: seconds, active: second, unit: 'second', renderItem: renderItem, onClick: (s) => handleSetTime(s, "second") }) }))] }));
|
|
3748
3791
|
}
|
|
3749
3792
|
|
|
3750
3793
|
const FORMAT = "hh:mm:ss";
|
|
3751
3794
|
function TimePicker(props) {
|
|
3752
3795
|
const { name, value, format = FORMAT, periods, placeholder = props.format ?? FORMAT, className, renderItem, onChange, onBlur, popupProps, ...restProps } = props;
|
|
3753
|
-
const
|
|
3754
|
-
|
|
3755
|
-
safeValue: undefined,
|
|
3756
|
-
});
|
|
3796
|
+
const [timeValue, setTimeValue] = useState(value);
|
|
3797
|
+
const [safeValue, setSafeValue] = useState(undefined);
|
|
3757
3798
|
const [active, setActive] = useState(false);
|
|
3758
3799
|
const handleChange = (v) => {
|
|
3759
|
-
|
|
3800
|
+
setTimeValue(v);
|
|
3760
3801
|
};
|
|
3761
3802
|
const handleFallback = (v) => {
|
|
3762
|
-
|
|
3803
|
+
setSafeValue(v);
|
|
3763
3804
|
};
|
|
3764
3805
|
const handleValidTime = () => {
|
|
3765
|
-
if (!
|
|
3806
|
+
if (!timeValue)
|
|
3766
3807
|
return;
|
|
3767
|
-
|
|
3768
|
-
handleChange(state.safeValue);
|
|
3808
|
+
setTimeValue(safeValue);
|
|
3769
3809
|
};
|
|
3770
3810
|
const handleBlur = (e) => {
|
|
3771
3811
|
onBlur?.(e);
|
|
@@ -3776,9 +3816,9 @@ function TimePicker(props) {
|
|
|
3776
3816
|
setActive(v);
|
|
3777
3817
|
};
|
|
3778
3818
|
useEffect(() => {
|
|
3779
|
-
|
|
3819
|
+
setTimeValue(value);
|
|
3780
3820
|
}, [value]);
|
|
3781
|
-
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start', watchResize: true, ...popupProps, onVisibleChange: handleVisibleChange, content: jsx(Panel, { value:
|
|
3821
|
+
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start', watchResize: true, ...popupProps, onVisibleChange: handleVisibleChange, content: jsx(Panel, { value: timeValue, format: format, periods: periods, renderItem: renderItem, onChange: handleChange, onFallback: handleFallback }), children: jsx(Input, { value: timeValue, placeholder: placeholder, append: jsx(Icon, { icon: jsx(AccessTimeRound, {}), className: 'i-timepicker-icon', size: '1em' }), onChange: handleChange, onBlur: handleBlur, className: classNames("i-timepicker-label", className), ...restProps }) }));
|
|
3782
3822
|
}
|
|
3783
3823
|
|
|
3784
3824
|
const defaultOk = {
|
|
@@ -3838,16 +3878,14 @@ function RadioItem(props) {
|
|
|
3838
3878
|
|
|
3839
3879
|
function Radio(props) {
|
|
3840
3880
|
const { label, name, options, value, type = "default", status = "normal", message, optionInline = true, labelInline, disabled, required, className, renderItem, onChange, } = props;
|
|
3841
|
-
const
|
|
3842
|
-
value,
|
|
3843
|
-
});
|
|
3881
|
+
const [selectedValue, setSelectedValue] = useState(value);
|
|
3844
3882
|
const formattedOptions = useMemo(() => formatOption(options), [options]);
|
|
3845
3883
|
const handleChange = (value, e) => {
|
|
3846
|
-
|
|
3884
|
+
setSelectedValue(value);
|
|
3847
3885
|
onChange?.(value, e);
|
|
3848
3886
|
};
|
|
3849
3887
|
useEffect(() => {
|
|
3850
|
-
|
|
3888
|
+
setSelectedValue(value);
|
|
3851
3889
|
}, [value]);
|
|
3852
3890
|
return (jsxs("div", { className: classNames("i-radio i-input-label", {
|
|
3853
3891
|
[`i-radio-${status}`]: status !== "normal",
|
|
@@ -3856,7 +3894,7 @@ function Radio(props) {
|
|
|
3856
3894
|
"i-options-block": !optionInline,
|
|
3857
3895
|
"i-radio-options-button": type === "button",
|
|
3858
3896
|
}), children: formattedOptions.map((option) => {
|
|
3859
|
-
const checked =
|
|
3897
|
+
const checked = selectedValue === option.value;
|
|
3860
3898
|
return (jsx(RadioItem, { name: name, value: option.value, checked: checked, type: type, disabled: disabled || option.disabled, onChange: handleChange, children: renderItem ?? option.label }, option.value));
|
|
3861
3899
|
}) })] }));
|
|
3862
3900
|
}
|
|
@@ -4313,25 +4351,23 @@ const Tabs = ((props) => {
|
|
|
4313
4351
|
const barRef = useRef(null);
|
|
4314
4352
|
const navsRef = useRef(null);
|
|
4315
4353
|
const contentsRef = useRef(new Map());
|
|
4316
|
-
const
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
tabs: [],
|
|
4324
|
-
});
|
|
4354
|
+
const [activeKey, setActiveKey] = useState(active);
|
|
4355
|
+
const [prevActiveKey, setPrevActiveKey] = useState(undefined);
|
|
4356
|
+
const [barStyle, setBarStyle] = useState({});
|
|
4357
|
+
const [cachedTabs, setCachedTabs] = useState([]);
|
|
4358
|
+
const [overflow, setOverflow] = useState(false);
|
|
4359
|
+
const [moreTabs, setMoreTabs] = useState([]);
|
|
4360
|
+
const [tabs, setTabs] = useState([]);
|
|
4325
4361
|
const { observe, unobserve } = useIntersectionObserver();
|
|
4326
4362
|
const size = useSize(navsRef);
|
|
4327
4363
|
useEffect(() => {
|
|
4328
4364
|
contentsRef.current.clear();
|
|
4329
4365
|
if (!items) {
|
|
4330
4366
|
if (!children) {
|
|
4331
|
-
|
|
4367
|
+
setTabs([]);
|
|
4332
4368
|
return;
|
|
4333
4369
|
}
|
|
4334
|
-
|
|
4370
|
+
setTabs(Children.map(children, (node, i) => {
|
|
4335
4371
|
const { key, props: nodeProps } = node;
|
|
4336
4372
|
const { title, children: tabChildren, content, keepDOM, closable, } = nodeProps;
|
|
4337
4373
|
const tabKey = String(key ?? i);
|
|
@@ -4342,10 +4378,10 @@ const Tabs = ((props) => {
|
|
|
4342
4378
|
keepDOM,
|
|
4343
4379
|
closable,
|
|
4344
4380
|
};
|
|
4345
|
-
});
|
|
4381
|
+
}) ?? []);
|
|
4346
4382
|
return;
|
|
4347
4383
|
}
|
|
4348
|
-
|
|
4384
|
+
setTabs(items.map((item, i) => {
|
|
4349
4385
|
if (["string", "number"].includes(typeof item)) {
|
|
4350
4386
|
const key = String(item);
|
|
4351
4387
|
return { key, title: item };
|
|
@@ -4357,90 +4393,99 @@ const Tabs = ((props) => {
|
|
|
4357
4393
|
...rest,
|
|
4358
4394
|
key,
|
|
4359
4395
|
};
|
|
4360
|
-
});
|
|
4396
|
+
}));
|
|
4361
4397
|
}, [children, items]);
|
|
4362
4398
|
const add = (tab) => {
|
|
4363
|
-
const tkey = String(tab.key ??
|
|
4364
|
-
const i =
|
|
4399
|
+
const tkey = String(tab.key ?? tabs.length);
|
|
4400
|
+
const i = tabs.findIndex((t) => t.key === tkey);
|
|
4365
4401
|
if (i > -1) {
|
|
4366
|
-
open(
|
|
4402
|
+
open(tabs[i].key ?? `${i}`);
|
|
4367
4403
|
return;
|
|
4368
4404
|
}
|
|
4369
4405
|
contentsRef.current.set(tkey, tab.content);
|
|
4370
4406
|
const { content, ...rest } = tab;
|
|
4371
|
-
|
|
4407
|
+
setTabs((ts) => [...ts, { ...rest, key: tkey }]);
|
|
4372
4408
|
open(tkey);
|
|
4373
4409
|
};
|
|
4374
4410
|
const close = (key) => {
|
|
4375
|
-
const i =
|
|
4411
|
+
const i = tabs.findIndex((t) => t.key === key);
|
|
4376
4412
|
if (i < 0)
|
|
4377
4413
|
return;
|
|
4378
4414
|
contentsRef.current.delete(key);
|
|
4379
|
-
|
|
4380
|
-
|
|
4415
|
+
const nextTabs = [...tabs];
|
|
4416
|
+
nextTabs.splice(i, 1);
|
|
4417
|
+
setTabs(nextTabs);
|
|
4418
|
+
if (activeKey !== key)
|
|
4381
4419
|
return;
|
|
4382
|
-
const next =
|
|
4383
|
-
open(
|
|
4420
|
+
const next = nextTabs[i] || nextTabs[i - 1];
|
|
4421
|
+
open(prevActiveKey ?? next?.key ?? "");
|
|
4384
4422
|
};
|
|
4385
4423
|
const open = (key) => {
|
|
4386
|
-
if (key ===
|
|
4424
|
+
if (key === activeKey) {
|
|
4387
4425
|
if (!toggable)
|
|
4388
4426
|
return;
|
|
4389
4427
|
onTabChange?.(undefined, key);
|
|
4390
|
-
|
|
4391
|
-
|
|
4428
|
+
setActiveKey(undefined);
|
|
4429
|
+
setBarStyle({
|
|
4392
4430
|
height: 0,
|
|
4393
4431
|
width: 0,
|
|
4394
|
-
};
|
|
4432
|
+
});
|
|
4395
4433
|
return;
|
|
4396
4434
|
}
|
|
4397
|
-
|
|
4398
|
-
onTabChange?.(key,
|
|
4399
|
-
|
|
4435
|
+
setPrevActiveKey(activeKey);
|
|
4436
|
+
onTabChange?.(key, activeKey);
|
|
4437
|
+
setActiveKey(key);
|
|
4400
4438
|
};
|
|
4401
4439
|
useEffect(() => {
|
|
4402
4440
|
if (!size || hideMore || !observe)
|
|
4403
4441
|
return;
|
|
4404
4442
|
const { scrollHeight, scrollWidth } = navsRef.current;
|
|
4405
4443
|
const { width, height } = size;
|
|
4406
|
-
|
|
4407
|
-
|
|
4444
|
+
const nextOverflow = scrollHeight > height || scrollWidth > width;
|
|
4445
|
+
setOverflow(nextOverflow);
|
|
4446
|
+
if (!nextOverflow)
|
|
4408
4447
|
return;
|
|
4409
4448
|
navRefs.current.map((nav, i) => {
|
|
4410
4449
|
if (!nav)
|
|
4411
4450
|
return;
|
|
4412
4451
|
observe(nav, (tar, visible) => {
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4452
|
+
setTabs((ts) => {
|
|
4453
|
+
if (!ts[i])
|
|
4454
|
+
return ts;
|
|
4455
|
+
const nextTabs = ts.map((t, idx) => idx === i ? { ...t, intersecting: visible } : t);
|
|
4456
|
+
setMoreTabs(nextTabs.filter((tab) => !tab.intersecting));
|
|
4457
|
+
return nextTabs;
|
|
4458
|
+
});
|
|
4417
4459
|
});
|
|
4418
4460
|
});
|
|
4419
|
-
}, [size, hideMore,
|
|
4461
|
+
}, [size, hideMore, tabs.length, observe]);
|
|
4420
4462
|
useEffect(() => {
|
|
4421
|
-
if (!bar || type === "pane" ||
|
|
4463
|
+
if (!bar || type === "pane" || activeKey === undefined) {
|
|
4422
4464
|
return;
|
|
4423
4465
|
}
|
|
4424
|
-
const index =
|
|
4466
|
+
const index = tabs.findIndex((tab) => tab.key === activeKey);
|
|
4425
4467
|
setTimeout(() => {
|
|
4426
4468
|
const nav = navRefs.current[index];
|
|
4427
4469
|
if (!nav)
|
|
4428
4470
|
return;
|
|
4429
|
-
if (
|
|
4430
|
-
|
|
4431
|
-
|
|
4471
|
+
if (tabs[index]?.keepDOM && activeKey) {
|
|
4472
|
+
setCachedTabs((keys) => {
|
|
4473
|
+
if (keys.includes(activeKey))
|
|
4474
|
+
return keys;
|
|
4475
|
+
return [activeKey, ...keys];
|
|
4476
|
+
});
|
|
4432
4477
|
}
|
|
4433
4478
|
const { offsetHeight, offsetLeft, offsetTop, offsetWidth } = nav;
|
|
4434
4479
|
const isLine = type === "line";
|
|
4435
|
-
|
|
4480
|
+
setBarStyle({
|
|
4436
4481
|
height: !vertical && isLine ? ".25em" : offsetHeight,
|
|
4437
4482
|
width: vertical && isLine ? ".25em" : offsetWidth,
|
|
4438
4483
|
transform: `translate(${offsetLeft}px, ${offsetTop}px)`,
|
|
4439
|
-
};
|
|
4484
|
+
});
|
|
4440
4485
|
}, 16);
|
|
4441
|
-
}, [
|
|
4486
|
+
}, [activeKey, bar, size, tabs, type, vertical]);
|
|
4442
4487
|
useEffect(() => {
|
|
4443
|
-
if (active === undefined ||
|
|
4488
|
+
if (active === undefined || activeKey === active)
|
|
4444
4489
|
return;
|
|
4445
4490
|
open(active);
|
|
4446
4491
|
}, [active]);
|
|
@@ -4450,7 +4495,7 @@ const Tabs = ((props) => {
|
|
|
4450
4495
|
return () => {
|
|
4451
4496
|
navRefs.current?.map(unobserve);
|
|
4452
4497
|
};
|
|
4453
|
-
}, [
|
|
4498
|
+
}, [tabs.length, hideMore, unobserve]);
|
|
4454
4499
|
useEffect(() => {
|
|
4455
4500
|
if (!navsRef.current || vertical)
|
|
4456
4501
|
return;
|
|
@@ -4480,26 +4525,26 @@ const Tabs = ((props) => {
|
|
|
4480
4525
|
}));
|
|
4481
4526
|
return (jsxs("div", { className: classNames("i-tabs", { flex: vertical, [`i-tabs-${type}`]: type !== "default" }, className), ...rest, children: [jsxs("div", { className: classNames("i-tab-navs-container", {
|
|
4482
4527
|
"i-tab-navs-vertical": vertical,
|
|
4483
|
-
}), children: [prepend, jsxs("div", { ref: navsRef, className: classNames("i-tab-navs", `justify-${navsJustify}`), children: [
|
|
4528
|
+
}), children: [prepend, jsxs("div", { ref: navsRef, className: classNames("i-tab-navs", `justify-${navsJustify}`), children: [tabs.map((tab, i) => {
|
|
4484
4529
|
const { title, key = `${i}`, closable } = tab;
|
|
4485
4530
|
return (jsxs("a", { ref: (ref) => (navRefs.current[i] = ref), className: classNames("i-tab-nav", {
|
|
4486
|
-
"i-tab-active":
|
|
4531
|
+
"i-tab-active": activeKey === key,
|
|
4487
4532
|
}), onClick: () => open(key), children: [title, closable && (jsx(Helpericon, { as: 'i', active: true, className: 'i-tab-nav-close', onClick: (e) => {
|
|
4488
4533
|
e.stopPropagation();
|
|
4489
4534
|
close(key);
|
|
4490
4535
|
} }))] }, key));
|
|
4491
|
-
}), bar && (jsx("span", { ref: barRef, className: classNames("i-tab-navs-bar", barClass), style:
|
|
4536
|
+
}), bar && (jsx("span", { ref: barRef, className: classNames("i-tab-navs-bar", barClass), style: barStyle }))] }), !hideMore && overflow && moreTabs.length > 0 && (jsx(Popup, { arrow: false, position: vertical ? "right" : "bottom", align: 'end', touchable: true, hideDelay: 500, content: jsx("div", { className: 'i-tabs-morelist pd-4', children: moreTabs.map((tab, i) => {
|
|
4492
4537
|
const { key = `${i}`, title } = tab;
|
|
4493
|
-
const isActive =
|
|
4538
|
+
const isActive = activeKey === key;
|
|
4494
4539
|
return (jsx("a", { className: classNames("i-tab-nav", {
|
|
4495
4540
|
"i-tab-active": isActive,
|
|
4496
4541
|
}), onClick: () => open(key), children: title }, key));
|
|
4497
|
-
}) }), children: renderMore(
|
|
4542
|
+
}) }), children: renderMore(moreTabs) })), append] }), jsx("div", { className: 'i-tab-contents', children: tabs.map((tab, i) => {
|
|
4498
4543
|
const key = tab.key ?? `${i}`;
|
|
4499
4544
|
const content = contentsRef.current.get(key);
|
|
4500
|
-
const isActive =
|
|
4545
|
+
const isActive = activeKey === key;
|
|
4501
4546
|
const show = isActive ||
|
|
4502
|
-
(key !== undefined &&
|
|
4547
|
+
(key !== undefined && cachedTabs.includes(key));
|
|
4503
4548
|
return (show && (jsx("div", { className: classNames("i-tab-content", {
|
|
4504
4549
|
"i-tab-active": isActive,
|
|
4505
4550
|
}), children: content }, key)));
|
|
@@ -4578,14 +4623,12 @@ const defaultNodeProps = {
|
|
|
4578
4623
|
};
|
|
4579
4624
|
const Tree = (props) => {
|
|
4580
4625
|
const { data = [], ref, selected, checked = [], disabledRelated, nodeProps, onItemSelect, onItemCheck, ...restProps } = props;
|
|
4581
|
-
const
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
nodeMaps: new Map(),
|
|
4586
|
-
});
|
|
4626
|
+
const [selectedKey, setSelectedKey] = useState(selected);
|
|
4627
|
+
const [checkedKeys, setCheckedKeys] = useState(checked);
|
|
4628
|
+
const [partofs, setPartofs] = useState({});
|
|
4629
|
+
const nodeMapsRef = useRef(new Map());
|
|
4587
4630
|
const oNodeProps = Object.assign({}, defaultNodeProps, nodeProps);
|
|
4588
|
-
const isChecked = (key) =>
|
|
4631
|
+
const isChecked = (key) => checkedKeys.includes(key || "");
|
|
4589
4632
|
const checkItem = (item, checked, direction) => {
|
|
4590
4633
|
const { key = "", parent, children } = item;
|
|
4591
4634
|
const shouldChanged = { [key]: checked };
|
|
@@ -4637,29 +4680,30 @@ const Tree = (props) => {
|
|
|
4637
4680
|
const handleCheck = (item, checked) => {
|
|
4638
4681
|
const [shouldChanged, partofs] = checkItem(item, checked);
|
|
4639
4682
|
const changedKeys = Object.keys(shouldChanged);
|
|
4640
|
-
|
|
4641
|
-
? Array.from(new Set([...
|
|
4642
|
-
:
|
|
4643
|
-
|
|
4644
|
-
|
|
4683
|
+
const nextChecked = checked
|
|
4684
|
+
? Array.from(new Set([...checkedKeys, ...changedKeys]))
|
|
4685
|
+
: checkedKeys.filter((k) => !changedKeys.includes(k));
|
|
4686
|
+
setCheckedKeys(nextChecked);
|
|
4687
|
+
setPartofs((p) => ({ ...p, ...partofs }));
|
|
4688
|
+
onItemCheck?.(item, checked, nextChecked);
|
|
4645
4689
|
};
|
|
4646
4690
|
const handleSelect = (key, item) => {
|
|
4647
4691
|
if (!props.selectable)
|
|
4648
4692
|
return;
|
|
4649
|
-
|
|
4693
|
+
setSelectedKey(key);
|
|
4650
4694
|
onItemSelect?.(key, item);
|
|
4651
4695
|
};
|
|
4652
4696
|
useEffect(() => {
|
|
4653
4697
|
if (selected === undefined)
|
|
4654
4698
|
return;
|
|
4655
|
-
|
|
4699
|
+
setSelectedKey(selected);
|
|
4656
4700
|
}, [selected]);
|
|
4657
4701
|
useEffect(() => {
|
|
4658
|
-
|
|
4702
|
+
nodeMapsRef.current.clear();
|
|
4659
4703
|
const { key, children } = oNodeProps;
|
|
4660
4704
|
const recursive = (nodes) => {
|
|
4661
4705
|
nodes.map((o) => {
|
|
4662
|
-
|
|
4706
|
+
nodeMapsRef.current.set(o[key], o);
|
|
4663
4707
|
o[children]?.length > 0 && recursive(o[children]);
|
|
4664
4708
|
});
|
|
4665
4709
|
};
|
|
@@ -4669,22 +4713,22 @@ const Tree = (props) => {
|
|
|
4669
4713
|
return {
|
|
4670
4714
|
getChecked: () => {
|
|
4671
4715
|
const items = [];
|
|
4672
|
-
|
|
4673
|
-
const item =
|
|
4716
|
+
checkedKeys.map((k) => {
|
|
4717
|
+
const item = nodeMapsRef.current.get(k);
|
|
4674
4718
|
items.push(item);
|
|
4675
4719
|
});
|
|
4676
|
-
return [
|
|
4720
|
+
return [checkedKeys, items];
|
|
4677
4721
|
},
|
|
4678
4722
|
getSelected: () => {
|
|
4679
|
-
const item =
|
|
4680
|
-
return [
|
|
4723
|
+
const item = nodeMapsRef.current.get(selectedKey);
|
|
4724
|
+
return [selectedKey, item];
|
|
4681
4725
|
},
|
|
4682
4726
|
getPartofs: () => {
|
|
4683
4727
|
const items = [];
|
|
4684
|
-
const keys = Object.keys(
|
|
4685
|
-
const indeterminate =
|
|
4728
|
+
const keys = Object.keys(partofs).filter((k) => {
|
|
4729
|
+
const indeterminate = partofs[k];
|
|
4686
4730
|
if (indeterminate) {
|
|
4687
|
-
const item =
|
|
4731
|
+
const item = nodeMapsRef.current.get(k);
|
|
4688
4732
|
items.push(item);
|
|
4689
4733
|
}
|
|
4690
4734
|
return indeterminate;
|
|
@@ -4693,7 +4737,7 @@ const Tree = (props) => {
|
|
|
4693
4737
|
},
|
|
4694
4738
|
};
|
|
4695
4739
|
});
|
|
4696
|
-
return (jsx(TreeList, { data: data, selected:
|
|
4740
|
+
return (jsx(TreeList, { data: data, selected: selectedKey, checked: checkedKeys, partofs: partofs, nodeProps: oNodeProps, onItemCheck: handleCheck, onItemSelect: handleSelect, ...restProps }));
|
|
4697
4741
|
};
|
|
4698
4742
|
|
|
4699
4743
|
const ListContainer = (props) => {
|
|
@@ -4746,12 +4790,8 @@ const FileListItem = (props) => {
|
|
|
4746
4790
|
|
|
4747
4791
|
const Upload = (props) => {
|
|
4748
4792
|
const { ref, label, labelInline, value, files = [], initialFiles, placeholder, status = "normal", message, className, style, children, defaultButtonProps, mode = "default", cardSize = "4em", disabled, sortable, limit = props.multiple ? Infinity : 1, multiple, renderItem, shouldUpload = () => true, uploader, onChange, onFilesChange, onUpload, ...restProps } = props;
|
|
4749
|
-
const
|
|
4750
|
-
|
|
4751
|
-
value,
|
|
4752
|
-
status,
|
|
4753
|
-
message,
|
|
4754
|
-
});
|
|
4793
|
+
const [fileList, setFileListState] = useState(files);
|
|
4794
|
+
const [uploadMessage, setUploadMessage] = useState(message);
|
|
4755
4795
|
const inputRef = useRef(null);
|
|
4756
4796
|
const preview = usePreview();
|
|
4757
4797
|
const defBtnProps = Object.assign({
|
|
@@ -4769,7 +4809,7 @@ const Upload = (props) => {
|
|
|
4769
4809
|
}, [mode, children]);
|
|
4770
4810
|
const handleChange = (e) => {
|
|
4771
4811
|
const files = Array.from(e.target.files || []);
|
|
4772
|
-
const
|
|
4812
|
+
const before = fileList;
|
|
4773
4813
|
const changed = [];
|
|
4774
4814
|
files.map((f) => {
|
|
4775
4815
|
const { id, name, size, type } = f;
|
|
@@ -4786,21 +4826,20 @@ const Upload = (props) => {
|
|
|
4786
4826
|
!same && changed.push(f);
|
|
4787
4827
|
});
|
|
4788
4828
|
const after = [...before, ...changed];
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
onChange?.(state.files, e);
|
|
4829
|
+
const last = after.at(-1);
|
|
4830
|
+
const nextFiles = multiple ? after.slice(0, limit) : last ? [last] : [];
|
|
4831
|
+
setFileListState(nextFiles);
|
|
4832
|
+
setUploadMessage(message);
|
|
4833
|
+
onFilesChange?.(nextFiles, changed, e);
|
|
4834
|
+
onChange?.(nextFiles, e);
|
|
4796
4835
|
handleUpload(changed);
|
|
4797
4836
|
inputRef.current && (inputRef.current.value = "");
|
|
4798
4837
|
};
|
|
4799
4838
|
const handleRemove = (i) => {
|
|
4800
|
-
const [...files] =
|
|
4839
|
+
const [...files] = fileList;
|
|
4801
4840
|
const changed = files.splice(i, 1);
|
|
4802
4841
|
URL.revokeObjectURL(changed[0]?.src || "");
|
|
4803
|
-
|
|
4842
|
+
setFileListState(files);
|
|
4804
4843
|
onFilesChange?.(files, changed);
|
|
4805
4844
|
onChange?.(files);
|
|
4806
4845
|
inputRef.current && (inputRef.current.value = "");
|
|
@@ -4813,44 +4852,43 @@ const Upload = (props) => {
|
|
|
4813
4852
|
return onUpload?.(result);
|
|
4814
4853
|
};
|
|
4815
4854
|
const handlePreview = (i) => {
|
|
4816
|
-
preview({ items:
|
|
4855
|
+
preview({ items: fileList, initial: i });
|
|
4817
4856
|
};
|
|
4818
4857
|
const setFileList = (files) => {
|
|
4819
4858
|
if (!files)
|
|
4820
4859
|
return;
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4860
|
+
setFileListState(files.map((f) => {
|
|
4861
|
+
const file = f;
|
|
4862
|
+
return { ...file, id: file.id ?? uid(7) };
|
|
4863
|
+
}));
|
|
4824
4864
|
};
|
|
4825
4865
|
const handleSortEnd = (before, after) => {
|
|
4826
|
-
const [...files] =
|
|
4827
|
-
|
|
4828
|
-
|
|
4866
|
+
const [...files] = fileList;
|
|
4867
|
+
const nextFiles = arrayMove(files, before, after);
|
|
4868
|
+
setFileListState(nextFiles);
|
|
4869
|
+
onChange?.(nextFiles);
|
|
4829
4870
|
};
|
|
4830
4871
|
useEffect(() => {
|
|
4831
|
-
|
|
4832
|
-
status,
|
|
4833
|
-
message,
|
|
4834
|
-
});
|
|
4872
|
+
setUploadMessage(message);
|
|
4835
4873
|
}, [status, message]);
|
|
4836
4874
|
useEffect(() => {
|
|
4837
|
-
|
|
4875
|
+
setFileListState(value?.filter?.((file) => !!file.id) ?? []);
|
|
4838
4876
|
}, [value]);
|
|
4839
4877
|
useEffect(() => {
|
|
4840
4878
|
setFileList(initialFiles);
|
|
4841
4879
|
}, []);
|
|
4842
4880
|
useImperativeHandle(ref, () => ({
|
|
4843
|
-
getFileList: () =>
|
|
4881
|
+
getFileList: () => fileList,
|
|
4844
4882
|
setFileList,
|
|
4845
|
-
}), []);
|
|
4883
|
+
}), [fileList]);
|
|
4846
4884
|
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", {
|
|
4847
4885
|
[`i-upload-${mode}`]: mode !== "default",
|
|
4848
|
-
}), style: { ["--upload-card-size"]: cardSize }, children: [jsx(ListContainer, { sortable: sortable, onSortEnd: handleSortEnd, children:
|
|
4886
|
+
}), style: { ["--upload-card-size"]: cardSize }, children: [jsx(ListContainer, { sortable: sortable, onSortEnd: handleSortEnd, children: fileList.map((file, i) => {
|
|
4849
4887
|
const node = (jsx(FileListItem, { index: i, file: file, mode: mode, renderItem: renderItem, onRemove: handleRemove, onPreview: handlePreview }, i));
|
|
4850
4888
|
if (!sortable)
|
|
4851
4889
|
return node;
|
|
4852
4890
|
return jsx(SortableItem, { children: node }, i);
|
|
4853
|
-
}) }),
|
|
4891
|
+
}) }), uploadMessage && (jsx("span", { className: 'i-upload-message', children: uploadMessage })), fileList.length < limit && (jsxs("label", { children: [jsx("input", { ...restProps, disabled: disabled, ref: inputRef, type: 'file', className: 'i-input-file-hidden', multiple: multiple, onChange: handleChange }), trigger] }))] }) }));
|
|
4854
4892
|
};
|
|
4855
4893
|
|
|
4856
4894
|
const useTheme = (props) => {
|