@reopt-ai/opt-ui-primitives 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1080 -589
- package/dist/index.d.cts +137 -21
- package/dist/index.d.ts +137 -21
- package/dist/index.js +1080 -591
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import React, { cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId as useId$1, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
2
|
+
import React, { cloneElement, createContext, createElement, forwardRef, isValidElement, useCallback, useContext, useEffect, useId as useId$1, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
3
3
|
import { FloatingFocusManager, FloatingPortal, autoUpdate, flip, hide, offset, shift, size, useDismiss, useFloating as useFloating$1 } from "@floating-ui/react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/hooks/use-controllable-state.ts
|
|
@@ -152,6 +152,32 @@ function removeGlobalListeners() {
|
|
|
152
152
|
document.removeEventListener("touchstart", handlePointerDown, true);
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Subscribe to the shared modality tracking and read it on demand.
|
|
157
|
+
*
|
|
158
|
+
* Returns a stable predicate answering "should this focus show as visible?".
|
|
159
|
+
* Widgets that must react ONLY to keyboard focus (a tooltip must not pop open
|
|
160
|
+
* because the user clicked its trigger) gate their focus handler on it — the
|
|
161
|
+
* `visibleOnly` behavior.
|
|
162
|
+
*
|
|
163
|
+
* The browser's own `:focus-visible` is the authority whenever the element and
|
|
164
|
+
* the engine support it: it knows about text inputs (which show a ring even
|
|
165
|
+
* after a click), programmatic focus, and platform conventions the modality
|
|
166
|
+
* heuristic cannot infer. The document-level heuristic is the fallback for
|
|
167
|
+
* engines and test environments where matching `:focus-visible` throws.
|
|
168
|
+
*/
|
|
169
|
+
function useKeyboardModality() {
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
addGlobalListeners();
|
|
172
|
+
return removeGlobalListeners;
|
|
173
|
+
}, []);
|
|
174
|
+
return useCallback((element) => {
|
|
175
|
+
if (element) try {
|
|
176
|
+
if (element.matches(":focus-visible")) return true;
|
|
177
|
+
} catch (_unused) {}
|
|
178
|
+
return hadKeyboardEvent;
|
|
179
|
+
}, []);
|
|
180
|
+
}
|
|
155
181
|
/** Returns `focusVisibleProps` to spread on a focusable element. */
|
|
156
182
|
function useFocusVisible() {
|
|
157
183
|
useEffect(() => {
|
|
@@ -168,6 +194,89 @@ function useFocusVisible() {
|
|
|
168
194
|
} };
|
|
169
195
|
}
|
|
170
196
|
//#endregion
|
|
197
|
+
//#region src/hooks/use-item-registry.ts
|
|
198
|
+
const DOCUMENT_POSITION_FOLLOWING = 4;
|
|
199
|
+
function resolveElement(entry) {
|
|
200
|
+
if (entry.element) return entry.element;
|
|
201
|
+
if (typeof document === "undefined") return null;
|
|
202
|
+
return document.getElementById(entry.id);
|
|
203
|
+
}
|
|
204
|
+
/** Insert `entry` at its document position instead of appending it. */
|
|
205
|
+
function insertByDomOrder(list, entry) {
|
|
206
|
+
const element = resolveElement(entry);
|
|
207
|
+
const lastElement = list.length > 0 ? resolveElement(list[list.length - 1]) : null;
|
|
208
|
+
if (!element || !lastElement || lastElement.compareDocumentPosition(element) & DOCUMENT_POSITION_FOLLOWING) {
|
|
209
|
+
list.push(entry);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
for (let i = 0; i < list.length; i += 1) {
|
|
213
|
+
const other = resolveElement(list[i]);
|
|
214
|
+
if (other && element.compareDocumentPosition(other) & DOCUMENT_POSITION_FOLLOWING) {
|
|
215
|
+
list.splice(i, 0, entry);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
list.push(entry);
|
|
220
|
+
}
|
|
221
|
+
/** Id of the first item that is not disabled. */
|
|
222
|
+
function firstEnabledId(items) {
|
|
223
|
+
var _items$find$id, _items$find;
|
|
224
|
+
return (_items$find$id = (_items$find = items.find((item) => !item.disabled)) === null || _items$find === void 0 ? void 0 : _items$find.id) !== null && _items$find$id !== void 0 ? _items$find$id : null;
|
|
225
|
+
}
|
|
226
|
+
/** Id of the last item that is not disabled. */
|
|
227
|
+
function lastEnabledId(items) {
|
|
228
|
+
for (let i = items.length - 1; i >= 0; i -= 1) if (!items[i].disabled) return items[i].id;
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Id `delta` enabled items away from `activeId` (disabled skipped).
|
|
233
|
+
*
|
|
234
|
+
* Clamps at the ends by default — the listbox/menu behavior. Pass
|
|
235
|
+
* `{ wrap: true }` for the WAI-ARIA tabs behavior, where the arrow keys cycle.
|
|
236
|
+
* With no active item, a forward move lands on the first enabled item and a
|
|
237
|
+
* backward move on the last.
|
|
238
|
+
*/
|
|
239
|
+
function moveActiveId(items, activeId, delta, options) {
|
|
240
|
+
const enabled = items.filter((item) => !item.disabled);
|
|
241
|
+
if (enabled.length === 0) return null;
|
|
242
|
+
const index = enabled.findIndex((item) => item.id === activeId);
|
|
243
|
+
if (index < 0) {
|
|
244
|
+
if (options === null || options === void 0 ? void 0 : options.wrap) return enabled[0].id;
|
|
245
|
+
return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
|
|
246
|
+
}
|
|
247
|
+
const count = enabled.length;
|
|
248
|
+
return enabled[(options === null || options === void 0 ? void 0 : options.wrap) ? ((index + delta) % count + count) % count : Math.min(count - 1, Math.max(0, index + delta))].id;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Id of the enabled item nearest to `index`: forward first (the item that took
|
|
252
|
+
* the removed slot), then backward. `null` when the list has none left.
|
|
253
|
+
*
|
|
254
|
+
* This is what keeps the navigation POSITION when the active item is removed.
|
|
255
|
+
*/
|
|
256
|
+
function nearestEnabledId(items, index) {
|
|
257
|
+
for (let i = Math.max(0, index); i < items.length; i += 1) if (!items[i].disabled) return items[i].id;
|
|
258
|
+
for (let i = Math.min(index, items.length) - 1; i >= 0; i -= 1) if (!items[i].disabled) return items[i].id;
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
/** Creates a document-ordered item registry. Stable across renders. */
|
|
262
|
+
function useItemRegistry() {
|
|
263
|
+
const items = useRef([]);
|
|
264
|
+
return {
|
|
265
|
+
items,
|
|
266
|
+
registerItem: useCallback((entry) => {
|
|
267
|
+
const list = items.current;
|
|
268
|
+
const existing = list.findIndex((item) => item.id === entry.id);
|
|
269
|
+
if (existing >= 0) list.splice(existing, 1);
|
|
270
|
+
insertByDomOrder(list, entry);
|
|
271
|
+
}, []),
|
|
272
|
+
unregisterItem: useCallback((id) => {
|
|
273
|
+
const index = items.current.findIndex((item) => item.id === id);
|
|
274
|
+
if (index >= 0) items.current.splice(index, 1);
|
|
275
|
+
return index;
|
|
276
|
+
}, [])
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
//#endregion
|
|
171
280
|
//#region src/hooks/use-roving-tabindex.ts
|
|
172
281
|
/**
|
|
173
282
|
* Implements roving tabindex pattern for keyboard navigation.
|
|
@@ -179,7 +288,7 @@ function useFocusVisible() {
|
|
|
179
288
|
*/
|
|
180
289
|
function useRovingTabindex(options = {}) {
|
|
181
290
|
const { orientation = "horizontal", loop = false, rtl = false, columns } = options;
|
|
182
|
-
const itemsRef =
|
|
291
|
+
const { items: itemsRef, registerItem: registerEntry, unregisterItem: removeItem } = useItemRegistry();
|
|
183
292
|
const [activeId, setActiveId] = useState(null);
|
|
184
293
|
const containerRef = useRef(null);
|
|
185
294
|
const seededRef = useRef(false);
|
|
@@ -187,14 +296,8 @@ function useRovingTabindex(options = {}) {
|
|
|
187
296
|
return itemsRef.current.filter((item) => !item.disabled);
|
|
188
297
|
}, []);
|
|
189
298
|
const register = useCallback((id, element, disabled) => {
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
if (existing >= 0) itemsRef.current[existing] = {
|
|
193
|
-
id,
|
|
194
|
-
element,
|
|
195
|
-
disabled
|
|
196
|
-
};
|
|
197
|
-
else itemsRef.current.push({
|
|
299
|
+
const activeBecameDisabled = itemsRef.current.findIndex((item) => item.id === id) >= 0 && id === activeId && !!disabled;
|
|
300
|
+
registerEntry({
|
|
198
301
|
id,
|
|
199
302
|
element,
|
|
200
303
|
disabled
|
|
@@ -203,21 +306,28 @@ function useRovingTabindex(options = {}) {
|
|
|
203
306
|
seededRef.current = true;
|
|
204
307
|
setActiveId(id);
|
|
205
308
|
} else if (activeBecameDisabled) {
|
|
206
|
-
|
|
207
|
-
const next = (_itemsRef$current$fin = (_itemsRef$current$fin2 = itemsRef.current.find((item) => !item.disabled)) === null || _itemsRef$current$fin2 === void 0 ? void 0 : _itemsRef$current$fin2.id) !== null && _itemsRef$current$fin !== void 0 ? _itemsRef$current$fin : null;
|
|
309
|
+
const next = firstEnabledId(itemsRef.current);
|
|
208
310
|
if (next === null) seededRef.current = false;
|
|
209
311
|
setActiveId(next);
|
|
210
312
|
}
|
|
211
|
-
}, [
|
|
313
|
+
}, [
|
|
314
|
+
activeId,
|
|
315
|
+
itemsRef,
|
|
316
|
+
registerEntry
|
|
317
|
+
]);
|
|
212
318
|
const unregister = useCallback((id) => {
|
|
213
|
-
|
|
319
|
+
const removedIndex = removeItem(id);
|
|
320
|
+
if (removedIndex < 0) return;
|
|
214
321
|
if (activeId === id) {
|
|
215
|
-
|
|
216
|
-
const next = (_getEnabledItems$0$id = (_getEnabledItems$ = getEnabledItems()[0]) === null || _getEnabledItems$ === void 0 ? void 0 : _getEnabledItems$.id) !== null && _getEnabledItems$0$id !== void 0 ? _getEnabledItems$0$id : null;
|
|
322
|
+
const next = nearestEnabledId(itemsRef.current, removedIndex);
|
|
217
323
|
if (next === null) seededRef.current = false;
|
|
218
324
|
setActiveId(next);
|
|
219
325
|
}
|
|
220
|
-
}, [
|
|
326
|
+
}, [
|
|
327
|
+
activeId,
|
|
328
|
+
itemsRef,
|
|
329
|
+
removeItem
|
|
330
|
+
]);
|
|
221
331
|
const moveTo = useCallback((id) => {
|
|
222
332
|
setActiveId(id);
|
|
223
333
|
const item = itemsRef.current.find((i) => i.id === id);
|
|
@@ -255,12 +365,12 @@ function useRovingTabindex(options = {}) {
|
|
|
255
365
|
moveByOffset(rtl ? 1 : -1);
|
|
256
366
|
} else if (e.key === "Home") {
|
|
257
367
|
e.preventDefault();
|
|
258
|
-
const
|
|
259
|
-
if (
|
|
368
|
+
const first = firstEnabledId(itemsRef.current);
|
|
369
|
+
if (first) moveTo(first);
|
|
260
370
|
} else if (e.key === "End") {
|
|
261
371
|
e.preventDefault();
|
|
262
|
-
const
|
|
263
|
-
if (
|
|
372
|
+
const last = lastEnabledId(itemsRef.current);
|
|
373
|
+
if (last) moveTo(last);
|
|
264
374
|
}
|
|
265
375
|
}, [
|
|
266
376
|
orientation,
|
|
@@ -417,6 +527,28 @@ function useFloating(options = {}) {
|
|
|
417
527
|
Object.assign(elements.floating.style, styles);
|
|
418
528
|
}
|
|
419
529
|
}));
|
|
530
|
+
m.push({
|
|
531
|
+
name: "optTransformOrigin",
|
|
532
|
+
fn(state) {
|
|
533
|
+
var _ref2, _middlewareData$shift, _middlewareData$shift2;
|
|
534
|
+
const { elements, middlewareData, placement: resolved, rects } = state;
|
|
535
|
+
const [resolvedSide, resolvedAlign] = resolved.split("-");
|
|
536
|
+
const isVertical = resolvedSide === "top" || resolvedSide === "bottom";
|
|
537
|
+
const so = sideOffsetRef.current;
|
|
538
|
+
const sideOffsetValue = (_ref2 = typeof so === "function" ? so({
|
|
539
|
+
rects,
|
|
540
|
+
placement: resolved
|
|
541
|
+
}) : so) !== null && _ref2 !== void 0 ? _ref2 : 0;
|
|
542
|
+
const shiftAmount = isVertical ? ((_middlewareData$shift = middlewareData.shift) === null || _middlewareData$shift === void 0 ? void 0 : _middlewareData$shift.x) || 0 : ((_middlewareData$shift2 = middlewareData.shift) === null || _middlewareData$shift2 === void 0 ? void 0 : _middlewareData$shift2.y) || 0;
|
|
543
|
+
let crossOrigin;
|
|
544
|
+
if (!resolvedAlign) crossOrigin = "50%";
|
|
545
|
+
else if (Math.abs(shiftAmount) <= 1) crossOrigin = resolvedAlign === "start" ? "0%" : "100%";
|
|
546
|
+
else crossOrigin = isVertical ? `${rects.reference.x + rects.reference.width / 2 - state.x}px` : `${rects.reference.y + rects.reference.height / 2 - state.y}px`;
|
|
547
|
+
const sideOrigin = resolvedSide === "top" || resolvedSide === "left" ? `calc(100% + ${sideOffsetValue}px)` : `${-sideOffsetValue}px`;
|
|
548
|
+
elements.floating.style.setProperty("--opt-transform-origin", isVertical ? `${crossOrigin} ${sideOrigin}` : `${sideOrigin} ${crossOrigin}`);
|
|
549
|
+
return {};
|
|
550
|
+
}
|
|
551
|
+
});
|
|
420
552
|
m.push(hide({ padding: overflowPadding }));
|
|
421
553
|
return m;
|
|
422
554
|
}, [
|
|
@@ -471,7 +603,8 @@ function useFloating(options = {}) {
|
|
|
471
603
|
ref: floating.refs.setFloating,
|
|
472
604
|
style: _objectSpread2(_objectSpread2({
|
|
473
605
|
"--opt-available-width": "100vw",
|
|
474
|
-
"--opt-available-height": "100vh"
|
|
606
|
+
"--opt-available-height": "100vh",
|
|
607
|
+
"--opt-transform-origin": "center"
|
|
475
608
|
}, floating.floatingStyles), isPositioned ? null : { opacity: 0 })
|
|
476
609
|
}),
|
|
477
610
|
/**
|
|
@@ -541,6 +674,137 @@ function useScrollActiveDescendantIntoView(activeId) {
|
|
|
541
674
|
}, [activeId]);
|
|
542
675
|
}
|
|
543
676
|
//#endregion
|
|
677
|
+
//#region src/hooks/use-hidden-until-found.ts
|
|
678
|
+
/**
|
|
679
|
+
* Keeps collapsed content reachable by browser find-in-page.
|
|
680
|
+
*
|
|
681
|
+
* The content stays MOUNTED and toggles `hidden="until-found"` instead of
|
|
682
|
+
* unmounting, so Chromium can match text inside it; when it does, the
|
|
683
|
+
* `beforematch` event fires and `onReveal` opens the owning disclosure so the
|
|
684
|
+
* component state stays consistent with what the browser just revealed.
|
|
685
|
+
*
|
|
686
|
+
* React coerces the `hidden` prop to a boolean attribute, so the "until-found"
|
|
687
|
+
* string has to be written imperatively — hence the ref rather than a prop.
|
|
688
|
+
*
|
|
689
|
+
* Progressive enhancement: browsers without `hidden="until-found"` treat it as
|
|
690
|
+
* plain `hidden`, which is the correct fallback.
|
|
691
|
+
*/
|
|
692
|
+
function useHiddenUntilFound(ref, { enabled, open, onReveal }) {
|
|
693
|
+
useEffect(() => {
|
|
694
|
+
const el = ref.current;
|
|
695
|
+
if (!el || !enabled) return;
|
|
696
|
+
const handleBeforeMatch = () => onReveal();
|
|
697
|
+
el.addEventListener("beforematch", handleBeforeMatch);
|
|
698
|
+
return () => el.removeEventListener("beforematch", handleBeforeMatch);
|
|
699
|
+
}, [
|
|
700
|
+
ref,
|
|
701
|
+
enabled,
|
|
702
|
+
onReveal
|
|
703
|
+
]);
|
|
704
|
+
useEffect(() => {
|
|
705
|
+
const el = ref.current;
|
|
706
|
+
if (!el || !enabled) return;
|
|
707
|
+
if (open) el.removeAttribute("hidden");
|
|
708
|
+
else el.setAttribute("hidden", "until-found");
|
|
709
|
+
}, [
|
|
710
|
+
ref,
|
|
711
|
+
enabled,
|
|
712
|
+
open
|
|
713
|
+
]);
|
|
714
|
+
}
|
|
715
|
+
//#endregion
|
|
716
|
+
//#region src/internal/merge-props.ts
|
|
717
|
+
const EVENT_HANDLER = /^on[A-Z]/;
|
|
718
|
+
function isSyntheticEvent(value) {
|
|
719
|
+
return typeof value === "object" && value !== null && "nativeEvent" in value;
|
|
720
|
+
}
|
|
721
|
+
function makePreventable(event) {
|
|
722
|
+
if (typeof event.preventOptHandler === "function") return;
|
|
723
|
+
event.optHandlerPrevented = false;
|
|
724
|
+
event.preventOptHandler = () => {
|
|
725
|
+
event.optHandlerPrevented = true;
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
function chainHandlers(a, b) {
|
|
729
|
+
return (...args) => {
|
|
730
|
+
const event = args[0];
|
|
731
|
+
if (isSyntheticEvent(event)) {
|
|
732
|
+
makePreventable(event);
|
|
733
|
+
a(...args);
|
|
734
|
+
if (event.optHandlerPrevented) return void 0;
|
|
735
|
+
return b(...args);
|
|
736
|
+
}
|
|
737
|
+
a(...args);
|
|
738
|
+
return b(...args);
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
/** Merge prop objects left→right with handler/className/style composition. */
|
|
742
|
+
function mergeProps(...parts) {
|
|
743
|
+
const result = {};
|
|
744
|
+
for (const part of parts) {
|
|
745
|
+
if (!part) continue;
|
|
746
|
+
for (const key in part) {
|
|
747
|
+
if (!Object.prototype.hasOwnProperty.call(part, key)) continue;
|
|
748
|
+
const value = part[key];
|
|
749
|
+
const existing = result[key];
|
|
750
|
+
if (EVENT_HANDLER.test(key)) {
|
|
751
|
+
if (typeof value === "function" && typeof existing === "function") result[key] = chainHandlers(existing, value);
|
|
752
|
+
else if (value === void 0 && typeof existing === "function") continue;
|
|
753
|
+
else result[key] = value;
|
|
754
|
+
} else if (key === "className") result[key] = [existing, value].filter(Boolean).join(" ") || void 0;
|
|
755
|
+
else if (key === "style" && existing && typeof existing === "object" && value && typeof value === "object") result[key] = _objectSpread2(_objectSpread2({}, existing), value);
|
|
756
|
+
else result[key] = value;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
return result;
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Merge multiple refs (callback or object) into one callback ref.
|
|
763
|
+
*
|
|
764
|
+
* Returns a React 19 ref CLEANUP function, so every merged ref is detached at
|
|
765
|
+
* exactly the right time: callback refs that themselves return a cleanup have
|
|
766
|
+
* it invoked (previously the returned cleanup was dropped on the floor, leaking
|
|
767
|
+
* whatever it was meant to release), and the rest are detached by being called
|
|
768
|
+
* with `null` / having their `.current` reset. Cleanups run in reverse
|
|
769
|
+
* attachment order, mirroring React's own teardown order.
|
|
770
|
+
*/
|
|
771
|
+
function mergeRefs(...refs) {
|
|
772
|
+
return (value) => {
|
|
773
|
+
const cleanups = [];
|
|
774
|
+
for (const ref of refs) if (typeof ref === "function") {
|
|
775
|
+
const cleanup = ref(value);
|
|
776
|
+
cleanups.push(typeof cleanup === "function" ? cleanup : () => ref(null));
|
|
777
|
+
} else if (ref != null) {
|
|
778
|
+
const objectRef = ref;
|
|
779
|
+
objectRef.current = value;
|
|
780
|
+
cleanups.push(() => {
|
|
781
|
+
objectRef.current = null;
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
return () => {
|
|
785
|
+
for (let i = cleanups.length - 1; i >= 0; i -= 1) cleanups[i]();
|
|
786
|
+
};
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
//#endregion
|
|
790
|
+
//#region src/hooks/use-merged-ref.ts
|
|
791
|
+
/**
|
|
792
|
+
* A STABLE merged ref callback.
|
|
793
|
+
*
|
|
794
|
+
* `mergeRefs` returns a fresh function on every call, and React re-attaches a
|
|
795
|
+
* callback ref whenever its identity changes: it detaches first (nulling every
|
|
796
|
+
* ref in the chain), then attaches again. Building the merged ref inline during
|
|
797
|
+
* render therefore made every render null out the element the animation and
|
|
798
|
+
* measurement code reads — which is how the collapsible content on the explore
|
|
799
|
+
* detail pages stopped opening.
|
|
800
|
+
*
|
|
801
|
+
* Memoizing on the ref identities keeps the callback stable across renders, so
|
|
802
|
+
* the refs are attached exactly once.
|
|
803
|
+
*/
|
|
804
|
+
function useMergedRef(...refs) {
|
|
805
|
+
return useMemo(() => mergeRefs(...refs), refs);
|
|
806
|
+
}
|
|
807
|
+
//#endregion
|
|
544
808
|
//#region \0@oxc-project+runtime@0.146.0/helpers/esm/objectWithoutPropertiesLoose.js
|
|
545
809
|
function _objectWithoutPropertiesLoose(r, e) {
|
|
546
810
|
if (null == r) return {};
|
|
@@ -615,24 +879,14 @@ function DisclosureContent(_ref2) {
|
|
|
615
879
|
const { open, setOpen, contentId, triggerId, animated } = useDisclosureContext();
|
|
616
880
|
const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated: animated && !hiddenUntilFound });
|
|
617
881
|
const innerRef = useRef(null);
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
const onBeforeMatch = () => setOpen(true);
|
|
625
|
-
el.addEventListener("beforematch", onBeforeMatch);
|
|
626
|
-
return () => el.removeEventListener("beforematch", onBeforeMatch);
|
|
627
|
-
}, [hiddenUntilFound, setOpen]);
|
|
628
|
-
useEffect(() => {
|
|
629
|
-
const el = innerRef.current;
|
|
630
|
-
if (!el || !hiddenUntilFound) return;
|
|
631
|
-
if (open) el.removeAttribute("hidden");
|
|
632
|
-
else el.setAttribute("hidden", "until-found");
|
|
633
|
-
}, [open, hiddenUntilFound]);
|
|
882
|
+
const contentRef = useMergedRef(innerRef, ref);
|
|
883
|
+
useHiddenUntilFound(innerRef, {
|
|
884
|
+
enabled: hiddenUntilFound,
|
|
885
|
+
open,
|
|
886
|
+
onReveal: useCallback(() => setOpen(true), [setOpen])
|
|
887
|
+
});
|
|
634
888
|
if (hiddenUntilFound) return /* @__PURE__ */ jsx("div", _objectSpread2({
|
|
635
|
-
ref:
|
|
889
|
+
ref: contentRef,
|
|
636
890
|
id: contentId,
|
|
637
891
|
role: "region",
|
|
638
892
|
"aria-labelledby": triggerId,
|
|
@@ -641,7 +895,7 @@ function DisclosureContent(_ref2) {
|
|
|
641
895
|
}, props));
|
|
642
896
|
if (!mounted) return null;
|
|
643
897
|
return /* @__PURE__ */ jsx("div", _objectSpread2(_objectSpread2({
|
|
644
|
-
ref:
|
|
898
|
+
ref: contentRef,
|
|
645
899
|
id: contentId,
|
|
646
900
|
role: "region",
|
|
647
901
|
"aria-labelledby": triggerId,
|
|
@@ -787,12 +1041,7 @@ const DialogPanel = forwardRef((_ref2, forwardedRef) => {
|
|
|
787
1041
|
lastFocusedRef.current = null;
|
|
788
1042
|
}
|
|
789
1043
|
}, [mounted]);
|
|
790
|
-
const mergedRef =
|
|
791
|
-
dialogRef.current = node;
|
|
792
|
-
enterLeaveRef.current = node;
|
|
793
|
-
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
794
|
-
else if (forwardedRef) forwardedRef.current = node;
|
|
795
|
-
}, [
|
|
1044
|
+
const mergedRef = useMemo(() => mergeRefs(dialogRef, enterLeaveRef, forwardedRef), [
|
|
796
1045
|
dialogRef,
|
|
797
1046
|
enterLeaveRef,
|
|
798
1047
|
forwardedRef
|
|
@@ -809,7 +1058,8 @@ const DialogPanel = forwardRef((_ref2, forwardedRef) => {
|
|
|
809
1058
|
}, [
|
|
810
1059
|
dialogRef,
|
|
811
1060
|
setOpen,
|
|
812
|
-
dismissOnEscape
|
|
1061
|
+
dismissOnEscape,
|
|
1062
|
+
mounted
|
|
813
1063
|
]);
|
|
814
1064
|
const handleClick = useCallback((e) => {
|
|
815
1065
|
if (dismissOnBackdrop && e.target === e.currentTarget) setOpen(false);
|
|
@@ -874,13 +1124,9 @@ const _excluded2$12 = [
|
|
|
874
1124
|
"onClick"
|
|
875
1125
|
];
|
|
876
1126
|
const _excluded3$9 = ["tabId"];
|
|
1127
|
+
/** WAI-ARIA tabs wrap at both ends, unlike a listbox/menu (which clamps). */
|
|
877
1128
|
function nextEnabledTabId(tabs, currentId, delta) {
|
|
878
|
-
|
|
879
|
-
if (enabled.length === 0) return null;
|
|
880
|
-
const idx = enabled.findIndex((t) => t.id === currentId);
|
|
881
|
-
if (idx < 0) return enabled[0].id;
|
|
882
|
-
const n = enabled.length;
|
|
883
|
-
return enabled[((idx + delta) % n + n) % n].id;
|
|
1129
|
+
return moveActiveId(tabs, currentId, delta, { wrap: true });
|
|
884
1130
|
}
|
|
885
1131
|
const TabsContext = createContext(null);
|
|
886
1132
|
function useTabsContext() {
|
|
@@ -892,37 +1138,54 @@ function useTabsContext() {
|
|
|
892
1138
|
function TabsRoot({ children, selectedId: controlledId, defaultSelectedId = "", onSelectedIdChange, setSelectedId: setSelectedIdDeprecated, orientation = "horizontal" }) {
|
|
893
1139
|
const [selectedId, setSelectedId] = useControllableState(defaultSelectedId, controlledId, onSelectedIdChange !== null && onSelectedIdChange !== void 0 ? onSelectedIdChange : setSelectedIdDeprecated);
|
|
894
1140
|
const baseId = useId();
|
|
895
|
-
const tabs =
|
|
896
|
-
const
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
}, []);
|
|
1141
|
+
const { items: tabs, registerItem, unregisterItem } = useItemRegistry();
|
|
1142
|
+
const selectedIdRef = useRef(selectedId);
|
|
1143
|
+
selectedIdRef.current = selectedId;
|
|
1144
|
+
const isControlled = controlledId !== void 0;
|
|
1145
|
+
const isControlledRef = useRef(isControlled);
|
|
1146
|
+
isControlledRef.current = isControlled;
|
|
1147
|
+
const setSelectedIdRef = useRef(setSelectedId);
|
|
1148
|
+
setSelectedIdRef.current = setSelectedId;
|
|
1149
|
+
const registerTab = useCallback((id, disabled) => registerItem({
|
|
1150
|
+
id,
|
|
1151
|
+
disabled
|
|
1152
|
+
}), [registerItem]);
|
|
907
1153
|
const unregisterTab = useCallback((id) => {
|
|
908
|
-
|
|
909
|
-
|
|
1154
|
+
const removedIndex = unregisterItem(id);
|
|
1155
|
+
if (selectedIdRef.current !== id) return;
|
|
1156
|
+
if (isControlledRef.current) return;
|
|
1157
|
+
const next = nearestEnabledId(tabs.current, removedIndex);
|
|
1158
|
+
if (next) setSelectedIdRef.current(next);
|
|
1159
|
+
}, [tabs, unregisterItem]);
|
|
910
1160
|
useLayoutEffect(() => {
|
|
911
1161
|
if (!selectedId) {
|
|
912
|
-
const first = tabs.current
|
|
913
|
-
if (first) setSelectedId(first
|
|
1162
|
+
const first = firstEnabledId(tabs.current);
|
|
1163
|
+
if (first) setSelectedId(first);
|
|
914
1164
|
}
|
|
915
|
-
}, [
|
|
1165
|
+
}, [
|
|
1166
|
+
selectedId,
|
|
1167
|
+
setSelectedId,
|
|
1168
|
+
tabs
|
|
1169
|
+
]);
|
|
1170
|
+
const contextValue = useMemo(() => ({
|
|
1171
|
+
selectedId,
|
|
1172
|
+
setSelectedId,
|
|
1173
|
+
baseId,
|
|
1174
|
+
orientation,
|
|
1175
|
+
registerTab,
|
|
1176
|
+
unregisterTab,
|
|
1177
|
+
tabs
|
|
1178
|
+
}), [
|
|
1179
|
+
selectedId,
|
|
1180
|
+
setSelectedId,
|
|
1181
|
+
baseId,
|
|
1182
|
+
orientation,
|
|
1183
|
+
registerTab,
|
|
1184
|
+
unregisterTab,
|
|
1185
|
+
tabs
|
|
1186
|
+
]);
|
|
916
1187
|
return /* @__PURE__ */ jsx(TabsContext.Provider, {
|
|
917
|
-
value:
|
|
918
|
-
selectedId,
|
|
919
|
-
setSelectedId,
|
|
920
|
-
baseId,
|
|
921
|
-
orientation,
|
|
922
|
-
registerTab,
|
|
923
|
-
unregisterTab,
|
|
924
|
-
tabs
|
|
925
|
-
},
|
|
1188
|
+
value: contextValue,
|
|
926
1189
|
children
|
|
927
1190
|
});
|
|
928
1191
|
}
|
|
@@ -1084,39 +1347,6 @@ const Radio = forwardRef((_ref2, ref) => {
|
|
|
1084
1347
|
});
|
|
1085
1348
|
Radio.displayName = "Radio";
|
|
1086
1349
|
//#endregion
|
|
1087
|
-
//#region src/internal/merge-props.ts
|
|
1088
|
-
const EVENT_HANDLER = /^on[A-Z]/;
|
|
1089
|
-
/** Merge prop objects left→right with handler/className/style composition. */
|
|
1090
|
-
function mergeProps(...parts) {
|
|
1091
|
-
const result = {};
|
|
1092
|
-
for (const part of parts) {
|
|
1093
|
-
if (!part) continue;
|
|
1094
|
-
for (const key in part) {
|
|
1095
|
-
if (!Object.prototype.hasOwnProperty.call(part, key)) continue;
|
|
1096
|
-
const value = part[key];
|
|
1097
|
-
const existing = result[key];
|
|
1098
|
-
if (EVENT_HANDLER.test(key) && typeof value === "function" && typeof existing === "function") {
|
|
1099
|
-
const a = existing;
|
|
1100
|
-
const b = value;
|
|
1101
|
-
result[key] = (...args) => {
|
|
1102
|
-
a(...args);
|
|
1103
|
-
return b(...args);
|
|
1104
|
-
};
|
|
1105
|
-
} else if (key === "className") result[key] = [existing, value].filter(Boolean).join(" ") || void 0;
|
|
1106
|
-
else if (key === "style" && existing && typeof existing === "object" && value && typeof value === "object") result[key] = _objectSpread2(_objectSpread2({}, existing), value);
|
|
1107
|
-
else result[key] = value;
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
return result;
|
|
1111
|
-
}
|
|
1112
|
-
/** Merge multiple refs (callback or object) into one callback ref. */
|
|
1113
|
-
function mergeRefs(...refs) {
|
|
1114
|
-
return (value) => {
|
|
1115
|
-
for (const ref of refs) if (typeof ref === "function") ref(value);
|
|
1116
|
-
else if (ref != null) ref.current = value;
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
//#endregion
|
|
1120
1350
|
//#region src/internal/overlay-portal.tsx
|
|
1121
1351
|
/**
|
|
1122
1352
|
* Conditionally portals overlay content. When `portal` is false, children render
|
|
@@ -1142,6 +1372,32 @@ function OverlayPortal({ portal, portalRoot, children }) {
|
|
|
1142
1372
|
});
|
|
1143
1373
|
}
|
|
1144
1374
|
//#endregion
|
|
1375
|
+
//#region src/internal/render-element.tsx
|
|
1376
|
+
/**
|
|
1377
|
+
* Renders one part of a primitive: merges prop objects, merges refs, and
|
|
1378
|
+
* honors a `render` prop.
|
|
1379
|
+
*
|
|
1380
|
+
* A plain function, not a hook, so parts can call it after an early return
|
|
1381
|
+
* (`if (!mounted) return null`) — which most overlay panels do.
|
|
1382
|
+
*
|
|
1383
|
+
* Every part used to hand-roll this — an inline `ref={(node) => {...}}` that
|
|
1384
|
+
* poked one ref object and then type-checked a floating-ui callback ref, plus
|
|
1385
|
+
* an effect copying an element into the enter/leave ref. Eight copies of the
|
|
1386
|
+
* same wiring meant a fix (React 19 ref cleanup, say) had to be applied eight
|
|
1387
|
+
* times, and only `Composite` ever supported `render`. Routing parts through
|
|
1388
|
+
* here fixes all of them at once and makes `render` universal.
|
|
1389
|
+
*/
|
|
1390
|
+
function renderElement(tag, { render, refs, props }) {
|
|
1391
|
+
const mergedProps = mergeProps(...props !== null && props !== void 0 ? props : []);
|
|
1392
|
+
const mergedRef = mergeRefs(...refs !== null && refs !== void 0 ? refs : []);
|
|
1393
|
+
if (typeof render === "function") return render(_objectSpread2(_objectSpread2({}, mergedProps), {}, { ref: mergedRef }));
|
|
1394
|
+
if (render && isValidElement(render)) {
|
|
1395
|
+
const renderProps = render.props;
|
|
1396
|
+
return cloneElement(render, _objectSpread2(_objectSpread2({}, mergeProps(renderProps, mergedProps)), {}, { ref: mergeRefs(renderProps.ref, mergedRef) }));
|
|
1397
|
+
}
|
|
1398
|
+
return createElement(tag, _objectSpread2(_objectSpread2({}, mergedProps), {}, { ref: mergedRef }));
|
|
1399
|
+
}
|
|
1400
|
+
//#endregion
|
|
1145
1401
|
//#region src/primitives/tooltip.tsx
|
|
1146
1402
|
const _excluded$15 = [
|
|
1147
1403
|
"children",
|
|
@@ -1152,7 +1408,8 @@ const _excluded2$10 = ["ref", "aria-describedby"];
|
|
|
1152
1408
|
const _excluded3$8 = [
|
|
1153
1409
|
"children",
|
|
1154
1410
|
"onMouseEnter",
|
|
1155
|
-
"onMouseLeave"
|
|
1411
|
+
"onMouseLeave",
|
|
1412
|
+
"render"
|
|
1156
1413
|
];
|
|
1157
1414
|
function mergeAriaDescribedBy(...values) {
|
|
1158
1415
|
const ids = values.flatMap((value) => typeof value === "string" ? value.trim().split(/\s+/) : []);
|
|
@@ -1162,53 +1419,98 @@ function mergeAriaDescribedBy(...values) {
|
|
|
1162
1419
|
const TooltipContext = createContext(null);
|
|
1163
1420
|
function useTooltipContext() {
|
|
1164
1421
|
const ctx = useContext(TooltipContext);
|
|
1165
|
-
if (!ctx) throw new Error("Tooltip components must be used within
|
|
1422
|
+
if (!ctx) throw new Error("Tooltip components must be used within TooltipRoot");
|
|
1166
1423
|
return ctx;
|
|
1167
1424
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1425
|
+
const TooltipGroupContext = createContext(null);
|
|
1426
|
+
/**
|
|
1427
|
+
* Groups sibling tooltips so moving between them does not re-pay the show
|
|
1428
|
+
* delay — the APG/desktop convention for toolbars and icon rows, where waiting
|
|
1429
|
+
* 700ms per button makes the row feel broken.
|
|
1430
|
+
*
|
|
1431
|
+
* Optional: a `TooltipProvider` outside any group keeps its own delay.
|
|
1432
|
+
*/
|
|
1433
|
+
function TooltipGroup({ children, skipDelay = 300 }) {
|
|
1434
|
+
const warmUntilRef = useRef(0);
|
|
1435
|
+
const cooldownRef = useRef(void 0);
|
|
1436
|
+
const value = useMemo(() => ({
|
|
1437
|
+
isWarm: () => skipDelay > 0 && Date.now() < warmUntilRef.current,
|
|
1438
|
+
onOpen: () => {
|
|
1439
|
+
clearTimeout(cooldownRef.current);
|
|
1440
|
+
warmUntilRef.current = 0;
|
|
1441
|
+
},
|
|
1442
|
+
onClose: () => {
|
|
1443
|
+
if (skipDelay <= 0) return;
|
|
1444
|
+
warmUntilRef.current = Date.now() + skipDelay;
|
|
1445
|
+
clearTimeout(cooldownRef.current);
|
|
1446
|
+
cooldownRef.current = setTimeout(() => {
|
|
1447
|
+
warmUntilRef.current = 0;
|
|
1448
|
+
}, skipDelay);
|
|
1449
|
+
}
|
|
1450
|
+
}), [skipDelay]);
|
|
1451
|
+
useEffect(() => () => clearTimeout(cooldownRef.current), []);
|
|
1452
|
+
return /* @__PURE__ */ jsx(TooltipGroupContext.Provider, {
|
|
1453
|
+
value,
|
|
1454
|
+
children
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* Owns ONE tooltip: its open state, delays, placement and portal.
|
|
1459
|
+
*
|
|
1460
|
+
* Wrap several of these in a {@link TooltipGroup} to share a skip-delay window.
|
|
1461
|
+
*/
|
|
1462
|
+
function TooltipRoot({ children, timeout, showTimeout = 700, hideTimeout = 300, placement = "top", animated = true, portal = false, portalRoot = null }) {
|
|
1170
1463
|
const [open, setOpen] = useState(false);
|
|
1171
1464
|
const tooltipId = useId();
|
|
1172
1465
|
const showDelay = timeout !== null && timeout !== void 0 ? timeout : showTimeout;
|
|
1173
1466
|
const showTimerRef = useRef(void 0);
|
|
1174
1467
|
const hideTimerRef = useRef(void 0);
|
|
1468
|
+
const group = useContext(TooltipGroupContext);
|
|
1469
|
+
const isKeyboardModality = useKeyboardModality();
|
|
1470
|
+
const clearTimers = useCallback(() => {
|
|
1471
|
+
clearTimeout(showTimerRef.current);
|
|
1472
|
+
clearTimeout(hideTimerRef.current);
|
|
1473
|
+
}, []);
|
|
1175
1474
|
const { getReferenceProps: getFloatRefProps, getFloatingProps } = useFloating({
|
|
1176
1475
|
placement,
|
|
1177
1476
|
gutter: 8,
|
|
1178
|
-
open
|
|
1477
|
+
open,
|
|
1478
|
+
onOpenChange: useCallback((next) => {
|
|
1479
|
+
if (next) return;
|
|
1480
|
+
clearTimers();
|
|
1481
|
+
setOpen(false);
|
|
1482
|
+
}, [clearTimers]),
|
|
1483
|
+
dismiss: {
|
|
1484
|
+
escapeKey: true,
|
|
1485
|
+
outsidePress: false
|
|
1486
|
+
}
|
|
1179
1487
|
});
|
|
1180
1488
|
const show = useCallback(() => {
|
|
1181
1489
|
clearTimeout(hideTimerRef.current);
|
|
1182
|
-
|
|
1183
|
-
|
|
1490
|
+
const delay = (group === null || group === void 0 ? void 0 : group.isWarm()) ? 0 : showDelay;
|
|
1491
|
+
showTimerRef.current = setTimeout(() => {
|
|
1492
|
+
group === null || group === void 0 || group.onOpen();
|
|
1493
|
+
setOpen(true);
|
|
1494
|
+
}, delay);
|
|
1495
|
+
}, [showDelay, group]);
|
|
1184
1496
|
const hide = useCallback(() => {
|
|
1185
1497
|
clearTimeout(showTimerRef.current);
|
|
1186
|
-
hideTimerRef.current = setTimeout(() =>
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
useEffect(() => {
|
|
1195
|
-
if (!open) return;
|
|
1196
|
-
const handler = (e) => {
|
|
1197
|
-
if (e.key === "Escape") {
|
|
1198
|
-
clearTimeout(showTimerRef.current);
|
|
1199
|
-
clearTimeout(hideTimerRef.current);
|
|
1200
|
-
setOpen(false);
|
|
1201
|
-
}
|
|
1202
|
-
};
|
|
1203
|
-
document.addEventListener("keydown", handler);
|
|
1204
|
-
return () => document.removeEventListener("keydown", handler);
|
|
1205
|
-
}, [open]);
|
|
1498
|
+
hideTimerRef.current = setTimeout(() => {
|
|
1499
|
+
setOpen((wasOpen) => {
|
|
1500
|
+
if (wasOpen) group === null || group === void 0 || group.onClose();
|
|
1501
|
+
return false;
|
|
1502
|
+
});
|
|
1503
|
+
}, hideTimeout);
|
|
1504
|
+
}, [hideTimeout, group]);
|
|
1505
|
+
useEffect(() => clearTimers, [clearTimers]);
|
|
1206
1506
|
const getReferenceProps = useCallback(() => {
|
|
1207
1507
|
return _objectSpread2(_objectSpread2({}, getFloatRefProps()), {}, {
|
|
1208
1508
|
"aria-describedby": open ? tooltipId : void 0,
|
|
1209
1509
|
onMouseEnter: show,
|
|
1210
1510
|
onMouseLeave: hide,
|
|
1211
|
-
onFocus:
|
|
1511
|
+
onFocus: (event) => {
|
|
1512
|
+
if (isKeyboardModality(event.currentTarget)) show();
|
|
1513
|
+
},
|
|
1212
1514
|
onBlur: hide
|
|
1213
1515
|
});
|
|
1214
1516
|
}, [
|
|
@@ -1216,24 +1518,46 @@ function TooltipProvider({ children, timeout, showTimeout = 700, hideTimeout = 3
|
|
|
1216
1518
|
open,
|
|
1217
1519
|
tooltipId,
|
|
1218
1520
|
show,
|
|
1219
|
-
hide
|
|
1521
|
+
hide,
|
|
1522
|
+
isKeyboardModality
|
|
1523
|
+
]);
|
|
1524
|
+
const contextValue = useMemo(() => ({
|
|
1525
|
+
open,
|
|
1526
|
+
setOpen,
|
|
1527
|
+
tooltipId,
|
|
1528
|
+
show,
|
|
1529
|
+
hide,
|
|
1530
|
+
animated,
|
|
1531
|
+
portal,
|
|
1532
|
+
portalRoot,
|
|
1533
|
+
getReferenceProps,
|
|
1534
|
+
getFloatingProps
|
|
1535
|
+
}), [
|
|
1536
|
+
open,
|
|
1537
|
+
setOpen,
|
|
1538
|
+
tooltipId,
|
|
1539
|
+
show,
|
|
1540
|
+
hide,
|
|
1541
|
+
animated,
|
|
1542
|
+
portal,
|
|
1543
|
+
portalRoot,
|
|
1544
|
+
getReferenceProps,
|
|
1545
|
+
getFloatingProps
|
|
1220
1546
|
]);
|
|
1221
1547
|
return /* @__PURE__ */ jsx(TooltipContext.Provider, {
|
|
1222
|
-
value:
|
|
1223
|
-
open,
|
|
1224
|
-
setOpen,
|
|
1225
|
-
tooltipId,
|
|
1226
|
-
show,
|
|
1227
|
-
hide,
|
|
1228
|
-
animated,
|
|
1229
|
-
portal,
|
|
1230
|
-
portalRoot,
|
|
1231
|
-
getReferenceProps,
|
|
1232
|
-
getFloatingProps
|
|
1233
|
-
},
|
|
1548
|
+
value: contextValue,
|
|
1234
1549
|
children
|
|
1235
1550
|
});
|
|
1236
1551
|
}
|
|
1552
|
+
/**
|
|
1553
|
+
* A single tooltip.
|
|
1554
|
+
*
|
|
1555
|
+
* @deprecated Renamed to {@link TooltipRoot}. Despite the name this component
|
|
1556
|
+
* never provided anything to a subtree of tooltips — it IS one tooltip. The
|
|
1557
|
+
* delay-sharing provider is {@link TooltipGroup}. Kept as an alias for
|
|
1558
|
+
* back-compat; scheduled for removal in the next major.
|
|
1559
|
+
*/
|
|
1560
|
+
const TooltipProvider = TooltipRoot;
|
|
1237
1561
|
const TooltipAnchor = forwardRef((_ref, ref) => {
|
|
1238
1562
|
let { children, render, "aria-describedby": ariaDescribedBy } = _ref, props = _objectWithoutProperties(_ref, _excluded$15);
|
|
1239
1563
|
const { getReferenceProps } = useTooltipContext();
|
|
@@ -1256,28 +1580,32 @@ const TooltipAnchor = forwardRef((_ref, ref) => {
|
|
|
1256
1580
|
TooltipAnchor.displayName = "TooltipAnchor";
|
|
1257
1581
|
/** Renders the `Tooltip` component. */
|
|
1258
1582
|
function Tooltip(_ref3) {
|
|
1259
|
-
let { children, onMouseEnter, onMouseLeave } = _ref3, props = _objectWithoutProperties(_ref3, _excluded3$8);
|
|
1583
|
+
let { children, onMouseEnter, onMouseLeave, render } = _ref3, props = _objectWithoutProperties(_ref3, _excluded3$8);
|
|
1260
1584
|
const { open, tooltipId, show, hide, animated, portal, portalRoot, getFloatingProps } = useTooltipContext();
|
|
1261
1585
|
const { mounted, dataAttributes, ref } = useEnterLeave(open, { animated });
|
|
1262
1586
|
const floatingProps = getFloatingProps();
|
|
1587
|
+
const panelRef = useMergedRef(ref, floatingProps.ref);
|
|
1263
1588
|
if (!mounted) return null;
|
|
1264
|
-
const node =
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1589
|
+
const node = renderElement("div", {
|
|
1590
|
+
render,
|
|
1591
|
+
refs: [panelRef],
|
|
1592
|
+
props: [
|
|
1593
|
+
{
|
|
1594
|
+
id: tooltipId,
|
|
1595
|
+
role: "tooltip",
|
|
1596
|
+
style: floatingProps.style,
|
|
1597
|
+
onMouseEnter: show,
|
|
1598
|
+
onMouseLeave: hide
|
|
1599
|
+
},
|
|
1600
|
+
dataAttributes,
|
|
1601
|
+
{
|
|
1602
|
+
onMouseEnter,
|
|
1603
|
+
onMouseLeave
|
|
1604
|
+
},
|
|
1605
|
+
props,
|
|
1606
|
+
{ children }
|
|
1607
|
+
]
|
|
1608
|
+
});
|
|
1281
1609
|
return /* @__PURE__ */ jsx(OverlayPortal, {
|
|
1282
1610
|
portal,
|
|
1283
1611
|
portalRoot,
|
|
@@ -1287,7 +1615,7 @@ function Tooltip(_ref3) {
|
|
|
1287
1615
|
//#endregion
|
|
1288
1616
|
//#region src/primitives/popover.tsx
|
|
1289
1617
|
const _excluded$14 = ["onClick"];
|
|
1290
|
-
const _excluded2$9 = ["children"];
|
|
1618
|
+
const _excluded2$9 = ["children", "render"];
|
|
1291
1619
|
const _excluded3$7 = ["onClick"];
|
|
1292
1620
|
const PopoverContext = createContext(null);
|
|
1293
1621
|
function usePopoverContext() {
|
|
@@ -1306,20 +1634,33 @@ function PopoverRoot({ children, open: controlledOpen, defaultOpen = false, onOp
|
|
|
1306
1634
|
onOpenChange: setOpen,
|
|
1307
1635
|
dismiss: true
|
|
1308
1636
|
});
|
|
1637
|
+
const contextValue = useMemo(() => ({
|
|
1638
|
+
open,
|
|
1639
|
+
setOpen,
|
|
1640
|
+
popoverId,
|
|
1641
|
+
manageFocus,
|
|
1642
|
+
animated,
|
|
1643
|
+
portal,
|
|
1644
|
+
portalRoot,
|
|
1645
|
+
getReferenceProps,
|
|
1646
|
+
getFloatingProps,
|
|
1647
|
+
getPositionerStateProps,
|
|
1648
|
+
context
|
|
1649
|
+
}), [
|
|
1650
|
+
open,
|
|
1651
|
+
setOpen,
|
|
1652
|
+
popoverId,
|
|
1653
|
+
manageFocus,
|
|
1654
|
+
animated,
|
|
1655
|
+
portal,
|
|
1656
|
+
portalRoot,
|
|
1657
|
+
getReferenceProps,
|
|
1658
|
+
getFloatingProps,
|
|
1659
|
+
getPositionerStateProps,
|
|
1660
|
+
context
|
|
1661
|
+
]);
|
|
1309
1662
|
return /* @__PURE__ */ jsx(PopoverContext.Provider, {
|
|
1310
|
-
value:
|
|
1311
|
-
open,
|
|
1312
|
-
setOpen,
|
|
1313
|
-
popoverId,
|
|
1314
|
-
manageFocus,
|
|
1315
|
-
animated,
|
|
1316
|
-
portal,
|
|
1317
|
-
portalRoot,
|
|
1318
|
-
getReferenceProps,
|
|
1319
|
-
getFloatingProps,
|
|
1320
|
-
getPositionerStateProps,
|
|
1321
|
-
context
|
|
1322
|
-
},
|
|
1663
|
+
value: contextValue,
|
|
1323
1664
|
children
|
|
1324
1665
|
});
|
|
1325
1666
|
}
|
|
@@ -1351,21 +1692,28 @@ const PopoverTrigger = forwardRef((_ref, ref) => {
|
|
|
1351
1692
|
PopoverTrigger.displayName = "PopoverTrigger";
|
|
1352
1693
|
/** Renders the `PopoverContent` component. */
|
|
1353
1694
|
function PopoverContent(_ref2) {
|
|
1354
|
-
let { children } = _ref2, props = _objectWithoutProperties(_ref2, _excluded2$9);
|
|
1695
|
+
let { children, render } = _ref2, props = _objectWithoutProperties(_ref2, _excluded2$9);
|
|
1355
1696
|
const { open, popoverId, manageFocus, animated, portal, portalRoot, getFloatingProps, getPositionerStateProps, context } = usePopoverContext();
|
|
1356
1697
|
const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated });
|
|
1357
1698
|
const floatingProps = getFloatingProps();
|
|
1699
|
+
const panelRef = useMergedRef(ref, floatingProps.ref);
|
|
1358
1700
|
if (!mounted) return null;
|
|
1359
|
-
const node =
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1701
|
+
const node = renderElement("div", {
|
|
1702
|
+
render,
|
|
1703
|
+
refs: [panelRef],
|
|
1704
|
+
props: [
|
|
1705
|
+
{
|
|
1706
|
+
id: popoverId,
|
|
1707
|
+
"data-popover-id": popoverId,
|
|
1708
|
+
tabIndex: -1,
|
|
1709
|
+
style: floatingProps.style
|
|
1710
|
+
},
|
|
1711
|
+
getPositionerStateProps(open),
|
|
1712
|
+
dataAttributes,
|
|
1713
|
+
props,
|
|
1714
|
+
{ children }
|
|
1715
|
+
]
|
|
1716
|
+
});
|
|
1369
1717
|
return /* @__PURE__ */ jsx(OverlayPortal, {
|
|
1370
1718
|
portal,
|
|
1371
1719
|
portalRoot,
|
|
@@ -1392,144 +1740,245 @@ const PopoverClose = forwardRef((_ref3, ref) => {
|
|
|
1392
1740
|
});
|
|
1393
1741
|
PopoverClose.displayName = "PopoverClose";
|
|
1394
1742
|
//#endregion
|
|
1743
|
+
//#region src/internal/create-store.ts
|
|
1744
|
+
/** Creates a {@link Store} seeded with `initial`. */
|
|
1745
|
+
function createStore(initial) {
|
|
1746
|
+
let state = initial;
|
|
1747
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
1748
|
+
return {
|
|
1749
|
+
getState: () => state,
|
|
1750
|
+
setState: (partial) => {
|
|
1751
|
+
let changed = false;
|
|
1752
|
+
for (const key in partial) if (!Object.is(state[key], partial[key])) {
|
|
1753
|
+
changed = true;
|
|
1754
|
+
break;
|
|
1755
|
+
}
|
|
1756
|
+
if (!changed) return;
|
|
1757
|
+
state = _objectSpread2(_objectSpread2({}, state), partial);
|
|
1758
|
+
for (const listener of listeners) listener();
|
|
1759
|
+
},
|
|
1760
|
+
subscribe: (listener) => {
|
|
1761
|
+
listeners.add(listener);
|
|
1762
|
+
return () => {
|
|
1763
|
+
listeners.delete(listener);
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Subscribe to a slice of a {@link Store}.
|
|
1770
|
+
*
|
|
1771
|
+
* The selector MUST return a stable value (primitive, or a referentially stable
|
|
1772
|
+
* object) — `useSyncExternalStore` re-renders in a loop otherwise.
|
|
1773
|
+
*/
|
|
1774
|
+
function useStoreSelector(store, selector) {
|
|
1775
|
+
return useSyncExternalStore(store.subscribe, () => selector(store.getState()), () => selector(store.getState()));
|
|
1776
|
+
}
|
|
1777
|
+
//#endregion
|
|
1395
1778
|
//#region src/primitives/select.tsx
|
|
1396
1779
|
const _excluded$13 = [
|
|
1397
1780
|
"onClick",
|
|
1398
1781
|
"onKeyDown",
|
|
1399
1782
|
"children"
|
|
1400
1783
|
];
|
|
1401
|
-
const _excluded2$8 = ["children"];
|
|
1784
|
+
const _excluded2$8 = ["children", "render"];
|
|
1402
1785
|
const _excluded3$6 = [
|
|
1403
1786
|
"value",
|
|
1404
1787
|
"disabled",
|
|
1405
1788
|
"onClick",
|
|
1406
1789
|
"children"
|
|
1407
1790
|
];
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1791
|
+
/** Normalize the raw value (single `string` or multiple `string[]`). */
|
|
1792
|
+
function toValues(value) {
|
|
1793
|
+
if (Array.isArray(value)) return value;
|
|
1794
|
+
return value === "" ? [] : [value];
|
|
1795
|
+
}
|
|
1796
|
+
const SelectStoreContext = createContext(null);
|
|
1797
|
+
function useSelectStoreContext() {
|
|
1798
|
+
const ctx = useContext(SelectStoreContext);
|
|
1799
|
+
if (!ctx) throw new Error("Select components must be used within SelectRoot");
|
|
1800
|
+
return ctx;
|
|
1411
1801
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
if (idx < 0) return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
|
|
1417
|
-
return enabled[Math.min(enabled.length - 1, Math.max(0, idx + delta))].id;
|
|
1802
|
+
/** Subscribe to a slice of select state; re-renders only when it changes. */
|
|
1803
|
+
function useSelectSelector(selector) {
|
|
1804
|
+
const { store } = useSelectStoreContext();
|
|
1805
|
+
return useStoreSelector(store, selector);
|
|
1418
1806
|
}
|
|
1419
|
-
const
|
|
1420
|
-
function
|
|
1421
|
-
const ctx = useContext(
|
|
1807
|
+
const SelectFloatingContext = createContext(null);
|
|
1808
|
+
function useSelectFloating() {
|
|
1809
|
+
const ctx = useContext(SelectFloatingContext);
|
|
1422
1810
|
if (!ctx) throw new Error("Select components must be used within SelectRoot");
|
|
1423
1811
|
return ctx;
|
|
1424
1812
|
}
|
|
1425
1813
|
/** Renders the `SelectRoot` component. */
|
|
1426
|
-
function SelectRoot({ children, value: controlledValue, defaultValue, onValueChange, setValue: setValueDeprecated, multiple = false, name, open: controlledOpen, onOpenChange, setOpen: setOpenDeprecated, animated = true, portal = false, portalRoot = null }) {
|
|
1814
|
+
function SelectRoot({ children, value: controlledValue, defaultValue, onValueChange, setValue: setValueDeprecated, multiple = false, readOnly = false, name, open: controlledOpen, onOpenChange, setOpen: setOpenDeprecated, animated = true, portal = false, portalRoot = null }) {
|
|
1427
1815
|
var _selectedValues$;
|
|
1428
|
-
const [value, setValue] = useControllableState(defaultValue !== null && defaultValue !== void 0 ? defaultValue : multiple ? [] : "", controlledValue, onValueChange !== null && onValueChange !== void 0 ? onValueChange : setValueDeprecated);
|
|
1429
|
-
const [open, setOpenState] = useState(controlledOpen !== null && controlledOpen !== void 0 ? controlledOpen : false);
|
|
1430
|
-
const onOpenChangeCb = onOpenChange !== null && onOpenChange !== void 0 ? onOpenChange : setOpenDeprecated;
|
|
1431
|
-
const [activeId, setActiveId] = useState(null);
|
|
1432
1816
|
const selectId = useId();
|
|
1433
1817
|
const listboxId = `${selectId}-listbox`;
|
|
1434
|
-
const items =
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
}
|
|
1443
|
-
const
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
if (multiple) {
|
|
1447
|
-
const arr = Array.isArray(value) ? value : value ? [value] : [];
|
|
1448
|
-
setValue(arr.includes(v) ? arr.filter((x) => x !== v) : [...arr, v]);
|
|
1449
|
-
} else {
|
|
1450
|
-
setValue(v);
|
|
1451
|
-
setOpen(false);
|
|
1452
|
-
}
|
|
1453
|
-
}, [
|
|
1818
|
+
const { items, registerItem, unregisterItem: removeItem } = useItemRegistry();
|
|
1819
|
+
const [store] = useState(() => {
|
|
1820
|
+
var _ref;
|
|
1821
|
+
return createStore({
|
|
1822
|
+
value: (_ref = controlledValue !== null && controlledValue !== void 0 ? controlledValue : defaultValue) !== null && _ref !== void 0 ? _ref : multiple ? [] : "",
|
|
1823
|
+
activeId: null,
|
|
1824
|
+
open: controlledOpen !== null && controlledOpen !== void 0 ? controlledOpen : false
|
|
1825
|
+
});
|
|
1826
|
+
});
|
|
1827
|
+
const propsRef = useRef({
|
|
1828
|
+
controlledValue,
|
|
1829
|
+
controlledOpen,
|
|
1454
1830
|
multiple,
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1831
|
+
readOnly,
|
|
1832
|
+
onValueChange: onValueChange !== null && onValueChange !== void 0 ? onValueChange : setValueDeprecated,
|
|
1833
|
+
onOpenChange: onOpenChange !== null && onOpenChange !== void 0 ? onOpenChange : setOpenDeprecated
|
|
1834
|
+
});
|
|
1835
|
+
propsRef.current = {
|
|
1836
|
+
controlledValue,
|
|
1837
|
+
controlledOpen,
|
|
1838
|
+
multiple,
|
|
1839
|
+
readOnly,
|
|
1840
|
+
onValueChange: onValueChange !== null && onValueChange !== void 0 ? onValueChange : setValueDeprecated,
|
|
1841
|
+
onOpenChange: onOpenChange !== null && onOpenChange !== void 0 ? onOpenChange : setOpenDeprecated
|
|
1842
|
+
};
|
|
1843
|
+
useLayoutEffect(() => {
|
|
1844
|
+
if (controlledValue !== void 0) store.setState({ value: controlledValue });
|
|
1845
|
+
}, [controlledValue, store]);
|
|
1846
|
+
useLayoutEffect(() => {
|
|
1847
|
+
if (controlledOpen !== void 0) store.setState({ open: controlledOpen });
|
|
1848
|
+
}, [controlledOpen, store]);
|
|
1849
|
+
const actions = useMemo(() => {
|
|
1850
|
+
const setValue = (v) => {
|
|
1851
|
+
var _p$onValueChange;
|
|
1852
|
+
const p = propsRef.current;
|
|
1853
|
+
if (p.controlledValue === void 0) store.setState({ value: v });
|
|
1854
|
+
(_p$onValueChange = p.onValueChange) === null || _p$onValueChange === void 0 || _p$onValueChange.call(p, v);
|
|
1855
|
+
};
|
|
1856
|
+
const setOpen = (v) => {
|
|
1857
|
+
var _p$onOpenChange;
|
|
1858
|
+
const p = propsRef.current;
|
|
1859
|
+
if (p.controlledOpen === void 0) store.setState({ open: v });
|
|
1860
|
+
(_p$onOpenChange = p.onOpenChange) === null || _p$onOpenChange === void 0 || _p$onOpenChange.call(p, v);
|
|
1861
|
+
if (!v) store.setState({ activeId: null });
|
|
1862
|
+
};
|
|
1863
|
+
return {
|
|
1864
|
+
setValue,
|
|
1865
|
+
setOpen,
|
|
1866
|
+
setActiveId: (updater) => {
|
|
1867
|
+
const cur = store.getState().activeId;
|
|
1868
|
+
const next = typeof updater === "function" ? updater(cur) : updater;
|
|
1869
|
+
store.setState({ activeId: next });
|
|
1870
|
+
},
|
|
1871
|
+
selectValue: (v) => {
|
|
1872
|
+
const p = propsRef.current;
|
|
1873
|
+
if (p.readOnly) return;
|
|
1874
|
+
if (p.multiple) {
|
|
1875
|
+
const arr = toValues(store.getState().value);
|
|
1876
|
+
setValue(arr.includes(v) ? arr.filter((x) => x !== v) : [...arr, v]);
|
|
1877
|
+
} else {
|
|
1878
|
+
setValue(v);
|
|
1879
|
+
setOpen(false);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1883
|
+
}, [store]);
|
|
1465
1884
|
const unregisterItem = useCallback((id) => {
|
|
1466
|
-
|
|
1467
|
-
|
|
1885
|
+
const removedIndex = removeItem(id);
|
|
1886
|
+
if (store.getState().activeId !== id) return;
|
|
1887
|
+
store.setState({ activeId: nearestEnabledId(items.current, removedIndex) });
|
|
1888
|
+
}, [
|
|
1889
|
+
items,
|
|
1890
|
+
removeItem,
|
|
1891
|
+
store
|
|
1892
|
+
]);
|
|
1893
|
+
const open = useStoreSelector(store, (state) => state.open);
|
|
1894
|
+
const value = useStoreSelector(store, (state) => state.value);
|
|
1895
|
+
const selectedValues = useMemo(() => toValues(value), [value]);
|
|
1468
1896
|
const { getReferenceProps, getFloatingProps } = useFloating({
|
|
1469
1897
|
placement: "bottom-start",
|
|
1470
1898
|
gutter: 4,
|
|
1471
1899
|
sameWidth: true,
|
|
1472
1900
|
open,
|
|
1473
|
-
onOpenChange: setOpen,
|
|
1901
|
+
onOpenChange: actions.setOpen,
|
|
1474
1902
|
dismiss: {
|
|
1475
1903
|
outsidePress: true,
|
|
1476
1904
|
escapeKey: false
|
|
1477
1905
|
}
|
|
1478
1906
|
});
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1907
|
+
const storeContext = useMemo(() => ({
|
|
1908
|
+
store,
|
|
1909
|
+
actions,
|
|
1910
|
+
multiple,
|
|
1911
|
+
readOnly,
|
|
1912
|
+
selectId,
|
|
1913
|
+
listboxId,
|
|
1914
|
+
items,
|
|
1915
|
+
registerItem,
|
|
1916
|
+
unregisterItem
|
|
1917
|
+
}), [
|
|
1918
|
+
store,
|
|
1919
|
+
actions,
|
|
1920
|
+
multiple,
|
|
1921
|
+
readOnly,
|
|
1922
|
+
selectId,
|
|
1923
|
+
listboxId,
|
|
1924
|
+
registerItem,
|
|
1925
|
+
unregisterItem
|
|
1926
|
+
]);
|
|
1927
|
+
const floatingContext = useMemo(() => ({
|
|
1928
|
+
getReferenceProps,
|
|
1929
|
+
getFloatingProps,
|
|
1930
|
+
animated,
|
|
1931
|
+
portal,
|
|
1932
|
+
portalRoot
|
|
1933
|
+
}), [
|
|
1934
|
+
getReferenceProps,
|
|
1935
|
+
getFloatingProps,
|
|
1936
|
+
animated,
|
|
1937
|
+
portal,
|
|
1938
|
+
portalRoot
|
|
1939
|
+
]);
|
|
1940
|
+
return /* @__PURE__ */ jsx(SelectStoreContext.Provider, {
|
|
1941
|
+
value: storeContext,
|
|
1942
|
+
children: /* @__PURE__ */ jsxs(SelectFloatingContext.Provider, {
|
|
1943
|
+
value: floatingContext,
|
|
1944
|
+
children: [children, name && (multiple ? selectedValues.map((v) => /* @__PURE__ */ jsx("input", {
|
|
1945
|
+
type: "hidden",
|
|
1946
|
+
name,
|
|
1947
|
+
value: v
|
|
1948
|
+
}, v)) : /* @__PURE__ */ jsx("input", {
|
|
1949
|
+
type: "hidden",
|
|
1950
|
+
name,
|
|
1951
|
+
value: (_selectedValues$ = selectedValues[0]) !== null && _selectedValues$ !== void 0 ? _selectedValues$ : ""
|
|
1952
|
+
}))]
|
|
1953
|
+
})
|
|
1510
1954
|
});
|
|
1511
1955
|
}
|
|
1512
1956
|
/** Renders the `SelectLabel` component. */
|
|
1513
1957
|
function SelectLabel(props) {
|
|
1514
|
-
const { selectId } =
|
|
1958
|
+
const { selectId } = useSelectStoreContext();
|
|
1515
1959
|
return /* @__PURE__ */ jsx("label", _objectSpread2({ htmlFor: selectId }, props));
|
|
1516
1960
|
}
|
|
1517
|
-
const SelectTrigger = forwardRef((
|
|
1961
|
+
const SelectTrigger = forwardRef((_ref2, ref) => {
|
|
1518
1962
|
var _selectedValues$2;
|
|
1519
|
-
let { onClick, onKeyDown, children } =
|
|
1520
|
-
const {
|
|
1963
|
+
let { onClick, onKeyDown, children } = _ref2, props = _objectWithoutProperties(_ref2, _excluded$13);
|
|
1964
|
+
const { actions, multiple, readOnly, selectId, listboxId, items, store } = useSelectStoreContext();
|
|
1965
|
+
const { getReferenceProps } = useSelectFloating();
|
|
1966
|
+
const open = useSelectSelector((state) => state.open);
|
|
1967
|
+
const activeId = useSelectSelector((state) => state.activeId);
|
|
1968
|
+
const value = useSelectSelector((state) => state.value);
|
|
1969
|
+
const selectedValues = useMemo(() => toValues(value), [value]);
|
|
1521
1970
|
const refProps = getReferenceProps();
|
|
1522
1971
|
const typeahead = useRef({
|
|
1523
1972
|
buffer: "",
|
|
1524
1973
|
timer: 0
|
|
1525
1974
|
});
|
|
1526
1975
|
const selectActive = useCallback(() => {
|
|
1527
|
-
const item = items.current.find((i) => i.id === activeId);
|
|
1528
|
-
if (item && !item.disabled) selectValue(item.value);
|
|
1976
|
+
const item = items.current.find((i) => i.id === store.getState().activeId);
|
|
1977
|
+
if (item && !item.disabled) actions.selectValue(item.value);
|
|
1529
1978
|
}, [
|
|
1530
1979
|
items,
|
|
1531
|
-
|
|
1532
|
-
|
|
1980
|
+
store,
|
|
1981
|
+
actions
|
|
1533
1982
|
]);
|
|
1534
1983
|
const runTypeahead = useCallback((char) => {
|
|
1535
1984
|
const t = typeahead.current;
|
|
@@ -1542,52 +1991,51 @@ const SelectTrigger = forwardRef((_ref, ref) => {
|
|
|
1542
1991
|
var _document$getElementB;
|
|
1543
1992
|
return (_document$getElementB = document.getElementById(i.id)) === null || _document$getElementB === void 0 || (_document$getElementB = _document$getElementB.textContent) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.trim().toLowerCase().startsWith(t.buffer);
|
|
1544
1993
|
});
|
|
1545
|
-
if (match) setActiveId(match.id);
|
|
1546
|
-
}, [items,
|
|
1994
|
+
if (match) actions.setActiveId(match.id);
|
|
1995
|
+
}, [items, actions]);
|
|
1547
1996
|
const handleClick = useCallback((e) => {
|
|
1548
|
-
setOpen(!open);
|
|
1997
|
+
actions.setOpen(!open);
|
|
1549
1998
|
onClick === null || onClick === void 0 || onClick(e);
|
|
1550
1999
|
}, [
|
|
1551
2000
|
open,
|
|
1552
|
-
|
|
2001
|
+
actions,
|
|
1553
2002
|
onClick
|
|
1554
2003
|
]);
|
|
1555
2004
|
const handleKeyDown = useCallback((e) => {
|
|
2005
|
+
const currentActiveId = store.getState().activeId;
|
|
1556
2006
|
switch (e.key) {
|
|
1557
2007
|
case "ArrowDown":
|
|
1558
2008
|
e.preventDefault();
|
|
1559
|
-
if (!open) setOpen(true);
|
|
1560
|
-
else setActiveId(moveActiveId
|
|
2009
|
+
if (!open) actions.setOpen(true);
|
|
2010
|
+
else actions.setActiveId(moveActiveId(items.current, currentActiveId, 1));
|
|
1561
2011
|
break;
|
|
1562
2012
|
case "ArrowUp":
|
|
1563
2013
|
e.preventDefault();
|
|
1564
|
-
if (!open) setOpen(true);
|
|
1565
|
-
else setActiveId(moveActiveId
|
|
2014
|
+
if (!open) actions.setOpen(true);
|
|
2015
|
+
else actions.setActiveId(moveActiveId(items.current, currentActiveId, -1));
|
|
1566
2016
|
break;
|
|
1567
2017
|
case "Home":
|
|
1568
2018
|
if (open) {
|
|
1569
2019
|
e.preventDefault();
|
|
1570
|
-
setActiveId(firstEnabledId
|
|
2020
|
+
actions.setActiveId(firstEnabledId(items.current));
|
|
1571
2021
|
}
|
|
1572
2022
|
break;
|
|
1573
2023
|
case "End":
|
|
1574
2024
|
if (open) {
|
|
1575
|
-
var _enabled$id, _enabled;
|
|
1576
2025
|
e.preventDefault();
|
|
1577
|
-
|
|
1578
|
-
setActiveId((_enabled$id = (_enabled = enabled[enabled.length - 1]) === null || _enabled === void 0 ? void 0 : _enabled.id) !== null && _enabled$id !== void 0 ? _enabled$id : null);
|
|
2026
|
+
actions.setActiveId(lastEnabledId(items.current));
|
|
1579
2027
|
}
|
|
1580
2028
|
break;
|
|
1581
2029
|
case "Enter":
|
|
1582
2030
|
case " ":
|
|
1583
2031
|
e.preventDefault();
|
|
1584
2032
|
if (open) selectActive();
|
|
1585
|
-
else setOpen(true);
|
|
2033
|
+
else actions.setOpen(true);
|
|
1586
2034
|
break;
|
|
1587
2035
|
case "Escape":
|
|
1588
2036
|
if (open) {
|
|
1589
2037
|
e.preventDefault();
|
|
1590
|
-
setOpen(false);
|
|
2038
|
+
actions.setOpen(false);
|
|
1591
2039
|
}
|
|
1592
2040
|
break;
|
|
1593
2041
|
default: if (open && e.key.length === 1 && e.key !== " " && !e.metaKey && !e.ctrlKey && !e.altKey && !e.nativeEvent.isComposing) runTypeahead(e.key);
|
|
@@ -1596,9 +2044,8 @@ const SelectTrigger = forwardRef((_ref, ref) => {
|
|
|
1596
2044
|
}, [
|
|
1597
2045
|
open,
|
|
1598
2046
|
items,
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
setOpen,
|
|
2047
|
+
store,
|
|
2048
|
+
actions,
|
|
1602
2049
|
selectActive,
|
|
1603
2050
|
runTypeahead,
|
|
1604
2051
|
onKeyDown
|
|
@@ -1616,6 +2063,8 @@ const SelectTrigger = forwardRef((_ref, ref) => {
|
|
|
1616
2063
|
"aria-haspopup": "listbox",
|
|
1617
2064
|
"aria-controls": open ? listboxId : void 0,
|
|
1618
2065
|
"aria-activedescendant": open ? activeId !== null && activeId !== void 0 ? activeId : void 0 : void 0,
|
|
2066
|
+
"aria-readonly": readOnly || void 0,
|
|
2067
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1619
2068
|
"data-select-trigger": selectId,
|
|
1620
2069
|
onClick: handleClick,
|
|
1621
2070
|
onKeyDown: handleKeyDown
|
|
@@ -1623,38 +2072,50 @@ const SelectTrigger = forwardRef((_ref, ref) => {
|
|
|
1623
2072
|
});
|
|
1624
2073
|
SelectTrigger.displayName = "SelectTrigger";
|
|
1625
2074
|
/** Renders the `SelectPopover` component. */
|
|
1626
|
-
function SelectPopover(
|
|
1627
|
-
let { children } =
|
|
1628
|
-
const {
|
|
2075
|
+
function SelectPopover(_ref3) {
|
|
2076
|
+
let { children, render } = _ref3, props = _objectWithoutProperties(_ref3, _excluded2$8);
|
|
2077
|
+
const { actions, multiple, readOnly, selectId, listboxId, items, store } = useSelectStoreContext();
|
|
2078
|
+
const { getFloatingProps, animated, portal, portalRoot } = useSelectFloating();
|
|
2079
|
+
const open = useSelectSelector((state) => state.open);
|
|
2080
|
+
const activeId = useSelectSelector((state) => state.activeId);
|
|
1629
2081
|
const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated });
|
|
1630
2082
|
const floatingProps = getFloatingProps();
|
|
2083
|
+
const panelRef = useMergedRef(ref, floatingProps.ref);
|
|
1631
2084
|
useLayoutEffect(() => {
|
|
1632
|
-
if (mounted)
|
|
2085
|
+
if (!mounted) return;
|
|
2086
|
+
actions.setActiveId((prev) => {
|
|
1633
2087
|
var _selected$id;
|
|
1634
2088
|
if (prev) return prev;
|
|
2089
|
+
const selectedValues = toValues(store.getState().value);
|
|
1635
2090
|
const selected = items.current.find((i) => selectedValues.includes(i.value));
|
|
1636
|
-
return (_selected$id = selected === null || selected === void 0 ? void 0 : selected.id) !== null && _selected$id !== void 0 ? _selected$id : firstEnabledId
|
|
2091
|
+
return (_selected$id = selected === null || selected === void 0 ? void 0 : selected.id) !== null && _selected$id !== void 0 ? _selected$id : firstEnabledId(items.current);
|
|
1637
2092
|
});
|
|
1638
2093
|
}, [
|
|
1639
2094
|
mounted,
|
|
1640
2095
|
items,
|
|
1641
|
-
|
|
1642
|
-
|
|
2096
|
+
store,
|
|
2097
|
+
actions
|
|
1643
2098
|
]);
|
|
1644
2099
|
useScrollActiveDescendantIntoView(activeId);
|
|
1645
2100
|
if (!mounted) return null;
|
|
1646
|
-
const node =
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
2101
|
+
const node = renderElement("div", {
|
|
2102
|
+
render,
|
|
2103
|
+
refs: [panelRef],
|
|
2104
|
+
props: [
|
|
2105
|
+
{
|
|
2106
|
+
id: listboxId,
|
|
2107
|
+
role: "listbox",
|
|
2108
|
+
"aria-multiselectable": multiple || void 0,
|
|
2109
|
+
"aria-readonly": readOnly || void 0,
|
|
2110
|
+
"aria-activedescendant": activeId !== null && activeId !== void 0 ? activeId : void 0,
|
|
2111
|
+
"data-select-id": selectId,
|
|
2112
|
+
style: floatingProps.style
|
|
2113
|
+
},
|
|
2114
|
+
dataAttributes,
|
|
2115
|
+
props,
|
|
2116
|
+
{ children }
|
|
2117
|
+
]
|
|
2118
|
+
});
|
|
1658
2119
|
return /* @__PURE__ */ jsx(OverlayPortal, {
|
|
1659
2120
|
portal,
|
|
1660
2121
|
portalRoot,
|
|
@@ -1662,12 +2123,12 @@ function SelectPopover(_ref2) {
|
|
|
1662
2123
|
});
|
|
1663
2124
|
}
|
|
1664
2125
|
/** Renders the `SelectItem` component. */
|
|
1665
|
-
function SelectItem(
|
|
1666
|
-
let { value: itemValue, disabled, onClick, children } =
|
|
1667
|
-
const {
|
|
2126
|
+
function SelectItem(_ref4) {
|
|
2127
|
+
let { value: itemValue, disabled, onClick, children } = _ref4, props = _objectWithoutProperties(_ref4, _excluded3$6);
|
|
2128
|
+
const { actions, registerItem, unregisterItem } = useSelectStoreContext();
|
|
1668
2129
|
const itemId = useId();
|
|
1669
|
-
const isSelected =
|
|
1670
|
-
const isActive = activeId === itemId;
|
|
2130
|
+
const isSelected = useSelectSelector((state) => toValues(state.value).includes(itemValue));
|
|
2131
|
+
const isActive = useSelectSelector((state) => state.activeId === itemId);
|
|
1671
2132
|
useLayoutEffect(() => {
|
|
1672
2133
|
registerItem({
|
|
1673
2134
|
id: itemId,
|
|
@@ -1683,12 +2144,12 @@ function SelectItem(_ref3) {
|
|
|
1683
2144
|
unregisterItem
|
|
1684
2145
|
]);
|
|
1685
2146
|
const handleClick = useCallback((e) => {
|
|
1686
|
-
if (!disabled) selectValue(itemValue);
|
|
2147
|
+
if (!disabled) actions.selectValue(itemValue);
|
|
1687
2148
|
onClick === null || onClick === void 0 || onClick(e);
|
|
1688
2149
|
}, [
|
|
1689
2150
|
disabled,
|
|
1690
2151
|
itemValue,
|
|
1691
|
-
|
|
2152
|
+
actions,
|
|
1692
2153
|
onClick
|
|
1693
2154
|
]);
|
|
1694
2155
|
return /* @__PURE__ */ jsx("div", _objectSpread2(_objectSpread2({
|
|
@@ -1700,14 +2161,14 @@ function SelectItem(_ref3) {
|
|
|
1700
2161
|
"data-disabled": disabled ? "" : void 0,
|
|
1701
2162
|
onClick: handleClick,
|
|
1702
2163
|
onMouseEnter: () => {
|
|
1703
|
-
if (!disabled) setActiveId(itemId);
|
|
2164
|
+
if (!disabled) actions.setActiveId(itemId);
|
|
1704
2165
|
}
|
|
1705
2166
|
}, props), {}, { children: children !== null && children !== void 0 ? children : itemValue }));
|
|
1706
2167
|
}
|
|
1707
2168
|
//#endregion
|
|
1708
2169
|
//#region src/primitives/combobox.tsx
|
|
1709
2170
|
const _excluded$12 = ["onKeyDown"];
|
|
1710
|
-
const _excluded2$7 = ["children"];
|
|
2171
|
+
const _excluded2$7 = ["children", "render"];
|
|
1711
2172
|
const _excluded3$5 = [
|
|
1712
2173
|
"value",
|
|
1713
2174
|
"disabled",
|
|
@@ -1715,36 +2176,6 @@ const _excluded3$5 = [
|
|
|
1715
2176
|
"children"
|
|
1716
2177
|
];
|
|
1717
2178
|
const _excluded4$3 = ["children"];
|
|
1718
|
-
function firstEnabledId$3(items) {
|
|
1719
|
-
var _items$find$id, _items$find;
|
|
1720
|
-
return (_items$find$id = (_items$find = items.find((i) => !i.disabled)) === null || _items$find === void 0 ? void 0 : _items$find.id) !== null && _items$find$id !== void 0 ? _items$find$id : null;
|
|
1721
|
-
}
|
|
1722
|
-
function moveActiveId$3(items, activeId, delta) {
|
|
1723
|
-
const enabled = items.filter((i) => !i.disabled);
|
|
1724
|
-
if (enabled.length === 0) return null;
|
|
1725
|
-
const idx = enabled.findIndex((i) => i.id === activeId);
|
|
1726
|
-
if (idx < 0) return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
|
|
1727
|
-
return enabled[Math.min(enabled.length - 1, Math.max(0, idx + delta))].id;
|
|
1728
|
-
}
|
|
1729
|
-
function createComboboxStore(initial) {
|
|
1730
|
-
let state = initial;
|
|
1731
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
1732
|
-
return {
|
|
1733
|
-
getState: () => state,
|
|
1734
|
-
setState: (partial) => {
|
|
1735
|
-
const next = _objectSpread2(_objectSpread2({}, state), partial);
|
|
1736
|
-
if (next.value === state.value && next.searchValue === state.searchValue && next.activeId === state.activeId && next.open === state.open) return;
|
|
1737
|
-
state = next;
|
|
1738
|
-
listeners.forEach((l) => l());
|
|
1739
|
-
},
|
|
1740
|
-
subscribe: (listener) => {
|
|
1741
|
-
listeners.add(listener);
|
|
1742
|
-
return () => {
|
|
1743
|
-
listeners.delete(listener);
|
|
1744
|
-
};
|
|
1745
|
-
}
|
|
1746
|
-
};
|
|
1747
|
-
}
|
|
1748
2179
|
const ComboboxStoreContext = createContext(null);
|
|
1749
2180
|
function useComboboxStoreContext() {
|
|
1750
2181
|
const ctx = useContext(ComboboxStoreContext);
|
|
@@ -1754,7 +2185,7 @@ function useComboboxStoreContext() {
|
|
|
1754
2185
|
/** Subscribe to a slice of combobox state; re-renders only when it changes. */
|
|
1755
2186
|
function useComboboxSelector(selector) {
|
|
1756
2187
|
const { store } = useComboboxStoreContext();
|
|
1757
|
-
return
|
|
2188
|
+
return useStoreSelector(store, selector);
|
|
1758
2189
|
}
|
|
1759
2190
|
const ComboboxFloatingContext = createContext(null);
|
|
1760
2191
|
function useComboboxFloating() {
|
|
@@ -1763,11 +2194,11 @@ function useComboboxFloating() {
|
|
|
1763
2194
|
return ctx;
|
|
1764
2195
|
}
|
|
1765
2196
|
/** Renders the `ComboboxRoot` component. */
|
|
1766
|
-
function ComboboxRoot({ children, value: controlledValue, defaultValue = "", onValueChange, setValue: setValueDeprecated, open: controlledOpen, onOpenChange, setOpen: setOpenDeprecated, animated = true, portal = false, portalRoot = null }) {
|
|
2197
|
+
function ComboboxRoot({ children, value: controlledValue, defaultValue = "", onValueChange, setValue: setValueDeprecated, readOnly = false, open: controlledOpen, onOpenChange, setOpen: setOpenDeprecated, animated = true, portal = false, portalRoot = null }) {
|
|
1767
2198
|
const comboboxId = useId();
|
|
1768
2199
|
const listboxId = `${comboboxId}-listbox`;
|
|
1769
|
-
const items =
|
|
1770
|
-
const [store] = useState(() =>
|
|
2200
|
+
const { items, registerItem, unregisterItem: removeItem } = useItemRegistry();
|
|
2201
|
+
const [store] = useState(() => createStore({
|
|
1771
2202
|
value: controlledValue !== null && controlledValue !== void 0 ? controlledValue : defaultValue,
|
|
1772
2203
|
searchValue: "",
|
|
1773
2204
|
activeId: null,
|
|
@@ -1785,10 +2216,10 @@ function ComboboxRoot({ children, value: controlledValue, defaultValue = "", onV
|
|
|
1785
2216
|
onValueChange: onValueChange !== null && onValueChange !== void 0 ? onValueChange : setValueDeprecated,
|
|
1786
2217
|
onOpenChange: onOpenChange !== null && onOpenChange !== void 0 ? onOpenChange : setOpenDeprecated
|
|
1787
2218
|
};
|
|
1788
|
-
|
|
2219
|
+
useLayoutEffect(() => {
|
|
1789
2220
|
if (controlledValue !== void 0) store.setState({ value: controlledValue });
|
|
1790
2221
|
}, [controlledValue, store]);
|
|
1791
|
-
|
|
2222
|
+
useLayoutEffect(() => {
|
|
1792
2223
|
if (controlledOpen !== void 0) store.setState({ open: controlledOpen });
|
|
1793
2224
|
}, [controlledOpen, store]);
|
|
1794
2225
|
const actions = useMemo(() => ({
|
|
@@ -1812,21 +2243,21 @@ function ComboboxRoot({ children, value: controlledValue, defaultValue = "", onV
|
|
|
1812
2243
|
store.setState({ activeId: next });
|
|
1813
2244
|
}
|
|
1814
2245
|
}), [store]);
|
|
1815
|
-
const registerItem = useCallback((entry) => {
|
|
1816
|
-
const list = items.current;
|
|
1817
|
-
const existing = list.findIndex((i) => i.id === entry.id);
|
|
1818
|
-
if (existing >= 0) list[existing] = entry;
|
|
1819
|
-
else list.push(entry);
|
|
1820
|
-
}, []);
|
|
1821
2246
|
const unregisterItem = useCallback((id) => {
|
|
1822
|
-
|
|
1823
|
-
|
|
2247
|
+
const removedIndex = removeItem(id);
|
|
2248
|
+
if (store.getState().activeId !== id) return;
|
|
2249
|
+
store.setState({ activeId: nearestEnabledId(items.current, removedIndex) });
|
|
2250
|
+
}, [
|
|
2251
|
+
items,
|
|
2252
|
+
removeItem,
|
|
2253
|
+
store
|
|
2254
|
+
]);
|
|
1824
2255
|
const { getReferenceProps, getFloatingProps } = useFloating({
|
|
1825
2256
|
placement: "bottom-start",
|
|
1826
2257
|
gutter: 4,
|
|
1827
2258
|
sameWidth: true,
|
|
1828
2259
|
lazyFlip: true,
|
|
1829
|
-
open:
|
|
2260
|
+
open: useStoreSelector(store, (state) => state.open),
|
|
1830
2261
|
onOpenChange: actions.setOpen,
|
|
1831
2262
|
dismiss: {
|
|
1832
2263
|
outsidePress: true,
|
|
@@ -1836,6 +2267,7 @@ function ComboboxRoot({ children, value: controlledValue, defaultValue = "", onV
|
|
|
1836
2267
|
const storeContext = useMemo(() => ({
|
|
1837
2268
|
store,
|
|
1838
2269
|
actions,
|
|
2270
|
+
readOnly,
|
|
1839
2271
|
comboboxId,
|
|
1840
2272
|
listboxId,
|
|
1841
2273
|
items,
|
|
@@ -1844,6 +2276,7 @@ function ComboboxRoot({ children, value: controlledValue, defaultValue = "", onV
|
|
|
1844
2276
|
}), [
|
|
1845
2277
|
store,
|
|
1846
2278
|
actions,
|
|
2279
|
+
readOnly,
|
|
1847
2280
|
comboboxId,
|
|
1848
2281
|
listboxId,
|
|
1849
2282
|
registerItem,
|
|
@@ -1872,7 +2305,7 @@ function ComboboxRoot({ children, value: controlledValue, defaultValue = "", onV
|
|
|
1872
2305
|
}
|
|
1873
2306
|
const ComboboxInput = forwardRef((_ref, ref) => {
|
|
1874
2307
|
let { onKeyDown } = _ref, props = _objectWithoutProperties(_ref, _excluded$12);
|
|
1875
|
-
const { actions, comboboxId, listboxId, items } = useComboboxStoreContext();
|
|
2308
|
+
const { actions, readOnly, comboboxId, listboxId, items } = useComboboxStoreContext();
|
|
1876
2309
|
const { getReferenceProps } = useComboboxFloating();
|
|
1877
2310
|
const open = useComboboxSelector((s) => s.open);
|
|
1878
2311
|
const searchValue = useComboboxSelector((s) => s.searchValue);
|
|
@@ -1885,6 +2318,7 @@ const ComboboxInput = forwardRef((_ref, ref) => {
|
|
|
1885
2318
|
actions.setActiveId(null);
|
|
1886
2319
|
}, [actions, open]);
|
|
1887
2320
|
const selectActive = useCallback(() => {
|
|
2321
|
+
if (readOnly) return;
|
|
1888
2322
|
const item = items.current.find((i) => i.id === activeId);
|
|
1889
2323
|
if (item && !item.disabled) {
|
|
1890
2324
|
actions.setValue(item.value);
|
|
@@ -1894,7 +2328,8 @@ const ComboboxInput = forwardRef((_ref, ref) => {
|
|
|
1894
2328
|
}, [
|
|
1895
2329
|
items,
|
|
1896
2330
|
activeId,
|
|
1897
|
-
actions
|
|
2331
|
+
actions,
|
|
2332
|
+
readOnly
|
|
1898
2333
|
]);
|
|
1899
2334
|
const handleKeyDown = useCallback((e) => {
|
|
1900
2335
|
if (e.nativeEvent.isComposing) {
|
|
@@ -1905,12 +2340,12 @@ const ComboboxInput = forwardRef((_ref, ref) => {
|
|
|
1905
2340
|
case "ArrowDown":
|
|
1906
2341
|
e.preventDefault();
|
|
1907
2342
|
if (!open) actions.setOpen(true);
|
|
1908
|
-
actions.setActiveId(moveActiveId
|
|
2343
|
+
actions.setActiveId(moveActiveId(items.current, activeId, 1));
|
|
1909
2344
|
break;
|
|
1910
2345
|
case "ArrowUp":
|
|
1911
2346
|
e.preventDefault();
|
|
1912
2347
|
if (!open) actions.setOpen(true);
|
|
1913
|
-
actions.setActiveId(moveActiveId
|
|
2348
|
+
actions.setActiveId(moveActiveId(items.current, activeId, -1));
|
|
1914
2349
|
break;
|
|
1915
2350
|
case "Enter":
|
|
1916
2351
|
if (open && activeId) {
|
|
@@ -1945,6 +2380,9 @@ const ComboboxInput = forwardRef((_ref, ref) => {
|
|
|
1945
2380
|
"aria-autocomplete": "list",
|
|
1946
2381
|
"aria-controls": open ? listboxId : void 0,
|
|
1947
2382
|
"aria-activedescendant": open ? activeId !== null && activeId !== void 0 ? activeId : void 0 : void 0,
|
|
2383
|
+
"aria-readonly": readOnly || void 0,
|
|
2384
|
+
readOnly,
|
|
2385
|
+
"data-readonly": readOnly ? "" : void 0,
|
|
1948
2386
|
"data-combobox-input": comboboxId,
|
|
1949
2387
|
value: searchValue,
|
|
1950
2388
|
onChange: handleChange,
|
|
@@ -1954,29 +2392,35 @@ const ComboboxInput = forwardRef((_ref, ref) => {
|
|
|
1954
2392
|
ComboboxInput.displayName = "ComboboxInput";
|
|
1955
2393
|
/** Renders the `ComboboxPopover` component. */
|
|
1956
2394
|
function ComboboxPopover(_ref2) {
|
|
1957
|
-
let { children } = _ref2, props = _objectWithoutProperties(_ref2, _excluded2$7);
|
|
2395
|
+
let { children, render } = _ref2, props = _objectWithoutProperties(_ref2, _excluded2$7);
|
|
1958
2396
|
const { actions, comboboxId, listboxId, items } = useComboboxStoreContext();
|
|
1959
2397
|
const { getFloatingProps, animated, portal, portalRoot } = useComboboxFloating();
|
|
1960
2398
|
const { ref, mounted, dataAttributes } = useEnterLeave(useComboboxSelector((s) => s.open), { animated });
|
|
1961
2399
|
const floatingProps = getFloatingProps();
|
|
2400
|
+
const panelRef = useMergedRef(ref, floatingProps.ref);
|
|
1962
2401
|
useLayoutEffect(() => {
|
|
1963
|
-
if (mounted) actions.setActiveId((prev) => prev !== null && prev !== void 0 ? prev : firstEnabledId
|
|
2402
|
+
if (mounted) actions.setActiveId((prev) => prev !== null && prev !== void 0 ? prev : firstEnabledId(items.current));
|
|
1964
2403
|
}, [
|
|
1965
2404
|
mounted,
|
|
1966
2405
|
items,
|
|
1967
2406
|
actions
|
|
1968
2407
|
]);
|
|
1969
2408
|
if (!mounted) return null;
|
|
1970
|
-
const node =
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
2409
|
+
const node = renderElement("div", {
|
|
2410
|
+
render,
|
|
2411
|
+
refs: [panelRef],
|
|
2412
|
+
props: [
|
|
2413
|
+
{
|
|
2414
|
+
id: listboxId,
|
|
2415
|
+
role: "listbox",
|
|
2416
|
+
"data-combobox-id": comboboxId,
|
|
2417
|
+
style: floatingProps.style
|
|
2418
|
+
},
|
|
2419
|
+
dataAttributes,
|
|
2420
|
+
props,
|
|
2421
|
+
{ children }
|
|
2422
|
+
]
|
|
2423
|
+
});
|
|
1980
2424
|
return /* @__PURE__ */ jsx(OverlayPortal, {
|
|
1981
2425
|
portal,
|
|
1982
2426
|
portalRoot,
|
|
@@ -1986,7 +2430,7 @@ function ComboboxPopover(_ref2) {
|
|
|
1986
2430
|
/** Renders the `ComboboxItem` component. */
|
|
1987
2431
|
function ComboboxItem(_ref3) {
|
|
1988
2432
|
let { value: itemValue, disabled, onClick, children } = _ref3, props = _objectWithoutProperties(_ref3, _excluded3$5);
|
|
1989
|
-
const { actions, registerItem, unregisterItem } = useComboboxStoreContext();
|
|
2433
|
+
const { actions, readOnly, registerItem, unregisterItem } = useComboboxStoreContext();
|
|
1990
2434
|
const itemId = useId();
|
|
1991
2435
|
const isSelected = useComboboxSelector((s) => s.value === itemValue);
|
|
1992
2436
|
const isActive = useComboboxSelector((s) => s.activeId === itemId);
|
|
@@ -2005,7 +2449,7 @@ function ComboboxItem(_ref3) {
|
|
|
2005
2449
|
unregisterItem
|
|
2006
2450
|
]);
|
|
2007
2451
|
const handleClick = useCallback((e) => {
|
|
2008
|
-
if (!disabled) {
|
|
2452
|
+
if (!disabled && !readOnly) {
|
|
2009
2453
|
actions.setValue(itemValue);
|
|
2010
2454
|
actions.setSearchValue(itemValue);
|
|
2011
2455
|
actions.setOpen(false);
|
|
@@ -2013,6 +2457,7 @@ function ComboboxItem(_ref3) {
|
|
|
2013
2457
|
onClick === null || onClick === void 0 || onClick(e);
|
|
2014
2458
|
}, [
|
|
2015
2459
|
disabled,
|
|
2460
|
+
readOnly,
|
|
2016
2461
|
itemValue,
|
|
2017
2462
|
actions,
|
|
2018
2463
|
onClick
|
|
@@ -2284,10 +2729,18 @@ function CommandGroup(_ref5) {
|
|
|
2284
2729
|
children
|
|
2285
2730
|
})] }));
|
|
2286
2731
|
}
|
|
2287
|
-
/**
|
|
2732
|
+
/**
|
|
2733
|
+
* Renders the `CommandSeparator` component.
|
|
2734
|
+
*
|
|
2735
|
+
* Rendered with `role="presentation"`: the separator is a child of
|
|
2736
|
+
* `CommandList` (`role="listbox"`), whose only permitted children are `option`
|
|
2737
|
+
* and `group`. A real `role="separator"` there fails
|
|
2738
|
+
* `aria-required-children` and corrupts the option count announced by screen
|
|
2739
|
+
* readers. (Menu separators keep `role="separator"` — `menu` permits it.)
|
|
2740
|
+
*/
|
|
2288
2741
|
function CommandSeparator(props) {
|
|
2289
2742
|
return /* @__PURE__ */ jsx("div", _objectSpread2({
|
|
2290
|
-
role: "
|
|
2743
|
+
role: "presentation",
|
|
2291
2744
|
"data-slot": "command-separator"
|
|
2292
2745
|
}, props));
|
|
2293
2746
|
}
|
|
@@ -2370,7 +2823,11 @@ const _excluded2$5 = [
|
|
|
2370
2823
|
"onKeyDown",
|
|
2371
2824
|
"role"
|
|
2372
2825
|
];
|
|
2373
|
-
const _excluded3$3 = [
|
|
2826
|
+
const _excluded3$3 = [
|
|
2827
|
+
"children",
|
|
2828
|
+
"onKeyDown",
|
|
2829
|
+
"render"
|
|
2830
|
+
];
|
|
2374
2831
|
const _excluded4$1 = [
|
|
2375
2832
|
"disabled",
|
|
2376
2833
|
"hideOnClick",
|
|
@@ -2391,19 +2848,6 @@ const _excluded6$1 = [
|
|
|
2391
2848
|
"onClick",
|
|
2392
2849
|
"children"
|
|
2393
2850
|
];
|
|
2394
|
-
/** First enabled item id, or null. */
|
|
2395
|
-
function firstEnabledId$2(items) {
|
|
2396
|
-
var _items$find$id, _items$find;
|
|
2397
|
-
return (_items$find$id = (_items$find = items.find((i) => !i.disabled)) === null || _items$find === void 0 ? void 0 : _items$find.id) !== null && _items$find$id !== void 0 ? _items$find$id : null;
|
|
2398
|
-
}
|
|
2399
|
-
/** Move the active id by `delta` over the enabled items (clamped, no wrap). */
|
|
2400
|
-
function moveActiveId$2(items, activeId, delta) {
|
|
2401
|
-
const enabled = items.filter((i) => !i.disabled);
|
|
2402
|
-
if (enabled.length === 0) return null;
|
|
2403
|
-
const idx = enabled.findIndex((i) => i.id === activeId);
|
|
2404
|
-
if (idx < 0) return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
|
|
2405
|
-
return enabled[Math.min(enabled.length - 1, Math.max(0, idx + delta))].id;
|
|
2406
|
-
}
|
|
2407
2851
|
const MenuContext = createContext(null);
|
|
2408
2852
|
function useMenuContext() {
|
|
2409
2853
|
const ctx = useContext(MenuContext);
|
|
@@ -2454,20 +2898,19 @@ function MenubarContainer(_ref) {
|
|
|
2454
2898
|
}
|
|
2455
2899
|
/** Renders the `MenuRoot` component. */
|
|
2456
2900
|
function MenuRoot({ children, open: controlledOpen, onOpenChange, setOpen: setOpenDeprecated, animated = true, portal = false, portalRoot = null }) {
|
|
2457
|
-
const [open, setOpenState] =
|
|
2901
|
+
const [open, setOpenState] = useControllableState(false, controlledOpen, onOpenChange !== null && onOpenChange !== void 0 ? onOpenChange : setOpenDeprecated);
|
|
2458
2902
|
const [activeId, setActiveId] = useState(null);
|
|
2459
2903
|
const menuId = useId();
|
|
2460
2904
|
const triggerId = `${menuId}-trigger`;
|
|
2461
|
-
const items =
|
|
2462
|
-
const
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
}, [
|
|
2905
|
+
const { items, registerItem: registerItemEntry, unregisterItem: removeItem } = useItemRegistry();
|
|
2906
|
+
const registerItem = useCallback((id, disabled) => registerItemEntry({
|
|
2907
|
+
id,
|
|
2908
|
+
disabled
|
|
2909
|
+
}), [registerItemEntry]);
|
|
2466
2910
|
const setOpen = useCallback((v) => {
|
|
2467
|
-
|
|
2468
|
-
onOpenChangeCb === null || onOpenChangeCb === void 0 || onOpenChangeCb(v);
|
|
2911
|
+
setOpenState(v);
|
|
2469
2912
|
if (!v) setActiveId(null);
|
|
2470
|
-
}, [
|
|
2913
|
+
}, [setOpenState]);
|
|
2471
2914
|
const focusTrigger = useCallback(() => {
|
|
2472
2915
|
var _document$getElementB;
|
|
2473
2916
|
(_document$getElementB = document.getElementById(triggerId)) === null || _document$getElementB === void 0 || _document$getElementB.focus();
|
|
@@ -2482,39 +2925,45 @@ function MenuRoot({ children, open: controlledOpen, onOpenChange, setOpen: setOp
|
|
|
2482
2925
|
escapeKey: false
|
|
2483
2926
|
}
|
|
2484
2927
|
});
|
|
2485
|
-
const registerItem = useCallback((id, disabled) => {
|
|
2486
|
-
const list = items.current;
|
|
2487
|
-
const existing = list.findIndex((i) => i.id === id);
|
|
2488
|
-
if (existing >= 0) list[existing] = {
|
|
2489
|
-
id,
|
|
2490
|
-
disabled
|
|
2491
|
-
};
|
|
2492
|
-
else list.push({
|
|
2493
|
-
id,
|
|
2494
|
-
disabled
|
|
2495
|
-
});
|
|
2496
|
-
}, []);
|
|
2497
2928
|
const unregisterItem = useCallback((id) => {
|
|
2498
|
-
|
|
2499
|
-
|
|
2929
|
+
const removedIndex = removeItem(id);
|
|
2930
|
+
setActiveId((prev) => prev === id ? nearestEnabledId(items.current, removedIndex) : prev);
|
|
2931
|
+
}, [items, removeItem]);
|
|
2932
|
+
const contextValue = useMemo(() => ({
|
|
2933
|
+
open,
|
|
2934
|
+
setOpen,
|
|
2935
|
+
menuId,
|
|
2936
|
+
triggerId,
|
|
2937
|
+
getReferenceProps,
|
|
2938
|
+
getFloatingProps,
|
|
2939
|
+
activeId,
|
|
2940
|
+
setActiveId,
|
|
2941
|
+
items,
|
|
2942
|
+
registerItem,
|
|
2943
|
+
unregisterItem,
|
|
2944
|
+
focusTrigger,
|
|
2945
|
+
animated,
|
|
2946
|
+
portal,
|
|
2947
|
+
portalRoot
|
|
2948
|
+
}), [
|
|
2949
|
+
open,
|
|
2950
|
+
setOpen,
|
|
2951
|
+
menuId,
|
|
2952
|
+
triggerId,
|
|
2953
|
+
getReferenceProps,
|
|
2954
|
+
getFloatingProps,
|
|
2955
|
+
activeId,
|
|
2956
|
+
setActiveId,
|
|
2957
|
+
items,
|
|
2958
|
+
registerItem,
|
|
2959
|
+
unregisterItem,
|
|
2960
|
+
focusTrigger,
|
|
2961
|
+
animated,
|
|
2962
|
+
portal,
|
|
2963
|
+
portalRoot
|
|
2964
|
+
]);
|
|
2500
2965
|
return /* @__PURE__ */ jsx(MenuContext.Provider, {
|
|
2501
|
-
value:
|
|
2502
|
-
open,
|
|
2503
|
-
setOpen,
|
|
2504
|
-
menuId,
|
|
2505
|
-
triggerId,
|
|
2506
|
-
getReferenceProps,
|
|
2507
|
-
getFloatingProps,
|
|
2508
|
-
activeId,
|
|
2509
|
-
setActiveId,
|
|
2510
|
-
items,
|
|
2511
|
-
registerItem,
|
|
2512
|
-
unregisterItem,
|
|
2513
|
-
focusTrigger,
|
|
2514
|
-
animated,
|
|
2515
|
-
portal,
|
|
2516
|
-
portalRoot
|
|
2517
|
-
},
|
|
2966
|
+
value: contextValue,
|
|
2518
2967
|
children
|
|
2519
2968
|
});
|
|
2520
2969
|
}
|
|
@@ -2558,11 +3007,12 @@ const MenuTrigger = forwardRef((_ref2, ref) => {
|
|
|
2558
3007
|
MenuTrigger.displayName = "MenuTrigger";
|
|
2559
3008
|
/** Renders the `MenuPopover` component. */
|
|
2560
3009
|
function MenuPopover(_ref3) {
|
|
2561
|
-
let { children, onKeyDown } = _ref3, props = _objectWithoutProperties(_ref3, _excluded3$3);
|
|
3010
|
+
let { children, onKeyDown, render } = _ref3, props = _objectWithoutProperties(_ref3, _excluded3$3);
|
|
2562
3011
|
const { open, setOpen, menuId, triggerId, getFloatingProps, items, activeId, setActiveId, focusTrigger, animated, portal, portalRoot } = useMenuContext();
|
|
2563
3012
|
const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated });
|
|
2564
3013
|
const floatingProps = getFloatingProps();
|
|
2565
3014
|
const menuRef = useRef(null);
|
|
3015
|
+
const panelRef = useMergedRef(menuRef, ref, floatingProps.ref);
|
|
2566
3016
|
const typeahead = useRef({
|
|
2567
3017
|
buffer: "",
|
|
2568
3018
|
timer: 0
|
|
@@ -2588,23 +3038,20 @@ function MenuPopover(_ref3) {
|
|
|
2588
3038
|
switch (e.key) {
|
|
2589
3039
|
case "ArrowDown":
|
|
2590
3040
|
e.preventDefault();
|
|
2591
|
-
setActiveId(moveActiveId
|
|
3041
|
+
setActiveId(moveActiveId(items.current, activeId, 1));
|
|
2592
3042
|
break;
|
|
2593
3043
|
case "ArrowUp":
|
|
2594
3044
|
e.preventDefault();
|
|
2595
|
-
setActiveId(moveActiveId
|
|
3045
|
+
setActiveId(moveActiveId(items.current, activeId, -1));
|
|
2596
3046
|
break;
|
|
2597
3047
|
case "Home":
|
|
2598
3048
|
e.preventDefault();
|
|
2599
|
-
setActiveId(firstEnabledId
|
|
3049
|
+
setActiveId(firstEnabledId(items.current));
|
|
2600
3050
|
break;
|
|
2601
|
-
case "End":
|
|
2602
|
-
var _enabled$id, _enabled;
|
|
3051
|
+
case "End":
|
|
2603
3052
|
e.preventDefault();
|
|
2604
|
-
|
|
2605
|
-
setActiveId((_enabled$id = (_enabled = enabled[enabled.length - 1]) === null || _enabled === void 0 ? void 0 : _enabled.id) !== null && _enabled$id !== void 0 ? _enabled$id : null);
|
|
3053
|
+
setActiveId(lastEnabledId(items.current));
|
|
2606
3054
|
break;
|
|
2607
|
-
}
|
|
2608
3055
|
case "Enter":
|
|
2609
3056
|
case " ":
|
|
2610
3057
|
e.preventDefault();
|
|
@@ -2635,7 +3082,7 @@ function MenuPopover(_ref3) {
|
|
|
2635
3082
|
if (mounted) {
|
|
2636
3083
|
var _menuRef$current;
|
|
2637
3084
|
(_menuRef$current = menuRef.current) === null || _menuRef$current === void 0 || _menuRef$current.focus();
|
|
2638
|
-
setActiveId((prev) => prev !== null && prev !== void 0 ? prev : firstEnabledId
|
|
3085
|
+
setActiveId((prev) => prev !== null && prev !== void 0 ? prev : firstEnabledId(items.current));
|
|
2639
3086
|
}
|
|
2640
3087
|
}, [
|
|
2641
3088
|
mounted,
|
|
@@ -2644,21 +3091,25 @@ function MenuPopover(_ref3) {
|
|
|
2644
3091
|
]);
|
|
2645
3092
|
useScrollActiveDescendantIntoView(activeId);
|
|
2646
3093
|
if (!mounted) return null;
|
|
2647
|
-
const node =
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
3094
|
+
const node = renderElement("div", {
|
|
3095
|
+
render,
|
|
3096
|
+
refs: [panelRef],
|
|
3097
|
+
props: [
|
|
3098
|
+
{
|
|
3099
|
+
id: menuId,
|
|
3100
|
+
role: "menu",
|
|
3101
|
+
"aria-labelledby": triggerId,
|
|
3102
|
+
"aria-activedescendant": activeId !== null && activeId !== void 0 ? activeId : void 0,
|
|
3103
|
+
"data-menu-id": menuId,
|
|
3104
|
+
style: floatingProps.style,
|
|
3105
|
+
tabIndex: -1,
|
|
3106
|
+
onKeyDown: handleKeyDown
|
|
3107
|
+
},
|
|
3108
|
+
dataAttributes,
|
|
3109
|
+
props,
|
|
3110
|
+
{ children }
|
|
3111
|
+
]
|
|
3112
|
+
});
|
|
2662
3113
|
return /* @__PURE__ */ jsx(OverlayPortal, {
|
|
2663
3114
|
portal,
|
|
2664
3115
|
portalRoot,
|
|
@@ -2777,17 +3228,6 @@ function MenuButtonArrow(props) {
|
|
|
2777
3228
|
//#region src/primitives/toolbar.tsx
|
|
2778
3229
|
const _excluded$9 = ["onKeyDown"];
|
|
2779
3230
|
const _excluded2$4 = ["disabled", "onFocus"];
|
|
2780
|
-
function firstEnabledId$1(items) {
|
|
2781
|
-
var _items$find$id, _items$find;
|
|
2782
|
-
return (_items$find$id = (_items$find = items.find((i) => !i.disabled)) === null || _items$find === void 0 ? void 0 : _items$find.id) !== null && _items$find$id !== void 0 ? _items$find$id : null;
|
|
2783
|
-
}
|
|
2784
|
-
function moveActiveId$1(items, activeId, delta) {
|
|
2785
|
-
const enabled = items.filter((i) => !i.disabled);
|
|
2786
|
-
if (enabled.length === 0) return null;
|
|
2787
|
-
const idx = enabled.findIndex((i) => i.id === activeId);
|
|
2788
|
-
if (idx < 0) return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
|
|
2789
|
-
return enabled[Math.min(enabled.length - 1, Math.max(0, idx + delta))].id;
|
|
2790
|
-
}
|
|
2791
3231
|
const ToolbarContext = createContext(null);
|
|
2792
3232
|
function useToolbarContext() {
|
|
2793
3233
|
const ctx = useContext(ToolbarContext);
|
|
@@ -2797,29 +3237,31 @@ function useToolbarContext() {
|
|
|
2797
3237
|
/** Renders the `ToolbarRoot` component. */
|
|
2798
3238
|
function ToolbarRoot({ children, orientation = "horizontal" }) {
|
|
2799
3239
|
const [activeId, setActiveId] = useState(null);
|
|
2800
|
-
const items =
|
|
2801
|
-
const registerItem = useCallback((entry) => {
|
|
2802
|
-
const list = items.current;
|
|
2803
|
-
const existing = list.findIndex((i) => i.id === entry.id);
|
|
2804
|
-
if (existing >= 0) list[existing] = entry;
|
|
2805
|
-
else list.push(entry);
|
|
2806
|
-
}, []);
|
|
3240
|
+
const { items, registerItem, unregisterItem: removeItem } = useItemRegistry();
|
|
2807
3241
|
const unregisterItem = useCallback((id) => {
|
|
2808
|
-
|
|
2809
|
-
setActiveId((prev) => prev === id ?
|
|
2810
|
-
}, []);
|
|
3242
|
+
const removedIndex = removeItem(id);
|
|
3243
|
+
setActiveId((prev) => prev === id ? nearestEnabledId(items.current, removedIndex) : prev);
|
|
3244
|
+
}, [items, removeItem]);
|
|
2811
3245
|
useLayoutEffect(() => {
|
|
2812
|
-
setActiveId((prev) => prev !== null && prev !== void 0 ? prev : firstEnabledId
|
|
3246
|
+
setActiveId((prev) => prev !== null && prev !== void 0 ? prev : firstEnabledId(items.current));
|
|
2813
3247
|
}, [activeId]);
|
|
3248
|
+
const contextValue = useMemo(() => ({
|
|
3249
|
+
orientation,
|
|
3250
|
+
activeId,
|
|
3251
|
+
setActiveId,
|
|
3252
|
+
registerItem,
|
|
3253
|
+
unregisterItem,
|
|
3254
|
+
items
|
|
3255
|
+
}), [
|
|
3256
|
+
orientation,
|
|
3257
|
+
activeId,
|
|
3258
|
+
setActiveId,
|
|
3259
|
+
registerItem,
|
|
3260
|
+
unregisterItem,
|
|
3261
|
+
items
|
|
3262
|
+
]);
|
|
2814
3263
|
return /* @__PURE__ */ jsx(ToolbarContext.Provider, {
|
|
2815
|
-
value:
|
|
2816
|
-
orientation,
|
|
2817
|
-
activeId,
|
|
2818
|
-
setActiveId,
|
|
2819
|
-
registerItem,
|
|
2820
|
-
unregisterItem,
|
|
2821
|
-
items
|
|
2822
|
-
},
|
|
3264
|
+
value: contextValue,
|
|
2823
3265
|
children
|
|
2824
3266
|
});
|
|
2825
3267
|
}
|
|
@@ -2838,18 +3280,16 @@ function ToolbarContainer(_ref) {
|
|
|
2838
3280
|
let nextId;
|
|
2839
3281
|
if (e.key === nextKey) {
|
|
2840
3282
|
e.preventDefault();
|
|
2841
|
-
nextId = moveActiveId
|
|
3283
|
+
nextId = moveActiveId(items.current, activeId, 1);
|
|
2842
3284
|
} else if (e.key === prevKey) {
|
|
2843
3285
|
e.preventDefault();
|
|
2844
|
-
nextId = moveActiveId
|
|
3286
|
+
nextId = moveActiveId(items.current, activeId, -1);
|
|
2845
3287
|
} else if (e.key === "Home") {
|
|
2846
3288
|
e.preventDefault();
|
|
2847
|
-
nextId = firstEnabledId
|
|
3289
|
+
nextId = firstEnabledId(items.current);
|
|
2848
3290
|
} else if (e.key === "End") {
|
|
2849
|
-
var _enabled$id, _enabled;
|
|
2850
3291
|
e.preventDefault();
|
|
2851
|
-
|
|
2852
|
-
nextId = (_enabled$id = (_enabled = enabled[enabled.length - 1]) === null || _enabled === void 0 ? void 0 : _enabled.id) !== null && _enabled$id !== void 0 ? _enabled$id : null;
|
|
3292
|
+
nextId = lastEnabledId(items.current);
|
|
2853
3293
|
}
|
|
2854
3294
|
if (nextId) {
|
|
2855
3295
|
setActiveId(nextId);
|
|
@@ -2923,6 +3363,10 @@ const _excluded3$2 = [
|
|
|
2923
3363
|
/**
|
|
2924
3364
|
* From `start`, return the index of the first enabled item walking in `dir`
|
|
2925
3365
|
* (+1/-1). Honors `loop`. Returns -1 if none.
|
|
3366
|
+
*
|
|
3367
|
+
* Composite navigates by INDEX (grid rows/columns, wrap and loop modes), which
|
|
3368
|
+
* is why it keeps this directional scan instead of the registry's id-based
|
|
3369
|
+
* `moveActiveId`.
|
|
2926
3370
|
*/
|
|
2927
3371
|
function firstEnabledFrom(list, start, dir, loop) {
|
|
2928
3372
|
const n = list.length;
|
|
@@ -2945,7 +3389,7 @@ function useCompositeContext() {
|
|
|
2945
3389
|
/** Renders the `CompositeProvider` component. */
|
|
2946
3390
|
function CompositeProvider({ children, focusLoop = false, focusWrap = false, orientation = "both", activeId: controlledActiveId, onActiveIdChange, setActiveId: setActiveIdDeprecated }) {
|
|
2947
3391
|
const [internalActiveId, setInternalActiveId] = useState(null);
|
|
2948
|
-
const items =
|
|
3392
|
+
const { items, registerItem: registerEntry, unregisterItem: removeItem } = useItemRegistry();
|
|
2949
3393
|
const onActiveIdChangeCb = onActiveIdChange !== null && onActiveIdChange !== void 0 ? onActiveIdChange : setActiveIdDeprecated;
|
|
2950
3394
|
const activeId = controlledActiveId !== void 0 ? controlledActiveId : internalActiveId;
|
|
2951
3395
|
const activeIdRef = useRef(activeId);
|
|
@@ -2957,16 +3401,8 @@ function CompositeProvider({ children, focusLoop = false, focusWrap = false, ori
|
|
|
2957
3401
|
}, [controlledActiveId, onActiveIdChangeCb]);
|
|
2958
3402
|
const registerItem = useCallback((id, element, row = 0, col = 0, disabled = false) => {
|
|
2959
3403
|
const list = items.current;
|
|
2960
|
-
const
|
|
2961
|
-
|
|
2962
|
-
if (existing >= 0) list[existing] = {
|
|
2963
|
-
id,
|
|
2964
|
-
element,
|
|
2965
|
-
row,
|
|
2966
|
-
col,
|
|
2967
|
-
disabled
|
|
2968
|
-
};
|
|
2969
|
-
else list.push({
|
|
3404
|
+
const activeBecameDisabled = list.findIndex((i) => i.id === id) >= 0 && id === activeIdRef.current && disabled;
|
|
3405
|
+
registerEntry({
|
|
2970
3406
|
id,
|
|
2971
3407
|
element,
|
|
2972
3408
|
row,
|
|
@@ -2987,29 +3423,48 @@ function CompositeProvider({ children, focusLoop = false, focusWrap = false, ori
|
|
|
2987
3423
|
setInternalActiveId(null);
|
|
2988
3424
|
} else setActiveId(nextId);
|
|
2989
3425
|
}
|
|
2990
|
-
}, [
|
|
3426
|
+
}, [
|
|
3427
|
+
controlledActiveId,
|
|
3428
|
+
setActiveId,
|
|
3429
|
+
items,
|
|
3430
|
+
registerEntry
|
|
3431
|
+
]);
|
|
2991
3432
|
const unregisterItem = useCallback((id) => {
|
|
2992
|
-
|
|
3433
|
+
const removedIndex = removeItem(id);
|
|
3434
|
+
if (removedIndex < 0) return;
|
|
2993
3435
|
if (controlledActiveId === void 0) setInternalActiveId((prev) => {
|
|
2994
3436
|
if (prev !== id) return prev;
|
|
2995
|
-
const
|
|
2996
|
-
const nextId = idx >= 0 ? items.current[idx].id : null;
|
|
3437
|
+
const nextId = nearestEnabledId(items.current, removedIndex);
|
|
2997
3438
|
activeIdRef.current = nextId;
|
|
2998
3439
|
if (nextId === null) seededRef.current = false;
|
|
2999
3440
|
return nextId;
|
|
3000
3441
|
});
|
|
3001
|
-
}, [
|
|
3442
|
+
}, [
|
|
3443
|
+
controlledActiveId,
|
|
3444
|
+
items,
|
|
3445
|
+
removeItem
|
|
3446
|
+
]);
|
|
3447
|
+
const contextValue = useMemo(() => ({
|
|
3448
|
+
activeId,
|
|
3449
|
+
setActiveId,
|
|
3450
|
+
registerItem,
|
|
3451
|
+
unregisterItem,
|
|
3452
|
+
items,
|
|
3453
|
+
focusLoop,
|
|
3454
|
+
focusWrap,
|
|
3455
|
+
orientation
|
|
3456
|
+
}), [
|
|
3457
|
+
activeId,
|
|
3458
|
+
setActiveId,
|
|
3459
|
+
registerItem,
|
|
3460
|
+
unregisterItem,
|
|
3461
|
+
items,
|
|
3462
|
+
focusLoop,
|
|
3463
|
+
focusWrap,
|
|
3464
|
+
orientation
|
|
3465
|
+
]);
|
|
3002
3466
|
return /* @__PURE__ */ jsx(CompositeContext.Provider, {
|
|
3003
|
-
value:
|
|
3004
|
-
activeId,
|
|
3005
|
-
setActiveId,
|
|
3006
|
-
registerItem,
|
|
3007
|
-
unregisterItem,
|
|
3008
|
-
items,
|
|
3009
|
-
focusLoop,
|
|
3010
|
-
focusWrap,
|
|
3011
|
-
orientation
|
|
3012
|
-
},
|
|
3467
|
+
value: contextValue,
|
|
3013
3468
|
children
|
|
3014
3469
|
});
|
|
3015
3470
|
}
|
|
@@ -3176,17 +3631,6 @@ const _excluded2$2 = [
|
|
|
3176
3631
|
"onClick",
|
|
3177
3632
|
"onFocus"
|
|
3178
3633
|
];
|
|
3179
|
-
function firstEnabledId(items) {
|
|
3180
|
-
var _items$find$id, _items$find;
|
|
3181
|
-
return (_items$find$id = (_items$find = items.find((i) => !i.disabled)) === null || _items$find === void 0 ? void 0 : _items$find.id) !== null && _items$find$id !== void 0 ? _items$find$id : null;
|
|
3182
|
-
}
|
|
3183
|
-
function moveActiveId(items, activeId, delta) {
|
|
3184
|
-
const enabled = items.filter((i) => !i.disabled);
|
|
3185
|
-
if (enabled.length === 0) return null;
|
|
3186
|
-
const idx = enabled.findIndex((i) => i.id === activeId);
|
|
3187
|
-
if (idx < 0) return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
|
|
3188
|
-
return enabled[Math.min(enabled.length - 1, Math.max(0, idx + delta))].id;
|
|
3189
|
-
}
|
|
3190
3634
|
const ToggleGroupContext = createContext(null);
|
|
3191
3635
|
/**
|
|
3192
3636
|
* Groups related `Toggle`s with roving-tabindex keyboard navigation and shared
|
|
@@ -3214,17 +3658,11 @@ function ToggleGroup(_ref) {
|
|
|
3214
3658
|
setValue
|
|
3215
3659
|
]);
|
|
3216
3660
|
const [activeId, setActiveId] = useState(null);
|
|
3217
|
-
const items =
|
|
3218
|
-
const registerItem = useCallback((entry) => {
|
|
3219
|
-
const list = items.current;
|
|
3220
|
-
const existing = list.findIndex((i) => i.id === entry.id);
|
|
3221
|
-
if (existing >= 0) list[existing] = entry;
|
|
3222
|
-
else list.push(entry);
|
|
3223
|
-
}, []);
|
|
3661
|
+
const { items, registerItem, unregisterItem: removeItem } = useItemRegistry();
|
|
3224
3662
|
const unregisterItem = useCallback((id) => {
|
|
3225
|
-
|
|
3226
|
-
setActiveId((prev) => prev === id ?
|
|
3227
|
-
}, []);
|
|
3663
|
+
const removedIndex = removeItem(id);
|
|
3664
|
+
setActiveId((prev) => prev === id ? nearestEnabledId(items.current, removedIndex) : prev);
|
|
3665
|
+
}, [items, removeItem]);
|
|
3228
3666
|
useLayoutEffect(() => {
|
|
3229
3667
|
setActiveId((prev) => prev !== null && prev !== void 0 ? prev : firstEnabledId(items.current));
|
|
3230
3668
|
}, [activeId]);
|
|
@@ -3247,10 +3685,8 @@ function ToggleGroup(_ref) {
|
|
|
3247
3685
|
e.preventDefault();
|
|
3248
3686
|
nextId = firstEnabledId(items.current);
|
|
3249
3687
|
} else if (e.key === "End") {
|
|
3250
|
-
var _enabled$id, _enabled;
|
|
3251
3688
|
e.preventDefault();
|
|
3252
|
-
|
|
3253
|
-
nextId = (_enabled$id = (_enabled = enabled[enabled.length - 1]) === null || _enabled === void 0 ? void 0 : _enabled.id) !== null && _enabled$id !== void 0 ? _enabled$id : null;
|
|
3689
|
+
nextId = lastEnabledId(items.current);
|
|
3254
3690
|
}
|
|
3255
3691
|
if (nextId) {
|
|
3256
3692
|
setActiveId(nextId);
|
|
@@ -3263,18 +3699,28 @@ function ToggleGroup(_ref) {
|
|
|
3263
3699
|
focusActive,
|
|
3264
3700
|
onKeyDown
|
|
3265
3701
|
]);
|
|
3702
|
+
const contextValue = useMemo(() => ({
|
|
3703
|
+
isPressed,
|
|
3704
|
+
toggle,
|
|
3705
|
+
disabled,
|
|
3706
|
+
orientation,
|
|
3707
|
+
activeId,
|
|
3708
|
+
setActiveId,
|
|
3709
|
+
registerItem,
|
|
3710
|
+
unregisterItem,
|
|
3711
|
+
items
|
|
3712
|
+
}), [
|
|
3713
|
+
isPressed,
|
|
3714
|
+
toggle,
|
|
3715
|
+
disabled,
|
|
3716
|
+
orientation,
|
|
3717
|
+
activeId,
|
|
3718
|
+
registerItem,
|
|
3719
|
+
unregisterItem,
|
|
3720
|
+
items
|
|
3721
|
+
]);
|
|
3266
3722
|
return /* @__PURE__ */ jsx(ToggleGroupContext.Provider, {
|
|
3267
|
-
value:
|
|
3268
|
-
isPressed,
|
|
3269
|
-
toggle,
|
|
3270
|
-
disabled,
|
|
3271
|
-
orientation,
|
|
3272
|
-
activeId,
|
|
3273
|
-
setActiveId,
|
|
3274
|
-
registerItem,
|
|
3275
|
-
unregisterItem,
|
|
3276
|
-
items
|
|
3277
|
-
},
|
|
3723
|
+
value: contextValue,
|
|
3278
3724
|
children: /* @__PURE__ */ jsx("div", _objectSpread2({
|
|
3279
3725
|
role: "group",
|
|
3280
3726
|
onKeyDown: handleKeyDown
|
|
@@ -3294,17 +3740,19 @@ function Toggle(_ref2) {
|
|
|
3294
3740
|
const [standalonePressed, setStandalonePressed] = useControllableState(defaultPressed, pressedProp, onPressedChange);
|
|
3295
3741
|
const inGroup = group !== null;
|
|
3296
3742
|
const isDisabled = disabled || inGroup && group.disabled || false;
|
|
3743
|
+
const registerItem = group === null || group === void 0 ? void 0 : group.registerItem;
|
|
3744
|
+
const unregisterItem = group === null || group === void 0 ? void 0 : group.unregisterItem;
|
|
3297
3745
|
useLayoutEffect(() => {
|
|
3298
|
-
if (!
|
|
3299
|
-
|
|
3746
|
+
if (!registerItem || !unregisterItem) return void 0;
|
|
3747
|
+
registerItem({
|
|
3300
3748
|
id: itemId,
|
|
3301
3749
|
element: buttonRef.current,
|
|
3302
3750
|
disabled: isDisabled
|
|
3303
3751
|
});
|
|
3304
|
-
return () =>
|
|
3752
|
+
return () => unregisterItem(itemId);
|
|
3305
3753
|
}, [
|
|
3306
|
-
|
|
3307
|
-
|
|
3754
|
+
registerItem,
|
|
3755
|
+
unregisterItem,
|
|
3308
3756
|
itemId,
|
|
3309
3757
|
isDisabled
|
|
3310
3758
|
]);
|
|
@@ -3532,7 +3980,7 @@ const Meter = forwardRef(function Meter(_ref, ref) {
|
|
|
3532
3980
|
//#region src/primitives/accordion.tsx
|
|
3533
3981
|
const _excluded$1 = ["value", "disabled"];
|
|
3534
3982
|
const _excluded2$1 = ["onClick", "disabled"];
|
|
3535
|
-
const _excluded3$1 = ["style"];
|
|
3983
|
+
const _excluded3$1 = ["hiddenUntilFound", "style"];
|
|
3536
3984
|
const AccordionRootContext = createContext(null);
|
|
3537
3985
|
function useAccordionRoot() {
|
|
3538
3986
|
const ctx = useContext(AccordionRootContext);
|
|
@@ -3619,17 +4067,31 @@ function AccordionTrigger(_ref2) {
|
|
|
3619
4067
|
}
|
|
3620
4068
|
/** Renders the `AccordionContent` component. */
|
|
3621
4069
|
function AccordionContent(_ref3) {
|
|
3622
|
-
let { style } = _ref3, props = _objectWithoutProperties(_ref3, _excluded3$1);
|
|
4070
|
+
let { hiddenUntilFound = false, style } = _ref3, props = _objectWithoutProperties(_ref3, _excluded3$1);
|
|
3623
4071
|
const root = useAccordionRoot();
|
|
3624
4072
|
const item = useAccordionItem();
|
|
3625
|
-
const
|
|
4073
|
+
const expanded = root.isExpanded(item.value);
|
|
4074
|
+
const { ref, mounted, dataAttributes } = useEnterLeave(expanded, { animated: root.animated && !hiddenUntilFound });
|
|
3626
4075
|
const innerRef = useRef(null);
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
4076
|
+
const contentRef = useMergedRef(innerRef, ref);
|
|
4077
|
+
useHiddenUntilFound(innerRef, {
|
|
4078
|
+
enabled: hiddenUntilFound,
|
|
4079
|
+
open: expanded,
|
|
4080
|
+
onReveal: useCallback(() => {
|
|
4081
|
+
if (!root.isExpanded(item.value)) root.toggle(item.value);
|
|
4082
|
+
}, [root, item.value])
|
|
4083
|
+
});
|
|
4084
|
+
if (hiddenUntilFound) return /* @__PURE__ */ jsx("div", _objectSpread2({
|
|
4085
|
+
ref: contentRef,
|
|
4086
|
+
id: item.contentId,
|
|
4087
|
+
role: "region",
|
|
4088
|
+
"aria-labelledby": item.triggerId,
|
|
4089
|
+
"data-state": expanded ? "open" : "closed",
|
|
4090
|
+
style
|
|
4091
|
+
}, props));
|
|
3630
4092
|
if (!mounted) return null;
|
|
3631
4093
|
return /* @__PURE__ */ jsx("div", _objectSpread2(_objectSpread2({
|
|
3632
|
-
ref:
|
|
4094
|
+
ref: contentRef,
|
|
3633
4095
|
id: item.contentId,
|
|
3634
4096
|
role: "region",
|
|
3635
4097
|
"aria-labelledby": item.triggerId,
|
|
@@ -3981,18 +4443,21 @@ const _excluded4 = [
|
|
|
3981
4443
|
"name",
|
|
3982
4444
|
"id",
|
|
3983
4445
|
"onChange",
|
|
4446
|
+
"onBlur",
|
|
3984
4447
|
"aria-describedby"
|
|
3985
4448
|
];
|
|
3986
4449
|
const _excluded5 = [
|
|
3987
4450
|
"name",
|
|
3988
4451
|
"id",
|
|
3989
4452
|
"onChange",
|
|
4453
|
+
"onBlur",
|
|
3990
4454
|
"aria-describedby"
|
|
3991
4455
|
];
|
|
3992
4456
|
const _excluded6 = [
|
|
3993
4457
|
"name",
|
|
3994
4458
|
"id",
|
|
3995
4459
|
"onChange",
|
|
4460
|
+
"onBlur",
|
|
3996
4461
|
"aria-describedby",
|
|
3997
4462
|
"children"
|
|
3998
4463
|
];
|
|
@@ -4103,7 +4568,7 @@ function FormLabel(_ref3) {
|
|
|
4103
4568
|
}
|
|
4104
4569
|
const FormInput = forwardRef((_ref4, ref) => {
|
|
4105
4570
|
var _useFieldValueMaybe;
|
|
4106
|
-
let { name, id, onChange, "aria-describedby": ariaDescribedBy } = _ref4, props = _objectWithoutProperties(_ref4, _excluded4);
|
|
4571
|
+
let { name, id, onChange, onBlur, "aria-describedby": ariaDescribedBy } = _ref4, props = _objectWithoutProperties(_ref4, _excluded4);
|
|
4107
4572
|
const form = useFormContext();
|
|
4108
4573
|
const field = useFormField();
|
|
4109
4574
|
const value = (_useFieldValueMaybe = useFieldValueMaybe(form, name)) !== null && _useFieldValueMaybe !== void 0 ? _useFieldValueMaybe : "";
|
|
@@ -4122,13 +4587,21 @@ const FormInput = forwardRef((_ref4, ref) => {
|
|
|
4122
4587
|
name,
|
|
4123
4588
|
onChange
|
|
4124
4589
|
]);
|
|
4590
|
+
const handleBlur = useCallback((e) => {
|
|
4591
|
+
form === null || form === void 0 || form.setFieldTouched(name, true);
|
|
4592
|
+
onBlur === null || onBlur === void 0 || onBlur(e);
|
|
4593
|
+
}, [
|
|
4594
|
+
form,
|
|
4595
|
+
name,
|
|
4596
|
+
onBlur
|
|
4597
|
+
]);
|
|
4125
4598
|
return /* @__PURE__ */ jsx("input", _objectSpread2({
|
|
4126
4599
|
ref: setRef,
|
|
4127
4600
|
id: id !== null && id !== void 0 ? id : field === null || field === void 0 ? void 0 : field.inputId,
|
|
4128
4601
|
name,
|
|
4129
4602
|
value,
|
|
4130
4603
|
onChange: handleChange,
|
|
4131
|
-
onBlur:
|
|
4604
|
+
onBlur: handleBlur,
|
|
4132
4605
|
"aria-invalid": hasError || void 0,
|
|
4133
4606
|
"aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
|
|
4134
4607
|
}, props));
|
|
@@ -4136,7 +4609,7 @@ const FormInput = forwardRef((_ref4, ref) => {
|
|
|
4136
4609
|
FormInput.displayName = "FormInput";
|
|
4137
4610
|
const FormTextarea = forwardRef((_ref5, ref) => {
|
|
4138
4611
|
var _useFieldValueMaybe2;
|
|
4139
|
-
let { name, id, onChange, "aria-describedby": ariaDescribedBy } = _ref5, props = _objectWithoutProperties(_ref5, _excluded5);
|
|
4612
|
+
let { name, id, onChange, onBlur, "aria-describedby": ariaDescribedBy } = _ref5, props = _objectWithoutProperties(_ref5, _excluded5);
|
|
4140
4613
|
const form = useFormContext();
|
|
4141
4614
|
const field = useFormField();
|
|
4142
4615
|
const value = (_useFieldValueMaybe2 = useFieldValueMaybe(form, name)) !== null && _useFieldValueMaybe2 !== void 0 ? _useFieldValueMaybe2 : "";
|
|
@@ -4152,13 +4625,21 @@ const FormTextarea = forwardRef((_ref5, ref) => {
|
|
|
4152
4625
|
name,
|
|
4153
4626
|
onChange
|
|
4154
4627
|
]);
|
|
4628
|
+
const handleBlur = useCallback((e) => {
|
|
4629
|
+
form === null || form === void 0 || form.setFieldTouched(name, true);
|
|
4630
|
+
onBlur === null || onBlur === void 0 || onBlur(e);
|
|
4631
|
+
}, [
|
|
4632
|
+
form,
|
|
4633
|
+
name,
|
|
4634
|
+
onBlur
|
|
4635
|
+
]);
|
|
4155
4636
|
return /* @__PURE__ */ jsx("textarea", _objectSpread2({
|
|
4156
4637
|
ref: setRef,
|
|
4157
4638
|
id: id !== null && id !== void 0 ? id : field === null || field === void 0 ? void 0 : field.inputId,
|
|
4158
4639
|
name,
|
|
4159
4640
|
value,
|
|
4160
4641
|
onChange: handleChange,
|
|
4161
|
-
onBlur:
|
|
4642
|
+
onBlur: handleBlur,
|
|
4162
4643
|
"aria-invalid": hasError || void 0,
|
|
4163
4644
|
"aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
|
|
4164
4645
|
}, props));
|
|
@@ -4166,7 +4647,7 @@ const FormTextarea = forwardRef((_ref5, ref) => {
|
|
|
4166
4647
|
FormTextarea.displayName = "FormTextarea";
|
|
4167
4648
|
const FormSelect = forwardRef((_ref6, ref) => {
|
|
4168
4649
|
var _useFieldValueMaybe3;
|
|
4169
|
-
let { name, id, onChange, "aria-describedby": ariaDescribedBy, children } = _ref6, props = _objectWithoutProperties(_ref6, _excluded6);
|
|
4650
|
+
let { name, id, onChange, onBlur, "aria-describedby": ariaDescribedBy, children } = _ref6, props = _objectWithoutProperties(_ref6, _excluded6);
|
|
4170
4651
|
const form = useFormContext();
|
|
4171
4652
|
const field = useFormField();
|
|
4172
4653
|
const value = (_useFieldValueMaybe3 = useFieldValueMaybe(form, name)) !== null && _useFieldValueMaybe3 !== void 0 ? _useFieldValueMaybe3 : "";
|
|
@@ -4182,13 +4663,21 @@ const FormSelect = forwardRef((_ref6, ref) => {
|
|
|
4182
4663
|
name,
|
|
4183
4664
|
onChange
|
|
4184
4665
|
]);
|
|
4666
|
+
const handleBlur = useCallback((e) => {
|
|
4667
|
+
form === null || form === void 0 || form.setFieldTouched(name, true);
|
|
4668
|
+
onBlur === null || onBlur === void 0 || onBlur(e);
|
|
4669
|
+
}, [
|
|
4670
|
+
form,
|
|
4671
|
+
name,
|
|
4672
|
+
onBlur
|
|
4673
|
+
]);
|
|
4185
4674
|
return /* @__PURE__ */ jsx("select", _objectSpread2(_objectSpread2({
|
|
4186
4675
|
ref: setRef,
|
|
4187
4676
|
id: id !== null && id !== void 0 ? id : field === null || field === void 0 ? void 0 : field.inputId,
|
|
4188
4677
|
name,
|
|
4189
4678
|
value,
|
|
4190
4679
|
onChange: handleChange,
|
|
4191
|
-
onBlur:
|
|
4680
|
+
onBlur: handleBlur,
|
|
4192
4681
|
"aria-invalid": hasError || void 0,
|
|
4193
4682
|
"aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
|
|
4194
4683
|
}, props), {}, { children }));
|
|
@@ -4396,4 +4885,4 @@ function FormGroupLabel(props) {
|
|
|
4396
4885
|
return /* @__PURE__ */ jsx("legend", _objectSpread2({}, props));
|
|
4397
4886
|
}
|
|
4398
4887
|
//#endregion
|
|
4399
|
-
export { AccordionContent, AccordionItem, AccordionRoot, AccordionTrigger, AlertDialogPanel, Button, Checkbox, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxPopover, ComboboxRoot, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandRoot, CommandSeparator, Composite, CompositeItem, CompositeProvider, CompositeRow, DialogDescription, DialogDisclosure, DialogDismiss, DialogHeading, DialogPanel, DialogRoot, DisclosureContent, DisclosureRoot, DisclosureTrigger, FormCheckbox, FormControl, FormDescription, FormError, FormField, FormGroup, FormGroupLabel, FormInput, FormLabel, FormProvider, FormPush, FormRadio, FormRadioGroup, FormRemove, FormReset, FormRoot, FormSelect, FormSubmit, FormSwitch, FormTextarea, MenuButtonArrow, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuPopover, MenuRoot, MenuSeparator, MenuTrigger, MenubarContainer, MenubarRoot, Meter, PopoverClose, PopoverContent, PopoverRoot, PopoverTrigger, Progress, Radio, RadioGroupRoot, SelectItem, SelectLabel, SelectPopover, SelectRoot, SelectTrigger, Separator, Switch, Tab, TabList, TabPanel, TabsRoot, Toggle, ToggleGroup, ToolbarButton, ToolbarContainer, ToolbarRoot, ToolbarSeparator, Tooltip, TooltipAnchor, TooltipProvider, useCommandState, useControllableState, useDialogClose, useEnterLeave, useFieldValue, useFloating, useFocusVisible, useFocusableWhenDisabled, useFormContext, useFormStore, useId, useMenubarContext, useRadioGroupContext, useRovingTabindex, useScrollActiveDescendantIntoView };
|
|
4888
|
+
export { AccordionContent, AccordionItem, AccordionRoot, AccordionTrigger, AlertDialogPanel, Button, Checkbox, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxPopover, ComboboxRoot, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandRoot, CommandSeparator, Composite, CompositeItem, CompositeProvider, CompositeRow, DialogDescription, DialogDisclosure, DialogDismiss, DialogHeading, DialogPanel, DialogRoot, DisclosureContent, DisclosureRoot, DisclosureTrigger, FormCheckbox, FormControl, FormDescription, FormError, FormField, FormGroup, FormGroupLabel, FormInput, FormLabel, FormProvider, FormPush, FormRadio, FormRadioGroup, FormRemove, FormReset, FormRoot, FormSelect, FormSubmit, FormSwitch, FormTextarea, MenuButtonArrow, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuPopover, MenuRoot, MenuSeparator, MenuTrigger, MenubarContainer, MenubarRoot, Meter, PopoverClose, PopoverContent, PopoverRoot, PopoverTrigger, Progress, Radio, RadioGroupRoot, SelectItem, SelectLabel, SelectPopover, SelectRoot, SelectTrigger, Separator, Switch, Tab, TabList, TabPanel, TabsRoot, Toggle, ToggleGroup, ToolbarButton, ToolbarContainer, ToolbarRoot, ToolbarSeparator, Tooltip, TooltipAnchor, TooltipGroup, TooltipProvider, TooltipRoot, useCommandState, useControllableState, useDialogClose, useEnterLeave, useFieldValue, useFloating, useFocusVisible, useFocusableWhenDisabled, useFormContext, useFormStore, useId, useMenubarContext, useRadioGroupContext, useRovingTabindex, useScrollActiveDescendantIntoView };
|