@enonic/ui 0.13.0 → 0.13.2
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/dist/enonic-ui.cjs +5 -6
- package/dist/enonic-ui.es.js +373 -343
- package/dist/styles/style.css +1 -1
- package/dist/types/components/combobox/combobox.d.ts +8 -2
- package/dist/types/components/listbox/listbox.d.ts +9 -3
- package/dist/types/hooks/index.d.ts +3 -0
- package/dist/types/hooks/use-controlled-state.d.ts +28 -0
- package/dist/types/hooks/use-item-registry.d.ts +57 -0
- package/dist/types/hooks/use-keyboard-navigation.d.ts +82 -0
- package/dist/types/providers/combobox-provider.d.ts +1 -1
- package/dist/types/providers/listbox-provider.d.ts +4 -0
- package/dist/types/utils/aria.d.ts +69 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/ref.d.ts +1 -1
- package/package.json +1 -1
package/dist/enonic-ui.es.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { options, Fragment } from "preact";
|
|
2
|
-
import { createContext, useContext, useId, useCallback, forwardRef, useState, useMemo, useEffect,
|
|
2
|
+
import { createContext, useContext, useId, useCallback, forwardRef, useState, useMemo, useEffect, useRef, createElement, isValidElement, Children, createPortal as createPortal$1 } from "react";
|
|
3
3
|
import { Slot, Root } from "@radix-ui/react-slot";
|
|
4
4
|
import { FocusTrap } from "focus-trap-react";
|
|
5
5
|
import { createPortal } from "react-dom";
|
|
6
|
-
import { useState as useState$1 } from "preact/hooks";
|
|
7
6
|
var f = 0;
|
|
8
7
|
function u(e, t, n, o, i, u2) {
|
|
9
8
|
t || (t = {});
|
|
@@ -13,7 +12,7 @@ function u(e, t, n, o, i, u2) {
|
|
|
13
12
|
if ("function" == typeof e && (a = e.defaultProps)) for (c in a) void 0 === p[c] && (p[c] = a[c]);
|
|
14
13
|
return options.vnode && options.vnode(l), l;
|
|
15
14
|
}
|
|
16
|
-
const AvatarContext = createContext(
|
|
15
|
+
const AvatarContext = createContext(void 0);
|
|
17
16
|
const AvatarProvider = ({ value, children }) => {
|
|
18
17
|
return /* @__PURE__ */ u(AvatarContext.Provider, { value, children });
|
|
19
18
|
};
|
|
@@ -25,7 +24,7 @@ const useAvatar = () => {
|
|
|
25
24
|
}
|
|
26
25
|
return ctx;
|
|
27
26
|
};
|
|
28
|
-
const ComboboxContext = createContext(
|
|
27
|
+
const ComboboxContext = createContext(void 0);
|
|
29
28
|
const ComboboxProvider = ({ value, children }) => {
|
|
30
29
|
return /* @__PURE__ */ u(ComboboxContext.Provider, { value, children });
|
|
31
30
|
};
|
|
@@ -59,7 +58,7 @@ const usePrefixedId = (providedId, prefix) => {
|
|
|
59
58
|
const context = useContext(IdContext);
|
|
60
59
|
return [context?.prefix, prefix, baseId].filter(Boolean).join("-");
|
|
61
60
|
};
|
|
62
|
-
const ListboxContext = createContext(
|
|
61
|
+
const ListboxContext = createContext(void 0);
|
|
63
62
|
const ListboxProvider = ({ value, children }) => {
|
|
64
63
|
return /* @__PURE__ */ u(ListboxContext.Provider, { value, children });
|
|
65
64
|
};
|
|
@@ -82,6 +81,27 @@ const useMenu = () => {
|
|
|
82
81
|
}
|
|
83
82
|
return context;
|
|
84
83
|
};
|
|
84
|
+
function generateAriaId(baseId, suffix) {
|
|
85
|
+
return `${baseId}-${suffix}`;
|
|
86
|
+
}
|
|
87
|
+
function generateAriaIds(baseId, parts) {
|
|
88
|
+
return parts.reduce(
|
|
89
|
+
(acc, part) => {
|
|
90
|
+
acc[part] = generateAriaId(baseId, part);
|
|
91
|
+
return acc;
|
|
92
|
+
},
|
|
93
|
+
{}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
function generateItemId(baseId, componentType, itemValue) {
|
|
97
|
+
return `${baseId}-${componentType}-item-${itemValue}`;
|
|
98
|
+
}
|
|
99
|
+
function getActiveDescendantId(baseId, componentType, activeValue) {
|
|
100
|
+
if (!activeValue) {
|
|
101
|
+
return void 0;
|
|
102
|
+
}
|
|
103
|
+
return generateItemId(baseId, componentType, activeValue);
|
|
104
|
+
}
|
|
85
105
|
function r(e) {
|
|
86
106
|
var t, f2, n = "";
|
|
87
107
|
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
@@ -3233,7 +3253,7 @@ const Avatar = Object.assign(AvatarRoot, {
|
|
|
3233
3253
|
const buttonVariants = cva(
|
|
3234
3254
|
[
|
|
3235
3255
|
"inline-flex items-center justify-center",
|
|
3236
|
-
"text-main font-
|
|
3256
|
+
"text-main font-semibold",
|
|
3237
3257
|
"box-border rounded-sm transition-highlight",
|
|
3238
3258
|
"focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:ring-offset-0",
|
|
3239
3259
|
"disabled:select-none disabled:pointer-events-none disabled:opacity-30",
|
|
@@ -3262,11 +3282,11 @@ const buttonVariants = cva(
|
|
|
3262
3282
|
const getIconSize = (size) => {
|
|
3263
3283
|
switch (size) {
|
|
3264
3284
|
case "sm":
|
|
3265
|
-
return
|
|
3285
|
+
return 14;
|
|
3266
3286
|
case "md":
|
|
3267
|
-
return 18;
|
|
3268
|
-
case "lg":
|
|
3269
3287
|
return 20;
|
|
3288
|
+
case "lg":
|
|
3289
|
+
return 24;
|
|
3270
3290
|
}
|
|
3271
3291
|
};
|
|
3272
3292
|
const Button = forwardRef(
|
|
@@ -3307,6 +3327,159 @@ const Button = forwardRef(
|
|
|
3307
3327
|
}
|
|
3308
3328
|
);
|
|
3309
3329
|
Button.displayName = "Button";
|
|
3330
|
+
const useScrollLock = (lock, element) => {
|
|
3331
|
+
useEffect(() => {
|
|
3332
|
+
if (!lock) {
|
|
3333
|
+
return;
|
|
3334
|
+
}
|
|
3335
|
+
const target = element ?? document.body;
|
|
3336
|
+
const originalOverflow = target.style.overflow;
|
|
3337
|
+
target.style.overflow = "hidden";
|
|
3338
|
+
return () => {
|
|
3339
|
+
target.style.overflow = originalOverflow;
|
|
3340
|
+
};
|
|
3341
|
+
}, [lock, element]);
|
|
3342
|
+
};
|
|
3343
|
+
function useControlledState(controlledValue, defaultValue, onChange) {
|
|
3344
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
3345
|
+
const isControlled = controlledValue !== void 0;
|
|
3346
|
+
const value = isControlled ? controlledValue : uncontrolledValue;
|
|
3347
|
+
const setValue = useCallback(
|
|
3348
|
+
(nextValue) => {
|
|
3349
|
+
if (!isControlled) {
|
|
3350
|
+
setUncontrolledValue(nextValue);
|
|
3351
|
+
}
|
|
3352
|
+
onChange?.(nextValue);
|
|
3353
|
+
},
|
|
3354
|
+
[isControlled, onChange]
|
|
3355
|
+
);
|
|
3356
|
+
return [value, setValue];
|
|
3357
|
+
}
|
|
3358
|
+
function useItemRegistry() {
|
|
3359
|
+
const itemsRef = useRef(/* @__PURE__ */ new Map());
|
|
3360
|
+
const registerItem = useCallback((id, disabled = false) => {
|
|
3361
|
+
itemsRef.current.set(id, { disabled });
|
|
3362
|
+
}, []);
|
|
3363
|
+
const unregisterItem = useCallback((id) => {
|
|
3364
|
+
itemsRef.current.delete(id);
|
|
3365
|
+
}, []);
|
|
3366
|
+
const getItems = useCallback(() => {
|
|
3367
|
+
return Array.from(itemsRef.current.keys());
|
|
3368
|
+
}, []);
|
|
3369
|
+
const isItemDisabled = useCallback((id) => {
|
|
3370
|
+
return itemsRef.current.get(id)?.disabled ?? false;
|
|
3371
|
+
}, []);
|
|
3372
|
+
return {
|
|
3373
|
+
registerItem,
|
|
3374
|
+
unregisterItem,
|
|
3375
|
+
getItems,
|
|
3376
|
+
isItemDisabled
|
|
3377
|
+
};
|
|
3378
|
+
}
|
|
3379
|
+
function useKeyboardNavigation(config) {
|
|
3380
|
+
const {
|
|
3381
|
+
getItems,
|
|
3382
|
+
isItemDisabled,
|
|
3383
|
+
active,
|
|
3384
|
+
setActive,
|
|
3385
|
+
loop = false,
|
|
3386
|
+
orientation = "vertical",
|
|
3387
|
+
onSelect,
|
|
3388
|
+
onEscape
|
|
3389
|
+
} = config;
|
|
3390
|
+
const moveActive = useCallback(
|
|
3391
|
+
(delta) => {
|
|
3392
|
+
const items = getItems();
|
|
3393
|
+
if (!items.length) {
|
|
3394
|
+
return;
|
|
3395
|
+
}
|
|
3396
|
+
const currentIndex = active ? items.indexOf(active) : -1;
|
|
3397
|
+
let newIndex;
|
|
3398
|
+
let attempts = 0;
|
|
3399
|
+
const maxAttempts = items.length;
|
|
3400
|
+
if (currentIndex === -1) {
|
|
3401
|
+
newIndex = delta > 0 ? 0 : items.length - 1;
|
|
3402
|
+
} else {
|
|
3403
|
+
newIndex = currentIndex + delta;
|
|
3404
|
+
}
|
|
3405
|
+
while (attempts < maxAttempts) {
|
|
3406
|
+
if (loop) {
|
|
3407
|
+
if (newIndex < 0) {
|
|
3408
|
+
newIndex = items.length - 1;
|
|
3409
|
+
} else if (newIndex >= items.length) {
|
|
3410
|
+
newIndex = 0;
|
|
3411
|
+
}
|
|
3412
|
+
} else {
|
|
3413
|
+
if (newIndex < 0 || newIndex >= items.length) {
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
if (!isItemDisabled(items[newIndex])) {
|
|
3418
|
+
setActive(items[newIndex]);
|
|
3419
|
+
return;
|
|
3420
|
+
}
|
|
3421
|
+
newIndex += delta;
|
|
3422
|
+
attempts++;
|
|
3423
|
+
}
|
|
3424
|
+
},
|
|
3425
|
+
[getItems, active, setActive, loop, isItemDisabled]
|
|
3426
|
+
);
|
|
3427
|
+
const handleKeyDown = useCallback(
|
|
3428
|
+
(e) => {
|
|
3429
|
+
const items = getItems();
|
|
3430
|
+
if (!items.length) {
|
|
3431
|
+
return;
|
|
3432
|
+
}
|
|
3433
|
+
const isVertical = orientation === "vertical";
|
|
3434
|
+
const nextKey = isVertical ? "ArrowDown" : "ArrowRight";
|
|
3435
|
+
const prevKey = isVertical ? "ArrowUp" : "ArrowLeft";
|
|
3436
|
+
switch (e.key) {
|
|
3437
|
+
case nextKey:
|
|
3438
|
+
e.preventDefault();
|
|
3439
|
+
moveActive(1);
|
|
3440
|
+
break;
|
|
3441
|
+
case prevKey:
|
|
3442
|
+
e.preventDefault();
|
|
3443
|
+
moveActive(-1);
|
|
3444
|
+
break;
|
|
3445
|
+
case "Home":
|
|
3446
|
+
e.preventDefault();
|
|
3447
|
+
{
|
|
3448
|
+
const firstEnabled = items.find((id) => !isItemDisabled(id));
|
|
3449
|
+
if (firstEnabled) {
|
|
3450
|
+
setActive(firstEnabled);
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
break;
|
|
3454
|
+
case "End":
|
|
3455
|
+
e.preventDefault();
|
|
3456
|
+
{
|
|
3457
|
+
const lastEnabled = [...items].reverse().find((id) => !isItemDisabled(id));
|
|
3458
|
+
if (lastEnabled) {
|
|
3459
|
+
setActive(lastEnabled);
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
break;
|
|
3463
|
+
case "Enter":
|
|
3464
|
+
case " ":
|
|
3465
|
+
e.preventDefault();
|
|
3466
|
+
if (active && !isItemDisabled(active)) {
|
|
3467
|
+
onSelect?.(active);
|
|
3468
|
+
}
|
|
3469
|
+
break;
|
|
3470
|
+
case "Escape":
|
|
3471
|
+
e.preventDefault();
|
|
3472
|
+
onEscape?.();
|
|
3473
|
+
break;
|
|
3474
|
+
}
|
|
3475
|
+
},
|
|
3476
|
+
[getItems, active, moveActive, setActive, isItemDisabled, orientation, onSelect, onEscape]
|
|
3477
|
+
);
|
|
3478
|
+
return {
|
|
3479
|
+
moveActive,
|
|
3480
|
+
handleKeyDown
|
|
3481
|
+
};
|
|
3482
|
+
}
|
|
3310
3483
|
/**
|
|
3311
3484
|
* @license lucide-react v0.545.0 - ISC
|
|
3312
3485
|
*
|
|
@@ -3570,9 +3743,7 @@ const Checkbox = forwardRef(
|
|
|
3570
3743
|
const inputId = usePrefixedId(unwrap(id));
|
|
3571
3744
|
const state = error ? "error" : "default";
|
|
3572
3745
|
const editable = !disabled && !readOnly;
|
|
3573
|
-
const [
|
|
3574
|
-
const isControlled = checked !== void 0;
|
|
3575
|
-
const checkedState = isControlled ? checked : uncontrolledChecked;
|
|
3746
|
+
const [checkedState, setCheckedState] = useControlledState(checked, defaultChecked, onCheckedChange);
|
|
3576
3747
|
const isIndeterminate = checkedState === "indeterminate";
|
|
3577
3748
|
const isChecked = checkedState === true;
|
|
3578
3749
|
const handleChange = (e) => {
|
|
@@ -3583,10 +3754,7 @@ const Checkbox = forwardRef(
|
|
|
3583
3754
|
} else {
|
|
3584
3755
|
nextValue = e.currentTarget.checked;
|
|
3585
3756
|
}
|
|
3586
|
-
|
|
3587
|
-
setUncontrolledChecked(nextValue);
|
|
3588
|
-
}
|
|
3589
|
-
onCheckedChange?.(nextValue);
|
|
3757
|
+
setCheckedState(nextValue);
|
|
3590
3758
|
};
|
|
3591
3759
|
return /* @__PURE__ */ u("div", { children: [
|
|
3592
3760
|
/* @__PURE__ */ u(
|
|
@@ -3687,141 +3855,103 @@ const IconButton = forwardRef(
|
|
|
3687
3855
|
}
|
|
3688
3856
|
);
|
|
3689
3857
|
IconButton.displayName = "IconButton";
|
|
3858
|
+
const EMPTY_SELECTION$1 = [];
|
|
3690
3859
|
const ComboboxRoot = ({
|
|
3691
3860
|
children,
|
|
3692
3861
|
open: controlledOpen,
|
|
3862
|
+
defaultOpen = false,
|
|
3693
3863
|
onOpenChange,
|
|
3694
3864
|
closeOnBlur = true,
|
|
3695
3865
|
value,
|
|
3866
|
+
defaultValue = "",
|
|
3696
3867
|
onChange,
|
|
3697
3868
|
disabled = false,
|
|
3698
3869
|
error = false,
|
|
3699
3870
|
selectionMode = "single",
|
|
3700
3871
|
selection: controlledSelection,
|
|
3701
|
-
|
|
3872
|
+
defaultSelection = EMPTY_SELECTION$1,
|
|
3873
|
+
onSelectionChange,
|
|
3874
|
+
active: controlledActive,
|
|
3875
|
+
defaultActive,
|
|
3876
|
+
setActive
|
|
3702
3877
|
}) => {
|
|
3703
3878
|
const baseId = usePrefixedId();
|
|
3704
|
-
const [
|
|
3705
|
-
const
|
|
3706
|
-
const
|
|
3707
|
-
const setOpen = useCallback(
|
|
3708
|
-
(next) => {
|
|
3709
|
-
if (!isOpenControlled) {
|
|
3710
|
-
setUncontrolledOpen(next);
|
|
3711
|
-
}
|
|
3712
|
-
onOpenChange?.(next);
|
|
3713
|
-
},
|
|
3714
|
-
[isOpenControlled, onOpenChange]
|
|
3715
|
-
);
|
|
3716
|
-
const [uncontrolledSelection, setUncontrolledSelection] = useState([]);
|
|
3879
|
+
const [open, setOpenInternal] = useControlledState(controlledOpen, defaultOpen, onOpenChange);
|
|
3880
|
+
const [inputValue, setInputValueInternal] = useControlledState(value, defaultValue, onChange);
|
|
3881
|
+
const [uncontrolledSelection, setUncontrolledSelection] = useState(() => new Set(defaultSelection));
|
|
3717
3882
|
const isSelectionControlled = controlledSelection !== void 0;
|
|
3718
|
-
const
|
|
3883
|
+
const selectionSet = useMemo(
|
|
3884
|
+
() => isSelectionControlled ? new Set(controlledSelection) : uncontrolledSelection,
|
|
3885
|
+
[isSelectionControlled, controlledSelection, uncontrolledSelection]
|
|
3886
|
+
);
|
|
3719
3887
|
const onSelectionChangeInner = useCallback(
|
|
3720
3888
|
(newSelection) => {
|
|
3889
|
+
const newSet = new Set(newSelection);
|
|
3721
3890
|
if (!isSelectionControlled) {
|
|
3722
|
-
setUncontrolledSelection(
|
|
3891
|
+
setUncontrolledSelection(newSet);
|
|
3723
3892
|
}
|
|
3724
3893
|
onSelectionChange?.(newSelection);
|
|
3725
3894
|
if (selectionMode === "single") {
|
|
3726
|
-
|
|
3895
|
+
setOpenInternal(false);
|
|
3727
3896
|
}
|
|
3728
3897
|
},
|
|
3729
|
-
[isSelectionControlled, selectionMode,
|
|
3898
|
+
[isSelectionControlled, selectionMode, setOpenInternal, onSelectionChange]
|
|
3730
3899
|
);
|
|
3731
|
-
const [
|
|
3732
|
-
const
|
|
3733
|
-
const inputValue = isInputControlled ? value : uncontrolledInput;
|
|
3900
|
+
const [activeInternal, setActiveInternal] = useControlledState(controlledActive, defaultActive, setActive);
|
|
3901
|
+
const { registerItem, unregisterItem, getItems, isItemDisabled } = useItemRegistry();
|
|
3734
3902
|
const setInputValue = useCallback(
|
|
3735
3903
|
(next) => {
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
}
|
|
3739
|
-
onChange?.(next);
|
|
3740
|
-
setOpen(true);
|
|
3904
|
+
setInputValueInternal(next);
|
|
3905
|
+
setOpenInternal(true);
|
|
3741
3906
|
},
|
|
3742
|
-
[
|
|
3907
|
+
[setInputValueInternal, setOpenInternal]
|
|
3743
3908
|
);
|
|
3744
|
-
const
|
|
3745
|
-
(
|
|
3746
|
-
|
|
3747
|
-
if (selectionMode === "multiple") {
|
|
3748
|
-
if (selectedItems.includes(value2)) {
|
|
3749
|
-
newSelection = selectedItems.filter((item) => item !== value2);
|
|
3750
|
-
} else {
|
|
3751
|
-
newSelection = [...selectedItems, value2];
|
|
3752
|
-
}
|
|
3753
|
-
} else {
|
|
3754
|
-
newSelection = [value2];
|
|
3755
|
-
}
|
|
3756
|
-
onSelectionChangeInner(newSelection);
|
|
3909
|
+
const setOpen = useCallback(
|
|
3910
|
+
(next) => {
|
|
3911
|
+
setOpenInternal(next);
|
|
3757
3912
|
},
|
|
3758
|
-
[
|
|
3913
|
+
[setOpenInternal]
|
|
3759
3914
|
);
|
|
3760
|
-
const
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3915
|
+
const { handleKeyDown: handleNavKeyDown } = useKeyboardNavigation({
|
|
3916
|
+
getItems,
|
|
3917
|
+
isItemDisabled,
|
|
3918
|
+
active: activeInternal,
|
|
3919
|
+
setActive: setActiveInternal,
|
|
3920
|
+
loop: false,
|
|
3921
|
+
orientation: "vertical",
|
|
3922
|
+
onSelect: (id) => {
|
|
3923
|
+
const newSelection = selectionMode === "multiple" ? selectionSet.has(id) ? Array.from(selectionSet).filter((item) => item !== id) : [...Array.from(selectionSet), id] : [id];
|
|
3924
|
+
onSelectionChangeInner(newSelection);
|
|
3766
3925
|
}
|
|
3767
|
-
|
|
3768
|
-
return Array.from(optionNodes).map((node) => node.dataset.value).filter((v) => v !== void 0);
|
|
3769
|
-
}, []);
|
|
3770
|
-
const moveActive = useCallback(
|
|
3771
|
-
(delta) => {
|
|
3772
|
-
const items = getItems();
|
|
3773
|
-
if (!items.length) {
|
|
3774
|
-
return;
|
|
3775
|
-
}
|
|
3776
|
-
const currentIndex = active ? items.indexOf(active) : -1;
|
|
3777
|
-
const newIndex = Math.max(0, Math.min(items.length - 1, currentIndex + delta));
|
|
3778
|
-
setActive(items[newIndex]);
|
|
3779
|
-
},
|
|
3780
|
-
[active, setActive, getItems]
|
|
3781
|
-
);
|
|
3926
|
+
});
|
|
3782
3927
|
const keyHandler = useCallback(
|
|
3783
3928
|
(e) => {
|
|
3784
3929
|
if (disabled) {
|
|
3785
3930
|
return;
|
|
3786
3931
|
}
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
e.preventDefault();
|
|
3790
|
-
setOpen(true);
|
|
3791
|
-
moveActive(1);
|
|
3792
|
-
} else if (e.key === "ArrowUp") {
|
|
3793
|
-
setOpen(true);
|
|
3794
|
-
moveActive(-1);
|
|
3795
|
-
} else if (e.key === "Home") {
|
|
3796
|
-
e.preventDefault();
|
|
3797
|
-
setActive(items[0]);
|
|
3798
|
-
} else if (e.key === "End") {
|
|
3799
|
-
e.preventDefault();
|
|
3800
|
-
setActive(items[items.length - 1]);
|
|
3801
|
-
} else if (e.key === "Enter") {
|
|
3802
|
-
if (open) {
|
|
3932
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
3933
|
+
if (!open) {
|
|
3803
3934
|
e.preventDefault();
|
|
3804
|
-
|
|
3805
|
-
toggleValueSelection(active);
|
|
3806
|
-
}
|
|
3807
|
-
setOpen(false);
|
|
3808
|
-
setActive(items[0]);
|
|
3935
|
+
setOpenInternal(true);
|
|
3809
3936
|
}
|
|
3810
|
-
} else if (e.key === "Escape") {
|
|
3811
|
-
setOpen(false);
|
|
3812
|
-
setActive(items[0]);
|
|
3813
3937
|
}
|
|
3938
|
+
if (e.key === "Escape") {
|
|
3939
|
+
e.preventDefault();
|
|
3940
|
+
setOpenInternal(false);
|
|
3941
|
+
return;
|
|
3942
|
+
}
|
|
3943
|
+
handleNavKeyDown(e);
|
|
3814
3944
|
},
|
|
3815
|
-
[disabled,
|
|
3945
|
+
[disabled, open, setOpenInternal, handleNavKeyDown]
|
|
3816
3946
|
);
|
|
3817
3947
|
useEffect(() => {
|
|
3818
|
-
if (open &&
|
|
3948
|
+
if (open && activeInternal === void 0) {
|
|
3819
3949
|
const items = getItems();
|
|
3820
3950
|
if (items.length > 0) {
|
|
3821
|
-
|
|
3951
|
+
setActiveInternal(items[0]);
|
|
3822
3952
|
}
|
|
3823
3953
|
}
|
|
3824
|
-
}, [open,
|
|
3954
|
+
}, [open, activeInternal, getItems, setActiveInternal]);
|
|
3825
3955
|
const context = useMemo(
|
|
3826
3956
|
() => ({
|
|
3827
3957
|
open,
|
|
@@ -3829,36 +3959,52 @@ const ComboboxRoot = ({
|
|
|
3829
3959
|
inputValue,
|
|
3830
3960
|
setInputValue,
|
|
3831
3961
|
baseId,
|
|
3832
|
-
active,
|
|
3962
|
+
active: activeInternal,
|
|
3833
3963
|
disabled,
|
|
3834
3964
|
error,
|
|
3835
3965
|
closeOnBlur,
|
|
3836
3966
|
keyHandler,
|
|
3837
|
-
selection:
|
|
3967
|
+
selection: selectionSet
|
|
3838
3968
|
}),
|
|
3839
|
-
[
|
|
3969
|
+
[
|
|
3970
|
+
open,
|
|
3971
|
+
setOpen,
|
|
3972
|
+
closeOnBlur,
|
|
3973
|
+
keyHandler,
|
|
3974
|
+
inputValue,
|
|
3975
|
+
setInputValue,
|
|
3976
|
+
activeInternal,
|
|
3977
|
+
baseId,
|
|
3978
|
+
disabled,
|
|
3979
|
+
error,
|
|
3980
|
+
selectionSet
|
|
3981
|
+
]
|
|
3840
3982
|
);
|
|
3841
|
-
return /* @__PURE__ */ u(
|
|
3983
|
+
return /* @__PURE__ */ u(ComboboxProvider, { value: context, children: /* @__PURE__ */ u(
|
|
3842
3984
|
Listbox.Root,
|
|
3843
3985
|
{
|
|
3844
3986
|
selectionMode,
|
|
3845
|
-
selection:
|
|
3987
|
+
selection: Array.from(selectionSet),
|
|
3846
3988
|
onSelectionChange: onSelectionChangeInner,
|
|
3847
3989
|
disabled,
|
|
3848
|
-
active,
|
|
3990
|
+
active: activeInternal,
|
|
3849
3991
|
focusable: false,
|
|
3850
3992
|
baseId,
|
|
3851
|
-
setActive,
|
|
3993
|
+
setActive: setActiveInternal,
|
|
3852
3994
|
keyHandler,
|
|
3995
|
+
registerItem,
|
|
3996
|
+
unregisterItem,
|
|
3997
|
+
getItems,
|
|
3998
|
+
isItemDisabled,
|
|
3853
3999
|
children
|
|
3854
4000
|
}
|
|
3855
|
-
) })
|
|
4001
|
+
) });
|
|
3856
4002
|
};
|
|
3857
4003
|
ComboboxRoot.displayName = "Combobox.Root";
|
|
3858
4004
|
const ComboboxContent = forwardRef(
|
|
3859
4005
|
({ className, children }, ref) => {
|
|
3860
|
-
const { setOpen, baseId, closeOnBlur } = useCombobox();
|
|
3861
4006
|
const innerRef = useRef(null);
|
|
4007
|
+
const { setOpen, baseId, closeOnBlur } = useCombobox();
|
|
3862
4008
|
const handleFocusOut = closeOnBlur ? useCallback(
|
|
3863
4009
|
(e) => {
|
|
3864
4010
|
const nextTarget = e.relatedTarget;
|
|
@@ -3875,6 +4021,7 @@ const ComboboxContent = forwardRef(
|
|
|
3875
4021
|
);
|
|
3876
4022
|
}
|
|
3877
4023
|
);
|
|
4024
|
+
ComboboxContent.displayName = "Combobox.Content";
|
|
3878
4025
|
const comboboxControlVariants = cva(
|
|
3879
4026
|
[
|
|
3880
4027
|
"flex items-center",
|
|
@@ -3925,8 +4072,8 @@ const ComboboxControl = ({ children, className }) => {
|
|
|
3925
4072
|
ComboboxControl.displayName = "Combobox.Control";
|
|
3926
4073
|
const ComboboxInput = forwardRef(
|
|
3927
4074
|
({ className, placeholder, ...props }, ref) => {
|
|
3928
|
-
const { inputValue, setInputValue, open, keyHandler, selection, baseId, active, disabled } = useCombobox();
|
|
3929
4075
|
const innerRef = useRef(null);
|
|
4076
|
+
const { inputValue, setInputValue, open, keyHandler, selection, baseId, active, disabled, error } = useCombobox();
|
|
3930
4077
|
useEffect(() => {
|
|
3931
4078
|
if (open && !disabled) {
|
|
3932
4079
|
innerRef.current?.focus();
|
|
@@ -3944,6 +4091,7 @@ const ComboboxInput = forwardRef(
|
|
|
3944
4091
|
placeholder,
|
|
3945
4092
|
disabled,
|
|
3946
4093
|
"aria-disabled": disabled,
|
|
4094
|
+
"aria-invalid": error ?? void 0,
|
|
3947
4095
|
role: "combobox",
|
|
3948
4096
|
"aria-autocomplete": "list",
|
|
3949
4097
|
"aria-expanded": open,
|
|
@@ -4009,37 +4157,13 @@ const Combobox = Object.assign(ComboboxRoot, {
|
|
|
4009
4157
|
Toggle: ComboboxToggle,
|
|
4010
4158
|
Popup: ComboboxPopup
|
|
4011
4159
|
});
|
|
4012
|
-
const useScrollLock = (lock, element) => {
|
|
4013
|
-
useEffect(() => {
|
|
4014
|
-
if (!lock) {
|
|
4015
|
-
return;
|
|
4016
|
-
}
|
|
4017
|
-
const target = element ?? document.body;
|
|
4018
|
-
const originalOverflow = target.style.overflow;
|
|
4019
|
-
target.style.overflow = "hidden";
|
|
4020
|
-
return () => {
|
|
4021
|
-
target.style.overflow = originalOverflow;
|
|
4022
|
-
};
|
|
4023
|
-
}, [lock, element]);
|
|
4024
|
-
};
|
|
4025
4160
|
const DialogRoot = ({
|
|
4026
4161
|
open: controlledOpen,
|
|
4027
4162
|
defaultOpen = false,
|
|
4028
4163
|
onOpenChange,
|
|
4029
4164
|
children
|
|
4030
4165
|
}) => {
|
|
4031
|
-
const
|
|
4032
|
-
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
|
|
4033
|
-
const open = isControlled ? controlledOpen : uncontrolledOpen;
|
|
4034
|
-
const setOpen = useCallback(
|
|
4035
|
-
(next) => {
|
|
4036
|
-
if (!isControlled) {
|
|
4037
|
-
setUncontrolledOpen(next);
|
|
4038
|
-
}
|
|
4039
|
-
onOpenChange?.(next);
|
|
4040
|
-
},
|
|
4041
|
-
[isControlled, onOpenChange]
|
|
4042
|
-
);
|
|
4166
|
+
const [open, setOpen] = useControlledState(controlledOpen, defaultOpen, onOpenChange);
|
|
4043
4167
|
const value = useMemo(() => ({ open, setOpen }), [open, setOpen]);
|
|
4044
4168
|
return /* @__PURE__ */ u(DialogProvider, { value, children });
|
|
4045
4169
|
};
|
|
@@ -4179,7 +4303,7 @@ const DialogContent = forwardRef(
|
|
|
4179
4303
|
preventScroll: false,
|
|
4180
4304
|
onActivate: () => {
|
|
4181
4305
|
requestAnimationFrame(() => {
|
|
4182
|
-
const event = new Event("openautofocus");
|
|
4306
|
+
const event = new Event("openautofocus", { bubbles: true, cancelable: true });
|
|
4183
4307
|
onOpenAutoFocus?.(event);
|
|
4184
4308
|
if (!event.defaultPrevented && contentRef.current) {
|
|
4185
4309
|
contentRef.current.focus();
|
|
@@ -4188,7 +4312,7 @@ const DialogContent = forwardRef(
|
|
|
4188
4312
|
},
|
|
4189
4313
|
onDeactivate: () => {
|
|
4190
4314
|
requestAnimationFrame(() => {
|
|
4191
|
-
const event = new Event("closeautofocus");
|
|
4315
|
+
const event = new Event("closeautofocus", { bubbles: true, cancelable: true });
|
|
4192
4316
|
onCloseAutoFocus?.(event);
|
|
4193
4317
|
});
|
|
4194
4318
|
}
|
|
@@ -4207,6 +4331,7 @@ const DialogContent = forwardRef(
|
|
|
4207
4331
|
"relative rounded-lg shadow-xl bg-surface-neutral",
|
|
4208
4332
|
"flex flex-col max-w-lg w-full max-h-[90vh] gap-10 p-10",
|
|
4209
4333
|
"border border-bdr-subtle outline-none overflow-hidden",
|
|
4334
|
+
"focus:outline-none focus:ring-0",
|
|
4210
4335
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
4211
4336
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
4212
4337
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
@@ -4379,7 +4504,7 @@ const Input = forwardRef(
|
|
|
4379
4504
|
const state = error ? "error" : "default";
|
|
4380
4505
|
const hasError = state === "error";
|
|
4381
4506
|
return /* @__PURE__ */ u("div", { className: cn("w-full", disabled && "opacity-30", className), children: [
|
|
4382
|
-
/* @__PURE__ */ u("div", { className: "mb-2", children: [
|
|
4507
|
+
(!!label || !!description) && /* @__PURE__ */ u("div", { className: "mb-2", children: [
|
|
4383
4508
|
label && /* @__PURE__ */ u(
|
|
4384
4509
|
"label",
|
|
4385
4510
|
{
|
|
@@ -4549,7 +4674,11 @@ const ListboxRoot = ({
|
|
|
4549
4674
|
focusable = true,
|
|
4550
4675
|
disabled,
|
|
4551
4676
|
children,
|
|
4552
|
-
keyHandler
|
|
4677
|
+
keyHandler,
|
|
4678
|
+
registerItem: externalRegisterItem,
|
|
4679
|
+
unregisterItem: externalUnregisterItem,
|
|
4680
|
+
getItems: externalGetItems,
|
|
4681
|
+
isItemDisabled: externalIsItemDisabled
|
|
4553
4682
|
}) => {
|
|
4554
4683
|
const listboxBaseId = baseId ?? usePrefixedId();
|
|
4555
4684
|
const [uncontrolledSelection, setUncontrolledSelection] = useState(() => new Set(defaultSelection));
|
|
@@ -4558,18 +4687,12 @@ const ListboxRoot = ({
|
|
|
4558
4687
|
() => isSelectionControlled ? new Set(controlledSelection) : uncontrolledSelection,
|
|
4559
4688
|
[isSelectionControlled, controlledSelection, uncontrolledSelection]
|
|
4560
4689
|
);
|
|
4561
|
-
const [
|
|
4562
|
-
const
|
|
4563
|
-
const
|
|
4564
|
-
const
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
setUncontrolledActive(id);
|
|
4568
|
-
}
|
|
4569
|
-
setActive?.(id);
|
|
4570
|
-
},
|
|
4571
|
-
[isActiveControlled, setActive]
|
|
4572
|
-
);
|
|
4690
|
+
const [active, updateActive] = useControlledState(controlledActive, defaultActive, setActive);
|
|
4691
|
+
const internalRegistry = useItemRegistry();
|
|
4692
|
+
const registerItem = externalRegisterItem ?? internalRegistry.registerItem;
|
|
4693
|
+
const unregisterItem = externalUnregisterItem ?? internalRegistry.unregisterItem;
|
|
4694
|
+
const getItems = externalGetItems ?? internalRegistry.getItems;
|
|
4695
|
+
const isItemDisabled = externalIsItemDisabled ?? internalRegistry.isItemDisabled;
|
|
4573
4696
|
const toggleValue = useCallback(
|
|
4574
4697
|
(value) => {
|
|
4575
4698
|
const isSelected = selectionSet.has(value);
|
|
@@ -4604,15 +4727,34 @@ const ListboxRoot = ({
|
|
|
4604
4727
|
setActive: updateActive,
|
|
4605
4728
|
toggleValue,
|
|
4606
4729
|
baseId: listboxBaseId,
|
|
4607
|
-
keyHandler
|
|
4730
|
+
keyHandler,
|
|
4731
|
+
registerItem,
|
|
4732
|
+
unregisterItem,
|
|
4733
|
+
getItems,
|
|
4734
|
+
isItemDisabled
|
|
4608
4735
|
}),
|
|
4609
|
-
[
|
|
4736
|
+
[
|
|
4737
|
+
active,
|
|
4738
|
+
selectionSet,
|
|
4739
|
+
selectionMode,
|
|
4740
|
+
focusable,
|
|
4741
|
+
disabled,
|
|
4742
|
+
updateActive,
|
|
4743
|
+
toggleValue,
|
|
4744
|
+
listboxBaseId,
|
|
4745
|
+
keyHandler,
|
|
4746
|
+
registerItem,
|
|
4747
|
+
unregisterItem,
|
|
4748
|
+
getItems,
|
|
4749
|
+
isItemDisabled
|
|
4750
|
+
]
|
|
4610
4751
|
);
|
|
4611
4752
|
return /* @__PURE__ */ u(ListboxProvider, { value: contextValue, children });
|
|
4612
4753
|
};
|
|
4613
4754
|
ListboxRoot.displayName = "ListboxRoot";
|
|
4614
4755
|
const ListboxContent = forwardRef(
|
|
4615
4756
|
({ className, label, children, ...props }, ref) => {
|
|
4757
|
+
const innerRef = useRef(null);
|
|
4616
4758
|
const {
|
|
4617
4759
|
active,
|
|
4618
4760
|
disabled,
|
|
@@ -4621,59 +4763,22 @@ const ListboxContent = forwardRef(
|
|
|
4621
4763
|
baseId,
|
|
4622
4764
|
selectionMode,
|
|
4623
4765
|
keyHandler,
|
|
4624
|
-
focusable = true
|
|
4766
|
+
focusable = true,
|
|
4767
|
+
getItems,
|
|
4768
|
+
isItemDisabled
|
|
4625
4769
|
} = useListbox();
|
|
4626
|
-
const
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4770
|
+
const { handleKeyDown: handleNavKeyDown } = useKeyboardNavigation({
|
|
4771
|
+
getItems,
|
|
4772
|
+
isItemDisabled,
|
|
4773
|
+
active,
|
|
4774
|
+
setActive,
|
|
4775
|
+
loop: false,
|
|
4776
|
+
orientation: "vertical",
|
|
4777
|
+
onSelect: (id) => {
|
|
4778
|
+
toggleValue(id);
|
|
4631
4779
|
}
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
}, []);
|
|
4635
|
-
const moveActive = useCallback(
|
|
4636
|
-
(delta) => {
|
|
4637
|
-
const items = getItems();
|
|
4638
|
-
if (!items.length) {
|
|
4639
|
-
return;
|
|
4640
|
-
}
|
|
4641
|
-
const currentIndex = active ? items.indexOf(active) : -1;
|
|
4642
|
-
const newIndex = Math.max(0, Math.min(items.length - 1, currentIndex + delta));
|
|
4643
|
-
setActive(items[newIndex]);
|
|
4644
|
-
},
|
|
4645
|
-
[active, setActive, getItems]
|
|
4646
|
-
);
|
|
4647
|
-
const handleKeyDown = keyHandler ?? useCallback(
|
|
4648
|
-
(e) => {
|
|
4649
|
-
if (disabled) {
|
|
4650
|
-
return;
|
|
4651
|
-
}
|
|
4652
|
-
const items = getItems();
|
|
4653
|
-
if (!items.length) {
|
|
4654
|
-
return;
|
|
4655
|
-
}
|
|
4656
|
-
if (e.key === "ArrowDown") {
|
|
4657
|
-
e.preventDefault();
|
|
4658
|
-
moveActive(1);
|
|
4659
|
-
} else if (e.key === "ArrowUp") {
|
|
4660
|
-
e.preventDefault();
|
|
4661
|
-
moveActive(-1);
|
|
4662
|
-
} else if (e.key === "Home") {
|
|
4663
|
-
e.preventDefault();
|
|
4664
|
-
setActive(items[0]);
|
|
4665
|
-
} else if (e.key === "End") {
|
|
4666
|
-
e.preventDefault();
|
|
4667
|
-
setActive(items[items.length - 1]);
|
|
4668
|
-
} else if (e.key === " " || e.key === "Enter") {
|
|
4669
|
-
e.preventDefault();
|
|
4670
|
-
if (active) {
|
|
4671
|
-
toggleValue(active);
|
|
4672
|
-
}
|
|
4673
|
-
}
|
|
4674
|
-
},
|
|
4675
|
-
[disabled, getItems, active, moveActive, toggleValue, setActive]
|
|
4676
|
-
);
|
|
4780
|
+
});
|
|
4781
|
+
const handleKeyDown = keyHandler ?? handleNavKeyDown;
|
|
4677
4782
|
useEffect(() => {
|
|
4678
4783
|
if (!active || !innerRef.current) {
|
|
4679
4784
|
return;
|
|
@@ -4721,6 +4826,10 @@ const listboxItemVariants = cva("flex w-full items-center px-4.5 py-1 gap-x-2.5
|
|
|
4721
4826
|
active: {
|
|
4722
4827
|
true: "bg-surface-primary-hover",
|
|
4723
4828
|
false: ""
|
|
4829
|
+
},
|
|
4830
|
+
disabled: {
|
|
4831
|
+
true: "opacity-30 cursor-not-allowed pointer-events-none",
|
|
4832
|
+
false: ""
|
|
4724
4833
|
}
|
|
4725
4834
|
},
|
|
4726
4835
|
compoundVariants: [
|
|
@@ -4732,19 +4841,25 @@ const listboxItemVariants = cva("flex w-full items-center px-4.5 py-1 gap-x-2.5
|
|
|
4732
4841
|
],
|
|
4733
4842
|
defaultVariants: {
|
|
4734
4843
|
selected: false,
|
|
4735
|
-
active: false
|
|
4844
|
+
active: false,
|
|
4845
|
+
disabled: false
|
|
4736
4846
|
}
|
|
4737
4847
|
});
|
|
4738
|
-
const ListboxItem = ({ value, children, className, ...props }) => {
|
|
4848
|
+
const ListboxItem = ({ value, disabled = false, children, className, ...props }) => {
|
|
4739
4849
|
const ctx = useListbox();
|
|
4740
|
-
const { disabled, toggleValue, baseId } = ctx;
|
|
4850
|
+
const { disabled: listboxDisabled, toggleValue, baseId, registerItem, unregisterItem } = ctx;
|
|
4741
4851
|
const isSelected = ctx.selection.has(value);
|
|
4742
4852
|
const isActive = ctx.active === value;
|
|
4853
|
+
const isDisabled = disabled || listboxDisabled;
|
|
4854
|
+
useEffect(() => {
|
|
4855
|
+
registerItem(value, isDisabled);
|
|
4856
|
+
return () => unregisterItem(value);
|
|
4857
|
+
}, [value, isDisabled, registerItem, unregisterItem]);
|
|
4743
4858
|
const handleClick = useCallback(() => {
|
|
4744
|
-
if (!
|
|
4859
|
+
if (!isDisabled) {
|
|
4745
4860
|
toggleValue(value);
|
|
4746
4861
|
}
|
|
4747
|
-
}, [
|
|
4862
|
+
}, [isDisabled, toggleValue, value]);
|
|
4748
4863
|
return (
|
|
4749
4864
|
// ARIA listbox pattern: options are not individually focusable
|
|
4750
4865
|
// Parent listbox handles all keyboard interactions via aria-activedescendant
|
|
@@ -4753,9 +4868,10 @@ const ListboxItem = ({ value, children, className, ...props }) => {
|
|
|
4753
4868
|
"div",
|
|
4754
4869
|
{
|
|
4755
4870
|
id: `${baseId}-listbox-option-${value}`,
|
|
4756
|
-
className: cn(listboxItemVariants({ selected: isSelected, active: isActive }), className),
|
|
4871
|
+
className: cn(listboxItemVariants({ selected: isSelected, active: isActive, disabled: isDisabled }), className),
|
|
4757
4872
|
role: "option",
|
|
4758
4873
|
"aria-selected": isSelected,
|
|
4874
|
+
"aria-disabled": isDisabled ?? void 0,
|
|
4759
4875
|
"data-value": value,
|
|
4760
4876
|
"data-active": isActive || void 0,
|
|
4761
4877
|
onClick: handleClick,
|
|
@@ -4777,35 +4893,12 @@ const MenuRoot = ({
|
|
|
4777
4893
|
onOpenChange,
|
|
4778
4894
|
children
|
|
4779
4895
|
}) => {
|
|
4780
|
-
const isControlled = controlledOpen !== void 0;
|
|
4781
|
-
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
|
|
4782
|
-
const open = isControlled ? controlledOpen : uncontrolledOpen;
|
|
4783
|
-
const setOpen = useCallback(
|
|
4784
|
-
(next) => {
|
|
4785
|
-
if (!isControlled) {
|
|
4786
|
-
setUncontrolledOpen(next);
|
|
4787
|
-
}
|
|
4788
|
-
onOpenChange?.(next);
|
|
4789
|
-
},
|
|
4790
|
-
[isControlled, onOpenChange]
|
|
4791
|
-
);
|
|
4792
|
-
const [active, setActive] = useState(void 0);
|
|
4793
|
-
const itemsRef = useRef(/* @__PURE__ */ new Map());
|
|
4794
4896
|
const triggerRef = useRef(null);
|
|
4795
4897
|
const triggerId = usePrefixedId(void 0, "menu-trigger");
|
|
4796
4898
|
const menuId = usePrefixedId(void 0, "menu");
|
|
4797
|
-
const
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
const unregisterItem = useCallback((id) => {
|
|
4801
|
-
itemsRef.current.delete(id);
|
|
4802
|
-
}, []);
|
|
4803
|
-
const getItems = useCallback(() => {
|
|
4804
|
-
return Array.from(itemsRef.current.keys());
|
|
4805
|
-
}, []);
|
|
4806
|
-
const isItemDisabled = useCallback((id) => {
|
|
4807
|
-
return itemsRef.current.get(id)?.disabled ?? false;
|
|
4808
|
-
}, []);
|
|
4899
|
+
const [open, setOpen] = useControlledState(controlledOpen, defaultOpen, onOpenChange);
|
|
4900
|
+
const [active, setActive] = useState(void 0);
|
|
4901
|
+
const { registerItem, unregisterItem, getItems, isItemDisabled } = useItemRegistry();
|
|
4809
4902
|
const value = useMemo(
|
|
4810
4903
|
() => ({
|
|
4811
4904
|
open,
|
|
@@ -4892,9 +4985,7 @@ const MenuContent = forwardRef(
|
|
|
4892
4985
|
const { open, setOpen, active, setActive, getItems, isItemDisabled, menuId, triggerRef } = useMenu();
|
|
4893
4986
|
const contentRef = useRef(null);
|
|
4894
4987
|
const composedRefs = useComposedRefs(ref, contentRef);
|
|
4895
|
-
const [position, setPosition] = useState(
|
|
4896
|
-
null
|
|
4897
|
-
);
|
|
4988
|
+
const [position, setPosition] = useState(void 0);
|
|
4898
4989
|
useEffect(() => {
|
|
4899
4990
|
if (!open || !triggerRef?.current || !contentRef.current) {
|
|
4900
4991
|
return;
|
|
@@ -4950,101 +5041,42 @@ const MenuContent = forwardRef(
|
|
|
4950
5041
|
}
|
|
4951
5042
|
}
|
|
4952
5043
|
}, [open, getItems, isItemDisabled, setActive]);
|
|
4953
|
-
const
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
newIndex = delta > 0 ? 0 : items.length - 1;
|
|
4965
|
-
} else {
|
|
4966
|
-
newIndex = currentIndex + delta;
|
|
4967
|
-
}
|
|
4968
|
-
while (attempts < maxAttempts) {
|
|
4969
|
-
if (loop) {
|
|
4970
|
-
if (newIndex < 0) {
|
|
4971
|
-
newIndex = items.length - 1;
|
|
4972
|
-
} else if (newIndex >= items.length) {
|
|
4973
|
-
newIndex = 0;
|
|
4974
|
-
}
|
|
4975
|
-
} else {
|
|
4976
|
-
if (newIndex < 0 || newIndex >= items.length) {
|
|
4977
|
-
return;
|
|
4978
|
-
}
|
|
4979
|
-
}
|
|
4980
|
-
if (!isItemDisabled(items[newIndex])) {
|
|
4981
|
-
setActive(items[newIndex]);
|
|
4982
|
-
return;
|
|
4983
|
-
}
|
|
4984
|
-
newIndex += delta;
|
|
4985
|
-
attempts++;
|
|
5044
|
+
const { handleKeyDown: handleNavKeyDown } = useKeyboardNavigation({
|
|
5045
|
+
getItems,
|
|
5046
|
+
isItemDisabled,
|
|
5047
|
+
active,
|
|
5048
|
+
setActive,
|
|
5049
|
+
loop,
|
|
5050
|
+
orientation: "vertical",
|
|
5051
|
+
onSelect: (id) => {
|
|
5052
|
+
const itemElement = document.getElementById(id);
|
|
5053
|
+
if (itemElement) {
|
|
5054
|
+
itemElement.click();
|
|
4986
5055
|
}
|
|
4987
|
-
}
|
|
4988
|
-
|
|
4989
|
-
);
|
|
5056
|
+
}
|
|
5057
|
+
});
|
|
4990
5058
|
const handleKeyDown = useCallback(
|
|
4991
5059
|
(e) => {
|
|
4992
|
-
|
|
4993
|
-
|
|
5060
|
+
if (e.key === "Tab") {
|
|
5061
|
+
setOpen(false);
|
|
4994
5062
|
return;
|
|
4995
5063
|
}
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
case "ArrowUp":
|
|
5002
|
-
e.preventDefault();
|
|
5003
|
-
moveActive(-1);
|
|
5004
|
-
break;
|
|
5005
|
-
case "Home":
|
|
5006
|
-
e.preventDefault();
|
|
5007
|
-
{
|
|
5008
|
-
const firstEnabled = items.find((id) => !isItemDisabled(id));
|
|
5009
|
-
if (firstEnabled) {
|
|
5010
|
-
setActive(firstEnabled);
|
|
5011
|
-
}
|
|
5012
|
-
}
|
|
5013
|
-
break;
|
|
5014
|
-
case "End":
|
|
5015
|
-
e.preventDefault();
|
|
5016
|
-
{
|
|
5017
|
-
const lastEnabled = [...items].reverse().find((id) => !isItemDisabled(id));
|
|
5018
|
-
if (lastEnabled) {
|
|
5019
|
-
setActive(lastEnabled);
|
|
5020
|
-
}
|
|
5021
|
-
}
|
|
5022
|
-
break;
|
|
5023
|
-
case "Enter":
|
|
5024
|
-
case " ":
|
|
5025
|
-
e.preventDefault();
|
|
5026
|
-
if (active && !isItemDisabled(active)) {
|
|
5027
|
-
const itemElement = document.getElementById(active);
|
|
5028
|
-
if (itemElement) {
|
|
5029
|
-
itemElement.click();
|
|
5030
|
-
}
|
|
5031
|
-
}
|
|
5032
|
-
break;
|
|
5033
|
-
case "Escape":
|
|
5034
|
-
e.preventDefault();
|
|
5035
|
-
onEscapeKeyDown?.(e);
|
|
5036
|
-
setOpen(false);
|
|
5037
|
-
break;
|
|
5038
|
-
case "Tab":
|
|
5039
|
-
setOpen(false);
|
|
5040
|
-
break;
|
|
5064
|
+
if (e.key === "Escape") {
|
|
5065
|
+
e.preventDefault();
|
|
5066
|
+
onEscapeKeyDown?.(e);
|
|
5067
|
+
setOpen(false);
|
|
5068
|
+
return;
|
|
5041
5069
|
}
|
|
5070
|
+
handleNavKeyDown(e);
|
|
5042
5071
|
},
|
|
5043
|
-
[
|
|
5072
|
+
[handleNavKeyDown, setOpen, onEscapeKeyDown]
|
|
5044
5073
|
);
|
|
5045
5074
|
const handlePointerDownOutside = useCallback(
|
|
5046
5075
|
(e) => {
|
|
5047
5076
|
const target = e.target;
|
|
5077
|
+
if (!(target instanceof Node)) {
|
|
5078
|
+
return;
|
|
5079
|
+
}
|
|
5048
5080
|
if (triggerRef?.current?.contains(target)) {
|
|
5049
5081
|
return;
|
|
5050
5082
|
}
|
|
@@ -5227,25 +5259,16 @@ const SearchInput = forwardRef(
|
|
|
5227
5259
|
...props
|
|
5228
5260
|
}, ref) => {
|
|
5229
5261
|
const inputId = usePrefixedId(unwrap(id));
|
|
5230
|
-
const
|
|
5231
|
-
const
|
|
5232
|
-
const inputValue = isControlled ? value : uncontrolledValue;
|
|
5262
|
+
const inputRef = useRef(null);
|
|
5263
|
+
const [inputValue, setInputValue] = useControlledState(value, defaultValue, onChange);
|
|
5233
5264
|
const isValueSet = inputValue.length > 0;
|
|
5234
5265
|
const canClear = showClearButton && isValueSet && !disabled && !readOnly;
|
|
5235
5266
|
const handleChange = (e) => {
|
|
5236
5267
|
const newValue = e.currentTarget.value;
|
|
5237
|
-
|
|
5238
|
-
setUncontrolledValue(newValue);
|
|
5239
|
-
}
|
|
5240
|
-
onChange?.(newValue);
|
|
5268
|
+
setInputValue(newValue);
|
|
5241
5269
|
};
|
|
5242
|
-
const inputRef = useRef(null);
|
|
5243
5270
|
const handleClear = () => {
|
|
5244
|
-
|
|
5245
|
-
if (!isControlled) {
|
|
5246
|
-
setUncontrolledValue(newValue);
|
|
5247
|
-
}
|
|
5248
|
-
onChange?.(newValue);
|
|
5271
|
+
setInputValue("");
|
|
5249
5272
|
inputRef.current?.focus();
|
|
5250
5273
|
};
|
|
5251
5274
|
return /* @__PURE__ */ u(
|
|
@@ -5277,7 +5300,7 @@ const SearchInput = forwardRef(
|
|
|
5277
5300
|
"w-full text-base border-0",
|
|
5278
5301
|
"text-main bg-surface-neutral",
|
|
5279
5302
|
"placeholder:text-subtle",
|
|
5280
|
-
"focus:outline-none",
|
|
5303
|
+
"focus:outline-none focus:ring-0",
|
|
5281
5304
|
"read-only:bg-surface-primary",
|
|
5282
5305
|
!showSearchIcon && "pl-4.5",
|
|
5283
5306
|
"pr-4"
|
|
@@ -5606,12 +5629,19 @@ export {
|
|
|
5606
5629
|
Separator,
|
|
5607
5630
|
Tooltip,
|
|
5608
5631
|
cn,
|
|
5632
|
+
generateAriaId,
|
|
5633
|
+
generateAriaIds,
|
|
5634
|
+
generateItemId,
|
|
5635
|
+
getActiveDescendantId,
|
|
5609
5636
|
setRef,
|
|
5610
5637
|
unwrap,
|
|
5611
5638
|
useAvatar,
|
|
5612
5639
|
useCombobox,
|
|
5613
5640
|
useComposedRefs,
|
|
5641
|
+
useControlledState,
|
|
5614
5642
|
useDialog,
|
|
5643
|
+
useItemRegistry,
|
|
5644
|
+
useKeyboardNavigation,
|
|
5615
5645
|
useListbox,
|
|
5616
5646
|
useMenu,
|
|
5617
5647
|
usePrefixedId,
|