@ioca/react 1.4.74 → 1.4.76
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/popconfirm/popconfirm.js +1 -1
- package/lib/cjs/components/popconfirm/popconfirm.js.map +1 -1
- package/lib/cjs/components/popup/content.js +5 -9
- package/lib/cjs/components/popup/content.js.map +1 -1
- package/lib/cjs/components/popup/popup.js +388 -157
- package/lib/cjs/components/popup/popup.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/cjs/js/hooks.js +0 -4
- package/lib/cjs/js/hooks.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/popconfirm/popconfirm.js +1 -1
- package/lib/es/components/popconfirm/popconfirm.js.map +1 -1
- package/lib/es/components/popup/content.js +6 -10
- package/lib/es/components/popup/content.js.map +1 -1
- package/lib/es/components/popup/popup.js +390 -159
- package/lib/es/components/popup/popup.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/es/js/hooks.js +2 -5
- package/lib/es/js/hooks.js.map +1 -1
- package/lib/index.js +803 -541
- package/lib/types/components/popup/type.d.ts +0 -4
- package/package.json +100 -99
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import { debounce, uid, throttle, title } from 'radash';
|
|
4
|
-
import { useState, useRef, useEffect, useMemo, Children, cloneElement, createElement, isValidElement, Fragment as Fragment$1, useTransition,
|
|
4
|
+
import { useState, useRef, useEffect, useMemo, Children, cloneElement, createElement, isValidElement, Fragment as Fragment$1, useTransition, forwardRef, useLayoutEffect, useImperativeHandle, createContext, useContext } from 'react';
|
|
5
5
|
import { SkipPreviousRound, CloseRound, MinusRound, PlusRound, InboxTwotone, ClearAllRound, UndoRound, RedoRound, StrikethroughSRound, FormatUnderlinedRound, FormatItalicRound, FormatBoldRound, 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, ListAltRound, DriveFolderUploadOutlined, PlusSharp } from '@ricons/material';
|
|
6
6
|
import { createRoot } from 'react-dom/client';
|
|
7
7
|
import { createPortal } from 'react-dom';
|
|
@@ -132,9 +132,6 @@ function useKeydown(listener, options) {
|
|
|
132
132
|
};
|
|
133
133
|
}, []);
|
|
134
134
|
}
|
|
135
|
-
function useCreation(factory, deps) {
|
|
136
|
-
return useMemo(factory, deps);
|
|
137
|
-
}
|
|
138
135
|
function useReactive(initialState) {
|
|
139
136
|
const [, setFlag] = useState(0);
|
|
140
137
|
const scheduledRef = useRef(false);
|
|
@@ -428,25 +425,21 @@ function Group(props) {
|
|
|
428
425
|
|
|
429
426
|
function Toggle(props) {
|
|
430
427
|
const { ref, active, activeClass, after, disabled, children, className, toggable, onClick, onToggle, ...restProps } = props;
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
done: true,
|
|
434
|
-
});
|
|
428
|
+
const [isActive, setIsActive] = useState(active);
|
|
429
|
+
const [done, setDone] = useState(true);
|
|
435
430
|
const toggle = async () => {
|
|
436
431
|
const hasAfter = !!after;
|
|
437
|
-
const nextActive = !
|
|
432
|
+
const nextActive = !isActive;
|
|
438
433
|
const canToggle = toggable ? await toggable() : true;
|
|
439
434
|
if (!canToggle)
|
|
440
435
|
return;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
done: !hasAfter,
|
|
444
|
-
});
|
|
436
|
+
setIsActive(nextActive);
|
|
437
|
+
setDone(!hasAfter);
|
|
445
438
|
onToggle?.(nextActive);
|
|
446
439
|
if (!hasAfter)
|
|
447
440
|
return;
|
|
448
441
|
setTimeout(() => {
|
|
449
|
-
|
|
442
|
+
setDone(true);
|
|
450
443
|
}, 16);
|
|
451
444
|
};
|
|
452
445
|
const handleClick = (e) => {
|
|
@@ -454,14 +447,12 @@ function Toggle(props) {
|
|
|
454
447
|
!disabled && toggle();
|
|
455
448
|
};
|
|
456
449
|
useEffect(() => {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
done: true,
|
|
460
|
-
});
|
|
450
|
+
setIsActive(active);
|
|
451
|
+
setDone(true);
|
|
461
452
|
}, [active]);
|
|
462
|
-
return (jsx(Button, { ref: ref, className: classNames(className, { [activeClass || ""]:
|
|
463
|
-
"i-btn-toggle-active":
|
|
464
|
-
}), children:
|
|
453
|
+
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", {
|
|
454
|
+
"i-btn-toggle-active": done,
|
|
455
|
+
}), children: isActive ? (after ?? children) : children }) }));
|
|
465
456
|
}
|
|
466
457
|
|
|
467
458
|
const formatClass = ({ outline, flat, loading, disabled, size = "normal", block, round, square, secondary, className, }) => classNames("i-btn", className, {
|
|
@@ -894,41 +885,39 @@ const arrayMove = (array, fromIndex, toIndex) => {
|
|
|
894
885
|
|
|
895
886
|
function CheckboxItem(props) {
|
|
896
887
|
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
|
-
});
|
|
888
|
+
const [checked, setChecked] = useState(value);
|
|
889
|
+
const [itemStatus, setItemStatus] = useState(status);
|
|
890
|
+
const [itemMessage, setItemMessage] = useState(message);
|
|
902
891
|
const isChildrenFn = typeof children === "function";
|
|
903
892
|
const handleChange = (e) => {
|
|
904
|
-
const
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
});
|
|
910
|
-
onChange?.(checked, e);
|
|
893
|
+
const next = e.target.checked;
|
|
894
|
+
setChecked(next);
|
|
895
|
+
setItemStatus(status);
|
|
896
|
+
setItemMessage(message);
|
|
897
|
+
onChange?.(next, e);
|
|
911
898
|
};
|
|
912
899
|
useEffect(() => {
|
|
913
|
-
|
|
900
|
+
setChecked(value);
|
|
914
901
|
}, [value]);
|
|
902
|
+
useEffect(() => {
|
|
903
|
+
setItemStatus(status);
|
|
904
|
+
setItemMessage(message);
|
|
905
|
+
}, [status, message]);
|
|
915
906
|
return (jsxs("label", { className: classNames("i-checkbox-item", {
|
|
916
|
-
[`i-checkbox-${
|
|
907
|
+
[`i-checkbox-${itemStatus}`]: itemStatus !== "normal",
|
|
917
908
|
disabled,
|
|
918
909
|
}, className), ...restProps, children: [jsx("input", { type: 'checkbox', name: name, className: classNames("i-checkbox-input", {
|
|
919
910
|
[`i-checkbox-${type}`]: !partof,
|
|
920
911
|
"i-checkbox-partof": partof,
|
|
921
|
-
}), checked:
|
|
912
|
+
}), 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
913
|
}
|
|
923
914
|
|
|
924
915
|
function Checkbox(props) {
|
|
925
916
|
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
|
-
});
|
|
917
|
+
const [selectedValues, setSelectedValues] = useState(value);
|
|
929
918
|
const formattedOptions = useMemo(() => formatOption(options), [options]);
|
|
930
919
|
const handleChange = (checked, opt, e) => {
|
|
931
|
-
const group = [...
|
|
920
|
+
const group = [...selectedValues];
|
|
932
921
|
const i = group.findIndex((item) => item === opt.value);
|
|
933
922
|
if (checked && i < 0) {
|
|
934
923
|
group.push(opt.value);
|
|
@@ -936,11 +925,11 @@ function Checkbox(props) {
|
|
|
936
925
|
else if (!checked && i > -1) {
|
|
937
926
|
group.splice(i, 1);
|
|
938
927
|
}
|
|
939
|
-
|
|
928
|
+
setSelectedValues(group);
|
|
940
929
|
onChange?.(group, opt, e);
|
|
941
930
|
};
|
|
942
931
|
useEffect(() => {
|
|
943
|
-
|
|
932
|
+
setSelectedValues(value);
|
|
944
933
|
}, [value]);
|
|
945
934
|
return (jsxs("div", { className: classNames("i-checkbox i-input-label", {
|
|
946
935
|
[`i-checkbox-${status}`]: status !== "normal",
|
|
@@ -949,7 +938,7 @@ function Checkbox(props) {
|
|
|
949
938
|
"i-options-block": !optionInline,
|
|
950
939
|
"i-checkbox-options-button": type === "button",
|
|
951
940
|
}), children: formattedOptions.map((option) => {
|
|
952
|
-
return (jsx(CheckboxItem, { name: name, value:
|
|
941
|
+
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
942
|
}) })] }));
|
|
954
943
|
}
|
|
955
944
|
Checkbox.Item = CheckboxItem;
|
|
@@ -975,9 +964,7 @@ function Item$5(props) {
|
|
|
975
964
|
|
|
976
965
|
const Collapse = (props) => {
|
|
977
966
|
const { active, items, multiple, border, headerClickable, className, children, renderToggle = (active) => active ? jsx(MinusRound, {}) : jsx(PlusRound, {}), onCollapse, ...restProps } = props;
|
|
978
|
-
const
|
|
979
|
-
active,
|
|
980
|
-
});
|
|
967
|
+
const [activeKey, setActiveKey] = useState(active);
|
|
981
968
|
const collapses = useMemo(() => {
|
|
982
969
|
if (!items) {
|
|
983
970
|
if (!children)
|
|
@@ -1007,19 +994,20 @@ const Collapse = (props) => {
|
|
|
1007
994
|
if (disabled)
|
|
1008
995
|
return;
|
|
1009
996
|
if (!multiple) {
|
|
1010
|
-
|
|
1011
|
-
|
|
997
|
+
const nextActive = activeKey === key ? undefined : key;
|
|
998
|
+
setActiveKey(nextActive);
|
|
999
|
+
onCollapse?.(key, nextActive !== undefined);
|
|
1012
1000
|
return;
|
|
1013
1001
|
}
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const i = state.active.findIndex((k) => k === key);
|
|
1002
|
+
const group = Array.isArray(activeKey) ? [...activeKey] : [];
|
|
1003
|
+
const i = group.findIndex((k) => k === key);
|
|
1017
1004
|
if (i > -1) {
|
|
1018
|
-
|
|
1005
|
+
group.splice(i, 1);
|
|
1019
1006
|
}
|
|
1020
1007
|
else {
|
|
1021
|
-
key !== undefined &&
|
|
1008
|
+
key !== undefined && group.push(key);
|
|
1022
1009
|
}
|
|
1010
|
+
setActiveKey(group);
|
|
1023
1011
|
onCollapse?.(key, i < 0);
|
|
1024
1012
|
};
|
|
1025
1013
|
return (jsx("div", { className: classNames("i-collapse", {
|
|
@@ -1027,8 +1015,8 @@ const Collapse = (props) => {
|
|
|
1027
1015
|
}, className), ...restProps, children: collapses.map((item) => {
|
|
1028
1016
|
const { key, title, content, disabled, className, ...restProps } = item;
|
|
1029
1017
|
const isActive = multiple
|
|
1030
|
-
? (
|
|
1031
|
-
:
|
|
1018
|
+
? (activeKey || []).includes(key)
|
|
1019
|
+
: activeKey === key;
|
|
1032
1020
|
return (jsxs("div", { className: classNames("i-collapse-item", className, {
|
|
1033
1021
|
"i-collapse-active": isActive,
|
|
1034
1022
|
"i-collapse-disabled": disabled,
|
|
@@ -1337,16 +1325,10 @@ const List$1 = (props) => {
|
|
|
1337
1325
|
};
|
|
1338
1326
|
List$1.Item = Item$4;
|
|
1339
1327
|
|
|
1340
|
-
const
|
|
1341
|
-
|
|
1342
|
-
const Content$2 = (props) => {
|
|
1343
|
-
const { ref, getContainer = (trigger) => {
|
|
1344
|
-
if (typeof document === "undefined")
|
|
1345
|
-
return null;
|
|
1346
|
-
return trigger?.offsetParent ?? document.body;
|
|
1347
|
-
}, trigger, arrow, arrowProps = {}, className, children, ...restProps } = props;
|
|
1328
|
+
const Content$2 = forwardRef((props, ref) => {
|
|
1329
|
+
const { arrow, arrowProps = {}, className, children, ...restProps } = props;
|
|
1348
1330
|
const arrowCSS = useMemo(() => {
|
|
1349
|
-
let { left, top, pos } = arrowProps;
|
|
1331
|
+
let { left = 0, top = 0, pos } = arrowProps;
|
|
1350
1332
|
let transform = "";
|
|
1351
1333
|
switch (pos) {
|
|
1352
1334
|
case "left":
|
|
@@ -1373,153 +1355,324 @@ const Content$2 = (props) => {
|
|
|
1373
1355
|
};
|
|
1374
1356
|
}, [arrowProps]);
|
|
1375
1357
|
const content = (jsxs("div", { ref: ref, className: classNames("i-popup", className), ...restProps, children: [arrow && (jsx("svg", { xmlns: 'http://www.w3.org/2000/svg', className: 'i-popup-arrow', style: arrowCSS, children: jsx("path", { d: 'M0.5 0L1.5 0C1.5 4, 3 5.5, 5 7.5S8,10 8,12S7 14.5, 5 16.5S1.5,20 1.5,24L0.5 24L0.5 0z' }) })), children] }));
|
|
1376
|
-
const container =
|
|
1358
|
+
const container = typeof document === "undefined" ? null : document.body;
|
|
1377
1359
|
if (!container)
|
|
1378
1360
|
return null;
|
|
1379
1361
|
return createPortal(content, container);
|
|
1380
|
-
};
|
|
1362
|
+
});
|
|
1381
1363
|
|
|
1382
1364
|
function Popup(props) {
|
|
1383
|
-
const { visible = false, content, trigger = "hover", gap = 12, offset = 8,
|
|
1365
|
+
const { visible = false, content, trigger = "hover", gap = 12, offset = 8, position = "top", showDelay = 16, hideDelay = 12, touchable, arrow = true, align = "center", fitSize, disabled, style, className, children, onVisibleChange, } = props;
|
|
1384
1366
|
const triggerRef = useRef(null);
|
|
1385
1367
|
const contentRef = useRef(null);
|
|
1386
1368
|
const timerRef = useRef(null);
|
|
1387
|
-
const
|
|
1388
|
-
const
|
|
1389
|
-
const
|
|
1390
|
-
const
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1369
|
+
const afterHideTimerRef = useRef(null);
|
|
1370
|
+
const rafRef = useRef(null);
|
|
1371
|
+
const [show, setShow] = useState(false);
|
|
1372
|
+
const showRef = useRef(false);
|
|
1373
|
+
showRef.current = show;
|
|
1374
|
+
const latestRef = useRef({
|
|
1375
|
+
disabled,
|
|
1376
|
+
trigger,
|
|
1377
|
+
touchable,
|
|
1378
|
+
showDelay,
|
|
1379
|
+
hideDelay,
|
|
1380
|
+
position,
|
|
1381
|
+
gap,
|
|
1382
|
+
offset,
|
|
1383
|
+
align,
|
|
1384
|
+
fitSize,
|
|
1385
|
+
onVisibleChange,
|
|
1404
1386
|
});
|
|
1387
|
+
latestRef.current = {
|
|
1388
|
+
disabled,
|
|
1389
|
+
trigger,
|
|
1390
|
+
touchable,
|
|
1391
|
+
showDelay,
|
|
1392
|
+
hideDelay,
|
|
1393
|
+
position,
|
|
1394
|
+
gap,
|
|
1395
|
+
offset,
|
|
1396
|
+
align,
|
|
1397
|
+
fitSize,
|
|
1398
|
+
onVisibleChange,
|
|
1399
|
+
};
|
|
1400
|
+
const phaseRef = useRef("");
|
|
1401
|
+
const lastPosRef = useRef(null);
|
|
1402
|
+
const lastArrowRef = useRef(null);
|
|
1403
|
+
const arrowElRef = useRef(null);
|
|
1404
|
+
const pointRef = useRef(null);
|
|
1405
1405
|
const clearTimer = () => {
|
|
1406
1406
|
if (!timerRef.current)
|
|
1407
1407
|
return;
|
|
1408
1408
|
clearTimeout(timerRef.current);
|
|
1409
1409
|
timerRef.current = null;
|
|
1410
|
-
|
|
1410
|
+
phaseRef.current = "";
|
|
1411
|
+
};
|
|
1412
|
+
const clearAllTimers = () => {
|
|
1413
|
+
clearTimer();
|
|
1414
|
+
if (afterHideTimerRef.current) {
|
|
1415
|
+
clearTimeout(afterHideTimerRef.current);
|
|
1416
|
+
afterHideTimerRef.current = null;
|
|
1417
|
+
}
|
|
1418
|
+
if (rafRef.current !== null) {
|
|
1419
|
+
cancelAnimationFrame(rafRef.current);
|
|
1420
|
+
rafRef.current = null;
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
const setContentVisible = (visible) => {
|
|
1424
|
+
const el = contentRef.current;
|
|
1425
|
+
if (!el)
|
|
1426
|
+
return;
|
|
1427
|
+
el.style.opacity = visible ? "1" : "0";
|
|
1428
|
+
el.style.transform = visible ? "none" : "translate(0, 2px)";
|
|
1429
|
+
};
|
|
1430
|
+
const ensureBaseStyle = () => {
|
|
1431
|
+
const el = contentRef.current;
|
|
1432
|
+
if (!el)
|
|
1433
|
+
return;
|
|
1434
|
+
const pos = "fixed";
|
|
1435
|
+
if (el.style.position !== pos)
|
|
1436
|
+
el.style.position = pos;
|
|
1437
|
+
};
|
|
1438
|
+
const applyFitSize = () => {
|
|
1439
|
+
const o = latestRef.current;
|
|
1440
|
+
const triggerEl = triggerRef.current;
|
|
1441
|
+
const contentEl = contentRef.current;
|
|
1442
|
+
if (!triggerEl || !contentEl)
|
|
1443
|
+
return;
|
|
1444
|
+
const vertical = ["top", "bottom"].includes(o.position);
|
|
1445
|
+
const key = vertical ? "width" : "height";
|
|
1446
|
+
if (!o.fitSize) {
|
|
1447
|
+
contentEl.style[key] = "";
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
const size = triggerEl[vertical ? "offsetWidth" : "offsetHeight"];
|
|
1451
|
+
contentEl.style[key] =
|
|
1452
|
+
typeof size === "number" ? `${size}px` : "";
|
|
1453
|
+
};
|
|
1454
|
+
const applyArrow = (arrowX, arrowY, arrowPos) => {
|
|
1455
|
+
const contentEl = contentRef.current;
|
|
1456
|
+
if (!contentEl)
|
|
1457
|
+
return;
|
|
1458
|
+
const arrowEl = arrowElRef.current ??
|
|
1459
|
+
contentEl.querySelector(".i-popup-arrow");
|
|
1460
|
+
arrowElRef.current = arrowEl;
|
|
1461
|
+
if (!arrowEl)
|
|
1462
|
+
return;
|
|
1463
|
+
let left = arrowX ?? 0;
|
|
1464
|
+
let top = arrowY ?? 0;
|
|
1465
|
+
let transform = "";
|
|
1466
|
+
switch (arrowPos) {
|
|
1467
|
+
case "left":
|
|
1468
|
+
left += 2;
|
|
1469
|
+
transform = `translate(-100%, -50%) rotate(180deg)`;
|
|
1470
|
+
break;
|
|
1471
|
+
case "right":
|
|
1472
|
+
left -= 2;
|
|
1473
|
+
transform = `translate(0, -50%)`;
|
|
1474
|
+
break;
|
|
1475
|
+
case "top":
|
|
1476
|
+
top -= 2;
|
|
1477
|
+
transform = `translate(-50%, -50%) rotate(-90deg)`;
|
|
1478
|
+
break;
|
|
1479
|
+
case "bottom":
|
|
1480
|
+
top += 2;
|
|
1481
|
+
transform = `translate(-50%, -50%) rotate(90deg)`;
|
|
1482
|
+
break;
|
|
1483
|
+
}
|
|
1484
|
+
const prev = lastArrowRef.current;
|
|
1485
|
+
if (prev &&
|
|
1486
|
+
prev.left === left &&
|
|
1487
|
+
prev.top === top &&
|
|
1488
|
+
prev.transform === transform) {
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
lastArrowRef.current = { left, top, transform };
|
|
1492
|
+
arrowEl.style.left = `${left}px`;
|
|
1493
|
+
arrowEl.style.top = `${top}px`;
|
|
1494
|
+
arrowEl.style.transform = transform;
|
|
1495
|
+
};
|
|
1496
|
+
const applyLeftTop = (left, top) => {
|
|
1497
|
+
const contentEl = contentRef.current;
|
|
1498
|
+
if (!contentEl)
|
|
1499
|
+
return;
|
|
1500
|
+
const prev = lastPosRef.current;
|
|
1501
|
+
if (prev && prev.left === left && prev.top === top)
|
|
1502
|
+
return;
|
|
1503
|
+
lastPosRef.current = { left, top };
|
|
1504
|
+
contentEl.style.left = `${left}px`;
|
|
1505
|
+
contentEl.style.top = `${top}px`;
|
|
1506
|
+
};
|
|
1507
|
+
const computeRelativePosition = () => {
|
|
1508
|
+
const triggerEl = triggerRef.current;
|
|
1509
|
+
const contentEl = contentRef.current;
|
|
1510
|
+
if (!triggerEl || !contentEl)
|
|
1511
|
+
return;
|
|
1512
|
+
const o = latestRef.current;
|
|
1513
|
+
applyFitSize();
|
|
1514
|
+
const [left, top, { arrowX, arrowY, arrowPos }] = getPosition(triggerEl, contentEl, {
|
|
1515
|
+
position: o.position,
|
|
1516
|
+
gap: o.gap,
|
|
1517
|
+
offset: o.offset,
|
|
1518
|
+
align: o.align,
|
|
1519
|
+
refWindow: true,
|
|
1520
|
+
});
|
|
1521
|
+
applyLeftTop(left, top);
|
|
1522
|
+
applyArrow(arrowX, arrowY, arrowPos);
|
|
1523
|
+
};
|
|
1524
|
+
const computePointPosition = () => {
|
|
1525
|
+
const contentEl = contentRef.current;
|
|
1526
|
+
if (!contentEl)
|
|
1527
|
+
return;
|
|
1528
|
+
const point = pointRef.current;
|
|
1529
|
+
if (!point)
|
|
1530
|
+
return;
|
|
1531
|
+
const [left, top] = getPointPosition(point, contentEl);
|
|
1532
|
+
applyLeftTop(left, top);
|
|
1533
|
+
};
|
|
1534
|
+
const scheduleComputePosition = () => {
|
|
1535
|
+
if (!showRef.current)
|
|
1536
|
+
return;
|
|
1537
|
+
if (rafRef.current !== null)
|
|
1538
|
+
return;
|
|
1539
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
1540
|
+
rafRef.current = null;
|
|
1541
|
+
if (!showRef.current)
|
|
1542
|
+
return;
|
|
1543
|
+
ensureBaseStyle();
|
|
1544
|
+
if (latestRef.current.trigger === "contextmenu") {
|
|
1545
|
+
computePointPosition();
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
computeRelativePosition();
|
|
1549
|
+
});
|
|
1411
1550
|
};
|
|
1412
1551
|
const handleShow = () => {
|
|
1413
|
-
|
|
1552
|
+
const opts = latestRef.current;
|
|
1553
|
+
if (opts.disabled)
|
|
1414
1554
|
return;
|
|
1415
|
-
|
|
1416
|
-
|
|
1555
|
+
clearAllTimers();
|
|
1556
|
+
if (showRef.current &&
|
|
1557
|
+
(opts.trigger !== "hover" ||
|
|
1558
|
+
(opts.trigger === "hover" && !opts.touchable))) {
|
|
1559
|
+
ensureBaseStyle();
|
|
1560
|
+
computeRelativePosition();
|
|
1561
|
+
setContentVisible(true);
|
|
1417
1562
|
return;
|
|
1418
1563
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1564
|
+
phaseRef.current = "showing";
|
|
1565
|
+
if (!showRef.current) {
|
|
1566
|
+
lastPosRef.current = null;
|
|
1567
|
+
lastArrowRef.current = null;
|
|
1568
|
+
arrowElRef.current = null;
|
|
1569
|
+
setShow(true);
|
|
1570
|
+
}
|
|
1421
1571
|
timerRef.current = setTimeout(() => {
|
|
1422
|
-
if (
|
|
1572
|
+
if (phaseRef.current !== "showing")
|
|
1423
1573
|
return;
|
|
1424
|
-
requestAnimationFrame(() => {
|
|
1425
|
-
|
|
1574
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
1575
|
+
rafRef.current = null;
|
|
1576
|
+
if (phaseRef.current !== "showing")
|
|
1426
1577
|
return;
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
left,
|
|
1439
|
-
top,
|
|
1440
|
-
};
|
|
1441
|
-
state.arrowProps = {
|
|
1442
|
-
left: arrowX,
|
|
1443
|
-
top: arrowY,
|
|
1444
|
-
pos: arrowPos,
|
|
1445
|
-
};
|
|
1446
|
-
onVisibleChange?.(true);
|
|
1578
|
+
if (!contentRef.current)
|
|
1579
|
+
return;
|
|
1580
|
+
ensureBaseStyle();
|
|
1581
|
+
if (opts.trigger === "contextmenu") {
|
|
1582
|
+
computePointPosition();
|
|
1583
|
+
}
|
|
1584
|
+
else {
|
|
1585
|
+
computeRelativePosition();
|
|
1586
|
+
}
|
|
1587
|
+
setContentVisible(true);
|
|
1588
|
+
opts.onVisibleChange?.(true);
|
|
1447
1589
|
clearTimer();
|
|
1448
|
-
|
|
1590
|
+
phaseRef.current = "";
|
|
1449
1591
|
});
|
|
1450
|
-
}, showDelay);
|
|
1592
|
+
}, opts.showDelay);
|
|
1451
1593
|
};
|
|
1452
1594
|
const handleHide = () => {
|
|
1453
|
-
if (!
|
|
1595
|
+
if (!showRef.current)
|
|
1454
1596
|
return;
|
|
1455
|
-
|
|
1597
|
+
clearAllTimers();
|
|
1598
|
+
phaseRef.current = "hiding";
|
|
1456
1599
|
timerRef.current = setTimeout(() => {
|
|
1457
|
-
if (
|
|
1600
|
+
if (phaseRef.current !== "hiding") {
|
|
1458
1601
|
clearTimer();
|
|
1459
1602
|
return;
|
|
1460
1603
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
clearTimer();
|
|
1469
|
-
onVisibleChange?.(false);
|
|
1470
|
-
statusRef.current = "";
|
|
1604
|
+
setContentVisible(false);
|
|
1605
|
+
afterHideTimerRef.current = setTimeout(() => {
|
|
1606
|
+
afterHideTimerRef.current = null;
|
|
1607
|
+
setShow(false);
|
|
1608
|
+
clearAllTimers();
|
|
1609
|
+
latestRef.current.onVisibleChange?.(false);
|
|
1610
|
+
phaseRef.current = "";
|
|
1471
1611
|
}, 160);
|
|
1472
|
-
}, hideDelay);
|
|
1612
|
+
}, latestRef.current.hideDelay);
|
|
1473
1613
|
};
|
|
1474
1614
|
const handleToggle = (action) => {
|
|
1475
1615
|
if (action !== undefined) {
|
|
1476
1616
|
action ? handleShow() : handleHide();
|
|
1477
1617
|
return;
|
|
1478
1618
|
}
|
|
1479
|
-
|
|
1480
|
-
};
|
|
1481
|
-
const
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
timerRef.current = setTimeout(() => {
|
|
1508
|
-
const [left, top] = getPointPosition(e, contentRef.current);
|
|
1509
|
-
state.style = {
|
|
1510
|
-
...state.style,
|
|
1511
|
-
opacity: 1,
|
|
1512
|
-
transform: "none",
|
|
1513
|
-
left,
|
|
1514
|
-
top,
|
|
1619
|
+
showRef.current ? handleHide() : handleShow();
|
|
1620
|
+
};
|
|
1621
|
+
const hideRef = useRef(handleHide);
|
|
1622
|
+
const toggleRef = useRef(handleToggle);
|
|
1623
|
+
hideRef.current = handleHide;
|
|
1624
|
+
toggleRef.current = handleToggle;
|
|
1625
|
+
const doHide = useMemo(() => () => hideRef.current(), []);
|
|
1626
|
+
const doToggle = useMemo(() => (action) => toggleRef.current(action), []);
|
|
1627
|
+
const eventMaps = useMemo(() => {
|
|
1628
|
+
return {
|
|
1629
|
+
click: {
|
|
1630
|
+
onClick: () => doToggle(true),
|
|
1631
|
+
},
|
|
1632
|
+
hover: {
|
|
1633
|
+
onMouseEnter: () => doToggle(true),
|
|
1634
|
+
onMouseLeave: () => doToggle(false),
|
|
1635
|
+
},
|
|
1636
|
+
focus: {
|
|
1637
|
+
onFocus: () => doToggle(true),
|
|
1638
|
+
onBlur: () => doToggle(false),
|
|
1639
|
+
},
|
|
1640
|
+
contextmenu: {
|
|
1641
|
+
onContextMenu: (e) => {
|
|
1642
|
+
e.preventDefault();
|
|
1643
|
+
e.stopPropagation();
|
|
1644
|
+
pointRef.current = {
|
|
1645
|
+
pageX: e.pageX,
|
|
1646
|
+
pageY: e.pageY,
|
|
1515
1647
|
};
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1648
|
+
if (showRef.current) {
|
|
1649
|
+
ensureBaseStyle();
|
|
1650
|
+
computePointPosition();
|
|
1651
|
+
return;
|
|
1652
|
+
}
|
|
1653
|
+
clearAllTimers();
|
|
1654
|
+
phaseRef.current = "showing";
|
|
1655
|
+
lastPosRef.current = null;
|
|
1656
|
+
lastArrowRef.current = null;
|
|
1657
|
+
arrowElRef.current = null;
|
|
1658
|
+
setShow(true);
|
|
1659
|
+
timerRef.current = setTimeout(() => {
|
|
1660
|
+
if (phaseRef.current !== "showing")
|
|
1661
|
+
return;
|
|
1662
|
+
if (!contentRef.current)
|
|
1663
|
+
return;
|
|
1664
|
+
ensureBaseStyle();
|
|
1665
|
+
computePointPosition();
|
|
1666
|
+
setContentVisible(true);
|
|
1667
|
+
clearTimer();
|
|
1668
|
+
latestRef.current.onVisibleChange?.(true);
|
|
1669
|
+
phaseRef.current = "";
|
|
1670
|
+
}, latestRef.current.showDelay);
|
|
1671
|
+
},
|
|
1519
1672
|
},
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
}
|
|
1673
|
+
none: {},
|
|
1674
|
+
};
|
|
1675
|
+
}, [doToggle]);
|
|
1523
1676
|
const contentTouch = useMemo(() => {
|
|
1524
1677
|
if (!touchable)
|
|
1525
1678
|
return {};
|
|
@@ -1532,72 +1685,132 @@ function Popup(props) {
|
|
|
1532
1685
|
}
|
|
1533
1686
|
return events;
|
|
1534
1687
|
}, [touchable, trigger]);
|
|
1535
|
-
const computePosition = () => {
|
|
1536
|
-
if (!state.show)
|
|
1537
|
-
return;
|
|
1538
|
-
const [left, top, { arrowX, arrowY, arrowPos }] = getPosition(triggerRef.current, contentRef.current, {
|
|
1539
|
-
position,
|
|
1540
|
-
gap,
|
|
1541
|
-
offset,
|
|
1542
|
-
align,
|
|
1543
|
-
refWindow,
|
|
1544
|
-
});
|
|
1545
|
-
Object.assign(state, {
|
|
1546
|
-
style: { ...state.style, left, top },
|
|
1547
|
-
arrowProps: { left: arrowX, top: arrowY, pos: arrowPos },
|
|
1548
|
-
});
|
|
1549
|
-
};
|
|
1550
1688
|
const { observe, unobserve, disconnect } = useResizeObserver();
|
|
1551
1689
|
useEffect(() => {
|
|
1552
|
-
if (
|
|
1553
|
-
return;
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1690
|
+
if (!observe)
|
|
1691
|
+
return;
|
|
1692
|
+
const triggerEl = triggerRef.current;
|
|
1693
|
+
const contentEl = contentRef.current;
|
|
1694
|
+
if (triggerEl)
|
|
1695
|
+
observe(triggerEl, scheduleComputePosition);
|
|
1696
|
+
if (contentEl)
|
|
1697
|
+
observe(contentEl, scheduleComputePosition);
|
|
1558
1698
|
return () => {
|
|
1559
|
-
if (
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1699
|
+
if (contentEl)
|
|
1700
|
+
unobserve(contentEl);
|
|
1701
|
+
if (triggerEl)
|
|
1702
|
+
unobserve(triggerEl);
|
|
1563
1703
|
disconnect();
|
|
1564
1704
|
};
|
|
1565
|
-
}, [
|
|
1705
|
+
}, [trigger, observe, unobserve, disconnect, show]);
|
|
1566
1706
|
useLayoutEffect(() => {
|
|
1567
|
-
if (!
|
|
1707
|
+
if (!show)
|
|
1568
1708
|
return;
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1709
|
+
ensureBaseStyle();
|
|
1710
|
+
if (latestRef.current.trigger === "contextmenu") {
|
|
1711
|
+
computePointPosition();
|
|
1712
|
+
}
|
|
1713
|
+
else {
|
|
1714
|
+
computeRelativePosition();
|
|
1715
|
+
}
|
|
1716
|
+
}, [show]);
|
|
1573
1717
|
useLayoutEffect(() => {
|
|
1574
|
-
|
|
1718
|
+
doToggle(visible);
|
|
1575
1719
|
}, [visible]);
|
|
1576
1720
|
useEffect(() => {
|
|
1577
1721
|
return () => {
|
|
1578
|
-
|
|
1722
|
+
clearAllTimers();
|
|
1579
1723
|
};
|
|
1580
1724
|
}, []);
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1725
|
+
const mouseUpHandlerRef = useRef(() => { });
|
|
1726
|
+
mouseUpHandlerRef.current = (e) => {
|
|
1727
|
+
if (!showRef.current)
|
|
1728
|
+
return;
|
|
1729
|
+
const triggerEl = triggerRef.current;
|
|
1730
|
+
const contentEl = contentRef.current;
|
|
1731
|
+
if (!triggerEl || !contentEl)
|
|
1732
|
+
return;
|
|
1733
|
+
const tar = e.target;
|
|
1734
|
+
if (triggerEl.contains(tar) || contentEl.contains(tar))
|
|
1735
|
+
return;
|
|
1736
|
+
doHide();
|
|
1737
|
+
};
|
|
1738
|
+
const onGlobalMouseUp = useMemo(() => (e) => mouseUpHandlerRef.current(e), []);
|
|
1739
|
+
useMouseUp(onGlobalMouseUp);
|
|
1740
|
+
useEffect(() => {
|
|
1741
|
+
if (!show)
|
|
1742
|
+
return;
|
|
1743
|
+
if (typeof window === "undefined")
|
|
1744
|
+
return;
|
|
1745
|
+
const onScrollOrResize = debounce({ delay: 160 }, () => {
|
|
1746
|
+
scheduleComputePosition();
|
|
1747
|
+
});
|
|
1748
|
+
window.addEventListener("scroll", onScrollOrResize, {
|
|
1749
|
+
passive: true,
|
|
1750
|
+
capture: true,
|
|
1751
|
+
});
|
|
1752
|
+
return () => {
|
|
1753
|
+
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
1754
|
+
};
|
|
1755
|
+
}, [show]);
|
|
1756
|
+
const mergeRefs = (...refs) => {
|
|
1757
|
+
return (node) => {
|
|
1758
|
+
for (const ref of refs) {
|
|
1759
|
+
if (!ref)
|
|
1760
|
+
continue;
|
|
1761
|
+
if (typeof ref === "function") {
|
|
1762
|
+
ref(node);
|
|
1763
|
+
}
|
|
1764
|
+
else {
|
|
1765
|
+
ref.current = node;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
};
|
|
1769
|
+
};
|
|
1770
|
+
return (jsxs(Fragment, { children: [(() => {
|
|
1771
|
+
const events = eventMaps[trigger];
|
|
1772
|
+
const items = Children.toArray(children);
|
|
1773
|
+
const canAttachRef = (el) => {
|
|
1774
|
+
if (!isValidElement(el))
|
|
1775
|
+
return false;
|
|
1776
|
+
const t = el.type;
|
|
1777
|
+
if (typeof t === "string")
|
|
1778
|
+
return true;
|
|
1779
|
+
if (t?.prototype?.isReactComponent)
|
|
1780
|
+
return true;
|
|
1781
|
+
if (t?.$$typeof === Symbol.for("react.forward_ref"))
|
|
1782
|
+
return true;
|
|
1783
|
+
return false;
|
|
1784
|
+
};
|
|
1785
|
+
if (items.length !== 1) {
|
|
1786
|
+
return (jsx("div", { ref: triggerRef, ...events, className: 'i-popup-trigger', style: { display: "inline-block" }, children: children }));
|
|
1787
|
+
}
|
|
1788
|
+
const only = items[0];
|
|
1789
|
+
if (!isValidElement(only) || !canAttachRef(only)) {
|
|
1790
|
+
return (jsx("div", { ref: triggerRef, ...events, className: 'i-popup-trigger', style: { display: "inline-block" }, children: only }));
|
|
1791
|
+
}
|
|
1792
|
+
const { className: childClassName, ...restProps } = only.props;
|
|
1793
|
+
const nextProps = { ...restProps };
|
|
1794
|
+
for (const evt of Object.keys(events)) {
|
|
1795
|
+
const theirs = restProps[evt];
|
|
1796
|
+
const ours = events[evt];
|
|
1797
|
+
nextProps[evt] =
|
|
1798
|
+
typeof theirs === "function"
|
|
1799
|
+
? (e) => {
|
|
1800
|
+
ours(e);
|
|
1801
|
+
theirs(e);
|
|
1802
|
+
}
|
|
1803
|
+
: ours;
|
|
1804
|
+
}
|
|
1805
|
+
return cloneElement(only, {
|
|
1806
|
+
ref: mergeRefs(only.ref, triggerRef),
|
|
1807
|
+
className: childClassName,
|
|
1808
|
+
...nextProps,
|
|
1599
1809
|
});
|
|
1600
|
-
}),
|
|
1810
|
+
})(), show && (jsx(Content$2, { ref: contentRef, arrow: arrow && trigger !== "contextmenu", style: {
|
|
1811
|
+
...style,
|
|
1812
|
+
position: "fixed",
|
|
1813
|
+
}, className: className, ...contentTouch, trigger: triggerRef.current, children: content }))] }));
|
|
1601
1814
|
}
|
|
1602
1815
|
|
|
1603
1816
|
const { Item: ListItem } = List$1;
|
|
@@ -1808,12 +2021,9 @@ const Context = createContext({});
|
|
|
1808
2021
|
|
|
1809
2022
|
function Field(props) {
|
|
1810
2023
|
const { name, required, children } = props;
|
|
1811
|
-
const
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
message: undefined,
|
|
1815
|
-
update: 0,
|
|
1816
|
-
});
|
|
2024
|
+
const [fieldValue, setFieldValue] = useState(undefined);
|
|
2025
|
+
const [fieldStatus, setFieldStatus] = useState("normal");
|
|
2026
|
+
const [fieldMessage, setFieldMessage] = useState(undefined);
|
|
1817
2027
|
const form = useContext(Context);
|
|
1818
2028
|
const { id } = form;
|
|
1819
2029
|
const handleChange = (v) => {
|
|
@@ -1830,33 +2040,33 @@ function Field(props) {
|
|
|
1830
2040
|
if (!isValidElement(node))
|
|
1831
2041
|
return null;
|
|
1832
2042
|
const { onChange } = node.props;
|
|
1833
|
-
const { value, status, message } = state;
|
|
1834
2043
|
return cloneElement(node, {
|
|
1835
|
-
value,
|
|
1836
|
-
status,
|
|
1837
|
-
message,
|
|
2044
|
+
value: fieldValue,
|
|
2045
|
+
status: fieldStatus,
|
|
2046
|
+
message: fieldMessage,
|
|
1838
2047
|
required,
|
|
1839
2048
|
onChange: (...args) => {
|
|
1840
2049
|
handleChange(args[0]);
|
|
1841
2050
|
onChange?.(...args);
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
message: undefined,
|
|
1845
|
-
});
|
|
2051
|
+
setFieldStatus("normal");
|
|
2052
|
+
setFieldMessage(undefined);
|
|
1846
2053
|
},
|
|
1847
2054
|
});
|
|
1848
2055
|
});
|
|
1849
|
-
}, [children,
|
|
2056
|
+
}, [children, fieldValue, fieldStatus, fieldMessage, required]);
|
|
1850
2057
|
useEffect(() => {
|
|
1851
2058
|
if (!name)
|
|
1852
2059
|
return;
|
|
1853
2060
|
PubSub.subscribe(`${id}:set:${name}`, (evt, v) => {
|
|
1854
|
-
|
|
1855
|
-
state.update += 1;
|
|
2061
|
+
setFieldValue(v);
|
|
1856
2062
|
});
|
|
1857
2063
|
PubSub.subscribe(`${id}:invalid:${name}`, (evt, v) => {
|
|
1858
|
-
|
|
1859
|
-
|
|
2064
|
+
if (v?.value !== undefined)
|
|
2065
|
+
setFieldValue(v.value);
|
|
2066
|
+
if (v?.status)
|
|
2067
|
+
setFieldStatus(v.status);
|
|
2068
|
+
if ("message" in (v ?? {}))
|
|
2069
|
+
setFieldMessage(v.message);
|
|
1860
2070
|
});
|
|
1861
2071
|
Promise.resolve().then(() => {
|
|
1862
2072
|
form.set(name, form.cacheData[name] ?? undefined);
|
|
@@ -2099,6 +2309,8 @@ function Content$1(props) {
|
|
|
2099
2309
|
return (jsxs(Fragment, { children: [showHeader && (jsxs("header", { className: 'i-modal-header', children: [title && jsx("b", { children: title }), jsx(Helpericon, { active: !hideCloseButton, className: 'i-modal-close', onClick: onClose })] })), jsx("div", { className: 'i-modal-content', children: children }), jsx("footer", { className: 'i-modal-footer', children: renderFooter })] }));
|
|
2100
2310
|
}
|
|
2101
2311
|
|
|
2312
|
+
const ModalContext = createContext(false);
|
|
2313
|
+
|
|
2102
2314
|
function useModal() {
|
|
2103
2315
|
const ref = useRef(null);
|
|
2104
2316
|
const handleOpen = (props) => {
|
|
@@ -2847,11 +3059,33 @@ function InputContainer(props) {
|
|
|
2847
3059
|
|
|
2848
3060
|
const Number$1 = (props) => {
|
|
2849
3061
|
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
|
-
|
|
3062
|
+
const [inputValue, setInputValue] = useState(value === undefined || value === null ? "" : String(value));
|
|
3063
|
+
const formatOut = (num) => {
|
|
3064
|
+
const v = clamp(num, min, max);
|
|
3065
|
+
if (precision !== undefined)
|
|
3066
|
+
return formatNumber(v, { precision, thousand });
|
|
3067
|
+
const s = String(v);
|
|
3068
|
+
if (!thousand)
|
|
3069
|
+
return s;
|
|
3070
|
+
const negative = s.startsWith("-");
|
|
3071
|
+
const body = negative ? s.slice(1) : s;
|
|
3072
|
+
const [integer, decimal] = body.split(".");
|
|
3073
|
+
const withThousand = integer.replace(/\B(?=(\d{3})+(?!\d))/g, thousand);
|
|
3074
|
+
return decimal
|
|
3075
|
+
? `${negative ? "-" : ""}${withThousand}.${decimal}`
|
|
3076
|
+
: `${negative ? "-" : ""}${withThousand}`;
|
|
3077
|
+
};
|
|
3078
|
+
const sanitizeNumberInput = (raw) => {
|
|
3079
|
+
const hasMinus = raw.startsWith("-");
|
|
3080
|
+
let v = raw.replace(/[^\d.]/g, "");
|
|
3081
|
+
if (hasMinus)
|
|
3082
|
+
v = `-${v}`;
|
|
3083
|
+
const parts = v.split(".");
|
|
3084
|
+
if (parts.length > 1) {
|
|
3085
|
+
v = `${parts.shift()}.${parts.join("")}`;
|
|
3086
|
+
}
|
|
3087
|
+
return v;
|
|
3088
|
+
};
|
|
2855
3089
|
const formatInputValue = (v) => {
|
|
2856
3090
|
if (!v)
|
|
2857
3091
|
return "";
|
|
@@ -2863,32 +3097,57 @@ const Number$1 = (props) => {
|
|
|
2863
3097
|
};
|
|
2864
3098
|
const handleChange = (e) => {
|
|
2865
3099
|
const { value } = e.target;
|
|
2866
|
-
const v = formatInputValue(value
|
|
2867
|
-
const
|
|
2868
|
-
|
|
2869
|
-
|
|
3100
|
+
const v = sanitizeNumberInput(formatInputValue(value));
|
|
3101
|
+
const isIntermediate = v === "" || v === "-" || v === "." || v === "-." || v.endsWith(".");
|
|
3102
|
+
setInputValue(v);
|
|
3103
|
+
if (isIntermediate)
|
|
3104
|
+
return;
|
|
3105
|
+
const num = parseFloat(v);
|
|
3106
|
+
if (globalThis.Number.isNaN(num))
|
|
3107
|
+
return;
|
|
3108
|
+
onChange?.(clamp(num, min, max), e);
|
|
3109
|
+
if (precision !== undefined)
|
|
3110
|
+
setInputValue(formatOut(num));
|
|
2870
3111
|
};
|
|
2871
3112
|
const handleOperate = (param) => {
|
|
2872
|
-
const value = parseFloat(formatInputValue(
|
|
2873
|
-
const result =
|
|
2874
|
-
|
|
2875
|
-
onChange?.(result);
|
|
3113
|
+
const value = parseFloat(formatInputValue(inputValue)) || 0; // 确保值为数字,默认值为 0
|
|
3114
|
+
const result = value + param;
|
|
3115
|
+
setInputValue(formatOut(result));
|
|
3116
|
+
onChange?.(clamp(result, min, max));
|
|
2876
3117
|
};
|
|
2877
3118
|
const handleMax = () => {
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
3119
|
+
setInputValue(formatOut(max));
|
|
3120
|
+
onChange?.(clamp(max, min, max));
|
|
3121
|
+
};
|
|
3122
|
+
const handleBlur = (e) => {
|
|
3123
|
+
onBlur?.(e);
|
|
3124
|
+
const v = sanitizeNumberInput(formatInputValue(inputValue));
|
|
3125
|
+
if (!v || v === "-" || v === "." || v === "-.") {
|
|
3126
|
+
setInputValue("");
|
|
3127
|
+
return;
|
|
3128
|
+
}
|
|
3129
|
+
const num = parseFloat(v);
|
|
3130
|
+
if (globalThis.Number.isNaN(num))
|
|
3131
|
+
return;
|
|
3132
|
+
const numValue = clamp(num, min, max);
|
|
3133
|
+
setInputValue(formatOut(numValue));
|
|
3134
|
+
onChange?.(numValue, e);
|
|
2881
3135
|
};
|
|
2882
3136
|
useEffect(() => {
|
|
2883
|
-
|
|
3137
|
+
setInputValue(value === undefined || value === null ? "" : String(value));
|
|
2884
3138
|
}, [value]);
|
|
2885
3139
|
const inputProps = {
|
|
2886
3140
|
ref,
|
|
2887
3141
|
name,
|
|
2888
3142
|
disabled,
|
|
2889
|
-
value:
|
|
3143
|
+
value: inputValue,
|
|
2890
3144
|
className: "i-input i-input-number",
|
|
2891
3145
|
onChange: handleChange,
|
|
3146
|
+
onKeyDown: (e) => {
|
|
3147
|
+
e.code === "Enter" && onEnter?.(e);
|
|
3148
|
+
},
|
|
3149
|
+
onInput,
|
|
3150
|
+
onBlur: handleBlur,
|
|
2892
3151
|
...restProps,
|
|
2893
3152
|
};
|
|
2894
3153
|
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 +3158,7 @@ const Number$1 = (props) => {
|
|
|
2899
3158
|
|
|
2900
3159
|
const Range = (props) => {
|
|
2901
3160
|
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
|
-
});
|
|
3161
|
+
const [rangeValue, setRangeValue] = useState(value);
|
|
2905
3162
|
const getRangeNumber = (v) => clamp(v, min, max);
|
|
2906
3163
|
const getFormatNumber = (v) => formatNumber(v, { precision, thousand });
|
|
2907
3164
|
const formatInputValue = (v) => {
|
|
@@ -2914,31 +3171,31 @@ const Range = (props) => {
|
|
|
2914
3171
|
const handleChange = (e, i) => {
|
|
2915
3172
|
const { value } = e.target;
|
|
2916
3173
|
const v = formatInputValue(value.replace(/[^\d\.-]/g, ""));
|
|
2917
|
-
const range = Array.isArray(
|
|
3174
|
+
const range = Array.isArray(rangeValue) ? [...rangeValue] : [];
|
|
2918
3175
|
range[i] = v;
|
|
2919
|
-
|
|
3176
|
+
setRangeValue(range);
|
|
2920
3177
|
onChange?.(range, e);
|
|
2921
3178
|
};
|
|
2922
3179
|
const handleOperate = (e, param, i) => {
|
|
2923
3180
|
e.preventDefault();
|
|
2924
3181
|
e.stopPropagation();
|
|
2925
|
-
const range = Array.isArray(
|
|
3182
|
+
const range = Array.isArray(rangeValue) ? [...rangeValue] : [];
|
|
2926
3183
|
const value = formatInputValue(range[i]) ?? 0;
|
|
2927
3184
|
const result = getRangeNumber(+value + param);
|
|
2928
3185
|
range[i] = getFormatNumber(result);
|
|
2929
|
-
|
|
3186
|
+
setRangeValue(range);
|
|
2930
3187
|
onChange?.(range, e);
|
|
2931
3188
|
};
|
|
2932
3189
|
const handleSwitch = (e) => {
|
|
2933
3190
|
e?.preventDefault();
|
|
2934
3191
|
e?.stopPropagation();
|
|
2935
|
-
const range =
|
|
3192
|
+
const range = Array.isArray(rangeValue) ? [...rangeValue] : [];
|
|
2936
3193
|
[range[0], range[1]] = [range[1], range[0]];
|
|
2937
|
-
|
|
3194
|
+
setRangeValue(range);
|
|
2938
3195
|
onChange?.(range);
|
|
2939
3196
|
};
|
|
2940
3197
|
useEffect(() => {
|
|
2941
|
-
|
|
3198
|
+
setRangeValue(value);
|
|
2942
3199
|
}, [value]);
|
|
2943
3200
|
const inputProps = {
|
|
2944
3201
|
name,
|
|
@@ -2948,7 +3205,7 @@ const Range = (props) => {
|
|
|
2948
3205
|
const handleBlur = () => {
|
|
2949
3206
|
if (!autoSwitch)
|
|
2950
3207
|
return;
|
|
2951
|
-
const range = Array.isArray(
|
|
3208
|
+
const range = Array.isArray(rangeValue) ? rangeValue : [];
|
|
2952
3209
|
if (range.length < 2)
|
|
2953
3210
|
return;
|
|
2954
3211
|
const [left, right] = range.map(Number);
|
|
@@ -2959,18 +3216,16 @@ const Range = (props) => {
|
|
|
2959
3216
|
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
3217
|
[`i-input-${status}`]: status !== "normal",
|
|
2961
3218
|
"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:
|
|
3219
|
+
}), 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
3220
|
};
|
|
2964
3221
|
|
|
2965
3222
|
const Textarea = (props) => {
|
|
2966
3223
|
const { ref, label, name, value = "", labelInline, className, status = "normal", message, tip, autoSize, border, width, style, onChange, onEnter, ...restProps } = props;
|
|
2967
|
-
const
|
|
2968
|
-
value,
|
|
2969
|
-
});
|
|
3224
|
+
const [textareaValue, setTextareaValue] = useState(value);
|
|
2970
3225
|
const refTextarea = useRef(null);
|
|
2971
3226
|
const handleChange = (e) => {
|
|
2972
3227
|
const v = e.target.value;
|
|
2973
|
-
|
|
3228
|
+
setTextareaValue(v);
|
|
2974
3229
|
const ta = refTextarea.current;
|
|
2975
3230
|
if (autoSize && ta) {
|
|
2976
3231
|
ta.style.height = `${ta.scrollHeight}px`;
|
|
@@ -2984,7 +3239,7 @@ const Textarea = (props) => {
|
|
|
2984
3239
|
onEnter?.(e);
|
|
2985
3240
|
};
|
|
2986
3241
|
useEffect(() => {
|
|
2987
|
-
|
|
3242
|
+
setTextareaValue(value);
|
|
2988
3243
|
}, [value]);
|
|
2989
3244
|
useImperativeHandle(ref, () => {
|
|
2990
3245
|
return {
|
|
@@ -2994,7 +3249,7 @@ const Textarea = (props) => {
|
|
|
2994
3249
|
const inputProps = {
|
|
2995
3250
|
ref: refTextarea,
|
|
2996
3251
|
name,
|
|
2997
|
-
value:
|
|
3252
|
+
value: textareaValue,
|
|
2998
3253
|
className: "i-input i-textarea",
|
|
2999
3254
|
onChange: handleChange,
|
|
3000
3255
|
onKeyDown: handleKeydown,
|
|
@@ -3008,14 +3263,12 @@ const Textarea = (props) => {
|
|
|
3008
3263
|
|
|
3009
3264
|
const Input = ((props) => {
|
|
3010
3265
|
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
|
-
});
|
|
3266
|
+
const [inputValue, setInputValue] = useState(value);
|
|
3267
|
+
const [inputType, setInputType] = useState(type);
|
|
3268
|
+
const [visible, setVisible] = useState(false);
|
|
3016
3269
|
const handleChange = (e) => {
|
|
3017
3270
|
const v = e.target.value;
|
|
3018
|
-
|
|
3271
|
+
setInputValue(v);
|
|
3019
3272
|
onChange?.(v, e);
|
|
3020
3273
|
};
|
|
3021
3274
|
const handleKeydown = (e) => {
|
|
@@ -3023,43 +3276,49 @@ const Input = ((props) => {
|
|
|
3023
3276
|
};
|
|
3024
3277
|
const handleHelperClick = () => {
|
|
3025
3278
|
if (type === "password" && !hideVisible) {
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3279
|
+
setVisible((v) => {
|
|
3280
|
+
const next = !v;
|
|
3281
|
+
setInputType(next ? "text" : "password");
|
|
3282
|
+
return next;
|
|
3029
3283
|
});
|
|
3030
3284
|
return;
|
|
3031
3285
|
}
|
|
3032
3286
|
const v = "";
|
|
3287
|
+
setInputValue(v);
|
|
3033
3288
|
onChange?.(v);
|
|
3034
3289
|
onClear?.();
|
|
3035
3290
|
};
|
|
3036
3291
|
const HelperIcon = useMemo(() => {
|
|
3037
3292
|
if (type === "password") {
|
|
3038
|
-
return
|
|
3293
|
+
return visible ? jsx(VisibilityRound, {}) : jsx(VisibilityOffRound, {});
|
|
3039
3294
|
}
|
|
3040
3295
|
return undefined;
|
|
3041
|
-
}, [
|
|
3296
|
+
}, [type, visible]);
|
|
3042
3297
|
useEffect(() => {
|
|
3043
|
-
|
|
3298
|
+
setInputValue(value);
|
|
3044
3299
|
}, [value]);
|
|
3045
3300
|
const inputProps = {
|
|
3046
3301
|
ref,
|
|
3047
|
-
type:
|
|
3302
|
+
type: inputType,
|
|
3048
3303
|
name,
|
|
3049
|
-
value:
|
|
3304
|
+
value: inputValue,
|
|
3050
3305
|
maxLength,
|
|
3051
3306
|
className: classNames("i-input", `i-input-${type}`),
|
|
3052
3307
|
onChange: handleChange,
|
|
3053
3308
|
onKeyDown: handleKeydown,
|
|
3054
3309
|
...restProps,
|
|
3055
3310
|
};
|
|
3056
|
-
|
|
3057
|
-
|
|
3311
|
+
useEffect(() => {
|
|
3312
|
+
setInputType(type);
|
|
3313
|
+
setVisible(false);
|
|
3314
|
+
}, [type]);
|
|
3315
|
+
const clearable = clear && inputValue;
|
|
3316
|
+
const showHelper = type === "password" && !!inputValue;
|
|
3058
3317
|
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
3318
|
[`i-input-${status}`]: status !== "normal",
|
|
3060
3319
|
"i-input-borderless": !border,
|
|
3061
3320
|
"i-input-underline": underline,
|
|
3062
|
-
}), children: [prepend && jsx("div", { className: 'i-input-prepend', children: prepend }), jsx("input", { ...inputProps }), maxLength &&
|
|
3321
|
+
}), 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
3322
|
});
|
|
3064
3323
|
Input.Textarea = Textarea;
|
|
3065
3324
|
Input.Number = Number$1;
|
|
@@ -3347,38 +3606,34 @@ const displayValue = (config) => {
|
|
|
3347
3606
|
|
|
3348
3607
|
const Select = (props) => {
|
|
3349
3608
|
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
|
-
});
|
|
3609
|
+
const [filterValue, setFilterValue] = useState("");
|
|
3610
|
+
const [selectedValue, setSelectedValue] = useState(value);
|
|
3356
3611
|
const [active, setActive] = useState(false);
|
|
3357
3612
|
const formattedOptions = useMemo(() => formatOption(options), [options]);
|
|
3358
3613
|
const filterOptions = useMemo(() => {
|
|
3359
|
-
const
|
|
3614
|
+
const fv = filterValue;
|
|
3360
3615
|
if (!fv || !filter)
|
|
3361
3616
|
return formattedOptions;
|
|
3362
3617
|
const filterFn = typeof filter === "function"
|
|
3363
3618
|
? filter
|
|
3364
3619
|
: (opt) => opt.value.includes(fv) || opt.label.includes(fv);
|
|
3365
3620
|
return formattedOptions.filter(filterFn);
|
|
3366
|
-
}, [formattedOptions, filter,
|
|
3621
|
+
}, [formattedOptions, filter, filterValue]);
|
|
3367
3622
|
const changeValue = (v) => {
|
|
3368
|
-
|
|
3623
|
+
setSelectedValue(v);
|
|
3369
3624
|
onChange?.(v);
|
|
3370
3625
|
};
|
|
3371
3626
|
const displayLabel = useMemo(() => {
|
|
3372
3627
|
if (multiple) {
|
|
3373
3628
|
return "";
|
|
3374
3629
|
}
|
|
3375
|
-
const option = formattedOptions.find((opt) => opt.value ===
|
|
3376
|
-
return option ? option.label :
|
|
3377
|
-
}, [
|
|
3630
|
+
const option = formattedOptions.find((opt) => opt.value === selectedValue);
|
|
3631
|
+
return option ? option.label : selectedValue;
|
|
3632
|
+
}, [selectedValue, formattedOptions]);
|
|
3378
3633
|
const handleSelect = (value, option) => {
|
|
3379
3634
|
onSelect?.(value, option);
|
|
3380
3635
|
if (multiple) {
|
|
3381
|
-
const values = [...
|
|
3636
|
+
const values = [...selectedValue];
|
|
3382
3637
|
const i = values.findIndex((v) => v === value);
|
|
3383
3638
|
i > -1 ? values.splice(i, 1) : values.push(value);
|
|
3384
3639
|
changeValue(values);
|
|
@@ -3391,7 +3646,7 @@ const Select = (props) => {
|
|
|
3391
3646
|
setActive(visible);
|
|
3392
3647
|
if (!filter)
|
|
3393
3648
|
return;
|
|
3394
|
-
|
|
3649
|
+
setFilterValue("");
|
|
3395
3650
|
};
|
|
3396
3651
|
const handleHelperClick = (e) => {
|
|
3397
3652
|
e.stopPropagation();
|
|
@@ -3402,34 +3657,34 @@ const Select = (props) => {
|
|
|
3402
3657
|
};
|
|
3403
3658
|
const handleFilterChange = debounce({ delay: 400 }, (e) => {
|
|
3404
3659
|
const v = e.target.value;
|
|
3405
|
-
|
|
3660
|
+
setFilterValue(v);
|
|
3406
3661
|
});
|
|
3407
3662
|
const handleInputChange = (e) => {
|
|
3408
|
-
|
|
3663
|
+
setFilterValue(e.target.value);
|
|
3409
3664
|
};
|
|
3410
3665
|
useEffect(() => {
|
|
3411
|
-
|
|
3666
|
+
setSelectedValue(value);
|
|
3412
3667
|
}, [value]);
|
|
3413
3668
|
const hasValue = multiple
|
|
3414
|
-
?
|
|
3415
|
-
: !!
|
|
3669
|
+
? selectedValue.length > 0
|
|
3670
|
+
: !!selectedValue;
|
|
3416
3671
|
const clearable = !hideClear && active && hasValue;
|
|
3417
3672
|
const text = message ?? tip;
|
|
3418
3673
|
return (jsxs("label", { className: classNames("i-input-label", className, {
|
|
3419
3674
|
"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:
|
|
3675
|
+
}), 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
3676
|
[`i-input-${status}`]: status !== "normal",
|
|
3422
3677
|
"i-input-borderless": !border,
|
|
3423
3678
|
"i-input-focus": active,
|
|
3424
|
-
}), onClick: () => setActive(true), children: [prepend, jsx("input", { ref: ref, type: 'hidden', value:
|
|
3679
|
+
}), 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
3680
|
"i-select-multiple": multiple,
|
|
3426
3681
|
}), children: displayValue({
|
|
3427
3682
|
options: formattedOptions,
|
|
3428
|
-
value:
|
|
3683
|
+
value: selectedValue,
|
|
3429
3684
|
multiple,
|
|
3430
3685
|
maxDisplay,
|
|
3431
3686
|
onSelect: handleSelect,
|
|
3432
|
-
}) })) : (jsx("input", { className: 'i-input i-select', placeholder: placeholder, readOnly: true }))) : null, !multiple && (jsx("input", { value: active ?
|
|
3687
|
+
}) })) : (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
3688
|
};
|
|
3434
3689
|
|
|
3435
3690
|
const ColorMethods = {
|
|
@@ -3439,23 +3694,21 @@ const ColorMethods = {
|
|
|
3439
3694
|
};
|
|
3440
3695
|
function Footer(props) {
|
|
3441
3696
|
const { value, type, onTypeChange, onChange, onOk } = props;
|
|
3442
|
-
const
|
|
3443
|
-
|
|
3444
|
-
type,
|
|
3445
|
-
});
|
|
3697
|
+
const [inputValue, setInputValue] = useState(value);
|
|
3698
|
+
const [colorType, setColorType] = useState(type);
|
|
3446
3699
|
const handleChange = (v) => {
|
|
3447
|
-
|
|
3700
|
+
setInputValue(v);
|
|
3448
3701
|
onChange(v);
|
|
3449
3702
|
};
|
|
3450
3703
|
const handleTypeChange = (t) => {
|
|
3451
|
-
|
|
3704
|
+
setColorType(t);
|
|
3452
3705
|
onTypeChange(t);
|
|
3453
3706
|
};
|
|
3454
3707
|
useEffect(() => {
|
|
3455
|
-
|
|
3456
|
-
|
|
3708
|
+
setInputValue(value);
|
|
3709
|
+
setColorType(type);
|
|
3457
3710
|
}, [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:
|
|
3711
|
+
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
3712
|
}
|
|
3460
3713
|
|
|
3461
3714
|
const Handle = (props) => {
|
|
@@ -3465,48 +3718,51 @@ const Handle = (props) => {
|
|
|
3465
3718
|
|
|
3466
3719
|
function ColorPicker(props) {
|
|
3467
3720
|
const { value, type = "HEX", disabledAlpha, children, usePanel, handle = "both", placeholder = "Colors", popupProps, onChange, } = props;
|
|
3468
|
-
const
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
visible: popupProps?.visible,
|
|
3473
|
-
});
|
|
3721
|
+
const [colorType, setColorType] = useState(type);
|
|
3722
|
+
const [colorValue, setColorValue] = useState(value);
|
|
3723
|
+
const [syncValue, setSyncValue] = useState(value);
|
|
3724
|
+
const [visible, setVisible] = useState(popupProps?.visible);
|
|
3474
3725
|
const handleChange = (target) => {
|
|
3475
|
-
|
|
3726
|
+
setSyncValue(target);
|
|
3476
3727
|
};
|
|
3477
3728
|
const handleComplete = (target) => {
|
|
3478
|
-
const method = ColorMethods[
|
|
3729
|
+
const method = ColorMethods[colorType];
|
|
3479
3730
|
if (target.a !== 1) {
|
|
3480
3731
|
target.a = parseFloat(target.a.toFixed(3));
|
|
3481
3732
|
}
|
|
3482
|
-
|
|
3733
|
+
setColorValue(target[method]?.());
|
|
3483
3734
|
};
|
|
3484
3735
|
const handleVisibleChange = (v) => {
|
|
3485
|
-
|
|
3736
|
+
setVisible(v);
|
|
3486
3737
|
popupProps?.onVisibleChange?.(v);
|
|
3487
3738
|
};
|
|
3488
3739
|
const handleTypeChange = (t) => {
|
|
3489
3740
|
const method = ColorMethods[t];
|
|
3490
|
-
|
|
3491
|
-
|
|
3741
|
+
setColorType(t);
|
|
3742
|
+
setColorValue(syncValue?.[method]?.());
|
|
3492
3743
|
};
|
|
3493
3744
|
const handleValueChange = (v) => {
|
|
3494
|
-
|
|
3495
|
-
|
|
3745
|
+
setColorValue(v);
|
|
3746
|
+
setSyncValue(v);
|
|
3496
3747
|
};
|
|
3497
3748
|
const handleOk = () => {
|
|
3498
|
-
onChange?.(
|
|
3499
|
-
|
|
3749
|
+
onChange?.(colorValue);
|
|
3750
|
+
setVisible(false);
|
|
3500
3751
|
};
|
|
3501
3752
|
useEffect(() => {
|
|
3502
|
-
|
|
3503
|
-
|
|
3753
|
+
setSyncValue(value);
|
|
3754
|
+
setColorValue(value);
|
|
3504
3755
|
}, [value]);
|
|
3756
|
+
useEffect(() => {
|
|
3757
|
+
if (popupProps?.visible !== undefined) {
|
|
3758
|
+
setVisible(popupProps.visible);
|
|
3759
|
+
}
|
|
3760
|
+
}, [popupProps?.visible]);
|
|
3505
3761
|
if (usePanel) {
|
|
3506
3762
|
return jsx(ColorsPanel, { ...props });
|
|
3507
3763
|
}
|
|
3508
|
-
return (jsx(Popup, { trigger: 'click', touchable: true, position: 'bottom', ...popupProps, visible:
|
|
3509
|
-
return (jsxs(Fragment, { children: [panel, jsx(Footer, { value:
|
|
3764
|
+
return (jsx(Popup, { trigger: 'click', touchable: true, position: 'bottom', ...popupProps, visible: visible, content: jsx(ColorsPanel, { value: syncValue, disabledAlpha: disabledAlpha, panelRender: (panel) => {
|
|
3765
|
+
return (jsxs(Fragment, { children: [panel, jsx(Footer, { value: colorValue, type: colorType, onTypeChange: handleTypeChange, onChange: handleValueChange, onOk: handleOk })] }));
|
|
3510
3766
|
}, onChange: handleChange, onChangeComplete: handleComplete }), onVisibleChange: handleVisibleChange, children: children ?? (jsx(Handle, { color: value, handle: handle, placeholder: placeholder })) }));
|
|
3511
3767
|
}
|
|
3512
3768
|
|
|
@@ -3556,61 +3812,56 @@ const YearMonth = (props) => {
|
|
|
3556
3812
|
};
|
|
3557
3813
|
const Panel$1 = (props) => {
|
|
3558
3814
|
const { value, unitYear, unitMonth, renderDate, renderMonth = (m) => m, renderYear = (y) => y, disabledDate, onDateClick, } = props;
|
|
3559
|
-
const
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
selectable: false,
|
|
3565
|
-
});
|
|
3815
|
+
const [today, setToday] = useState(value);
|
|
3816
|
+
const [month, setMonth] = useState(value || dayjs());
|
|
3817
|
+
const [selectedYear, setSelectedYear] = useState(dayjs());
|
|
3818
|
+
const [years, setYears] = useState([]);
|
|
3819
|
+
const [selectable, setSelectable] = useState(false);
|
|
3566
3820
|
const $years = useRef(null);
|
|
3567
3821
|
const handleOperateMonth = (next) => {
|
|
3568
|
-
|
|
3822
|
+
setMonth((m) => m[next ? "add" : "subtract"](1, "month"));
|
|
3569
3823
|
};
|
|
3570
3824
|
const handleChangeDate = (date) => {
|
|
3571
|
-
if (date.isSame(
|
|
3825
|
+
if (date.isSame(today, "day"))
|
|
3572
3826
|
return;
|
|
3573
|
-
if (!date.isSame(
|
|
3574
|
-
|
|
3827
|
+
if (!date.isSame(month, "month")) {
|
|
3828
|
+
setMonth(date);
|
|
3575
3829
|
}
|
|
3576
|
-
|
|
3830
|
+
setToday(date);
|
|
3577
3831
|
onDateClick?.(date);
|
|
3578
3832
|
};
|
|
3579
3833
|
const handleChangeMonth = (month) => {
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
.month(month - 1);
|
|
3583
|
-
state.selectable = false;
|
|
3834
|
+
setMonth((m) => m.year(selectedYear.year()).month(month - 1));
|
|
3835
|
+
setSelectable(false);
|
|
3584
3836
|
};
|
|
3585
3837
|
const getMoreYears = throttle({ interval: 100 }, (e) => {
|
|
3586
3838
|
const isUp = e.deltaY < 0;
|
|
3587
|
-
|
|
3839
|
+
setYears((ys) => ys.map((y) => y + (isUp ? -1 : 1)));
|
|
3588
3840
|
});
|
|
3589
3841
|
useEffect(() => {
|
|
3590
|
-
if (!
|
|
3842
|
+
if (!selectable)
|
|
3591
3843
|
return;
|
|
3592
|
-
|
|
3593
|
-
const y =
|
|
3594
|
-
const
|
|
3595
|
-
|
|
3596
|
-
}, [
|
|
3844
|
+
setSelectedYear(month);
|
|
3845
|
+
const y = month.year();
|
|
3846
|
+
const nextYears = Array.from({ length: 7 }).map((_, i) => y - 3 + i);
|
|
3847
|
+
setYears([...nextYears]);
|
|
3848
|
+
}, [selectable, month]);
|
|
3597
3849
|
useEffect(() => {
|
|
3598
|
-
|
|
3599
|
-
|
|
3850
|
+
setToday(value);
|
|
3851
|
+
setMonth(value || dayjs());
|
|
3600
3852
|
}, [value]);
|
|
3601
|
-
return (jsxs("div", { className: 'i-datepicker', children: [jsxs("div", { className: 'i-datepicker-units', children: [jsx(YearMonth, { value:
|
|
3602
|
-
"i-datepicker-active":
|
|
3853
|
+
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", {
|
|
3854
|
+
"i-datepicker-active": selectable,
|
|
3603
3855
|
}), children: [jsx(Helpericon, { active: true, className: 'i-datepicker-close', onClick: (e) => {
|
|
3604
3856
|
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) => {
|
|
3857
|
+
setSelectable(false);
|
|
3858
|
+
} }), jsx("div", { ref: $years, className: 'i-datepicker-years', onWheel: getMoreYears, children: years.map((y) => (jsx("a", { className: classNames("i-datepicker-year", {
|
|
3859
|
+
"i-datepicker-active": y === selectedYear.year(),
|
|
3860
|
+
}), onClick: () => setSelectedYear((sy) => sy.year(y)), children: renderYear(y) }, y))) }), jsx("div", { className: 'i-datepicker-months', children: MONTHS.map((m) => {
|
|
3610
3861
|
return (jsx("a", { className: classNames("i-datepicker-month", {
|
|
3611
|
-
"i-datepicker-active": m ===
|
|
3862
|
+
"i-datepicker-active": m === month.month() + 1,
|
|
3612
3863
|
}), onClick: () => handleChangeMonth(m), children: renderMonth(m) }, m));
|
|
3613
|
-
}) })] }), jsx(Dates, { value:
|
|
3864
|
+
}) })] }), jsx(Dates, { value: today, month: month, disabledDate: disabledDate, onDateClick: handleChangeDate, renderDate: renderDate })] }));
|
|
3614
3865
|
};
|
|
3615
3866
|
|
|
3616
3867
|
dayjs.extend(customParseFormat);
|
|
@@ -3618,29 +3869,27 @@ const FORMATTYPES = ["YYYY-MM-DD", "YYYY-M-D", "YYYY/MM/DD", "YYYY/M/D"];
|
|
|
3618
3869
|
const FORMAT$1 = "YYYY-MM-DD";
|
|
3619
3870
|
const Datepicker = (props) => {
|
|
3620
3871
|
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
|
-
});
|
|
3872
|
+
const [inputValue, setInputValue] = useState(value);
|
|
3624
3873
|
const [active, setActive] = useState(false);
|
|
3625
3874
|
const dayJsValue = useMemo(() => {
|
|
3626
|
-
if (!
|
|
3875
|
+
if (!inputValue)
|
|
3627
3876
|
return null;
|
|
3628
|
-
const date = dayjs(
|
|
3877
|
+
const date = dayjs(inputValue, format, true);
|
|
3629
3878
|
if (date.isValid())
|
|
3630
3879
|
return date;
|
|
3631
3880
|
return null;
|
|
3632
|
-
}, [
|
|
3881
|
+
}, [inputValue, format]);
|
|
3633
3882
|
const handleDateClick = (date) => {
|
|
3634
3883
|
handleChange(date.format(format));
|
|
3635
3884
|
};
|
|
3636
3885
|
const handleChange = (v) => {
|
|
3637
|
-
|
|
3886
|
+
setInputValue(v);
|
|
3638
3887
|
onChange?.(v);
|
|
3639
3888
|
};
|
|
3640
3889
|
const handleSetDate = () => {
|
|
3641
|
-
if (!
|
|
3890
|
+
if (!inputValue)
|
|
3642
3891
|
return;
|
|
3643
|
-
const date = dayjs(
|
|
3892
|
+
const date = dayjs(inputValue, FORMATTYPES, true);
|
|
3644
3893
|
if (date.isValid()) {
|
|
3645
3894
|
handleChange(date.format(format));
|
|
3646
3895
|
return;
|
|
@@ -3656,9 +3905,9 @@ const Datepicker = (props) => {
|
|
|
3656
3905
|
setActive(v);
|
|
3657
3906
|
};
|
|
3658
3907
|
useEffect(() => {
|
|
3659
|
-
|
|
3908
|
+
setInputValue(value);
|
|
3660
3909
|
}, [value]);
|
|
3661
|
-
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start', onVisibleChange: handleVisibleChange,
|
|
3910
|
+
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start', onVisibleChange: handleVisibleChange, 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
3911
|
};
|
|
3663
3912
|
|
|
3664
3913
|
function Items(props) {
|
|
@@ -3681,12 +3930,10 @@ const UnitMaps = {
|
|
|
3681
3930
|
};
|
|
3682
3931
|
function Panel(props) {
|
|
3683
3932
|
const { value, stepH = 1, stepM = 1, stepS = 1, format, periods, renderItem, onChange, onFallback, } = props;
|
|
3684
|
-
const
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
second: undefined,
|
|
3689
|
-
});
|
|
3933
|
+
const [period, setPeriod] = useState(undefined);
|
|
3934
|
+
const [hour, setHour] = useState(undefined);
|
|
3935
|
+
const [minute, setMinute] = useState(undefined);
|
|
3936
|
+
const [second, setSecond] = useState(undefined);
|
|
3690
3937
|
const [hours, minutes, seconds] = useMemo(() => {
|
|
3691
3938
|
const hasH = format.includes("h");
|
|
3692
3939
|
const hasM = format.includes("m");
|
|
@@ -3702,29 +3949,45 @@ function Panel(props) {
|
|
|
3702
3949
|
: [];
|
|
3703
3950
|
return [hours, minutes, seconds];
|
|
3704
3951
|
}, [stepH, stepM, stepS, format, periods]);
|
|
3705
|
-
const updateValue = () => {
|
|
3952
|
+
const updateValue = (next) => {
|
|
3953
|
+
const nextPeriod = next?.period ?? period;
|
|
3954
|
+
const nextHour = next?.hour ?? hour;
|
|
3955
|
+
const nextMinute = next?.minute ?? minute;
|
|
3956
|
+
const nextSecond = next?.second ?? second;
|
|
3706
3957
|
const reg = /(hh|h){1}|(mm|m){1}|(ss|s){1}/gi;
|
|
3707
3958
|
let result = format.replace(reg, (pattern) => {
|
|
3708
3959
|
const p = pattern.toLowerCase();
|
|
3709
3960
|
const u = UnitMaps[p];
|
|
3710
|
-
const n =
|
|
3961
|
+
const n = u === "hour"
|
|
3962
|
+
? (nextHour ?? 0)
|
|
3963
|
+
: u === "minute"
|
|
3964
|
+
? (nextMinute ?? 0)
|
|
3965
|
+
: (nextSecond ?? 0);
|
|
3711
3966
|
return p.length > 1 && n < 10 ? `0${n ?? 0}` : n ?? 0;
|
|
3712
3967
|
});
|
|
3713
3968
|
if (periods && hours.length > 0) {
|
|
3714
|
-
result = `${
|
|
3969
|
+
result = `${nextPeriod ?? periods[0]} ${result}`;
|
|
3715
3970
|
}
|
|
3716
3971
|
onChange(result);
|
|
3717
3972
|
};
|
|
3718
3973
|
const handleSetTime = (v, unit) => {
|
|
3719
|
-
|
|
3720
|
-
|
|
3974
|
+
const next = { period, hour, minute, second, [unit]: v };
|
|
3975
|
+
if (unit === "period")
|
|
3976
|
+
setPeriod(v);
|
|
3977
|
+
if (unit === "hour")
|
|
3978
|
+
setHour(v);
|
|
3979
|
+
if (unit === "minute")
|
|
3980
|
+
setMinute(v);
|
|
3981
|
+
if (unit === "second")
|
|
3982
|
+
setSecond(v);
|
|
3983
|
+
updateValue(next);
|
|
3721
3984
|
};
|
|
3722
3985
|
useEffect(() => {
|
|
3723
3986
|
let time = value ?? "";
|
|
3724
3987
|
if (periods && hours.length > 0 && value) {
|
|
3725
3988
|
const [p, t] = value.split(" ");
|
|
3726
3989
|
time = t ?? "";
|
|
3727
|
-
|
|
3990
|
+
setPeriod(periods.includes(p) ? p : undefined);
|
|
3728
3991
|
}
|
|
3729
3992
|
const nums = time.match(/\d+/g) ?? [];
|
|
3730
3993
|
if (!nums.length) {
|
|
@@ -3732,40 +3995,41 @@ function Panel(props) {
|
|
|
3732
3995
|
return;
|
|
3733
3996
|
}
|
|
3734
3997
|
let i = 0;
|
|
3998
|
+
const parsed = {
|
|
3999
|
+
hour: undefined,
|
|
4000
|
+
minute: undefined,
|
|
4001
|
+
second: undefined,
|
|
4002
|
+
};
|
|
3735
4003
|
const r = format.replace(/(hh|h)+|(mm|m)+|(ss|s)+/gi, (p) => {
|
|
3736
4004
|
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;
|
|
4005
|
+
const o = Math.min(59, n);
|
|
4006
|
+
parsed[UnitMaps[p]] = o;
|
|
3743
4007
|
return p.length > 1 && o < 10 ? `0${o}` : o;
|
|
3744
4008
|
});
|
|
4009
|
+
setHour(parsed.hour);
|
|
4010
|
+
setMinute(parsed.minute);
|
|
4011
|
+
setSecond(parsed.second);
|
|
3745
4012
|
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:
|
|
4013
|
+
}, [value, format, hours.length, periods]);
|
|
4014
|
+
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
4015
|
}
|
|
3749
4016
|
|
|
3750
4017
|
const FORMAT = "hh:mm:ss";
|
|
3751
4018
|
function TimePicker(props) {
|
|
3752
4019
|
const { name, value, format = FORMAT, periods, placeholder = props.format ?? FORMAT, className, renderItem, onChange, onBlur, popupProps, ...restProps } = props;
|
|
3753
|
-
const
|
|
3754
|
-
|
|
3755
|
-
safeValue: undefined,
|
|
3756
|
-
});
|
|
4020
|
+
const [timeValue, setTimeValue] = useState(value);
|
|
4021
|
+
const [safeValue, setSafeValue] = useState(undefined);
|
|
3757
4022
|
const [active, setActive] = useState(false);
|
|
3758
4023
|
const handleChange = (v) => {
|
|
3759
|
-
|
|
4024
|
+
setTimeValue(v);
|
|
3760
4025
|
};
|
|
3761
4026
|
const handleFallback = (v) => {
|
|
3762
|
-
|
|
4027
|
+
setSafeValue(v);
|
|
3763
4028
|
};
|
|
3764
4029
|
const handleValidTime = () => {
|
|
3765
|
-
if (!
|
|
4030
|
+
if (!timeValue)
|
|
3766
4031
|
return;
|
|
3767
|
-
|
|
3768
|
-
handleChange(state.safeValue);
|
|
4032
|
+
setTimeValue(safeValue);
|
|
3769
4033
|
};
|
|
3770
4034
|
const handleBlur = (e) => {
|
|
3771
4035
|
onBlur?.(e);
|
|
@@ -3776,9 +4040,9 @@ function TimePicker(props) {
|
|
|
3776
4040
|
setActive(v);
|
|
3777
4041
|
};
|
|
3778
4042
|
useEffect(() => {
|
|
3779
|
-
|
|
4043
|
+
setTimeValue(value);
|
|
3780
4044
|
}, [value]);
|
|
3781
|
-
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start',
|
|
4045
|
+
return (jsx(Popup, { visible: active, trigger: 'click', position: 'bottom', arrow: false, align: 'start', ...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
4046
|
}
|
|
3783
4047
|
|
|
3784
4048
|
const defaultOk = {
|
|
@@ -3789,7 +4053,7 @@ const defaultCancel = {
|
|
|
3789
4053
|
secondary: true,
|
|
3790
4054
|
};
|
|
3791
4055
|
const Popconfirm = (props) => {
|
|
3792
|
-
const { trigger = "click", visible, icon = jsx(Icon, { icon: jsx(InfoOutlined, {}), className: 'error', size: '1.2em' }), content, okButtonProps, cancelButtonProps, children, align
|
|
4056
|
+
const { trigger = "click", visible, icon = jsx(Icon, { icon: jsx(InfoOutlined, {}), className: 'error', size: '1.2em' }), content, okButtonProps, cancelButtonProps, children, align, position = "top", offset = 12, extra, onOk, onClose, ...restProps } = props;
|
|
3793
4057
|
const state = useReactive({
|
|
3794
4058
|
loading: false,
|
|
3795
4059
|
visible,
|
|
@@ -3838,16 +4102,14 @@ function RadioItem(props) {
|
|
|
3838
4102
|
|
|
3839
4103
|
function Radio(props) {
|
|
3840
4104
|
const { label, name, options, value, type = "default", status = "normal", message, optionInline = true, labelInline, disabled, required, className, renderItem, onChange, } = props;
|
|
3841
|
-
const
|
|
3842
|
-
value,
|
|
3843
|
-
});
|
|
4105
|
+
const [selectedValue, setSelectedValue] = useState(value);
|
|
3844
4106
|
const formattedOptions = useMemo(() => formatOption(options), [options]);
|
|
3845
4107
|
const handleChange = (value, e) => {
|
|
3846
|
-
|
|
4108
|
+
setSelectedValue(value);
|
|
3847
4109
|
onChange?.(value, e);
|
|
3848
4110
|
};
|
|
3849
4111
|
useEffect(() => {
|
|
3850
|
-
|
|
4112
|
+
setSelectedValue(value);
|
|
3851
4113
|
}, [value]);
|
|
3852
4114
|
return (jsxs("div", { className: classNames("i-radio i-input-label", {
|
|
3853
4115
|
[`i-radio-${status}`]: status !== "normal",
|
|
@@ -3856,7 +4118,7 @@ function Radio(props) {
|
|
|
3856
4118
|
"i-options-block": !optionInline,
|
|
3857
4119
|
"i-radio-options-button": type === "button",
|
|
3858
4120
|
}), children: formattedOptions.map((option) => {
|
|
3859
|
-
const checked =
|
|
4121
|
+
const checked = selectedValue === option.value;
|
|
3860
4122
|
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
4123
|
}) })] }));
|
|
3862
4124
|
}
|
|
@@ -4313,25 +4575,23 @@ const Tabs = ((props) => {
|
|
|
4313
4575
|
const barRef = useRef(null);
|
|
4314
4576
|
const navsRef = useRef(null);
|
|
4315
4577
|
const contentsRef = useRef(new Map());
|
|
4316
|
-
const
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
tabs: [],
|
|
4324
|
-
});
|
|
4578
|
+
const [activeKey, setActiveKey] = useState(active);
|
|
4579
|
+
const [prevActiveKey, setPrevActiveKey] = useState(undefined);
|
|
4580
|
+
const [barStyle, setBarStyle] = useState({});
|
|
4581
|
+
const [cachedTabs, setCachedTabs] = useState([]);
|
|
4582
|
+
const [overflow, setOverflow] = useState(false);
|
|
4583
|
+
const [moreTabs, setMoreTabs] = useState([]);
|
|
4584
|
+
const [tabs, setTabs] = useState([]);
|
|
4325
4585
|
const { observe, unobserve } = useIntersectionObserver();
|
|
4326
4586
|
const size = useSize(navsRef);
|
|
4327
4587
|
useEffect(() => {
|
|
4328
4588
|
contentsRef.current.clear();
|
|
4329
4589
|
if (!items) {
|
|
4330
4590
|
if (!children) {
|
|
4331
|
-
|
|
4591
|
+
setTabs([]);
|
|
4332
4592
|
return;
|
|
4333
4593
|
}
|
|
4334
|
-
|
|
4594
|
+
setTabs(Children.map(children, (node, i) => {
|
|
4335
4595
|
const { key, props: nodeProps } = node;
|
|
4336
4596
|
const { title, children: tabChildren, content, keepDOM, closable, } = nodeProps;
|
|
4337
4597
|
const tabKey = String(key ?? i);
|
|
@@ -4342,10 +4602,10 @@ const Tabs = ((props) => {
|
|
|
4342
4602
|
keepDOM,
|
|
4343
4603
|
closable,
|
|
4344
4604
|
};
|
|
4345
|
-
});
|
|
4605
|
+
}) ?? []);
|
|
4346
4606
|
return;
|
|
4347
4607
|
}
|
|
4348
|
-
|
|
4608
|
+
setTabs(items.map((item, i) => {
|
|
4349
4609
|
if (["string", "number"].includes(typeof item)) {
|
|
4350
4610
|
const key = String(item);
|
|
4351
4611
|
return { key, title: item };
|
|
@@ -4357,90 +4617,99 @@ const Tabs = ((props) => {
|
|
|
4357
4617
|
...rest,
|
|
4358
4618
|
key,
|
|
4359
4619
|
};
|
|
4360
|
-
});
|
|
4620
|
+
}));
|
|
4361
4621
|
}, [children, items]);
|
|
4362
4622
|
const add = (tab) => {
|
|
4363
|
-
const tkey = String(tab.key ??
|
|
4364
|
-
const i =
|
|
4623
|
+
const tkey = String(tab.key ?? tabs.length);
|
|
4624
|
+
const i = tabs.findIndex((t) => t.key === tkey);
|
|
4365
4625
|
if (i > -1) {
|
|
4366
|
-
open(
|
|
4626
|
+
open(tabs[i].key ?? `${i}`);
|
|
4367
4627
|
return;
|
|
4368
4628
|
}
|
|
4369
4629
|
contentsRef.current.set(tkey, tab.content);
|
|
4370
4630
|
const { content, ...rest } = tab;
|
|
4371
|
-
|
|
4631
|
+
setTabs((ts) => [...ts, { ...rest, key: tkey }]);
|
|
4372
4632
|
open(tkey);
|
|
4373
4633
|
};
|
|
4374
4634
|
const close = (key) => {
|
|
4375
|
-
const i =
|
|
4635
|
+
const i = tabs.findIndex((t) => t.key === key);
|
|
4376
4636
|
if (i < 0)
|
|
4377
4637
|
return;
|
|
4378
4638
|
contentsRef.current.delete(key);
|
|
4379
|
-
|
|
4380
|
-
|
|
4639
|
+
const nextTabs = [...tabs];
|
|
4640
|
+
nextTabs.splice(i, 1);
|
|
4641
|
+
setTabs(nextTabs);
|
|
4642
|
+
if (activeKey !== key)
|
|
4381
4643
|
return;
|
|
4382
|
-
const next =
|
|
4383
|
-
open(
|
|
4644
|
+
const next = nextTabs[i] || nextTabs[i - 1];
|
|
4645
|
+
open(prevActiveKey ?? next?.key ?? "");
|
|
4384
4646
|
};
|
|
4385
4647
|
const open = (key) => {
|
|
4386
|
-
if (key ===
|
|
4648
|
+
if (key === activeKey) {
|
|
4387
4649
|
if (!toggable)
|
|
4388
4650
|
return;
|
|
4389
4651
|
onTabChange?.(undefined, key);
|
|
4390
|
-
|
|
4391
|
-
|
|
4652
|
+
setActiveKey(undefined);
|
|
4653
|
+
setBarStyle({
|
|
4392
4654
|
height: 0,
|
|
4393
4655
|
width: 0,
|
|
4394
|
-
};
|
|
4656
|
+
});
|
|
4395
4657
|
return;
|
|
4396
4658
|
}
|
|
4397
|
-
|
|
4398
|
-
onTabChange?.(key,
|
|
4399
|
-
|
|
4659
|
+
setPrevActiveKey(activeKey);
|
|
4660
|
+
onTabChange?.(key, activeKey);
|
|
4661
|
+
setActiveKey(key);
|
|
4400
4662
|
};
|
|
4401
4663
|
useEffect(() => {
|
|
4402
4664
|
if (!size || hideMore || !observe)
|
|
4403
4665
|
return;
|
|
4404
4666
|
const { scrollHeight, scrollWidth } = navsRef.current;
|
|
4405
4667
|
const { width, height } = size;
|
|
4406
|
-
|
|
4407
|
-
|
|
4668
|
+
const nextOverflow = scrollHeight > height || scrollWidth > width;
|
|
4669
|
+
setOverflow(nextOverflow);
|
|
4670
|
+
if (!nextOverflow)
|
|
4408
4671
|
return;
|
|
4409
4672
|
navRefs.current.map((nav, i) => {
|
|
4410
4673
|
if (!nav)
|
|
4411
4674
|
return;
|
|
4412
4675
|
observe(nav, (tar, visible) => {
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4676
|
+
setTabs((ts) => {
|
|
4677
|
+
if (!ts[i])
|
|
4678
|
+
return ts;
|
|
4679
|
+
const nextTabs = ts.map((t, idx) => idx === i ? { ...t, intersecting: visible } : t);
|
|
4680
|
+
setMoreTabs(nextTabs.filter((tab) => !tab.intersecting));
|
|
4681
|
+
return nextTabs;
|
|
4682
|
+
});
|
|
4417
4683
|
});
|
|
4418
4684
|
});
|
|
4419
|
-
}, [size, hideMore,
|
|
4685
|
+
}, [size, hideMore, tabs.length, observe]);
|
|
4420
4686
|
useEffect(() => {
|
|
4421
|
-
if (!bar || type === "pane" ||
|
|
4687
|
+
if (!bar || type === "pane" || activeKey === undefined) {
|
|
4422
4688
|
return;
|
|
4423
4689
|
}
|
|
4424
|
-
const index =
|
|
4690
|
+
const index = tabs.findIndex((tab) => tab.key === activeKey);
|
|
4425
4691
|
setTimeout(() => {
|
|
4426
4692
|
const nav = navRefs.current[index];
|
|
4427
4693
|
if (!nav)
|
|
4428
4694
|
return;
|
|
4429
|
-
if (
|
|
4430
|
-
|
|
4431
|
-
|
|
4695
|
+
if (tabs[index]?.keepDOM && activeKey) {
|
|
4696
|
+
setCachedTabs((keys) => {
|
|
4697
|
+
if (keys.includes(activeKey))
|
|
4698
|
+
return keys;
|
|
4699
|
+
return [activeKey, ...keys];
|
|
4700
|
+
});
|
|
4432
4701
|
}
|
|
4433
4702
|
const { offsetHeight, offsetLeft, offsetTop, offsetWidth } = nav;
|
|
4434
4703
|
const isLine = type === "line";
|
|
4435
|
-
|
|
4704
|
+
setBarStyle({
|
|
4436
4705
|
height: !vertical && isLine ? ".25em" : offsetHeight,
|
|
4437
4706
|
width: vertical && isLine ? ".25em" : offsetWidth,
|
|
4438
4707
|
transform: `translate(${offsetLeft}px, ${offsetTop}px)`,
|
|
4439
|
-
};
|
|
4708
|
+
});
|
|
4440
4709
|
}, 16);
|
|
4441
|
-
}, [
|
|
4710
|
+
}, [activeKey, bar, size, tabs, type, vertical]);
|
|
4442
4711
|
useEffect(() => {
|
|
4443
|
-
if (active === undefined ||
|
|
4712
|
+
if (active === undefined || activeKey === active)
|
|
4444
4713
|
return;
|
|
4445
4714
|
open(active);
|
|
4446
4715
|
}, [active]);
|
|
@@ -4450,7 +4719,7 @@ const Tabs = ((props) => {
|
|
|
4450
4719
|
return () => {
|
|
4451
4720
|
navRefs.current?.map(unobserve);
|
|
4452
4721
|
};
|
|
4453
|
-
}, [
|
|
4722
|
+
}, [tabs.length, hideMore, unobserve]);
|
|
4454
4723
|
useEffect(() => {
|
|
4455
4724
|
if (!navsRef.current || vertical)
|
|
4456
4725
|
return;
|
|
@@ -4480,26 +4749,26 @@ const Tabs = ((props) => {
|
|
|
4480
4749
|
}));
|
|
4481
4750
|
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
4751
|
"i-tab-navs-vertical": vertical,
|
|
4483
|
-
}), children: [prepend, jsxs("div", { ref: navsRef, className: classNames("i-tab-navs", `justify-${navsJustify}`), children: [
|
|
4752
|
+
}), children: [prepend, jsxs("div", { ref: navsRef, className: classNames("i-tab-navs", `justify-${navsJustify}`), children: [tabs.map((tab, i) => {
|
|
4484
4753
|
const { title, key = `${i}`, closable } = tab;
|
|
4485
4754
|
return (jsxs("a", { ref: (ref) => (navRefs.current[i] = ref), className: classNames("i-tab-nav", {
|
|
4486
|
-
"i-tab-active":
|
|
4755
|
+
"i-tab-active": activeKey === key,
|
|
4487
4756
|
}), onClick: () => open(key), children: [title, closable && (jsx(Helpericon, { as: 'i', active: true, className: 'i-tab-nav-close', onClick: (e) => {
|
|
4488
4757
|
e.stopPropagation();
|
|
4489
4758
|
close(key);
|
|
4490
4759
|
} }))] }, key));
|
|
4491
|
-
}), bar && (jsx("span", { ref: barRef, className: classNames("i-tab-navs-bar", barClass), style:
|
|
4760
|
+
}), 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
4761
|
const { key = `${i}`, title } = tab;
|
|
4493
|
-
const isActive =
|
|
4762
|
+
const isActive = activeKey === key;
|
|
4494
4763
|
return (jsx("a", { className: classNames("i-tab-nav", {
|
|
4495
4764
|
"i-tab-active": isActive,
|
|
4496
4765
|
}), onClick: () => open(key), children: title }, key));
|
|
4497
|
-
}) }), children: renderMore(
|
|
4766
|
+
}) }), children: renderMore(moreTabs) })), append] }), jsx("div", { className: 'i-tab-contents', children: tabs.map((tab, i) => {
|
|
4498
4767
|
const key = tab.key ?? `${i}`;
|
|
4499
4768
|
const content = contentsRef.current.get(key);
|
|
4500
|
-
const isActive =
|
|
4769
|
+
const isActive = activeKey === key;
|
|
4501
4770
|
const show = isActive ||
|
|
4502
|
-
(key !== undefined &&
|
|
4771
|
+
(key !== undefined && cachedTabs.includes(key));
|
|
4503
4772
|
return (show && (jsx("div", { className: classNames("i-tab-content", {
|
|
4504
4773
|
"i-tab-active": isActive,
|
|
4505
4774
|
}), children: content }, key)));
|
|
@@ -4578,14 +4847,12 @@ const defaultNodeProps = {
|
|
|
4578
4847
|
};
|
|
4579
4848
|
const Tree = (props) => {
|
|
4580
4849
|
const { data = [], ref, selected, checked = [], disabledRelated, nodeProps, onItemSelect, onItemCheck, ...restProps } = props;
|
|
4581
|
-
const
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
nodeMaps: new Map(),
|
|
4586
|
-
});
|
|
4850
|
+
const [selectedKey, setSelectedKey] = useState(selected);
|
|
4851
|
+
const [checkedKeys, setCheckedKeys] = useState(checked);
|
|
4852
|
+
const [partofs, setPartofs] = useState({});
|
|
4853
|
+
const nodeMapsRef = useRef(new Map());
|
|
4587
4854
|
const oNodeProps = Object.assign({}, defaultNodeProps, nodeProps);
|
|
4588
|
-
const isChecked = (key) =>
|
|
4855
|
+
const isChecked = (key) => checkedKeys.includes(key || "");
|
|
4589
4856
|
const checkItem = (item, checked, direction) => {
|
|
4590
4857
|
const { key = "", parent, children } = item;
|
|
4591
4858
|
const shouldChanged = { [key]: checked };
|
|
@@ -4637,29 +4904,30 @@ const Tree = (props) => {
|
|
|
4637
4904
|
const handleCheck = (item, checked) => {
|
|
4638
4905
|
const [shouldChanged, partofs] = checkItem(item, checked);
|
|
4639
4906
|
const changedKeys = Object.keys(shouldChanged);
|
|
4640
|
-
|
|
4641
|
-
? Array.from(new Set([...
|
|
4642
|
-
:
|
|
4643
|
-
|
|
4644
|
-
|
|
4907
|
+
const nextChecked = checked
|
|
4908
|
+
? Array.from(new Set([...checkedKeys, ...changedKeys]))
|
|
4909
|
+
: checkedKeys.filter((k) => !changedKeys.includes(k));
|
|
4910
|
+
setCheckedKeys(nextChecked);
|
|
4911
|
+
setPartofs((p) => ({ ...p, ...partofs }));
|
|
4912
|
+
onItemCheck?.(item, checked, nextChecked);
|
|
4645
4913
|
};
|
|
4646
4914
|
const handleSelect = (key, item) => {
|
|
4647
4915
|
if (!props.selectable)
|
|
4648
4916
|
return;
|
|
4649
|
-
|
|
4917
|
+
setSelectedKey(key);
|
|
4650
4918
|
onItemSelect?.(key, item);
|
|
4651
4919
|
};
|
|
4652
4920
|
useEffect(() => {
|
|
4653
4921
|
if (selected === undefined)
|
|
4654
4922
|
return;
|
|
4655
|
-
|
|
4923
|
+
setSelectedKey(selected);
|
|
4656
4924
|
}, [selected]);
|
|
4657
4925
|
useEffect(() => {
|
|
4658
|
-
|
|
4926
|
+
nodeMapsRef.current.clear();
|
|
4659
4927
|
const { key, children } = oNodeProps;
|
|
4660
4928
|
const recursive = (nodes) => {
|
|
4661
4929
|
nodes.map((o) => {
|
|
4662
|
-
|
|
4930
|
+
nodeMapsRef.current.set(o[key], o);
|
|
4663
4931
|
o[children]?.length > 0 && recursive(o[children]);
|
|
4664
4932
|
});
|
|
4665
4933
|
};
|
|
@@ -4669,22 +4937,22 @@ const Tree = (props) => {
|
|
|
4669
4937
|
return {
|
|
4670
4938
|
getChecked: () => {
|
|
4671
4939
|
const items = [];
|
|
4672
|
-
|
|
4673
|
-
const item =
|
|
4940
|
+
checkedKeys.map((k) => {
|
|
4941
|
+
const item = nodeMapsRef.current.get(k);
|
|
4674
4942
|
items.push(item);
|
|
4675
4943
|
});
|
|
4676
|
-
return [
|
|
4944
|
+
return [checkedKeys, items];
|
|
4677
4945
|
},
|
|
4678
4946
|
getSelected: () => {
|
|
4679
|
-
const item =
|
|
4680
|
-
return [
|
|
4947
|
+
const item = nodeMapsRef.current.get(selectedKey);
|
|
4948
|
+
return [selectedKey, item];
|
|
4681
4949
|
},
|
|
4682
4950
|
getPartofs: () => {
|
|
4683
4951
|
const items = [];
|
|
4684
|
-
const keys = Object.keys(
|
|
4685
|
-
const indeterminate =
|
|
4952
|
+
const keys = Object.keys(partofs).filter((k) => {
|
|
4953
|
+
const indeterminate = partofs[k];
|
|
4686
4954
|
if (indeterminate) {
|
|
4687
|
-
const item =
|
|
4955
|
+
const item = nodeMapsRef.current.get(k);
|
|
4688
4956
|
items.push(item);
|
|
4689
4957
|
}
|
|
4690
4958
|
return indeterminate;
|
|
@@ -4693,7 +4961,7 @@ const Tree = (props) => {
|
|
|
4693
4961
|
},
|
|
4694
4962
|
};
|
|
4695
4963
|
});
|
|
4696
|
-
return (jsx(TreeList, { data: data, selected:
|
|
4964
|
+
return (jsx(TreeList, { data: data, selected: selectedKey, checked: checkedKeys, partofs: partofs, nodeProps: oNodeProps, onItemCheck: handleCheck, onItemSelect: handleSelect, ...restProps }));
|
|
4697
4965
|
};
|
|
4698
4966
|
|
|
4699
4967
|
const ListContainer = (props) => {
|
|
@@ -4746,12 +5014,8 @@ const FileListItem = (props) => {
|
|
|
4746
5014
|
|
|
4747
5015
|
const Upload = (props) => {
|
|
4748
5016
|
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
|
-
});
|
|
5017
|
+
const [fileList, setFileListState] = useState(files);
|
|
5018
|
+
const [uploadMessage, setUploadMessage] = useState(message);
|
|
4755
5019
|
const inputRef = useRef(null);
|
|
4756
5020
|
const preview = usePreview();
|
|
4757
5021
|
const defBtnProps = Object.assign({
|
|
@@ -4769,7 +5033,7 @@ const Upload = (props) => {
|
|
|
4769
5033
|
}, [mode, children]);
|
|
4770
5034
|
const handleChange = (e) => {
|
|
4771
5035
|
const files = Array.from(e.target.files || []);
|
|
4772
|
-
const
|
|
5036
|
+
const before = fileList;
|
|
4773
5037
|
const changed = [];
|
|
4774
5038
|
files.map((f) => {
|
|
4775
5039
|
const { id, name, size, type } = f;
|
|
@@ -4786,21 +5050,20 @@ const Upload = (props) => {
|
|
|
4786
5050
|
!same && changed.push(f);
|
|
4787
5051
|
});
|
|
4788
5052
|
const after = [...before, ...changed];
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
onChange?.(state.files, e);
|
|
5053
|
+
const last = after.at(-1);
|
|
5054
|
+
const nextFiles = multiple ? after.slice(0, limit) : last ? [last] : [];
|
|
5055
|
+
setFileListState(nextFiles);
|
|
5056
|
+
setUploadMessage(message);
|
|
5057
|
+
onFilesChange?.(nextFiles, changed, e);
|
|
5058
|
+
onChange?.(nextFiles, e);
|
|
4796
5059
|
handleUpload(changed);
|
|
4797
5060
|
inputRef.current && (inputRef.current.value = "");
|
|
4798
5061
|
};
|
|
4799
5062
|
const handleRemove = (i) => {
|
|
4800
|
-
const [...files] =
|
|
5063
|
+
const [...files] = fileList;
|
|
4801
5064
|
const changed = files.splice(i, 1);
|
|
4802
5065
|
URL.revokeObjectURL(changed[0]?.src || "");
|
|
4803
|
-
|
|
5066
|
+
setFileListState(files);
|
|
4804
5067
|
onFilesChange?.(files, changed);
|
|
4805
5068
|
onChange?.(files);
|
|
4806
5069
|
inputRef.current && (inputRef.current.value = "");
|
|
@@ -4813,44 +5076,43 @@ const Upload = (props) => {
|
|
|
4813
5076
|
return onUpload?.(result);
|
|
4814
5077
|
};
|
|
4815
5078
|
const handlePreview = (i) => {
|
|
4816
|
-
preview({ items:
|
|
5079
|
+
preview({ items: fileList, initial: i });
|
|
4817
5080
|
};
|
|
4818
5081
|
const setFileList = (files) => {
|
|
4819
5082
|
if (!files)
|
|
4820
5083
|
return;
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
5084
|
+
setFileListState(files.map((f) => {
|
|
5085
|
+
const file = f;
|
|
5086
|
+
return { ...file, id: file.id ?? uid(7) };
|
|
5087
|
+
}));
|
|
4824
5088
|
};
|
|
4825
5089
|
const handleSortEnd = (before, after) => {
|
|
4826
|
-
const [...files] =
|
|
4827
|
-
|
|
4828
|
-
|
|
5090
|
+
const [...files] = fileList;
|
|
5091
|
+
const nextFiles = arrayMove(files, before, after);
|
|
5092
|
+
setFileListState(nextFiles);
|
|
5093
|
+
onChange?.(nextFiles);
|
|
4829
5094
|
};
|
|
4830
5095
|
useEffect(() => {
|
|
4831
|
-
|
|
4832
|
-
status,
|
|
4833
|
-
message,
|
|
4834
|
-
});
|
|
5096
|
+
setUploadMessage(message);
|
|
4835
5097
|
}, [status, message]);
|
|
4836
5098
|
useEffect(() => {
|
|
4837
|
-
|
|
5099
|
+
setFileListState(value?.filter?.((file) => !!file.id) ?? []);
|
|
4838
5100
|
}, [value]);
|
|
4839
5101
|
useEffect(() => {
|
|
4840
5102
|
setFileList(initialFiles);
|
|
4841
5103
|
}, []);
|
|
4842
5104
|
useImperativeHandle(ref, () => ({
|
|
4843
|
-
getFileList: () =>
|
|
5105
|
+
getFileList: () => fileList,
|
|
4844
5106
|
setFileList,
|
|
4845
|
-
}), []);
|
|
5107
|
+
}), [fileList]);
|
|
4846
5108
|
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
5109
|
[`i-upload-${mode}`]: mode !== "default",
|
|
4848
|
-
}), style: { ["--upload-card-size"]: cardSize }, children: [jsx(ListContainer, { sortable: sortable, onSortEnd: handleSortEnd, children:
|
|
5110
|
+
}), style: { ["--upload-card-size"]: cardSize }, children: [jsx(ListContainer, { sortable: sortable, onSortEnd: handleSortEnd, children: fileList.map((file, i) => {
|
|
4849
5111
|
const node = (jsx(FileListItem, { index: i, file: file, mode: mode, renderItem: renderItem, onRemove: handleRemove, onPreview: handlePreview }, i));
|
|
4850
5112
|
if (!sortable)
|
|
4851
5113
|
return node;
|
|
4852
5114
|
return jsx(SortableItem, { children: node }, i);
|
|
4853
|
-
}) }),
|
|
5115
|
+
}) }), 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
5116
|
};
|
|
4855
5117
|
|
|
4856
5118
|
const useTheme = (props) => {
|