mado-ui 0.2.2 → 0.3.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.
@@ -2,9 +2,29 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var tailwindMerge = require('tailwind-merge');
5
- var react = require('react');
6
- var react$1 = require('@headlessui/react');
7
- var reactDom = require('react-dom');
5
+ var React = require('react');
6
+ var react = require('@headlessui/react');
7
+ var ReactDOM = require('react-dom');
8
+
9
+ function _interopNamespaceDefault(e) {
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
27
+ var ReactDOM__namespace = /*#__PURE__*/_interopNamespaceDefault(ReactDOM);
8
28
 
9
29
  const integerList = Array.from({ length: 100 }, (_, i) => `${i + 1}`);
10
30
  const twMerge = tailwindMerge.extendTailwindMerge({
@@ -227,14 +247,14 @@ function getWeekdayName(weekday = d) {
227
247
  }
228
248
 
229
249
  function findComponentByType(children, componentType) {
230
- const childrenArray = react.Children.toArray(children);
250
+ const childrenArray = React.Children.toArray(children);
231
251
  for (const child of childrenArray) {
232
- if (react.isValidElement(child) && child.type === componentType)
252
+ if (React.isValidElement(child) && child.type === componentType)
233
253
  return child;
234
254
  }
235
255
  for (const child of childrenArray) {
236
- if (react.isValidElement(child)) {
237
- if (child.type === react.Fragment && child.props.children) {
256
+ if (React.isValidElement(child)) {
257
+ if (child.type === React.Fragment && child.props.children) {
238
258
  const found = findComponentByType(child.props.children, componentType);
239
259
  if (found)
240
260
  return found;
@@ -310,7 +330,7 @@ function twSort(className) {
310
330
  return className;
311
331
  }
312
332
 
313
- function Anchor({ className, disabled, href, onClick, ref, target, rel, ...props }) {
333
+ function Anchor({ as, className, disabled, href, onClick, target, rel, ...props }) {
314
334
  const isExternal = `${href}`.startsWith('http'), hasHash = `${href}`.includes('#');
315
335
  const handleClick = e => {
316
336
  if (disabled)
@@ -318,7 +338,8 @@ function Anchor({ className, disabled, href, onClick, ref, target, rel, ...props
318
338
  onClick?.(e);
319
339
  setTimeout(() => history.replaceState({}, document.title, location.pathname), 100);
320
340
  };
321
- return (jsxRuntime.jsx("a", { ref: ref, ...props, "aria-disabled": disabled, className: twMerge(className, disabled && 'pointer-events-none'), href: href, target: target || (isExternal ? '_blank' : '_self'), onClick: hasHash ? handleClick : onClick, rel: rel !== undefined
341
+ const AnchorElement = as || 'a';
342
+ return (jsxRuntime.jsx(AnchorElement, { ...props, "aria-disabled": disabled, className: twMerge(className, disabled && 'pointer-events-none'), href: href, target: target || (isExternal ? '_blank' : '_self'), onClick: hasHash ? handleClick : onClick, rel: rel !== undefined
322
343
  ? rel === 'nofollow'
323
344
  ? `${rel} noreferrer noopener`
324
345
  : `${rel} prefetch`
@@ -347,68 +368,104 @@ const lineLiftClasses = tailwindMerge.twJoin([
347
368
  ]);
348
369
  const fillClasses = tailwindMerge.twJoin(baseClasses, 'whitespace-nowrap transition-[transform_color] after:top-1/2 after:h-[calc(100%+0.05rem)] after:w-[calc(100%+0.25rem)] after:-translate-y-1/2 after:rounded after:ease-exponential active:text-zinc-50 pointer-fine:hover:text-zinc-50');
349
370
  // Define theme-specific fill color transition classes
350
- const getFillColorTransitionClasses = (theme = 'blue') => {
371
+ const getFillColorTransitionClasses = (theme = 'blue', customTheme) => {
372
+ let fillColorTransitionClasses = tailwindMerge.twJoin(fillClasses, 'transition-transform after:bg-(--theme-color)');
351
373
  switch (theme) {
374
+ case 'blue':
375
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-blue)]');
376
+ break;
352
377
  case 'brown':
353
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-brown after:transition-transform contrast-more:after:bg-ui-brown');
378
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-brow)]');
379
+ break;
354
380
  case 'green':
355
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-green after:transition-transform contrast-more:after:bg-ui-green');
381
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-green)]');
382
+ break;
356
383
  case 'grey':
357
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-grey after:transition-transform contrast-more:after:bg-ui-grey');
384
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-grey)]');
385
+ break;
358
386
  case 'sky-blue':
359
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-sky-blue after:transition-transform contrast-more:after:bg-ui-sky-blue');
387
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-sky-blue)]');
388
+ break;
360
389
  case 'magenta':
361
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-magenta after:transition-transform contrast-more:after:bg-ui-magenta');
362
- case 'neutral':
363
- return tailwindMerge.twJoin(fillClasses, 'after:bg-zinc-700 after:transition-transform contrast-more:after:bg-zinc-700 dark:after:bg-zinc-300 dark:contrast-more:after:bg-zinc-300');
390
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-magenta)]');
391
+ break;
364
392
  case 'orange':
365
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-orange after:transition-transform contrast-more:after:bg-ui-orange');
393
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-orange)]');
394
+ break;
366
395
  case 'pink':
367
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-pink after:transition-transform contrast-more:after:bg-ui-pink');
396
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-pink)]');
397
+ break;
368
398
  case 'purple':
369
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-purple after:transition-transform contrast-more:after:bg-ui-purple');
399
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-purple)]');
400
+ break;
370
401
  case 'red':
371
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-red after:transition-transform contrast-more:after:bg-ui-red');
402
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-red)]');
403
+ break;
372
404
  case 'violet':
373
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-violet after:transition-transform contrast-more:after:bg-ui-violet');
405
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-violet)]');
406
+ break;
374
407
  case 'yellow':
375
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-yellow after:transition-transform contrast-more:after:bg-ui-yellow');
376
- case 'blue':
377
- default:
378
- return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-blue after:transition-transform contrast-more:after:bg-ui-blue');
408
+ fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, 'after:[--theme-color:var(--color-ui-yellow)]');
409
+ break;
410
+ case 'custom':
411
+ if (customTheme && customTheme.themeColor && !customTheme.themeColor.includes('after:[--theme-color:'))
412
+ throw new Error('`customTheme.themeColor` must modify the `--theme-color` variable on the ::after pseudo element. Otherwise, please use `customTheme.classes`.');
413
+ fillColorTransitionClasses = customTheme.themeColor
414
+ ? twMerge(fillColorTransitionClasses, customTheme.themeColor)
415
+ : twMerge(fillClasses, customTheme.classes);
416
+ break;
379
417
  }
418
+ return fillColorTransitionClasses;
380
419
  };
381
420
  // Define theme-specific fill center classes
382
- const getFillCenterClasses = (theme = 'blue') => {
421
+ const getFillCenterClasses = (theme = 'blue', customTheme) => {
422
+ let fillCenterColorClasses = tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-(--theme-color)/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-(--theme-color) pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-(--theme-color)');
383
423
  switch (theme) {
424
+ case 'blue':
425
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-blue)]');
426
+ break;
384
427
  case 'brown':
385
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-brown/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-brown pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-brown');
428
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-brown)]');
429
+ break;
386
430
  case 'green':
387
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-green/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-green pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-green');
431
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-green)]');
432
+ break;
388
433
  case 'grey':
389
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-grey/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-grey pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-grey');
434
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-grey)]');
435
+ break;
390
436
  case 'sky-blue':
391
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-sky-blue/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-sky-blue pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-sky-blue');
437
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-sky-blue)]');
438
+ break;
392
439
  case 'magenta':
393
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-magenta/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-magenta pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-magenta');
394
- case 'neutral':
395
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-zinc-700/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-zinc-700 dark:after:bg-zinc-300/0 dark:active:after:bg-zinc-300 pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-zinc-700 dark:pointer-fine:hover:after:bg-zinc-300');
440
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-magenta)]');
441
+ break;
396
442
  case 'orange':
397
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-orange/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-orange pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-orange');
443
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-orange)]');
444
+ break;
398
445
  case 'pink':
399
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-pink/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-pink pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-pink');
446
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-pink)]');
447
+ break;
400
448
  case 'purple':
401
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-purple/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-purple pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-purple');
449
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-purple)]');
450
+ break;
402
451
  case 'red':
403
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-red/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-red pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-red');
452
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-red)]');
453
+ break;
404
454
  case 'violet':
405
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-violet/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-violet pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-violet');
455
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-violet)]');
456
+ break;
406
457
  case 'yellow':
407
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-yellow/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-yellow pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-yellow');
408
- case 'blue':
409
- default:
410
- return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-blue/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-blue pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-blue');
458
+ fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, 'after:[--theme-color:var(--color-ui-yellow)]');
459
+ break;
460
+ case 'custom':
461
+ if (customTheme && customTheme.themeColor && !customTheme.themeColor.includes('after:[--theme-color:'))
462
+ throw new Error('`customTheme.themeColor` must modify the `--theme-color` variable on the ::after pseudo element. Otherwise, please use `customTheme.classes`.');
463
+ fillCenterColorClasses = customTheme.themeColor
464
+ ? twMerge(fillCenterColorClasses, customTheme.themeColor)
465
+ : twMerge(fillClasses, customTheme.classes);
466
+ break;
411
467
  }
468
+ return fillCenterColorClasses;
412
469
  };
413
470
  const multilineBaseClasses = twSort('bg-linear-to-r from-current to-current bg-no-repeat active:scale-95');
414
471
  const multilineLineStaticClasses = 'underline';
@@ -420,80 +477,115 @@ const multilineLineRtlClasses = tailwindMerge.twJoin([multilineXClasses, 'bg-[po
420
477
  const multilineLineCenterClasses = tailwindMerge.twJoin([multilineXClasses, 'bg-[position:50%_100%]']);
421
478
  const multilineLineLiftClasses = tailwindMerge.twJoin(multilineLineClasses, 'bg-[size:auto_0px] focus-visible:bg-[size:auto_2px] active:bg-[size:auto_2px] pointer-fine:hover:bg-[size:auto_2px]');
422
479
  const multilineFillBaseClasses = tailwindMerge.twJoin(multilineBaseClasses, 'rounded px-0.5 py-0.75 focus-visible:text-zinc-50 active:text-zinc-50 pointer-fine:hover:text-zinc-50');
423
- const getMultilineFillColorClasses = (theme = 'blue') => {
480
+ const getMultilineFillColorClasses = (theme = 'blue', customTheme) => {
481
+ let multilineFillColorClasses = tailwindMerge.twJoin(multilineFillBaseClasses, 'from-(--theme-color) to-(--theme-color) transition-[background-size_color]');
424
482
  switch (theme) {
483
+ case 'blue':
484
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-blue)]');
485
+ break;
425
486
  case 'brown':
426
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-brown to-ui-brown transition-[background-size_color] contrast-more:from-ui-brown contrast-more:to-ui-brown');
487
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-brown)]');
488
+ break;
427
489
  case 'green':
428
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-green to-ui-green transition-[background-size_color] contrast-more:from-ui-green contrast-more:to-ui-green');
490
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-green)]');
491
+ break;
429
492
  case 'grey':
430
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-grey to-ui-grey transition-[background-size_color] contrast-more:from-ui-grey contrast-more:to-ui-grey');
493
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-grey)]');
494
+ break;
431
495
  case 'sky-blue':
432
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-sky-blue to-ui-sky-blue transition-[background-size_color] contrast-more:from-ui-sky-blue contrast-more:to-ui-sky-blue');
496
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-sky-blue)]');
497
+ break;
433
498
  case 'magenta':
434
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-magenta to-ui-magenta transition-[background-size_color] contrast-more:from-ui-magenta contrast-more:to-ui-magenta');
435
- case 'neutral':
436
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-zinc-700 to-zinc-700 transition-[background-size_color] contrast-more:from-zinc-700 contrast-more:to-zinc-700 dark:from-zinc-300 dark:to-zinc-300 dark:contrast-more:from-zinc-300 dark:contrast-more:to-zinc-300');
499
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-magenta)]');
500
+ break;
437
501
  case 'orange':
438
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-orange to-ui-orange transition-[background-size_color] contrast-more:from-ui-orange contrast-more:to-ui-orange');
502
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-orange)]');
503
+ break;
439
504
  case 'pink':
440
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-pink to-ui-pink transition-[background-size_color] contrast-more:from-ui-pink contrast-more:to-ui-pink');
505
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-pink)]');
506
+ break;
441
507
  case 'purple':
442
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-purple to-ui-purple transition-[background-size_color] contrast-more:from-ui-purple contrast-more:to-ui-purple');
508
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-purple)]');
509
+ break;
443
510
  case 'red':
444
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-red to-ui-red transition-[background-size_color] contrast-more:from-ui-red contrast-more:to-ui-red');
511
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-red)]');
512
+ break;
445
513
  case 'violet':
446
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-violet to-ui-violet transition-[background-size_color] contrast-more:from-ui-violet contrast-more:to-ui-violet');
514
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-violet)]');
515
+ break;
447
516
  case 'yellow':
448
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-yellow to-ui-yellow transition-[background-size_color] contrast-more:from-ui-yellow contrast-more:to-ui-yellow');
449
- case 'blue':
450
- default:
451
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-blue to-ui-blue transition-[background-size_color] contrast-more:from-ui-blue contrast-more:to-ui-blue');
517
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-yellow)]');
518
+ break;
519
+ case 'custom':
520
+ if (customTheme && customTheme.themeColor && !customTheme.themeColor.includes('[--theme-color:'))
521
+ throw new Error('`customTheme.themeColor` must modify the `--theme-color` variable. Otherwise, please use `customTheme.classes`.');
522
+ multilineFillColorClasses = customTheme.themeColor
523
+ ? twMerge(multilineFillColorClasses, customTheme.themeColor)
524
+ : twMerge(multilineFillBaseClasses, customTheme.classes);
525
+ break;
452
526
  }
527
+ return multilineFillColorClasses;
453
528
  };
454
- // Define theme-specific multiline fill classes
455
- const getMultilineFillClasses = (theme = 'blue') => {
529
+ const getMultilineFillClasses = (theme = 'blue', customTheme) => {
530
+ let multilineFillColorClasses = tailwindMerge.twJoin(multilineFillBaseClasses, 'from-(--theme-color)/0 to-(--theme-color)/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-(--theme-color) focus-visible:to-(--theme-color) focus-visible:bg-[size:100%_100%] active:from-(--theme-color) active:to-(--theme-color) active:bg-[size:100%_100%] contrast-more:from-(--theme-color)/0 pointer-fine:hover:from-(--theme-color) pointer-fine:hover:to-(--theme-color) pointer-fine:hover:bg-[size:100%_100%]');
456
531
  switch (theme) {
532
+ case 'blue':
533
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-blue)]');
534
+ break;
457
535
  case 'brown':
458
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-brown/0 to-ui-brown/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-brown focus-visible:to-ui-brown focus-visible:bg-[size:100%_100%] active:from-ui-brown active:to-ui-brown active:bg-[size:100%_100%] contrast-more:from-ui-brown/0 contrast-more:to-ui-brown/0 focus-visible:contrast-more:from-ui-brown focus-visible:contrast-more:to-ui-brown active:contrast-more:from-ui-brown active:contrast-more:to-ui-brown pointer-fine:hover:from-ui-brown pointer-fine:hover:to-ui-brown pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-brown pointer-fine:hover:contrast-more:to-ui-brown');
536
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-brown)]');
537
+ break;
459
538
  case 'green':
460
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-green/0 to-ui-green/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-green focus-visible:to-ui-green focus-visible:bg-[size:100%_100%] active:from-ui-green active:to-ui-green active:bg-[size:100%_100%] contrast-more:from-ui-green/0 contrast-more:to-ui-green/0 focus-visible:contrast-more:from-ui-green focus-visible:contrast-more:to-ui-green active:contrast-more:from-ui-green active:contrast-more:to-ui-green pointer-fine:hover:from-ui-green pointer-fine:hover:to-ui-green pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-green pointer-fine:hover:contrast-more:to-ui-green');
539
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-green)]');
540
+ break;
461
541
  case 'grey':
462
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-grey/0 to-ui-grey/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-grey focus-visible:to-ui-grey focus-visible:bg-[size:100%_100%] active:from-ui-grey active:to-ui-grey active:bg-[size:100%_100%] contrast-more:from-ui-grey/0 contrast-more:to-ui-grey/0 focus-visible:contrast-more:from-ui-grey focus-visible:contrast-more:to-ui-grey active:contrast-more:from-ui-grey active:contrast-more:to-ui-grey pointer-fine:hover:from-ui-grey pointer-fine:hover:to-ui-grey pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-grey pointer-fine:hover:contrast-more:to-ui-grey');
542
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-grey)]');
543
+ break;
463
544
  case 'sky-blue':
464
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-sky-blue/0 to-ui-sky-blue/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-sky-blue focus-visible:to-ui-sky-blue focus-visible:bg-[size:100%_100%] active:from-ui-sky-blue active:to-ui-sky-blue active:bg-[size:100%_100%] contrast-more:from-ui-sky-blue/0 contrast-more:to-ui-sky-blue/0 focus-visible:contrast-more:from-ui-sky-blue focus-visible:contrast-more:to-ui-sky-blue active:contrast-more:from-ui-sky-blue active:contrast-more:to-ui-sky-blue pointer-fine:hover:from-ui-sky-blue pointer-fine:hover:to-ui-sky-blue pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-sky-blue pointer-fine:hover:contrast-more:to-ui-sky-blue');
545
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-sky-blue)]');
546
+ break;
465
547
  case 'magenta':
466
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-magenta/0 to-ui-magenta/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-magenta focus-visible:to-ui-magenta focus-visible:bg-[size:100%_100%] active:from-ui-magenta active:to-ui-magenta active:bg-[size:100%_100%] contrast-more:from-ui-magenta/0 contrast-more:to-ui-magenta/0 focus-visible:contrast-more:from-ui-magenta focus-visible:contrast-more:to-ui-magenta active:contrast-more:from-ui-magenta active:contrast-more:to-ui-magenta pointer-fine:hover:from-ui-magenta pointer-fine:hover:to-ui-magenta pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-magenta pointer-fine:hover:contrast-more:to-ui-magenta');
467
- case 'neutral':
468
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-zinc-700/0 to-zinc-700/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-zinc-700 focus-visible:to-zinc-700 focus-visible:bg-[size:100%_100%] active:from-zinc-700 active:to-zinc-700 active:bg-[size:100%_100%] contrast-more:from-zinc-700/0 contrast-more:to-zinc-700/0 focus-visible:contrast-more:from-zinc-700 focus-visible:contrast-more:to-zinc-700 active:contrast-more:from-zinc-700 active:contrast-more:to-zinc-700 dark:from-zinc-300/0 dark:to-zinc-300/0 dark:focus-visible:from-zinc-300 dark:focus-visible:to-zinc-300 dark:active:from-zinc-300 dark:active:to-zinc-300 dark:contrast-more:from-zinc-300/0 dark:contrast-more:to-zinc-300/0 dark:focus-visible:contrast-more:from-zinc-300 dark:focus-visible:contrast-more:to-zinc-300 dark:active:contrast-more:from-zinc-300 dark:active:contrast-more:to-zinc-300 pointer-fine:hover:from-zinc-700 pointer-fine:hover:to-zinc-700 pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-zinc-700 pointer-fine:hover:contrast-more:to-zinc-700 dark:pointer-fine:hover:from-zinc-300 dark:pointer-fine:hover:to-zinc-300 dark:pointer-fine:hover:contrast-more:from-zinc-300 dark:pointer-fine:hover:contrast-more:to-zinc-300');
548
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-magenta)]');
549
+ break;
469
550
  case 'orange':
470
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-orange/0 to-ui-orange/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-orange focus-visible:to-ui-orange focus-visible:bg-[size:100%_100%] active:from-ui-orange active:to-ui-orange active:bg-[size:100%_100%] contrast-more:from-ui-orange/0 contrast-more:to-ui-orange/0 focus-visible:contrast-more:from-ui-orange focus-visible:contrast-more:to-ui-orange active:contrast-more:from-ui-orange active:contrast-more:to-ui-orange pointer-fine:hover:from-ui-orange pointer-fine:hover:to-ui-orange pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-orange pointer-fine:hover:contrast-more:to-ui-orange');
551
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-orange)]');
552
+ break;
471
553
  case 'pink':
472
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-pink/0 to-ui-pink/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-pink focus-visible:to-ui-pink focus-visible:bg-[size:100%_100%] active:from-ui-pink active:to-ui-pink active:bg-[size:100%_100%] contrast-more:from-ui-pink/0 contrast-more:to-ui-pink/0 focus-visible:contrast-more:from-ui-pink focus-visible:contrast-more:to-ui-pink active:contrast-more:from-ui-pink active:contrast-more:to-ui-pink pointer-fine:hover:from-ui-pink pointer-fine:hover:to-ui-pink pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-pink pointer-fine:hover:contrast-more:to-ui-pink');
554
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-pink)]');
555
+ break;
473
556
  case 'purple':
