@spacing-ui/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +988 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +150 -6
- package/dist/index.d.ts +150 -6
- package/dist/index.js +983 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,7 +21,7 @@ var Root = ({ value, onValueChange, children }) => {
|
|
|
21
21
|
const triggerRef = react.useRef(null);
|
|
22
22
|
const listboxRef = react.useRef(null);
|
|
23
23
|
const reactId = react.useId();
|
|
24
|
-
const
|
|
24
|
+
const triggerId2 = `${reactId}trigger`;
|
|
25
25
|
const listboxId = `${reactId}listbox`;
|
|
26
26
|
const optionIdPrefix = `${reactId}option-`;
|
|
27
27
|
const getOptionId = react.useCallback(
|
|
@@ -60,7 +60,7 @@ var Root = ({ value, onValueChange, children }) => {
|
|
|
60
60
|
onValueChange,
|
|
61
61
|
activeValue,
|
|
62
62
|
setActiveValue,
|
|
63
|
-
triggerId,
|
|
63
|
+
triggerId: triggerId2,
|
|
64
64
|
listboxId,
|
|
65
65
|
triggerRef,
|
|
66
66
|
listboxRef,
|
|
@@ -73,7 +73,7 @@ var Root = ({ value, onValueChange, children }) => {
|
|
|
73
73
|
value,
|
|
74
74
|
onValueChange,
|
|
75
75
|
activeValue,
|
|
76
|
-
|
|
76
|
+
triggerId2,
|
|
77
77
|
listboxId,
|
|
78
78
|
getOptionId,
|
|
79
79
|
getOrderedOptions
|
|
@@ -252,7 +252,992 @@ var Select = Object.assign(Root, {
|
|
|
252
252
|
Content,
|
|
253
253
|
Option
|
|
254
254
|
});
|
|
255
|
+
var DEFAULT_DELAY_MS = 700;
|
|
256
|
+
var DEFAULT_SKIP_DELAY_MS = 300;
|
|
257
|
+
var ProviderContext = react.createContext(null);
|
|
258
|
+
var Provider = ({
|
|
259
|
+
children,
|
|
260
|
+
delayDuration = DEFAULT_DELAY_MS,
|
|
261
|
+
skipDelayDuration = DEFAULT_SKIP_DELAY_MS
|
|
262
|
+
}) => {
|
|
263
|
+
const lastCloseAt = react.useRef(0);
|
|
264
|
+
const isInSkipWindow = react.useCallback(
|
|
265
|
+
() => Date.now() - lastCloseAt.current < skipDelayDuration,
|
|
266
|
+
[skipDelayDuration]
|
|
267
|
+
);
|
|
268
|
+
const noteClose = react.useCallback(() => {
|
|
269
|
+
lastCloseAt.current = Date.now();
|
|
270
|
+
}, []);
|
|
271
|
+
const value = react.useMemo(
|
|
272
|
+
() => ({ delayDuration, skipDelayDuration, isInSkipWindow, noteClose }),
|
|
273
|
+
[delayDuration, skipDelayDuration, isInSkipWindow, noteClose]
|
|
274
|
+
);
|
|
275
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ProviderContext.Provider, { value, children });
|
|
276
|
+
};
|
|
277
|
+
var TooltipContext = react.createContext(null);
|
|
278
|
+
function useTooltipContext(component) {
|
|
279
|
+
const ctx = react.useContext(TooltipContext);
|
|
280
|
+
if (!ctx) {
|
|
281
|
+
throw new Error(`<Tooltip.${component}> must be rendered inside <Tooltip>`);
|
|
282
|
+
}
|
|
283
|
+
return ctx;
|
|
284
|
+
}
|
|
285
|
+
var Root2 = ({
|
|
286
|
+
children,
|
|
287
|
+
delayDuration,
|
|
288
|
+
open: controlledOpen,
|
|
289
|
+
defaultOpen = false,
|
|
290
|
+
onOpenChange
|
|
291
|
+
}) => {
|
|
292
|
+
const provider = react.useContext(ProviderContext);
|
|
293
|
+
const effectiveDelay = delayDuration ?? provider?.delayDuration ?? DEFAULT_DELAY_MS;
|
|
294
|
+
const isControlled = controlledOpen !== void 0;
|
|
295
|
+
const [uncontrolledOpen, setUncontrolledOpen] = react.useState(defaultOpen);
|
|
296
|
+
const open = isControlled ? controlledOpen : uncontrolledOpen;
|
|
297
|
+
const openTimerRef = react.useRef(null);
|
|
298
|
+
const triggerRef = react.useRef(null);
|
|
299
|
+
const reactId = react.useId();
|
|
300
|
+
const contentId2 = `${reactId}content`;
|
|
301
|
+
const clearOpenTimer = react.useCallback(() => {
|
|
302
|
+
if (openTimerRef.current !== null) {
|
|
303
|
+
clearTimeout(openTimerRef.current);
|
|
304
|
+
openTimerRef.current = null;
|
|
305
|
+
}
|
|
306
|
+
}, []);
|
|
307
|
+
const setOpen = react.useCallback(
|
|
308
|
+
(next) => {
|
|
309
|
+
if (!isControlled) setUncontrolledOpen(next);
|
|
310
|
+
onOpenChange?.(next);
|
|
311
|
+
if (!next) provider?.noteClose();
|
|
312
|
+
},
|
|
313
|
+
[isControlled, onOpenChange, provider]
|
|
314
|
+
);
|
|
315
|
+
const scheduleOpen = react.useCallback(() => {
|
|
316
|
+
clearOpenTimer();
|
|
317
|
+
if (provider?.isInSkipWindow()) {
|
|
318
|
+
setOpen(true);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
openTimerRef.current = setTimeout(() => {
|
|
322
|
+
setOpen(true);
|
|
323
|
+
openTimerRef.current = null;
|
|
324
|
+
}, effectiveDelay);
|
|
325
|
+
}, [clearOpenTimer, effectiveDelay, provider, setOpen]);
|
|
326
|
+
const closeImmediately = react.useCallback(() => {
|
|
327
|
+
clearOpenTimer();
|
|
328
|
+
setOpen(false);
|
|
329
|
+
}, [clearOpenTimer, setOpen]);
|
|
330
|
+
react.useEffect(() => clearOpenTimer, [clearOpenTimer]);
|
|
331
|
+
const setTriggerRef = react.useCallback((node) => {
|
|
332
|
+
triggerRef.current = node;
|
|
333
|
+
}, []);
|
|
334
|
+
const triggerProps = react.useMemo(
|
|
335
|
+
() => ({
|
|
336
|
+
onMouseEnter: () => scheduleOpen(),
|
|
337
|
+
onMouseLeave: () => closeImmediately(),
|
|
338
|
+
onFocus: () => {
|
|
339
|
+
clearOpenTimer();
|
|
340
|
+
setOpen(true);
|
|
341
|
+
},
|
|
342
|
+
onBlur: () => closeImmediately(),
|
|
343
|
+
onKeyDown: (e) => {
|
|
344
|
+
if (e.key === "Escape" && open) {
|
|
345
|
+
closeImmediately();
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
"aria-describedby": open ? contentId2 : void 0
|
|
349
|
+
}),
|
|
350
|
+
[scheduleOpen, closeImmediately, clearOpenTimer, setOpen, open, contentId2]
|
|
351
|
+
);
|
|
352
|
+
const value = react.useMemo(
|
|
353
|
+
() => ({ open, contentId: contentId2, triggerProps, setTriggerRef }),
|
|
354
|
+
[open, contentId2, triggerProps, setTriggerRef]
|
|
355
|
+
);
|
|
356
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TooltipContext.Provider, { value, children });
|
|
357
|
+
};
|
|
358
|
+
function composeRef(...refs) {
|
|
359
|
+
return (node) => {
|
|
360
|
+
for (const ref of refs) {
|
|
361
|
+
if (!ref) continue;
|
|
362
|
+
if (typeof ref === "function") ref(node);
|
|
363
|
+
else ref.current = node;
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function composeHandler(...handlers) {
|
|
368
|
+
return (e) => {
|
|
369
|
+
for (const handler of handlers) {
|
|
370
|
+
handler?.(e);
|
|
371
|
+
if (typeof e.defaultPrevented === "boolean" && e.defaultPrevented) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
var Trigger3 = ({ children }) => {
|
|
378
|
+
const ctx = useTooltipContext("Trigger");
|
|
379
|
+
if (!react.isValidElement(children)) {
|
|
380
|
+
throw new Error("<Tooltip.Trigger> expects a single React element child.");
|
|
381
|
+
}
|
|
382
|
+
const child = children;
|
|
383
|
+
const childProps = child.props;
|
|
384
|
+
const childRef = child.ref;
|
|
385
|
+
const merged = {
|
|
386
|
+
...childProps,
|
|
387
|
+
onMouseEnter: composeHandler(
|
|
388
|
+
childProps.onMouseEnter,
|
|
389
|
+
ctx.triggerProps.onMouseEnter
|
|
390
|
+
),
|
|
391
|
+
onMouseLeave: composeHandler(
|
|
392
|
+
childProps.onMouseLeave,
|
|
393
|
+
ctx.triggerProps.onMouseLeave
|
|
394
|
+
),
|
|
395
|
+
onFocus: composeHandler(
|
|
396
|
+
childProps.onFocus,
|
|
397
|
+
ctx.triggerProps.onFocus
|
|
398
|
+
),
|
|
399
|
+
onBlur: composeHandler(
|
|
400
|
+
childProps.onBlur,
|
|
401
|
+
ctx.triggerProps.onBlur
|
|
402
|
+
),
|
|
403
|
+
onKeyDown: composeHandler(
|
|
404
|
+
childProps.onKeyDown,
|
|
405
|
+
ctx.triggerProps.onKeyDown
|
|
406
|
+
),
|
|
407
|
+
"aria-describedby": [childProps["aria-describedby"], ctx.triggerProps["aria-describedby"]].filter(Boolean).join(" ") || void 0,
|
|
408
|
+
ref: composeRef(childRef, ctx.setTriggerRef)
|
|
409
|
+
};
|
|
410
|
+
return react.cloneElement(child, merged);
|
|
411
|
+
};
|
|
412
|
+
var Content2 = ({ children, forceMount, id, ...rest }) => {
|
|
413
|
+
const ctx = useTooltipContext("Content");
|
|
414
|
+
if (!ctx.open && !forceMount) return null;
|
|
415
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
416
|
+
"div",
|
|
417
|
+
{
|
|
418
|
+
id: id ?? ctx.contentId,
|
|
419
|
+
role: "tooltip",
|
|
420
|
+
"data-state": ctx.open ? "open" : "closed",
|
|
421
|
+
...rest,
|
|
422
|
+
children
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
};
|
|
426
|
+
var Tooltip = Object.assign(Root2, {
|
|
427
|
+
Provider,
|
|
428
|
+
Trigger: Trigger3,
|
|
429
|
+
Content: Content2
|
|
430
|
+
});
|
|
431
|
+
var Switch = react.forwardRef(function Switch2({
|
|
432
|
+
checked: controlledChecked,
|
|
433
|
+
defaultChecked = false,
|
|
434
|
+
onCheckedChange,
|
|
435
|
+
disabled,
|
|
436
|
+
onClick,
|
|
437
|
+
onKeyDown,
|
|
438
|
+
...rest
|
|
439
|
+
}, ref) {
|
|
440
|
+
const isControlled = controlledChecked !== void 0;
|
|
441
|
+
const [uncontrolled, setUncontrolled] = react.useState(defaultChecked);
|
|
442
|
+
const checked = isControlled ? controlledChecked : uncontrolled;
|
|
443
|
+
const toggle = react.useCallback(() => {
|
|
444
|
+
if (disabled) return;
|
|
445
|
+
const next = !checked;
|
|
446
|
+
if (!isControlled) setUncontrolled(next);
|
|
447
|
+
onCheckedChange?.(next);
|
|
448
|
+
}, [checked, disabled, isControlled, onCheckedChange]);
|
|
449
|
+
const handleClick = (e) => {
|
|
450
|
+
onClick?.(e);
|
|
451
|
+
if (e.defaultPrevented) return;
|
|
452
|
+
toggle();
|
|
453
|
+
};
|
|
454
|
+
const handleKeyDown = (e) => {
|
|
455
|
+
onKeyDown?.(e);
|
|
456
|
+
if (e.defaultPrevented) return;
|
|
457
|
+
if (e.key === " " || e.key === "Enter") {
|
|
458
|
+
e.preventDefault();
|
|
459
|
+
toggle();
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
463
|
+
"button",
|
|
464
|
+
{
|
|
465
|
+
ref,
|
|
466
|
+
type: "button",
|
|
467
|
+
role: "switch",
|
|
468
|
+
"aria-checked": checked,
|
|
469
|
+
"aria-disabled": disabled || void 0,
|
|
470
|
+
disabled,
|
|
471
|
+
"data-state": checked ? "checked" : "unchecked",
|
|
472
|
+
"data-disabled": disabled || void 0,
|
|
473
|
+
onClick: handleClick,
|
|
474
|
+
onKeyDown: handleKeyDown,
|
|
475
|
+
...rest
|
|
476
|
+
}
|
|
477
|
+
);
|
|
478
|
+
});
|
|
479
|
+
var isChecked = (s) => s === true;
|
|
480
|
+
var isIndeterminate = (s) => s === "indeterminate";
|
|
481
|
+
var Checkbox = react.forwardRef(function Checkbox2({
|
|
482
|
+
checked: controlled,
|
|
483
|
+
defaultChecked = false,
|
|
484
|
+
onCheckedChange,
|
|
485
|
+
disabled,
|
|
486
|
+
required,
|
|
487
|
+
onClick,
|
|
488
|
+
onKeyDown,
|
|
489
|
+
...rest
|
|
490
|
+
}, ref) {
|
|
491
|
+
const isControlled = controlled !== void 0;
|
|
492
|
+
const [uncontrolled, setUncontrolled] = react.useState(defaultChecked);
|
|
493
|
+
const value = isControlled ? controlled : uncontrolled;
|
|
494
|
+
const toggle = react.useCallback(() => {
|
|
495
|
+
if (disabled) return;
|
|
496
|
+
const next = isChecked(value) ? false : true;
|
|
497
|
+
if (!isControlled) setUncontrolled(next);
|
|
498
|
+
onCheckedChange?.(next);
|
|
499
|
+
}, [disabled, isControlled, onCheckedChange, value]);
|
|
500
|
+
const handleClick = (e) => {
|
|
501
|
+
onClick?.(e);
|
|
502
|
+
if (e.defaultPrevented) return;
|
|
503
|
+
toggle();
|
|
504
|
+
};
|
|
505
|
+
const handleKeyDown = (e) => {
|
|
506
|
+
onKeyDown?.(e);
|
|
507
|
+
if (e.defaultPrevented) return;
|
|
508
|
+
if (e.key === " ") {
|
|
509
|
+
e.preventDefault();
|
|
510
|
+
toggle();
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
const ariaChecked = isIndeterminate(value) ? "mixed" : isChecked(value) ? "true" : "false";
|
|
514
|
+
const dataState = isIndeterminate(value) ? "indeterminate" : isChecked(value) ? "checked" : "unchecked";
|
|
515
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
516
|
+
"button",
|
|
517
|
+
{
|
|
518
|
+
ref,
|
|
519
|
+
type: "button",
|
|
520
|
+
role: "checkbox",
|
|
521
|
+
"aria-checked": ariaChecked,
|
|
522
|
+
"aria-required": required || void 0,
|
|
523
|
+
"aria-disabled": disabled || void 0,
|
|
524
|
+
disabled,
|
|
525
|
+
"data-state": dataState,
|
|
526
|
+
"data-disabled": disabled || void 0,
|
|
527
|
+
onClick: handleClick,
|
|
528
|
+
onKeyDown: handleKeyDown,
|
|
529
|
+
...rest
|
|
530
|
+
}
|
|
531
|
+
);
|
|
532
|
+
});
|
|
533
|
+
var RadioGroupContext = react.createContext(null);
|
|
534
|
+
function useRadioGroupContext(component) {
|
|
535
|
+
const ctx = react.useContext(RadioGroupContext);
|
|
536
|
+
if (!ctx) {
|
|
537
|
+
throw new Error(`<${component}> must be rendered inside <RadioGroup>`);
|
|
538
|
+
}
|
|
539
|
+
return ctx;
|
|
540
|
+
}
|
|
541
|
+
var Root3 = react.forwardRef(function RadioGroup({
|
|
542
|
+
value: controlled,
|
|
543
|
+
defaultValue,
|
|
544
|
+
onValueChange,
|
|
545
|
+
name,
|
|
546
|
+
disabled = false,
|
|
547
|
+
orientation = "vertical",
|
|
548
|
+
children,
|
|
549
|
+
...rest
|
|
550
|
+
}, forwardedRef) {
|
|
551
|
+
const isControlled = controlled !== void 0;
|
|
552
|
+
const [uncontrolled, setUncontrolled] = react.useState(defaultValue ?? null);
|
|
553
|
+
const value = isControlled ? controlled ?? null : uncontrolled;
|
|
554
|
+
const reactId = react.useId();
|
|
555
|
+
const generatedName = name ?? `${reactId}name`;
|
|
556
|
+
const groupRef = react.useRef(null);
|
|
557
|
+
const setRefs = (node) => {
|
|
558
|
+
groupRef.current = node;
|
|
559
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
560
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
561
|
+
};
|
|
562
|
+
const setValue = react.useCallback(
|
|
563
|
+
(next) => {
|
|
564
|
+
if (disabled) return;
|
|
565
|
+
if (!isControlled) setUncontrolled(next);
|
|
566
|
+
onValueChange?.(next);
|
|
567
|
+
},
|
|
568
|
+
[disabled, isControlled, onValueChange]
|
|
569
|
+
);
|
|
570
|
+
react.useEffect(() => {
|
|
571
|
+
const root = groupRef.current;
|
|
572
|
+
if (!root) return;
|
|
573
|
+
const items = Array.from(root.querySelectorAll('[role="radio"]'));
|
|
574
|
+
const tabbable = value !== null ? items.find((el) => el.getAttribute("data-value") === value && !el.disabled) : items.find((el) => !el.disabled);
|
|
575
|
+
items.forEach((el) => {
|
|
576
|
+
el.tabIndex = el === tabbable ? 0 : -1;
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
const ctx = react.useMemo(
|
|
580
|
+
() => ({
|
|
581
|
+
value,
|
|
582
|
+
onValueChange: setValue,
|
|
583
|
+
name: generatedName,
|
|
584
|
+
disabled,
|
|
585
|
+
orientation,
|
|
586
|
+
groupRef
|
|
587
|
+
}),
|
|
588
|
+
[value, setValue, generatedName, disabled, orientation]
|
|
589
|
+
);
|
|
590
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
591
|
+
"div",
|
|
592
|
+
{
|
|
593
|
+
ref: setRefs,
|
|
594
|
+
role: "radiogroup",
|
|
595
|
+
"aria-orientation": orientation,
|
|
596
|
+
"aria-disabled": disabled || void 0,
|
|
597
|
+
"data-disabled": disabled || void 0,
|
|
598
|
+
...rest,
|
|
599
|
+
children
|
|
600
|
+
}
|
|
601
|
+
) });
|
|
602
|
+
});
|
|
603
|
+
var Item = react.forwardRef(function RadioGroupItem({ value, disabled: itemDisabled, onClick, onKeyDown, ...rest }, ref) {
|
|
604
|
+
const ctx = useRadioGroupContext("RadioGroup.Item");
|
|
605
|
+
const disabled = ctx.disabled || !!itemDisabled;
|
|
606
|
+
const checked = ctx.value === value;
|
|
607
|
+
const handleClick = (e) => {
|
|
608
|
+
onClick?.(e);
|
|
609
|
+
if (e.defaultPrevented || disabled) return;
|
|
610
|
+
ctx.onValueChange(value);
|
|
611
|
+
};
|
|
612
|
+
const move = (direction) => {
|
|
613
|
+
const root = ctx.groupRef.current;
|
|
614
|
+
if (!root) return;
|
|
615
|
+
const items = Array.from(root.querySelectorAll('[role="radio"]')).filter(
|
|
616
|
+
(el) => !el.disabled
|
|
617
|
+
);
|
|
618
|
+
if (items.length === 0) return;
|
|
619
|
+
const idx = items.findIndex((el) => el === document.activeElement);
|
|
620
|
+
const nextIdx = (idx + direction + items.length) % items.length;
|
|
621
|
+
const next = items[nextIdx];
|
|
622
|
+
if (!next) return;
|
|
623
|
+
next.focus();
|
|
624
|
+
const nextValue = next.getAttribute("data-value");
|
|
625
|
+
if (nextValue) ctx.onValueChange(nextValue);
|
|
626
|
+
};
|
|
627
|
+
const handleKeyDown = (e) => {
|
|
628
|
+
onKeyDown?.(e);
|
|
629
|
+
if (e.defaultPrevented || disabled) return;
|
|
630
|
+
const nextKey = ctx.orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
|
|
631
|
+
const prevKey = ctx.orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
|
|
632
|
+
if (e.key === nextKey) {
|
|
633
|
+
e.preventDefault();
|
|
634
|
+
move(1);
|
|
635
|
+
} else if (e.key === prevKey) {
|
|
636
|
+
e.preventDefault();
|
|
637
|
+
move(-1);
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
641
|
+
"button",
|
|
642
|
+
{
|
|
643
|
+
ref,
|
|
644
|
+
type: "button",
|
|
645
|
+
role: "radio",
|
|
646
|
+
name: ctx.name,
|
|
647
|
+
value,
|
|
648
|
+
"aria-checked": checked,
|
|
649
|
+
"aria-disabled": disabled || void 0,
|
|
650
|
+
disabled,
|
|
651
|
+
tabIndex: -1,
|
|
652
|
+
"data-value": value,
|
|
653
|
+
"data-state": checked ? "checked" : "unchecked",
|
|
654
|
+
"data-disabled": disabled || void 0,
|
|
655
|
+
onClick: handleClick,
|
|
656
|
+
onKeyDown: handleKeyDown,
|
|
657
|
+
...rest
|
|
658
|
+
}
|
|
659
|
+
);
|
|
660
|
+
});
|
|
661
|
+
var RadioGroup2 = Object.assign(Root3, { Item });
|
|
662
|
+
var TabsContext = react.createContext(null);
|
|
663
|
+
function useTabsContext(component) {
|
|
664
|
+
const ctx = react.useContext(TabsContext);
|
|
665
|
+
if (!ctx) {
|
|
666
|
+
throw new Error(`<Tabs.${component}> must be rendered inside <Tabs>`);
|
|
667
|
+
}
|
|
668
|
+
return ctx;
|
|
669
|
+
}
|
|
670
|
+
var triggerId = (prefix, value) => `${prefix}trigger-${value.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
671
|
+
var contentId = (prefix, value) => `${prefix}content-${value.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
672
|
+
var Root4 = react.forwardRef(function Tabs({
|
|
673
|
+
value: controlled,
|
|
674
|
+
defaultValue,
|
|
675
|
+
onValueChange,
|
|
676
|
+
orientation = "horizontal",
|
|
677
|
+
activationMode = "automatic",
|
|
678
|
+
children,
|
|
679
|
+
...rest
|
|
680
|
+
}, ref) {
|
|
681
|
+
const isControlled = controlled !== void 0;
|
|
682
|
+
const [uncontrolled, setUncontrolled] = react.useState(defaultValue ?? null);
|
|
683
|
+
const value = isControlled ? controlled ?? null : uncontrolled;
|
|
684
|
+
const reactId = react.useId();
|
|
685
|
+
const listRef = react.useRef(null);
|
|
686
|
+
const setValue = react.useCallback(
|
|
687
|
+
(next) => {
|
|
688
|
+
if (!isControlled) setUncontrolled(next);
|
|
689
|
+
onValueChange?.(next);
|
|
690
|
+
},
|
|
691
|
+
[isControlled, onValueChange]
|
|
692
|
+
);
|
|
693
|
+
const ctx = react.useMemo(
|
|
694
|
+
() => ({
|
|
695
|
+
value,
|
|
696
|
+
onValueChange: setValue,
|
|
697
|
+
activationMode,
|
|
698
|
+
orientation,
|
|
699
|
+
idPrefix: reactId,
|
|
700
|
+
listRef
|
|
701
|
+
}),
|
|
702
|
+
[value, setValue, activationMode, orientation, reactId]
|
|
703
|
+
);
|
|
704
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref, "data-orientation": orientation, ...rest, children }) });
|
|
705
|
+
});
|
|
706
|
+
var List = react.forwardRef(function TabsList({ loop = true, children, ...rest }, forwardedRef) {
|
|
707
|
+
const ctx = useTabsContext("List");
|
|
708
|
+
const setRefs = (node) => {
|
|
709
|
+
ctx.listRef.current = node;
|
|
710
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
711
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
712
|
+
};
|
|
713
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
714
|
+
"div",
|
|
715
|
+
{
|
|
716
|
+
ref: setRefs,
|
|
717
|
+
role: "tablist",
|
|
718
|
+
"aria-orientation": ctx.orientation,
|
|
719
|
+
"data-orientation": ctx.orientation,
|
|
720
|
+
"data-loop": loop || void 0,
|
|
721
|
+
...rest,
|
|
722
|
+
children
|
|
723
|
+
}
|
|
724
|
+
);
|
|
725
|
+
});
|
|
726
|
+
var Trigger4 = react.forwardRef(function TabsTrigger({ value, disabled, onClick, onKeyDown, onFocus, ...rest }, ref) {
|
|
727
|
+
const ctx = useTabsContext("Trigger");
|
|
728
|
+
const selected = ctx.value === value;
|
|
729
|
+
const handleClick = (e) => {
|
|
730
|
+
onClick?.(e);
|
|
731
|
+
if (e.defaultPrevented || disabled) return;
|
|
732
|
+
ctx.onValueChange(value);
|
|
733
|
+
};
|
|
734
|
+
const move = (direction) => {
|
|
735
|
+
const root = ctx.listRef.current;
|
|
736
|
+
if (!root) return;
|
|
737
|
+
const triggers = Array.from(root.querySelectorAll('[role="tab"]')).filter(
|
|
738
|
+
(el) => !el.disabled
|
|
739
|
+
);
|
|
740
|
+
if (triggers.length === 0) return;
|
|
741
|
+
let nextIdx;
|
|
742
|
+
if (direction === "first") nextIdx = 0;
|
|
743
|
+
else if (direction === "last") nextIdx = triggers.length - 1;
|
|
744
|
+
else {
|
|
745
|
+
const idx = triggers.findIndex((el) => el === document.activeElement);
|
|
746
|
+
const loopList = (root.getAttribute("data-loop") ?? "true") !== "false";
|
|
747
|
+
const candidate = idx + direction;
|
|
748
|
+
if (candidate < 0) nextIdx = loopList ? triggers.length - 1 : 0;
|
|
749
|
+
else if (candidate >= triggers.length) nextIdx = loopList ? 0 : triggers.length - 1;
|
|
750
|
+
else nextIdx = candidate;
|
|
751
|
+
}
|
|
752
|
+
const target = triggers[nextIdx];
|
|
753
|
+
if (!target) return;
|
|
754
|
+
target.focus();
|
|
755
|
+
if (ctx.activationMode === "automatic") {
|
|
756
|
+
const v = target.getAttribute("data-value");
|
|
757
|
+
if (v) ctx.onValueChange(v);
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
const handleKeyDown = (e) => {
|
|
761
|
+
onKeyDown?.(e);
|
|
762
|
+
if (e.defaultPrevented || disabled) return;
|
|
763
|
+
const nextKey = ctx.orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
|
|
764
|
+
const prevKey = ctx.orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
|
|
765
|
+
if (e.key === nextKey) {
|
|
766
|
+
e.preventDefault();
|
|
767
|
+
move(1);
|
|
768
|
+
} else if (e.key === prevKey) {
|
|
769
|
+
e.preventDefault();
|
|
770
|
+
move(-1);
|
|
771
|
+
} else if (e.key === "Home") {
|
|
772
|
+
e.preventDefault();
|
|
773
|
+
move("first");
|
|
774
|
+
} else if (e.key === "End") {
|
|
775
|
+
e.preventDefault();
|
|
776
|
+
move("last");
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
780
|
+
"button",
|
|
781
|
+
{
|
|
782
|
+
ref,
|
|
783
|
+
type: "button",
|
|
784
|
+
role: "tab",
|
|
785
|
+
id: triggerId(ctx.idPrefix, value),
|
|
786
|
+
"aria-selected": selected,
|
|
787
|
+
"aria-controls": contentId(ctx.idPrefix, value),
|
|
788
|
+
"aria-disabled": disabled || void 0,
|
|
789
|
+
disabled,
|
|
790
|
+
tabIndex: selected ? 0 : -1,
|
|
791
|
+
"data-value": value,
|
|
792
|
+
"data-state": selected ? "active" : "inactive",
|
|
793
|
+
"data-disabled": disabled || void 0,
|
|
794
|
+
"data-orientation": ctx.orientation,
|
|
795
|
+
onClick: handleClick,
|
|
796
|
+
onKeyDown: handleKeyDown,
|
|
797
|
+
onFocus,
|
|
798
|
+
...rest
|
|
799
|
+
}
|
|
800
|
+
);
|
|
801
|
+
});
|
|
802
|
+
var Content3 = react.forwardRef(function TabsContent({ value, forceMount, hidden, ...rest }, ref) {
|
|
803
|
+
const ctx = useTabsContext("Content");
|
|
804
|
+
const selected = ctx.value === value;
|
|
805
|
+
if (!selected && !forceMount) return null;
|
|
806
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
807
|
+
"div",
|
|
808
|
+
{
|
|
809
|
+
ref,
|
|
810
|
+
role: "tabpanel",
|
|
811
|
+
id: contentId(ctx.idPrefix, value),
|
|
812
|
+
"aria-labelledby": triggerId(ctx.idPrefix, value),
|
|
813
|
+
"data-state": selected ? "active" : "inactive",
|
|
814
|
+
"data-orientation": ctx.orientation,
|
|
815
|
+
hidden: hidden ?? !selected,
|
|
816
|
+
tabIndex: 0,
|
|
817
|
+
...rest
|
|
818
|
+
}
|
|
819
|
+
);
|
|
820
|
+
});
|
|
821
|
+
var Tabs2 = Object.assign(Root4, { List, Trigger: Trigger4, Content: Content3 });
|
|
822
|
+
var AccordionContext = react.createContext(null);
|
|
823
|
+
function useAccordionContext(component) {
|
|
824
|
+
const ctx = react.useContext(AccordionContext);
|
|
825
|
+
if (!ctx) {
|
|
826
|
+
throw new Error(`<Accordion.${component}> must be rendered inside <Accordion>`);
|
|
827
|
+
}
|
|
828
|
+
return ctx;
|
|
829
|
+
}
|
|
830
|
+
var ItemContext = react.createContext(null);
|
|
831
|
+
function useItemContext(component) {
|
|
832
|
+
const ctx = react.useContext(ItemContext);
|
|
833
|
+
if (!ctx) {
|
|
834
|
+
throw new Error(`<Accordion.${component}> must be rendered inside <Accordion.Item>`);
|
|
835
|
+
}
|
|
836
|
+
return ctx;
|
|
837
|
+
}
|
|
838
|
+
var Root5 = react.forwardRef(function Accordion(props, forwardedRef) {
|
|
839
|
+
const {
|
|
840
|
+
type,
|
|
841
|
+
disabled = false,
|
|
842
|
+
children,
|
|
843
|
+
// strip controlled-state props so they don't leak onto the DOM
|
|
844
|
+
value: _v,
|
|
845
|
+
defaultValue: _dv,
|
|
846
|
+
onValueChange: _ovc,
|
|
847
|
+
collapsible: _col,
|
|
848
|
+
...rest
|
|
849
|
+
} = props;
|
|
850
|
+
const isMultiple = type === "multiple";
|
|
851
|
+
const controlled = "value" in props ? isMultiple ? props.value : props.value : void 0;
|
|
852
|
+
const isControlled = controlled !== void 0;
|
|
853
|
+
const defaultValue = "defaultValue" in props ? isMultiple ? props.defaultValue ?? [] : props.defaultValue ?? null : isMultiple ? [] : null;
|
|
854
|
+
const [uncontrolledArr, setUncontrolledArr] = react.useState(
|
|
855
|
+
isMultiple ? defaultValue ?? [] : []
|
|
856
|
+
);
|
|
857
|
+
const [uncontrolledStr, setUncontrolledStr] = react.useState(
|
|
858
|
+
isMultiple ? null : defaultValue ?? null
|
|
859
|
+
);
|
|
860
|
+
const values = react.useMemo(() => {
|
|
861
|
+
if (isMultiple) {
|
|
862
|
+
return isControlled ? controlled ?? [] : uncontrolledArr;
|
|
863
|
+
}
|
|
864
|
+
return isControlled ? controlled ? [controlled] : [] : uncontrolledStr ? [uncontrolledStr] : [];
|
|
865
|
+
}, [isMultiple, isControlled, controlled, uncontrolledArr, uncontrolledStr]);
|
|
866
|
+
const collapsible = !isMultiple && "collapsible" in props ? !!props.collapsible : isMultiple;
|
|
867
|
+
const reactId = react.useId();
|
|
868
|
+
const rootRef = react.useRef(null);
|
|
869
|
+
const setRefs = (node) => {
|
|
870
|
+
rootRef.current = node;
|
|
871
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
872
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
873
|
+
};
|
|
874
|
+
const toggle = react.useCallback(
|
|
875
|
+
(value) => {
|
|
876
|
+
if (disabled) return;
|
|
877
|
+
if (isMultiple) {
|
|
878
|
+
const arr = isControlled ? controlled ?? [] : uncontrolledArr;
|
|
879
|
+
const next = arr.includes(value) ? arr.filter((v) => v !== value) : [...arr, value];
|
|
880
|
+
if (!isControlled) setUncontrolledArr(next);
|
|
881
|
+
props.onValueChange?.(next);
|
|
882
|
+
} else {
|
|
883
|
+
const current = isControlled ? controlled : uncontrolledStr;
|
|
884
|
+
const allowEmpty = "collapsible" in props ? !!props.collapsible : false;
|
|
885
|
+
let next;
|
|
886
|
+
if (current === value) {
|
|
887
|
+
if (!allowEmpty) return;
|
|
888
|
+
next = "";
|
|
889
|
+
} else {
|
|
890
|
+
next = value;
|
|
891
|
+
}
|
|
892
|
+
if (!isControlled) setUncontrolledStr(next || null);
|
|
893
|
+
props.onValueChange?.(next);
|
|
894
|
+
}
|
|
895
|
+
},
|
|
896
|
+
[disabled, isMultiple, isControlled, controlled, uncontrolledArr, uncontrolledStr, props]
|
|
897
|
+
);
|
|
898
|
+
const ctx = react.useMemo(
|
|
899
|
+
() => ({
|
|
900
|
+
type,
|
|
901
|
+
values,
|
|
902
|
+
toggle,
|
|
903
|
+
collapsible,
|
|
904
|
+
disabled,
|
|
905
|
+
idPrefix: reactId,
|
|
906
|
+
rootRef
|
|
907
|
+
}),
|
|
908
|
+
[type, values, toggle, collapsible, disabled, reactId]
|
|
909
|
+
);
|
|
910
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AccordionContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setRefs, "data-disabled": disabled || void 0, ...rest, children }) });
|
|
911
|
+
});
|
|
912
|
+
var Item2 = react.forwardRef(function AccordionItem({ value, disabled: itemDisabled, children, ...rest }, ref) {
|
|
913
|
+
const ctx = useAccordionContext("Item");
|
|
914
|
+
const open = ctx.values.includes(value);
|
|
915
|
+
const disabled = ctx.disabled || !!itemDisabled;
|
|
916
|
+
const safeValue = value.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
917
|
+
const triggerId2 = `${ctx.idPrefix}trigger-${safeValue}`;
|
|
918
|
+
const contentId2 = `${ctx.idPrefix}content-${safeValue}`;
|
|
919
|
+
const itemCtx = react.useMemo(
|
|
920
|
+
() => ({ value, open, disabled, triggerId: triggerId2, contentId: contentId2 }),
|
|
921
|
+
[value, open, disabled, triggerId2, contentId2]
|
|
922
|
+
);
|
|
923
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ItemContext.Provider, { value: itemCtx, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
924
|
+
"div",
|
|
925
|
+
{
|
|
926
|
+
ref,
|
|
927
|
+
"data-state": open ? "open" : "closed",
|
|
928
|
+
"data-disabled": disabled || void 0,
|
|
929
|
+
...rest,
|
|
930
|
+
children
|
|
931
|
+
}
|
|
932
|
+
) });
|
|
933
|
+
});
|
|
934
|
+
var Trigger5 = react.forwardRef(function AccordionTrigger({ onClick, onKeyDown, ...rest }, ref) {
|
|
935
|
+
const ctx = useAccordionContext("Trigger");
|
|
936
|
+
const item = useItemContext("Trigger");
|
|
937
|
+
const handleClick = (e) => {
|
|
938
|
+
onClick?.(e);
|
|
939
|
+
if (e.defaultPrevented || item.disabled) return;
|
|
940
|
+
ctx.toggle(item.value);
|
|
941
|
+
};
|
|
942
|
+
const move = (direction) => {
|
|
943
|
+
const root = ctx.rootRef.current;
|
|
944
|
+
if (!root) return;
|
|
945
|
+
const triggers = Array.from(
|
|
946
|
+
root.querySelectorAll('[data-accordion-trigger="true"]')
|
|
947
|
+
).filter((el) => !el.disabled);
|
|
948
|
+
if (triggers.length === 0) return;
|
|
949
|
+
let nextIdx;
|
|
950
|
+
if (direction === "first") nextIdx = 0;
|
|
951
|
+
else if (direction === "last") nextIdx = triggers.length - 1;
|
|
952
|
+
else {
|
|
953
|
+
const idx = triggers.findIndex((el) => el === document.activeElement);
|
|
954
|
+
const candidate = idx + direction;
|
|
955
|
+
nextIdx = (candidate + triggers.length) % triggers.length;
|
|
956
|
+
}
|
|
957
|
+
triggers[nextIdx]?.focus();
|
|
958
|
+
};
|
|
959
|
+
const handleKeyDown = (e) => {
|
|
960
|
+
onKeyDown?.(e);
|
|
961
|
+
if (e.defaultPrevented) return;
|
|
962
|
+
if (e.key === "ArrowDown") {
|
|
963
|
+
e.preventDefault();
|
|
964
|
+
move(1);
|
|
965
|
+
} else if (e.key === "ArrowUp") {
|
|
966
|
+
e.preventDefault();
|
|
967
|
+
move(-1);
|
|
968
|
+
} else if (e.key === "Home") {
|
|
969
|
+
e.preventDefault();
|
|
970
|
+
move("first");
|
|
971
|
+
} else if (e.key === "End") {
|
|
972
|
+
e.preventDefault();
|
|
973
|
+
move("last");
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
977
|
+
"button",
|
|
978
|
+
{
|
|
979
|
+
ref,
|
|
980
|
+
type: "button",
|
|
981
|
+
id: item.triggerId,
|
|
982
|
+
"aria-expanded": item.open,
|
|
983
|
+
"aria-controls": item.contentId,
|
|
984
|
+
"aria-disabled": item.disabled || void 0,
|
|
985
|
+
disabled: item.disabled,
|
|
986
|
+
"data-state": item.open ? "open" : "closed",
|
|
987
|
+
"data-disabled": item.disabled || void 0,
|
|
988
|
+
"data-accordion-trigger": "true",
|
|
989
|
+
onClick: handleClick,
|
|
990
|
+
onKeyDown: handleKeyDown,
|
|
991
|
+
...rest
|
|
992
|
+
}
|
|
993
|
+
);
|
|
994
|
+
});
|
|
995
|
+
var Content4 = react.forwardRef(function AccordionContent({ forceMount, hidden, children, ...rest }, ref) {
|
|
996
|
+
const item = useItemContext("Content");
|
|
997
|
+
if (!item.open && !forceMount) return null;
|
|
998
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
999
|
+
"div",
|
|
1000
|
+
{
|
|
1001
|
+
ref,
|
|
1002
|
+
role: "region",
|
|
1003
|
+
id: item.contentId,
|
|
1004
|
+
"aria-labelledby": item.triggerId,
|
|
1005
|
+
"data-state": item.open ? "open" : "closed",
|
|
1006
|
+
hidden: hidden ?? !item.open,
|
|
1007
|
+
...rest,
|
|
1008
|
+
children
|
|
1009
|
+
}
|
|
1010
|
+
);
|
|
1011
|
+
});
|
|
1012
|
+
var Accordion2 = Object.assign(Root5, { Item: Item2, Trigger: Trigger5, Content: Content4 });
|
|
1013
|
+
var FOCUSABLE_SELECTOR = [
|
|
1014
|
+
"a[href]",
|
|
1015
|
+
"button:not([disabled])",
|
|
1016
|
+
"input:not([disabled])",
|
|
1017
|
+
"select:not([disabled])",
|
|
1018
|
+
"textarea:not([disabled])",
|
|
1019
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
1020
|
+
].join(",");
|
|
1021
|
+
function getFocusables(root) {
|
|
1022
|
+
if (!root) return [];
|
|
1023
|
+
return Array.from(root.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
|
|
1024
|
+
(el) => !el.hasAttribute("disabled") && el.getAttribute("aria-hidden") !== "true"
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
1027
|
+
var DialogContext = react.createContext(null);
|
|
1028
|
+
function useDialogContext(component) {
|
|
1029
|
+
const ctx = react.useContext(DialogContext);
|
|
1030
|
+
if (!ctx) {
|
|
1031
|
+
throw new Error(`<Dialog.${component}> must be rendered inside <Dialog>`);
|
|
1032
|
+
}
|
|
1033
|
+
return ctx;
|
|
1034
|
+
}
|
|
1035
|
+
var Root6 = ({
|
|
1036
|
+
children,
|
|
1037
|
+
open: controlled,
|
|
1038
|
+
defaultOpen = false,
|
|
1039
|
+
onOpenChange,
|
|
1040
|
+
modal = true
|
|
1041
|
+
}) => {
|
|
1042
|
+
const isControlled = controlled !== void 0;
|
|
1043
|
+
const [uncontrolled, setUncontrolled] = react.useState(defaultOpen);
|
|
1044
|
+
const open = isControlled ? controlled : uncontrolled;
|
|
1045
|
+
const triggerRef = react.useRef(null);
|
|
1046
|
+
const contentRef = react.useRef(null);
|
|
1047
|
+
const [hasTitle, setHasTitle] = react.useState(false);
|
|
1048
|
+
const [hasDescription, setHasDescription] = react.useState(false);
|
|
1049
|
+
const reactId = react.useId();
|
|
1050
|
+
const contentId2 = `${reactId}content`;
|
|
1051
|
+
const titleId = `${reactId}title`;
|
|
1052
|
+
const descriptionId = `${reactId}description`;
|
|
1053
|
+
const setOpen = react.useCallback(
|
|
1054
|
+
(next) => {
|
|
1055
|
+
if (!isControlled) setUncontrolled(next);
|
|
1056
|
+
onOpenChange?.(next);
|
|
1057
|
+
},
|
|
1058
|
+
[isControlled, onOpenChange]
|
|
1059
|
+
);
|
|
1060
|
+
const ctx = react.useMemo(
|
|
1061
|
+
() => ({
|
|
1062
|
+
open,
|
|
1063
|
+
setOpen,
|
|
1064
|
+
triggerRef,
|
|
1065
|
+
contentRef,
|
|
1066
|
+
contentId: contentId2,
|
|
1067
|
+
titleId,
|
|
1068
|
+
descriptionId,
|
|
1069
|
+
hasTitle,
|
|
1070
|
+
setHasTitle,
|
|
1071
|
+
hasDescription,
|
|
1072
|
+
setHasDescription,
|
|
1073
|
+
modal
|
|
1074
|
+
}),
|
|
1075
|
+
[open, setOpen, contentId2, titleId, descriptionId, hasTitle, hasDescription, modal]
|
|
1076
|
+
);
|
|
1077
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DialogContext.Provider, { value: ctx, children });
|
|
1078
|
+
};
|
|
1079
|
+
var Trigger6 = react.forwardRef(function DialogTrigger({ onClick, ...rest }, forwardedRef) {
|
|
1080
|
+
const ctx = useDialogContext("Trigger");
|
|
1081
|
+
const setRefs = (node) => {
|
|
1082
|
+
ctx.triggerRef.current = node;
|
|
1083
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
1084
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
1085
|
+
};
|
|
1086
|
+
const handleClick = (e) => {
|
|
1087
|
+
onClick?.(e);
|
|
1088
|
+
if (e.defaultPrevented) return;
|
|
1089
|
+
ctx.setOpen(true);
|
|
1090
|
+
};
|
|
1091
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1092
|
+
"button",
|
|
1093
|
+
{
|
|
1094
|
+
ref: setRefs,
|
|
1095
|
+
type: "button",
|
|
1096
|
+
"aria-haspopup": "dialog",
|
|
1097
|
+
"aria-expanded": ctx.open,
|
|
1098
|
+
"aria-controls": ctx.open ? ctx.contentId : void 0,
|
|
1099
|
+
"data-state": ctx.open ? "open" : "closed",
|
|
1100
|
+
onClick: handleClick,
|
|
1101
|
+
...rest
|
|
1102
|
+
}
|
|
1103
|
+
);
|
|
1104
|
+
});
|
|
1105
|
+
var Overlay = react.forwardRef(function DialogOverlay({ forceMount, onClick, ...rest }, ref) {
|
|
1106
|
+
const ctx = useDialogContext("Overlay");
|
|
1107
|
+
if (!ctx.open && !forceMount) return null;
|
|
1108
|
+
const handleClick = (e) => {
|
|
1109
|
+
onClick?.(e);
|
|
1110
|
+
if (e.defaultPrevented || !ctx.modal) return;
|
|
1111
|
+
if (e.target === e.currentTarget) {
|
|
1112
|
+
ctx.setOpen(false);
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, "data-state": ctx.open ? "open" : "closed", onClick: handleClick, ...rest });
|
|
1116
|
+
});
|
|
1117
|
+
var Content5 = react.forwardRef(function DialogContent({ forceMount, onEscapeKeyDown, onKeyDown, children, ...rest }, forwardedRef) {
|
|
1118
|
+
const ctx = useDialogContext("Content");
|
|
1119
|
+
const setRefs = (node) => {
|
|
1120
|
+
ctx.contentRef.current = node;
|
|
1121
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
1122
|
+
else if (forwardedRef) forwardedRef.current = node;
|
|
1123
|
+
};
|
|
1124
|
+
react.useEffect(() => {
|
|
1125
|
+
if (!ctx.open) return;
|
|
1126
|
+
const previouslyFocused = document.activeElement;
|
|
1127
|
+
const id = requestAnimationFrame(() => {
|
|
1128
|
+
const root = ctx.contentRef.current;
|
|
1129
|
+
if (!root) return;
|
|
1130
|
+
const focusables = getFocusables(root);
|
|
1131
|
+
const target = focusables[0] ?? root;
|
|
1132
|
+
target.focus();
|
|
1133
|
+
});
|
|
1134
|
+
return () => {
|
|
1135
|
+
cancelAnimationFrame(id);
|
|
1136
|
+
const trigger = ctx.triggerRef.current;
|
|
1137
|
+
(trigger ?? previouslyFocused)?.focus?.();
|
|
1138
|
+
};
|
|
1139
|
+
}, [ctx.open, ctx.contentRef, ctx.triggerRef]);
|
|
1140
|
+
react.useEffect(() => {
|
|
1141
|
+
if (!ctx.open || !ctx.modal) return;
|
|
1142
|
+
const prev = document.body.style.overflow;
|
|
1143
|
+
document.body.style.overflow = "hidden";
|
|
1144
|
+
return () => {
|
|
1145
|
+
document.body.style.overflow = prev;
|
|
1146
|
+
};
|
|
1147
|
+
}, [ctx.open, ctx.modal]);
|
|
1148
|
+
const { open: ctxOpen, setOpen: ctxSetOpen } = ctx;
|
|
1149
|
+
react.useEffect(() => {
|
|
1150
|
+
if (!ctxOpen) return;
|
|
1151
|
+
const onKey = (e) => {
|
|
1152
|
+
if (e.key !== "Escape") return;
|
|
1153
|
+
onEscapeKeyDown?.(e);
|
|
1154
|
+
if (e.defaultPrevented) return;
|
|
1155
|
+
ctxSetOpen(false);
|
|
1156
|
+
};
|
|
1157
|
+
document.addEventListener("keydown", onKey);
|
|
1158
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
1159
|
+
}, [ctxOpen, ctxSetOpen, onEscapeKeyDown]);
|
|
1160
|
+
if (!ctx.open && !forceMount) return null;
|
|
1161
|
+
const handleKeyDown = (e) => {
|
|
1162
|
+
onKeyDown?.(e);
|
|
1163
|
+
if (e.defaultPrevented) return;
|
|
1164
|
+
if (e.key !== "Tab" || !ctx.modal) return;
|
|
1165
|
+
const focusables = getFocusables(ctx.contentRef.current);
|
|
1166
|
+
if (focusables.length === 0) {
|
|
1167
|
+
e.preventDefault();
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
const first = focusables[0];
|
|
1171
|
+
const last = focusables[focusables.length - 1];
|
|
1172
|
+
const active = document.activeElement;
|
|
1173
|
+
if (e.shiftKey && (active === first || !ctx.contentRef.current?.contains(active))) {
|
|
1174
|
+
e.preventDefault();
|
|
1175
|
+
last.focus();
|
|
1176
|
+
} else if (!e.shiftKey && active === last) {
|
|
1177
|
+
e.preventDefault();
|
|
1178
|
+
first.focus();
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1182
|
+
"div",
|
|
1183
|
+
{
|
|
1184
|
+
ref: setRefs,
|
|
1185
|
+
role: "dialog",
|
|
1186
|
+
"aria-modal": ctx.modal || void 0,
|
|
1187
|
+
id: ctx.contentId,
|
|
1188
|
+
"aria-labelledby": ctx.hasTitle ? ctx.titleId : void 0,
|
|
1189
|
+
"aria-describedby": ctx.hasDescription ? ctx.descriptionId : void 0,
|
|
1190
|
+
tabIndex: -1,
|
|
1191
|
+
"data-state": ctx.open ? "open" : "closed",
|
|
1192
|
+
onKeyDown: handleKeyDown,
|
|
1193
|
+
...rest,
|
|
1194
|
+
children
|
|
1195
|
+
}
|
|
1196
|
+
);
|
|
1197
|
+
});
|
|
1198
|
+
var Title = react.forwardRef(function DialogTitle(props, ref) {
|
|
1199
|
+
const ctx = useDialogContext("Title");
|
|
1200
|
+
react.useEffect(() => {
|
|
1201
|
+
ctx.setHasTitle(true);
|
|
1202
|
+
return () => ctx.setHasTitle(false);
|
|
1203
|
+
}, [ctx]);
|
|
1204
|
+
return /* @__PURE__ */ jsxRuntime.jsx("h2", { ref, id: ctx.titleId, ...props });
|
|
1205
|
+
});
|
|
1206
|
+
var Description = react.forwardRef(
|
|
1207
|
+
function DialogDescription(props, ref) {
|
|
1208
|
+
const ctx = useDialogContext("Description");
|
|
1209
|
+
react.useEffect(() => {
|
|
1210
|
+
ctx.setHasDescription(true);
|
|
1211
|
+
return () => ctx.setHasDescription(false);
|
|
1212
|
+
}, [ctx]);
|
|
1213
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { ref, id: ctx.descriptionId, ...props });
|
|
1214
|
+
}
|
|
1215
|
+
);
|
|
1216
|
+
var Close = react.forwardRef(function DialogClose({ onClick, ...rest }, ref) {
|
|
1217
|
+
const ctx = useDialogContext("Close");
|
|
1218
|
+
const handleClick = (e) => {
|
|
1219
|
+
onClick?.(e);
|
|
1220
|
+
if (e.defaultPrevented) return;
|
|
1221
|
+
ctx.setOpen(false);
|
|
1222
|
+
};
|
|
1223
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { ref, type: "button", onClick: handleClick, ...rest });
|
|
1224
|
+
});
|
|
1225
|
+
var Dialog = Object.assign(Root6, {
|
|
1226
|
+
Trigger: Trigger6,
|
|
1227
|
+
Overlay,
|
|
1228
|
+
Content: Content5,
|
|
1229
|
+
Title,
|
|
1230
|
+
Description,
|
|
1231
|
+
Close
|
|
1232
|
+
});
|
|
255
1233
|
|
|
1234
|
+
exports.Accordion = Accordion2;
|
|
1235
|
+
exports.Checkbox = Checkbox;
|
|
1236
|
+
exports.Dialog = Dialog;
|
|
1237
|
+
exports.RadioGroup = RadioGroup2;
|
|
256
1238
|
exports.Select = Select;
|
|
1239
|
+
exports.Switch = Switch;
|
|
1240
|
+
exports.Tabs = Tabs2;
|
|
1241
|
+
exports.Tooltip = Tooltip;
|
|
257
1242
|
//# sourceMappingURL=index.cjs.map
|
|
258
1243
|
//# sourceMappingURL=index.cjs.map
|