prime-ui-kit 0.7.4 → 0.7.8
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/components/index.css +529 -34
- package/dist/components/index.css.map +4 -4
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1116 -110
- package/dist/components/index.js.map +4 -4
- package/dist/components/popover/Popover.d.ts +6 -1
- package/dist/components/popover/Popover.d.ts.map +1 -1
- package/dist/components/select/Select.d.ts +26 -9
- package/dist/components/select/Select.d.ts.map +1 -1
- package/dist/components/select/examples/pattern-multiple.d.ts +3 -0
- package/dist/components/select/examples/pattern-multiple.d.ts.map +1 -0
- package/dist/components/tag-select/TagSelect.d.ts +60 -0
- package/dist/components/tag-select/TagSelect.d.ts.map +1 -0
- package/dist/components/tag-select/examples/pattern-canonical.d.ts +6 -0
- package/dist/components/tag-select/examples/pattern-canonical.d.ts.map +1 -0
- package/dist/components/tag-select/examples/pattern-features.d.ts +3 -0
- package/dist/components/tag-select/examples/pattern-features.d.ts.map +1 -0
- package/dist/hooks/usePosition.d.ts.map +1 -1
- package/dist/index.css +531 -36
- package/dist/index.css.map +4 -4
- package/dist/index.js +1116 -110
- package/dist/index.js.map +4 -4
- package/dist/tokens/semantic.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/select/COMPONENT.md +91 -32
- package/src/components/select/examples/pattern-multiple.tsx +30 -0
- package/src/components/tag-select/COMPONENT.md +154 -0
- package/src/components/tag-select/examples/examples.module.css +14 -0
- package/src/components/tag-select/examples/pattern-canonical.tsx +69 -0
- package/src/components/tag-select/examples/pattern-features.tsx +68 -0
- package/src/styles/theme-dark.css +1 -1
- package/src/styles/theme-light.css +1 -1
package/dist/components/index.js
CHANGED
|
@@ -3832,11 +3832,15 @@ function usePosition(anchorRef, contentRef, options = {}) {
|
|
|
3832
3832
|
(pos) => {
|
|
3833
3833
|
const content = contentRef.current;
|
|
3834
3834
|
if (!content) return;
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
content.style.
|
|
3835
|
+
const nextTop = `${pos.top}px`;
|
|
3836
|
+
const nextLeft = `${pos.left}px`;
|
|
3837
|
+
const nextMinW = pos.minWidth !== void 0 ? `${pos.minWidth}px` : "";
|
|
3838
|
+
const nextMaxH = pos.maxHeight !== void 0 ? `${pos.maxHeight}px` : "";
|
|
3839
|
+
if (content.style.position !== pos.position) content.style.position = pos.position;
|
|
3840
|
+
if (content.style.top !== nextTop) content.style.top = nextTop;
|
|
3841
|
+
if (content.style.left !== nextLeft) content.style.left = nextLeft;
|
|
3842
|
+
if (content.style.minWidth !== nextMinW) content.style.minWidth = nextMinW;
|
|
3843
|
+
if (content.style.maxHeight !== nextMaxH) content.style.maxHeight = nextMaxH;
|
|
3840
3844
|
},
|
|
3841
3845
|
[contentRef]
|
|
3842
3846
|
);
|
|
@@ -3854,7 +3858,7 @@ function usePosition(anchorRef, contentRef, options = {}) {
|
|
|
3854
3858
|
window.innerHeight,
|
|
3855
3859
|
{ preferredSide, align, offset, viewportPad, flip, matchTriggerMinWidth }
|
|
3856
3860
|
);
|
|
3857
|
-
setResolvedSide(pos.resolvedSide);
|
|
3861
|
+
setResolvedSide((prev) => pos.resolvedSide === prev ? prev : pos.resolvedSide);
|
|
3858
3862
|
applyPositionStyle({
|
|
3859
3863
|
position: "fixed",
|
|
3860
3864
|
top: pos.top,
|
|
@@ -3877,6 +3881,21 @@ function usePosition(anchorRef, contentRef, options = {}) {
|
|
|
3877
3881
|
return { resolvedSide, update };
|
|
3878
3882
|
}
|
|
3879
3883
|
|
|
3884
|
+
// src/internal/scrollAncestors.ts
|
|
3885
|
+
var SCROLLABLE = /^(auto|scroll|overlay)$/;
|
|
3886
|
+
function getScrollContainers(node) {
|
|
3887
|
+
const out = [window];
|
|
3888
|
+
if (!node || typeof window === "undefined") return out;
|
|
3889
|
+
for (let el = node.parentElement; el; el = el.parentElement) {
|
|
3890
|
+
const { overflowX, overflowY } = window.getComputedStyle(el);
|
|
3891
|
+
if (SCROLLABLE.test(overflowY) || SCROLLABLE.test(overflowX)) {
|
|
3892
|
+
out.push(el);
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
if (window.visualViewport) out.push(window.visualViewport);
|
|
3896
|
+
return out;
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3880
3899
|
// src/components/select/Select.module.css
|
|
3881
3900
|
var Select_default = {
|
|
3882
3901
|
trigger: "Select_trigger2",
|
|
@@ -3958,13 +3977,22 @@ function handleSelectListboxKeyDown(e, ctx) {
|
|
|
3958
3977
|
|
|
3959
3978
|
// src/components/select/Select.tsx
|
|
3960
3979
|
import { jsx as jsx26, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3980
|
+
var SELECT_LISTBOX_POSITION_OPTS = {
|
|
3981
|
+
side: "bottom",
|
|
3982
|
+
align: "start"
|
|
3983
|
+
};
|
|
3961
3984
|
var [SelectProvider, useSelectContext] = createComponentContext("Select");
|
|
3962
3985
|
function SelectRoot(props) {
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3986
|
+
if (props.multiple === true) {
|
|
3987
|
+
if (props.native === true) {
|
|
3988
|
+
return /* @__PURE__ */ jsx26(SelectNativeMultiRoot, { ...props });
|
|
3989
|
+
}
|
|
3990
|
+
return /* @__PURE__ */ jsx26(SelectComboboxMultiRoot, { ...props });
|
|
3991
|
+
}
|
|
3992
|
+
if (props.native === true) {
|
|
3993
|
+
return /* @__PURE__ */ jsx26(SelectNativeRoot, { ...props });
|
|
3966
3994
|
}
|
|
3967
|
-
return /* @__PURE__ */ jsx26(SelectComboboxRoot, { ...
|
|
3995
|
+
return /* @__PURE__ */ jsx26(SelectComboboxRoot, { ...props });
|
|
3968
3996
|
}
|
|
3969
3997
|
SelectRoot.displayName = "SelectRoot";
|
|
3970
3998
|
function SelectComboboxRoot({
|
|
@@ -4012,32 +4040,138 @@ function SelectComboboxRoot({
|
|
|
4012
4040
|
);
|
|
4013
4041
|
const onClose = React38.useCallback(() => setIsOpen(false), []);
|
|
4014
4042
|
const onOpen = React38.useCallback(() => setIsOpen(true), []);
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4043
|
+
const contextValue = React38.useMemo(
|
|
4044
|
+
() => ({
|
|
4045
|
+
size,
|
|
4046
|
+
hasError,
|
|
4047
|
+
isOpen,
|
|
4048
|
+
multiple: false,
|
|
4049
|
+
selectedValue,
|
|
4050
|
+
selectedLabelBinding,
|
|
4051
|
+
selectedValues: [],
|
|
4052
|
+
labelsByValue: {},
|
|
4053
|
+
onSelect,
|
|
4054
|
+
onClose,
|
|
4055
|
+
onOpen,
|
|
4056
|
+
highlightedValue,
|
|
4057
|
+
setHighlightedValue,
|
|
4058
|
+
triggerId,
|
|
4059
|
+
listboxId,
|
|
4060
|
+
triggerRef,
|
|
4061
|
+
disabled,
|
|
4062
|
+
placeholder,
|
|
4063
|
+
onInitLabel
|
|
4064
|
+
}),
|
|
4065
|
+
[
|
|
4066
|
+
size,
|
|
4067
|
+
hasError,
|
|
4068
|
+
isOpen,
|
|
4069
|
+
selectedValue,
|
|
4070
|
+
selectedLabelBinding,
|
|
4071
|
+
onSelect,
|
|
4072
|
+
onClose,
|
|
4073
|
+
onOpen,
|
|
4074
|
+
highlightedValue,
|
|
4075
|
+
triggerId,
|
|
4076
|
+
listboxId,
|
|
4077
|
+
disabled,
|
|
4078
|
+
placeholder,
|
|
4079
|
+
onInitLabel
|
|
4080
|
+
]
|
|
4038
4081
|
);
|
|
4082
|
+
return /* @__PURE__ */ jsx26(SelectProvider, { value: contextValue, children: /* @__PURE__ */ jsx26(ControlSizeProvider, { value: size, children }) });
|
|
4039
4083
|
}
|
|
4040
4084
|
SelectComboboxRoot.displayName = "SelectComboboxRoot";
|
|
4085
|
+
function SelectComboboxMultiRoot({
|
|
4086
|
+
size = "m",
|
|
4087
|
+
value,
|
|
4088
|
+
defaultValue,
|
|
4089
|
+
onChange,
|
|
4090
|
+
disabled,
|
|
4091
|
+
placeholder,
|
|
4092
|
+
hasError = false,
|
|
4093
|
+
children
|
|
4094
|
+
}) {
|
|
4095
|
+
const handleChange = React38.useCallback(
|
|
4096
|
+
(next) => {
|
|
4097
|
+
onChange?.(next);
|
|
4098
|
+
},
|
|
4099
|
+
[onChange]
|
|
4100
|
+
);
|
|
4101
|
+
const [selectedValues, setSelectedValues] = useControllableState({
|
|
4102
|
+
value,
|
|
4103
|
+
defaultValue: defaultValue ?? [],
|
|
4104
|
+
onChange: handleChange
|
|
4105
|
+
});
|
|
4106
|
+
const [labelsByValue, setLabelsByValue] = React38.useState({});
|
|
4107
|
+
const [isOpen, setIsOpen] = React38.useState(false);
|
|
4108
|
+
const [highlightedValue, setHighlightedValue] = React38.useState(void 0);
|
|
4109
|
+
const generatedId = React38.useId();
|
|
4110
|
+
const triggerId = `${generatedId}-trigger`;
|
|
4111
|
+
const listboxId = `${generatedId}-listbox`;
|
|
4112
|
+
const triggerRef = React38.useRef(null);
|
|
4113
|
+
const onInitLabel = React38.useCallback((val, label) => {
|
|
4114
|
+
setLabelsByValue((prev) => {
|
|
4115
|
+
if (prev[val] === label) return prev;
|
|
4116
|
+
return { ...prev, [val]: label };
|
|
4117
|
+
});
|
|
4118
|
+
}, []);
|
|
4119
|
+
const onSelect = React38.useCallback(
|
|
4120
|
+
(val, label) => {
|
|
4121
|
+
setLabelsByValue((prev) => ({ ...prev, [val]: label }));
|
|
4122
|
+
setSelectedValues((prev) => {
|
|
4123
|
+
if (prev.includes(val)) {
|
|
4124
|
+
return prev.filter((x) => x !== val);
|
|
4125
|
+
}
|
|
4126
|
+
return [...prev, val];
|
|
4127
|
+
});
|
|
4128
|
+
},
|
|
4129
|
+
[setSelectedValues]
|
|
4130
|
+
);
|
|
4131
|
+
const onClose = React38.useCallback(() => setIsOpen(false), []);
|
|
4132
|
+
const onOpen = React38.useCallback(() => setIsOpen(true), []);
|
|
4133
|
+
const contextValue = React38.useMemo(
|
|
4134
|
+
() => ({
|
|
4135
|
+
size,
|
|
4136
|
+
hasError,
|
|
4137
|
+
isOpen,
|
|
4138
|
+
multiple: true,
|
|
4139
|
+
selectedValue: void 0,
|
|
4140
|
+
selectedLabelBinding: void 0,
|
|
4141
|
+
selectedValues,
|
|
4142
|
+
labelsByValue,
|
|
4143
|
+
onSelect,
|
|
4144
|
+
onClose,
|
|
4145
|
+
onOpen,
|
|
4146
|
+
highlightedValue,
|
|
4147
|
+
setHighlightedValue,
|
|
4148
|
+
triggerId,
|
|
4149
|
+
listboxId,
|
|
4150
|
+
triggerRef,
|
|
4151
|
+
disabled,
|
|
4152
|
+
placeholder,
|
|
4153
|
+
onInitLabel
|
|
4154
|
+
}),
|
|
4155
|
+
[
|
|
4156
|
+
size,
|
|
4157
|
+
hasError,
|
|
4158
|
+
isOpen,
|
|
4159
|
+
selectedValues,
|
|
4160
|
+
labelsByValue,
|
|
4161
|
+
onSelect,
|
|
4162
|
+
onClose,
|
|
4163
|
+
onOpen,
|
|
4164
|
+
highlightedValue,
|
|
4165
|
+
triggerId,
|
|
4166
|
+
listboxId,
|
|
4167
|
+
disabled,
|
|
4168
|
+
placeholder,
|
|
4169
|
+
onInitLabel
|
|
4170
|
+
]
|
|
4171
|
+
);
|
|
4172
|
+
return /* @__PURE__ */ jsx26(SelectProvider, { value: contextValue, children: /* @__PURE__ */ jsx26(ControlSizeProvider, { value: size, children }) });
|
|
4173
|
+
}
|
|
4174
|
+
SelectComboboxMultiRoot.displayName = "SelectComboboxMultiRoot";
|
|
4041
4175
|
var SelectTrigger = React38.forwardRef(
|
|
4042
4176
|
({ className, children, onClick, onKeyDown, ...rest }, forwardedRef) => {
|
|
4043
4177
|
const { isOpen, onOpen, onClose, triggerId, listboxId, disabled, size, hasError, triggerRef } = useSelectContext();
|
|
@@ -4092,7 +4226,20 @@ var SelectTrigger = React38.forwardRef(
|
|
|
4092
4226
|
);
|
|
4093
4227
|
SelectTrigger.displayName = "SelectTrigger";
|
|
4094
4228
|
function SelectValue({ className }) {
|
|
4095
|
-
const
|
|
4229
|
+
const ctx = useSelectContext();
|
|
4230
|
+
if (ctx.multiple) {
|
|
4231
|
+
const { selectedValues, labelsByValue, placeholder: placeholder2 } = ctx;
|
|
4232
|
+
const display2 = selectedValues.length === 0 ? placeholder2 : selectedValues.map((v) => labelsByValue[v] ?? v).join(", ");
|
|
4233
|
+
return /* @__PURE__ */ jsx26(
|
|
4234
|
+
"span",
|
|
4235
|
+
{
|
|
4236
|
+
className: cx(Select_default.triggerValue, className),
|
|
4237
|
+
...toDataAttributes({ placeholder: display2 == null || display2 === "" }),
|
|
4238
|
+
children: display2
|
|
4239
|
+
}
|
|
4240
|
+
);
|
|
4241
|
+
}
|
|
4242
|
+
const { selectedLabelBinding, selectedValue, placeholder } = ctx;
|
|
4096
4243
|
const display = selectedLabelBinding && selectedLabelBinding.value === selectedValue ? selectedLabelBinding.label : selectedValue ?? placeholder;
|
|
4097
4244
|
return /* @__PURE__ */ jsx26(
|
|
4098
4245
|
"span",
|
|
@@ -4119,67 +4266,109 @@ function SelectContent({ className, children }) {
|
|
|
4119
4266
|
highlightedValue,
|
|
4120
4267
|
setHighlightedValue,
|
|
4121
4268
|
selectedValue,
|
|
4269
|
+
selectedValues,
|
|
4270
|
+
multiple,
|
|
4122
4271
|
size
|
|
4123
4272
|
} = useSelectContext();
|
|
4273
|
+
const selectedValueRef = React38.useRef(selectedValue);
|
|
4274
|
+
selectedValueRef.current = selectedValue;
|
|
4275
|
+
const selectedValuesRef = React38.useRef(selectedValues);
|
|
4276
|
+
selectedValuesRef.current = selectedValues;
|
|
4277
|
+
const multipleRef = React38.useRef(multiple);
|
|
4278
|
+
multipleRef.current = multiple;
|
|
4124
4279
|
const overlayPortalLayer = useOverlayPortalLayer();
|
|
4125
4280
|
const contentRef = React38.useRef(null);
|
|
4126
|
-
const { resolvedSide, update } = usePosition(
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4281
|
+
const { resolvedSide, update } = usePosition(
|
|
4282
|
+
triggerRef,
|
|
4283
|
+
contentRef,
|
|
4284
|
+
SELECT_LISTBOX_POSITION_OPTS
|
|
4285
|
+
);
|
|
4286
|
+
const updateRef = React38.useRef(update);
|
|
4287
|
+
updateRef.current = update;
|
|
4130
4288
|
const getItems = React38.useCallback(() => queryEnabledSelectOptions(contentRef.current), []);
|
|
4131
4289
|
React38.useLayoutEffect(() => {
|
|
4132
4290
|
if (!isOpen) return;
|
|
4133
|
-
|
|
4134
|
-
const rafId = requestAnimationFrame(() =>
|
|
4291
|
+
updateRef.current();
|
|
4292
|
+
const rafId = requestAnimationFrame(() => updateRef.current());
|
|
4135
4293
|
return () => cancelAnimationFrame(rafId);
|
|
4136
|
-
}, [isOpen
|
|
4294
|
+
}, [isOpen]);
|
|
4137
4295
|
React38.useEffect(() => {
|
|
4138
4296
|
if (!isOpen) {
|
|
4139
4297
|
setHighlightedValue(void 0);
|
|
4140
4298
|
return;
|
|
4141
4299
|
}
|
|
4142
|
-
const reposition = () => {
|
|
4143
|
-
requestAnimationFrame(() => update());
|
|
4144
|
-
};
|
|
4145
4300
|
const bootstrap = () => {
|
|
4146
4301
|
requestAnimationFrame(() => {
|
|
4147
4302
|
const el = contentRef.current;
|
|
4148
4303
|
if (!el) return;
|
|
4149
4304
|
el.focus({ preventScroll: true });
|
|
4150
4305
|
const items = queryEnabledSelectOptions(el);
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4306
|
+
if (multipleRef.current) {
|
|
4307
|
+
const sv = selectedValuesRef.current;
|
|
4308
|
+
const firstSelected = sv.find((v) => items.some((i) => i.dataset.value === v));
|
|
4309
|
+
setHighlightedValue(firstSelected ?? void 0);
|
|
4310
|
+
} else {
|
|
4311
|
+
const sv = selectedValueRef.current;
|
|
4312
|
+
const selectedIndex = items.findIndex((i) => i.dataset.value === sv);
|
|
4313
|
+
if (selectedIndex >= 0 && sv) {
|
|
4314
|
+
setHighlightedValue(sv);
|
|
4315
|
+
}
|
|
4154
4316
|
}
|
|
4155
4317
|
});
|
|
4156
4318
|
};
|
|
4157
4319
|
bootstrap();
|
|
4158
|
-
|
|
4320
|
+
}, [isOpen, setHighlightedValue]);
|
|
4321
|
+
React38.useEffect(() => {
|
|
4322
|
+
if (!isOpen) return;
|
|
4323
|
+
let rafCoalesce = 0;
|
|
4324
|
+
const schedule = () => {
|
|
4325
|
+
cancelAnimationFrame(rafCoalesce);
|
|
4326
|
+
rafCoalesce = requestAnimationFrame(() => updateRef.current());
|
|
4327
|
+
};
|
|
4328
|
+
window.addEventListener("resize", schedule);
|
|
4329
|
+
const scrollTargets = getScrollContainers(triggerRef.current);
|
|
4330
|
+
for (const t of scrollTargets) {
|
|
4331
|
+
t.addEventListener("scroll", schedule, { passive: true });
|
|
4332
|
+
}
|
|
4159
4333
|
const vv = window.visualViewport;
|
|
4160
|
-
vv?.addEventListener("resize",
|
|
4334
|
+
vv?.addEventListener("resize", schedule);
|
|
4335
|
+
const panel = contentRef.current;
|
|
4336
|
+
let ro = null;
|
|
4337
|
+
if (typeof ResizeObserver !== "undefined" && panel) {
|
|
4338
|
+
ro = new ResizeObserver(schedule);
|
|
4339
|
+
ro.observe(panel);
|
|
4340
|
+
}
|
|
4161
4341
|
return () => {
|
|
4162
|
-
|
|
4163
|
-
|
|
4342
|
+
cancelAnimationFrame(rafCoalesce);
|
|
4343
|
+
window.removeEventListener("resize", schedule);
|
|
4344
|
+
for (const t of scrollTargets) {
|
|
4345
|
+
t.removeEventListener("scroll", schedule);
|
|
4346
|
+
}
|
|
4347
|
+
vv?.removeEventListener("resize", schedule);
|
|
4348
|
+
ro?.disconnect();
|
|
4164
4349
|
};
|
|
4165
|
-
}, [isOpen,
|
|
4350
|
+
}, [isOpen, triggerRef]);
|
|
4166
4351
|
useEscapeKey({ enabled: isOpen, onEscape: onClose });
|
|
4167
4352
|
useOutsideClick({ refs: [triggerRef, contentRef], enabled: isOpen, onOutsideClick: onClose });
|
|
4168
|
-
const handleKeyDown = (
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4353
|
+
const handleKeyDown = React38.useCallback(
|
|
4354
|
+
(e) => {
|
|
4355
|
+
handleSelectListboxKeyDown(e, {
|
|
4356
|
+
items: getItems(),
|
|
4357
|
+
highlightedValue,
|
|
4358
|
+
setHighlightedValue,
|
|
4359
|
+
onSelect,
|
|
4360
|
+
onClose
|
|
4361
|
+
});
|
|
4362
|
+
},
|
|
4363
|
+
[getItems, highlightedValue, setHighlightedValue, onSelect, onClose]
|
|
4364
|
+
);
|
|
4177
4365
|
return /* @__PURE__ */ jsx26(Portal, { children: /* @__PURE__ */ jsx26(
|
|
4178
4366
|
ScrollContainer,
|
|
4179
4367
|
{
|
|
4180
4368
|
ref: contentRef,
|
|
4181
4369
|
id: listboxId,
|
|
4182
4370
|
role: "listbox",
|
|
4371
|
+
"aria-multiselectable": multiple ? true : void 0,
|
|
4183
4372
|
"aria-labelledby": triggerId,
|
|
4184
4373
|
"aria-hidden": !isOpen,
|
|
4185
4374
|
tabIndex: -1,
|
|
@@ -4198,6 +4387,17 @@ function SelectItemIcon({ className, children, ...rest }) {
|
|
|
4198
4387
|
return /* @__PURE__ */ jsx26("span", { className: cx(Select_default.itemIcon, className), ...rest, children });
|
|
4199
4388
|
}
|
|
4200
4389
|
SelectItemIcon.displayName = "SelectItemIcon";
|
|
4390
|
+
var SELECT_ITEM_ICON_MARKER = "__primeSelectItemIcon";
|
|
4391
|
+
Object.assign(SelectItemIcon, { [SELECT_ITEM_ICON_MARKER]: true });
|
|
4392
|
+
function isSelectItemIconType(type) {
|
|
4393
|
+
if (type === SelectItemIcon) return true;
|
|
4394
|
+
if (typeof type === "function") {
|
|
4395
|
+
const fn = type;
|
|
4396
|
+
if (fn[SELECT_ITEM_ICON_MARKER] === true) return true;
|
|
4397
|
+
if (fn.displayName === "SelectItemIcon") return true;
|
|
4398
|
+
}
|
|
4399
|
+
return false;
|
|
4400
|
+
}
|
|
4201
4401
|
function selectItemTextFromRest(rest) {
|
|
4202
4402
|
const parts = [];
|
|
4203
4403
|
for (const node of rest) {
|
|
@@ -4212,7 +4412,7 @@ function partitionSelectItemChildren(children) {
|
|
|
4212
4412
|
const icons = [];
|
|
4213
4413
|
const rest = [];
|
|
4214
4414
|
React38.Children.forEach(children, (child) => {
|
|
4215
|
-
if (React38.isValidElement(child) && child.type
|
|
4415
|
+
if (React38.isValidElement(child) && isSelectItemIconType(child.type)) {
|
|
4216
4416
|
icons.push(child);
|
|
4217
4417
|
} else if (child != null && child !== false) {
|
|
4218
4418
|
rest.push(child);
|
|
@@ -4222,9 +4422,18 @@ function partitionSelectItemChildren(children) {
|
|
|
4222
4422
|
}
|
|
4223
4423
|
var SelectItem = React38.forwardRef(
|
|
4224
4424
|
({ value, label, disabled, className, children }, ref) => {
|
|
4225
|
-
const {
|
|
4425
|
+
const {
|
|
4426
|
+
multiple,
|
|
4427
|
+
size,
|
|
4428
|
+
selectedValue,
|
|
4429
|
+
selectedValues,
|
|
4430
|
+
highlightedValue,
|
|
4431
|
+
setHighlightedValue,
|
|
4432
|
+
onSelect,
|
|
4433
|
+
onInitLabel
|
|
4434
|
+
} = useSelectContext();
|
|
4226
4435
|
const { icons, rest } = partitionSelectItemChildren(children);
|
|
4227
|
-
const isSelected = selectedValue === value;
|
|
4436
|
+
const isSelected = multiple ? selectedValues.includes(value) : selectedValue === value;
|
|
4228
4437
|
const isHighlighted = highlightedValue === value;
|
|
4229
4438
|
const resolvedLabel = label ?? selectItemTextFromRest(rest) ?? (typeof children === "string" ? children : void 0) ?? value;
|
|
4230
4439
|
React38.useEffect(() => {
|
|
@@ -4259,7 +4468,8 @@ var SelectItem = React38.forwardRef(
|
|
|
4259
4468
|
label: resolvedLabel,
|
|
4260
4469
|
selected: isSelected,
|
|
4261
4470
|
highlighted: isHighlighted,
|
|
4262
|
-
disabled: Boolean(disabled)
|
|
4471
|
+
disabled: Boolean(disabled),
|
|
4472
|
+
size
|
|
4263
4473
|
}),
|
|
4264
4474
|
children: [
|
|
4265
4475
|
icons.map(
|
|
@@ -4280,7 +4490,8 @@ function SelectGroup({ className, ...rest }) {
|
|
|
4280
4490
|
}
|
|
4281
4491
|
SelectGroup.displayName = "SelectGroup";
|
|
4282
4492
|
function SelectGroupLabel({ className, ...rest }) {
|
|
4283
|
-
|
|
4493
|
+
const { size } = useSelectContext();
|
|
4494
|
+
return /* @__PURE__ */ jsx26("div", { className: cx(Select_default.groupLabel, className), ...rest, ...toDataAttributes({ size }) });
|
|
4284
4495
|
}
|
|
4285
4496
|
SelectGroupLabel.displayName = "SelectGroupLabel";
|
|
4286
4497
|
function SelectSeparator({ className, ...rest }) {
|
|
@@ -4416,6 +4627,49 @@ function SelectNativeRoot({
|
|
|
4416
4627
|
) });
|
|
4417
4628
|
}
|
|
4418
4629
|
SelectNativeRoot.displayName = "SelectNativeRoot";
|
|
4630
|
+
function SelectNativeMultiRoot({
|
|
4631
|
+
size = "m",
|
|
4632
|
+
value,
|
|
4633
|
+
defaultValue,
|
|
4634
|
+
onChange,
|
|
4635
|
+
disabled,
|
|
4636
|
+
hasError = false,
|
|
4637
|
+
children
|
|
4638
|
+
}) {
|
|
4639
|
+
const handleChange = React38.useCallback(
|
|
4640
|
+
(next) => {
|
|
4641
|
+
onChange?.(next);
|
|
4642
|
+
},
|
|
4643
|
+
[onChange]
|
|
4644
|
+
);
|
|
4645
|
+
const [selectedValues, setSelectedValues] = useControllableState({
|
|
4646
|
+
value,
|
|
4647
|
+
defaultValue: defaultValue ?? [],
|
|
4648
|
+
onChange: handleChange
|
|
4649
|
+
});
|
|
4650
|
+
const { nodes: optionNodes } = React38.useMemo(() => walkNativeOptions(children), [children]);
|
|
4651
|
+
const handleNativeChange = React38.useCallback(
|
|
4652
|
+
(e) => {
|
|
4653
|
+
const next = Array.from(e.target.selectedOptions, (o) => o.value);
|
|
4654
|
+
setSelectedValues(next);
|
|
4655
|
+
},
|
|
4656
|
+
[setSelectedValues]
|
|
4657
|
+
);
|
|
4658
|
+
return /* @__PURE__ */ jsx26(ControlSizeProvider, { value: size, children: /* @__PURE__ */ jsx26(
|
|
4659
|
+
"select",
|
|
4660
|
+
{
|
|
4661
|
+
className: Select_default.nativeSelect,
|
|
4662
|
+
"data-multiple": "true",
|
|
4663
|
+
disabled,
|
|
4664
|
+
multiple: true,
|
|
4665
|
+
value: selectedValues,
|
|
4666
|
+
onChange: handleNativeChange,
|
|
4667
|
+
...toDataAttributes({ size, "has-error": hasError }),
|
|
4668
|
+
children: optionNodes
|
|
4669
|
+
}
|
|
4670
|
+
) });
|
|
4671
|
+
}
|
|
4672
|
+
SelectNativeMultiRoot.displayName = "SelectNativeMultiRoot";
|
|
4419
4673
|
var Select = {
|
|
4420
4674
|
Root: SelectRoot,
|
|
4421
4675
|
Trigger: SelectTrigger,
|
|
@@ -7068,21 +7322,6 @@ function handleMenuNavigationKeyDown(e, container) {
|
|
|
7068
7322
|
// src/components/dropdown/useDropdownPosition.ts
|
|
7069
7323
|
import * as React48 from "react";
|
|
7070
7324
|
|
|
7071
|
-
// src/internal/scrollAncestors.ts
|
|
7072
|
-
var SCROLLABLE = /^(auto|scroll|overlay)$/;
|
|
7073
|
-
function getScrollContainers(node) {
|
|
7074
|
-
const out = [window];
|
|
7075
|
-
if (!node || typeof window === "undefined") return out;
|
|
7076
|
-
for (let el = node.parentElement; el; el = el.parentElement) {
|
|
7077
|
-
const { overflowX, overflowY } = window.getComputedStyle(el);
|
|
7078
|
-
if (SCROLLABLE.test(overflowY) || SCROLLABLE.test(overflowX)) {
|
|
7079
|
-
out.push(el);
|
|
7080
|
-
}
|
|
7081
|
-
}
|
|
7082
|
-
if (window.visualViewport) out.push(window.visualViewport);
|
|
7083
|
-
return out;
|
|
7084
|
-
}
|
|
7085
|
-
|
|
7086
7325
|
// src/components/dropdown/dropdownGeometry.ts
|
|
7087
7326
|
var DROPDOWN_MIN_MAX_HEIGHT = 120;
|
|
7088
7327
|
function getDropdownMaxHeightForAnchorSide(anchor, side, viewportHeight, panelOffsetPx, viewportPadPx) {
|
|
@@ -8891,6 +9130,7 @@ function PopoverContent({
|
|
|
8891
9130
|
trapFocus = false,
|
|
8892
9131
|
insetPadding = "none",
|
|
8893
9132
|
insetGap = "pad",
|
|
9133
|
+
stackAboveDropdown = false,
|
|
8894
9134
|
children,
|
|
8895
9135
|
className
|
|
8896
9136
|
}) {
|
|
@@ -8928,6 +9168,7 @@ function PopoverContent({
|
|
|
8928
9168
|
"aria-labelledby": triggerId,
|
|
8929
9169
|
"data-react-aria-top-layer": "true",
|
|
8930
9170
|
"data-overlay-portal-layer": overlayPortalLayer,
|
|
9171
|
+
"data-overlay-stack": stackAboveDropdown ? "above-dropdown" : void 0,
|
|
8931
9172
|
"data-side": layout?.resolvedSide ?? side,
|
|
8932
9173
|
"data-size": size,
|
|
8933
9174
|
"data-inset-padding": insetPadding,
|
|
@@ -10146,9 +10387,773 @@ function TagIcon({ children, className }) {
|
|
|
10146
10387
|
TagIcon.displayName = "TagIcon";
|
|
10147
10388
|
var Tag = { Root: TagRoot, Icon: TagIcon };
|
|
10148
10389
|
|
|
10149
|
-
// src/components/
|
|
10390
|
+
// src/components/tag-select/TagSelect.tsx
|
|
10150
10391
|
import * as React71 from "react";
|
|
10151
10392
|
|
|
10393
|
+
// src/components/tag-select/TagSelect.module.css
|
|
10394
|
+
var TagSelect_default = {
|
|
10395
|
+
control: "TagSelect_control2",
|
|
10396
|
+
chips: "TagSelect_chips2",
|
|
10397
|
+
chip: "TagSelect_chip2",
|
|
10398
|
+
chipBadge: "TagSelect_chipBadge2",
|
|
10399
|
+
chipLabel: "TagSelect_chipLabel2",
|
|
10400
|
+
chipRemove: "TagSelect_chipRemove2",
|
|
10401
|
+
removeIcon: "TagSelect_removeIcon2",
|
|
10402
|
+
input: "TagSelect_input2",
|
|
10403
|
+
inputCollapsed: "TagSelect_inputCollapsed2",
|
|
10404
|
+
chevronSlot: "TagSelect_chevronSlot2",
|
|
10405
|
+
chevron: "TagSelect_chevron2",
|
|
10406
|
+
panelInner: "TagSelect_panelInner2",
|
|
10407
|
+
hint: "TagSelect_hint2",
|
|
10408
|
+
optionRow: "TagSelect_optionRow2",
|
|
10409
|
+
createRow: "TagSelect_createRow2",
|
|
10410
|
+
createLabel: "TagSelect_createLabel2",
|
|
10411
|
+
optionRowWrap: "TagSelect_optionRowWrap2",
|
|
10412
|
+
optionRowSelect: "TagSelect_optionRowSelect2",
|
|
10413
|
+
optionMenuTrigger: "TagSelect_optionMenuTrigger2",
|
|
10414
|
+
optionMenuDots: "TagSelect_optionMenuDots2",
|
|
10415
|
+
managePopoverSurface: "TagSelect_managePopoverSurface2",
|
|
10416
|
+
managePopoverShell: "TagSelect_managePopoverShell2",
|
|
10417
|
+
manageDelete: "TagSelect_manageDelete2",
|
|
10418
|
+
manageDeleteIcon: "TagSelect_manageDeleteIcon2",
|
|
10419
|
+
manageSeparator: "TagSelect_manageSeparator2",
|
|
10420
|
+
manageColorsHeading: "TagSelect_manageColorsHeading2",
|
|
10421
|
+
manageColorList: "TagSelect_manageColorList2",
|
|
10422
|
+
manageColorRow: "TagSelect_manageColorRow2",
|
|
10423
|
+
manageColorSwatch: "TagSelect_manageColorSwatch2",
|
|
10424
|
+
manageColorLabel: "TagSelect_manageColorLabel2",
|
|
10425
|
+
manageCheck: "TagSelect_manageCheck2",
|
|
10426
|
+
manageCheckPlaceholder: "TagSelect_manageCheckPlaceholder2"
|
|
10427
|
+
};
|
|
10428
|
+
|
|
10429
|
+
// src/components/tag-select/TagSelect.tsx
|
|
10430
|
+
import { Fragment as Fragment6, jsx as jsx57, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
10431
|
+
var CREATE_VALUE = "__prime_tag_select_create__";
|
|
10432
|
+
var TAG_COLOR_CHOICES = [
|
|
10433
|
+
{ color: "gray", label: "Default" },
|
|
10434
|
+
{ color: "red", label: "Red" },
|
|
10435
|
+
{ color: "orange", label: "Orange" },
|
|
10436
|
+
{ color: "yellow", label: "Yellow" },
|
|
10437
|
+
{ color: "green", label: "Green" },
|
|
10438
|
+
{ color: "blue", label: "Blue" },
|
|
10439
|
+
{ color: "purple", label: "Purple" },
|
|
10440
|
+
{ color: "pink", label: "Pink" },
|
|
10441
|
+
{ color: "sky", label: "Sky" },
|
|
10442
|
+
{ color: "teal", label: "Teal" }
|
|
10443
|
+
];
|
|
10444
|
+
function normalizeList(selected, options, defaultTagColor) {
|
|
10445
|
+
return selected.map((v) => {
|
|
10446
|
+
const o = options.find((x) => x.value === v);
|
|
10447
|
+
return {
|
|
10448
|
+
value: v,
|
|
10449
|
+
label: o?.label ?? v,
|
|
10450
|
+
color: o?.color ?? defaultTagColor
|
|
10451
|
+
};
|
|
10452
|
+
});
|
|
10453
|
+
}
|
|
10454
|
+
function filterOptions(options, query) {
|
|
10455
|
+
const q = query.trim().toLowerCase();
|
|
10456
|
+
if (q.length === 0) return options;
|
|
10457
|
+
return options.filter((o) => {
|
|
10458
|
+
if (o.disabled) return false;
|
|
10459
|
+
return o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q);
|
|
10460
|
+
});
|
|
10461
|
+
}
|
|
10462
|
+
function optionsForList(options, query, selected) {
|
|
10463
|
+
return filterOptions(options, query).filter((o) => !selected.includes(o.value));
|
|
10464
|
+
}
|
|
10465
|
+
function shouldShowCreate(creatable, inputTrim, selected, options) {
|
|
10466
|
+
if (!creatable || inputTrim.length === 0) return false;
|
|
10467
|
+
if (selected.includes(inputTrim)) return false;
|
|
10468
|
+
const lower = inputTrim.toLowerCase();
|
|
10469
|
+
const exists = options.some(
|
|
10470
|
+
(o) => o.value === inputTrim || o.label.toLowerCase() === lower || o.value.toLowerCase() === lower
|
|
10471
|
+
);
|
|
10472
|
+
return !exists;
|
|
10473
|
+
}
|
|
10474
|
+
function mergeOptionsWithCreated(options, created) {
|
|
10475
|
+
const existing = new Set(options.map((o) => o.value));
|
|
10476
|
+
const extra = created.filter((c) => !existing.has(c.value));
|
|
10477
|
+
return extra.length === 0 ? options : [...options, ...extra];
|
|
10478
|
+
}
|
|
10479
|
+
function TagOptionManagePopover({
|
|
10480
|
+
option,
|
|
10481
|
+
open,
|
|
10482
|
+
onOpenChange,
|
|
10483
|
+
defaultTagColor,
|
|
10484
|
+
management,
|
|
10485
|
+
disabled
|
|
10486
|
+
}) {
|
|
10487
|
+
const inputRef = React71.useRef(null);
|
|
10488
|
+
const resolvedColor = option.color ?? defaultTagColor;
|
|
10489
|
+
const [draftLabel, setDraftLabel] = React71.useState(option.label);
|
|
10490
|
+
React71.useEffect(() => {
|
|
10491
|
+
if (open) {
|
|
10492
|
+
setDraftLabel(option.label);
|
|
10493
|
+
}
|
|
10494
|
+
}, [open, option.label]);
|
|
10495
|
+
React71.useEffect(() => {
|
|
10496
|
+
if (!open) return;
|
|
10497
|
+
const id = requestAnimationFrame(() => inputRef.current?.focus());
|
|
10498
|
+
return () => cancelAnimationFrame(id);
|
|
10499
|
+
}, [open]);
|
|
10500
|
+
const commitLabel = () => {
|
|
10501
|
+
const next = draftLabel.trim();
|
|
10502
|
+
if (next.length > 0 && next !== option.label) {
|
|
10503
|
+
management.onUpdate(option.value, { label: next });
|
|
10504
|
+
}
|
|
10505
|
+
if (next.length === 0) {
|
|
10506
|
+
setDraftLabel(option.label);
|
|
10507
|
+
}
|
|
10508
|
+
};
|
|
10509
|
+
const colorsSectionLabel = management.colorsSectionLabel ?? "Colors";
|
|
10510
|
+
const deleteLabel = management.deleteLabel ?? "Delete";
|
|
10511
|
+
const menuPrefix = management.editMenuAriaLabelPrefix ?? "Edit tag";
|
|
10512
|
+
return /* @__PURE__ */ jsxs31(Popover.Root, { open, onOpenChange, children: [
|
|
10513
|
+
/* @__PURE__ */ jsx57(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsx57(
|
|
10514
|
+
"button",
|
|
10515
|
+
{
|
|
10516
|
+
type: "button",
|
|
10517
|
+
className: TagSelect_default.optionMenuTrigger,
|
|
10518
|
+
"aria-label": `${menuPrefix} ${option.label}`,
|
|
10519
|
+
disabled,
|
|
10520
|
+
onMouseDown: (e) => {
|
|
10521
|
+
e.preventDefault();
|
|
10522
|
+
e.stopPropagation();
|
|
10523
|
+
},
|
|
10524
|
+
onClick: (e) => {
|
|
10525
|
+
e.stopPropagation();
|
|
10526
|
+
},
|
|
10527
|
+
children: /* @__PURE__ */ jsxs31(
|
|
10528
|
+
"svg",
|
|
10529
|
+
{
|
|
10530
|
+
className: TagSelect_default.optionMenuDots,
|
|
10531
|
+
viewBox: "0 0 16 16",
|
|
10532
|
+
fill: "currentColor",
|
|
10533
|
+
"aria-hidden": true,
|
|
10534
|
+
children: [
|
|
10535
|
+
/* @__PURE__ */ jsx57("circle", { cx: "4", cy: "8", r: "1.5" }),
|
|
10536
|
+
/* @__PURE__ */ jsx57("circle", { cx: "8", cy: "8", r: "1.5" }),
|
|
10537
|
+
/* @__PURE__ */ jsx57("circle", { cx: "12", cy: "8", r: "1.5" })
|
|
10538
|
+
]
|
|
10539
|
+
}
|
|
10540
|
+
)
|
|
10541
|
+
}
|
|
10542
|
+
) }),
|
|
10543
|
+
/* @__PURE__ */ jsx57(
|
|
10544
|
+
Popover.Content,
|
|
10545
|
+
{
|
|
10546
|
+
side: "bottom",
|
|
10547
|
+
align: "end",
|
|
10548
|
+
trapFocus: false,
|
|
10549
|
+
insetPadding: "none",
|
|
10550
|
+
insetGap: "none",
|
|
10551
|
+
size: "s",
|
|
10552
|
+
stackAboveDropdown: true,
|
|
10553
|
+
className: TagSelect_default.managePopoverSurface,
|
|
10554
|
+
children: /* @__PURE__ */ jsxs31(
|
|
10555
|
+
"fieldset",
|
|
10556
|
+
{
|
|
10557
|
+
className: TagSelect_default.managePopoverShell,
|
|
10558
|
+
onKeyDown: (e) => {
|
|
10559
|
+
e.stopPropagation();
|
|
10560
|
+
},
|
|
10561
|
+
children: [
|
|
10562
|
+
/* @__PURE__ */ jsx57(Input.Root, { size: "s", children: /* @__PURE__ */ jsx57(Input.Wrapper, { children: /* @__PURE__ */ jsx57(
|
|
10563
|
+
Input.Field,
|
|
10564
|
+
{
|
|
10565
|
+
ref: inputRef,
|
|
10566
|
+
value: draftLabel,
|
|
10567
|
+
onChange: (e) => setDraftLabel(e.target.value),
|
|
10568
|
+
onBlur: commitLabel,
|
|
10569
|
+
onKeyDown: (e) => {
|
|
10570
|
+
if (e.key === "Enter") {
|
|
10571
|
+
e.preventDefault();
|
|
10572
|
+
commitLabel();
|
|
10573
|
+
onOpenChange(false);
|
|
10574
|
+
}
|
|
10575
|
+
},
|
|
10576
|
+
"aria-label": "Tag name"
|
|
10577
|
+
}
|
|
10578
|
+
) }) }),
|
|
10579
|
+
/* @__PURE__ */ jsxs31(
|
|
10580
|
+
Button.Root,
|
|
10581
|
+
{
|
|
10582
|
+
type: "button",
|
|
10583
|
+
variant: "error",
|
|
10584
|
+
mode: "ghost",
|
|
10585
|
+
size: "s",
|
|
10586
|
+
className: TagSelect_default.manageDelete,
|
|
10587
|
+
onClick: () => {
|
|
10588
|
+
management.onDelete(option.value);
|
|
10589
|
+
onOpenChange(false);
|
|
10590
|
+
},
|
|
10591
|
+
children: [
|
|
10592
|
+
/* @__PURE__ */ jsx57("svg", { className: TagSelect_default.manageDeleteIcon, viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx57(
|
|
10593
|
+
"path",
|
|
10594
|
+
{
|
|
10595
|
+
d: "M4 4h8M6 4V3h4v1m2 0v9a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4h10zM6 7v4M10 7v4",
|
|
10596
|
+
stroke: "currentColor",
|
|
10597
|
+
strokeWidth: "1.25",
|
|
10598
|
+
strokeLinecap: "round",
|
|
10599
|
+
strokeLinejoin: "round"
|
|
10600
|
+
}
|
|
10601
|
+
) }),
|
|
10602
|
+
deleteLabel
|
|
10603
|
+
]
|
|
10604
|
+
}
|
|
10605
|
+
),
|
|
10606
|
+
/* @__PURE__ */ jsx57("hr", { className: TagSelect_default.manageSeparator }),
|
|
10607
|
+
/* @__PURE__ */ jsx57("span", { className: TagSelect_default.manageColorsHeading, children: colorsSectionLabel }),
|
|
10608
|
+
/* @__PURE__ */ jsx57("div", { className: TagSelect_default.manageColorList, children: TAG_COLOR_CHOICES.map((row) => {
|
|
10609
|
+
const selected = resolvedColor === row.color;
|
|
10610
|
+
return /* @__PURE__ */ jsxs31(
|
|
10611
|
+
"button",
|
|
10612
|
+
{
|
|
10613
|
+
type: "button",
|
|
10614
|
+
className: TagSelect_default.manageColorRow,
|
|
10615
|
+
onClick: () => {
|
|
10616
|
+
management.onUpdate(option.value, { color: row.color });
|
|
10617
|
+
},
|
|
10618
|
+
children: [
|
|
10619
|
+
/* @__PURE__ */ jsx57(
|
|
10620
|
+
"span",
|
|
10621
|
+
{
|
|
10622
|
+
className: TagSelect_default.manageColorSwatch,
|
|
10623
|
+
"aria-hidden": true,
|
|
10624
|
+
...toDataAttributes({ color: row.color })
|
|
10625
|
+
}
|
|
10626
|
+
),
|
|
10627
|
+
/* @__PURE__ */ jsx57("span", { className: TagSelect_default.manageColorLabel, children: row.label }),
|
|
10628
|
+
selected ? /* @__PURE__ */ jsx57(Fragment6, { children: /* @__PURE__ */ jsx57("svg", { className: TagSelect_default.manageCheck, viewBox: "0 0 16 16", "aria-hidden": true, children: /* @__PURE__ */ jsx57(
|
|
10629
|
+
"path",
|
|
10630
|
+
{
|
|
10631
|
+
d: "M3 8l3 3 7-7",
|
|
10632
|
+
stroke: "currentColor",
|
|
10633
|
+
strokeWidth: "1.75",
|
|
10634
|
+
fill: "none",
|
|
10635
|
+
strokeLinecap: "round",
|
|
10636
|
+
strokeLinejoin: "round"
|
|
10637
|
+
}
|
|
10638
|
+
) }) }) : /* @__PURE__ */ jsx57("span", { className: TagSelect_default.manageCheckPlaceholder, "aria-hidden": true })
|
|
10639
|
+
]
|
|
10640
|
+
},
|
|
10641
|
+
`${row.label}-${row.color}`
|
|
10642
|
+
);
|
|
10643
|
+
}) })
|
|
10644
|
+
]
|
|
10645
|
+
}
|
|
10646
|
+
)
|
|
10647
|
+
}
|
|
10648
|
+
)
|
|
10649
|
+
] });
|
|
10650
|
+
}
|
|
10651
|
+
function TagSelectRoot({
|
|
10652
|
+
options,
|
|
10653
|
+
value: valueProp,
|
|
10654
|
+
defaultValue = [],
|
|
10655
|
+
onValueChange,
|
|
10656
|
+
creatable = false,
|
|
10657
|
+
onCreated,
|
|
10658
|
+
defaultTagColor = "gray",
|
|
10659
|
+
hint = "Select an option or create one",
|
|
10660
|
+
createActionLabel = "Create",
|
|
10661
|
+
disabled = false,
|
|
10662
|
+
placeholder = "",
|
|
10663
|
+
hasError = false,
|
|
10664
|
+
size = "m",
|
|
10665
|
+
optionManagement,
|
|
10666
|
+
id: idProp,
|
|
10667
|
+
className,
|
|
10668
|
+
"aria-label": ariaLabel,
|
|
10669
|
+
"aria-labelledby": ariaLabelledBy
|
|
10670
|
+
}) {
|
|
10671
|
+
const generatedId = React71.useId();
|
|
10672
|
+
const rootId = idProp ?? generatedId;
|
|
10673
|
+
const listboxId = `${rootId}-listbox`;
|
|
10674
|
+
const inputId = `${rootId}-input`;
|
|
10675
|
+
const [selected, setSelected] = useControllableState({
|
|
10676
|
+
value: valueProp,
|
|
10677
|
+
defaultValue,
|
|
10678
|
+
onChange: onValueChange
|
|
10679
|
+
});
|
|
10680
|
+
const [inputValue, setInputValue] = React71.useState("");
|
|
10681
|
+
const [inputFocused, setInputFocused] = React71.useState(false);
|
|
10682
|
+
const [open, setOpen] = React71.useState(false);
|
|
10683
|
+
const [highlightedValue, setHighlightedValue] = React71.useState(void 0);
|
|
10684
|
+
const [manageOpenValue, setManageOpenValue] = React71.useState(null);
|
|
10685
|
+
const [createdOptions, setCreatedOptions] = React71.useState([]);
|
|
10686
|
+
const triggerRef = React71.useRef(null);
|
|
10687
|
+
const inputRef = React71.useRef(null);
|
|
10688
|
+
const listboxRef = React71.useRef(null);
|
|
10689
|
+
const overlayPortalLayer = useOverlayPortalLayer();
|
|
10690
|
+
const { resolvedSide, update } = usePosition(triggerRef, listboxRef, {
|
|
10691
|
+
side: "bottom",
|
|
10692
|
+
align: "start"
|
|
10693
|
+
});
|
|
10694
|
+
const updateRef = React71.useRef(update);
|
|
10695
|
+
updateRef.current = update;
|
|
10696
|
+
const inputTrim = inputValue.trim();
|
|
10697
|
+
const mergedOptions = React71.useMemo(
|
|
10698
|
+
() => mergeOptionsWithCreated(options, createdOptions),
|
|
10699
|
+
[options, createdOptions]
|
|
10700
|
+
);
|
|
10701
|
+
React71.useEffect(() => {
|
|
10702
|
+
setCreatedOptions((prev) => {
|
|
10703
|
+
const next = prev.filter((c) => !options.some((o) => o.value === c.value));
|
|
10704
|
+
return next.length === prev.length ? prev : next;
|
|
10705
|
+
});
|
|
10706
|
+
}, [options]);
|
|
10707
|
+
const filtered = React71.useMemo(
|
|
10708
|
+
() => optionsForList(mergedOptions, inputValue, selected),
|
|
10709
|
+
[mergedOptions, inputValue, selected]
|
|
10710
|
+
);
|
|
10711
|
+
const showCreate = shouldShowCreate(creatable, inputTrim, selected, mergedOptions);
|
|
10712
|
+
const resolvedOptionManagement = React71.useMemo(() => {
|
|
10713
|
+
if (!optionManagement) return void 0;
|
|
10714
|
+
return {
|
|
10715
|
+
...optionManagement,
|
|
10716
|
+
onUpdate: (value, updates) => {
|
|
10717
|
+
const inProps = options.some((o) => o.value === value);
|
|
10718
|
+
if (!inProps) {
|
|
10719
|
+
setCreatedOptions(
|
|
10720
|
+
(prev) => prev.map(
|
|
10721
|
+
(o) => o.value === value ? {
|
|
10722
|
+
...o,
|
|
10723
|
+
...updates.label !== void 0 ? { label: updates.label } : {},
|
|
10724
|
+
...updates.color !== void 0 ? { color: updates.color } : {}
|
|
10725
|
+
} : o
|
|
10726
|
+
)
|
|
10727
|
+
);
|
|
10728
|
+
}
|
|
10729
|
+
optionManagement.onUpdate(value, updates);
|
|
10730
|
+
},
|
|
10731
|
+
onDelete: (value) => {
|
|
10732
|
+
setSelected((prev) => prev.filter((x) => x !== value));
|
|
10733
|
+
setCreatedOptions((prev) => prev.filter((o) => o.value !== value));
|
|
10734
|
+
optionManagement.onDelete(value);
|
|
10735
|
+
}
|
|
10736
|
+
};
|
|
10737
|
+
}, [optionManagement, options, setSelected]);
|
|
10738
|
+
const hasPanelContent = filtered.length > 0 || showCreate;
|
|
10739
|
+
const flatOptionValues = React71.useMemo(() => {
|
|
10740
|
+
const v = [];
|
|
10741
|
+
if (showCreate) v.push(CREATE_VALUE);
|
|
10742
|
+
for (const o of filtered) {
|
|
10743
|
+
if (!o.disabled) v.push(o.value);
|
|
10744
|
+
}
|
|
10745
|
+
return v;
|
|
10746
|
+
}, [filtered, showCreate]);
|
|
10747
|
+
React71.useLayoutEffect(() => {
|
|
10748
|
+
if (!open) return;
|
|
10749
|
+
updateRef.current();
|
|
10750
|
+
const raf = requestAnimationFrame(() => updateRef.current());
|
|
10751
|
+
return () => cancelAnimationFrame(raf);
|
|
10752
|
+
}, [open]);
|
|
10753
|
+
React71.useEffect(() => {
|
|
10754
|
+
if (!open) return;
|
|
10755
|
+
let rafCoalesce = 0;
|
|
10756
|
+
const schedule = () => {
|
|
10757
|
+
cancelAnimationFrame(rafCoalesce);
|
|
10758
|
+
rafCoalesce = requestAnimationFrame(() => updateRef.current());
|
|
10759
|
+
};
|
|
10760
|
+
window.addEventListener("resize", schedule);
|
|
10761
|
+
const scrollTargets = getScrollContainers(triggerRef.current);
|
|
10762
|
+
for (const t of scrollTargets) {
|
|
10763
|
+
t.addEventListener("scroll", schedule, { passive: true });
|
|
10764
|
+
}
|
|
10765
|
+
const vv = window.visualViewport;
|
|
10766
|
+
vv?.addEventListener("resize", schedule);
|
|
10767
|
+
const panel = listboxRef.current;
|
|
10768
|
+
let ro = null;
|
|
10769
|
+
if (typeof ResizeObserver !== "undefined" && panel) {
|
|
10770
|
+
ro = new ResizeObserver(schedule);
|
|
10771
|
+
ro.observe(panel);
|
|
10772
|
+
}
|
|
10773
|
+
return () => {
|
|
10774
|
+
cancelAnimationFrame(rafCoalesce);
|
|
10775
|
+
window.removeEventListener("resize", schedule);
|
|
10776
|
+
for (const t of scrollTargets) {
|
|
10777
|
+
t.removeEventListener("scroll", schedule);
|
|
10778
|
+
}
|
|
10779
|
+
vv?.removeEventListener("resize", schedule);
|
|
10780
|
+
ro?.disconnect();
|
|
10781
|
+
};
|
|
10782
|
+
}, [open]);
|
|
10783
|
+
React71.useEffect(() => {
|
|
10784
|
+
if (!open) {
|
|
10785
|
+
setHighlightedValue(void 0);
|
|
10786
|
+
return;
|
|
10787
|
+
}
|
|
10788
|
+
if (flatOptionValues.length === 0) {
|
|
10789
|
+
setHighlightedValue(void 0);
|
|
10790
|
+
return;
|
|
10791
|
+
}
|
|
10792
|
+
setHighlightedValue(
|
|
10793
|
+
(prev) => prev && flatOptionValues.includes(prev) ? prev : flatOptionValues[0]
|
|
10794
|
+
);
|
|
10795
|
+
}, [open, flatOptionValues]);
|
|
10796
|
+
React71.useEffect(() => {
|
|
10797
|
+
if (!open) return;
|
|
10798
|
+
if (!hasPanelContent) setOpen(false);
|
|
10799
|
+
}, [open, hasPanelContent]);
|
|
10800
|
+
React71.useEffect(() => {
|
|
10801
|
+
if (!open) setManageOpenValue(null);
|
|
10802
|
+
}, [open]);
|
|
10803
|
+
useEscapeKey({ enabled: open && manageOpenValue === null, onEscape: () => setOpen(false) });
|
|
10804
|
+
useOutsideClick({
|
|
10805
|
+
refs: [triggerRef, listboxRef],
|
|
10806
|
+
enabled: open,
|
|
10807
|
+
onOutsideClick: () => setOpen(false),
|
|
10808
|
+
shouldSuppressOutsideClick: (target) => {
|
|
10809
|
+
if (!(target instanceof Element)) return false;
|
|
10810
|
+
const dialog = target.closest('[role="dialog"][data-react-aria-top-layer="true"]');
|
|
10811
|
+
if (!dialog) return false;
|
|
10812
|
+
return dialog !== listboxRef.current;
|
|
10813
|
+
}
|
|
10814
|
+
});
|
|
10815
|
+
const toggleValue = React71.useCallback(
|
|
10816
|
+
(value) => {
|
|
10817
|
+
setSelected((prev) => {
|
|
10818
|
+
if (prev.includes(value)) {
|
|
10819
|
+
return prev.filter((x) => x !== value);
|
|
10820
|
+
}
|
|
10821
|
+
return [...prev, value];
|
|
10822
|
+
});
|
|
10823
|
+
},
|
|
10824
|
+
[setSelected]
|
|
10825
|
+
);
|
|
10826
|
+
const handleSelectFromList = React71.useCallback(
|
|
10827
|
+
(rawValue) => {
|
|
10828
|
+
if (rawValue === CREATE_VALUE) {
|
|
10829
|
+
const v = inputTrim;
|
|
10830
|
+
if (v.length === 0) return;
|
|
10831
|
+
setSelected((prev) => {
|
|
10832
|
+
if (prev.includes(v)) return prev;
|
|
10833
|
+
onCreated?.(v);
|
|
10834
|
+
return [...prev, v];
|
|
10835
|
+
});
|
|
10836
|
+
setCreatedOptions((prev) => {
|
|
10837
|
+
if (prev.some((o) => o.value === v) || options.some((o) => o.value === v)) {
|
|
10838
|
+
return prev;
|
|
10839
|
+
}
|
|
10840
|
+
return [...prev, { value: v, label: v, color: defaultTagColor }];
|
|
10841
|
+
});
|
|
10842
|
+
setInputValue("");
|
|
10843
|
+
return;
|
|
10844
|
+
}
|
|
10845
|
+
toggleValue(rawValue);
|
|
10846
|
+
setInputValue("");
|
|
10847
|
+
},
|
|
10848
|
+
[defaultTagColor, inputTrim, onCreated, options, setSelected, toggleValue]
|
|
10849
|
+
);
|
|
10850
|
+
const getItems = React71.useCallback(() => queryEnabledSelectOptions(listboxRef.current), []);
|
|
10851
|
+
const onListboxKeyDown = (e) => {
|
|
10852
|
+
handleSelectListboxKeyDown(e, {
|
|
10853
|
+
items: getItems(),
|
|
10854
|
+
highlightedValue,
|
|
10855
|
+
setHighlightedValue,
|
|
10856
|
+
onSelect: (v) => {
|
|
10857
|
+
handleSelectFromList(v);
|
|
10858
|
+
},
|
|
10859
|
+
onClose: () => setOpen(false)
|
|
10860
|
+
});
|
|
10861
|
+
};
|
|
10862
|
+
const onInputKeyDown = (e) => {
|
|
10863
|
+
if (disabled) return;
|
|
10864
|
+
if (e.key === "Backspace" && inputValue.length === 0 && selected.length > 0) {
|
|
10865
|
+
e.preventDefault();
|
|
10866
|
+
setSelected((prev) => prev.slice(0, -1));
|
|
10867
|
+
return;
|
|
10868
|
+
}
|
|
10869
|
+
if (e.key === "Escape") {
|
|
10870
|
+
if (open) {
|
|
10871
|
+
e.preventDefault();
|
|
10872
|
+
setOpen(false);
|
|
10873
|
+
}
|
|
10874
|
+
return;
|
|
10875
|
+
}
|
|
10876
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Enter" || e.key === " ") {
|
|
10877
|
+
if (!open) {
|
|
10878
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
10879
|
+
e.preventDefault();
|
|
10880
|
+
if (filtered.length > 0 || showCreate) setOpen(true);
|
|
10881
|
+
}
|
|
10882
|
+
return;
|
|
10883
|
+
}
|
|
10884
|
+
if (flatOptionValues.length === 0) return;
|
|
10885
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
10886
|
+
e.preventDefault();
|
|
10887
|
+
const hv = highlightedValue ?? flatOptionValues[0];
|
|
10888
|
+
if (hv === CREATE_VALUE) {
|
|
10889
|
+
handleSelectFromList(CREATE_VALUE);
|
|
10890
|
+
} else if (hv) {
|
|
10891
|
+
const o = mergedOptions.find((x) => x.value === hv);
|
|
10892
|
+
if (o && !o.disabled) {
|
|
10893
|
+
handleSelectFromList(o.value);
|
|
10894
|
+
}
|
|
10895
|
+
}
|
|
10896
|
+
return;
|
|
10897
|
+
}
|
|
10898
|
+
handleSelectListboxKeyDown(e, {
|
|
10899
|
+
items: getItems(),
|
|
10900
|
+
highlightedValue,
|
|
10901
|
+
setHighlightedValue,
|
|
10902
|
+
onSelect: (v) => handleSelectFromList(v),
|
|
10903
|
+
onClose: () => setOpen(false)
|
|
10904
|
+
});
|
|
10905
|
+
}
|
|
10906
|
+
};
|
|
10907
|
+
const chips = normalizeList(selected, mergedOptions, defaultTagColor);
|
|
10908
|
+
const isEmpty = selected.length === 0 && inputTrim.length === 0;
|
|
10909
|
+
const inputCollapsed = !inputFocused && inputTrim.length === 0 && selected.length > 0;
|
|
10910
|
+
const focusInput = () => {
|
|
10911
|
+
inputRef.current?.focus();
|
|
10912
|
+
};
|
|
10913
|
+
const handleInputBlur = React71.useCallback((e) => {
|
|
10914
|
+
const next = e.relatedTarget;
|
|
10915
|
+
if (next instanceof Node && triggerRef.current?.contains(next)) {
|
|
10916
|
+
return;
|
|
10917
|
+
}
|
|
10918
|
+
window.requestAnimationFrame(() => {
|
|
10919
|
+
if (triggerRef.current?.contains(document.activeElement)) {
|
|
10920
|
+
return;
|
|
10921
|
+
}
|
|
10922
|
+
setInputFocused(false);
|
|
10923
|
+
setInputValue("");
|
|
10924
|
+
});
|
|
10925
|
+
}, []);
|
|
10926
|
+
return /* @__PURE__ */ jsxs31(ControlSizeProvider, { value: size, children: [
|
|
10927
|
+
/* @__PURE__ */ jsxs31(
|
|
10928
|
+
"div",
|
|
10929
|
+
{
|
|
10930
|
+
ref: triggerRef,
|
|
10931
|
+
className: cx(TagSelect_default.control, className),
|
|
10932
|
+
onClick: () => {
|
|
10933
|
+
if (!disabled) {
|
|
10934
|
+
focusInput();
|
|
10935
|
+
if (hasPanelContent) setOpen(true);
|
|
10936
|
+
}
|
|
10937
|
+
},
|
|
10938
|
+
...toDataAttributes({
|
|
10939
|
+
size,
|
|
10940
|
+
open,
|
|
10941
|
+
empty: isEmpty ? true : void 0,
|
|
10942
|
+
disabled: disabled ? true : void 0,
|
|
10943
|
+
"has-error": hasError ? true : void 0
|
|
10944
|
+
}),
|
|
10945
|
+
children: [
|
|
10946
|
+
/* @__PURE__ */ jsxs31("div", { className: TagSelect_default.chips, children: [
|
|
10947
|
+
chips.map((c) => /* @__PURE__ */ jsx57("span", { className: TagSelect_default.chip, children: /* @__PURE__ */ jsxs31(Badge.Root, { color: c.color, variant: "filled", className: TagSelect_default.chipBadge, children: [
|
|
10948
|
+
/* @__PURE__ */ jsx57("span", { className: TagSelect_default.chipLabel, children: c.label }),
|
|
10949
|
+
/* @__PURE__ */ jsx57(
|
|
10950
|
+
"button",
|
|
10951
|
+
{
|
|
10952
|
+
type: "button",
|
|
10953
|
+
className: TagSelect_default.chipRemove,
|
|
10954
|
+
"aria-label": `Remove ${c.label}`,
|
|
10955
|
+
disabled,
|
|
10956
|
+
onMouseDown: (e) => {
|
|
10957
|
+
e.preventDefault();
|
|
10958
|
+
},
|
|
10959
|
+
onClick: (e) => {
|
|
10960
|
+
e.stopPropagation();
|
|
10961
|
+
setSelected((prev) => prev.filter((x) => x !== c.value));
|
|
10962
|
+
},
|
|
10963
|
+
children: /* @__PURE__ */ jsx57(
|
|
10964
|
+
"svg",
|
|
10965
|
+
{
|
|
10966
|
+
className: TagSelect_default.removeIcon,
|
|
10967
|
+
viewBox: "0 0 12 12",
|
|
10968
|
+
fill: "none",
|
|
10969
|
+
"aria-hidden": "true",
|
|
10970
|
+
children: /* @__PURE__ */ jsx57(
|
|
10971
|
+
"path",
|
|
10972
|
+
{
|
|
10973
|
+
d: "M2 2l8 8M10 2l-8 8",
|
|
10974
|
+
stroke: "currentColor",
|
|
10975
|
+
strokeWidth: "1.5",
|
|
10976
|
+
strokeLinecap: "round"
|
|
10977
|
+
}
|
|
10978
|
+
)
|
|
10979
|
+
}
|
|
10980
|
+
)
|
|
10981
|
+
}
|
|
10982
|
+
)
|
|
10983
|
+
] }) }, c.value)),
|
|
10984
|
+
/* @__PURE__ */ jsx57(
|
|
10985
|
+
"input",
|
|
10986
|
+
{
|
|
10987
|
+
ref: inputRef,
|
|
10988
|
+
id: inputId,
|
|
10989
|
+
type: "text",
|
|
10990
|
+
role: "combobox",
|
|
10991
|
+
"aria-expanded": open,
|
|
10992
|
+
"aria-controls": listboxId,
|
|
10993
|
+
"aria-autocomplete": "list",
|
|
10994
|
+
"aria-label": ariaLabel,
|
|
10995
|
+
"aria-labelledby": ariaLabelledBy,
|
|
10996
|
+
disabled,
|
|
10997
|
+
placeholder: selected.length === 0 ? placeholder : void 0,
|
|
10998
|
+
className: cx(TagSelect_default.input, inputCollapsed && TagSelect_default.inputCollapsed),
|
|
10999
|
+
value: inputValue,
|
|
11000
|
+
onChange: (e) => {
|
|
11001
|
+
const next = e.target.value;
|
|
11002
|
+
setInputValue(next);
|
|
11003
|
+
const nextTrim = next.trim();
|
|
11004
|
+
const nextMerged = mergeOptionsWithCreated(options, createdOptions);
|
|
11005
|
+
const nextFiltered = optionsForList(nextMerged, next, selected);
|
|
11006
|
+
const nextShowCreate = shouldShowCreate(creatable, nextTrim, selected, nextMerged);
|
|
11007
|
+
if (nextFiltered.length > 0 || nextShowCreate) {
|
|
11008
|
+
setOpen(true);
|
|
11009
|
+
} else {
|
|
11010
|
+
setOpen(false);
|
|
11011
|
+
}
|
|
11012
|
+
},
|
|
11013
|
+
onKeyDown: onInputKeyDown,
|
|
11014
|
+
onFocus: () => {
|
|
11015
|
+
setInputFocused(true);
|
|
11016
|
+
if (!disabled && hasPanelContent) setOpen(true);
|
|
11017
|
+
},
|
|
11018
|
+
onBlur: handleInputBlur
|
|
11019
|
+
}
|
|
11020
|
+
)
|
|
11021
|
+
] }),
|
|
11022
|
+
/* @__PURE__ */ jsx57("span", { className: TagSelect_default.chevronSlot, "aria-hidden": true, children: /* @__PURE__ */ jsx57("span", { className: TagSelect_default.chevron }) })
|
|
11023
|
+
]
|
|
11024
|
+
}
|
|
11025
|
+
),
|
|
11026
|
+
/* @__PURE__ */ jsx57(Portal, { children: /* @__PURE__ */ jsxs31(
|
|
11027
|
+
ScrollContainer,
|
|
11028
|
+
{
|
|
11029
|
+
ref: listboxRef,
|
|
11030
|
+
id: listboxId,
|
|
11031
|
+
role: "listbox",
|
|
11032
|
+
"aria-multiselectable": "true",
|
|
11033
|
+
"aria-hidden": !open,
|
|
11034
|
+
tabIndex: -1,
|
|
11035
|
+
"data-react-aria-top-layer": "true",
|
|
11036
|
+
"data-overlay-portal-layer": overlayPortalLayer,
|
|
11037
|
+
className: cx(Select_default.content, TagSelect_default.panelInner),
|
|
11038
|
+
onKeyDown: onListboxKeyDown,
|
|
11039
|
+
style: { display: open ? void 0 : "none" },
|
|
11040
|
+
...toDataAttributes({ side: resolvedSide, size }),
|
|
11041
|
+
children: [
|
|
11042
|
+
hint ? /* @__PURE__ */ jsx57("div", { className: TagSelect_default.hint, children: /* @__PURE__ */ jsx57(Typography.Root, { as: "div", variant: "body-small", tone: "muted", children: hint }) }) : null,
|
|
11043
|
+
showCreate ? /* @__PURE__ */ jsxs31(
|
|
11044
|
+
"button",
|
|
11045
|
+
{
|
|
11046
|
+
type: "button",
|
|
11047
|
+
role: "option",
|
|
11048
|
+
"aria-selected": false,
|
|
11049
|
+
className: TagSelect_default.createRow,
|
|
11050
|
+
...toDataAttributes({
|
|
11051
|
+
value: CREATE_VALUE,
|
|
11052
|
+
label: inputTrim,
|
|
11053
|
+
highlighted: highlightedValue === CREATE_VALUE,
|
|
11054
|
+
disabled: false
|
|
11055
|
+
}),
|
|
11056
|
+
onMouseDown: (e) => {
|
|
11057
|
+
e.preventDefault();
|
|
11058
|
+
},
|
|
11059
|
+
onMouseEnter: () => setHighlightedValue(CREATE_VALUE),
|
|
11060
|
+
onClick: () => handleSelectFromList(CREATE_VALUE),
|
|
11061
|
+
children: [
|
|
11062
|
+
/* @__PURE__ */ jsx57(
|
|
11063
|
+
Typography.Root,
|
|
11064
|
+
{
|
|
11065
|
+
as: "span",
|
|
11066
|
+
variant: "body-small",
|
|
11067
|
+
tone: "muted",
|
|
11068
|
+
className: TagSelect_default.createLabel,
|
|
11069
|
+
children: createActionLabel
|
|
11070
|
+
}
|
|
11071
|
+
),
|
|
11072
|
+
/* @__PURE__ */ jsx57(Badge.Root, { color: defaultTagColor, variant: "filled", children: inputTrim })
|
|
11073
|
+
]
|
|
11074
|
+
},
|
|
11075
|
+
CREATE_VALUE
|
|
11076
|
+
) : null,
|
|
11077
|
+
resolvedOptionManagement ? filtered.map((o) => /* @__PURE__ */ jsxs31(
|
|
11078
|
+
"div",
|
|
11079
|
+
{
|
|
11080
|
+
role: "option",
|
|
11081
|
+
tabIndex: -1,
|
|
11082
|
+
"aria-selected": false,
|
|
11083
|
+
className: TagSelect_default.optionRowWrap,
|
|
11084
|
+
...toDataAttributes({
|
|
11085
|
+
value: o.value,
|
|
11086
|
+
label: o.label,
|
|
11087
|
+
highlighted: highlightedValue === o.value,
|
|
11088
|
+
selected: false,
|
|
11089
|
+
disabled: Boolean(o.disabled)
|
|
11090
|
+
}),
|
|
11091
|
+
onMouseEnter: () => !o.disabled && setHighlightedValue(o.value),
|
|
11092
|
+
children: [
|
|
11093
|
+
/* @__PURE__ */ jsx57(
|
|
11094
|
+
"button",
|
|
11095
|
+
{
|
|
11096
|
+
type: "button",
|
|
11097
|
+
className: TagSelect_default.optionRowSelect,
|
|
11098
|
+
disabled: o.disabled,
|
|
11099
|
+
onMouseDown: (e) => {
|
|
11100
|
+
if (!o.disabled) e.preventDefault();
|
|
11101
|
+
},
|
|
11102
|
+
onClick: () => !o.disabled && handleSelectFromList(o.value),
|
|
11103
|
+
children: /* @__PURE__ */ jsx57(Badge.Root, { color: o.color ?? defaultTagColor, variant: "filled", children: o.label })
|
|
11104
|
+
}
|
|
11105
|
+
),
|
|
11106
|
+
!o.disabled ? /* @__PURE__ */ jsx57(
|
|
11107
|
+
TagOptionManagePopover,
|
|
11108
|
+
{
|
|
11109
|
+
option: o,
|
|
11110
|
+
open: manageOpenValue === o.value,
|
|
11111
|
+
onOpenChange: (next) => setManageOpenValue(next ? o.value : null),
|
|
11112
|
+
defaultTagColor,
|
|
11113
|
+
management: resolvedOptionManagement,
|
|
11114
|
+
disabled
|
|
11115
|
+
}
|
|
11116
|
+
) : null
|
|
11117
|
+
]
|
|
11118
|
+
},
|
|
11119
|
+
o.value
|
|
11120
|
+
)) : filtered.map((o) => /* @__PURE__ */ jsx57(
|
|
11121
|
+
"button",
|
|
11122
|
+
{
|
|
11123
|
+
type: "button",
|
|
11124
|
+
role: "option",
|
|
11125
|
+
"aria-selected": false,
|
|
11126
|
+
disabled: o.disabled,
|
|
11127
|
+
className: TagSelect_default.optionRow,
|
|
11128
|
+
...toDataAttributes({
|
|
11129
|
+
value: o.value,
|
|
11130
|
+
label: o.label,
|
|
11131
|
+
highlighted: highlightedValue === o.value,
|
|
11132
|
+
selected: false,
|
|
11133
|
+
disabled: Boolean(o.disabled)
|
|
11134
|
+
}),
|
|
11135
|
+
onMouseDown: (e) => {
|
|
11136
|
+
if (!o.disabled) e.preventDefault();
|
|
11137
|
+
},
|
|
11138
|
+
onMouseEnter: () => !o.disabled && setHighlightedValue(o.value),
|
|
11139
|
+
onClick: () => !o.disabled && handleSelectFromList(o.value),
|
|
11140
|
+
children: /* @__PURE__ */ jsx57(Badge.Root, { color: o.color ?? defaultTagColor, variant: "filled", children: o.label })
|
|
11141
|
+
},
|
|
11142
|
+
o.value
|
|
11143
|
+
))
|
|
11144
|
+
]
|
|
11145
|
+
}
|
|
11146
|
+
) })
|
|
11147
|
+
] });
|
|
11148
|
+
}
|
|
11149
|
+
TagSelectRoot.displayName = "TagSelectRoot";
|
|
11150
|
+
var TagSelect = {
|
|
11151
|
+
Root: TagSelectRoot
|
|
11152
|
+
};
|
|
11153
|
+
|
|
11154
|
+
// src/components/textarea/Textarea.tsx
|
|
11155
|
+
import * as React72 from "react";
|
|
11156
|
+
|
|
10152
11157
|
// src/components/textarea/Textarea.module.css
|
|
10153
11158
|
var Textarea_default = {
|
|
10154
11159
|
field: "Textarea_field2",
|
|
@@ -10164,11 +11169,11 @@ var Textarea_default = {
|
|
|
10164
11169
|
};
|
|
10165
11170
|
|
|
10166
11171
|
// src/components/textarea/Textarea.tsx
|
|
10167
|
-
import { jsx as
|
|
11172
|
+
import { jsx as jsx58, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
10168
11173
|
var [TextareaProvider, useTextareaContext] = createComponentContext("Textarea");
|
|
10169
11174
|
function TextareaCharCounter({ current, max }) {
|
|
10170
11175
|
const overflow = current > max;
|
|
10171
|
-
return /* @__PURE__ */
|
|
11176
|
+
return /* @__PURE__ */ jsxs32(
|
|
10172
11177
|
"span",
|
|
10173
11178
|
{
|
|
10174
11179
|
className: Textarea_default.charCounter,
|
|
@@ -10186,8 +11191,8 @@ TextareaCharCounter.displayName = "Textarea.CharCounter";
|
|
|
10186
11191
|
function partitionTextareaChildren(children) {
|
|
10187
11192
|
const counters = [];
|
|
10188
11193
|
const rest = [];
|
|
10189
|
-
|
|
10190
|
-
if (
|
|
11194
|
+
React72.Children.forEach(children, (child) => {
|
|
11195
|
+
if (React72.isValidElement(child) && child.type === TextareaCharCounter) {
|
|
10191
11196
|
counters.push(child);
|
|
10192
11197
|
} else if (child != null && child !== false) {
|
|
10193
11198
|
rest.push(child);
|
|
@@ -10195,7 +11200,7 @@ function partitionTextareaChildren(children) {
|
|
|
10195
11200
|
});
|
|
10196
11201
|
return { counters, rest };
|
|
10197
11202
|
}
|
|
10198
|
-
var TextareaRoot =
|
|
11203
|
+
var TextareaRoot = React72.forwardRef(
|
|
10199
11204
|
({
|
|
10200
11205
|
id,
|
|
10201
11206
|
className,
|
|
@@ -10212,12 +11217,12 @@ var TextareaRoot = React71.forwardRef(
|
|
|
10212
11217
|
children,
|
|
10213
11218
|
...rest
|
|
10214
11219
|
}, ref) => {
|
|
10215
|
-
const rawId =
|
|
11220
|
+
const rawId = React72.useId();
|
|
10216
11221
|
const inputId = id ?? rawId;
|
|
10217
11222
|
const hintId = `${inputId}-hint`;
|
|
10218
11223
|
const errorId = `${inputId}-error`;
|
|
10219
|
-
const [hasHint, setHasHint] =
|
|
10220
|
-
const [hasError, setHasError] =
|
|
11224
|
+
const [hasHint, setHasHint] = React72.useState(false);
|
|
11225
|
+
const [hasError, setHasError] = React72.useState(false);
|
|
10221
11226
|
const invalid = variant === "error" || hasError;
|
|
10222
11227
|
const resolvedAriaInvalid = ariaInvalid ?? (invalid || void 0);
|
|
10223
11228
|
const parts = [
|
|
@@ -10226,25 +11231,25 @@ var TextareaRoot = React71.forwardRef(
|
|
|
10226
11231
|
hasError ? errorId : void 0
|
|
10227
11232
|
].filter(Boolean);
|
|
10228
11233
|
const describedBy = parts.length > 0 ? parts.join(" ") : void 0;
|
|
10229
|
-
const registerHint =
|
|
10230
|
-
const unregisterHint =
|
|
10231
|
-
const registerError =
|
|
10232
|
-
const unregisterError =
|
|
10233
|
-
const wrapperRef =
|
|
11234
|
+
const registerHint = React72.useCallback(() => setHasHint(true), []);
|
|
11235
|
+
const unregisterHint = React72.useCallback(() => setHasHint(false), []);
|
|
11236
|
+
const registerError = React72.useCallback(() => setHasError(true), []);
|
|
11237
|
+
const unregisterError = React72.useCallback(() => setHasError(false), []);
|
|
11238
|
+
const wrapperRef = React72.useRef(null);
|
|
10234
11239
|
const { counters: counterChildren, rest: otherChildren } = partitionTextareaChildren(children);
|
|
10235
11240
|
const showFooter = counterChildren.length > 0;
|
|
10236
|
-
|
|
11241
|
+
React72.useLayoutEffect(() => {
|
|
10237
11242
|
if (!autoResize || !wrapperRef.current) return;
|
|
10238
11243
|
const textarea = wrapperRef.current.querySelector("textarea");
|
|
10239
11244
|
if (textarea) {
|
|
10240
11245
|
wrapperRef.current.dataset.value = textarea.value;
|
|
10241
11246
|
}
|
|
10242
11247
|
}, [autoResize]);
|
|
10243
|
-
|
|
11248
|
+
React72.useEffect(() => {
|
|
10244
11249
|
if (!autoResize || !wrapperRef.current || typeof value !== "string") return;
|
|
10245
11250
|
wrapperRef.current.dataset.value = value;
|
|
10246
11251
|
}, [autoResize, value]);
|
|
10247
|
-
const handleInput =
|
|
11252
|
+
const handleInput = React72.useCallback(
|
|
10248
11253
|
(e) => {
|
|
10249
11254
|
if (autoResize && wrapperRef.current) {
|
|
10250
11255
|
wrapperRef.current.dataset.value = e.currentTarget.value;
|
|
@@ -10253,7 +11258,7 @@ var TextareaRoot = React71.forwardRef(
|
|
|
10253
11258
|
},
|
|
10254
11259
|
[autoResize, onInput]
|
|
10255
11260
|
);
|
|
10256
|
-
const ctxValue =
|
|
11261
|
+
const ctxValue = React72.useMemo(
|
|
10257
11262
|
() => ({
|
|
10258
11263
|
hintId,
|
|
10259
11264
|
errorId,
|
|
@@ -10277,7 +11282,7 @@ var TextareaRoot = React71.forwardRef(
|
|
|
10277
11282
|
unregisterError
|
|
10278
11283
|
]
|
|
10279
11284
|
);
|
|
10280
|
-
const textareaEl = /* @__PURE__ */
|
|
11285
|
+
const textareaEl = /* @__PURE__ */ jsx58(
|
|
10281
11286
|
"textarea",
|
|
10282
11287
|
{
|
|
10283
11288
|
ref,
|
|
@@ -10293,9 +11298,9 @@ var TextareaRoot = React71.forwardRef(
|
|
|
10293
11298
|
...rest
|
|
10294
11299
|
}
|
|
10295
11300
|
);
|
|
10296
|
-
const textareaBlock = autoResize ? /* @__PURE__ */
|
|
10297
|
-
return /* @__PURE__ */
|
|
10298
|
-
/* @__PURE__ */
|
|
11301
|
+
const textareaBlock = autoResize ? /* @__PURE__ */ jsx58("div", { ref: wrapperRef, className: Textarea_default.autoResize, children: textareaEl }) : textareaEl;
|
|
11302
|
+
return /* @__PURE__ */ jsx58(TextareaProvider, { value: ctxValue, children: /* @__PURE__ */ jsx58(ControlSizeProvider, { value: size, children: /* @__PURE__ */ jsxs32("div", { className: Textarea_default.field, ...toDataAttributes({ size }), children: [
|
|
11303
|
+
/* @__PURE__ */ jsx58(
|
|
10299
11304
|
"label",
|
|
10300
11305
|
{
|
|
10301
11306
|
htmlFor: inputId,
|
|
@@ -10306,9 +11311,9 @@ var TextareaRoot = React71.forwardRef(
|
|
|
10306
11311
|
readonly: Boolean(readOnly),
|
|
10307
11312
|
size
|
|
10308
11313
|
}),
|
|
10309
|
-
children: /* @__PURE__ */
|
|
10310
|
-
/* @__PURE__ */
|
|
10311
|
-
showFooter ? /* @__PURE__ */
|
|
11314
|
+
children: /* @__PURE__ */ jsxs32("div", { className: Textarea_default.controlStack, children: [
|
|
11315
|
+
/* @__PURE__ */ jsx58("div", { className: Textarea_default.textareaRegion, children: textareaBlock }),
|
|
11316
|
+
showFooter ? /* @__PURE__ */ jsx58("div", { className: Textarea_default.controlFooter, children: counterChildren }) : null
|
|
10312
11317
|
] })
|
|
10313
11318
|
}
|
|
10314
11319
|
),
|
|
@@ -10319,13 +11324,13 @@ var TextareaRoot = React71.forwardRef(
|
|
|
10319
11324
|
TextareaRoot.displayName = "Textarea.Root";
|
|
10320
11325
|
function TextareaHint({ children, className, ...rest }) {
|
|
10321
11326
|
const { hintId, registerHint, unregisterHint, size, disabled, readOnly } = useTextareaContext();
|
|
10322
|
-
|
|
11327
|
+
React72.useLayoutEffect(() => {
|
|
10323
11328
|
registerHint();
|
|
10324
11329
|
return () => {
|
|
10325
11330
|
unregisterHint();
|
|
10326
11331
|
};
|
|
10327
11332
|
}, [registerHint, unregisterHint]);
|
|
10328
|
-
return /* @__PURE__ */
|
|
11333
|
+
return /* @__PURE__ */ jsx58(
|
|
10329
11334
|
Hint.Root,
|
|
10330
11335
|
{
|
|
10331
11336
|
id: hintId,
|
|
@@ -10340,13 +11345,13 @@ function TextareaHint({ children, className, ...rest }) {
|
|
|
10340
11345
|
TextareaHint.displayName = "Textarea.Hint";
|
|
10341
11346
|
function TextareaError({ children, className, ...rest }) {
|
|
10342
11347
|
const { errorId, registerError, unregisterError, size } = useTextareaContext();
|
|
10343
|
-
|
|
11348
|
+
React72.useLayoutEffect(() => {
|
|
10344
11349
|
registerError();
|
|
10345
11350
|
return () => {
|
|
10346
11351
|
unregisterError();
|
|
10347
11352
|
};
|
|
10348
11353
|
}, [registerError, unregisterError]);
|
|
10349
|
-
return /* @__PURE__ */
|
|
11354
|
+
return /* @__PURE__ */ jsx58(
|
|
10350
11355
|
Hint.Root,
|
|
10351
11356
|
{
|
|
10352
11357
|
id: errorId,
|
|
@@ -10419,6 +11424,7 @@ export {
|
|
|
10419
11424
|
Switch,
|
|
10420
11425
|
Tabs,
|
|
10421
11426
|
Tag,
|
|
11427
|
+
TagSelect,
|
|
10422
11428
|
Textarea,
|
|
10423
11429
|
Tooltip,
|
|
10424
11430
|
Typography,
|