@ioca/react 1.5.18 → 1.5.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/components/editor/editor.js +4 -2
- package/lib/cjs/components/editor/editor.js.map +1 -1
- package/lib/cjs/components/input/textarea.js +1 -1
- package/lib/cjs/components/input/textarea.js.map +1 -1
- package/lib/cjs/components/modal/content.js +16 -8
- package/lib/cjs/components/modal/content.js.map +1 -1
- package/lib/cjs/components/modal/modal.js +60 -19
- package/lib/cjs/components/modal/modal.js.map +1 -1
- package/lib/cjs/components/modal/modalManager.js +83 -0
- package/lib/cjs/components/modal/modalManager.js.map +1 -0
- package/lib/cjs/js/hooks.js +5 -2
- 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/css/input.css +8 -4
- package/lib/es/components/editor/editor.js +4 -2
- package/lib/es/components/editor/editor.js.map +1 -1
- package/lib/es/components/input/textarea.js +1 -1
- package/lib/es/components/input/textarea.js.map +1 -1
- package/lib/es/components/modal/content.js +18 -10
- package/lib/es/components/modal/content.js.map +1 -1
- package/lib/es/components/modal/modal.js +61 -20
- package/lib/es/components/modal/modal.js.map +1 -1
- package/lib/es/components/modal/modalManager.js +76 -0
- package/lib/es/components/modal/modalManager.js.map +1 -0
- package/lib/es/js/hooks.js +5 -2
- package/lib/es/js/hooks.js.map +1 -1
- package/lib/index.js +161 -34
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -135,12 +135,15 @@ function useMouseUp(listener, options) {
|
|
|
135
135
|
}
|
|
136
136
|
function useKeydown(listener, options) {
|
|
137
137
|
initEventsOnce();
|
|
138
|
+
const listenerRef = useRef(listener);
|
|
139
|
+
listenerRef.current = listener;
|
|
138
140
|
useEffect(() => {
|
|
139
141
|
if (options?.disabled)
|
|
140
142
|
return;
|
|
141
|
-
|
|
143
|
+
const handler = (e) => listenerRef.current(e);
|
|
144
|
+
KeydownEvents.add(handler);
|
|
142
145
|
return () => {
|
|
143
|
-
KeydownEvents.delete(
|
|
146
|
+
KeydownEvents.delete(handler);
|
|
144
147
|
};
|
|
145
148
|
}, []);
|
|
146
149
|
}
|
|
@@ -1785,7 +1788,7 @@ const List$1 = forwardRef((props, ref) => {
|
|
|
1785
1788
|
});
|
|
1786
1789
|
List$1.Item = Item$4;
|
|
1787
1790
|
|
|
1788
|
-
const Content$
|
|
1791
|
+
const Content$3 = forwardRef((props, ref) => {
|
|
1789
1792
|
const { arrow, arrowProps = {}, className, children, ...restProps } = props;
|
|
1790
1793
|
const arrowCSS = useMemo(() => {
|
|
1791
1794
|
let { left = 0, top = 0, pos } = arrowProps;
|
|
@@ -2297,7 +2300,7 @@ function Popup(props) {
|
|
|
2297
2300
|
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
2298
2301
|
};
|
|
2299
2302
|
}, [show]);
|
|
2300
|
-
return (jsxs(Fragment, { children: [triggerNode, show && (jsx(Content$
|
|
2303
|
+
return (jsxs(Fragment, { children: [triggerNode, show && (jsx(Content$3, { ref: contentRef, arrow: arrow && trigger !== "contextmenu", style: {
|
|
2301
2304
|
...style,
|
|
2302
2305
|
position: "fixed",
|
|
2303
2306
|
}, className: className, ...contentTouch, trigger: triggerRef.current, children: content }))] }));
|
|
@@ -2703,6 +2706,7 @@ const Editor = (props) => {
|
|
|
2703
2706
|
const [memtionKeyword, setMemtionKeyword] = useState("");
|
|
2704
2707
|
const [memtionActiveIndex, setMemtionActiveIndex] = useState(0);
|
|
2705
2708
|
const [activeMemtionIndex, setActiveMemtionIndex] = useState(-1);
|
|
2709
|
+
const activeMemtionIndexRef = useRef(-1);
|
|
2706
2710
|
const memtionOptions = useMemo(() => {
|
|
2707
2711
|
if (activeMemtionIndex < 0 || !memtion?.length)
|
|
2708
2712
|
return [];
|
|
@@ -2838,6 +2842,7 @@ const Editor = (props) => {
|
|
|
2838
2842
|
memtionTriggerRangeRef.current =
|
|
2839
2843
|
selectionRef.current?.cloneRange() ?? null;
|
|
2840
2844
|
pendingMemtionRef.current = true;
|
|
2845
|
+
activeMemtionIndexRef.current = matchedIndex;
|
|
2841
2846
|
setActiveMemtionIndex(matchedIndex);
|
|
2842
2847
|
}
|
|
2843
2848
|
}
|
|
@@ -2887,8 +2892,8 @@ const Editor = (props) => {
|
|
|
2887
2892
|
setEditorValue(nextValue);
|
|
2888
2893
|
}
|
|
2889
2894
|
rememberSelection();
|
|
2890
|
-
if (
|
|
2891
|
-
const active = memtion?.[
|
|
2895
|
+
if (activeMemtionIndexRef.current >= 0 && (pendingMemtionRef.current || memtionVisible)) {
|
|
2896
|
+
const active = memtion?.[activeMemtionIndexRef.current];
|
|
2892
2897
|
if (!active) {
|
|
2893
2898
|
hideMemtion();
|
|
2894
2899
|
return;
|
|
@@ -3261,14 +3266,21 @@ Form.useForm = useForm;
|
|
|
3261
3266
|
Form.Field = Field;
|
|
3262
3267
|
Form.useConfig = useConfig;
|
|
3263
3268
|
|
|
3264
|
-
|
|
3269
|
+
const Content$1 = (props) => {
|
|
3265
3270
|
const { title, footer, hideCloseButton, footerLeft, okButtonProps, cancelButtonProps, children, onOk, onClose, } = props;
|
|
3266
3271
|
const showHeader = title || !hideCloseButton;
|
|
3272
|
+
const [loading, setLoading] = useState(false);
|
|
3267
3273
|
const handleOk = async () => {
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3274
|
+
setLoading(true);
|
|
3275
|
+
try {
|
|
3276
|
+
const ret = await onOk?.();
|
|
3277
|
+
if (ret === false)
|
|
3278
|
+
return;
|
|
3279
|
+
onClose?.();
|
|
3280
|
+
}
|
|
3281
|
+
finally {
|
|
3282
|
+
setLoading(false);
|
|
3283
|
+
}
|
|
3272
3284
|
};
|
|
3273
3285
|
const renderFooter = useMemo(() => {
|
|
3274
3286
|
if (footer || footer === null)
|
|
@@ -3276,19 +3288,94 @@ function Content$1(props) {
|
|
|
3276
3288
|
const propsOk = Object.assign({
|
|
3277
3289
|
children: "确定",
|
|
3278
3290
|
onClick: handleOk,
|
|
3279
|
-
}, okButtonProps);
|
|
3291
|
+
}, okButtonProps, { loading });
|
|
3280
3292
|
const propsCancel = Object.assign({
|
|
3281
3293
|
secondary: true,
|
|
3282
3294
|
children: "关闭",
|
|
3283
3295
|
onClick: onClose,
|
|
3284
3296
|
}, cancelButtonProps);
|
|
3285
3297
|
return (jsxs(Fragment, { children: [footerLeft, jsx(Button, { ...propsOk }), jsx(Button, { ...propsCancel })] }));
|
|
3286
|
-
}, [footer, okButtonProps, cancelButtonProps]);
|
|
3298
|
+
}, [footer, okButtonProps, cancelButtonProps, loading]);
|
|
3287
3299
|
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 })] }));
|
|
3288
|
-
}
|
|
3300
|
+
};
|
|
3301
|
+
var Content$2 = memo(Content$1);
|
|
3289
3302
|
|
|
3290
3303
|
const ModalContext = createContext(false);
|
|
3291
3304
|
|
|
3305
|
+
const CONTAINER_ID = "i-modal-container";
|
|
3306
|
+
const BACKDROP_ID = "i-modal-backdrop";
|
|
3307
|
+
let containerEl = null;
|
|
3308
|
+
let backdropEl = null;
|
|
3309
|
+
const stack = [];
|
|
3310
|
+
const listeners = new Set();
|
|
3311
|
+
function ensureContainer() {
|
|
3312
|
+
if (containerEl)
|
|
3313
|
+
return containerEl;
|
|
3314
|
+
containerEl = document.createElement("div");
|
|
3315
|
+
containerEl.id = CONTAINER_ID;
|
|
3316
|
+
containerEl.className = "i-modal-container";
|
|
3317
|
+
document.body.append(containerEl);
|
|
3318
|
+
backdropEl = document.createElement("div");
|
|
3319
|
+
backdropEl.id = BACKDROP_ID;
|
|
3320
|
+
backdropEl.className = "i-modal-backdrop";
|
|
3321
|
+
containerEl.prepend(backdropEl);
|
|
3322
|
+
return containerEl;
|
|
3323
|
+
}
|
|
3324
|
+
function syncBackdrop() {
|
|
3325
|
+
if (!backdropEl)
|
|
3326
|
+
return;
|
|
3327
|
+
const show = stack.some((e) => e.visible && !e.hideBackdrop);
|
|
3328
|
+
backdropEl.classList.toggle("i-modal-backdrop-active", show);
|
|
3329
|
+
}
|
|
3330
|
+
function notify$1() {
|
|
3331
|
+
listeners.forEach((fn) => fn());
|
|
3332
|
+
}
|
|
3333
|
+
function register(entry) {
|
|
3334
|
+
ensureContainer();
|
|
3335
|
+
stack.push(entry);
|
|
3336
|
+
syncBackdrop();
|
|
3337
|
+
notify$1();
|
|
3338
|
+
return () => {
|
|
3339
|
+
const idx = stack.findIndex((e) => e.mid === entry.mid);
|
|
3340
|
+
if (idx !== -1)
|
|
3341
|
+
stack.splice(idx, 1);
|
|
3342
|
+
syncBackdrop();
|
|
3343
|
+
notify$1();
|
|
3344
|
+
if (stack.length === 0) {
|
|
3345
|
+
backdropEl?.remove();
|
|
3346
|
+
backdropEl = null;
|
|
3347
|
+
containerEl?.remove();
|
|
3348
|
+
containerEl = null;
|
|
3349
|
+
}
|
|
3350
|
+
};
|
|
3351
|
+
}
|
|
3352
|
+
function updateVisible(mid, visible) {
|
|
3353
|
+
const entry = stack.find((e) => e.mid === mid);
|
|
3354
|
+
if (entry) {
|
|
3355
|
+
entry.visible = visible;
|
|
3356
|
+
syncBackdrop();
|
|
3357
|
+
notify$1();
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
function isTop(mid) {
|
|
3361
|
+
const top = getTopVisible();
|
|
3362
|
+
return top?.mid === mid;
|
|
3363
|
+
}
|
|
3364
|
+
function getTopVisible() {
|
|
3365
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
3366
|
+
if (stack[i].visible)
|
|
3367
|
+
return stack[i];
|
|
3368
|
+
}
|
|
3369
|
+
return undefined;
|
|
3370
|
+
}
|
|
3371
|
+
function getContainer() {
|
|
3372
|
+
return ensureContainer();
|
|
3373
|
+
}
|
|
3374
|
+
function subscribe(fn) {
|
|
3375
|
+
listeners.add(fn);
|
|
3376
|
+
return () => listeners.delete(fn);
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3292
3379
|
function useModal() {
|
|
3293
3380
|
const ref = useRef(null);
|
|
3294
3381
|
const handleOpen = (props) => {
|
|
@@ -3316,26 +3403,41 @@ function useModal() {
|
|
|
3316
3403
|
};
|
|
3317
3404
|
}
|
|
3318
3405
|
|
|
3406
|
+
let midCounter = 0;
|
|
3319
3407
|
function Modal(props) {
|
|
3320
3408
|
const { visible, title, footer, okButtonProps, cancelButtonProps, closable = true, hideBackdrop, backdropClosable = true, hideCloseButton, disableEsc, width, height, customized, fixed, hideShadow, children, style, className, keepDOM, footerLeft, onClick, onVisibleChange, onClose, onOk, ...restProps } = props;
|
|
3409
|
+
const midRef = useRef(`modal-${++midCounter}`);
|
|
3410
|
+
const mid = midRef.current;
|
|
3321
3411
|
const [show, setShow] = useState(visible);
|
|
3322
3412
|
const [active, setActive] = useState(false);
|
|
3323
3413
|
const [bounced, setBounced] = useState(false);
|
|
3324
3414
|
const [mounted, setMounted] = useState(false);
|
|
3415
|
+
const [top, setTop] = useState(false);
|
|
3325
3416
|
const toggable = useRef(true);
|
|
3326
|
-
const
|
|
3417
|
+
const layerRef = useRef(null);
|
|
3418
|
+
const handleShow = useCallback(() => {
|
|
3327
3419
|
if (!toggable.current)
|
|
3328
3420
|
return;
|
|
3329
|
-
(!keepDOM || !show)
|
|
3421
|
+
if (!keepDOM || !show)
|
|
3422
|
+
setShow(true);
|
|
3330
3423
|
toggable.current = false;
|
|
3331
|
-
|
|
3424
|
+
updateVisible(mid, true);
|
|
3425
|
+
const raf = requestAnimationFrame(() => {
|
|
3426
|
+
if (!layerRef.current) {
|
|
3427
|
+
requestAnimationFrame(() => {
|
|
3428
|
+
setActive(true);
|
|
3429
|
+
onVisibleChange?.(true);
|
|
3430
|
+
toggable.current = true;
|
|
3431
|
+
});
|
|
3432
|
+
return;
|
|
3433
|
+
}
|
|
3332
3434
|
setActive(true);
|
|
3333
3435
|
onVisibleChange?.(true);
|
|
3334
3436
|
toggable.current = true;
|
|
3335
|
-
}
|
|
3336
|
-
return () =>
|
|
3337
|
-
};
|
|
3338
|
-
const handleHide = () => {
|
|
3437
|
+
});
|
|
3438
|
+
return () => cancelAnimationFrame(raf);
|
|
3439
|
+
}, [keepDOM, show, onVisibleChange]);
|
|
3440
|
+
const handleHide = useCallback(() => {
|
|
3339
3441
|
if (!toggable.current)
|
|
3340
3442
|
return;
|
|
3341
3443
|
toggable.current = false;
|
|
@@ -3348,28 +3450,53 @@ function Modal(props) {
|
|
|
3348
3450
|
return () => clearTimeout(timer);
|
|
3349
3451
|
}
|
|
3350
3452
|
setActive(false);
|
|
3453
|
+
updateVisible(mid, false);
|
|
3351
3454
|
const timer = setTimeout(() => {
|
|
3352
|
-
!keepDOM
|
|
3455
|
+
if (!keepDOM)
|
|
3456
|
+
setShow(false);
|
|
3353
3457
|
toggable.current = true;
|
|
3354
3458
|
onVisibleChange?.(false);
|
|
3355
3459
|
onClose?.();
|
|
3356
3460
|
}, 240);
|
|
3357
3461
|
return () => clearTimeout(timer);
|
|
3358
|
-
};
|
|
3462
|
+
}, [closable, keepDOM, onClose, onVisibleChange]);
|
|
3359
3463
|
const handleBackdropClick = () => {
|
|
3360
3464
|
backdropClosable && handleHide();
|
|
3361
3465
|
};
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3466
|
+
useEffect(() => {
|
|
3467
|
+
const unsub = subscribe(() => {
|
|
3468
|
+
setTop(isTop(mid));
|
|
3469
|
+
});
|
|
3470
|
+
return unsub;
|
|
3471
|
+
}, []);
|
|
3472
|
+
useEffect(() => {
|
|
3473
|
+
const unregister = register({
|
|
3474
|
+
mid,
|
|
3475
|
+
visible: !!visible,
|
|
3476
|
+
hideBackdrop: !!hideBackdrop,
|
|
3477
|
+
closable: !!closable,
|
|
3478
|
+
});
|
|
3479
|
+
return unregister;
|
|
3480
|
+
}, []);
|
|
3367
3481
|
useEffect(() => {
|
|
3368
3482
|
visible ? handleShow() : handleHide();
|
|
3369
3483
|
}, [visible]);
|
|
3484
|
+
useEffect(() => {
|
|
3485
|
+
if (!show)
|
|
3486
|
+
return;
|
|
3487
|
+
const raf = requestAnimationFrame(() => {
|
|
3488
|
+
setActive(top);
|
|
3489
|
+
});
|
|
3490
|
+
return () => cancelAnimationFrame(raf);
|
|
3491
|
+
}, [top]);
|
|
3370
3492
|
useEffect(() => {
|
|
3371
3493
|
setMounted(true);
|
|
3372
3494
|
}, []);
|
|
3495
|
+
useKeydown((e) => {
|
|
3496
|
+
if (e.code !== "Escape" || !visible || !top)
|
|
3497
|
+
return;
|
|
3498
|
+
handleHide();
|
|
3499
|
+
}, { disabled: disableEsc });
|
|
3373
3500
|
const handleClick = () => {
|
|
3374
3501
|
if (typeof document === "undefined")
|
|
3375
3502
|
return;
|
|
@@ -3377,12 +3504,12 @@ function Modal(props) {
|
|
|
3377
3504
|
};
|
|
3378
3505
|
if (!show || !mounted)
|
|
3379
3506
|
return null;
|
|
3380
|
-
return createPortal(jsx("div", { className: classNames("i-modal-
|
|
3381
|
-
"i-modal-backdrop": !hideBackdrop,
|
|
3382
|
-
"i-modal-customized": customized,
|
|
3507
|
+
return createPortal(jsx("div", { ref: layerRef, className: classNames("i-modal-layer", {
|
|
3383
3508
|
"i-modal-active": active,
|
|
3509
|
+
"i-modal-customized": customized,
|
|
3510
|
+
"i-modal-hide-backdrop": hideBackdrop,
|
|
3384
3511
|
fixed,
|
|
3385
|
-
}, className), style: style, onClick: handleBackdropClick,
|
|
3512
|
+
}, className), style: style, onClick: handleBackdropClick, children: jsx("div", { className: classNames("i-modal", {
|
|
3386
3513
|
bounced,
|
|
3387
3514
|
shadow: !hideShadow,
|
|
3388
3515
|
}), style: {
|
|
@@ -3392,7 +3519,7 @@ function Modal(props) {
|
|
|
3392
3519
|
e.stopPropagation();
|
|
3393
3520
|
handleClick();
|
|
3394
3521
|
onClick?.(e);
|
|
3395
|
-
}, role:
|
|
3522
|
+
}, role: "dialog", "aria-modal": top, "data-mid": mid, ...restProps, children: jsxs(ModalContext.Provider, { value: true, children: [customized && children, !customized && (jsx(Content$2, { title: title, hideCloseButton: hideCloseButton, footer: footer, okButtonProps: okButtonProps, cancelButtonProps: cancelButtonProps, children: children, footerLeft: footerLeft, onOk: onOk, onClose: handleHide }))] }) }) }), getContainer());
|
|
3396
3523
|
}
|
|
3397
3524
|
Modal.useModal = useModal;
|
|
3398
3525
|
|
|
@@ -4258,7 +4385,7 @@ const Textarea = (props) => {
|
|
|
4258
4385
|
onKeyDown: handleKeydown,
|
|
4259
4386
|
...restProps,
|
|
4260
4387
|
};
|
|
4261
|
-
return (jsx(InputContainer, { label: label, labelInline: labelInline, className: className, style: { width, ...style }, tip: message ?? tip, status: status, children: jsx("div", { className: classNames("i-input-item", {
|
|
4388
|
+
return (jsx(InputContainer, { label: label, labelInline: labelInline, className: classNames("i-textarea-label", className), style: { width, ...style }, tip: message ?? tip, status: status, children: jsx("div", { className: classNames("i-input-item", {
|
|
4262
4389
|
[`i-input-${status}`]: status !== "normal",
|
|
4263
4390
|
"i-input-borderless": !border,
|
|
4264
4391
|
}), children: jsx("textarea", { ...inputProps }) }) }));
|