@enonic/ui 0.13.0 → 0.13.1
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 +369 -340
- 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
|
};
|
|
@@ -4379,7 +4503,7 @@ const Input = forwardRef(
|
|
|
4379
4503
|
const state = error ? "error" : "default";
|
|
4380
4504
|
const hasError = state === "error";
|
|
4381
4505
|
return /* @__PURE__ */ u("div", { className: cn("w-full", disabled && "opacity-30", className), children: [
|
|
4382
|
-
/* @__PURE__ */ u("div", { className: "mb-2", children: [
|
|
4506
|
+
(!!label || !!description) && /* @__PURE__ */ u("div", { className: "mb-2", children: [
|
|
4383
4507
|
label && /* @__PURE__ */ u(
|
|
4384
4508
|
"label",
|
|
4385
4509
|
{
|
|
@@ -4549,7 +4673,11 @@ const ListboxRoot = ({
|
|
|
4549
4673
|
focusable = true,
|
|
4550
4674
|
disabled,
|
|
4551
4675
|
children,
|
|
4552
|
-
keyHandler
|
|
4676
|
+
keyHandler,
|
|
4677
|
+
registerItem: externalRegisterItem,
|
|
4678
|
+
unregisterItem: externalUnregisterItem,
|
|
4679
|
+
getItems: externalGetItems,
|
|
4680
|
+
isItemDisabled: externalIsItemDisabled
|
|
4553
4681
|
}) => {
|
|
4554
4682
|
const listboxBaseId = baseId ?? usePrefixedId();
|
|
4555
4683
|
const [uncontrolledSelection, setUncontrolledSelection] = useState(() => new Set(defaultSelection));
|
|
@@ -4558,18 +4686,12 @@ const ListboxRoot = ({
|
|
|
4558
4686
|
() => isSelectionControlled ? new Set(controlledSelection) : uncontrolledSelection,
|
|
4559
4687
|
[isSelectionControlled, controlledSelection, uncontrolledSelection]
|
|
4560
4688
|
);
|
|
4561
|
-
const [
|
|
4562
|
-
const
|
|
4563
|
-
const
|
|
4564
|
-
const
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
setUncontrolledActive(id);
|
|
4568
|
-
}
|
|
4569
|
-
setActive?.(id);
|
|
4570
|
-
},
|
|
4571
|
-
[isActiveControlled, setActive]
|
|
4572
|
-
);
|
|
4689
|
+
const [active, updateActive] = useControlledState(controlledActive, defaultActive, setActive);
|
|
4690
|
+
const internalRegistry = useItemRegistry();
|
|
4691
|
+
const registerItem = externalRegisterItem ?? internalRegistry.registerItem;
|
|
4692
|
+
const unregisterItem = externalUnregisterItem ?? internalRegistry.unregisterItem;
|
|
4693
|
+
const getItems = externalGetItems ?? internalRegistry.getItems;
|
|
4694
|
+
const isItemDisabled = externalIsItemDisabled ?? internalRegistry.isItemDisabled;
|
|
4573
4695
|
const toggleValue = useCallback(
|
|
4574
4696
|
(value) => {
|
|
4575
4697
|
const isSelected = selectionSet.has(value);
|
|
@@ -4604,15 +4726,34 @@ const ListboxRoot = ({
|
|
|
4604
4726
|
setActive: updateActive,
|
|
4605
4727
|
toggleValue,
|
|
4606
4728
|
baseId: listboxBaseId,
|
|
4607
|
-
keyHandler
|
|
4729
|
+
keyHandler,
|
|
4730
|
+
registerItem,
|
|
4731
|
+
unregisterItem,
|
|
4732
|
+
getItems,
|
|
4733
|
+
isItemDisabled
|
|
4608
4734
|
}),
|
|
4609
|
-
[
|
|
4735
|
+
[
|
|
4736
|
+
active,
|
|
4737
|
+
selectionSet,
|
|
4738
|
+
selectionMode,
|
|
4739
|
+
focusable,
|
|
4740
|
+
disabled,
|
|
4741
|
+
updateActive,
|
|
4742
|
+
toggleValue,
|
|
4743
|
+
listboxBaseId,
|
|
4744
|
+
keyHandler,
|
|
4745
|
+
registerItem,
|
|
4746
|
+
unregisterItem,
|
|
4747
|
+
getItems,
|
|
4748
|
+
isItemDisabled
|
|
4749
|
+
]
|
|
4610
4750
|
);
|
|
4611
4751
|
return /* @__PURE__ */ u(ListboxProvider, { value: contextValue, children });
|
|
4612
4752
|
};
|
|
4613
4753
|
ListboxRoot.displayName = "ListboxRoot";
|
|
4614
4754
|
const ListboxContent = forwardRef(
|
|
4615
4755
|
({ className, label, children, ...props }, ref) => {
|
|
4756
|
+
const innerRef = useRef(null);
|
|
4616
4757
|
const {
|
|
4617
4758
|
active,
|
|
4618
4759
|
disabled,
|
|
@@ -4621,59 +4762,22 @@ const ListboxContent = forwardRef(
|
|
|
4621
4762
|
baseId,
|
|
4622
4763
|
selectionMode,
|
|
4623
4764
|
keyHandler,
|
|
4624
|
-
focusable = true
|
|
4765
|
+
focusable = true,
|
|
4766
|
+
getItems,
|
|
4767
|
+
isItemDisabled
|
|
4625
4768
|
} = useListbox();
|
|
4626
|
-
const
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4769
|
+
const { handleKeyDown: handleNavKeyDown } = useKeyboardNavigation({
|
|
4770
|
+
getItems,
|
|
4771
|
+
isItemDisabled,
|
|
4772
|
+
active,
|
|
4773
|
+
setActive,
|
|
4774
|
+
loop: false,
|
|
4775
|
+
orientation: "vertical",
|
|
4776
|
+
onSelect: (id) => {
|
|
4777
|
+
toggleValue(id);
|
|
4631
4778
|
}
|
|
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
|
-
);
|
|
4779
|
+
});
|
|
4780
|
+
const handleKeyDown = keyHandler ?? handleNavKeyDown;
|
|
4677
4781
|
useEffect(() => {
|
|
4678
4782
|
if (!active || !innerRef.current) {
|
|
4679
4783
|
return;
|
|
@@ -4721,6 +4825,10 @@ const listboxItemVariants = cva("flex w-full items-center px-4.5 py-1 gap-x-2.5
|
|
|
4721
4825
|
active: {
|
|
4722
4826
|
true: "bg-surface-primary-hover",
|
|
4723
4827
|
false: ""
|
|
4828
|
+
},
|
|
4829
|
+
disabled: {
|
|
4830
|
+
true: "opacity-30 cursor-not-allowed pointer-events-none",
|
|
4831
|
+
false: ""
|
|
4724
4832
|
}
|
|
4725
4833
|
},
|
|
4726
4834
|
compoundVariants: [
|
|
@@ -4732,19 +4840,25 @@ const listboxItemVariants = cva("flex w-full items-center px-4.5 py-1 gap-x-2.5
|
|
|
4732
4840
|
],
|
|
4733
4841
|
defaultVariants: {
|
|
4734
4842
|
selected: false,
|
|
4735
|
-
active: false
|
|
4843
|
+
active: false,
|
|
4844
|
+
disabled: false
|
|
4736
4845
|
}
|
|
4737
4846
|
});
|
|
4738
|
-
const ListboxItem = ({ value, children, className, ...props }) => {
|
|
4847
|
+
const ListboxItem = ({ value, disabled = false, children, className, ...props }) => {
|
|
4739
4848
|
const ctx = useListbox();
|
|
4740
|
-
const { disabled, toggleValue, baseId } = ctx;
|
|
4849
|
+
const { disabled: listboxDisabled, toggleValue, baseId, registerItem, unregisterItem } = ctx;
|
|
4741
4850
|
const isSelected = ctx.selection.has(value);
|
|
4742
4851
|
const isActive = ctx.active === value;
|
|
4852
|
+
const isDisabled = disabled || listboxDisabled;
|
|
4853
|
+
useEffect(() => {
|
|
4854
|
+
registerItem(value, isDisabled);
|
|
4855
|
+
return () => unregisterItem(value);
|
|
4856
|
+
}, [value, isDisabled, registerItem, unregisterItem]);
|
|
4743
4857
|
const handleClick = useCallback(() => {
|
|
4744
|
-
if (!
|
|
4858
|
+
if (!isDisabled) {
|
|
4745
4859
|
toggleValue(value);
|
|
4746
4860
|
}
|
|
4747
|
-
}, [
|
|
4861
|
+
}, [isDisabled, toggleValue, value]);
|
|
4748
4862
|
return (
|
|
4749
4863
|
// ARIA listbox pattern: options are not individually focusable
|
|
4750
4864
|
// Parent listbox handles all keyboard interactions via aria-activedescendant
|
|
@@ -4753,9 +4867,10 @@ const ListboxItem = ({ value, children, className, ...props }) => {
|
|
|
4753
4867
|
"div",
|
|
4754
4868
|
{
|
|
4755
4869
|
id: `${baseId}-listbox-option-${value}`,
|
|
4756
|
-
className: cn(listboxItemVariants({ selected: isSelected, active: isActive }), className),
|
|
4870
|
+
className: cn(listboxItemVariants({ selected: isSelected, active: isActive, disabled: isDisabled }), className),
|
|
4757
4871
|
role: "option",
|
|
4758
4872
|
"aria-selected": isSelected,
|
|
4873
|
+
"aria-disabled": isDisabled ?? void 0,
|
|
4759
4874
|
"data-value": value,
|
|
4760
4875
|
"data-active": isActive || void 0,
|
|
4761
4876
|
onClick: handleClick,
|
|
@@ -4777,35 +4892,12 @@ const MenuRoot = ({
|
|
|
4777
4892
|
onOpenChange,
|
|
4778
4893
|
children
|
|
4779
4894
|
}) => {
|
|
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
4895
|
const triggerRef = useRef(null);
|
|
4795
4896
|
const triggerId = usePrefixedId(void 0, "menu-trigger");
|
|
4796
4897
|
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
|
-
}, []);
|
|
4898
|
+
const [open, setOpen] = useControlledState(controlledOpen, defaultOpen, onOpenChange);
|
|
4899
|
+
const [active, setActive] = useState(void 0);
|
|
4900
|
+
const { registerItem, unregisterItem, getItems, isItemDisabled } = useItemRegistry();
|
|
4809
4901
|
const value = useMemo(
|
|
4810
4902
|
() => ({
|
|
4811
4903
|
open,
|
|
@@ -4892,9 +4984,7 @@ const MenuContent = forwardRef(
|
|
|
4892
4984
|
const { open, setOpen, active, setActive, getItems, isItemDisabled, menuId, triggerRef } = useMenu();
|
|
4893
4985
|
const contentRef = useRef(null);
|
|
4894
4986
|
const composedRefs = useComposedRefs(ref, contentRef);
|
|
4895
|
-
const [position, setPosition] = useState(
|
|
4896
|
-
null
|
|
4897
|
-
);
|
|
4987
|
+
const [position, setPosition] = useState(void 0);
|
|
4898
4988
|
useEffect(() => {
|
|
4899
4989
|
if (!open || !triggerRef?.current || !contentRef.current) {
|
|
4900
4990
|
return;
|
|
@@ -4950,101 +5040,42 @@ const MenuContent = forwardRef(
|
|
|
4950
5040
|
}
|
|
4951
5041
|
}
|
|
4952
5042
|
}, [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++;
|
|
5043
|
+
const { handleKeyDown: handleNavKeyDown } = useKeyboardNavigation({
|
|
5044
|
+
getItems,
|
|
5045
|
+
isItemDisabled,
|
|
5046
|
+
active,
|
|
5047
|
+
setActive,
|
|
5048
|
+
loop,
|
|
5049
|
+
orientation: "vertical",
|
|
5050
|
+
onSelect: (id) => {
|
|
5051
|
+
const itemElement = document.getElementById(id);
|
|
5052
|
+
if (itemElement) {
|
|
5053
|
+
itemElement.click();
|
|
4986
5054
|
}
|
|
4987
|
-
}
|
|
4988
|
-
|
|
4989
|
-
);
|
|
5055
|
+
}
|
|
5056
|
+
});
|
|
4990
5057
|
const handleKeyDown = useCallback(
|
|
4991
5058
|
(e) => {
|
|
4992
|
-
|
|
4993
|
-
|
|
5059
|
+
if (e.key === "Tab") {
|
|
5060
|
+
setOpen(false);
|
|
4994
5061
|
return;
|
|
4995
5062
|
}
|
|
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;
|
|
5063
|
+
if (e.key === "Escape") {
|
|
5064
|
+
e.preventDefault();
|
|
5065
|
+
onEscapeKeyDown?.(e);
|
|
5066
|
+
setOpen(false);
|
|
5067
|
+
return;
|
|
5041
5068
|
}
|
|
5069
|
+
handleNavKeyDown(e);
|
|
5042
5070
|
},
|
|
5043
|
-
[
|
|
5071
|
+
[handleNavKeyDown, setOpen, onEscapeKeyDown]
|
|
5044
5072
|
);
|
|
5045
5073
|
const handlePointerDownOutside = useCallback(
|
|
5046
5074
|
(e) => {
|
|
5047
5075
|
const target = e.target;
|
|
5076
|
+
if (!(target instanceof Node)) {
|
|
5077
|
+
return;
|
|
5078
|
+
}
|
|
5048
5079
|
if (triggerRef?.current?.contains(target)) {
|
|
5049
5080
|
return;
|
|
5050
5081
|
}
|
|
@@ -5227,25 +5258,16 @@ const SearchInput = forwardRef(
|
|
|
5227
5258
|
...props
|
|
5228
5259
|
}, ref) => {
|
|
5229
5260
|
const inputId = usePrefixedId(unwrap(id));
|
|
5230
|
-
const
|
|
5231
|
-
const
|
|
5232
|
-
const inputValue = isControlled ? value : uncontrolledValue;
|
|
5261
|
+
const inputRef = useRef(null);
|
|
5262
|
+
const [inputValue, setInputValue] = useControlledState(value, defaultValue, onChange);
|
|
5233
5263
|
const isValueSet = inputValue.length > 0;
|
|
5234
5264
|
const canClear = showClearButton && isValueSet && !disabled && !readOnly;
|
|
5235
5265
|
const handleChange = (e) => {
|
|
5236
5266
|
const newValue = e.currentTarget.value;
|
|
5237
|
-
|
|
5238
|
-
setUncontrolledValue(newValue);
|
|
5239
|
-
}
|
|
5240
|
-
onChange?.(newValue);
|
|
5267
|
+
setInputValue(newValue);
|
|
5241
5268
|
};
|
|
5242
|
-
const inputRef = useRef(null);
|
|
5243
5269
|
const handleClear = () => {
|
|
5244
|
-
|
|
5245
|
-
if (!isControlled) {
|
|
5246
|
-
setUncontrolledValue(newValue);
|
|
5247
|
-
}
|
|
5248
|
-
onChange?.(newValue);
|
|
5270
|
+
setInputValue("");
|
|
5249
5271
|
inputRef.current?.focus();
|
|
5250
5272
|
};
|
|
5251
5273
|
return /* @__PURE__ */ u(
|
|
@@ -5606,12 +5628,19 @@ export {
|
|
|
5606
5628
|
Separator,
|
|
5607
5629
|
Tooltip,
|
|
5608
5630
|
cn,
|
|
5631
|
+
generateAriaId,
|
|
5632
|
+
generateAriaIds,
|
|
5633
|
+
generateItemId,
|
|
5634
|
+
getActiveDescendantId,
|
|
5609
5635
|
setRef,
|
|
5610
5636
|
unwrap,
|
|
5611
5637
|
useAvatar,
|
|
5612
5638
|
useCombobox,
|
|
5613
5639
|
useComposedRefs,
|
|
5640
|
+
useControlledState,
|
|
5614
5641
|
useDialog,
|
|
5642
|
+
useItemRegistry,
|
|
5643
|
+
useKeyboardNavigation,
|
|
5615
5644
|
useListbox,
|
|
5616
5645
|
useMenu,
|
|
5617
5646
|
usePrefixedId,
|