@enonic/ui 0.13.2 → 0.15.0
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 -5
- package/dist/enonic-ui.es.js +299 -144
- package/dist/styles/style.css +1 -1
- package/dist/types/components/combobox/combobox.d.ts +30 -9
- package/dist/types/components/index.d.ts +1 -1
- package/dist/types/components/search-field/index.d.ts +1 -0
- package/dist/types/components/search-field/search-field.d.ts +39 -0
- package/dist/types/providers/combobox-provider.d.ts +6 -0
- package/dist/types/providers/index.d.ts +1 -0
- package/dist/types/providers/search-field-provider.d.ts +17 -0
- package/dist/types/utils/array.d.ts +1 -0
- package/package.json +1 -1
- package/dist/types/components/search-input/index.d.ts +0 -1
- package/dist/types/components/search-input/search-input.d.ts +0 -16
package/dist/enonic-ui.es.js
CHANGED
|
@@ -81,6 +81,17 @@ const useMenu = () => {
|
|
|
81
81
|
}
|
|
82
82
|
return context;
|
|
83
83
|
};
|
|
84
|
+
const SearchFieldContext = createContext(void 0);
|
|
85
|
+
const SearchFieldProvider = ({ value, children }) => {
|
|
86
|
+
return /* @__PURE__ */ u(SearchFieldContext.Provider, { value, children });
|
|
87
|
+
};
|
|
88
|
+
const useSearchField = () => {
|
|
89
|
+
const context = useContext(SearchFieldContext);
|
|
90
|
+
if (!context) {
|
|
91
|
+
throw new Error("useSearchField must be used within a SearchFieldProvider");
|
|
92
|
+
}
|
|
93
|
+
return context;
|
|
94
|
+
};
|
|
84
95
|
function generateAriaId(baseId, suffix) {
|
|
85
96
|
return `${baseId}-${suffix}`;
|
|
86
97
|
}
|
|
@@ -3855,7 +3866,27 @@ const IconButton = forwardRef(
|
|
|
3855
3866
|
}
|
|
3856
3867
|
);
|
|
3857
3868
|
IconButton.displayName = "IconButton";
|
|
3869
|
+
function areArraysEquals(left, right, order = "any") {
|
|
3870
|
+
if (left === right) {
|
|
3871
|
+
return true;
|
|
3872
|
+
}
|
|
3873
|
+
if (left == null || right == null) {
|
|
3874
|
+
return false;
|
|
3875
|
+
}
|
|
3876
|
+
if (left.length !== right.length) {
|
|
3877
|
+
return false;
|
|
3878
|
+
}
|
|
3879
|
+
const leftArray = order === "any" ? [...left].sort() : left;
|
|
3880
|
+
const rightArray = order === "any" ? [...right].sort() : right;
|
|
3881
|
+
for (let i = 0; i < leftArray.length; i += 1) {
|
|
3882
|
+
if (leftArray[i] !== rightArray[i]) {
|
|
3883
|
+
return false;
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
return true;
|
|
3887
|
+
}
|
|
3858
3888
|
const EMPTY_SELECTION$1 = [];
|
|
3889
|
+
const updateArrayIfChanged = (next) => (prev) => areArraysEquals(prev, next) ? prev : next;
|
|
3859
3890
|
const ComboboxRoot = ({
|
|
3860
3891
|
children,
|
|
3861
3892
|
open: controlledOpen,
|
|
@@ -3878,25 +3909,35 @@ const ComboboxRoot = ({
|
|
|
3878
3909
|
const baseId = usePrefixedId();
|
|
3879
3910
|
const [open, setOpenInternal] = useControlledState(controlledOpen, defaultOpen, onOpenChange);
|
|
3880
3911
|
const [inputValue, setInputValueInternal] = useControlledState(value, defaultValue, onChange);
|
|
3912
|
+
const isMultipleSelection = selectionMode !== "single";
|
|
3913
|
+
const stagingEnabled = selectionMode === "staged";
|
|
3881
3914
|
const [uncontrolledSelection, setUncontrolledSelection] = useState(() => new Set(defaultSelection));
|
|
3882
3915
|
const isSelectionControlled = controlledSelection !== void 0;
|
|
3883
|
-
const
|
|
3916
|
+
const appliedSelectionSet = useMemo(
|
|
3884
3917
|
() => isSelectionControlled ? new Set(controlledSelection) : uncontrolledSelection,
|
|
3885
3918
|
[isSelectionControlled, controlledSelection, uncontrolledSelection]
|
|
3886
3919
|
);
|
|
3887
|
-
const
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3920
|
+
const appliedSelection = useMemo(() => Array.from(appliedSelectionSet), [appliedSelectionSet]);
|
|
3921
|
+
const [stagedSelection, setStagedSelection] = useState(appliedSelection);
|
|
3922
|
+
useEffect(() => {
|
|
3923
|
+
if (!stagingEnabled) {
|
|
3924
|
+
setStagedSelection(appliedSelection);
|
|
3925
|
+
return;
|
|
3926
|
+
}
|
|
3927
|
+
setStagedSelection(updateArrayIfChanged(appliedSelection));
|
|
3928
|
+
}, [appliedSelection, stagingEnabled]);
|
|
3929
|
+
const currentSelection = stagingEnabled ? stagedSelection : appliedSelection;
|
|
3930
|
+
const currentSelectionSet = useMemo(() => new Set(currentSelection), [currentSelection]);
|
|
3931
|
+
const hasStagedChanges = useMemo(
|
|
3932
|
+
() => stagingEnabled && !areArraysEquals(stagedSelection, appliedSelection),
|
|
3933
|
+
[stagingEnabled, stagedSelection, appliedSelection]
|
|
3899
3934
|
);
|
|
3935
|
+
const resetStagedSelection = useCallback(() => {
|
|
3936
|
+
if (!stagingEnabled) {
|
|
3937
|
+
return;
|
|
3938
|
+
}
|
|
3939
|
+
setStagedSelection(updateArrayIfChanged(appliedSelection));
|
|
3940
|
+
}, [stagingEnabled, appliedSelection]);
|
|
3900
3941
|
const [activeInternal, setActiveInternal] = useControlledState(controlledActive, defaultActive, setActive);
|
|
3901
3942
|
const { registerItem, unregisterItem, getItems, isItemDisabled } = useItemRegistry();
|
|
3902
3943
|
const setInputValue = useCallback(
|
|
@@ -3909,9 +3950,44 @@ const ComboboxRoot = ({
|
|
|
3909
3950
|
const setOpen = useCallback(
|
|
3910
3951
|
(next) => {
|
|
3911
3952
|
setOpenInternal(next);
|
|
3953
|
+
if (!next) {
|
|
3954
|
+
resetStagedSelection();
|
|
3955
|
+
}
|
|
3912
3956
|
},
|
|
3913
|
-
[setOpenInternal]
|
|
3957
|
+
[setOpenInternal, resetStagedSelection]
|
|
3914
3958
|
);
|
|
3959
|
+
const commitSelection = useCallback(
|
|
3960
|
+
(newSelection) => {
|
|
3961
|
+
const newSet = new Set(newSelection);
|
|
3962
|
+
if (!isSelectionControlled) {
|
|
3963
|
+
setUncontrolledSelection(newSet);
|
|
3964
|
+
}
|
|
3965
|
+
onSelectionChange?.(newSelection);
|
|
3966
|
+
if (selectionMode === "single") {
|
|
3967
|
+
setOpenInternal(false);
|
|
3968
|
+
}
|
|
3969
|
+
},
|
|
3970
|
+
[isSelectionControlled, onSelectionChange, selectionMode, setOpenInternal]
|
|
3971
|
+
);
|
|
3972
|
+
const handleSelectionChange = useCallback(
|
|
3973
|
+
(nextSelection) => {
|
|
3974
|
+
if (stagingEnabled) {
|
|
3975
|
+
setStagedSelection(nextSelection);
|
|
3976
|
+
return;
|
|
3977
|
+
}
|
|
3978
|
+
commitSelection(nextSelection);
|
|
3979
|
+
},
|
|
3980
|
+
[stagingEnabled, commitSelection]
|
|
3981
|
+
);
|
|
3982
|
+
const applyStagedSelection = useCallback(() => {
|
|
3983
|
+
if (!stagingEnabled) {
|
|
3984
|
+
return;
|
|
3985
|
+
}
|
|
3986
|
+
if (!areArraysEquals(stagedSelection, appliedSelection)) {
|
|
3987
|
+
commitSelection(stagedSelection);
|
|
3988
|
+
}
|
|
3989
|
+
setOpenInternal(false);
|
|
3990
|
+
}, [stagingEnabled, stagedSelection, appliedSelection, commitSelection, setOpenInternal]);
|
|
3915
3991
|
const { handleKeyDown: handleNavKeyDown } = useKeyboardNavigation({
|
|
3916
3992
|
getItems,
|
|
3917
3993
|
isItemDisabled,
|
|
@@ -3920,8 +3996,15 @@ const ComboboxRoot = ({
|
|
|
3920
3996
|
loop: false,
|
|
3921
3997
|
orientation: "vertical",
|
|
3922
3998
|
onSelect: (id) => {
|
|
3923
|
-
|
|
3924
|
-
|
|
3999
|
+
let nextSelection;
|
|
4000
|
+
if (!isMultipleSelection) {
|
|
4001
|
+
nextSelection = [id];
|
|
4002
|
+
} else if (currentSelection.includes(id)) {
|
|
4003
|
+
nextSelection = currentSelection.filter((item) => item !== id);
|
|
4004
|
+
} else {
|
|
4005
|
+
nextSelection = [...currentSelection, id];
|
|
4006
|
+
}
|
|
4007
|
+
handleSelectionChange(nextSelection);
|
|
3925
4008
|
}
|
|
3926
4009
|
});
|
|
3927
4010
|
const keyHandler = useCallback(
|
|
@@ -3937,12 +4020,12 @@ const ComboboxRoot = ({
|
|
|
3937
4020
|
}
|
|
3938
4021
|
if (e.key === "Escape") {
|
|
3939
4022
|
e.preventDefault();
|
|
3940
|
-
|
|
4023
|
+
setOpen(false);
|
|
3941
4024
|
return;
|
|
3942
4025
|
}
|
|
3943
4026
|
handleNavKeyDown(e);
|
|
3944
4027
|
},
|
|
3945
|
-
[disabled, open, setOpenInternal, handleNavKeyDown]
|
|
4028
|
+
[disabled, open, setOpenInternal, setOpen, handleNavKeyDown]
|
|
3946
4029
|
);
|
|
3947
4030
|
useEffect(() => {
|
|
3948
4031
|
if (open && activeInternal === void 0) {
|
|
@@ -3964,7 +4047,13 @@ const ComboboxRoot = ({
|
|
|
3964
4047
|
error,
|
|
3965
4048
|
closeOnBlur,
|
|
3966
4049
|
keyHandler,
|
|
3967
|
-
selection:
|
|
4050
|
+
selection: currentSelectionSet,
|
|
4051
|
+
appliedSelection,
|
|
4052
|
+
stagedSelection,
|
|
4053
|
+
stagingEnabled,
|
|
4054
|
+
hasStagedChanges,
|
|
4055
|
+
applyStagedSelection,
|
|
4056
|
+
resetStagedSelection
|
|
3968
4057
|
}),
|
|
3969
4058
|
[
|
|
3970
4059
|
open,
|
|
@@ -3977,15 +4066,21 @@ const ComboboxRoot = ({
|
|
|
3977
4066
|
baseId,
|
|
3978
4067
|
disabled,
|
|
3979
4068
|
error,
|
|
3980
|
-
|
|
4069
|
+
currentSelectionSet,
|
|
4070
|
+
appliedSelection,
|
|
4071
|
+
stagedSelection,
|
|
4072
|
+
stagingEnabled,
|
|
4073
|
+
hasStagedChanges,
|
|
4074
|
+
applyStagedSelection,
|
|
4075
|
+
resetStagedSelection
|
|
3981
4076
|
]
|
|
3982
4077
|
);
|
|
3983
4078
|
return /* @__PURE__ */ u(ComboboxProvider, { value: context, children: /* @__PURE__ */ u(
|
|
3984
4079
|
Listbox.Root,
|
|
3985
4080
|
{
|
|
3986
|
-
selectionMode,
|
|
3987
|
-
selection:
|
|
3988
|
-
onSelectionChange:
|
|
4081
|
+
selectionMode: isMultipleSelection ? "multiple" : "single",
|
|
4082
|
+
selection: currentSelection,
|
|
4083
|
+
onSelectionChange: handleSelectionChange,
|
|
3989
4084
|
disabled,
|
|
3990
4085
|
active: activeInternal,
|
|
3991
4086
|
focusable: false,
|
|
@@ -4002,10 +4097,10 @@ const ComboboxRoot = ({
|
|
|
4002
4097
|
};
|
|
4003
4098
|
ComboboxRoot.displayName = "Combobox.Root";
|
|
4004
4099
|
const ComboboxContent = forwardRef(
|
|
4005
|
-
({ className, children }, ref) => {
|
|
4100
|
+
({ className, children, ...props }, ref) => {
|
|
4006
4101
|
const innerRef = useRef(null);
|
|
4007
|
-
const { setOpen,
|
|
4008
|
-
const
|
|
4102
|
+
const { setOpen, closeOnBlur } = useCombobox();
|
|
4103
|
+
const handleOnBlur = closeOnBlur ? useCallback(
|
|
4009
4104
|
(e) => {
|
|
4010
4105
|
const nextTarget = e.relatedTarget;
|
|
4011
4106
|
if (nextTarget && innerRef.current?.contains(nextTarget)) {
|
|
@@ -4013,18 +4108,18 @@ const ComboboxContent = forwardRef(
|
|
|
4013
4108
|
}
|
|
4014
4109
|
setOpen(false);
|
|
4015
4110
|
},
|
|
4016
|
-
[
|
|
4111
|
+
[setOpen]
|
|
4017
4112
|
) : void 0;
|
|
4018
4113
|
return (
|
|
4019
|
-
// eslint-disable-next-line
|
|
4020
|
-
/* @__PURE__ */ u("div", {
|
|
4114
|
+
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
4115
|
+
/* @__PURE__ */ u("div", { ref: useComposedRefs(ref, innerRef), className, onBlur: handleOnBlur, ...props, children })
|
|
4021
4116
|
);
|
|
4022
4117
|
}
|
|
4023
4118
|
);
|
|
4024
4119
|
ComboboxContent.displayName = "Combobox.Content";
|
|
4025
4120
|
const comboboxControlVariants = cva(
|
|
4026
4121
|
[
|
|
4027
|
-
"flex items-center",
|
|
4122
|
+
"flex gap-2.5 items-center",
|
|
4028
4123
|
"h-12 rounded-sm border bg-surface-neutral",
|
|
4029
4124
|
"focus-within:outline-none focus-within:ring-3 focus-within:ring-ring/50 focus-within:ring-offset-0",
|
|
4030
4125
|
"transition-highlight"
|
|
@@ -4051,7 +4146,7 @@ const comboboxControlVariants = cva(
|
|
|
4051
4146
|
}
|
|
4052
4147
|
}
|
|
4053
4148
|
);
|
|
4054
|
-
const ComboboxControl = ({ children,
|
|
4149
|
+
const ComboboxControl = ({ className, children, ...props }) => {
|
|
4055
4150
|
const { open, disabled, error } = useCombobox();
|
|
4056
4151
|
return /* @__PURE__ */ u(
|
|
4057
4152
|
"div",
|
|
@@ -4065,31 +4160,27 @@ const ComboboxControl = ({ children, className }) => {
|
|
|
4065
4160
|
className
|
|
4066
4161
|
),
|
|
4067
4162
|
"data-open": open ? "true" : void 0,
|
|
4163
|
+
...props,
|
|
4068
4164
|
children
|
|
4069
4165
|
}
|
|
4070
4166
|
);
|
|
4071
4167
|
};
|
|
4072
4168
|
ComboboxControl.displayName = "Combobox.Control";
|
|
4073
4169
|
const ComboboxInput = forwardRef(
|
|
4074
|
-
({
|
|
4170
|
+
({ placeholder, ...props }, ref) => {
|
|
4075
4171
|
const innerRef = useRef(null);
|
|
4076
|
-
const {
|
|
4172
|
+
const { open, keyHandler, baseId, active, disabled, error } = useCombobox();
|
|
4077
4173
|
useEffect(() => {
|
|
4078
4174
|
if (open && !disabled) {
|
|
4079
4175
|
innerRef.current?.focus();
|
|
4080
4176
|
}
|
|
4081
|
-
}, [open,
|
|
4177
|
+
}, [open, disabled]);
|
|
4082
4178
|
return /* @__PURE__ */ u(
|
|
4083
|
-
|
|
4179
|
+
SearchField.Input,
|
|
4084
4180
|
{
|
|
4085
4181
|
ref: useComposedRefs(ref, innerRef),
|
|
4086
4182
|
id: `${baseId}-input`,
|
|
4087
|
-
className: "border-none focus:outline-none focus-within:outline-none h-auto focus-within:ring-0 grow",
|
|
4088
|
-
value: inputValue,
|
|
4089
|
-
onChange: setInputValue,
|
|
4090
4183
|
onKeyDown: keyHandler,
|
|
4091
|
-
placeholder,
|
|
4092
|
-
disabled,
|
|
4093
4184
|
"aria-disabled": disabled,
|
|
4094
4185
|
"aria-invalid": error ?? void 0,
|
|
4095
4186
|
role: "combobox",
|
|
@@ -4098,41 +4189,74 @@ const ComboboxInput = forwardRef(
|
|
|
4098
4189
|
"aria-haspopup": "listbox",
|
|
4099
4190
|
"aria-controls": `${baseId}-listbox`,
|
|
4100
4191
|
"aria-activedescendant": active ? `${baseId}-listbox-option-${active}` : void 0,
|
|
4101
|
-
showClearButton: false,
|
|
4102
4192
|
...props
|
|
4103
4193
|
}
|
|
4104
4194
|
);
|
|
4105
4195
|
}
|
|
4106
4196
|
);
|
|
4107
4197
|
ComboboxInput.displayName = "Combobox.Input";
|
|
4108
|
-
const
|
|
4198
|
+
const ComboboxSearch = ({ children, className, ...props }) => {
|
|
4199
|
+
const { inputValue, setInputValue } = useCombobox();
|
|
4200
|
+
return /* @__PURE__ */ u(
|
|
4201
|
+
SearchField.Root,
|
|
4202
|
+
{
|
|
4203
|
+
value: inputValue,
|
|
4204
|
+
onChange: setInputValue,
|
|
4205
|
+
className: cn(
|
|
4206
|
+
"w-full pr-0",
|
|
4207
|
+
"border-0 focus-within:border-0 focus-within:ring-0 focus-within:ring-offset-0",
|
|
4208
|
+
className
|
|
4209
|
+
),
|
|
4210
|
+
...props,
|
|
4211
|
+
children
|
|
4212
|
+
}
|
|
4213
|
+
);
|
|
4214
|
+
};
|
|
4215
|
+
ComboboxSearch.displayName = "Combobox.Search";
|
|
4216
|
+
const ComboboxToggle = ({ className, ...props }) => {
|
|
4109
4217
|
const { open, setOpen, disabled } = useCombobox();
|
|
4110
4218
|
return /* @__PURE__ */ u(
|
|
4111
4219
|
IconButton,
|
|
4112
4220
|
{
|
|
4113
4221
|
type: "button",
|
|
4114
4222
|
variant: "text",
|
|
4115
|
-
size: "
|
|
4223
|
+
size: "lg",
|
|
4116
4224
|
icon: ChevronDown,
|
|
4117
4225
|
"aria-label": "Toggle",
|
|
4118
4226
|
onClick: () => {
|
|
4119
|
-
if (disabled)
|
|
4120
|
-
return;
|
|
4121
|
-
}
|
|
4122
|
-
setOpen(!open);
|
|
4227
|
+
if (!disabled) setOpen(!open);
|
|
4123
4228
|
},
|
|
4124
4229
|
disabled,
|
|
4125
4230
|
tabIndex: -1,
|
|
4126
4231
|
className: cn(
|
|
4127
|
-
"
|
|
4232
|
+
"shrink-0 text-subtle transition-transform hover:bg-surface-primary-hover",
|
|
4128
4233
|
open && "rotate-180",
|
|
4129
4234
|
className
|
|
4130
|
-
)
|
|
4235
|
+
),
|
|
4236
|
+
...props
|
|
4131
4237
|
}
|
|
4132
4238
|
);
|
|
4133
4239
|
};
|
|
4134
4240
|
ComboboxToggle.displayName = "Combobox.Toggle";
|
|
4135
|
-
const
|
|
4241
|
+
const ComboboxApply = ({ className, label = "Apply", ...props }) => {
|
|
4242
|
+
const { stagingEnabled, hasStagedChanges, applyStagedSelection } = useCombobox();
|
|
4243
|
+
if (!stagingEnabled || !hasStagedChanges) {
|
|
4244
|
+
return null;
|
|
4245
|
+
}
|
|
4246
|
+
return /* @__PURE__ */ u(
|
|
4247
|
+
Button,
|
|
4248
|
+
{
|
|
4249
|
+
className: cn("h-7 px-2.5 min-w-14 gap-2 text-xs", className),
|
|
4250
|
+
type: "button",
|
|
4251
|
+
label,
|
|
4252
|
+
variant: "outline",
|
|
4253
|
+
onClick: applyStagedSelection,
|
|
4254
|
+
...props
|
|
4255
|
+
}
|
|
4256
|
+
);
|
|
4257
|
+
};
|
|
4258
|
+
ComboboxApply.displayName = "Combobox.Apply";
|
|
4259
|
+
const ComboboxPopup = ({ children, className, ...props }) => {
|
|
4136
4260
|
const { open } = useCombobox();
|
|
4137
4261
|
if (!open) {
|
|
4138
4262
|
return null;
|
|
@@ -4144,6 +4268,7 @@ const ComboboxPopup = ({ children, className }) => {
|
|
|
4144
4268
|
"absolute left-0 right-0 z-50 mt-1 rounded-sm bg-surface-neutral shadow-lg ring-1 ring-bdr-subtle",
|
|
4145
4269
|
className
|
|
4146
4270
|
),
|
|
4271
|
+
...props,
|
|
4147
4272
|
children
|
|
4148
4273
|
}
|
|
4149
4274
|
);
|
|
@@ -4153,8 +4278,11 @@ const Combobox = Object.assign(ComboboxRoot, {
|
|
|
4153
4278
|
Root: ComboboxRoot,
|
|
4154
4279
|
Content: ComboboxContent,
|
|
4155
4280
|
Control: ComboboxControl,
|
|
4281
|
+
Search: ComboboxSearch,
|
|
4156
4282
|
Input: ComboboxInput,
|
|
4283
|
+
SearchIcon: SearchField.Icon,
|
|
4157
4284
|
Toggle: ComboboxToggle,
|
|
4285
|
+
Apply: ComboboxApply,
|
|
4158
4286
|
Popup: ComboboxPopup
|
|
4159
4287
|
});
|
|
4160
4288
|
const DialogRoot = ({
|
|
@@ -4505,18 +4633,11 @@ const Input = forwardRef(
|
|
|
4505
4633
|
const hasError = state === "error";
|
|
4506
4634
|
return /* @__PURE__ */ u("div", { className: cn("w-full", disabled && "opacity-30", className), children: [
|
|
4507
4635
|
(!!label || !!description) && /* @__PURE__ */ u("div", { className: "mb-2", children: [
|
|
4508
|
-
label && /* @__PURE__ */ u(
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
children: /* @__PURE__ */ u("div", { className: "flex items-center gap-2", children: [
|
|
4514
|
-
readOnly && /* @__PURE__ */ u(LockKeyhole, { size: 16, strokeWidth: 2.5 }),
|
|
4515
|
-
label
|
|
4516
|
-
] })
|
|
4517
|
-
}
|
|
4518
|
-
),
|
|
4519
|
-
description && /* @__PURE__ */ u("div", { className: cn("text-sm text-subtle", disabled && "opacity-30"), children: description })
|
|
4636
|
+
label && /* @__PURE__ */ u("label", { htmlFor: inputId, className: "block text-base font-semibold text-main", children: /* @__PURE__ */ u("div", { className: "flex items-center gap-2", children: [
|
|
4637
|
+
readOnly && /* @__PURE__ */ u(LockKeyhole, { size: 16, strokeWidth: 2.5 }),
|
|
4638
|
+
label
|
|
4639
|
+
] }) }),
|
|
4640
|
+
description && /* @__PURE__ */ u("div", { className: "text-sm text-subtle", children: description })
|
|
4520
4641
|
] }),
|
|
4521
4642
|
/* @__PURE__ */ u("div", { className: cn(inputContainerVariants({ state, disabled })), children: [
|
|
4522
4643
|
startAddon && /* @__PURE__ */ u(Addon, { error: hasError, children: startAddon }),
|
|
@@ -4529,7 +4650,7 @@ const Input = forwardRef(
|
|
|
4529
4650
|
"flex-1 w-full px-4.5 text-base",
|
|
4530
4651
|
"text-main bg-surface-neutral placeholder:text-subtle",
|
|
4531
4652
|
"border-0 focus:outline-none",
|
|
4532
|
-
"disabled:select-none read-only:bg-surface-primary",
|
|
4653
|
+
"disabled:select-none enabled:read-only:bg-surface-primary",
|
|
4533
4654
|
startAddon && "rounded-l-none",
|
|
4534
4655
|
endAddon && "rounded-r-none"
|
|
4535
4656
|
),
|
|
@@ -4817,7 +4938,7 @@ const ListboxContent = forwardRef(
|
|
|
4817
4938
|
}
|
|
4818
4939
|
);
|
|
4819
4940
|
ListboxContent.displayName = "ListboxContent";
|
|
4820
|
-
const listboxItemVariants = cva("flex w-full items-center px-4.5 py-1 gap-x-2.5 cursor-pointer", {
|
|
4941
|
+
const listboxItemVariants = cva("group flex w-full items-center px-4.5 py-1 gap-x-2.5 cursor-pointer", {
|
|
4821
4942
|
variants: {
|
|
4822
4943
|
selected: {
|
|
4823
4944
|
true: "bg-surface-primary-selected text-alt hover:bg-surface-primary-selected-hover",
|
|
@@ -4874,6 +4995,7 @@ const ListboxItem = ({ value, disabled = false, children, className, ...props })
|
|
|
4874
4995
|
"aria-disabled": isDisabled ?? void 0,
|
|
4875
4996
|
"data-value": value,
|
|
4876
4997
|
"data-active": isActive || void 0,
|
|
4998
|
+
"data-tone": isSelected && "inverse",
|
|
4877
4999
|
onClick: handleClick,
|
|
4878
5000
|
...props,
|
|
4879
5001
|
children
|
|
@@ -5243,95 +5365,126 @@ const Menu = Object.assign(MenuRoot, {
|
|
|
5243
5365
|
Label: MenuLabel,
|
|
5244
5366
|
Separator: MenuSeparator
|
|
5245
5367
|
});
|
|
5246
|
-
const
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5368
|
+
const SearchFieldRoot = ({
|
|
5369
|
+
id,
|
|
5370
|
+
value,
|
|
5371
|
+
defaultValue = "",
|
|
5372
|
+
onChange,
|
|
5373
|
+
placeholder = "Search",
|
|
5374
|
+
clearLabel = "Clear",
|
|
5375
|
+
disabled,
|
|
5376
|
+
readOnly,
|
|
5377
|
+
children,
|
|
5378
|
+
className,
|
|
5379
|
+
...props
|
|
5380
|
+
}) => {
|
|
5381
|
+
const inputId = usePrefixedId(unwrap(id));
|
|
5382
|
+
const inputRef = useRef(null);
|
|
5383
|
+
const [inputValue, setInputValue] = useControlledState(value, defaultValue, onChange);
|
|
5384
|
+
const context = useMemo(
|
|
5385
|
+
() => ({
|
|
5386
|
+
id: inputId,
|
|
5387
|
+
value: inputValue,
|
|
5388
|
+
disabled,
|
|
5389
|
+
readOnly,
|
|
5390
|
+
placeholder,
|
|
5391
|
+
clearLabel,
|
|
5392
|
+
setValue: setInputValue,
|
|
5393
|
+
inputRef
|
|
5394
|
+
}),
|
|
5395
|
+
[inputId, inputValue, disabled, readOnly, placeholder, clearLabel, setInputValue]
|
|
5396
|
+
);
|
|
5397
|
+
return /* @__PURE__ */ u(SearchFieldProvider, { value: context, children: /* @__PURE__ */ u(
|
|
5398
|
+
"div",
|
|
5399
|
+
{
|
|
5400
|
+
className: cn(
|
|
5401
|
+
"relative flex gap-2.5 items-center rounded-sm overflow-hidden",
|
|
5402
|
+
"h-11.5 px-4.5 py-3",
|
|
5403
|
+
"border border-bdr-subtle focus-within:border-bdr-strong",
|
|
5404
|
+
"focus-within:outline-none focus-within:ring-3 focus-within:ring-ring/50 focus-within:ring-offset-0",
|
|
5405
|
+
"transition-highlight",
|
|
5406
|
+
readOnly ? "bg-surface-primary" : "bg-surface-neutral",
|
|
5407
|
+
disabled && "pointer-events-none select-none opacity-30",
|
|
5408
|
+
className
|
|
5409
|
+
),
|
|
5410
|
+
...props,
|
|
5411
|
+
children
|
|
5412
|
+
}
|
|
5413
|
+
) });
|
|
5414
|
+
};
|
|
5415
|
+
SearchFieldRoot.displayName = "SearchFieldRoot";
|
|
5416
|
+
const SearchFieldIcon = ({ className }) => {
|
|
5417
|
+
return /* @__PURE__ */ u(
|
|
5418
|
+
Search,
|
|
5419
|
+
{
|
|
5420
|
+
className: cn("flex items-center justify-center shrink-0 size-5.5 text-subtle", className),
|
|
5421
|
+
strokeWidth: 1.5
|
|
5422
|
+
}
|
|
5423
|
+
);
|
|
5424
|
+
};
|
|
5425
|
+
SearchFieldIcon.displayName = "SearchFieldIcon";
|
|
5426
|
+
const SearchFieldInput = forwardRef(
|
|
5427
|
+
({ className, ...props }, ref) => {
|
|
5428
|
+
const { id, value, disabled, readOnly, placeholder, setValue, inputRef } = useSearchField();
|
|
5266
5429
|
const handleChange = (e) => {
|
|
5267
|
-
|
|
5268
|
-
setInputValue(newValue);
|
|
5269
|
-
};
|
|
5270
|
-
const handleClear = () => {
|
|
5271
|
-
setInputValue("");
|
|
5272
|
-
inputRef.current?.focus();
|
|
5430
|
+
setValue(e.currentTarget.value);
|
|
5273
5431
|
};
|
|
5274
5432
|
return /* @__PURE__ */ u(
|
|
5275
|
-
"
|
|
5433
|
+
"input",
|
|
5276
5434
|
{
|
|
5435
|
+
ref: useComposedRefs(ref, inputRef),
|
|
5436
|
+
id,
|
|
5277
5437
|
className: cn(
|
|
5278
|
-
"
|
|
5279
|
-
"
|
|
5280
|
-
"
|
|
5281
|
-
"
|
|
5282
|
-
|
|
5438
|
+
"h-5.5 w-full text-base border-0",
|
|
5439
|
+
"text-main bg-surface-neutral",
|
|
5440
|
+
"placeholder:text-subtle",
|
|
5441
|
+
"focus:outline-none",
|
|
5442
|
+
"enabled:read-only:bg-surface-primary",
|
|
5283
5443
|
className
|
|
5284
5444
|
),
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
),
|
|
5294
|
-
/* @__PURE__ */ u(
|
|
5295
|
-
"input",
|
|
5296
|
-
{
|
|
5297
|
-
ref: useComposedRefs(ref, inputRef),
|
|
5298
|
-
id: inputId,
|
|
5299
|
-
className: cn(
|
|
5300
|
-
"w-full text-base border-0",
|
|
5301
|
-
"text-main bg-surface-neutral",
|
|
5302
|
-
"placeholder:text-subtle",
|
|
5303
|
-
"focus:outline-none focus:ring-0",
|
|
5304
|
-
"read-only:bg-surface-primary",
|
|
5305
|
-
!showSearchIcon && "pl-4.5",
|
|
5306
|
-
"pr-4"
|
|
5307
|
-
),
|
|
5308
|
-
value: inputValue,
|
|
5309
|
-
onChange: handleChange,
|
|
5310
|
-
readOnly,
|
|
5311
|
-
disabled,
|
|
5312
|
-
placeholder,
|
|
5313
|
-
"aria-label": "Search",
|
|
5314
|
-
"aria-disabled": disabled,
|
|
5315
|
-
...props
|
|
5316
|
-
}
|
|
5317
|
-
),
|
|
5318
|
-
canClear && /* @__PURE__ */ u(
|
|
5319
|
-
IconButton,
|
|
5320
|
-
{
|
|
5321
|
-
className: "flex items-center justify-center shrink-0 h-10 w-10 mr-1 text-subtle",
|
|
5322
|
-
size: "lg",
|
|
5323
|
-
icon: X,
|
|
5324
|
-
title: clearLabel,
|
|
5325
|
-
onClick: handleClear,
|
|
5326
|
-
disabled
|
|
5327
|
-
}
|
|
5328
|
-
)
|
|
5329
|
-
]
|
|
5445
|
+
value,
|
|
5446
|
+
onChange: handleChange,
|
|
5447
|
+
readOnly,
|
|
5448
|
+
disabled,
|
|
5449
|
+
placeholder,
|
|
5450
|
+
"aria-label": "Search",
|
|
5451
|
+
"aria-disabled": disabled,
|
|
5452
|
+
...props
|
|
5330
5453
|
}
|
|
5331
5454
|
);
|
|
5332
5455
|
}
|
|
5333
5456
|
);
|
|
5334
|
-
|
|
5457
|
+
SearchFieldInput.displayName = "SearchFieldInput";
|
|
5458
|
+
const SearchFieldClear = ({ className, ...props }) => {
|
|
5459
|
+
const { value, disabled, readOnly, clearLabel, setValue, inputRef } = useSearchField();
|
|
5460
|
+
if (!value || disabled || readOnly) {
|
|
5461
|
+
return null;
|
|
5462
|
+
}
|
|
5463
|
+
const handleClear = () => {
|
|
5464
|
+
setValue("");
|
|
5465
|
+
inputRef.current?.focus();
|
|
5466
|
+
};
|
|
5467
|
+
return /* @__PURE__ */ u(
|
|
5468
|
+
IconButton,
|
|
5469
|
+
{
|
|
5470
|
+
className: cn("flex items-center justify-center shrink-0 size-7 -mx-1.5 text-subtle", className),
|
|
5471
|
+
icon: X,
|
|
5472
|
+
title: clearLabel,
|
|
5473
|
+
onClick: handleClear,
|
|
5474
|
+
disabled,
|
|
5475
|
+
iconSize: 28,
|
|
5476
|
+
iconStrokeWidth: 1.25,
|
|
5477
|
+
...props
|
|
5478
|
+
}
|
|
5479
|
+
);
|
|
5480
|
+
};
|
|
5481
|
+
SearchFieldClear.displayName = "SearchFieldClear";
|
|
5482
|
+
const SearchField = Object.assign(SearchFieldRoot, {
|
|
5483
|
+
Root: SearchFieldRoot,
|
|
5484
|
+
Icon: SearchFieldIcon,
|
|
5485
|
+
Input: SearchFieldInput,
|
|
5486
|
+
Clear: SearchFieldClear
|
|
5487
|
+
});
|
|
5335
5488
|
const SelectableListItem = ({
|
|
5336
5489
|
className,
|
|
5337
5490
|
selected,
|
|
@@ -5624,7 +5777,8 @@ export {
|
|
|
5624
5777
|
ListboxProvider,
|
|
5625
5778
|
Menu,
|
|
5626
5779
|
MenuProvider,
|
|
5627
|
-
|
|
5780
|
+
SearchField,
|
|
5781
|
+
SearchFieldProvider,
|
|
5628
5782
|
SelectableListItem,
|
|
5629
5783
|
Separator,
|
|
5630
5784
|
Tooltip,
|
|
@@ -5645,5 +5799,6 @@ export {
|
|
|
5645
5799
|
useListbox,
|
|
5646
5800
|
useMenu,
|
|
5647
5801
|
usePrefixedId,
|
|
5648
|
-
useScrollLock
|
|
5802
|
+
useScrollLock,
|
|
5803
|
+
useSearchField
|
|
5649
5804
|
};
|