474
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-purple/0 to-ui-purple/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-purple focus-visible:to-ui-purple focus-visible:bg-[size:100%_100%] active:from-ui-purple active:to-ui-purple active:bg-[size:100%_100%] contrast-more:from-ui-purple/0 contrast-more:to-ui-purple/0 focus-visible:contrast-more:from-ui-purple focus-visible:contrast-more:to-ui-purple active:contrast-more:from-ui-purple active:contrast-more:to-ui-purple pointer-fine:hover:from-ui-purple pointer-fine:hover:to-ui-purple pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-purple pointer-fine:hover:contrast-more:to-ui-purple');
557
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-purple)]');
558
+ break;
475
559
  case 'red':
476
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-red/0 to-ui-red/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-red focus-visible:to-ui-red focus-visible:bg-[size:100%_100%] active:from-ui-red active:to-ui-red active:bg-[size:100%_100%] contrast-more:from-ui-red/0 contrast-more:to-ui-red/0 focus-visible:contrast-more:from-ui-red focus-visible:contrast-more:to-ui-red active:contrast-more:from-ui-red active:contrast-more:to-ui-red pointer-fine:hover:from-ui-red pointer-fine:hover:to-ui-red pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-red pointer-fine:hover:contrast-more:to-ui-red');
560
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-red)]');
561
+ break;
477
562
  case 'violet':
478
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-violet/0 to-ui-violet/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-violet focus-visible:to-ui-violet focus-visible:bg-[size:100%_100%] active:from-ui-violet active:to-ui-violet active:bg-[size:100%_100%] contrast-more:from-ui-violet/0 contrast-more:to-ui-violet/0 focus-visible:contrast-more:from-ui-violet focus-visible:contrast-more:to-ui-violet active:contrast-more:from-ui-violet active:contrast-more:to-ui-violet pointer-fine:hover:from-ui-violet pointer-fine:hover:to-ui-violet pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-violet pointer-fine:hover:contrast-more:to-ui-violet');
563
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-violet)]');
564
+ break;
479
565
  case 'yellow':
480
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-yellow/0 to-ui-yellow/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-yellow focus-visible:to-ui-yellow focus-visible:bg-[size:100%_100%] active:from-ui-yellow active:to-ui-yellow active:bg-[size:100%_100%] contrast-more:from-ui-yellow/0 contrast-more:to-ui-yellow/0 focus-visible:contrast-more:from-ui-yellow focus-visible:contrast-more:to-ui-yellow active:contrast-more:from-ui-yellow active:contrast-more:to-ui-yellow pointer-fine:hover:from-ui-yellow pointer-fine:hover:to-ui-yellow pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-yellow pointer-fine:hover:contrast-more:to-ui-yellow');
481
- case 'blue':
482
- default:
483
- return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-blue/0 to-ui-blue/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-blue focus-visible:to-ui-blue focus-visible:bg-[size:100%_100%] active:from-ui-blue active:to-ui-blue active:bg-[size:100%_100%] contrast-more:from-ui-blue/0 contrast-more:to-ui-blue/0 focus-visible:contrast-more:from-ui-blue focus-visible:contrast-more:to-ui-blue active:contrast-more:from-ui-blue active:contrast-more:to-ui-blue pointer-fine:hover:from-ui-blue pointer-fine:hover:to-ui-blue pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-blue pointer-fine:hover:contrast-more:to-ui-blue');
566
+ multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, '[--theme-color:var(--color-ui-yellow)]');
567
+ break;
568
+ case 'custom':
569
+ if (customTheme && customTheme.themeColor && !customTheme.themeColor.includes('[--theme-color:'))
570
+ throw new Error('`customTheme.themeColor` must modify the `--theme-color` variable. Otherwise, please use `customTheme.classes`.');
571
+ multilineFillColorClasses = customTheme.themeColor
572
+ ? twMerge(multilineFillColorClasses, customTheme.themeColor)
573
+ : twMerge(multilineFillBaseClasses, customTheme.classes);
574
+ break;
484
575
  }
576
+ return multilineFillColorClasses;
485
577
  };
