@botiverse/raft-ui 0.11.0 → 0.13.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/CHANGELOG.md +36 -0
- package/dist/components/combobox-select/combobox-select.css +19 -115
- package/dist/foundation.css +25 -3
- package/dist/index-epyBg4aG.d.mts +1089 -0
- package/dist/index.d.mts +7 -712
- package/dist/index.mjs +595 -2531
- package/dist/message-list-DP03T8gF.mjs +3224 -0
- package/dist/style.css +15 -128
- package/dist/styles.css +15 -0
- package/dist/tokens.json +57 -0
- package/dist/wip.d.mts +9 -22
- package/dist/wip.mjs +66 -370
- package/package.json +1 -1
- package/dist/drawer-yZD16Ybl.mjs +0 -988
- package/dist/index-CAdZkAtE.d.mts +0 -311
package/dist/wip.mjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Check, ChevronDown, LoaderCircle, Plus,
|
|
1
|
+
import { Bn as DialogTitle, Gn as defaultNativeButton, Hn as Button$1, Mn as DialogContent, Qn as tv, Rt as useOverflowTitle, Vn as DialogTrigger, Xn as useTheme, Yn as useThemeScopeProps, ct as MessageItemDelegatedAvatar, dt as MessageItemDelegatedByName, i as MessageListJumpPillGroup, jn as DialogClose, kn as Dialog, lt as MessageItemDelegatedBy, n as MessageListJumpPill, p as MessageQuotedPreviewAuthorDelegatedBy, r as MessageListJumpPillDismiss, t as MessageListJumpControls, ut as MessageItemDelegatedByButton } from "./message-list-DP03T8gF.mjs";
|
|
2
|
+
import { Check, ChevronDown, LoaderCircle, Plus, X } from "lucide-react";
|
|
3
3
|
import { createContext, use, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { Button } from "@base-ui/react/button";
|
|
6
6
|
import { mergeProps } from "@base-ui/react/merge-props";
|
|
7
7
|
import { useRender } from "@base-ui/react/use-render";
|
|
8
8
|
import { Combobox } from "@base-ui/react/combobox";
|
|
9
|
-
import { Select } from "@base-ui/react/select";
|
|
10
9
|
//#region src/lib/phone-media.ts
|
|
11
10
|
/**
|
|
12
11
|
* A phone: a touch screen narrower than the desktop layout. The complement, on
|
|
@@ -28,28 +27,17 @@ function getSnapshot() {
|
|
|
28
27
|
function usePhoneMedia() {
|
|
29
28
|
return useSyncExternalStore(subscribe, getSnapshot, () => false);
|
|
30
29
|
}
|
|
31
|
-
function resolveComboboxSelectMode({ phone, optionCount, sheetThreshold = 10, create = false, remote = false }) {
|
|
32
|
-
if (!phone) return "field";
|
|
33
|
-
if (create || remote) return "sheet";
|
|
34
|
-
return optionCount > sheetThreshold ? "sheet" : "list";
|
|
35
|
-
}
|
|
36
|
-
/** Options people can pick, flat or grouped: disabled options don't count. */
|
|
37
|
-
function countSelectableOptions(groups) {
|
|
38
|
-
let count = 0;
|
|
39
|
-
for (const group of groups) for (const item of group.items) if (!item.disabled) count += 1;
|
|
40
|
-
return count;
|
|
41
|
-
}
|
|
42
|
-
/** The tallest the anchored list gets (`.r-combobox-select__list`, 16rem). */
|
|
43
|
-
const LIST_MAX_HEIGHT = 256;
|
|
44
30
|
/**
|
|
45
|
-
* The side
|
|
46
|
-
*
|
|
47
|
-
*
|
|
31
|
+
* The side a phone's list opens on, chosen once when it opens so it never flips
|
|
32
|
+
* while it is open (a phone's visual viewport keeps changing under it, as the
|
|
33
|
+
* keyboard and the address bar come and go). Below, unless the room below is
|
|
34
|
+
* short of the list and there is more above. `listHeight` is the list's full
|
|
35
|
+
* height and `maxHeight` its cap (`listMaxHeight`), both in pixels.
|
|
48
36
|
*/
|
|
49
|
-
function preferredListSide(anchor, viewport, listHeight) {
|
|
37
|
+
function preferredListSide(anchor, viewport, listHeight, maxHeight) {
|
|
50
38
|
const below = viewport.top + viewport.height - anchor.bottom;
|
|
51
39
|
const above = anchor.top - viewport.top;
|
|
52
|
-
return below >= Math.min(listHeight,
|
|
40
|
+
return below >= Math.min(listHeight, maxHeight) || below >= above ? "bottom" : "top";
|
|
53
41
|
}
|
|
54
42
|
//#endregion
|
|
55
43
|
//#region src/components/combobox-select/combobox-select.options.ts
|
|
@@ -79,25 +67,24 @@ const defaultMessages = {
|
|
|
79
67
|
selected: "Selected options",
|
|
80
68
|
chipDescription: "Press Backspace or Delete to remove",
|
|
81
69
|
inputDescription: "From the start of the input, press Left Arrow to focus selected options",
|
|
82
|
-
remove: (label) => `Remove ${label}
|
|
83
|
-
search: "Search",
|
|
84
|
-
done: "Done",
|
|
85
|
-
close: "Close"
|
|
70
|
+
remove: (label) => `Remove ${label}`
|
|
86
71
|
};
|
|
87
72
|
const defaultRenderCreateLabel = (query) => `Create “${query}”`;
|
|
73
|
+
/** An option's or a chip's text, with its whole value as the title when it is cut off. */
|
|
74
|
+
function OverflowText({ children }) {
|
|
75
|
+
return /* @__PURE__ */ jsx("span", {
|
|
76
|
+
ref: useOverflowTitle(),
|
|
77
|
+
className: "r-combobox-select__text",
|
|
78
|
+
children
|
|
79
|
+
});
|
|
80
|
+
}
|
|
88
81
|
function recordLabel(record, renderLabel) {
|
|
89
82
|
return record.option === void 0 ? record.label : renderLabel?.(record.option) ?? record.label;
|
|
90
83
|
}
|
|
91
84
|
function renderOptionContent({ record, selected, renderLabel, renderOption, renderCreateLabel }) {
|
|
92
|
-
if (record.createQuery !== void 0) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Plus, { "aria-hidden": true }), /* @__PURE__ */ jsx(
|
|
93
|
-
className: "r-combobox-select__text",
|
|
94
|
-
children: renderCreateLabel(record.label)
|
|
95
|
-
})] });
|
|
85
|
+
if (record.createQuery !== void 0) return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Plus, { "aria-hidden": true }), /* @__PURE__ */ jsx(OverflowText, { children: renderCreateLabel(record.label) })] });
|
|
96
86
|
const content = record.option === void 0 ? record.label : renderOption?.(record.option, { selected }) ?? recordLabel(record, renderLabel);
|
|
97
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(
|
|
98
|
-
className: "r-combobox-select__text",
|
|
99
|
-
children: content
|
|
100
|
-
}), /* @__PURE__ */ jsx(Combobox.ItemIndicator, {
|
|
87
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(OverflowText, { children: content }), /* @__PURE__ */ jsx(Combobox.ItemIndicator, {
|
|
101
88
|
className: "r-combobox-select__indicator",
|
|
102
89
|
children: /* @__PURE__ */ jsx(Check, { "aria-hidden": true })
|
|
103
90
|
})] });
|
|
@@ -111,72 +98,34 @@ function renderSelectedChip({ record, index, tagLimit, strings, renderLabel, ren
|
|
|
111
98
|
"data-overflow": overflow || void 0,
|
|
112
99
|
"aria-label": record.label,
|
|
113
100
|
"aria-description": strings.chipDescription,
|
|
114
|
-
children: [/* @__PURE__ */ jsx(
|
|
115
|
-
className: "r-combobox-select__text",
|
|
116
|
-
children: content
|
|
117
|
-
}), /* @__PURE__ */ jsx(Combobox.ChipRemove, {
|
|
101
|
+
children: [/* @__PURE__ */ jsx(OverflowText, { children: content }), /* @__PURE__ */ jsx(Combobox.ChipRemove, {
|
|
118
102
|
className: "r-combobox-select__remove",
|
|
119
103
|
"aria-label": strings.remove(record.label),
|
|
120
104
|
children: /* @__PURE__ */ jsx(X, { "aria-hidden": true })
|
|
121
105
|
})]
|
|
122
106
|
}, optionKey(record.value));
|
|
123
107
|
}
|
|
124
|
-
/**
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
value: record,
|
|
129
|
-
label: record.label,
|
|
130
|
-
disabled: record.disabled || loading,
|
|
131
|
-
className: "r-combobox-select__option",
|
|
132
|
-
children: [/* @__PURE__ */ jsx(Select.ItemText, {
|
|
133
|
-
className: "r-combobox-select__text",
|
|
134
|
-
children: content
|
|
135
|
-
}), /* @__PURE__ */ jsx(Select.ItemIndicator, {
|
|
136
|
-
className: "r-combobox-select__indicator",
|
|
137
|
-
children: /* @__PURE__ */ jsx(Check, { "aria-hidden": true })
|
|
138
|
-
})]
|
|
139
|
-
}, optionKey(record.value));
|
|
140
|
-
}
|
|
141
|
-
/** Change details for the phone's own changes: the clear button outside any Base UI root, the sheet's search emptied as it closes. */
|
|
142
|
-
function syntheticDetails(reason, event) {
|
|
143
|
-
let canceled = false;
|
|
144
|
-
return {
|
|
145
|
-
reason,
|
|
146
|
-
event,
|
|
147
|
-
trigger: void 0,
|
|
148
|
-
cancel() {
|
|
149
|
-
canceled = true;
|
|
150
|
-
},
|
|
151
|
-
allowPropagation() {},
|
|
152
|
-
get isCanceled() {
|
|
153
|
-
return canceled;
|
|
154
|
-
},
|
|
155
|
-
get isPropagationAllowed() {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
function assignRef(ref, value) {
|
|
161
|
-
if (typeof ref === "function") ref(value);
|
|
162
|
-
else if (ref) ref.current = value;
|
|
163
|
-
}
|
|
164
|
-
/** The text that names a field: its `aria-labelledby` elements, else its `<label>`. */
|
|
165
|
-
function readFieldLabel(element, labelledBy) {
|
|
166
|
-
if (!element) return "";
|
|
167
|
-
const doc = element.ownerDocument;
|
|
168
|
-
const fromIds = (labelledBy ?? "").split(/\s+/).filter(Boolean).map((labelId) => doc.getElementById(labelId)?.textContent?.trim() ?? "").filter(Boolean).join(" ");
|
|
169
|
-
if (fromIds) return fromIds;
|
|
170
|
-
return [...element.labels ?? []].map((label) => label.textContent?.trim() ?? "").filter(Boolean).join(" ");
|
|
171
|
-
}
|
|
172
|
-
/** The phone's anchored list keeps the side it opened on: it never flips while open. */
|
|
108
|
+
/**
|
|
109
|
+
* On a phone the list keeps the side it opened on: it never flips while it is
|
|
110
|
+
* open, as the keyboard or the address bar change the visual viewport under it.
|
|
111
|
+
*/
|
|
173
112
|
const PHONE_LIST_COLLISION = {
|
|
174
113
|
side: "none",
|
|
175
114
|
align: "shift",
|
|
176
115
|
fallbackAxisSide: "none"
|
|
177
116
|
};
|
|
178
|
-
/**
|
|
179
|
-
function
|
|
117
|
+
/** A CSS length in pixels, as the document resolves it (rem, vh, calc()). */
|
|
118
|
+
function resolveLength(doc, length) {
|
|
119
|
+
const probe = doc.createElement("div");
|
|
120
|
+
probe.style.cssText = "position:absolute;visibility:hidden;pointer-events:none;width:0";
|
|
121
|
+
probe.style.height = length;
|
|
122
|
+
doc.body.append(probe);
|
|
123
|
+
const height = probe.getBoundingClientRect().height;
|
|
124
|
+
probe.remove();
|
|
125
|
+
return height;
|
|
126
|
+
}
|
|
127
|
+
/** The side the phone's list opens on, from the room around the field and the list's cap. */
|
|
128
|
+
function measureListSide(anchor, groups, maxHeight) {
|
|
180
129
|
const view = anchor?.ownerDocument.defaultView;
|
|
181
130
|
if (!anchor || !view) return "bottom";
|
|
182
131
|
const visual = view.visualViewport;
|
|
@@ -187,7 +136,7 @@ function measureListSide(anchor, groups) {
|
|
|
187
136
|
} : {
|
|
188
137
|
top: 0,
|
|
189
138
|
height: view.innerHeight
|
|
190
|
-
}, rows * 36 + 12);
|
|
139
|
+
}, rows * 36 + 12, resolveLength(anchor.ownerDocument, maxHeight));
|
|
191
140
|
}
|
|
192
141
|
/** Options-driven composition. The stable compound Combobox API stays unchanged. */
|
|
193
142
|
function isItemEqualToValue(a, b) {
|
|
@@ -199,7 +148,7 @@ function itemToStringLabel(record) {
|
|
|
199
148
|
function itemToStringValue(record) {
|
|
200
149
|
return String(record.value);
|
|
201
150
|
}
|
|
202
|
-
function ComboboxSelect({ options, multiple, value, defaultValue, onValueChange, labelField = "label", valueField = "value", disabledField = "disabled", fallbackOption, filterable = true, filter, remote = false, onSearch, loading = false, create = false, creatable, onCreate, clearable = false, showArrow = true, clearFilterAfterSelect = true, onClear, maxTagCount, size = "md", status, placeholder = "Select an option", renderLabel, renderOption, renderTag, renderCreateLabel = defaultRenderCreateLabel, emptyContent = "No options found", loadingContent = "Loading…", messages,
|
|
151
|
+
function ComboboxSelect({ options, multiple, value, defaultValue, onValueChange, labelField = "label", valueField = "value", disabledField = "disabled", fallbackOption, filterable = true, filter, remote = false, onSearch, loading = false, create = false, creatable, onCreate, clearable = false, showArrow = true, clearFilterAfterSelect = true, onClear, maxTagCount, size = "md", status, placeholder = "Select an option", renderLabel, renderOption, renderTag, renderCreateLabel = defaultRenderCreateLabel, emptyContent = "No options found", loadingContent = "Loading…", messages, listMaxHeight, inputProps, portalProps, positionerProps, popupProps, className, style, id: idProp, ref, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, inputValue, defaultInputValue, onInputValueChange, disabled, readOnly, autoHighlight = true, onOpenChange, ...rootProps }) {
|
|
203
152
|
const generatedId = useId();
|
|
204
153
|
const id = idProp ?? generatedId;
|
|
205
154
|
const { resolvedMode } = useTheme();
|
|
@@ -288,15 +237,18 @@ function ComboboxSelect({ options, multiple, value, defaultValue, onValueChange,
|
|
|
288
237
|
const css = `r-combobox-select r-combobox-select--${size}${resolvedMode === "dark" ? " r-combobox-select--dark" : ""}`;
|
|
289
238
|
const tagLimit = maxTagCount === void 0 ? Infinity : Math.max(0, Math.floor(maxTagCount));
|
|
290
239
|
const inputClassName = ["r-combobox-select__input", typeof inputProps?.className === "string" ? inputProps.className : null].filter(Boolean).join(" ");
|
|
240
|
+
const phone = usePhoneMedia();
|
|
291
241
|
const controlClassName = [
|
|
292
242
|
css,
|
|
293
243
|
"r-combobox-select__control has-focus-visible:shadow-focus",
|
|
244
|
+
phone ? "r-combobox-select__control--phone" : null,
|
|
294
245
|
className
|
|
295
246
|
].filter(Boolean).join(" ");
|
|
296
247
|
const positionerClassName = ["r-combobox-select__positioner", typeof positionerProps?.className === "string" ? positionerProps.className : null].filter(Boolean).join(" ");
|
|
297
248
|
const popupClassName = [
|
|
298
249
|
css,
|
|
299
250
|
"r-combobox-select__popup",
|
|
251
|
+
phone ? "r-combobox-select__popup--anchored" : null,
|
|
300
252
|
typeof popupProps?.className === "string" ? popupProps.className : null
|
|
301
253
|
].filter(Boolean).join(" ");
|
|
302
254
|
const inputRef = ref ?? inputProps?.ref;
|
|
@@ -468,293 +420,30 @@ function ComboboxSelect({ options, multiple, value, defaultValue, onValueChange,
|
|
|
468
420
|
]
|
|
469
421
|
});
|
|
470
422
|
const valueChange = handleValueChange;
|
|
471
|
-
const
|
|
472
|
-
phone: usePhoneMedia(),
|
|
473
|
-
optionCount: countSelectableOptions(normalized.groups),
|
|
474
|
-
sheetThreshold,
|
|
475
|
-
create: Boolean(create || creatable),
|
|
476
|
-
remote
|
|
477
|
-
});
|
|
423
|
+
const listHeight = typeof listMaxHeight === "number" ? `${listMaxHeight}px` : listMaxHeight;
|
|
478
424
|
const fieldRef = useRef(null);
|
|
479
|
-
const triggerRef = useRef(null);
|
|
480
|
-
const searchInputRef = useRef(null);
|
|
481
|
-
const [uncontrolledPhoneOpen, setUncontrolledPhoneOpen] = useState(Boolean(rootProps.defaultOpen));
|
|
482
|
-
const phoneOpen = rootProps.open ?? uncontrolledPhoneOpen;
|
|
483
425
|
const [listSide, setListSide] = useState("bottom");
|
|
484
|
-
const [fieldLabel, setFieldLabel] = useState("");
|
|
485
|
-
const sheetNamed = sheetTitle != null || Boolean(inputLabel);
|
|
486
|
-
useLayoutEffect(() => {
|
|
487
|
-
if (mode !== "sheet" || !phoneOpen || sheetNamed) return;
|
|
488
|
-
setFieldLabel(readFieldLabel(triggerRef.current, inputLabelledBy));
|
|
489
|
-
}, [
|
|
490
|
-
mode,
|
|
491
|
-
phoneOpen,
|
|
492
|
-
sheetNamed,
|
|
493
|
-
inputLabelledBy
|
|
494
|
-
]);
|
|
495
|
-
const setSearchInput = useCallback((element) => {
|
|
496
|
-
searchInputRef.current = element;
|
|
497
|
-
assignRef(inputRef, element);
|
|
498
|
-
}, [inputRef]);
|
|
499
|
-
const onOpenChangeProp = rootProps.onOpenChange;
|
|
500
|
-
const openProp = rootProps.open;
|
|
501
426
|
const groups = normalized.groups;
|
|
502
|
-
const
|
|
503
|
-
|
|
504
|
-
if (details.isCanceled)
|
|
505
|
-
if (next && mode === "list") setListSide(measureListSide(fieldRef.current, groups));
|
|
506
|
-
if (!next && mode === "sheet") handleInputValueChange("", syntheticDetails("input-clear", details.event));
|
|
507
|
-
if (openProp === void 0) setUncontrolledPhoneOpen(next);
|
|
427
|
+
const handleOpenChange = useCallback((next, details) => {
|
|
428
|
+
onOpenChange?.(next, details);
|
|
429
|
+
if (next && phone && !details.isCanceled) setListSide(measureListSide(fieldRef.current, groups, listHeight ?? "16rem"));
|
|
508
430
|
}, [
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
mode,
|
|
431
|
+
onOpenChange,
|
|
432
|
+
phone,
|
|
512
433
|
groups,
|
|
513
|
-
|
|
514
|
-
]);
|
|
515
|
-
const handleSheetValueChange = useCallback((next, details) => {
|
|
516
|
-
handleValueChange(next, details);
|
|
517
|
-
if (!multiple && !details.isCanceled) handlePhoneOpenChange(false, details);
|
|
518
|
-
}, [
|
|
519
|
-
handleValueChange,
|
|
520
|
-
multiple,
|
|
521
|
-
handlePhoneOpenChange
|
|
434
|
+
listHeight
|
|
522
435
|
]);
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
className: "r-combobox-select__placeholder",
|
|
530
|
-
children: placeholder
|
|
531
|
-
});
|
|
532
|
-
const phoneValue = multiple ? selected.length ? /* @__PURE__ */ jsxs("span", {
|
|
533
|
-
className: "r-combobox-select__chips",
|
|
534
|
-
children: [selected.slice(0, tagLimit).map((record) => /* @__PURE__ */ jsx("span", {
|
|
535
|
-
className: "r-combobox-select__chip",
|
|
536
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
537
|
-
className: "r-combobox-select__text",
|
|
538
|
-
children: record.option === void 0 ? record.label : renderTag?.(record.option) ?? recordLabel(record, renderLabel)
|
|
539
|
-
})
|
|
540
|
-
}, optionKey(record.value))), overflow]
|
|
541
|
-
}) : placeholderText : selected[0] ? /* @__PURE__ */ jsx("span", {
|
|
542
|
-
className: "r-combobox-select__value",
|
|
543
|
-
children: selected[0].label
|
|
544
|
-
}) : placeholderText;
|
|
545
|
-
const phoneClear = clearable && selected.length > 0 && !disabled && !readOnly ? /* @__PURE__ */ jsx("button", {
|
|
546
|
-
type: "button",
|
|
547
|
-
className: "r-combobox-select__action r-combobox-select__clear",
|
|
548
|
-
"aria-label": strings.clear,
|
|
549
|
-
onClick: handlePhoneClear,
|
|
550
|
-
children: /* @__PURE__ */ jsx(X, { "aria-hidden": true })
|
|
551
|
-
}) : null;
|
|
552
|
-
const phoneActions = /* @__PURE__ */ jsxs("span", {
|
|
553
|
-
className: "r-combobox-select__actions",
|
|
554
|
-
children: [
|
|
555
|
-
loadingIndicator,
|
|
556
|
-
phoneClear,
|
|
557
|
-
showArrow ? /* @__PURE__ */ jsx("span", {
|
|
558
|
-
className: "r-combobox-select__action r-combobox-select__arrow",
|
|
559
|
-
"aria-hidden": true,
|
|
560
|
-
children: /* @__PURE__ */ jsx(ChevronDown, {})
|
|
561
|
-
}) : null
|
|
562
|
-
]
|
|
563
|
-
});
|
|
564
|
-
const phoneControlClassName = [
|
|
565
|
-
css,
|
|
566
|
-
"r-combobox-select__control r-combobox-select__control--trigger has-focus-visible:shadow-focus",
|
|
567
|
-
className
|
|
568
|
-
].filter(Boolean).join(" ");
|
|
569
|
-
const triggerProps = {
|
|
570
|
-
ref: triggerRef,
|
|
571
|
-
id,
|
|
572
|
-
"data-slot": "combobox-select-trigger",
|
|
573
|
-
className: "r-combobox-select__trigger",
|
|
574
|
-
"aria-label": inputLabel,
|
|
575
|
-
"aria-labelledby": inputLabelledBy,
|
|
576
|
-
"aria-describedby": inputDescribedBy,
|
|
577
|
-
"aria-invalid": inputInvalid
|
|
578
|
-
};
|
|
579
|
-
const field = (trigger) => /* @__PURE__ */ jsxs("div", {
|
|
580
|
-
ref: fieldRef,
|
|
581
|
-
"data-slot": "combobox-select",
|
|
582
|
-
"data-status": status,
|
|
583
|
-
"data-disabled": disabled || void 0,
|
|
584
|
-
"data-readonly": readOnly || void 0,
|
|
585
|
-
"data-popup-open": phoneOpen || void 0,
|
|
586
|
-
className: phoneControlClassName,
|
|
587
|
-
style,
|
|
588
|
-
children: [trigger, phoneActions]
|
|
436
|
+
const popupPropsStyle = popupProps?.style;
|
|
437
|
+
const popupStyle = useMemo(() => {
|
|
438
|
+
if (listHeight === void 0) return popupPropsStyle;
|
|
439
|
+
return (state) => ({
|
|
440
|
+
...typeof popupPropsStyle === "function" ? popupPropsStyle(state) : popupPropsStyle,
|
|
441
|
+
"--combobox-select-list-max-height": listHeight
|
|
589
442
|
});
|
|
590
|
-
|
|
591
|
-
const anchoredPopupClassName = `${popupClassName} r-combobox-select__popup--anchored`;
|
|
592
|
-
const hasOptions = normalized.groups.some((group) => group.items.length > 0);
|
|
593
|
-
return /* @__PURE__ */ jsxs(Select.Root, {
|
|
594
|
-
multiple,
|
|
595
|
-
value: controlValue,
|
|
596
|
-
onValueChange: valueChange,
|
|
597
|
-
open: phoneOpen,
|
|
598
|
-
onOpenChange: handlePhoneOpenChange,
|
|
599
|
-
onOpenChangeComplete: rootProps.onOpenChangeComplete,
|
|
600
|
-
modal: false,
|
|
601
|
-
name: rootProps.name,
|
|
602
|
-
form: rootProps.form,
|
|
603
|
-
required: rootProps.required,
|
|
604
|
-
autoComplete: rootProps.autoComplete,
|
|
605
|
-
disabled,
|
|
606
|
-
readOnly,
|
|
607
|
-
itemToStringLabel,
|
|
608
|
-
itemToStringValue,
|
|
609
|
-
isItemEqualToValue,
|
|
610
|
-
children: [field(/* @__PURE__ */ jsx(Select.Trigger, {
|
|
611
|
-
...triggerProps,
|
|
612
|
-
children: phoneValue
|
|
613
|
-
})), /* @__PURE__ */ jsx(Select.Portal, {
|
|
614
|
-
...scopedPortalProps,
|
|
615
|
-
children: /* @__PURE__ */ jsx(Select.Positioner, {
|
|
616
|
-
anchor: fieldRef,
|
|
617
|
-
side: listSide,
|
|
618
|
-
align: "start",
|
|
619
|
-
sideOffset: 4,
|
|
620
|
-
alignItemWithTrigger: false,
|
|
621
|
-
collisionAvoidance: PHONE_LIST_COLLISION,
|
|
622
|
-
className: positionerClassName,
|
|
623
|
-
children: /* @__PURE__ */ jsxs(Select.Popup, {
|
|
624
|
-
"data-slot": "combobox-select-popup",
|
|
625
|
-
className: anchoredPopupClassName,
|
|
626
|
-
children: [
|
|
627
|
-
loading ? /* @__PURE__ */ jsx("div", {
|
|
628
|
-
role: "status",
|
|
629
|
-
className: "r-combobox-select__message",
|
|
630
|
-
children: loadingContent
|
|
631
|
-
}) : null,
|
|
632
|
-
/* @__PURE__ */ jsx(Select.List, {
|
|
633
|
-
className: "r-combobox-select__list",
|
|
634
|
-
"aria-busy": loading,
|
|
635
|
-
children: normalized.groups.map((group) => /* @__PURE__ */ jsxs(Select.Group, { children: [group.label == null ? null : /* @__PURE__ */ jsx(Select.GroupLabel, {
|
|
636
|
-
className: "r-combobox-select__group-label",
|
|
637
|
-
children: group.label
|
|
638
|
-
}), group.items.map((record) => renderSelectOption({
|
|
639
|
-
record,
|
|
640
|
-
selected: selected.some((item) => item.value === record.value),
|
|
641
|
-
loading,
|
|
642
|
-
renderLabel,
|
|
643
|
-
renderOption
|
|
644
|
-
}))] }, group.key))
|
|
645
|
-
}),
|
|
646
|
-
!hasOptions ? emptyMessage : null
|
|
647
|
-
]
|
|
648
|
-
})
|
|
649
|
-
})
|
|
650
|
-
})]
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
const titleId = `${id}-sheet-title`;
|
|
654
|
-
const sheetCss = `r-combobox-select r-combobox-select--md${resolvedMode === "dark" ? " r-combobox-select--dark" : ""} r-combobox-select__sheet`;
|
|
655
|
-
const hiddenInputs = rootProps.name ? selectedKeys.map((key) => /* @__PURE__ */ jsx("input", {
|
|
656
|
-
type: "hidden",
|
|
657
|
-
name: rootProps.name,
|
|
658
|
-
form: rootProps.form,
|
|
659
|
-
value: String(key),
|
|
660
|
-
disabled
|
|
661
|
-
}, optionKey(key))) : null;
|
|
662
|
-
return /* @__PURE__ */ jsxs(Drawer, {
|
|
663
|
-
open: phoneOpen,
|
|
664
|
-
onOpenChange: handlePhoneOpenChange,
|
|
665
|
-
onOpenChangeComplete: rootProps.onOpenChangeComplete,
|
|
666
|
-
children: [
|
|
667
|
-
field(/* @__PURE__ */ jsx(DrawerTrigger, {
|
|
668
|
-
...triggerProps,
|
|
669
|
-
disabled,
|
|
670
|
-
role: "combobox",
|
|
671
|
-
"aria-haspopup": "dialog",
|
|
672
|
-
"aria-expanded": phoneOpen,
|
|
673
|
-
"aria-readonly": readOnly || void 0,
|
|
674
|
-
"aria-required": rootProps.required || void 0,
|
|
675
|
-
children: phoneValue
|
|
676
|
-
})),
|
|
677
|
-
hiddenInputs,
|
|
678
|
-
/* @__PURE__ */ jsx(DrawerContent, {
|
|
679
|
-
portalProps,
|
|
680
|
-
"data-slot": "combobox-select-sheet",
|
|
681
|
-
className: "r-combobox-select__sheet-popup",
|
|
682
|
-
initialFocus: create || creatable ? focusSearchInput : void 0,
|
|
683
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
684
|
-
className: sheetCss,
|
|
685
|
-
children: [
|
|
686
|
-
/* @__PURE__ */ jsxs(DrawerHeader, {
|
|
687
|
-
className: "r-combobox-select__sheet-header",
|
|
688
|
-
children: [/* @__PURE__ */ jsx(DrawerTitle, {
|
|
689
|
-
id: titleId,
|
|
690
|
-
className: "r-combobox-select__sheet-title",
|
|
691
|
-
children: sheetTitle ?? inputLabel ?? (fieldLabel || placeholder)
|
|
692
|
-
}), /* @__PURE__ */ jsx(DrawerClose, { "aria-label": strings.close })]
|
|
693
|
-
}),
|
|
694
|
-
/* @__PURE__ */ jsxs(Combobox.Root, {
|
|
695
|
-
inline: true,
|
|
696
|
-
multiple,
|
|
697
|
-
disabled,
|
|
698
|
-
readOnly,
|
|
699
|
-
items,
|
|
700
|
-
value: controlValue,
|
|
701
|
-
onValueChange: handleSheetValueChange,
|
|
702
|
-
inputValue,
|
|
703
|
-
defaultInputValue,
|
|
704
|
-
onInputValueChange: handleInputValueChange,
|
|
705
|
-
filter: filterOptions,
|
|
706
|
-
itemToStringLabel,
|
|
707
|
-
itemToStringValue,
|
|
708
|
-
isItemEqualToValue,
|
|
709
|
-
autoHighlight,
|
|
710
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
711
|
-
className: "r-combobox-select__sheet-search",
|
|
712
|
-
children: /* @__PURE__ */ jsxs(Combobox.InputGroup, {
|
|
713
|
-
className: "r-combobox-select__control has-focus-visible:shadow-focus",
|
|
714
|
-
children: [
|
|
715
|
-
/* @__PURE__ */ jsx(Search, {
|
|
716
|
-
className: "r-combobox-select__search-icon",
|
|
717
|
-
"aria-hidden": true
|
|
718
|
-
}),
|
|
719
|
-
/* @__PURE__ */ jsx(Combobox.Input, {
|
|
720
|
-
...inputProps,
|
|
721
|
-
ref: setSearchInput,
|
|
722
|
-
id: `${id}-search`,
|
|
723
|
-
"data-slot": "combobox-select-input",
|
|
724
|
-
className: inputClassName,
|
|
725
|
-
"aria-labelledby": titleId,
|
|
726
|
-
placeholder: strings.search,
|
|
727
|
-
readOnly: inputReadOnly,
|
|
728
|
-
enterKeyHint: "search"
|
|
729
|
-
}),
|
|
730
|
-
loadingIndicator
|
|
731
|
-
]
|
|
732
|
-
})
|
|
733
|
-
}), /* @__PURE__ */ jsxs(DrawerBody, {
|
|
734
|
-
className: "r-combobox-select__sheet-body",
|
|
735
|
-
children: [
|
|
736
|
-
/* @__PURE__ */ jsx(Combobox.Status, { children: loadingMessage }),
|
|
737
|
-
/* @__PURE__ */ jsx(Combobox.List, {
|
|
738
|
-
className: "r-combobox-select__list",
|
|
739
|
-
"aria-busy": loading,
|
|
740
|
-
children: renderGroup
|
|
741
|
-
}),
|
|
742
|
-
/* @__PURE__ */ jsx(Combobox.Empty, { children: emptyMessage })
|
|
743
|
-
]
|
|
744
|
-
})]
|
|
745
|
-
}),
|
|
746
|
-
multiple ? /* @__PURE__ */ jsx(DrawerFooter, { children: /* @__PURE__ */ jsx(DrawerActions, { children: /* @__PURE__ */ jsx(DrawerClose, {
|
|
747
|
-
render: /* @__PURE__ */ jsx(Button$1, { size: "lg" }),
|
|
748
|
-
children: strings.done
|
|
749
|
-
}) }) }) : null
|
|
750
|
-
]
|
|
751
|
-
})
|
|
752
|
-
})
|
|
753
|
-
]
|
|
754
|
-
});
|
|
755
|
-
}
|
|
443
|
+
}, [listHeight, popupPropsStyle]);
|
|
756
444
|
return /* @__PURE__ */ jsxs(Combobox.Root, {
|
|
757
445
|
...rootProps,
|
|
446
|
+
onOpenChange: handleOpenChange,
|
|
758
447
|
id,
|
|
759
448
|
multiple,
|
|
760
449
|
disabled,
|
|
@@ -771,6 +460,7 @@ function ComboboxSelect({ options, multiple, value, defaultValue, onValueChange,
|
|
|
771
460
|
isItemEqualToValue,
|
|
772
461
|
autoHighlight,
|
|
773
462
|
children: [/* @__PURE__ */ jsxs(Combobox.InputGroup, {
|
|
463
|
+
ref: fieldRef,
|
|
774
464
|
"data-slot": "combobox-select",
|
|
775
465
|
"data-status": status,
|
|
776
466
|
className: controlClassName,
|
|
@@ -781,12 +471,18 @@ function ComboboxSelect({ options, multiple, value, defaultValue, onValueChange,
|
|
|
781
471
|
children: /* @__PURE__ */ jsx(Combobox.Positioner, {
|
|
782
472
|
sideOffset: 4,
|
|
783
473
|
align: "start",
|
|
474
|
+
collisionPadding: 8,
|
|
475
|
+
...phone ? {
|
|
476
|
+
side: listSide,
|
|
477
|
+
collisionAvoidance: PHONE_LIST_COLLISION
|
|
478
|
+
} : null,
|
|
784
479
|
...positionerProps,
|
|
785
480
|
className: positionerClassName,
|
|
786
481
|
children: /* @__PURE__ */ jsxs(Combobox.Popup, {
|
|
787
482
|
initialFocus: false,
|
|
788
483
|
finalFocus: false,
|
|
789
484
|
...popupProps,
|
|
485
|
+
style: popupStyle,
|
|
790
486
|
"data-slot": "combobox-select-popup",
|
|
791
487
|
className: popupClassName,
|
|
792
488
|
children: [
|
|
@@ -938,7 +634,7 @@ const comment = tv({
|
|
|
938
634
|
cardTrigger: [
|
|
939
635
|
"absolute -inset-px z-10 cursor-pointer",
|
|
940
636
|
"rounded-container border-0 bg-transparent p-0",
|
|
941
|
-
"hover:bg-fill-
|
|
637
|
+
"hover:bg-fill-row-hover active:bg-fill-pressed",
|
|
942
638
|
"outline-none focus-visible:shadow-focus"
|
|
943
639
|
],
|
|
944
640
|
cardQuote: ["sr-only"],
|
|
@@ -1410,4 +1106,4 @@ function useCommentMarginFits(element, { minWidth = 784 } = {}) {
|
|
|
1410
1106
|
return desktop && element !== null && width >= minWidth;
|
|
1411
1107
|
}
|
|
1412
1108
|
//#endregion
|
|
1413
|
-
export { Dialog as AnnouncementDialog, AnnouncementDialogAction, AnnouncementDialogBody, DialogClose as AnnouncementDialogClose, AnnouncementDialogContent, AnnouncementDialogFooter, AnnouncementDialogHeader, AnnouncementDialogLabel, AnnouncementDialogPicture, AnnouncementDialogSecondaryAction, AnnouncementDialogText, AnnouncementDialogTitle, DialogTrigger as AnnouncementDialogTrigger, COMMENT_HIGHLIGHT, COMMENT_HIGHLIGHT_ACTIVE, ComboboxSelect, CommentCard, CommentCardMeta, CommentCardQuote, CommentCardTrigger, CommentEntry, CommentEntryAuthor, CommentEntryBody, CommentEntryHeader, CommentEntryTime, CommentMargin, CommentMarginItem, CommentMarker, resolveCommentMarginLayout, setCommentHighlights, useCommentMarginFits };
|
|
1109
|
+
export { Dialog as AnnouncementDialog, AnnouncementDialogAction, AnnouncementDialogBody, DialogClose as AnnouncementDialogClose, AnnouncementDialogContent, AnnouncementDialogFooter, AnnouncementDialogHeader, AnnouncementDialogLabel, AnnouncementDialogPicture, AnnouncementDialogSecondaryAction, AnnouncementDialogText, AnnouncementDialogTitle, DialogTrigger as AnnouncementDialogTrigger, COMMENT_HIGHLIGHT, COMMENT_HIGHLIGHT_ACTIVE, ComboboxSelect, CommentCard, CommentCardMeta, CommentCardQuote, CommentCardTrigger, CommentEntry, CommentEntryAuthor, CommentEntryBody, CommentEntryHeader, CommentEntryTime, CommentMargin, CommentMarginItem, CommentMarker, MessageItemDelegatedAvatar, MessageItemDelegatedBy, MessageItemDelegatedByButton, MessageItemDelegatedByName, MessageListJumpControls, MessageListJumpPill, MessageListJumpPillDismiss, MessageListJumpPillGroup, MessageQuotedPreviewAuthorDelegatedBy, resolveCommentMarginLayout, setCommentHighlights, useCommentMarginFits };
|