486
- const getMultilineFillLiftClasses = (theme = 'blue') => {
487
- return tailwindMerge.twJoin(getMultilineFillColorClasses(theme), 'bg-[size:auto_0px] bg-[position:50%_100%] focus-visible:bg-[size:auto_100%] active:bg-[size:auto_100%] pointer-fine:hover:bg-[size:auto_100%]');
578
+ const getMultilineFillLiftClasses = (theme = 'blue', customTheme) => {
579
+ return tailwindMerge.twJoin(getMultilineFillColorClasses(theme, customTheme), 'bg-[size:auto_0px] bg-[position:50%_100%] focus-visible:bg-[size:auto_100%] active:bg-[size:auto_100%] pointer-fine:hover:bg-[size:auto_100%]');
488
580
  };
489
- const getMultilineFillXClasses = (theme = 'blue') => {
490
- return tailwindMerge.twJoin(getMultilineFillColorClasses(theme), 'bg-[size:0%_100%] focus-visible:bg-[size:100%_100%] active:bg-[size:100%_100%] pointer-fine:hover:bg-[size:100%_100%]');
581
+ const getMultilineFillXClasses = (theme = 'blue', customTheme) => {
582
+ return tailwindMerge.twJoin(getMultilineFillColorClasses(theme, customTheme), 'bg-[size:0%_100%] focus-visible:bg-[size:100%_100%] active:bg-[size:100%_100%] pointer-fine:hover:bg-[size:100%_100%]');
491
583
  };
492
- const getMultilineFillRtlClasses = (theme = 'blue') => {
493
- return tailwindMerge.twJoin(getMultilineFillXClasses(theme), 'bg-[position:100%_auto]');
584
+ const getMultilineFillRtlClasses = (theme = 'blue', customTheme) => {
585
+ return tailwindMerge.twJoin(getMultilineFillXClasses(theme, customTheme), 'bg-[position:100%_auto]');
494
586
  };
495
- const getMultilineFillCenterClasses = (theme = 'blue') => {
496
- return tailwindMerge.twJoin(getMultilineFillXClasses(theme), 'bg-[position:50%_auto]');
587
+ const getMultilineFillCenterClasses = (theme = 'blue', customTheme) => {
588
+ return tailwindMerge.twJoin(getMultilineFillXClasses(theme, customTheme), 'bg-[position:50%_auto]');
497
589
  };
498
590
  /**
499
591
  * # Link
@@ -524,7 +616,7 @@ const getMultilineFillCenterClasses = (theme = 'blue') => {
524
616
  * @example
525
617
  * <Link href='/about' type='fill-ltr' theme='red' title='About Us'>Learn more about our company</Link>
526
618
  */
527
- function Link({ as, className, ref, theme = 'blue', type, ...props }) {
619
+ function Link({ as, className, customTheme, theme = 'blue', type, ...props }) {
528
620
  const getLinkClasses = () => {
529
621
  switch (type) {
530
622
  case 'static':
@@ -538,13 +630,13 @@ function Link({ as, className, ref, theme = 'blue', type, ...props }) {
538
630
  case 'lift':
539
631
  return lineLiftClasses;
540
632
  case 'fill':
541
- return getFillCenterClasses(theme);
633
+ return getFillCenterClasses(theme, customTheme);
542
634
  case 'fill-ltr':
543
- return tailwindMerge.twJoin([getFillColorTransitionClasses(theme), scaleXClasses, 'after:origin-left']);
635
+ return tailwindMerge.twJoin([getFillColorTransitionClasses(theme, customTheme), scaleXClasses, 'after:origin-left']);
544
636
  case 'fill-rtl':
545
- return tailwindMerge.twJoin([getFillColorTransitionClasses(theme), scaleXClasses, 'after:origin-right']);
637
+ return tailwindMerge.twJoin([getFillColorTransitionClasses(theme, customTheme), scaleXClasses, 'after:origin-right']);
546
638
  case 'fill-lift':
547
- return tailwindMerge.twJoin([getFillColorTransitionClasses(theme), scaleYClasses, 'after:origin-bottom']);
639
+ return tailwindMerge.twJoin([getFillColorTransitionClasses(theme, customTheme), scaleYClasses, 'after:origin-bottom']);
548
640
  case 'multiline':
549
641
  return multilineNormalClasses;
550
642
  case 'multiline-static':
@@ -558,29 +650,29 @@ function Link({ as, className, ref, theme = 'blue', type, ...props }) {
558
650
  case 'multiline-lift':
559
651
  return multilineLineLiftClasses;
560
652
  case 'multiline-fill':
561
- return getMultilineFillClasses(theme);
653
+ return getMultilineFillClasses(theme, customTheme);
562
654
  case 'multiline-fill-ltr':
563
- return getMultilineFillXClasses(theme);
655
+ return getMultilineFillXClasses(theme, customTheme);
564
656
  case 'multiline-fill-rtl':
565
- return getMultilineFillRtlClasses(theme);
657
+ return getMultilineFillRtlClasses(theme, customTheme);
566
658
  case 'multiline-fill-center':
567
- return getMultilineFillCenterClasses(theme);
659
+ return getMultilineFillCenterClasses(theme, customTheme);
568
660
  case 'multiline-fill-lift':
569
- return getMultilineFillLiftClasses(theme);
661
+ return getMultilineFillLiftClasses(theme, customTheme);
570
662
  default:
571
663
  return lineNormalClasses;
572
664
  }
573
665
  };
574
666
  const linkClasses = getLinkClasses();
575
667
  const LinkElement = as || Anchor;
576
- return jsxRuntime.jsx(LinkElement, { ...props, className: twMerge(linkClasses, className), ref: ref });
668
+ return jsxRuntime.jsx(LinkElement, { ...props, className: twMerge(linkClasses, className) });
577
669
  }
578
670
 
579
671
  /**
580
672
  * # Button
581
673
  * - A pre-styled button with utility props for easy customization depending on use case.
582
674
  */
583
- function Button({ className, padding = 'md', rounded = 'lg', theme = 'blue', ref, ...props }) {
675
+ function Button({ className, customTheme, gradient = false, padding = 'md', rounded = 'lg', theme = 'blue', ...props }) {
584
676
  const getPaddingClasses = () => {
585
677
  switch (padding) {
586
678
  case 'xs':
@@ -611,104 +703,120 @@ function Button({ className, padding = 'md', rounded = 'lg', theme = 'blue', ref
611
703
  return 'rounded-full';
612
704
  }
613
705
  };
614
- const getThemeClasses = () => {
615
- const classList = [];
706
+ const getThemeColorVariable = () => {
616
707
  switch (theme) {
617
708
  case 'blue':
618
- classList.push(twSort('text-white shadow-lg shadow-ui-blue/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-blue before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
619
- break;
620
- case 'blue-gradient':
621
- classList.push(twSort('bg-ui-blue text-white shadow-lg shadow-ui-blue/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
622
- break;
709
+ return twSort('text-white [--theme-color:var(--color-ui-blue)]');
623
710
  case 'brown':
624
- classList.push(twSort('text-white shadow-lg shadow-ui-brown/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-brown before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
625
- break;
626
- case 'brown-gradient':
627
- classList.push(twSort('bg-ui-brown text-white shadow-lg shadow-ui-brown/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
628
- break;
711
+ return twSort('text-white [--theme-color:var(--color-ui-brown)]');
629
712
  case 'green':
630
- classList.push(twSort('text-white shadow-lg shadow-ui-green/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-green before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
631
- break;
632
- case 'green-gradient':
633
- classList.push(twSort('bg-ui-green text-white shadow-lg shadow-ui-green/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
634
- break;
713
+ return twSort('text-white [--theme-color:var(--color-ui-green)]');
635
714
  case 'grey':
636
- classList.push(twSort('text-white shadow-lg shadow-ui-grey/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-grey before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
637
- break;
638
- case 'grey-gradient':
639
- classList.push(twSort('bg-ui-grey text-white shadow-lg shadow-ui-grey/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
640
- break;
641
- case 'sky-blue':
642
- classList.push(twSort('text-white shadow-lg shadow-ui-sky-blue/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-sky-blue before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
643
- break;
644
- case 'sky-blue-gradient':
645
- classList.push(twSort('bg-ui-sky-blue text-white shadow-lg shadow-ui-sky-blue/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
646
- break;
715
+ return twSort('text-white [--theme-color:var(--color-ui-grey)]');
647
716
  case 'magenta':
648
- classList.push(twSort('text-white shadow-lg shadow-ui-magenta/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-magenta before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
649
- break;
650
- case 'magenta-gradient':
651
- classList.push(twSort('bg-ui-magenta text-white shadow-lg shadow-ui-magenta/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
652
- break;
653
- case 'neutral':
654
- classList.push(twSort('pointer-fine:active:before:brightness-90text-white dark bg-zinc-200 text-black before:absolute before:inset-0 before:rounded-[inherit] before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 dark:bg-zinc-800 pointer-fine:hover:before:brightness-110'));
655
- break;
656
- case 'neutral-gradient':
657
- classList.push(twSort('dark bg-linear-to-t from-zinc-300 via-zinc-200 to-zinc-100 text-black before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 dark:from-zinc-900 dark:via-zinc-800 dark:to-zinc-700 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
658
- break;
717
+ return twSort('text-white [--theme-color:var(--color-ui-magenta)]');
659
718
  case 'orange':
660
- classList.push(twSort('text-white shadow-lg shadow-ui-orange/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-orange before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
661
- break;
662
- case 'orange-gradient':
663
- classList.push(twSort('bg-ui-orange text-white shadow-lg shadow-ui-orange/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
664
- break;
719
+ return twSort('text-white [--theme-color:var(--color-ui-orange)]');
665
720
  case 'pink':
666
- classList.push(twSort('text-white shadow-lg shadow-ui-pink/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-pink before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
667
- break;
668
- case 'pink-gradient':
669
- classList.push(twSort('before:to-white/75/75 bg-ui-pink text-white shadow-lg shadow-ui-pink/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
670
- break;
721
+ return twSort('text-white [--theme-color:var(--color-ui-pink)]');
671
722
  case 'purple':
672
- classList.push(twSort('text-white shadow-lg shadow-ui-purple/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-purple before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
673
- break;
674
- case 'purple-gradient':
675
- classList.push(twSort('bg-ui-purple text-white shadow-lg shadow-ui-purple/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
676
- break;
723
+ return twSort('text-white [--theme-color:var(--color-ui-purple)]');
677
724
  case 'red':
678
- classList.push(twSort('text-white shadow-lg shadow-ui-red/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-red before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
679
- break;
680
- case 'red-gradient':
681
- classList.push(twSort('bg-ui-red text-white shadow-lg shadow-ui-red/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
682
- break;
725
+ return twSort('text-white [--theme-color:var(--color-ui-red)]');
726
+ case 'sky-blue':
727
+ return twSort('text-white [--theme-color:var(--color-ui-sky-blue)]');
683
728
  case 'violet':
684
- classList.push(twSort('text-white shadow-lg shadow-ui-violet/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-violet before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
685
- break;
686
- case 'violet-gradient':
687
- classList.push(twSort('bg-ui-violet text-white shadow-lg shadow-ui-violet/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
688
- break;
729
+ return twSort('text-white [--theme-color:var(--color-ui-violet)]');
689
730
  case 'yellow':
690
- classList.push(twSort('text-black shadow-lg shadow-ui-yellow/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-yellow before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
691
- break;
692
- case 'yellow-gradient':
693
- classList.push(twSort('bg-ui-yellow text-black shadow-lg shadow-ui-yellow/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black before:via-black/50 before:to-white/50 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
694
- break;
731
+ return twSort('text-black [--theme-color:var(--color-ui-yellow)]');
732
+ case 'custom':
733
+ if (customTheme && customTheme.themeColor && !customTheme.themeColor.includes('[--theme-color:'))
734
+ throw new Error('`customTheme.themeColor` must modify the `--theme-color` variable. Otherwise, please use `customTheme.classes`.');
735
+ return customTheme.themeColor || customTheme.classes;
695
736
  }
696
- return classList.join(' ');
697
737
  };
698
- const paddingClasses = getPaddingClasses(), roundedClasses = getRoundedClasses(), themeClasses = getThemeClasses();
738
+ const paddingClasses = getPaddingClasses(), roundedClasses = getRoundedClasses(), themeColorVariable = getThemeColorVariable();
739
+ const themeClasses = customTheme && customTheme.classes
740
+ ? customTheme.classes
741
+ : [
742
+ gradient
743
+ ? twSort('bg-linear-to-t from-[color-mix(in_oklab,var(--theme-color),var(--color-black)_20%)] via-(--theme-color) to-[color-mix(in_oklab,var(--theme-color),var(--color-white)_20%)] bg-[size:100%_200%] transition-[scale,background-position-y] [background-position-y:50%] active:[background-position-y:100%] data-focus:[background-position-y:0%] pointer-fine:hover:[background-position-y:0%] pointer-fine:hover:active:[background-position-y:100%]')
744
+ : twSort('bg-(--theme-color) transition-[scale,background-color] active:bg-[color-mix(in_oklab,var(--theme-color),var(--color-black)_10%)] data-focus:bg-[color-mix(in_oklab,var(--theme-color),var(--color-white)_10%)] pointer-fine:hover:bg-[color-mix(in_oklab,var(--theme-color),var(--color-white)_10%)] pointer-fine:hover:active:bg-[color-mix(in_oklab,var(--theme-color),var(--color-black)_10%)]'),
745
+ 'shadow-(--theme-color)/25',
746
+ ].join(' ');
699
747
  const buttonClasses = twMerge([
700
- 'block w-fit min-w-fit text-center font-semibold duration-300 ease-exponential focus-visible:scale-101 active:scale-95 pointer-fine:hover:scale-101 pointer-fine:active:scale-99',
748
+ 'block w-fit min-w-fit text-center font-semibold shadow-lg duration-300 ease-exponential active:scale-99 data-focus:scale-101 pointer-fine:hover:scale-101 pointer-fine:hover:active:scale-99',
701
749
  paddingClasses,
702
750
  roundedClasses,
751
+ themeColorVariable,
703
752
  themeClasses,
704
753
  className,
705
754
  ]);
706
- return 'href' in props && typeof props.href === 'string' ? (jsxRuntime.jsx(Anchor, { ref: ref, ...props, className: buttonClasses })) : (jsxRuntime.jsx(react$1.Button, { ref: ref, ...props, className: buttonClasses }));
755
+ const ButtonElement = 'as' in props ? props.as : props.href ? Anchor : react.Button;
756
+ const { as, ...restProps } = 'as' in props ? props : { ...props, as: undefined };
757
+ return jsxRuntime.jsx(ButtonElement, { ...restProps, className: buttonClasses });
758
+ }
759
+
760
+ function ChevronDown(props) {
761
+ return (jsxRuntime.jsx("svg", { viewBox: '0 0 64 36', ...props, children: jsxRuntime.jsx("path", { d: 'M32,36c1,0,1.8-0.4,2.5-1.1L63,5.7c0.7-0.7,1-1.4,1-2.3c0-1-0.3-1.8-1-2.4c-0.6-0.7-1.4-1-2.3-1s-1.7,0.3-2.4,1L30,29.8H34 L5.7,1C5.1,0.3,4.3,0,3.4,0C2.4,0,1.6,0.3,1,1C0.3,1.6,0,2.4,0,3.4c0,0.9,0.3,1.7,1,2.3l28.5,29.2C30.3,35.7,31.1,36,32,36z' }) }));
762
+ }
763
+
764
+ function ExclamationmarkOctagon(props) {
765
+ return (jsxRuntime.jsxs("svg", { viewBox: '0 0 64 61.6', ...props, children: [jsxRuntime.jsx("path", { d: 'M61.4,16.8l-12.1-13.3C47.3,1.3,45.4,0,41.4,0h-18.9C18.6,0,16.7,1.3,14.7,3.5L2.6,16.8c-2,2.3-2.6,3.8-2.6,6.9v14.2c0,3.1.5,4.6,2.6,6.9l12.1,13.3c2,2.2,3.9,3.5,7.8,3.5h18.9c4,0,5.8-1.3,7.9-3.5l12.1-13.3c2.1-2.3,2.6-3.8,2.6-6.9v-14.2c0-3.1-.5-4.6-2.6-6.9ZM58.2,37.3c0,2.3-.3,3.1-1.5,4.4l-11.2,12.3c-1.7,1.9-2.6,2.5-5.8,2.5h-15.5c-3.1,0-4-.7-5.7-2.5l-11.2-12.3c-1.2-1.4-1.5-2.2-1.5-4.4v-13.1c0-2.3.3-3.1,1.5-4.4l11.2-12.3c1.7-1.9,2.6-2.5,5.7-2.5h15.5c3.1,0,4,.7,5.8,2.5l11.2,12.3c1.3,1.4,1.5,2.2,1.5,4.4v13.1Z' }), jsxRuntime.jsx("path", { d: 'M32,36.4c1.5,0,2.4-.9,2.4-2.5l.4-16.4c0-1.6-1.2-2.8-2.9-2.8s-2.9,1.1-2.8,2.7l.4,16.5c0,1.6.9,2.5,2.4,2.5Z' }), jsxRuntime.jsx("path", { d: 'M32,46.5c1.8,0,3.4-1.4,3.4-3.2s-1.5-3.2-3.4-3.2-3.3,1.4-3.3,3.2,1.5,3.2,3.3,3.2Z' })] }));
766
+ }
767
+
768
+ function xmark(props) {
769
+ return (jsxRuntime.jsx("svg", { viewBox: '0 0 64 64', ...props, children: jsxRuntime.jsx("path", { d: 'M1,63c0.7,0.7,1.6,1,2.6,1s1.9-0.3,2.6-1L32,37.1L57.8,63c0.7,0.7,1.5,1,2.5,1c1,0,1.9-0.3,2.6-1c0.7-0.7,1-1.6,1-2.6 c0-1-0.3-1.8-1-2.5L37.1,32L63,6.2c0.7-0.7,1-1.6,1-2.6S63.7,1.7,63,1c-0.7-0.7-1.6-1-2.6-1c-1,0-1.8,0.3-2.5,1L32,26.9L6.2,1 C5.5,0.3,4.6,0,3.6,0C2.6,0,1.7,0.3,1,1C0.3,1.7,0,2.6,0,3.6c0,1,0.3,1.9,1,2.6L26.9,32L1,57.8c-0.7,0.7-1,1.5-1,2.6 C0,61.4,0.3,62.3,1,63z' }) }));
770
+ }
771
+
772
+ function DetailsSummary({ arrow = true, as, children, className, ...props }) {
773
+ return (
774
+ // @ts-expect-error Button has some extra props
775
+ jsxRuntime.jsx(react.DisclosureButton, { ...props, as: as || (Button), className: twMerge('w-full', className, Boolean(arrow) && 'grid grid-cols-[1fr_1rem] gap-2'), role: 'summary', children: bag => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [typeof children === 'function' ? children(bag) : children, arrow &&
776
+ (typeof arrow === 'boolean' ? (jsxRuntime.jsx(ChevronDown, { className: 'absolute top-1/2 right-3 block w-4 -translate-y-1/2' })) : (arrow))] })) }));
777
+ }
778
+ function DetailsBody({ children, className, ...props }) {
779
+ return (jsxRuntime.jsx(react.DisclosurePanel, { ...props, className: twMerge('grid grid-rows-1fr transition-rows duration-500 ease-exponential data-closed:grid-rows-0fr', className), transition: true, children: bag => (jsxRuntime.jsx("div", { className: 'overflow-y-hidden px-2 pt-3 pb-1', children: typeof children === 'function' ? children(bag) : children })) }));
780
+ }
781
+ function Details({ as = 'div', className, ...props }) {
782
+ return (jsxRuntime.jsx(react.Disclosure, { ...props, as: as, className: twMerge('rounded-2xl bg-neutral-50/20 p-2 backdrop-blur-md backdrop-brightness-150', className), role: 'details' }));
783
+ }
784
+
785
+ function DropDownButton({ arrow = true, as, children, className, ...props }) {
786
+ return (jsxRuntime.jsxs(react.MenuButton, { ...props, as: as || 'button', className: tailwindMerge.twJoin('group/button', className), children: [children, arrow &&
787
+ (typeof arrow === 'boolean' ? (jsxRuntime.jsx(ChevronDown, { className: '-top-px -mr-1 ml-2 w-4 animate-flip-again group-data-open/button:animate-flip' })) : (arrow))] }));
788
+ }
789
+ function DropDownItem({ as, ...props }) {
790
+ return jsxRuntime.jsx(react.MenuItem, { as: as || 'div', ...props });
791
+ }
792
+ function DropDownItems({ anchor, children, className, style, ...props }) {
793
+ const getAnchorProps = () => {
794
+ let initialAnchor = { gap: '1rem', padding: '1rem', to: 'bottom start' };
795
+ if (anchor) {
796
+ if (typeof anchor === 'string')
797
+ initialAnchor.to = anchor;
798
+ if (typeof anchor === 'object')
799
+ initialAnchor = { ...initialAnchor, ...anchor };
800
+ }
801
+ return initialAnchor;
802
+ };
803
+ const anchorProps = getAnchorProps();
804
+ return (jsxRuntime.jsx(react.MenuItems, { ...props, anchor: anchorProps, className: 'grid grid-rows-1fr rounded-xl shadow-xl transition-rows duration-500 ease-exponential data-closed:grid-rows-0fr', transition: true, style: { ...style, minWidth: 'var(--button-width)' }, children: bag => (jsxRuntime.jsx("div", { className: 'overflow-y-hidden', children: jsxRuntime.jsx("div", { className: twMerge('bg-neutral-50/20 px-6 py-5 backdrop-blur-md backdrop-brightness-150', className), children: typeof children === 'function' ? children(bag) : children }) })) }));
805
+ }
806
+ function DropDownSection({ children, label, labelProps, separatorAbove, separatorBelow, ...props }) {
807
+ const { labelClassName, ...restLabelProps } = { labelClassName: labelProps?.className || '', ...labelProps };
808
+ return (jsxRuntime.jsx(react.MenuSection, { ...props, children: sectionBag => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [separatorAbove && jsxRuntime.jsx(DropDownSeparator, {}), jsxRuntime.jsx(react.MenuHeading, { ...restLabelProps, className: headingBag => twMerge('text-[size:larger] font-bold', typeof labelClassName === 'function' ? labelClassName(headingBag) : labelClassName), children: label }), typeof children === 'function' ? children(sectionBag) : children, separatorBelow && jsxRuntime.jsx(DropDownSeparator, {})] })) }));
809
+ }
810
+ function DropDownSeparator({ className, ...props }) {
811
+ return (jsxRuntime.jsx(react.MenuSeparator, { ...props, className: bag => twMerge('my-4 block h-px rounded-full bg-neutral-950/20', typeof className === 'function' ? className(bag) : className) }));
812
+ }
813
+ function DropDown(props) {
814
+ return jsxRuntime.jsx(react.Menu, { ...props });
707
815
  }
708
816
 
709
817
  function createFastContext(defaultInitialState) {
710
818
  function useStoreData(initialState = defaultInitialState) {
711
- const store = react.useRef(initialState), get = () => store.current, subscribers = react.useRef(new Set());
819
+ const store = React.useRef(initialState), get = () => store.current, subscribers = React.useRef(new Set());
712
820
  const set = (value) => {
713
821
  if (typeof value === 'function') {
714
822
  store.current = value(store.current);
@@ -728,19 +836,19 @@ function createFastContext(defaultInitialState) {
728
836
  subscribe,
729
837
  };
730
838
  }
731
- const StoreContext = react.createContext(null);
839
+ const StoreContext = React.createContext(null);
732
840
  function Provider({ initialValue = defaultInitialState, ...props }) {
733
841
  return jsxRuntime.jsx(StoreContext.Provider, { value: useStoreData(initialValue), ...props });
734
842
  }
735
843
  function useStore(selector, initialValue) {
736
- const store = react.useContext(StoreContext);
844
+ const store = React.useContext(StoreContext);
737
845
  if (!store) {
738
846
  const localStoreValue = initialValue !== undefined ? initialValue : defaultInitialState;
739
847
  const selectedValue = selector(localStoreValue);
740
848
  const noOpSet = () => console.warn('Attempting to set store value outside of Provider');
741
849
  return [selectedValue, noOpSet];
742
850
  }
743
- const state = react.useSyncExternalStore(store.subscribe, () => selector(store.get()), () => selector(initialValue !== undefined ? initialValue : defaultInitialState));
851
+ const state = React.useSyncExternalStore(store.subscribe, () => selector(store.get()), () => selector(initialValue !== undefined ? initialValue : defaultInitialState));
744
852
  return [state, store.set];
745
853
  }
746
854
  return {
@@ -768,36 +876,2213 @@ function useFormContext() {
768
876
  const DEFAULT_STATUS = 'incomplete';
769
877
  const { Provider, useStore } = createFastContext(DEFAULT_STATUS);
770
878
  function FormStatusProvider({ children, initialStatus = DEFAULT_STATUS, }) {
771
- return (jsxRuntime.jsx(react.Suspense, { children: jsxRuntime.jsx(Provider, { initialValue: initialStatus, children: children }) }));
879
+ return (jsxRuntime.jsx(React.Suspense, { children: jsxRuntime.jsx(Provider, { initialValue: initialStatus, children: children }) }));
772
880
  }
773
881
  function useFormStatus() {
774
882
  return useStore(store => store);
775
883
  }
776
884
 
777
- function validateField$1(value, { required, type }) {
778
- const noValue = !value || value === '';
779
- if (!required && noValue)
780
- return true;
781
- if (noValue)
885
+ function Fieldset({ children, className, legend, legendProps, ...props }) {
886
+ const { className: legendClassName, ...restLegendProps } = legendProps || {};
887
+ return (jsxRuntime.jsx(react.Fieldset, { ...props, className: bag => twMerge('contents', typeof className === 'function' ? className(bag) : className), children: bag => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(react.Legend, { ...restLegendProps, className: twMerge('text-lg font-bold sm:text-xl', typeof legendClassName === 'function' ? legendClassName(bag) : legendClassName), children: legend }), typeof children === 'function' ? children(bag) : children] })) }));
888
+ }
889
+
890
+ /**
891
+ * Custom positioning reference element.
892
+ * @see https://floating-ui.com/docs/virtual-elements
893
+ */
894
+
895
+ const min = Math.min;
896
+ const max = Math.max;
897
+ const round = Math.round;
898
+ const floor = Math.floor;
899
+ const createCoords = v => ({
900
+ x: v,
901
+ y: v
902
+ });
903
+ const oppositeSideMap = {
904
+ left: 'right',
905
+ right: 'left',
906
+ bottom: 'top',
907
+ top: 'bottom'
908
+ };
909
+ const oppositeAlignmentMap = {
910
+ start: 'end',
911
+ end: 'start'
912
+ };
913
+ function clamp(start, value, end) {
914
+ return max(start, min(value, end));
915
+ }
916
+ function evaluate(value, param) {
917
+ return typeof value === 'function' ? value(param) : value;
918
+ }
919
+ function getSide(placement) {
920
+ return placement.split('-')[0];
921
+ }
922
+ function getAlignment(placement) {
923
+ return placement.split('-')[1];
924
+ }
925
+ function getOppositeAxis(axis) {
926
+ return axis === 'x' ? 'y' : 'x';
927
+ }
928
+ function getAxisLength(axis) {
929
+ return axis === 'y' ? 'height' : 'width';
930
+ }
931
+ const yAxisSides = /*#__PURE__*/new Set(['top', 'bottom']);
932
+ function getSideAxis(placement) {
933
+ return yAxisSides.has(getSide(placement)) ? 'y' : 'x';
934
+ }
935
+ function getAlignmentAxis(placement) {
936
+ return getOppositeAxis(getSideAxis(placement));
937
+ }
938
+ function getAlignmentSides(placement, rects, rtl) {
939
+ if (rtl === void 0) {
940
+ rtl = false;
941
+ }
942
+ const alignment = getAlignment(placement);
943
+ const alignmentAxis = getAlignmentAxis(placement);
944
+ const length = getAxisLength(alignmentAxis);
945
+ let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
946
+ if (rects.reference[length] > rects.floating[length]) {
947
+ mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
948
+ }
949
+ return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
950
+ }
951
+ function getExpandedPlacements(placement) {
952
+ const oppositePlacement = getOppositePlacement(placement);
953
+ return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
954
+ }
955
+ function getOppositeAlignmentPlacement(placement) {
956
+ return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
957
+ }
958
+ const lrPlacement = ['left', 'right'];
959
+ const rlPlacement = ['right', 'left'];
960
+ const tbPlacement = ['top', 'bottom'];
961
+ const btPlacement = ['bottom', 'top'];
962
+ function getSideList(side, isStart, rtl) {
963
+ switch (side) {
964
+ case 'top':
965
+ case 'bottom':
966
+ if (rtl) return isStart ? rlPlacement : lrPlacement;
967
+ return isStart ? lrPlacement : rlPlacement;
968
+ case 'left':
969
+ case 'right':
970
+ return isStart ? tbPlacement : btPlacement;
971
+ default:
972
+ return [];
973
+ }
974
+ }
975
+ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
976
+ const alignment = getAlignment(placement);
977
+ let list = getSideList(getSide(placement), direction === 'start', rtl);
978
+ if (alignment) {
979
+ list = list.map(side => side + "-" + alignment);
980
+ if (flipAlignment) {
981
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
982
+ }
983
+ }
984
+ return list;
985
+ }
986
+ function getOppositePlacement(placement) {
987
+ return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]);
988
+ }
989
+ function expandPaddingObject(padding) {
990
+ return {
991
+ top: 0,
992
+ right: 0,
993
+ bottom: 0,
994
+ left: 0,
995
+ ...padding
996
+ };
997
+ }
998
+ function getPaddingObject(padding) {
999
+ return typeof padding !== 'number' ? expandPaddingObject(padding) : {
1000
+ top: padding,
1001
+ right: padding,
1002
+ bottom: padding,
1003
+ left: padding
1004
+ };
1005
+ }
1006
+ function rectToClientRect(rect) {
1007
+ const {
1008
+ x,
1009
+ y,
1010
+ width,
1011
+ height
1012
+ } = rect;
1013
+ return {
1014
+ width,
1015
+ height,
1016
+ top: y,
1017
+ left: x,
1018
+ right: x + width,
1019
+ bottom: y + height,
1020
+ x,
1021
+ y
1022
+ };
1023
+ }
1024
+
1025
+ function computeCoordsFromPlacement(_ref, placement, rtl) {
1026
+ let {
1027
+ reference,
1028
+ floating
1029
+ } = _ref;
1030
+ const sideAxis = getSideAxis(placement);
1031
+ const alignmentAxis = getAlignmentAxis(placement);
1032
+ const alignLength = getAxisLength(alignmentAxis);
1033
+ const side = getSide(placement);
1034
+ const isVertical = sideAxis === 'y';
1035
+ const commonX = reference.x + reference.width / 2 - floating.width / 2;
1036
+ const commonY = reference.y + reference.height / 2 - floating.height / 2;
1037
+ const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
1038
+ let coords;
1039
+ switch (side) {
1040
+ case 'top':
1041
+ coords = {
1042
+ x: commonX,
1043
+ y: reference.y - floating.height
1044
+ };
1045
+ break;
1046
+ case 'bottom':
1047
+ coords = {
1048
+ x: commonX,
1049
+ y: reference.y + reference.height
1050
+ };
1051
+ break;
1052
+ case 'right':
1053
+ coords = {
1054
+ x: reference.x + reference.width,
1055
+ y: commonY
1056
+ };
1057
+ break;
1058
+ case 'left':
1059
+ coords = {
1060
+ x: reference.x - floating.width,
1061
+ y: commonY
1062
+ };
1063
+ break;
1064
+ default:
1065
+ coords = {
1066
+ x: reference.x,
1067
+ y: reference.y
1068
+ };
1069
+ }
1070
+ switch (getAlignment(placement)) {
1071
+ case 'start':
1072
+ coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
1073
+ break;
1074
+ case 'end':
1075
+ coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
1076
+ break;
1077
+ }
1078
+ return coords;
1079
+ }
1080
+
1081
+ /**
1082
+ * Computes the `x` and `y` coordinates that will place the floating element
1083
+ * next to a given reference element.
1084
+ *
1085
+ * This export does not have any `platform` interface logic. You will need to
1086
+ * write one for the platform you are using Floating UI with.
1087
+ */
1088
+ const computePosition$1 = async (reference, floating, config) => {
1089
+ const {
1090
+ placement = 'bottom',
1091
+ strategy = 'absolute',
1092
+ middleware = [],
1093
+ platform
1094
+ } = config;
1095
+ const validMiddleware = middleware.filter(Boolean);
1096
+ const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));
1097
+ let rects = await platform.getElementRects({
1098
+ reference,
1099
+ floating,
1100
+ strategy
1101
+ });
1102
+ let {
1103
+ x,
1104
+ y
1105
+ } = computeCoordsFromPlacement(rects, placement, rtl);
1106
+ let statefulPlacement = placement;
1107
+ let middlewareData = {};
1108
+ let resetCount = 0;
1109
+ for (let i = 0; i < validMiddleware.length; i++) {
1110
+ const {
1111
+ name,
1112
+ fn
1113
+ } = validMiddleware[i];
1114
+ const {
1115
+ x: nextX,
1116
+ y: nextY,
1117
+ data,
1118
+ reset
1119
+ } = await fn({
1120
+ x,
1121
+ y,
1122
+ initialPlacement: placement,
1123
+ placement: statefulPlacement,
1124
+ strategy,
1125
+ middlewareData,
1126
+ rects,
1127
+ platform,
1128
+ elements: {
1129
+ reference,
1130
+ floating
1131
+ }
1132
+ });
1133
+ x = nextX != null ? nextX : x;
1134
+ y = nextY != null ? nextY : y;
1135
+ middlewareData = {
1136
+ ...middlewareData,
1137
+ [name]: {
1138
+ ...middlewareData[name],
1139
+ ...data
1140
+ }
1141
+ };
1142
+ if (reset && resetCount <= 50) {
1143
+ resetCount++;
1144
+ if (typeof reset === 'object') {
1145
+ if (reset.placement) {
1146
+ statefulPlacement = reset.placement;
1147
+ }
1148
+ if (reset.rects) {
1149
+ rects = reset.rects === true ? await platform.getElementRects({
1150
+ reference,
1151
+ floating,
1152
+ strategy
1153
+ }) : reset.rects;
1154
+ }
1155
+ ({
1156
+ x,
1157
+ y
1158
+ } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
1159
+ }
1160
+ i = -1;
1161
+ }
1162
+ }
1163
+ return {
1164
+ x,
1165
+ y,
1166
+ placement: statefulPlacement,
1167
+ strategy,
1168
+ middlewareData
1169
+ };
1170
+ };
1171
+
1172
+ /**
1173
+ * Resolves with an object of overflow side offsets that determine how much the
1174
+ * element is overflowing a given clipping boundary on each side.
1175
+ * - positive = overflowing the boundary by that number of pixels
1176
+ * - negative = how many pixels left before it will overflow
1177
+ * - 0 = lies flush with the boundary
1178
+ * @see https://floating-ui.com/docs/detectOverflow
1179
+ */
1180
+ async function detectOverflow(state, options) {
1181
+ var _await$platform$isEle;
1182
+ if (options === void 0) {
1183
+ options = {};
1184
+ }
1185
+ const {
1186
+ x,
1187
+ y,
1188
+ platform,
1189
+ rects,
1190
+ elements,
1191
+ strategy
1192
+ } = state;
1193
+ const {
1194
+ boundary = 'clippingAncestors',
1195
+ rootBoundary = 'viewport',
1196
+ elementContext = 'floating',
1197
+ altBoundary = false,
1198
+ padding = 0
1199
+ } = evaluate(options, state);
1200
+ const paddingObject = getPaddingObject(padding);
1201
+ const altContext = elementContext === 'floating' ? 'reference' : 'floating';
1202
+ const element = elements[altBoundary ? altContext : elementContext];
1203
+ const clippingClientRect = rectToClientRect(await platform.getClippingRect({
1204
+ element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))),
1205
+ boundary,
1206
+ rootBoundary,
1207
+ strategy
1208
+ }));
1209
+ const rect = elementContext === 'floating' ? {
1210
+ x,
1211
+ y,
1212
+ width: rects.floating.width,
1213
+ height: rects.floating.height
1214
+ } : rects.reference;
1215
+ const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
1216
+ const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {
1217
+ x: 1,
1218
+ y: 1
1219
+ } : {
1220
+ x: 1,
1221
+ y: 1
1222
+ };
1223
+ const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
1224
+ elements,
1225
+ rect,
1226
+ offsetParent,
1227
+ strategy
1228
+ }) : rect);
1229
+ return {
1230
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
1231
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
1232
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
1233
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
1234
+ };
1235
+ }
1236
+
1237
+ /**
1238
+ * Provides data to position an inner element of the floating element so that it
1239
+ * appears centered to the reference element.
1240
+ * @see https://floating-ui.com/docs/arrow
1241
+ */
1242
+ const arrow$3 = options => ({
1243
+ name: 'arrow',
1244
+ options,
1245
+ async fn(state) {
1246
+ const {
1247
+ x,
1248
+ y,
1249
+ placement,
1250
+ rects,
1251
+ platform,
1252
+ elements,
1253
+ middlewareData
1254
+ } = state;
1255
+ // Since `element` is required, we don't Partial<> the type.
1256
+ const {
1257
+ element,
1258
+ padding = 0
1259
+ } = evaluate(options, state) || {};
1260
+ if (element == null) {
1261
+ return {};
1262
+ }
1263
+ const paddingObject = getPaddingObject(padding);
1264
+ const coords = {
1265
+ x,
1266
+ y
1267
+ };
1268
+ const axis = getAlignmentAxis(placement);
1269
+ const length = getAxisLength(axis);
1270
+ const arrowDimensions = await platform.getDimensions(element);
1271
+ const isYAxis = axis === 'y';
1272
+ const minProp = isYAxis ? 'top' : 'left';
1273
+ const maxProp = isYAxis ? 'bottom' : 'right';
1274
+ const clientProp = isYAxis ? 'clientHeight' : 'clientWidth';
1275
+ const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length];
1276
+ const startDiff = coords[axis] - rects.reference[axis];
1277
+ const arrowOffsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(element));
1278
+ let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0;
1279
+
1280
+ // DOM platform can return `window` as the `offsetParent`.
1281
+ if (!clientSize || !(await (platform.isElement == null ? void 0 : platform.isElement(arrowOffsetParent)))) {
1282
+ clientSize = elements.floating[clientProp] || rects.floating[length];
1283
+ }
1284
+ const centerToReference = endDiff / 2 - startDiff / 2;
1285
+
1286
+ // If the padding is large enough that it causes the arrow to no longer be
1287
+ // centered, modify the padding so that it is centered.
1288
+ const largestPossiblePadding = clientSize / 2 - arrowDimensions[length] / 2 - 1;
1289
+ const minPadding = min(paddingObject[minProp], largestPossiblePadding);
1290
+ const maxPadding = min(paddingObject[maxProp], largestPossiblePadding);
1291
+
1292
+ // Make sure the arrow doesn't overflow the floating element if the center
1293
+ // point is outside the floating element's bounds.
1294
+ const min$1 = minPadding;
1295
+ const max = clientSize - arrowDimensions[length] - maxPadding;
1296
+ const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;
1297
+ const offset = clamp(min$1, center, max);
1298
+
1299
+ // If the reference is small enough that the arrow's padding causes it to
1300
+ // to point to nothing for an aligned placement, adjust the offset of the
1301
+ // floating element itself. To ensure `shift()` continues to take action,
1302
+ // a single reset is performed when this is true.
1303
+ const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;
1304
+ const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max : 0;
1305
+ return {
1306
+ [axis]: coords[axis] + alignmentOffset,
1307
+ data: {
1308
+ [axis]: offset,
1309
+ centerOffset: center - offset - alignmentOffset,
1310
+ ...(shouldAddOffset && {
1311
+ alignmentOffset
1312
+ })
1313
+ },
1314
+ reset: shouldAddOffset
1315
+ };
1316
+ }
1317
+ });
1318
+
1319
+ /**
1320
+ * Optimizes the visibility of the floating element by flipping the `placement`
1321
+ * in order to keep it in view when the preferred placement(s) will overflow the
1322
+ * clipping boundary. Alternative to `autoPlacement`.
1323
+ * @see https://floating-ui.com/docs/flip
1324
+ */
1325
+ const flip$2 = function (options) {
1326
+ if (options === void 0) {
1327
+ options = {};
1328
+ }
1329
+ return {
1330
+ name: 'flip',
1331
+ options,
1332
+ async fn(state) {
1333
+ var _middlewareData$arrow, _middlewareData$flip;
1334
+ const {
1335
+ placement,
1336
+ middlewareData,
1337
+ rects,
1338
+ initialPlacement,
1339
+ platform,
1340
+ elements
1341
+ } = state;
1342
+ const {
1343
+ mainAxis: checkMainAxis = true,
1344
+ crossAxis: checkCrossAxis = true,
1345
+ fallbackPlacements: specifiedFallbackPlacements,
1346
+ fallbackStrategy = 'bestFit',
1347
+ fallbackAxisSideDirection = 'none',
1348
+ flipAlignment = true,
1349
+ ...detectOverflowOptions
1350
+ } = evaluate(options, state);
1351
+
1352
+ // If a reset by the arrow was caused due to an alignment offset being
1353
+ // added, we should skip any logic now since `flip()` has already done its
1354
+ // work.
1355
+ // https://github.com/floating-ui/floating-ui/issues/2549#issuecomment-1719601643
1356
+ if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
1357
+ return {};
1358
+ }
1359
+ const side = getSide(placement);
1360
+ const initialSideAxis = getSideAxis(initialPlacement);
1361
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
1362
+ const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
1363
+ const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
1364
+ const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== 'none';
1365
+ if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
1366
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
1367
+ }
1368
+ const placements = [initialPlacement, ...fallbackPlacements];
1369
+ const overflow = await detectOverflow(state, detectOverflowOptions);
1370
+ const overflows = [];
1371
+ let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
1372
+ if (checkMainAxis) {
1373
+ overflows.push(overflow[side]);
1374
+ }
1375
+ if (checkCrossAxis) {
1376
+ const sides = getAlignmentSides(placement, rects, rtl);
1377
+ overflows.push(overflow[sides[0]], overflow[sides[1]]);
1378
+ }
1379
+ overflowsData = [...overflowsData, {
1380
+ placement,
1381
+ overflows
1382
+ }];
1383
+
1384
+ // One or more sides is overflowing.
1385
+ if (!overflows.every(side => side <= 0)) {
1386
+ var _middlewareData$flip2, _overflowsData$filter;
1387
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
1388
+ const nextPlacement = placements[nextIndex];
1389
+ if (nextPlacement) {
1390
+ const ignoreCrossAxisOverflow = checkCrossAxis === 'alignment' ? initialSideAxis !== getSideAxis(nextPlacement) : false;
1391
+ if (!ignoreCrossAxisOverflow ||
1392
+ // We leave the current main axis only if every placement on that axis
1393
+ // overflows the main axis.
1394
+ overflowsData.every(d => d.overflows[0] > 0 && getSideAxis(d.placement) === initialSideAxis)) {
1395
+ // Try next placement and re-run the lifecycle.
1396
+ return {
1397
+ data: {
1398
+ index: nextIndex,
1399
+ overflows: overflowsData
1400
+ },
1401
+ reset: {
1402
+ placement: nextPlacement
1403
+ }
1404
+ };
1405
+ }
1406
+ }
1407
+
1408
+ // First, find the candidates that fit on the mainAxis side of overflow,
1409
+ // then find the placement that fits the best on the main crossAxis side.
1410
+ let resetPlacement = (_overflowsData$filter = overflowsData.filter(d => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
1411
+
1412
+ // Otherwise fallback.
1413
+ if (!resetPlacement) {
1414
+ switch (fallbackStrategy) {
1415
+ case 'bestFit':
1416
+ {
1417
+ var _overflowsData$filter2;
1418
+ const placement = (_overflowsData$filter2 = overflowsData.filter(d => {
1419
+ if (hasFallbackAxisSideDirection) {
1420
+ const currentSideAxis = getSideAxis(d.placement);
1421
+ return currentSideAxis === initialSideAxis ||
1422
+ // Create a bias to the `y` side axis due to horizontal
1423
+ // reading directions favoring greater width.
1424
+ currentSideAxis === 'y';
1425
+ }
1426
+ return true;
1427
+ }).map(d => [d.placement, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
1428
+ if (placement) {
1429
+ resetPlacement = placement;
1430
+ }
1431
+ break;
1432
+ }
1433
+ case 'initialPlacement':
1434
+ resetPlacement = initialPlacement;
1435
+ break;
1436
+ }
1437
+ }
1438
+ if (placement !== resetPlacement) {
1439
+ return {
1440
+ reset: {
1441
+ placement: resetPlacement
1442
+ }
1443
+ };
1444
+ }
1445
+ }
1446
+ return {};
1447
+ }
1448
+ };
1449
+ };
1450
+
1451
+ const originSides = /*#__PURE__*/new Set(['left', 'top']);
1452
+
1453
+ // For type backwards-compatibility, the `OffsetOptions` type was also
1454
+ // Derivable.
1455
+
1456
+ async function convertValueToCoords(state, options) {
1457
+ const {
1458
+ placement,
1459
+ platform,
1460
+ elements
1461
+ } = state;
1462
+ const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
1463
+ const side = getSide(placement);
1464
+ const alignment = getAlignment(placement);
1465
+ const isVertical = getSideAxis(placement) === 'y';
1466
+ const mainAxisMulti = originSides.has(side) ? -1 : 1;
1467
+ const crossAxisMulti = rtl && isVertical ? -1 : 1;
1468
+ const rawValue = evaluate(options, state);
1469
+
1470
+ // eslint-disable-next-line prefer-const
1471
+ let {
1472
+ mainAxis,
1473
+ crossAxis,
1474
+ alignmentAxis
1475
+ } = typeof rawValue === 'number' ? {
1476
+ mainAxis: rawValue,
1477
+ crossAxis: 0,
1478
+ alignmentAxis: null
1479
+ } : {
1480
+ mainAxis: rawValue.mainAxis || 0,
1481
+ crossAxis: rawValue.crossAxis || 0,
1482
+ alignmentAxis: rawValue.alignmentAxis
1483
+ };
1484
+ if (alignment && typeof alignmentAxis === 'number') {
1485
+ crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;
1486
+ }
1487
+ return isVertical ? {
1488
+ x: crossAxis * crossAxisMulti,
1489
+ y: mainAxis * mainAxisMulti
1490
+ } : {
1491
+ x: mainAxis * mainAxisMulti,
1492
+ y: crossAxis * crossAxisMulti
1493
+ };
1494
+ }
1495
+
1496
+ /**
1497
+ * Modifies the placement by translating the floating element along the
1498
+ * specified axes.
1499
+ * A number (shorthand for `mainAxis` or distance), or an axes configuration
1500
+ * object may be passed.
1501
+ * @see https://floating-ui.com/docs/offset
1502
+ */
1503
+ const offset$2 = function (options) {
1504
+ if (options === void 0) {
1505
+ options = 0;
1506
+ }
1507
+ return {
1508
+ name: 'offset',
1509
+ options,
1510
+ async fn(state) {
1511
+ var _middlewareData$offse, _middlewareData$arrow;
1512
+ const {
1513
+ x,
1514
+ y,
1515
+ placement,
1516
+ middlewareData
1517
+ } = state;
1518
+ const diffCoords = await convertValueToCoords(state, options);
1519
+
1520
+ // If the placement is the same and the arrow caused an alignment offset
1521
+ // then we don't need to change the positioning coordinates.
1522
+ if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
1523
+ return {};
1524
+ }
1525
+ return {
1526
+ x: x + diffCoords.x,
1527
+ y: y + diffCoords.y,
1528
+ data: {
1529
+ ...diffCoords,
1530
+ placement
1531
+ }
1532
+ };
1533
+ }
1534
+ };
1535
+ };
1536
+
1537
+ /**
1538
+ * Optimizes the visibility of the floating element by shifting it in order to
1539
+ * keep it in view when it will overflow the clipping boundary.
1540
+ * @see https://floating-ui.com/docs/shift
1541
+ */
1542
+ const shift$2 = function (options) {
1543
+ if (options === void 0) {
1544
+ options = {};
1545
+ }
1546
+ return {
1547
+ name: 'shift',
1548
+ options,
1549
+ async fn(state) {
1550
+ const {
1551
+ x,
1552
+ y,
1553
+ placement
1554
+ } = state;
1555
+ const {
1556
+ mainAxis: checkMainAxis = true,
1557
+ crossAxis: checkCrossAxis = false,
1558
+ limiter = {
1559
+ fn: _ref => {
1560
+ let {
1561
+ x,
1562
+ y
1563
+ } = _ref;
1564
+ return {
1565
+ x,
1566
+ y
1567
+ };
1568
+ }
1569
+ },
1570
+ ...detectOverflowOptions
1571
+ } = evaluate(options, state);
1572
+ const coords = {
1573
+ x,
1574
+ y
1575
+ };
1576
+ const overflow = await detectOverflow(state, detectOverflowOptions);
1577
+ const crossAxis = getSideAxis(getSide(placement));
1578
+ const mainAxis = getOppositeAxis(crossAxis);
1579
+ let mainAxisCoord = coords[mainAxis];
1580
+ let crossAxisCoord = coords[crossAxis];
1581
+ if (checkMainAxis) {
1582
+ const minSide = mainAxis === 'y' ? 'top' : 'left';
1583
+ const maxSide = mainAxis === 'y' ? 'bottom' : 'right';
1584
+ const min = mainAxisCoord + overflow[minSide];
1585
+ const max = mainAxisCoord - overflow[maxSide];
1586
+ mainAxisCoord = clamp(min, mainAxisCoord, max);
1587
+ }
1588
+ if (checkCrossAxis) {
1589
+ const minSide = crossAxis === 'y' ? 'top' : 'left';
1590
+ const maxSide = crossAxis === 'y' ? 'bottom' : 'right';
1591
+ const min = crossAxisCoord + overflow[minSide];
1592
+ const max = crossAxisCoord - overflow[maxSide];
1593
+ crossAxisCoord = clamp(min, crossAxisCoord, max);
1594
+ }
1595
+ const limitedCoords = limiter.fn({
1596
+ ...state,
1597
+ [mainAxis]: mainAxisCoord,
1598
+ [crossAxis]: crossAxisCoord
1599
+ });
1600
+ return {
1601
+ ...limitedCoords,
1602
+ data: {
1603
+ x: limitedCoords.x - x,
1604
+ y: limitedCoords.y - y,
1605
+ enabled: {
1606
+ [mainAxis]: checkMainAxis,
1607
+ [crossAxis]: checkCrossAxis
1608
+ }
1609
+ }
1610
+ };
1611
+ }
1612
+ };
1613
+ };
1614
+
1615
+ /**
1616
+ * Provides data that allows you to change the size of the floating element —
1617
+ * for instance, prevent it from overflowing the clipping boundary or match the
1618
+ * width of the reference element.
1619
+ * @see https://floating-ui.com/docs/size
1620
+ */
1621
+ const size$2 = function (options) {
1622
+ if (options === void 0) {
1623
+ options = {};
1624
+ }
1625
+ return {
1626
+ name: 'size',
1627
+ options,
1628
+ async fn(state) {
1629
+ var _state$middlewareData, _state$middlewareData2;
1630
+ const {
1631
+ placement,
1632
+ rects,
1633
+ platform,
1634
+ elements
1635
+ } = state;
1636
+ const {
1637
+ apply = () => {},
1638
+ ...detectOverflowOptions
1639
+ } = evaluate(options, state);
1640
+ const overflow = await detectOverflow(state, detectOverflowOptions);
1641
+ const side = getSide(placement);
1642
+ const alignment = getAlignment(placement);
1643
+ const isYAxis = getSideAxis(placement) === 'y';
1644
+ const {
1645
+ width,
1646
+ height
1647
+ } = rects.floating;
1648
+ let heightSide;
1649
+ let widthSide;
1650
+ if (side === 'top' || side === 'bottom') {
1651
+ heightSide = side;
1652
+ widthSide = alignment === ((await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))) ? 'start' : 'end') ? 'left' : 'right';
1653
+ } else {
1654
+ widthSide = side;
1655
+ heightSide = alignment === 'end' ? 'top' : 'bottom';
1656
+ }
1657
+ const maximumClippingHeight = height - overflow.top - overflow.bottom;
1658
+ const maximumClippingWidth = width - overflow.left - overflow.right;
1659
+ const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight);
1660
+ const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth);
1661
+ const noShift = !state.middlewareData.shift;
1662
+ let availableHeight = overflowAvailableHeight;
1663
+ let availableWidth = overflowAvailableWidth;
1664
+ if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {
1665
+ availableWidth = maximumClippingWidth;
1666
+ }
1667
+ if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {
1668
+ availableHeight = maximumClippingHeight;
1669
+ }
1670
+ if (noShift && !alignment) {
1671
+ const xMin = max(overflow.left, 0);
1672
+ const xMax = max(overflow.right, 0);
1673
+ const yMin = max(overflow.top, 0);
1674
+ const yMax = max(overflow.bottom, 0);
1675
+ if (isYAxis) {
1676
+ availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));
1677
+ } else {
1678
+ availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));
1679
+ }
1680
+ }
1681
+ await apply({
1682
+ ...state,
1683
+ availableWidth,
1684
+ availableHeight
1685
+ });
1686
+ const nextDimensions = await platform.getDimensions(elements.floating);
1687
+ if (width !== nextDimensions.width || height !== nextDimensions.height) {
1688
+ return {
1689
+ reset: {
1690
+ rects: true
1691
+ }
1692
+ };
1693
+ }
1694
+ return {};
1695
+ }
1696
+ };
1697
+ };
1698
+
1699
+ function hasWindow() {
1700
+ return typeof window !== 'undefined';
1701
+ }
1702
+ function getNodeName(node) {
1703
+ if (isNode(node)) {
1704
+ return (node.nodeName || '').toLowerCase();
1705
+ }
1706
+ // Mocked nodes in testing environments may not be instances of Node. By
1707
+ // returning `#document` an infinite loop won't occur.
1708
+ // https://github.com/floating-ui/floating-ui/issues/2317
1709
+ return '#document';
1710
+ }
1711
+ function getWindow(node) {
1712
+ var _node$ownerDocument;
1713
+ return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
1714
+ }
1715
+ function getDocumentElement(node) {
1716
+ var _ref;
1717
+ return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
1718
+ }
1719
+ function isNode(value) {
1720
+ if (!hasWindow()) {
1721
+ return false;
1722
+ }
1723
+ return value instanceof Node || value instanceof getWindow(value).Node;
1724
+ }
1725
+ function isElement(value) {
1726
+ if (!hasWindow()) {
1727
+ return false;
1728
+ }
1729
+ return value instanceof Element || value instanceof getWindow(value).Element;
1730
+ }
1731
+ function isHTMLElement(value) {
1732
+ if (!hasWindow()) {
1733
+ return false;
1734
+ }
1735
+ return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
1736
+ }
1737
+ function isShadowRoot(value) {
1738
+ if (!hasWindow() || typeof ShadowRoot === 'undefined') {
1739
+ return false;
1740
+ }
1741
+ return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
1742
+ }
1743
+ const invalidOverflowDisplayValues = /*#__PURE__*/new Set(['inline', 'contents']);
1744
+ function isOverflowElement(element) {
1745
+ const {
1746
+ overflow,
1747
+ overflowX,
1748
+ overflowY,
1749
+ display
1750
+ } = getComputedStyle(element);
1751
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
1752
+ }
1753
+ const tableElements = /*#__PURE__*/new Set(['table', 'td', 'th']);
1754
+ function isTableElement(element) {
1755
+ return tableElements.has(getNodeName(element));
1756
+ }
1757
+ const topLayerSelectors = [':popover-open', ':modal'];
1758
+ function isTopLayer(element) {
1759
+ return topLayerSelectors.some(selector => {
1760
+ try {
1761
+ return element.matches(selector);
1762
+ } catch (_e) {
1763
+ return false;
1764
+ }
1765
+ });
1766
+ }
1767
+ const transformProperties = ['transform', 'translate', 'scale', 'rotate', 'perspective'];
1768
+ const willChangeValues = ['transform', 'translate', 'scale', 'rotate', 'perspective', 'filter'];
1769
+ const containValues = ['paint', 'layout', 'strict', 'content'];
1770
+ function isContainingBlock(elementOrCss) {
1771
+ const webkit = isWebKit();
1772
+ const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
1773
+
1774
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
1775
+ // https://drafts.csswg.org/css-transforms-2/#individual-transforms
1776
+ return transformProperties.some(value => css[value] ? css[value] !== 'none' : false) || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || willChangeValues.some(value => (css.willChange || '').includes(value)) || containValues.some(value => (css.contain || '').includes(value));
1777
+ }
1778
+ function getContainingBlock(element) {
1779
+ let currentNode = getParentNode(element);
1780
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
1781
+ if (isContainingBlock(currentNode)) {
1782
+ return currentNode;
1783
+ } else if (isTopLayer(currentNode)) {
1784
+ return null;
1785
+ }
1786
+ currentNode = getParentNode(currentNode);
1787
+ }
1788
+ return null;
1789
+ }
1790
+ function isWebKit() {
1791
+ if (typeof CSS === 'undefined' || !CSS.supports) return false;
1792
+ return CSS.supports('-webkit-backdrop-filter', 'none');
1793
+ }
1794
+ const lastTraversableNodeNames = /*#__PURE__*/new Set(['html', 'body', '#document']);
1795
+ function isLastTraversableNode(node) {
1796
+ return lastTraversableNodeNames.has(getNodeName(node));
1797
+ }
1798
+ function getComputedStyle(element) {
1799
+ return getWindow(element).getComputedStyle(element);
1800
+ }
1801
+ function getNodeScroll(element) {
1802
+ if (isElement(element)) {
1803
+ return {
1804
+ scrollLeft: element.scrollLeft,
1805
+ scrollTop: element.scrollTop
1806
+ };
1807
+ }
1808
+ return {
1809
+ scrollLeft: element.scrollX,
1810
+ scrollTop: element.scrollY
1811
+ };
1812
+ }
1813
+ function getParentNode(node) {
1814
+ if (getNodeName(node) === 'html') {
1815
+ return node;
1816
+ }
1817
+ const result =
1818
+ // Step into the shadow DOM of the parent of a slotted node.
1819
+ node.assignedSlot ||
1820
+ // DOM Element detected.
1821
+ node.parentNode ||
1822
+ // ShadowRoot detected.
1823
+ isShadowRoot(node) && node.host ||
1824
+ // Fallback.
1825
+ getDocumentElement(node);
1826
+ return isShadowRoot(result) ? result.host : result;
1827
+ }
1828
+ function getNearestOverflowAncestor(node) {
1829
+ const parentNode = getParentNode(node);
1830
+ if (isLastTraversableNode(parentNode)) {
1831
+ return node.ownerDocument ? node.ownerDocument.body : node.body;
1832
+ }
1833
+ if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
1834
+ return parentNode;
1835
+ }
1836
+ return getNearestOverflowAncestor(parentNode);
1837
+ }
1838
+ function getOverflowAncestors(node, list, traverseIframes) {
1839
+ var _node$ownerDocument2;
1840
+ if (list === void 0) {
1841
+ list = [];
1842
+ }
1843
+ if (traverseIframes === void 0) {
1844
+ traverseIframes = true;
1845
+ }
1846
+ const scrollableAncestor = getNearestOverflowAncestor(node);
1847
+ const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
1848
+ const win = getWindow(scrollableAncestor);
1849
+ if (isBody) {
1850
+ const frameElement = getFrameElement(win);
1851
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
1852
+ }
1853
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
1854
+ }
1855
+ function getFrameElement(win) {
1856
+ return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
1857
+ }
1858
+
1859
+ function getCssDimensions(element) {
1860
+ const css = getComputedStyle(element);
1861
+ // In testing environments, the `width` and `height` properties are empty
1862
+ // strings for SVG elements, returning NaN. Fallback to `0` in this case.
1863
+ let width = parseFloat(css.width) || 0;
1864
+ let height = parseFloat(css.height) || 0;
1865
+ const hasOffset = isHTMLElement(element);
1866
+ const offsetWidth = hasOffset ? element.offsetWidth : width;
1867
+ const offsetHeight = hasOffset ? element.offsetHeight : height;
1868
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
1869
+ if (shouldFallback) {
1870
+ width = offsetWidth;
1871
+ height = offsetHeight;
1872
+ }
1873
+ return {
1874
+ width,
1875
+ height,
1876
+ $: shouldFallback
1877
+ };
1878
+ }
1879
+
1880
+ function unwrapElement(element) {
1881
+ return !isElement(element) ? element.contextElement : element;
1882
+ }
1883
+
1884
+ function getScale(element) {
1885
+ const domElement = unwrapElement(element);
1886
+ if (!isHTMLElement(domElement)) {
1887
+ return createCoords(1);
1888
+ }
1889
+ const rect = domElement.getBoundingClientRect();
1890
+ const {
1891
+ width,
1892
+ height,
1893
+ $
1894
+ } = getCssDimensions(domElement);
1895
+ let x = ($ ? round(rect.width) : rect.width) / width;
1896
+ let y = ($ ? round(rect.height) : rect.height) / height;
1897
+
1898
+ // 0, NaN, or Infinity should always fallback to 1.
1899
+
1900
+ if (!x || !Number.isFinite(x)) {
1901
+ x = 1;
1902
+ }
1903
+ if (!y || !Number.isFinite(y)) {
1904
+ y = 1;
1905
+ }
1906
+ return {
1907
+ x,
1908
+ y
1909
+ };
1910
+ }
1911
+
1912
+ const noOffsets = /*#__PURE__*/createCoords(0);
1913
+ function getVisualOffsets(element) {
1914
+ const win = getWindow(element);
1915
+ if (!isWebKit() || !win.visualViewport) {
1916
+ return noOffsets;
1917
+ }
1918
+ return {
1919
+ x: win.visualViewport.offsetLeft,
1920
+ y: win.visualViewport.offsetTop
1921
+ };
1922
+ }
1923
+ function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
1924
+ if (isFixed === void 0) {
1925
+ isFixed = false;
1926
+ }
1927
+ if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
1928
+ return false;
1929
+ }
1930
+ return isFixed;
1931
+ }
1932
+
1933
+ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
1934
+ if (includeScale === void 0) {
1935
+ includeScale = false;
1936
+ }
1937
+ if (isFixedStrategy === void 0) {
1938
+ isFixedStrategy = false;
1939
+ }
1940
+ const clientRect = element.getBoundingClientRect();
1941
+ const domElement = unwrapElement(element);
1942
+ let scale = createCoords(1);
1943
+ if (includeScale) {
1944
+ if (offsetParent) {
1945
+ if (isElement(offsetParent)) {
1946
+ scale = getScale(offsetParent);
1947
+ }
1948
+ } else {
1949
+ scale = getScale(element);
1950
+ }
1951
+ }
1952
+ const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
1953
+ let x = (clientRect.left + visualOffsets.x) / scale.x;
1954
+ let y = (clientRect.top + visualOffsets.y) / scale.y;
1955
+ let width = clientRect.width / scale.x;
1956
+ let height = clientRect.height / scale.y;
1957
+ if (domElement) {
1958
+ const win = getWindow(domElement);
1959
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
1960
+ let currentWin = win;
1961
+ let currentIFrame = getFrameElement(currentWin);
1962
+ while (currentIFrame && offsetParent && offsetWin !== currentWin) {
1963
+ const iframeScale = getScale(currentIFrame);
1964
+ const iframeRect = currentIFrame.getBoundingClientRect();
1965
+ const css = getComputedStyle(currentIFrame);
1966
+ const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
1967
+ const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
1968
+ x *= iframeScale.x;
1969
+ y *= iframeScale.y;
1970
+ width *= iframeScale.x;
1971
+ height *= iframeScale.y;
1972
+ x += left;
1973
+ y += top;
1974
+ currentWin = getWindow(currentIFrame);
1975
+ currentIFrame = getFrameElement(currentWin);
1976
+ }
1977
+ }
1978
+ return rectToClientRect({
1979
+ width,
1980
+ height,
1981
+ x,
1982
+ y
1983
+ });
1984
+ }
1985
+
1986
+ // If <html> has a CSS width greater than the viewport, then this will be
1987
+ // incorrect for RTL.
1988
+ function getWindowScrollBarX(element, rect) {
1989
+ const leftScroll = getNodeScroll(element).scrollLeft;
1990
+ if (!rect) {
1991
+ return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
1992
+ }
1993
+ return rect.left + leftScroll;
1994
+ }
1995
+
1996
+ function getHTMLOffset(documentElement, scroll, ignoreScrollbarX) {
1997
+ if (ignoreScrollbarX === void 0) {
1998
+ ignoreScrollbarX = false;
1999
+ }
2000
+ const htmlRect = documentElement.getBoundingClientRect();
2001
+ const x = htmlRect.left + scroll.scrollLeft - (ignoreScrollbarX ? 0 :
2002
+ // RTL <body> scrollbar.
2003
+ getWindowScrollBarX(documentElement, htmlRect));
2004
+ const y = htmlRect.top + scroll.scrollTop;
2005
+ return {
2006
+ x,
2007
+ y
2008
+ };
2009
+ }
2010
+
2011
+ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
2012
+ let {
2013
+ elements,
2014
+ rect,
2015
+ offsetParent,
2016
+ strategy
2017
+ } = _ref;
2018
+ const isFixed = strategy === 'fixed';
2019
+ const documentElement = getDocumentElement(offsetParent);
2020
+ const topLayer = elements ? isTopLayer(elements.floating) : false;
2021
+ if (offsetParent === documentElement || topLayer && isFixed) {
2022
+ return rect;
2023
+ }
2024
+ let scroll = {
2025
+ scrollLeft: 0,
2026
+ scrollTop: 0
2027
+ };
2028
+ let scale = createCoords(1);
2029
+ const offsets = createCoords(0);
2030
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
2031
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
2032
+ if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
2033
+ scroll = getNodeScroll(offsetParent);
2034
+ }
2035
+ if (isHTMLElement(offsetParent)) {
2036
+ const offsetRect = getBoundingClientRect(offsetParent);
2037
+ scale = getScale(offsetParent);
2038
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
2039
+ offsets.y = offsetRect.y + offsetParent.clientTop;
2040
+ }
2041
+ }
2042
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll, true) : createCoords(0);
2043
+ return {
2044
+ width: rect.width * scale.x,
2045
+ height: rect.height * scale.y,
2046
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
2047
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
2048
+ };
2049
+ }
2050
+
2051
+ function getClientRects(element) {
2052
+ return Array.from(element.getClientRects());
2053
+ }
2054
+
2055
+ // Gets the entire size of the scrollable document area, even extending outside
2056
+ // of the `<html>` and `<body>` rect bounds if horizontally scrollable.
2057
+ function getDocumentRect(element) {
2058
+ const html = getDocumentElement(element);
2059
+ const scroll = getNodeScroll(element);
2060
+ const body = element.ownerDocument.body;
2061
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
2062
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
2063
+ let x = -scroll.scrollLeft + getWindowScrollBarX(element);
2064
+ const y = -scroll.scrollTop;
2065
+ if (getComputedStyle(body).direction === 'rtl') {
2066
+ x += max(html.clientWidth, body.clientWidth) - width;
2067
+ }
2068
+ return {
2069
+ width,
2070
+ height,
2071
+ x,
2072
+ y
2073
+ };
2074
+ }
2075
+
2076
+ function getViewportRect(element, strategy) {
2077
+ const win = getWindow(element);
2078
+ const html = getDocumentElement(element);
2079
+ const visualViewport = win.visualViewport;
2080
+ let width = html.clientWidth;
2081
+ let height = html.clientHeight;
2082
+ let x = 0;
2083
+ let y = 0;
2084
+ if (visualViewport) {
2085
+ width = visualViewport.width;
2086
+ height = visualViewport.height;
2087
+ const visualViewportBased = isWebKit();
2088
+ if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {
2089
+ x = visualViewport.offsetLeft;
2090
+ y = visualViewport.offsetTop;
2091
+ }
2092
+ }
2093
+ return {
2094
+ width,
2095
+ height,
2096
+ x,
2097
+ y
2098
+ };
2099
+ }
2100
+
2101
+ const absoluteOrFixed = /*#__PURE__*/new Set(['absolute', 'fixed']);
2102
+ // Returns the inner client rect, subtracting scrollbars if present.
2103
+ function getInnerBoundingClientRect(element, strategy) {
2104
+ const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
2105
+ const top = clientRect.top + element.clientTop;
2106
+ const left = clientRect.left + element.clientLeft;
2107
+ const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
2108
+ const width = element.clientWidth * scale.x;
2109
+ const height = element.clientHeight * scale.y;
2110
+ const x = left * scale.x;
2111
+ const y = top * scale.y;
2112
+ return {
2113
+ width,
2114
+ height,
2115
+ x,
2116
+ y
2117
+ };
2118
+ }
2119
+ function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
2120
+ let rect;
2121
+ if (clippingAncestor === 'viewport') {
2122
+ rect = getViewportRect(element, strategy);
2123
+ } else if (clippingAncestor === 'document') {
2124
+ rect = getDocumentRect(getDocumentElement(element));
2125
+ } else if (isElement(clippingAncestor)) {
2126
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
2127
+ } else {
2128
+ const visualOffsets = getVisualOffsets(element);
2129
+ rect = {
2130
+ x: clippingAncestor.x - visualOffsets.x,
2131
+ y: clippingAncestor.y - visualOffsets.y,
2132
+ width: clippingAncestor.width,
2133
+ height: clippingAncestor.height
2134
+ };
2135
+ }
2136
+ return rectToClientRect(rect);
2137
+ }
2138
+ function hasFixedPositionAncestor(element, stopNode) {
2139
+ const parentNode = getParentNode(element);
2140
+ if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
2141
+ return false;
2142
+ }
2143
+ return getComputedStyle(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);
2144
+ }
2145
+
2146
+ // A "clipping ancestor" is an `overflow` element with the characteristic of
2147
+ // clipping (or hiding) child elements. This returns all clipping ancestors
2148
+ // of the given element up the tree.
2149
+ function getClippingElementAncestors(element, cache) {
2150
+ const cachedResult = cache.get(element);
2151
+ if (cachedResult) {
2152
+ return cachedResult;
2153
+ }
2154
+ let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');
2155
+ let currentContainingBlockComputedStyle = null;
2156
+ const elementIsFixed = getComputedStyle(element).position === 'fixed';
2157
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
2158
+
2159
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
2160
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
2161
+ const computedStyle = getComputedStyle(currentNode);
2162
+ const currentNodeIsContaining = isContainingBlock(currentNode);
2163
+ if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
2164
+ currentContainingBlockComputedStyle = null;
2165
+ }
2166
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
2167
+ if (shouldDropCurrentNode) {
2168
+ // Drop non-containing blocks.
2169
+ result = result.filter(ancestor => ancestor !== currentNode);
2170
+ } else {
2171
+ // Record last containing block for next iteration.
2172
+ currentContainingBlockComputedStyle = computedStyle;
2173
+ }
2174
+ currentNode = getParentNode(currentNode);
2175
+ }
2176
+ cache.set(element, result);
2177
+ return result;
2178
+ }
2179
+
2180
+ // Gets the maximum area that the element is visible in due to any number of
2181
+ // clipping ancestors.
2182
+ function getClippingRect(_ref) {
2183
+ let {
2184
+ element,
2185
+ boundary,
2186
+ rootBoundary,
2187
+ strategy
2188
+ } = _ref;
2189
+ const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
2190
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
2191
+ const firstClippingAncestor = clippingAncestors[0];
2192
+ const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
2193
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
2194
+ accRect.top = max(rect.top, accRect.top);
2195
+ accRect.right = min(rect.right, accRect.right);
2196
+ accRect.bottom = min(rect.bottom, accRect.bottom);
2197
+ accRect.left = max(rect.left, accRect.left);
2198
+ return accRect;
2199
+ }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
2200
+ return {
2201
+ width: clippingRect.right - clippingRect.left,
2202
+ height: clippingRect.bottom - clippingRect.top,
2203
+ x: clippingRect.left,
2204
+ y: clippingRect.top
2205
+ };
2206
+ }
2207
+
2208
+ function getDimensions(element) {
2209
+ const {
2210
+ width,
2211
+ height
2212
+ } = getCssDimensions(element);
2213
+ return {
2214
+ width,
2215
+ height
2216
+ };
2217
+ }
2218
+
2219
+ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
2220
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
2221
+ const documentElement = getDocumentElement(offsetParent);
2222
+ const isFixed = strategy === 'fixed';
2223
+ const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
2224
+ let scroll = {
2225
+ scrollLeft: 0,
2226
+ scrollTop: 0
2227
+ };
2228
+ const offsets = createCoords(0);
2229
+
2230
+ // If the <body> scrollbar appears on the left (e.g. RTL systems). Use
2231
+ // Firefox with layout.scrollbar.side = 3 in about:config to test this.
2232
+ function setLeftRTLScrollbarOffset() {
2233
+ offsets.x = getWindowScrollBarX(documentElement);
2234
+ }
2235
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
2236
+ if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
2237
+ scroll = getNodeScroll(offsetParent);
2238
+ }
2239
+ if (isOffsetParentAnElement) {
2240
+ const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
2241
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
2242
+ offsets.y = offsetRect.y + offsetParent.clientTop;
2243
+ } else if (documentElement) {
2244
+ setLeftRTLScrollbarOffset();
2245
+ }
2246
+ }
2247
+ if (isFixed && !isOffsetParentAnElement && documentElement) {
2248
+ setLeftRTLScrollbarOffset();
2249
+ }
2250
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
2251
+ const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
2252
+ const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
2253
+ return {
2254
+ x,
2255
+ y,
2256
+ width: rect.width,
2257
+ height: rect.height
2258
+ };
2259
+ }
2260
+
2261
+ function isStaticPositioned(element) {
2262
+ return getComputedStyle(element).position === 'static';
2263
+ }
2264
+
2265
+ function getTrueOffsetParent(element, polyfill) {
2266
+ if (!isHTMLElement(element) || getComputedStyle(element).position === 'fixed') {
2267
+ return null;
2268
+ }
2269
+ if (polyfill) {
2270
+ return polyfill(element);
2271
+ }
2272
+ let rawOffsetParent = element.offsetParent;
2273
+
2274
+ // Firefox returns the <html> element as the offsetParent if it's non-static,
2275
+ // while Chrome and Safari return the <body> element. The <body> element must
2276
+ // be used to perform the correct calculations even if the <html> element is
2277
+ // non-static.
2278
+ if (getDocumentElement(element) === rawOffsetParent) {
2279
+ rawOffsetParent = rawOffsetParent.ownerDocument.body;
2280
+ }
2281
+ return rawOffsetParent;
2282
+ }
2283
+
2284
+ // Gets the closest ancestor positioned element. Handles some edge cases,
2285
+ // such as table ancestors and cross browser bugs.
2286
+ function getOffsetParent(element, polyfill) {
2287
+ const win = getWindow(element);
2288
+ if (isTopLayer(element)) {
2289
+ return win;
2290
+ }
2291
+ if (!isHTMLElement(element)) {
2292
+ let svgOffsetParent = getParentNode(element);
2293
+ while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
2294
+ if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
2295
+ return svgOffsetParent;
2296
+ }
2297
+ svgOffsetParent = getParentNode(svgOffsetParent);
2298
+ }
2299
+ return win;
2300
+ }
2301
+ let offsetParent = getTrueOffsetParent(element, polyfill);
2302
+ while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
2303
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
2304
+ }
2305
+ if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
2306
+ return win;
2307
+ }
2308
+ return offsetParent || getContainingBlock(element) || win;
2309
+ }
2310
+
2311
+ const getElementRects = async function (data) {
2312
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
2313
+ const getDimensionsFn = this.getDimensions;
2314
+ const floatingDimensions = await getDimensionsFn(data.floating);
2315
+ return {
2316
+ reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
2317
+ floating: {
2318
+ x: 0,
2319
+ y: 0,
2320
+ width: floatingDimensions.width,
2321
+ height: floatingDimensions.height
2322
+ }
2323
+ };
2324
+ };
2325
+
2326
+ function isRTL(element) {
2327
+ return getComputedStyle(element).direction === 'rtl';
2328
+ }
2329
+
2330
+ const platform = {
2331
+ convertOffsetParentRelativeRectToViewportRelativeRect,
2332
+ getDocumentElement,
2333
+ getClippingRect,
2334
+ getOffsetParent,
2335
+ getElementRects,
2336
+ getClientRects,
2337
+ getDimensions,
2338
+ getScale,
2339
+ isElement,
2340
+ isRTL
2341
+ };
2342
+
2343
+ function rectsAreEqual(a, b) {
2344
+ return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
2345
+ }
2346
+
2347
+ // https://samthor.au/2021/observing-dom/
2348
+ function observeMove(element, onMove) {
2349
+ let io = null;
2350
+ let timeoutId;
2351
+ const root = getDocumentElement(element);
2352
+ function cleanup() {
2353
+ var _io;
2354
+ clearTimeout(timeoutId);
2355
+ (_io = io) == null || _io.disconnect();
2356
+ io = null;
2357
+ }
2358
+ function refresh(skip, threshold) {
2359
+ if (skip === void 0) {
2360
+ skip = false;
2361
+ }
2362
+ if (threshold === void 0) {
2363
+ threshold = 1;
2364
+ }
2365
+ cleanup();
2366
+ const elementRectForRootMargin = element.getBoundingClientRect();
2367
+ const {
2368
+ left,
2369
+ top,
2370
+ width,
2371
+ height
2372
+ } = elementRectForRootMargin;
2373
+ if (!skip) {
2374
+ onMove();
2375
+ }
2376
+ if (!width || !height) {
2377
+ return;
2378
+ }
2379
+ const insetTop = floor(top);
2380
+ const insetRight = floor(root.clientWidth - (left + width));
2381
+ const insetBottom = floor(root.clientHeight - (top + height));
2382
+ const insetLeft = floor(left);
2383
+ const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
2384
+ const options = {
2385
+ rootMargin,
2386
+ threshold: max(0, min(1, threshold)) || 1
2387
+ };
2388
+ let isFirstUpdate = true;
2389
+ function handleObserve(entries) {
2390
+ const ratio = entries[0].intersectionRatio;
2391
+ if (ratio !== threshold) {
2392
+ if (!isFirstUpdate) {
2393
+ return refresh();
2394
+ }
2395
+ if (!ratio) {
2396
+ // If the reference is clipped, the ratio is 0. Throttle the refresh
2397
+ // to prevent an infinite loop of updates.
2398
+ timeoutId = setTimeout(() => {
2399
+ refresh(false, 1e-7);
2400
+ }, 1000);
2401
+ } else {
2402
+ refresh(false, ratio);
2403
+ }
2404
+ }
2405
+ if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {
2406
+ // It's possible that even though the ratio is reported as 1, the
2407
+ // element is not actually fully within the IntersectionObserver's root
2408
+ // area anymore. This can happen under performance constraints. This may
2409
+ // be a bug in the browser's IntersectionObserver implementation. To
2410
+ // work around this, we compare the element's bounding rect now with
2411
+ // what it was at the time we created the IntersectionObserver. If they
2412
+ // are not equal then the element moved, so we refresh.
2413
+ refresh();
2414
+ }
2415
+ isFirstUpdate = false;
2416
+ }
2417
+
2418
+ // Older browsers don't support a `document` as the root and will throw an
2419
+ // error.
2420
+ try {
2421
+ io = new IntersectionObserver(handleObserve, {
2422
+ ...options,
2423
+ // Handle <iframe>s
2424
+ root: root.ownerDocument
2425
+ });
2426
+ } catch (_e) {
2427
+ io = new IntersectionObserver(handleObserve, options);
2428
+ }
2429
+ io.observe(element);
2430
+ }
2431
+ refresh(true);
2432
+ return cleanup;
2433
+ }
2434
+
2435
+ /**
2436
+ * Automatically updates the position of the floating element when necessary.
2437
+ * Should only be called when the floating element is mounted on the DOM or
2438
+ * visible on the screen.
2439
+ * @returns cleanup function that should be invoked when the floating element is
2440
+ * removed from the DOM or hidden from the screen.
2441
+ * @see https://floating-ui.com/docs/autoUpdate
2442
+ */
2443
+ function autoUpdate(reference, floating, update, options) {
2444
+ if (options === void 0) {
2445
+ options = {};
2446
+ }
2447
+ const {
2448
+ ancestorScroll = true,
2449
+ ancestorResize = true,
2450
+ elementResize = typeof ResizeObserver === 'function',
2451
+ layoutShift = typeof IntersectionObserver === 'function',
2452
+ animationFrame = false
2453
+ } = options;
2454
+ const referenceEl = unwrapElement(reference);
2455
+ const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...getOverflowAncestors(floating)] : [];
2456
+ ancestors.forEach(ancestor => {
2457
+ ancestorScroll && ancestor.addEventListener('scroll', update, {
2458
+ passive: true
2459
+ });
2460
+ ancestorResize && ancestor.addEventListener('resize', update);
2461
+ });
2462
+ const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
2463
+ let reobserveFrame = -1;
2464
+ let resizeObserver = null;
2465
+ if (elementResize) {
2466
+ resizeObserver = new ResizeObserver(_ref => {
2467
+ let [firstEntry] = _ref;
2468
+ if (firstEntry && firstEntry.target === referenceEl && resizeObserver) {
2469
+ // Prevent update loops when using the `size` middleware.
2470
+ // https://github.com/floating-ui/floating-ui/issues/1740
2471
+ resizeObserver.unobserve(floating);
2472
+ cancelAnimationFrame(reobserveFrame);
2473
+ reobserveFrame = requestAnimationFrame(() => {
2474
+ var _resizeObserver;
2475
+ (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
2476
+ });
2477
+ }
2478
+ update();
2479
+ });
2480
+ if (referenceEl && !animationFrame) {
2481
+ resizeObserver.observe(referenceEl);
2482
+ }
2483
+ resizeObserver.observe(floating);
2484
+ }
2485
+ let frameId;
2486
+ let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
2487
+ if (animationFrame) {
2488
+ frameLoop();
2489
+ }
2490
+ function frameLoop() {
2491
+ const nextRefRect = getBoundingClientRect(reference);
2492
+ if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {
2493
+ update();
2494
+ }
2495
+ prevRefRect = nextRefRect;
2496
+ frameId = requestAnimationFrame(frameLoop);
2497
+ }
2498
+ update();
2499
+ return () => {
2500
+ var _resizeObserver2;
2501
+ ancestors.forEach(ancestor => {
2502
+ ancestorScroll && ancestor.removeEventListener('scroll', update);
2503
+ ancestorResize && ancestor.removeEventListener('resize', update);
2504
+ });
2505
+ cleanupIo == null || cleanupIo();
2506
+ (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
2507
+ resizeObserver = null;
2508
+ if (animationFrame) {
2509
+ cancelAnimationFrame(frameId);
2510
+ }
2511
+ };
2512
+ }
2513
+
2514
+ /**
2515
+ * Modifies the placement by translating the floating element along the
2516
+ * specified axes.
2517
+ * A number (shorthand for `mainAxis` or distance), or an axes configuration
2518
+ * object may be passed.
2519
+ * @see https://floating-ui.com/docs/offset
2520
+ */
2521
+ const offset$1 = offset$2;
2522
+
2523
+ /**
2524
+ * Optimizes the visibility of the floating element by shifting it in order to
2525
+ * keep it in view when it will overflow the clipping boundary.
2526
+ * @see https://floating-ui.com/docs/shift
2527
+ */
2528
+ const shift$1 = shift$2;
2529
+
2530
+ /**
2531
+ * Optimizes the visibility of the floating element by flipping the `placement`
2532
+ * in order to keep it in view when the preferred placement(s) will overflow the
2533
+ * clipping boundary. Alternative to `autoPlacement`.
2534
+ * @see https://floating-ui.com/docs/flip
2535
+ */
2536
+ const flip$1 = flip$2;
2537
+
2538
+ /**
2539
+ * Provides data that allows you to change the size of the floating element —
2540
+ * for instance, prevent it from overflowing the clipping boundary or match the
2541
+ * width of the reference element.
2542
+ * @see https://floating-ui.com/docs/size
2543
+ */
2544
+ const size$1 = size$2;
2545
+
2546
+ /**
2547
+ * Provides data to position an inner element of the floating element so that it
2548
+ * appears centered to the reference element.
2549
+ * @see https://floating-ui.com/docs/arrow
2550
+ */
2551
+ const arrow$2 = arrow$3;
2552
+
2553
+ /**
2554
+ * Computes the `x` and `y` coordinates that will place the floating element
2555
+ * next to a given reference element.
2556
+ */
2557
+ const computePosition = (reference, floating, options) => {
2558
+ // This caches the expensive `getClippingElementAncestors` function so that
2559
+ // multiple lifecycle resets re-use the same result. It only lives for a
2560
+ // single call. If other functions become expensive, we can add them as well.
2561
+ const cache = new Map();
2562
+ const mergedOptions = {
2563
+ platform,
2564
+ ...options
2565
+ };
2566
+ const platformWithCache = {
2567
+ ...mergedOptions.platform,
2568
+ _c: cache
2569
+ };
2570
+ return computePosition$1(reference, floating, {
2571
+ ...mergedOptions,
2572
+ platform: platformWithCache
2573
+ });
2574
+ };
2575
+
2576
+ var isClient = typeof document !== 'undefined';
2577
+
2578
+ var noop = function noop() {};
2579
+ var index = isClient ? React.useLayoutEffect : noop;
2580
+
2581
+ // Fork of `fast-deep-equal` that only does the comparisons we need and compares
2582
+ // functions
2583
+ function deepEqual(a, b) {
2584
+ if (a === b) {
2585
+ return true;
2586
+ }
2587
+ if (typeof a !== typeof b) {
2588
+ return false;
2589
+ }
2590
+ if (typeof a === 'function' && a.toString() === b.toString()) {
2591
+ return true;
2592
+ }
2593
+ let length;
2594
+ let i;
2595
+ let keys;
2596
+ if (a && b && typeof a === 'object') {
2597
+ if (Array.isArray(a)) {
2598
+ length = a.length;
2599
+ if (length !== b.length) return false;
2600
+ for (i = length; i-- !== 0;) {
2601
+ if (!deepEqual(a[i], b[i])) {
2602
+ return false;
2603
+ }
2604
+ }
2605
+ return true;
2606
+ }
2607
+ keys = Object.keys(a);
2608
+ length = keys.length;
2609
+ if (length !== Object.keys(b).length) {
2610
+ return false;
2611
+ }
2612
+ for (i = length; i-- !== 0;) {
2613
+ if (!{}.hasOwnProperty.call(b, keys[i])) {
782
2614
  return false;
783
- switch (type) {
784
- case 'email':
785
- return isEmail(value);
786
- case 'number':
787
- return !isNaN(Number(value));
788
- case 'tel':
789
- return isPhoneNumber(value);
790
- default:
791
- return true;
2615
+ }
792
2616
  }
2617
+ for (i = length; i-- !== 0;) {
2618
+ const key = keys[i];
2619
+ if (key === '_owner' && a.$$typeof) {
2620
+ continue;
2621
+ }
2622
+ if (!deepEqual(a[key], b[key])) {
2623
+ return false;
2624
+ }
2625
+ }
2626
+ return true;
2627
+ }
2628
+ return a !== a && b !== b;
2629
+ }
2630
+
2631
+ function getDPR(element) {
2632
+ if (typeof window === 'undefined') {
2633
+ return 1;
2634
+ }
2635
+ const win = element.ownerDocument.defaultView || window;
2636
+ return win.devicePixelRatio || 1;
2637
+ }
2638
+
2639
+ function roundByDPR(element, value) {
2640
+ const dpr = getDPR(element);
2641
+ return Math.round(value * dpr) / dpr;
793
2642
  }
2643
+
2644
+ function useLatestRef(value) {
2645
+ const ref = React__namespace.useRef(value);
2646
+ index(() => {
2647
+ ref.current = value;
2648
+ });
2649
+ return ref;
2650
+ }
2651
+
2652
+ /**
2653
+ * Provides data to position a floating element.
2654
+ * @see https://floating-ui.com/docs/useFloating
2655
+ */
2656
+ function useFloating(options) {
2657
+ if (options === void 0) {
2658
+ options = {};
2659
+ }
2660
+ const {
2661
+ placement = 'bottom',
2662
+ strategy = 'absolute',
2663
+ middleware = [],
2664
+ platform,
2665
+ elements: {
2666
+ reference: externalReference,
2667
+ floating: externalFloating
2668
+ } = {},
2669
+ transform = true,
2670
+ whileElementsMounted,
2671
+ open
2672
+ } = options;
2673
+ const [data, setData] = React__namespace.useState({
2674
+ x: 0,
2675
+ y: 0,
2676
+ strategy,
2677
+ placement,
2678
+ middlewareData: {},
2679
+ isPositioned: false
2680
+ });
2681
+ const [latestMiddleware, setLatestMiddleware] = React__namespace.useState(middleware);
2682
+ if (!deepEqual(latestMiddleware, middleware)) {
2683
+ setLatestMiddleware(middleware);
2684
+ }
2685
+ const [_reference, _setReference] = React__namespace.useState(null);
2686
+ const [_floating, _setFloating] = React__namespace.useState(null);
2687
+ const setReference = React__namespace.useCallback(node => {
2688
+ if (node !== referenceRef.current) {
2689
+ referenceRef.current = node;
2690
+ _setReference(node);
2691
+ }
2692
+ }, []);
2693
+ const setFloating = React__namespace.useCallback(node => {
2694
+ if (node !== floatingRef.current) {
2695
+ floatingRef.current = node;
2696
+ _setFloating(node);
2697
+ }
2698
+ }, []);
2699
+ const referenceEl = externalReference || _reference;
2700
+ const floatingEl = externalFloating || _floating;
2701
+ const referenceRef = React__namespace.useRef(null);
2702
+ const floatingRef = React__namespace.useRef(null);
2703
+ const dataRef = React__namespace.useRef(data);
2704
+ const hasWhileElementsMounted = whileElementsMounted != null;
2705
+ const whileElementsMountedRef = useLatestRef(whileElementsMounted);
2706
+ const platformRef = useLatestRef(platform);
2707
+ const openRef = useLatestRef(open);
2708
+ const update = React__namespace.useCallback(() => {
2709
+ if (!referenceRef.current || !floatingRef.current) {
2710
+ return;
2711
+ }
2712
+ const config = {
2713
+ placement,
2714
+ strategy,
2715
+ middleware: latestMiddleware
2716
+ };
2717
+ if (platformRef.current) {
2718
+ config.platform = platformRef.current;
2719
+ }
2720
+ computePosition(referenceRef.current, floatingRef.current, config).then(data => {
2721
+ const fullData = {
2722
+ ...data,
2723
+ // The floating element's position may be recomputed while it's closed
2724
+ // but still mounted (such as when transitioning out). To ensure
2725
+ // `isPositioned` will be `false` initially on the next open, avoid
2726
+ // setting it to `true` when `open === false` (must be specified).
2727
+ isPositioned: openRef.current !== false
2728
+ };
2729
+ if (isMountedRef.current && !deepEqual(dataRef.current, fullData)) {
2730
+ dataRef.current = fullData;
2731
+ ReactDOM__namespace.flushSync(() => {
2732
+ setData(fullData);
2733
+ });
2734
+ }
2735
+ });
2736
+ }, [latestMiddleware, placement, strategy, platformRef, openRef]);
2737
+ index(() => {
2738
+ if (open === false && dataRef.current.isPositioned) {
2739
+ dataRef.current.isPositioned = false;
2740
+ setData(data => ({
2741
+ ...data,
2742
+ isPositioned: false
2743
+ }));
2744
+ }
2745
+ }, [open]);
2746
+ const isMountedRef = React__namespace.useRef(false);
2747
+ index(() => {
2748
+ isMountedRef.current = true;
2749
+ return () => {
2750
+ isMountedRef.current = false;
2751
+ };
2752
+ }, []);
2753
+ index(() => {
2754
+ if (referenceEl) referenceRef.current = referenceEl;
2755
+ if (floatingEl) floatingRef.current = floatingEl;
2756
+ if (referenceEl && floatingEl) {
2757
+ if (whileElementsMountedRef.current) {
2758
+ return whileElementsMountedRef.current(referenceEl, floatingEl, update);
2759
+ }
2760
+ update();
2761
+ }
2762
+ }, [referenceEl, floatingEl, update, whileElementsMountedRef, hasWhileElementsMounted]);
2763
+ const refs = React__namespace.useMemo(() => ({
2764
+ reference: referenceRef,
2765
+ floating: floatingRef,
2766
+ setReference,
2767
+ setFloating
2768
+ }), [setReference, setFloating]);
2769
+ const elements = React__namespace.useMemo(() => ({
2770
+ reference: referenceEl,
2771
+ floating: floatingEl
2772
+ }), [referenceEl, floatingEl]);
2773
+ const floatingStyles = React__namespace.useMemo(() => {
2774
+ const initialStyles = {
2775
+ position: strategy,
2776
+ left: 0,
2777
+ top: 0
2778
+ };
2779
+ if (!elements.floating) {
2780
+ return initialStyles;
2781
+ }
2782
+ const x = roundByDPR(elements.floating, data.x);
2783
+ const y = roundByDPR(elements.floating, data.y);
2784
+ if (transform) {
2785
+ return {
2786
+ ...initialStyles,
2787
+ transform: "translate(" + x + "px, " + y + "px)",
2788
+ ...(getDPR(elements.floating) >= 1.5 && {
2789
+ willChange: 'transform'
2790
+ })
2791
+ };
2792
+ }
2793
+ return {
2794
+ position: strategy,
2795
+ left: x,
2796
+ top: y
2797
+ };
2798
+ }, [strategy, transform, elements.floating, data.x, data.y]);
2799
+ return React__namespace.useMemo(() => ({
2800
+ ...data,
2801
+ update,
2802
+ refs,
2803
+ elements,
2804
+ floatingStyles
2805
+ }), [data, update, refs, elements, floatingStyles]);
2806
+ }
2807
+
2808
+ /**
2809
+ * Provides data to position an inner element of the floating element so that it
2810
+ * appears centered to the reference element.
2811
+ * This wraps the core `arrow` middleware to allow React refs as the element.
2812
+ * @see https://floating-ui.com/docs/arrow
2813
+ */
2814
+ const arrow$1 = options => {
2815
+ function isRef(value) {
2816
+ return {}.hasOwnProperty.call(value, 'current');
2817
+ }
2818
+ return {
2819
+ name: 'arrow',
2820
+ options,
2821
+ fn(state) {
2822
+ const {
2823
+ element,
2824
+ padding
2825
+ } = typeof options === 'function' ? options(state) : options;
2826
+ if (element && isRef(element)) {
2827
+ if (element.current != null) {
2828
+ return arrow$2({
2829
+ element: element.current,
2830
+ padding
2831
+ }).fn(state);
2832
+ }
2833
+ return {};
2834
+ }
2835
+ if (element) {
2836
+ return arrow$2({
2837
+ element,
2838
+ padding
2839
+ }).fn(state);
2840
+ }
2841
+ return {};
2842
+ }
2843
+ };
2844
+ };
2845
+
2846
+ /**
2847
+ * Modifies the placement by translating the floating element along the
2848
+ * specified axes.
2849
+ * A number (shorthand for `mainAxis` or distance), or an axes configuration
2850
+ * object may be passed.
2851
+ * @see https://floating-ui.com/docs/offset
2852
+ */
2853
+ const offset = (options, deps) => ({
2854
+ ...offset$1(options),
2855
+ options: [options, deps]
2856
+ });
2857
+
2858
+ /**
2859
+ * Optimizes the visibility of the floating element by shifting it in order to
2860
+ * keep it in view when it will overflow the clipping boundary.
2861
+ * @see https://floating-ui.com/docs/shift
2862
+ */
2863
+ const shift = (options, deps) => ({
2864
+ ...shift$1(options),
2865
+ options: [options, deps]
2866
+ });
2867
+
2868
+ /**
2869
+ * Optimizes the visibility of the floating element by flipping the `placement`
2870
+ * in order to keep it in view when the preferred placement(s) will overflow the
2871
+ * clipping boundary. Alternative to `autoPlacement`.
2872
+ * @see https://floating-ui.com/docs/flip
2873
+ */
2874
+ const flip = (options, deps) => ({
2875
+ ...flip$1(options),
2876
+ options: [options, deps]
2877
+ });
2878
+
2879
+ /**
2880
+ * Provides data that allows you to change the size of the floating element —
2881
+ * for instance, prevent it from overflowing the clipping boundary or match the
2882
+ * width of the reference element.
2883
+ * @see https://floating-ui.com/docs/size
2884
+ */
2885
+ const size = (options, deps) => ({
2886
+ ...size$1(options),
2887
+ options: [options, deps]
2888
+ });
2889
+
2890
+ /**
2891
+ * Provides data to position an inner element of the floating element so that it
2892
+ * appears centered to the reference element.
2893
+ * This wraps the core `arrow` middleware to allow React refs as the element.
2894
+ * @see https://floating-ui.com/docs/arrow
2895
+ */
2896
+ const arrow = (options, deps) => ({
2897
+ ...arrow$1(options),
2898
+ options: [options, deps]
2899
+ });
2900
+
2901
+ function TooltipTrigger({ as, asChild = false, children, ...props }) {
2902
+ const TooltipTriggerElement = as || react.Button;
2903
+ if (asChild && React.isValidElement(children))
2904
+ return React.cloneElement(children, props);
2905
+ return jsxRuntime.jsx(TooltipTriggerElement, { ...props, children: children });
2906
+ }
2907
+ function TooltipPanel({ as, children, className, style, ...props }) {
2908
+ const TooltipPanelElement = as || 'div';
2909
+ return (jsxRuntime.jsx(TooltipPanelElement, { ...props, className: twMerge('absolute top-0 left-0 z-50 w-max rounded-md bg-neutral-50 px-2 py-1 text-sm text-neutral-950 opacity-0 shadow-lg outline-1 outline-neutral-400 data-portal:fixed data-ready:animate-fade-in dark:bg-neutral-800 dark:text-neutral-50 dark:shadow-none dark:-outline-offset-1 dark:outline-neutral-600', className), style: style, children: children }));
2910
+ }
2911
+ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, delay = 500, offset: offset$1 = 8, onClose, onOpen, portal, }) {
2912
+ const [isOpen, setIsOpen] = React.useState(false), timeoutRef = React.useRef(undefined), arrowRef = React.useRef(null);
2913
+ const [bodyElement, setBodyElement] = React.useState(() => typeof window !== 'undefined' ? document.body : null);
2914
+ React.useEffect(() => {
2915
+ if (typeof window !== 'undefined' && !bodyElement) {
2916
+ const documentBody = document.body;
2917
+ setBodyElement(documentBody);
2918
+ }
2919
+ }, [bodyElement, portal]);
2920
+ const { refs, floatingStyles, isPositioned, placement, middlewareData } = useFloating({
2921
+ middleware: [
2922
+ offset(offset$1),
2923
+ flip({ padding: 20 }),
2924
+ shift({ padding: 20 }),
2925
+ size({
2926
+ apply({ availableHeight, availableWidth, elements }) {
2927
+ const height = `${Math.max(0, availableHeight) / 16}rem`, width = `${Math.min(418, availableWidth) / 16}rem`;
2928
+ elements.floating.style.maxHeight = height;
2929
+ elements.floating.style.maxWidth = width;
2930
+ },
2931
+ }),
2932
+ ...(arrowRef.current ? [arrow({ element: arrowRef.current })] : []),
2933
+ ],
2934
+ placement: anchor,
2935
+ strategy: portal ? 'fixed' : 'absolute',
2936
+ whileElementsMounted: autoUpdate,
2937
+ open: isOpen,
2938
+ });
2939
+ const openTooltip = React.useCallback(() => {
2940
+ clearTimeout(timeoutRef.current);
2941
+ if (delay > 0) {
2942
+ timeoutRef.current = setTimeout(() => {
2943
+ setIsOpen(true);
2944
+ onOpen?.();
2945
+ }, delay);
2946
+ }
2947
+ else {
2948
+ setIsOpen(true);
2949
+ onOpen?.();
2950
+ }
2951
+ }, [delay, onOpen]);
2952
+ const closeTooltip = React.useCallback(() => {
2953
+ clearTimeout(timeoutRef.current);
2954
+ setIsOpen(false);
2955
+ onClose?.();
2956
+ }, [onClose]);
2957
+ React.useEffect(() => {
2958
+ return () => {
2959
+ clearTimeout(timeoutRef.current);
2960
+ };
2961
+ }, []);
2962
+ const content = typeof children === 'function' ? children({ openTooltip, closeTooltip }) : children;
2963
+ const triggerElement = findComponentByType(content, TooltipTrigger), contentElement = findComponentByType(content, TooltipPanel);
2964
+ if (!contentElement)
2965
+ throw new Error('TooltipPanel must be defined in Tooltip children');
2966
+ if (!triggerElement && typeof children !== 'function')
2967
+ throw new Error('TooltipTrigger must be provided when not using render prop pattern');
2968
+ const arrowStyles = {};
2969
+ const reversedAnchor = {
2970
+ top: 'bottom',
2971
+ right: 'left',
2972
+ bottom: 'top',
2973
+ left: 'right',
2974
+ 'top-start': 'bottom left',
2975
+ 'top-end': 'bottom right',
2976
+ 'right-start': 'top left',
2977
+ 'right-end': 'bottom left',
2978
+ 'bottom-start': 'top left',
2979
+ 'bottom-end': 'top right',
2980
+ 'left-start': 'top right',
2981
+ 'left-end': 'bottom right',
2982
+ }[placement];
2983
+ if (middlewareData.arrow && arrow$1) {
2984
+ const { x, y } = middlewareData.arrow;
2985
+ const staticSide = {
2986
+ top: 'bottom',
2987
+ right: 'left',
2988
+ bottom: 'top',
2989
+ left: 'right',
2990
+ }[placement.split('-')[0]];
2991
+ if (staticSide) {
2992
+ arrowStyles[staticSide] = '-4px';
2993
+ if (x != null)
2994
+ arrowStyles.left = `${x}px`;
2995
+ if (y != null)
2996
+ arrowStyles.top = `${y}px`;
2997
+ }
2998
+ }
2999
+ const getArrowLocationClasses = () => {
3000
+ switch (placement) {
3001
+ case 'bottom':
3002
+ case 'bottom-end':
3003
+ case 'bottom-start':
3004
+ return '-translate-y-1';
3005
+ case 'top':
3006
+ case 'top-end':
3007
+ case 'top-start':
3008
+ return 'rotate-180 translate-y-1';
3009
+ case 'left':
3010
+ case 'left-end':
3011
+ case 'left-start':
3012
+ return 'rotate-90 translate-x-2';
3013
+ case 'right':
3014
+ case 'right-end':
3015
+ case 'right-start':
3016
+ return '-rotate-90 -translate-x-2';
3017
+ }
3018
+ };
3019
+ const arrowLocationClasses = getArrowLocationClasses();
3020
+ const handleMouseEnter = e => {
3021
+ openTooltip();
3022
+ triggerElement?.props.onMouseEnter?.(e);
3023
+ };
3024
+ const handleMouseLeave = e => {
3025
+ triggerElement?.props.onMouseLeave?.(e);
3026
+ closeTooltip();
3027
+ };
3028
+ const handleTouchStart = e => {
3029
+ openTooltip();
3030
+ triggerElement?.props.onTouchStart?.(e);
3031
+ };
3032
+ const handleFocus = e => {
3033
+ triggerElement?.props.onFocus?.(e);
3034
+ openTooltip();
3035
+ };
3036
+ const handleBlur = e => {
3037
+ triggerElement?.props.onBlur?.(e);
3038
+ closeTooltip();
3039
+ };
3040
+ const tooltipContent = (jsxRuntime.jsx(jsxRuntime.Fragment, { children: isOpen &&
3041
+ contentElement &&
3042
+ React.cloneElement(contentElement, {
3043
+ children: (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [contentElement.props.children, arrow$1 && (jsxRuntime.jsx(ArrowSvg, { className: twMerge('absolute', arrowLocationClasses, arrowClassName), style: arrowStyles, "data-tooltip-arrow": true }))] })),
3044
+ ...(portal ? { 'data-portal': true } : {}),
3045
+ ...(isPositioned ? { 'data-ready': true } : {}),
3046
+ onMouseEnter: openTooltip,
3047
+ onMouseLeave: closeTooltip,
3048
+ onTouchStart: handleTouchStart,
3049
+ ref: (node) => {
3050
+ refs.setFloating(node);
3051
+ if (node && arrow$1) {
3052
+ const arrowElement = node.querySelector('[data-tooltip-arrow]');
3053
+ if (arrowElement)
3054
+ arrowRef.current = arrowElement;
3055
+ }
3056
+ },
3057
+ role: 'tooltip',
3058
+ style: {
3059
+ ...contentElement.props.style,
3060
+ ...floatingStyles,
3061
+ transformOrigin: reversedAnchor,
3062
+ pointerEvents: 'none',
3063
+ },
3064
+ }) }));
3065
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [triggerElement &&
3066
+ React.cloneElement(triggerElement, {
3067
+ ref: refs.setReference,
3068
+ onMouseEnter: handleMouseEnter,
3069
+ onMouseLeave: handleMouseLeave,
3070
+ onFocus: handleFocus,
3071
+ onBlur: handleBlur,
3072
+ 'aria-describedby': isOpen ? 'tooltip' : undefined,
3073
+ }), portal ? bodyElement && ReactDOM.createPortal(tooltipContent, bodyElement) : tooltipContent] }));
3074
+ }
3075
+ function ArrowSvg({ className, ...props }) {
3076
+ return (jsxRuntime.jsxs("svg", { viewBox: '0 0 20 10', className: twMerge('h-2.5 w-5 fill-none', className), ...props, children: [jsxRuntime.jsx("path", { d: 'M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z', className: 'fill-neutral-50 dark:fill-neutral-800' }), jsxRuntime.jsx("path", { d: 'M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z', className: 'fill-neutral-400 dark:fill-none' }), jsxRuntime.jsx("path", { d: 'M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z', className: 'dark:fill-neutral-600' })] }));
3077
+ }
3078
+
794
3079
  function Input({ checked, className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, name, onBlur, onChange, placeholder, ref, required = true, type, value, ...props }) {
795
- const [formContext, setFormContext] = useFormContext();
3080
+ const [formContext, setFormContext] = useFormContext(), [errorMessage, setErrorMessage] = React.useState(undefined);
796
3081
  if (placeholder === '*')
797
3082
  placeholder = name + (required && !label ? '*' : '');
798
3083
  if (label === '*')
799
3084
  label = name;
800
- const uniqueID = react.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
3085
+ const uniqueID = React.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
801
3086
  if (Boolean(formContext?.find(field => field.id === fieldContextID)?.invalid))
802
3087
  invalid = true;
803
3088
  const getFieldContextType = () => {
@@ -825,7 +3110,7 @@ function Input({ checked, className, defaultValue, description, descriptionProps
825
3110
  required,
826
3111
  value: value ? `${value}` : defaultValue ? `${defaultValue}` : '',
827
3112
  });
828
- react.useEffect(() => {
3113
+ React.useEffect(() => {
829
3114
  if (!setFormContext)
830
3115
  return;
831
3116
  setFormContext(prevContext => {
@@ -837,13 +3122,40 @@ function Input({ checked, className, defaultValue, description, descriptionProps
837
3122
  };
838
3123
  }, [setFormContext]);
839
3124
  const fieldContext = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id) || initialFieldContext;
840
- const debounceTimerRef = react.useRef(undefined);
3125
+ const validateField = (validValue) => {
3126
+ const noValue = !validValue || validValue === '';
3127
+ if (!required && noValue)
3128
+ return true;
3129
+ const errorMessageList = [];
3130
+ if (noValue) {
3131
+ errorMessageList.push('This field is required.');
3132
+ setErrorMessage(errorMessageList.join(' '));
3133
+ return false;
3134
+ }
3135
+ switch (type) {
3136
+ case 'email':
3137
+ if (!isEmail(validValue))
3138
+ errorMessageList.push('This is not a valid email.');
3139
+ break;
3140
+ case 'number':
3141
+ if (isNaN(Number(validValue)))
3142
+ errorMessageList.push('This is not a valid number.');
3143
+ break;
3144
+ case 'tel':
3145
+ if (!isPhoneNumber(validValue))
3146
+ errorMessageList.push('This is not a valid phone number.');
3147
+ break;
3148
+ }
3149
+ if (errorMessageList.length === 0)
3150
+ return true;
3151
+ setErrorMessage(errorMessageList.join(' '));
3152
+ return false;
3153
+ };
841
3154
  const handleChange = e => {
842
3155
  if (disabled) {
843
3156
  e.preventDefault();
844
3157
  return;
845
3158
  }
846
- clearTimeout(debounceTimerRef.current);
847
3159
  const { currentTarget } = e, { value: newValue } = currentTarget;
848
3160
  setFormContext?.(prevContext => {
849
3161
  if (!prevContext)
@@ -853,25 +3165,11 @@ function Input({ checked, className, defaultValue, description, descriptionProps
853
3165
  throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
854
3166
  const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
855
3167
  const updatedField = { ...field, value: newValue };
3168
+ const invalidField = validateField(newValue) === false;
3169
+ if (invalidField !== field.invalid)
3170
+ updatedField.invalid = invalidField;
856
3171
  return [...otherFields, updatedField];
857
3172
  });
858
- debounceTimerRef.current = setTimeout(() => {
859
- const field = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
860
- if (!field)
861
- return;
862
- const invalid = validateField$1(newValue, field) === false;
863
- if (invalid !== field.invalid)
864
- setFormContext?.(prevContext => {
865
- if (!prevContext)
866
- return [];
867
- const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
868
- if (!field)
869
- throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
870
- const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
871
- const updatedField = { ...field, invalid };
872
- return [...otherFields, updatedField];
873
- });
874
- }, 500);
875
3173
  onChange?.(e);
876
3174
  };
877
3175
  const handleBlur = e => {
@@ -880,6 +3178,8 @@ function Input({ checked, className, defaultValue, description, descriptionProps
880
3178
  return;
881
3179
  }
882
3180
  const { currentTarget } = e, { value: newValue } = currentTarget;
3181
+ if (required)
3182
+ validateField(newValue);
883
3183
  switch (type) {
884
3184
  case 'email':
885
3185
  setFormContext?.(prevContext => {
@@ -917,20 +3217,20 @@ function Input({ checked, className, defaultValue, description, descriptionProps
917
3217
  const restDescriptionProps = descriptionProps
918
3218
  ? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== 'className'))
919
3219
  : {};
920
- return (jsxRuntime.jsxs(react$1.Field, { ...restFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react$1.Label, { ...restLabelProps, className: bag => twMerge('text-sm font-medium', required ? 'after:text-ui-red after:content-["_*"]' : '', typeof labelProps?.className === 'function' ? labelProps?.className(bag) : labelProps?.className), children: label })), jsxRuntime.jsx(react$1.Input, { ...props, className: bag => twMerge(
921
- // Base styles
922
- 'rounded-xl border-1 border-neutral-500/50 bg-neutral-100 py-1 pl-2 text-neutral-950 outline-offset-1 outline-ui-sky-blue/95 transition-[background-color] duration-300 ease-exponential dark:bg-neutral-700 dark:text-neutral-50',
923
- // Pseudo styles
924
- 'focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800',
925
- // user-invalid styles
926
- 'user-invalid:border-ui-red user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-100))] user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-800))] dark:user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))] user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-100))] user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))]',
927
- // Custom styles
928
- typeof className === 'function' ? className(bag) : className), id: fieldContext?.id, invalid: invalid, onBlur: handleBlur, onChange: handleChange, placeholder: placeholder, ref: ref, required: required, type: type, value: fieldContext?.value }), description && (jsxRuntime.jsx(react$1.Description, { ...restDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
3220
+ return (jsxRuntime.jsxs(react.Field, { ...restFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react.Label, { ...restLabelProps, className: bag => twMerge('text-sm font-medium', required ? 'after:text-ui-red after:content-["_*"]' : '', typeof labelProps?.className === 'function' ? labelProps?.className(bag) : labelProps?.className), children: label })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(react.Input, { ...props, className: bag => twMerge(
3221
+ // Base styles
3222
+ 'w-full rounded-xl border-1 border-neutral-500/50 bg-neutral-100 py-1 pl-2 text-neutral-950 outline-offset-1 outline-ui-sky-blue/95 transition-[background-color] duration-300 ease-exponential dark:bg-neutral-700 dark:text-neutral-50',
3223
+ // Pseudo styles
3224
+ 'focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800',
3225
+ // user-invalid styles
3226
+ 'user-invalid:border-ui-red user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-100))] user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-800))] dark:user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))] user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-100))] user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))]',
3227
+ // Custom styles
3228
+ typeof className === 'function' ? className(bag) : className), invalid: invalid, onBlur: handleBlur, onChange: handleChange, placeholder: placeholder, ref: ref, required: required, type: type, value: fieldContext?.value }), fieldContext.invalid && errorMessage && (jsxRuntime.jsxs(Tooltip, { anchor: 'top-end', arrow: true, portal: true, children: [jsxRuntime.jsx(TooltipTrigger, { as: Button, className: 'absolute top-1.25 right-1.25 z-10 size-6 min-w-0', padding: 'none', rounded: 'md', theme: 'red', children: jsxRuntime.jsx(ExclamationmarkOctagon, { className: 'absolute top-1/2 left-1/2 size-full -translate-x-1/2 -translate-y-1/2 scale-70' }) }), jsxRuntime.jsx(TooltipPanel, { children: errorMessage })] }))] }), description && (jsxRuntime.jsx(react.Description, { ...restDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
929
3229
  ? descriptionProps?.className(bag)
930
3230
  : descriptionProps?.className), children: description }))] }));
931
3231
  }
932
3232
 
933
- function SubmitButton({ children, className, error, incomplete, loading, success, theme, type = 'submit', ref, ...props }) {
3233
+ function SubmitButton({ children, className, customTheme, error, incomplete, loading, success, type = 'submit', ...props }) {
934
3234
  const [formStatus] = useFormStatus();
935
3235
  const getFormStatusButtonClasses = () => {
936
3236
  switch (formStatus) {
@@ -944,21 +3244,6 @@ function SubmitButton({ children, className, error, incomplete, loading, success
944
3244
  }
945
3245
  };
946
3246
  const formStatusButtonClasses = getFormStatusButtonClasses();
947
- const getFormStatusButtonTheme = () => {
948
- switch (formStatus) {
949
- case 'incomplete':
950
- return 'grey';
951
- case 'loading':
952
- return 'blue';
953
- case 'error':
954
- return 'red';
955
- case 'success':
956
- return 'green';
957
- default:
958
- return theme;
959
- }
960
- };
961
- const formStatusButtonTheme = getFormStatusButtonTheme();
962
3247
  const getButtonText = () => {
963
3248
  switch (formStatus) {
964
3249
  case 'incomplete':
@@ -974,24 +3259,37 @@ function SubmitButton({ children, className, error, incomplete, loading, success
974
3259
  }
975
3260
  };
976
3261
  const buttonText = getButtonText();
977
- return (jsxRuntime.jsx(Button, { ...props, className: twMerge([formStatusButtonClasses, 'w-full', className]), ref: ref, theme: formStatusButtonTheme, type: type, children: buttonText }));
3262
+ const getDataFormState = () => {
3263
+ switch (formStatus) {
3264
+ case 'error':
3265
+ return { 'data-error': true };
3266
+ case 'incomplete':
3267
+ return { 'data-incomplete': true };
3268
+ case 'loading':
3269
+ return { 'data-loading': true };
3270
+ case 'readonly':
3271
+ return { 'data-readonly': true };
3272
+ case 'ready':
3273
+ return { 'data-ready': true };
3274
+ case 'success':
3275
+ return { 'data-success': true };
3276
+ default:
3277
+ return {};
3278
+ }
3279
+ };
3280
+ const dataFormState = getDataFormState();
3281
+ return (jsxRuntime.jsx(Button, { ...props, ...dataFormState, as: 'button', className: twMerge([formStatusButtonClasses, 'w-full text-white data-loading:text-black', className]), customTheme: {
3282
+ themeColor: twMerge('data-error:[--theme-color:var(--color-ui-red)] data-incomplete:[--theme-color:var(--color-ui-grey)] data-loading:[--theme-color:var(--color-ui-yellow)] data-readonly:[--theme-color:var(--color-ui-grey)] data-ready:[--theme-color:var(--color-ui-blue)] data-success:[--theme-color:var(--color-ui-green)]', customTheme?.themeColor),
3283
+ }, theme: 'custom', type: type, children: buttonText }));
978
3284
  }
979
3285
 
980
- function validateField(value, { required }) {
981
- const noValue = !value || value === '';
982
- if (!required && noValue)
983
- return true;
984
- if (noValue)
985
- return false;
986
- return true;
987
- }
988
3286
  function Textarea({ className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, name, onBlur, onChange, placeholder, ref, required = true, value, ...props }) {
989
- const [formContext, setFormContext] = useFormContext();
3287
+ const [formContext, setFormContext] = useFormContext(), [errorMessage, setErrorMessage] = React.useState(undefined);
990
3288
  if (placeholder === '*')
991
3289
  placeholder = name + (required && !label ? '*' : '');
992
3290
  if (label === '*')
993
3291
  label = name;
994
- const uniqueID = react.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
3292
+ const uniqueID = React.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
995
3293
  if (Boolean(formContext?.find(field => field.id === fieldContextID)?.invalid))
996
3294
  invalid = true;
997
3295
  const initialFieldContext = defineField({
@@ -1002,7 +3300,7 @@ function Textarea({ className, defaultValue, description, descriptionProps, disa
1002
3300
  required,
1003
3301
  value: value ? `${value}` : defaultValue ? `${defaultValue}` : '',
1004
3302
  });
1005
- react.useEffect(() => {
3303
+ React.useEffect(() => {
1006
3304
  if (!setFormContext)
1007
3305
  return;
1008
3306
  setFormContext(prevContext => {
@@ -1014,13 +3312,26 @@ function Textarea({ className, defaultValue, description, descriptionProps, disa
1014
3312
  };
1015
3313
  }, [setFormContext]);
1016
3314
  const fieldContext = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id) || initialFieldContext;
1017
- const debounceTimerRef = react.useRef(undefined);
3315
+ const validateField = (validValue) => {
3316
+ const noValue = !validValue || validValue === '';
3317
+ if (!required && noValue)
3318
+ return true;
3319
+ const errorMessageList = [];
3320
+ if (noValue) {
3321
+ errorMessageList.push('This field is required.');
3322
+ setErrorMessage(errorMessageList.join(' '));
3323
+ return false;
3324
+ }
3325
+ if (errorMessageList.length === 0)
3326
+ return true;
3327
+ setErrorMessage(errorMessageList.join(' '));
3328
+ return false;
3329
+ };
1018
3330
  const handleChange = e => {
1019
3331
  if (disabled) {
1020
3332
  e.preventDefault();
1021
3333
  return;
1022
3334
  }
1023
- clearTimeout(debounceTimerRef.current);
1024
3335
  const { currentTarget } = e, { value: newValue } = currentTarget;
1025
3336
  setFormContext?.(prevContext => {
1026
3337
  if (!prevContext)
@@ -1030,25 +3341,11 @@ function Textarea({ className, defaultValue, description, descriptionProps, disa
1030
3341
  throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
1031
3342
  const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
1032
3343
  const updatedField = { ...field, value: newValue };
3344
+ const invalidField = validateField(newValue) === false;
3345
+ if (invalidField !== field.invalid)
3346
+ updatedField.invalid = invalidField;
1033
3347
  return [...otherFields, updatedField];
1034
3348
  });
1035
- debounceTimerRef.current = setTimeout(() => {
1036
- const field = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
1037
- if (!field)
1038
- return;
1039
- const invalid = validateField(newValue, field) === false;
1040
- if (invalid !== field.invalid)
1041
- setFormContext?.(prevContext => {
1042
- if (!prevContext)
1043
- return [];
1044
- const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
1045
- if (!field)
1046
- throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
1047
- const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
1048
- const updatedField = { ...field, invalid };
1049
- return [...otherFields, updatedField];
1050
- });
1051
- }, 500);
1052
3349
  onChange?.(e);
1053
3350
  };
1054
3351
  const restFieldProps = fieldProps
@@ -1060,15 +3357,15 @@ function Textarea({ className, defaultValue, description, descriptionProps, disa
1060
3357
  const restDescriptionProps = descriptionProps
1061
3358
  ? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== 'className'))
1062
3359
  : {};
1063
- return (jsxRuntime.jsxs(react$1.Field, { ...restFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react$1.Label, { ...restLabelProps, className: bag => twMerge('text-sm font-medium', required ? 'after:text-ui-red after:content-["_*"]' : '', typeof labelProps?.className === 'function' ? labelProps?.className(bag) : labelProps?.className), children: label })), jsxRuntime.jsx(react$1.Textarea, { ...props, className: bag => twMerge(
1064
- // Base styles
1065
- 'field-sizing-content resize-none rounded-xl border-1 border-neutral-500/50 bg-neutral-100 py-1 pl-2 text-neutral-950 outline-offset-1 outline-ui-sky-blue/95 transition-[background-color] duration-300 ease-exponential dark:bg-neutral-700 dark:text-neutral-50',
1066
- // Pseudo styles
1067
- 'focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800',
1068
- // user-invalid styles
1069
- 'user-invalid:border-ui-red user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-100))] user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-800))] dark:user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))] user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-100))] user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))]',
1070
- // Custom styles
1071
- typeof className === 'function' ? className(bag) : className), id: fieldContext?.id, invalid: invalid, onChange: handleChange, placeholder: placeholder, ref: ref, required: required, value: fieldContext?.value }), description && (jsxRuntime.jsx(react$1.Description, { ...restDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
3360
+ return (jsxRuntime.jsxs(react.Field, { ...restFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react.Label, { ...restLabelProps, className: bag => twMerge('text-sm font-medium', required ? 'after:text-ui-red after:content-["_*"]' : '', typeof labelProps?.className === 'function' ? labelProps?.className(bag) : labelProps?.className), children: label })), jsxRuntime.jsxs("div", { className: 'z-10 -mb-1.5', children: [jsxRuntime.jsx(react.Textarea, { ...props, className: bag => twMerge(
3361
+ // Base styles
3362
+ 'field-sizing-content w-full resize-none rounded-xl border-1 border-neutral-500/50 bg-neutral-100 py-1 pl-2 text-neutral-950 outline-offset-1 outline-ui-sky-blue/95 transition-[background-color] duration-300 ease-exponential dark:bg-neutral-700 dark:text-neutral-50',
3363
+ // Pseudo styles
3364
+ 'focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800',
3365
+ // user-invalid styles
3366
+ 'user-invalid:border-ui-red user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-100))] user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-800))] dark:user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))] user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-100))] user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))]',
3367
+ // Custom styles
3368
+ typeof className === 'function' ? className(bag) : className), id: fieldContext?.id, invalid: invalid, onChange: handleChange, placeholder: placeholder, ref: ref, required: required, value: fieldContext?.value }), fieldContext.invalid && errorMessage && (jsxRuntime.jsxs(Tooltip, { anchor: 'top-end', arrow: true, portal: true, children: [jsxRuntime.jsx(TooltipTrigger, { as: Button, className: 'absolute top-1.25 right-1.25 z-10 size-6 min-w-0', padding: 'none', rounded: 'md', theme: 'red', children: jsxRuntime.jsx(ExclamationmarkOctagon, { className: 'absolute top-1/2 left-1/2 size-full -translate-x-1/2 -translate-y-1/2 scale-70' }) }), jsxRuntime.jsx(TooltipPanel, { children: errorMessage })] }))] }), description && (jsxRuntime.jsx(react.Description, { ...restDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
1072
3369
  ? descriptionProps?.className(bag)
1073
3370
  : descriptionProps?.className), children: description }))] }));
1074
3371
  }
@@ -1077,7 +3374,7 @@ function Textarea({ className, defaultValue, description, descriptionProps, disa
1077
3374
  function FormComponent({ as, children, className, handleSubmit, onError, onSubmit, onSuccess, ...props }) {
1078
3375
  const [formContext] = useFormContext(), [formStatus, setFormStatus] = useFormStatus();
1079
3376
  // const submitButton = findComponentByType(children, SubmitButton)
1080
- react.useEffect(() => {
3377
+ React.useEffect(() => {
1081
3378
  if (!formContext)
1082
3379
  return;
1083
3380
  if (formStatus !== 'incomplete' && formContext.find(({ invalid }) => invalid))
@@ -1093,19 +3390,19 @@ function FormComponent({ as, children, className, handleSubmit, onError, onSubmi
1093
3390
  const response = await onSubmit?.({ event: e, formContext });
1094
3391
  if (response && ('error' in response || response.status === 'error')) {
1095
3392
  setFormStatus?.('error');
1096
- onError?.({ event: e, error: response.error || 'An error occurred when submitting the form.' });
3393
+ onError?.({ event: e, error: response.error || 'An error occurred when submitting the form.', formContext });
1097
3394
  return;
1098
3395
  }
1099
3396
  if ((response && response.status === 'success') || !response) {
1100
3397
  setFormStatus?.('success');
1101
- onSuccess?.({ event: e });
3398
+ onSuccess?.({ event: e, formContext });
1102
3399
  }
1103
3400
  });
1104
3401
  const FormElement = as || 'form';
1105
3402
  return (jsxRuntime.jsx(FormElement, { ...props, className: twMerge(className, 'grid gap-3'), onSubmit: processSubmit, children: children }));
1106
3403
  }
1107
3404
  function Form({ controlled = 'auto', initialStatus = 'incomplete', ...props }) {
1108
- const FormContextOrNotProvider = controlled === 'auto' ? FormContextProvider : react.Fragment;
3405
+ const FormContextOrNotProvider = controlled === 'auto' ? FormContextProvider : React.Fragment;
1109
3406
  return (jsxRuntime.jsx(FormStatusProvider, { initialStatus: initialStatus, children: jsxRuntime.jsx(FormContextOrNotProvider, { children: jsxRuntime.jsx(FormComponent, { ...props }) }) }));
1110
3407
  }
1111
3408
 
@@ -1115,11 +3412,11 @@ function Ghost({ children, className, ...props }) {
1115
3412
 
1116
3413
  function getTextFromChildren(children) {
1117
3414
  let text = '';
1118
- react.Children.forEach(children, child => {
3415
+ React.Children.forEach(children, child => {
1119
3416
  if (typeof child === 'string' || typeof child === 'number') {
1120
3417
  text += child;
1121
3418
  }
1122
- else if (react.isValidElement(child)) {
3419
+ else if (React.isValidElement(child)) {
1123
3420
  text += getTextFromChildren(child.props.children);
1124
3421
  }
1125
3422
  });
@@ -1136,52 +3433,50 @@ function Heading({ as = 'h2', children, customize, className, id, ref, ...props
1136
3433
  const getBaseClasses = () => {
1137
3434
  switch (as) {
1138
3435
  case 'h1':
1139
- return customize?.h1 || twSort('pb-2.5 text-6xl font-black last:pb-0');
3436
+ return twMerge('pb-2.5 text-6xl font-black last:pb-0', customize?.h1);
1140
3437
  case 'h3':
1141
- return customize?.h3 || twSort('pb-2 text-4xl font-extralight last:pb-0');
3438
+ return twMerge('pb-2 text-4xl font-extralight last:pb-0', customize?.h3);
1142
3439
  case 'h4':
1143
- return customize?.h4 || twSort('pb-2 text-3xl font-extrabold last:pb-0');
3440
+ return twMerge('pb-2 text-3xl font-extrabold last:pb-0', customize?.h4);
1144
3441
  case 'h5':
1145
- return customize?.h5 || twSort('pb-1.5 text-2xl font-semibold last:pb-0');
3442
+ return twMerge('pb-1.5 text-2xl font-semibold last:pb-0', customize?.h5);
1146
3443
  case 'h6':
1147
- return customize?.h6 || twSort('pb-1 text-xl font-bold last:pb-0');
3444
+ return twMerge('pb-1 text-xl font-bold last:pb-0', customize?.h6);
1148
3445
  default:
1149
- return customize?.h2 || twSort('pb-2.5 text-5xl font-medium last:pb-0');
3446
+ return twMerge('pb-2.5 text-5xl font-medium last:pb-0', customize?.h2);
1150
3447
  }
1151
3448
  };
1152
3449
  const baseClasses = getBaseClasses();
1153
3450
  return (jsxRuntime.jsx(H, { ref: ref, id: targetableID, ...props, className: twMerge(baseClasses, className), children: children }));
1154
3451
  }
1155
3452
 
1156
- function xmark(props) {
1157
- return (jsxRuntime.jsx("svg", { viewBox: '0 0 64 64', ...props, children: jsxRuntime.jsx("path", { d: 'M1,63c0.7,0.7,1.6,1,2.6,1s1.9-0.3,2.6-1L32,37.1L57.8,63c0.7,0.7,1.5,1,2.5,1c1,0,1.9-0.3,2.6-1c0.7-0.7,1-1.6,1-2.6 c0-1-0.3-1.8-1-2.5L37.1,32L63,6.2c0.7-0.7,1-1.6,1-2.6S63.7,1.7,63,1c-0.7-0.7-1.6-1-2.6-1c-1,0-1.8,0.3-2.5,1L32,26.9L6.2,1 C5.5,0.3,4.6,0,3.6,0C2.6,0,1.7,0.3,1,1C0.3,1.7,0,2.6,0,3.6c0,1,0.3,1.9,1,2.6L26.9,32L1,57.8c-0.7,0.7-1,1.5-1,2.6 C0,61.4,0.3,62.3,1,63z' }) }));
1158
- }
1159
-
1160
3453
  function ModalTrigger({ as, ...props }) {
1161
- const Element = as || react$1.Button;
3454
+ const Element = as || react.Button;
1162
3455
  return jsxRuntime.jsx(Element, { ...props });
1163
3456
  }
1164
3457
  function ModalDialog(props) {
1165
3458
  return jsxRuntime.jsx("div", { ...props });
1166
3459
  }
1167
3460
  function Modal({ children, className, onClose, onOpen, place = 'bottom' }) {
1168
- const [bodyElement, setBodyElement] = react.useState(null);
1169
- react.useEffect(() => {
3461
+ const [bodyElement, setBodyElement] = React.useState(null);
3462
+ React.useEffect(() => {
1170
3463
  if (!bodyElement && typeof window !== 'undefined')
1171
3464
  setBodyElement(document.body);
1172
3465
  }, [bodyElement]);
1173
- const [isOpen, setIsOpen] = react.useState(false);
1174
- const dialogPanelRef = react.useRef(null), dragMoveBoxRef = react.useRef(null),
3466
+ const [isOpen, setIsOpen] = React.useState(false);
3467
+ const dialogPanelRef = React.useRef(null), dragMoveBoxRef = React.useRef(null),
1175
3468
  // lastTouchYRef = useRef(0),
1176
- startDragCoords = react.useRef({ x: 0, y: 0 });
1177
- const [allowDragClose, setAllowDragClose] = react.useState(false), [readyToClose, setReadyToClose] = react.useState(false);
3469
+ startDragCoords = React.useRef({ x: 0, y: 0 });
3470
+ const [allowDragClose, setAllowDragClose] = React.useState(false), [readyToClose, setReadyToClose] = React.useState(false);
1178
3471
  const openModal = () => {
1179
- console.log('open');
3472
+ if (isOpen)
3473
+ return;
1180
3474
  setIsOpen(true);
1181
3475
  onOpen?.();
1182
3476
  };
1183
3477
  const closeModal = () => {
1184
- console.log('close');
3478
+ if (!isOpen)
3479
+ return;
1185
3480
  setIsOpen(false);
1186
3481
  onClose?.();
1187
3482
  };
@@ -1256,28 +3551,28 @@ function Modal({ children, className, onClose, onOpen, place = 'bottom' }) {
1256
3551
  }
1257
3552
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [allowDragClose &&
1258
3553
  bodyElement &&
1259
- reactDom.createPortal(jsxRuntime.jsx("div", { ref: dragMoveBoxRef, className: 'z-99 pointer-coarse:hidden fixed inset-0 h-dvh w-screen bg-transparent active:cursor-grabbing', onMouseMove: handleMouseMove, onMouseUp: disableMouseDragClose }), bodyElement), triggerElement &&
1260
- react.cloneElement(triggerElement, { onClick: openModal }), jsxRuntime.jsxs(react$1.Dialog, { open: isOpen, onClose: closeModal, className: [
3554
+ ReactDOM.createPortal(jsxRuntime.jsx("div", { ref: dragMoveBoxRef, className: 'fixed inset-0 z-99 h-dvh w-screen bg-transparent active:cursor-grabbing pointer-coarse:hidden', onMouseMove: handleMouseMove, onMouseUp: disableMouseDragClose }), bodyElement), triggerElement &&
3555
+ React.cloneElement(triggerElement, { onClick: openModal }), jsxRuntime.jsxs(react.Dialog, { open: isOpen, onClose: closeModal, className: [
1261
3556
  'isolate z-50',
1262
3557
  place === 'bottom' &&
1263
3558
  'after:fixed after:inset-x-0 after:bottom-0 after:-z-10 after:h-16 after:bg-neutral-50 sm:after:hidden',
1264
- ].join(' '), children: [jsxRuntime.jsx(react$1.DialogBackdrop, { transition: true, className: [
1265
- 'duration-750 ease-exponential data-closed:opacity-0 fixed inset-0 cursor-pointer transition-[opacity_background-color_backdrop-filter_-webkit-backdrop-filter] delay-100',
3559
+ ].join(' '), children: [jsxRuntime.jsx(react.DialogBackdrop, { transition: true, className: [
3560
+ 'fixed inset-0 cursor-pointer transition-[opacity_background-color_backdrop-filter_-webkit-backdrop-filter] delay-100 duration-750 ease-exponential data-closed:opacity-0',
1266
3561
  readyToClose
1267
3562
  ? 'bg-neutral-50/5 backdrop-blur-[1px] dark:bg-neutral-950/5'
1268
3563
  : 'bg-neutral-50/25 backdrop-blur-sm dark:bg-neutral-950/25',
1269
- ].join(' '), children: jsxRuntime.jsx(Button, { theme: 'blue', padding: 'none', rounded: 'full', className: 'group/button pointer-fine:hover:w-20 fixed right-4 top-4 h-7 w-7 overflow-x-hidden transition-[scale_width_filter]', children: jsxRuntime.jsxs("div", { className: 'pointer-fine:group-hover/button:-translate-x-0.5 ease-exponential absolute right-1 top-1 flex items-center gap-1 pt-px transition-transform duration-300', children: [jsxRuntime.jsxs("span", { className: 'block text-xs font-medium uppercase leading-none text-neutral-50', children: ["Close", jsxRuntime.jsx("span", { className: 'sr-only', children: " Modal" })] }), jsxRuntime.jsx(xmark, { className: '-top-px block size-5 rotate-90 scale-75 fill-white stroke-white stroke-1 transition-transform duration-300 ease-in-out group-hover/button:rotate-0' })] }) }) }), jsxRuntime.jsxs(react$1.DialogPanel, { ref: dialogPanelRef, transition: true, className: twMerge('duration-750 ease-exponential data-closed:opacity-0 data-closed:scale-50 fixed left-1/2 -translate-x-1/2 overflow-y-scroll bg-neutral-50 p-4 shadow-[0_-15px_50px_-12px] shadow-neutral-950/25 transition-[transform_translate_opacity] sm:w-[calc(100vw-2rem)] sm:max-w-fit sm:p-6 sm:shadow-2xl lg:p-8 dark:bg-neutral-900', place === 'center'
1270
- ? 'data-enter:translate-y-[calc(-50%+12rem)] data-leave:translate-y-[calc(-50%-8rem)] top-1/2 -translate-y-1/2 rounded-2xl'
1271
- : 'rounded-t-4xl pointer-fine:top-1/2 pointer-fine:bottom-auto pointer-fine:-translate-y-1/2 pointer-fine:rounded-2xl data-enter:translate-y-full sm:data-enter:translate-y-[calc(-50%+12rem)] data-leave:translate-y-full sm:data-leave:translate-y-[calc(-50%-8rem)] sm:data-open:-translate-y-1/2 bottom-0 h-fit max-h-[calc(100dvh-4rem)] translate-y-0 sm:bottom-auto sm:top-1/2 sm:rounded-b-2xl sm:rounded-t-2xl', className), children: [jsxRuntime.jsx("button", { onTouchStart: enableTouchClose, onMouseDown: enableMouseClose, className: [
1272
- 'after:ease-exponential absolute inset-x-0 top-0 z-10 flex h-6 cursor-grab items-center justify-center after:h-1 after:w-8 after:rounded-full after:transition-[transform_background-color] after:duration-500 active:cursor-grabbing',
3564
+ ].join(' '), children: jsxRuntime.jsx(Button, { theme: 'blue', padding: 'none', rounded: 'full', className: 'group/button fixed top-4 right-4 h-7 w-7 overflow-x-hidden transition-[scale_width_filter] pointer-fine:hover:w-20', children: jsxRuntime.jsxs("div", { className: 'absolute top-1 right-1 flex items-center gap-1 pt-px transition-transform duration-300 ease-exponential pointer-fine:group-hover/button:-translate-x-0.5', children: [jsxRuntime.jsxs("span", { className: 'block text-xs leading-none font-medium text-neutral-50 uppercase', children: ["Close", jsxRuntime.jsx("span", { className: 'sr-only', children: " Modal" })] }), jsxRuntime.jsx(xmark, { className: '-top-px block size-5 scale-75 rotate-90 fill-white stroke-white stroke-1 transition-transform duration-300 ease-in-out group-hover/button:rotate-0' })] }) }) }), jsxRuntime.jsxs(react.DialogPanel, { ref: dialogPanelRef, transition: true, className: twMerge('fixed left-1/2 -translate-x-1/2 overflow-y-scroll bg-neutral-50 p-4 shadow-[0_-15px_50px_-12px] shadow-neutral-950/25 transition-[transform_translate_opacity] duration-750 ease-exponential data-closed:scale-50 data-closed:opacity-0 sm:w-[calc(100vw-2rem)] sm:max-w-fit sm:p-6 sm:shadow-2xl lg:p-8 dark:bg-neutral-900', place === 'center'
3565
+ ? 'top-1/2 -translate-y-1/2 rounded-2xl data-enter:translate-y-[calc(-50%+12rem)] data-leave:translate-y-[calc(-50%-8rem)]'
3566
+ : 'bottom-0 h-fit max-h-[calc(100dvh-4rem)] translate-y-0 rounded-t-4xl data-enter:translate-y-full data-leave:translate-y-full sm:top-1/2 sm:bottom-auto sm:rounded-t-2xl sm:rounded-b-2xl sm:data-enter:translate-y-[calc(-50%+12rem)] sm:data-leave:translate-y-[calc(-50%-8rem)] sm:data-open:-translate-y-1/2 pointer-fine:top-1/2 pointer-fine:bottom-auto pointer-fine:-translate-y-1/2 pointer-fine:rounded-2xl', className), children: [jsxRuntime.jsx("button", { onTouchStart: enableTouchClose, onMouseDown: enableMouseClose, className: [
3567
+ 'absolute inset-x-0 top-0 z-10 flex h-6 cursor-grab items-center justify-center after:h-1 after:w-8 after:rounded-full after:transition-[transform_background-color] after:duration-500 after:ease-exponential active:cursor-grabbing',
1273
3568
  readyToClose
1274
3569
  ? 'after:scale-x-200 after:scale-y-200 after:bg-ui-blue'
1275
- : 'after:bg-ui-grey/50 active:after:bg-ui-grey pointer-fine:hover:after:scale-x-125 pointer-fine:hover:after:bg-neutral-500/75 pointer-fine:active:after:scale-x-150 pointer-fine:active:after:bg-ui-grey active:after:scale-x-150 active:after:scale-y-125',
3570
+ : 'after:bg-ui-grey/50 active:after:scale-x-150 active:after:scale-y-125 active:after:bg-ui-grey pointer-fine:hover:after:scale-x-125 pointer-fine:hover:after:bg-neutral-500/75 pointer-fine:active:after:scale-x-150 pointer-fine:active:after:bg-ui-grey',
1276
3571
  ].join(' '), children: jsxRuntime.jsx("span", { className: 'sr-only', children: "Drag down to close" }) }), dialogElement] })] })] }));
1277
3572
  }
1278
3573
 
1279
3574
  function Time({ children, dateObject, dateTime, day, hours, milliseconds, minutes, month, seconds, year, ref, ...props }) {
1280
- const [date, setDate] = react.useState(dateObject || undefined);
3575
+ const [date, setDate] = React.useState(dateObject || undefined);
1281
3576
  const getDateAndTime = () => {
1282
3577
  if (dateTime)
1283
3578
  return dateTime;
@@ -1316,7 +3611,7 @@ function Time({ children, dateObject, dateTime, day, hours, milliseconds, minute
1316
3611
  .join(' ');
1317
3612
  };
1318
3613
  const dateDisplay = getDateDisplay();
1319
- react.useEffect(() => {
3614
+ React.useEffect(() => {
1320
3615
  if (date === undefined &&
1321
3616
  dateObject === undefined &&
1322
3617
  dateTime === undefined &&
@@ -1329,6 +3624,16 @@ function Time({ children, dateObject, dateTime, day, hours, milliseconds, minute
1329
3624
 
1330
3625
  exports.Anchor = Anchor;
1331
3626
  exports.Button = Button;
3627
+ exports.Details = Details;
3628
+ exports.DetailsBody = DetailsBody;
3629
+ exports.DetailsSummary = DetailsSummary;
3630
+ exports.DropDown = DropDown;
3631
+ exports.DropDownButton = DropDownButton;
3632
+ exports.DropDownItem = DropDownItem;
3633
+ exports.DropDownItems = DropDownItems;
3634
+ exports.DropDownSection = DropDownSection;
3635
+ exports.DropDownSeparator = DropDownSeparator;
3636
+ exports.Fieldset = Fieldset;
1332
3637
  exports.Form = Form;
1333
3638
  exports.Ghost = Ghost;
1334
3639
  exports.Heading = Heading;
@@ -1340,4 +3645,7 @@ exports.ModalTrigger = ModalTrigger;
1340
3645
  exports.SubmitButton = SubmitButton;
1341
3646
  exports.Textarea = Textarea;
1342
3647
  exports.Time = Time;
3648
+ exports.Tooltip = Tooltip;
3649
+ exports.TooltipPanel = TooltipPanel;
3650
+ exports.TooltipTrigger = TooltipTrigger;
1343
3651
  //# sourceMappingURL=components.js.map