mado-ui 0.5.5 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/index.css +100 -13
- package/dist/components/drop-down.d.ts +12 -12
- package/dist/components/drop-down.d.ts.map +1 -1
- package/dist/components/form/human-verification.d.ts +15 -0
- package/dist/components/form/human-verification.d.ts.map +1 -0
- package/dist/components/form/index.d.ts +0 -1
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/input/date/index.d.ts +16 -36
- package/dist/components/form/input/date/index.d.ts.map +1 -1
- package/dist/components/form/input/index.d.ts +91 -8
- package/dist/components/form/input/index.d.ts.map +1 -1
- package/dist/components/link.d.ts +14 -13
- package/dist/components/link.d.ts.map +1 -1
- package/dist/components/tooltip.d.ts +7 -7
- package/dist/components/tooltip.d.ts.map +1 -1
- package/dist/components/video.d.ts +6 -6
- package/dist/components/video.d.ts.map +1 -1
- package/dist/components.d.ts +96 -194
- package/dist/components.esm.js +624 -782
- package/dist/components.esm.js.map +1 -1
- package/dist/components.js +621 -779
- package/dist/components.js.map +1 -1
- package/dist/graphics.esm.js +2 -2
- package/dist/graphics.esm.js.map +1 -1
- package/dist/graphics.js +2 -2
- package/dist/graphics.js.map +1 -1
- package/dist/hooks/use-fieldset-context.d.ts.map +1 -1
- package/dist/hooks/use-form-context.d.ts +5 -5
- package/dist/hooks/use-form-context.d.ts.map +1 -1
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.esm.js.map +1 -1
- package/dist/hooks.js.map +1 -1
- package/dist/icons/index.d.ts +142 -143
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/square-and-arrow-up-right.d.ts +3 -0
- package/dist/icons/square-and-arrow-up-right.d.ts.map +1 -0
- package/dist/icons/square-and-pencil.d.ts +2 -2
- package/dist/icons/square-and-pencil.d.ts.map +1 -1
- package/dist/icons.d.ts +2 -4
- package/dist/icons.esm.js +2 -6
- package/dist/icons.esm.js.map +1 -1
- package/dist/icons.js +1 -6
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +96 -194
- package/dist/index.esm.js +624 -782
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +621 -779
- package/dist/index.js.map +1 -1
- package/dist/utils/get-date.d.ts +20 -32
- package/dist/utils/get-date.d.ts.map +1 -1
- package/dist/utils.d.ts +22 -34
- package/dist/utils.esm.js +40 -1064
- package/dist/utils.esm.js.map +1 -1
- package/dist/utils.js +41 -1067
- package/dist/utils.js.map +1 -1
- package/package.json +88 -100
- package/dist/components/form/input/date/views/index.d.ts +0 -5
- package/dist/components/form/input/date/views/index.d.ts.map +0 -1
- package/dist/icons/square-and-pencil-fill.d.ts +0 -3
- package/dist/icons/square-and-pencil-fill.d.ts.map +0 -1
package/dist/components.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
|
2
2
|
import { extendTailwindMerge, twJoin } from 'tailwind-merge';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { Children, isValidElement, Fragment, createContext, useContext, useSyncExternalStore, useRef, useCallback, useEffect, Suspense, useState, useId, useLayoutEffect, cloneElement } from 'react';
|
|
5
|
-
import { Button as Button$1, DisclosureButton, DisclosurePanel, Disclosure, MenuButton, MenuItem, MenuItems, MenuSection, MenuHeading, MenuSeparator, Menu, Fieldset as Fieldset$1, Legend, Input as Input$1,
|
|
5
|
+
import { Button as Button$1, DisclosureButton, DisclosurePanel, Disclosure, MenuButton, MenuItem, MenuItems, MenuSection, MenuHeading, MenuSeparator, Menu, Fieldset as Fieldset$1, Legend, Field, Label, Input as Input$1, Description, Textarea as Textarea$1, DialogTitle, Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react';
|
|
6
6
|
import * as ReactDOM from 'react-dom';
|
|
7
7
|
import { createPortal } from 'react-dom';
|
|
8
8
|
|
|
@@ -119,7 +119,7 @@ getMonthName();
|
|
|
119
119
|
/** The name of the current day of the week */
|
|
120
120
|
getWeekdayName();
|
|
121
121
|
/**
|
|
122
|
-
*
|
|
122
|
+
* ### Get Date
|
|
123
123
|
* - Returns the date with two digits
|
|
124
124
|
* @param {number|Date} date The date to get date
|
|
125
125
|
* @returns {string} The date with two digits
|
|
@@ -133,7 +133,7 @@ function getDate(date = d) {
|
|
|
133
133
|
return formattedDate;
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
136
|
-
*
|
|
136
|
+
* ### Get Hours
|
|
137
137
|
* - Returns the hours with two digits
|
|
138
138
|
* @param {number|Date} hours The date to get hours
|
|
139
139
|
* @returns {string} The hours with two digits
|
|
@@ -147,7 +147,7 @@ function getHours(hours = d) {
|
|
|
147
147
|
return formattedHours;
|
|
148
148
|
}
|
|
149
149
|
/**
|
|
150
|
-
*
|
|
150
|
+
* ### Get Milliseconds
|
|
151
151
|
* - Returns the milliseconds with two digits
|
|
152
152
|
* @param {number|Date} milliseconds The date to get milliseconds
|
|
153
153
|
* @returns {string} The milliseconds with two digits
|
|
@@ -161,7 +161,7 @@ function getMilliseconds(milliseconds = d) {
|
|
|
161
161
|
return formattedMilliseconds;
|
|
162
162
|
}
|
|
163
163
|
/**
|
|
164
|
-
*
|
|
164
|
+
* ### Get Minutes
|
|
165
165
|
* - Returns the minutes with two digits
|
|
166
166
|
* @param {number|Date} minutes The date to get minutes
|
|
167
167
|
* @returns {string} The minutes with two digits
|
|
@@ -175,7 +175,7 @@ function getMinutes(minutes = d) {
|
|
|
175
175
|
return formattedMinutes;
|
|
176
176
|
}
|
|
177
177
|
/**
|
|
178
|
-
*
|
|
178
|
+
* ### Get Month
|
|
179
179
|
* - Returns the month with two digits
|
|
180
180
|
* @param {number|Date} month The date to get month
|
|
181
181
|
* @returns {string} The month with two digits
|
|
@@ -192,7 +192,7 @@ function getMonthIndexFromName(name) {
|
|
|
192
192
|
return monthNamesList.findIndex(monthName => monthName === name);
|
|
193
193
|
}
|
|
194
194
|
/**
|
|
195
|
-
*
|
|
195
|
+
* ### Get Month Name
|
|
196
196
|
* - Returns the name of the specified month
|
|
197
197
|
* @param {Date} date A Date object representing the month to get the name of the month from. (Preset to the current date)
|
|
198
198
|
* @returns {MonthName} The name of the specified month
|
|
@@ -203,7 +203,7 @@ function getMonthName(date = d) {
|
|
|
203
203
|
return monthNamesList[date.getMonth()];
|
|
204
204
|
}
|
|
205
205
|
/**
|
|
206
|
-
*
|
|
206
|
+
* ### Get Seconds
|
|
207
207
|
* - Returns the seconds with two digits
|
|
208
208
|
* @param {number|Date} seconds The date to get seconds
|
|
209
209
|
* @returns {string} The seconds with two digits
|
|
@@ -217,7 +217,7 @@ function getSeconds(seconds = d) {
|
|
|
217
217
|
return formattedSeconds;
|
|
218
218
|
}
|
|
219
219
|
/**
|
|
220
|
-
*
|
|
220
|
+
* ### Get User Readable Date
|
|
221
221
|
* - Returns a string of the current date in a user-friendly way
|
|
222
222
|
* - Includes `'Yesterday'`, '`Today'`, and `'Tomorrow'`
|
|
223
223
|
* @param date (default: `new Date()`)
|
|
@@ -241,7 +241,7 @@ function getUserReadableDate(date = d) {
|
|
|
241
241
|
return fullDateString;
|
|
242
242
|
}
|
|
243
243
|
/**
|
|
244
|
-
*
|
|
244
|
+
* ### Get Weekday Name
|
|
245
245
|
* - Returns the weekday name of the specified day
|
|
246
246
|
* @param {number | Date} weekday A Date object or number representing the day to get the weekday name from. (Preset to the current date)
|
|
247
247
|
* @returns {WeekdayName} The name of the specified weekday
|
|
@@ -253,7 +253,7 @@ function getWeekdayName(weekday = d) {
|
|
|
253
253
|
return weekdayNamesList[weekday.getDay()];
|
|
254
254
|
}
|
|
255
255
|
/**
|
|
256
|
-
*
|
|
256
|
+
* ### To Full Date String
|
|
257
257
|
* - Returns a formatted string to display the date
|
|
258
258
|
* @param {Date} date (default: `new Date()`)
|
|
259
259
|
* @param {ToFullDateStringOptionsProps} options Change how to display the weekday, month name, day of the month, and year.
|
|
@@ -451,85 +451,93 @@ function twSort(className) {
|
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
function Anchor({ as, className, disabled, href, onClick, target, rel, ...props }) {
|
|
454
|
-
const isExternal = `${href}`.startsWith(
|
|
455
|
-
const handleClick = e => {
|
|
454
|
+
const isExternal = `${href}`.startsWith("http"), hasHash = `${href}`.includes("#");
|
|
455
|
+
const handleClick = (e) => {
|
|
456
456
|
if (disabled)
|
|
457
457
|
return e.preventDefault();
|
|
458
458
|
onClick?.(e);
|
|
459
459
|
setTimeout(() => history.replaceState({}, document.title, location.pathname), 100);
|
|
460
460
|
};
|
|
461
|
-
const AnchorElement = as ||
|
|
462
|
-
return (jsx(AnchorElement, { ...props, "aria-disabled": disabled, className: twMerge(className, disabled &&
|
|
463
|
-
? rel ===
|
|
464
|
-
? `${rel} noreferrer noopener`
|
|
465
|
-
: `${rel} prefetch`
|
|
461
|
+
const AnchorElement = as || "a";
|
|
462
|
+
return (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
|
|
463
|
+
? rel === "nofollow" ? `${rel} noreferrer noopener` : `${rel} prefetch`
|
|
466
464
|
: isExternal
|
|
467
|
-
?
|
|
468
|
-
:
|
|
465
|
+
? "nofollow noreferrer noopener"
|
|
466
|
+
: "prefetch" }));
|
|
469
467
|
}
|
|
470
468
|
// * Styles
|
|
471
|
-
const baseClasses = twSort(
|
|
472
|
-
const lineStaticClasses = twJoin(baseClasses,
|
|
473
|
-
const lineClasses = twJoin(lineStaticClasses,
|
|
474
|
-
const scaleXClasses =
|
|
475
|
-
const scaleYClasses =
|
|
469
|
+
const baseClasses = twSort("isolate inline-block cursor-pointer duration-300 ease-exponential after:absolute after:left-1/2 after:-z-10 after:-translate-x-1/2 after:duration-500 active:scale-95 active:after:opacity-100");
|
|
470
|
+
const lineStaticClasses = twJoin(baseClasses, "whitespace-nowrap after:-bottom-0.5 after:w-[calc(100%+0.15rem)] after:rounded-full after:border-1 after:border-current");
|
|
471
|
+
const lineClasses = twJoin(lineStaticClasses, "whitespace-nowrap transition-transform after:transition-transform after:ease-exponential");
|
|
472
|
+
const scaleXClasses = "after:scale-x-0 pointer-fine:hover:after:scale-x-100 active:after:scale-x-100";
|
|
473
|
+
const scaleYClasses = "after:scale-y-0 pointer-fine:hover:after:scale-y-100 active:after:scale-y-100";
|
|
476
474
|
const lineNormalClasses = twJoin([
|
|
477
475
|
lineClasses,
|
|
478
476
|
scaleYClasses,
|
|
479
|
-
|
|
477
|
+
"after:origin-bottom after:translate-y-0.5 active:after:translate-y-0 pointer-fine:hover:after:translate-y-0",
|
|
478
|
+
]);
|
|
479
|
+
const lineLtrClasses = twJoin([
|
|
480
|
+
lineClasses,
|
|
481
|
+
scaleXClasses,
|
|
482
|
+
"after:origin-left",
|
|
483
|
+
]);
|
|
484
|
+
const lineRtlClasses = twJoin([
|
|
485
|
+
lineClasses,
|
|
486
|
+
scaleXClasses,
|
|
487
|
+
"after:origin-right",
|
|
480
488
|
]);
|
|
481
|
-
const lineLtrClasses = twJoin([lineClasses, scaleXClasses, 'after:origin-left']);
|
|
482
|
-
const lineRtlClasses = twJoin([lineClasses, scaleXClasses, 'after:origin-right']);
|
|
483
489
|
const lineCenterClasses = twJoin([lineClasses, scaleXClasses]);
|
|
484
490
|
const lineLiftClasses = twJoin([
|
|
485
491
|
lineClasses,
|
|
486
492
|
scaleYClasses,
|
|
487
|
-
|
|
493
|
+
"after:origin-bottom after:translate-y-1 after:scale-x-75 active:after:translate-y-0 active:after:scale-x-100 pointer-fine:hover:after:translate-y-0 pointer-fine:hover:after:scale-x-100",
|
|
488
494
|
]);
|
|
489
|
-
const fillClasses = twJoin(baseClasses,
|
|
495
|
+
const fillClasses = 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");
|
|
490
496
|
// Define theme-specific fill color transition classes
|
|
491
|
-
const getFillColorTransitionClasses = (theme =
|
|
492
|
-
let fillColorTransitionClasses = twJoin(fillClasses,
|
|
497
|
+
const getFillColorTransitionClasses = (theme = "blue", customTheme) => {
|
|
498
|
+
let fillColorTransitionClasses = twJoin(fillClasses, "transition-transform after:bg-(--theme-color)");
|
|
493
499
|
switch (theme) {
|
|
494
|
-
case
|
|
495
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
500
|
+
case "blue":
|
|
501
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-blue)]");
|
|
496
502
|
break;
|
|
497
|
-
case
|
|
498
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
503
|
+
case "brown":
|
|
504
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-brow)]");
|
|
499
505
|
break;
|
|
500
|
-
case
|
|
501
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
506
|
+
case "green":
|
|
507
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-green)]");
|
|
502
508
|
break;
|
|
503
|
-
case
|
|
504
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
509
|
+
case "grey":
|
|
510
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-grey)]");
|
|
505
511
|
break;
|
|
506
|
-
case
|
|
507
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
512
|
+
case "sky-blue":
|
|
513
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-sky-blue)]");
|
|
508
514
|
break;
|
|
509
|
-
case
|
|
510
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
515
|
+
case "magenta":
|
|
516
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-magenta)]");
|
|
511
517
|
break;
|
|
512
|
-
case
|
|
513
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
518
|
+
case "orange":
|
|
519
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-orange)]");
|
|
514
520
|
break;
|
|
515
|
-
case
|
|
516
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
521
|
+
case "pink":
|
|
522
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-pink)]");
|
|
517
523
|
break;
|
|
518
|
-
case
|
|
519
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
524
|
+
case "purple":
|
|
525
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-purple)]");
|
|
520
526
|
break;
|
|
521
|
-
case
|
|
522
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
527
|
+
case "red":
|
|
528
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-red)]");
|
|
523
529
|
break;
|
|
524
|
-
case
|
|
525
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
530
|
+
case "violet":
|
|
531
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-violet)]");
|
|
526
532
|
break;
|
|
527
|
-
case
|
|
528
|
-
fillColorTransitionClasses = twJoin(fillColorTransitionClasses,
|
|
533
|
+
case "yellow":
|
|
534
|
+
fillColorTransitionClasses = twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-yellow)]");
|
|
529
535
|
break;
|
|
530
|
-
case
|
|
531
|
-
if (customTheme && customTheme.themeColor &&
|
|
532
|
-
|
|
536
|
+
case "custom":
|
|
537
|
+
if (customTheme && customTheme.themeColor &&
|
|
538
|
+
!customTheme.themeColor.includes("after:[--theme-color:")) {
|
|
539
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable on the ::after pseudo element. Otherwise, please use `customTheme.classes`.");
|
|
540
|
+
}
|
|
533
541
|
fillColorTransitionClasses = customTheme.themeColor
|
|
534
542
|
? twMerge(fillColorTransitionClasses, customTheme.themeColor)
|
|
535
543
|
: twMerge(fillClasses, customTheme.classes);
|
|
@@ -538,48 +546,50 @@ const getFillColorTransitionClasses = (theme = 'blue', customTheme) => {
|
|
|
538
546
|
return fillColorTransitionClasses;
|
|
539
547
|
};
|
|
540
548
|
// Define theme-specific fill center classes
|
|
541
|
-
const getFillCenterClasses = (theme =
|
|
542
|
-
let fillCenterColorClasses = twJoin(fillClasses,
|
|
549
|
+
const getFillCenterClasses = (theme = "blue", customTheme) => {
|
|
550
|
+
let fillCenterColorClasses = 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)");
|
|
543
551
|
switch (theme) {
|
|
544
|
-
case
|
|
545
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
552
|
+
case "blue":
|
|
553
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-blue)]");
|
|
546
554
|
break;
|
|
547
|
-
case
|
|
548
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
555
|
+
case "brown":
|
|
556
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-brown)]");
|
|
549
557
|
break;
|
|
550
|
-
case
|
|
551
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
558
|
+
case "green":
|
|
559
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-green)]");
|
|
552
560
|
break;
|
|
553
|
-
case
|
|
554
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
561
|
+
case "grey":
|
|
562
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-grey)]");
|
|
555
563
|
break;
|
|
556
|
-
case
|
|
557
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
564
|
+
case "sky-blue":
|
|
565
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-sky-blue)]");
|
|
558
566
|
break;
|
|
559
|
-
case
|
|
560
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
567
|
+
case "magenta":
|
|
568
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-magenta)]");
|
|
561
569
|
break;
|
|
562
|
-
case
|
|
563
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
570
|
+
case "orange":
|
|
571
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-orange)]");
|
|
564
572
|
break;
|
|
565
|
-
case
|
|
566
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
573
|
+
case "pink":
|
|
574
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-pink)]");
|
|
567
575
|
break;
|
|
568
|
-
case
|
|
569
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
576
|
+
case "purple":
|
|
577
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-purple)]");
|
|
570
578
|
break;
|
|
571
|
-
case
|
|
572
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
579
|
+
case "red":
|
|
580
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-red)]");
|
|
573
581
|
break;
|
|
574
|
-
case
|
|
575
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
582
|
+
case "violet":
|
|
583
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-violet)]");
|
|
576
584
|
break;
|
|
577
|
-
case
|
|
578
|
-
fillCenterColorClasses = twJoin(fillCenterColorClasses,
|
|
585
|
+
case "yellow":
|
|
586
|
+
fillCenterColorClasses = twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-yellow)]");
|
|
579
587
|
break;
|
|
580
|
-
case
|
|
581
|
-
if (customTheme && customTheme.themeColor &&
|
|
582
|
-
|
|
588
|
+
case "custom":
|
|
589
|
+
if (customTheme && customTheme.themeColor &&
|
|
590
|
+
!customTheme.themeColor.includes("after:[--theme-color:")) {
|
|
591
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable on the ::after pseudo element. Otherwise, please use `customTheme.classes`.");
|
|
592
|
+
}
|
|
583
593
|
fillCenterColorClasses = customTheme.themeColor
|
|
584
594
|
? twMerge(fillCenterColorClasses, customTheme.themeColor)
|
|
585
595
|
: twMerge(fillClasses, customTheme.classes);
|
|
@@ -587,58 +597,66 @@ const getFillCenterClasses = (theme = 'blue', customTheme) => {
|
|
|
587
597
|
}
|
|
588
598
|
return fillCenterColorClasses;
|
|
589
599
|
};
|
|
590
|
-
const multilineBaseClasses = twSort(
|
|
591
|
-
const multilineLineStaticClasses =
|
|
592
|
-
const multilineNormalClasses = twSort(
|
|
593
|
-
const multilineClasses = twJoin(multilineBaseClasses,
|
|
594
|
-
const multilineLineClasses = twJoin(multilineClasses,
|
|
595
|
-
const multilineXClasses = twJoin(multilineLineClasses,
|
|
596
|
-
const multilineLineRtlClasses = twJoin([
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
const
|
|
601
|
-
|
|
600
|
+
const multilineBaseClasses = twSort("bg-linear-to-r from-current to-current bg-no-repeat active:scale-95");
|
|
601
|
+
const multilineLineStaticClasses = "underline";
|
|
602
|
+
const multilineNormalClasses = twSort("underline-offset-1 active:underline pointer-fine:hover:underline");
|
|
603
|
+
const multilineClasses = twJoin(multilineBaseClasses, "duration-500 ease-exponential");
|
|
604
|
+
const multilineLineClasses = twJoin(multilineClasses, "bg-[position:0%_100%] px-px pb-px transition-[background-size]");
|
|
605
|
+
const multilineXClasses = twJoin(multilineLineClasses, "bg-[size:0%_2px] focus-visible:bg-[size:100%_2px] active:bg-[size:100%_2px] pointer-fine:hover:bg-[size:100%_2px]");
|
|
606
|
+
const multilineLineRtlClasses = twJoin([
|
|
607
|
+
multilineXClasses,
|
|
608
|
+
"bg-[position:100%_100%]",
|
|
609
|
+
]);
|
|
610
|
+
const multilineLineCenterClasses = twJoin([
|
|
611
|
+
multilineXClasses,
|
|
612
|
+
"bg-[position:50%_100%]",
|
|
613
|
+
]);
|
|
614
|
+
const multilineLineLiftClasses = twJoin(multilineLineClasses, "bg-[size:auto_0px] focus-visible:bg-[size:auto_2px] active:bg-[size:auto_2px] pointer-fine:hover:bg-[size:auto_2px]");
|
|
615
|
+
const multilineFillBaseClasses = twJoin(multilineBaseClasses, "rounded px-0.5 py-0.75 focus-visible:text-zinc-50 active:text-zinc-50 pointer-fine:hover:text-zinc-50");
|
|
616
|
+
const getMultilineFillColorClasses = (theme = "blue", customTheme) => {
|
|
617
|
+
let multilineFillColorClasses = twJoin(multilineFillBaseClasses, "from-(--theme-color) to-(--theme-color) transition-[background-size,color]");
|
|
602
618
|
switch (theme) {
|
|
603
|
-
case
|
|
604
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
619
|
+
case "blue":
|
|
620
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-blue)]");
|
|
605
621
|
break;
|
|
606
|
-
case
|
|
607
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
622
|
+
case "brown":
|
|
623
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-brown)]");
|
|
608
624
|
break;
|
|
609
|
-
case
|
|
610
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
625
|
+
case "green":
|
|
626
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-green)]");
|
|
611
627
|
break;
|
|
612
|
-
case
|
|
613
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
628
|
+
case "grey":
|
|
629
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-grey)]");
|
|
614
630
|
break;
|
|
615
|
-
case
|
|
616
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
631
|
+
case "sky-blue":
|
|
632
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-sky-blue)]");
|
|
617
633
|
break;
|
|
618
|
-
case
|
|
619
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
634
|
+
case "magenta":
|
|
635
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-magenta)]");
|
|
620
636
|
break;
|
|
621
|
-
case
|
|
622
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
637
|
+
case "orange":
|
|
638
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-orange)]");
|
|
623
639
|
break;
|
|
624
|
-
case
|
|
625
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
640
|
+
case "pink":
|
|
641
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-pink)]");
|
|
626
642
|
break;
|
|
627
|
-
case
|
|
628
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
643
|
+
case "purple":
|
|
644
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-purple)]");
|
|
629
645
|
break;
|
|
630
|
-
case
|
|
631
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
646
|
+
case "red":
|
|
647
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-red)]");
|
|
632
648
|
break;
|
|
633
|
-
case
|
|
634
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
649
|
+
case "violet":
|
|
650
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-violet)]");
|
|
635
651
|
break;
|
|
636
|
-
case
|
|
637
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
652
|
+
case "yellow":
|
|
653
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-yellow)]");
|
|
638
654
|
break;
|
|
639
|
-
case
|
|
640
|
-
if (customTheme && customTheme.themeColor &&
|
|
641
|
-
|
|
655
|
+
case "custom":
|
|
656
|
+
if (customTheme && customTheme.themeColor &&
|
|
657
|
+
!customTheme.themeColor.includes("[--theme-color:")) {
|
|
658
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable. Otherwise, please use `customTheme.classes`.");
|
|
659
|
+
}
|
|
642
660
|
multilineFillColorClasses = customTheme.themeColor
|
|
643
661
|
? twMerge(multilineFillColorClasses, customTheme.themeColor)
|
|
644
662
|
: twMerge(multilineFillBaseClasses, customTheme.classes);
|
|
@@ -646,48 +664,50 @@ const getMultilineFillColorClasses = (theme = 'blue', customTheme) => {
|
|
|
646
664
|
}
|
|
647
665
|
return multilineFillColorClasses;
|
|
648
666
|
};
|
|
649
|
-
const getMultilineFillClasses = (theme =
|
|
650
|
-
let multilineFillColorClasses = twJoin(multilineFillBaseClasses,
|
|
667
|
+
const getMultilineFillClasses = (theme = "blue", customTheme) => {
|
|
668
|
+
let multilineFillColorClasses = 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%]");
|
|
651
669
|
switch (theme) {
|
|
652
|
-
case
|
|
653
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
670
|
+
case "blue":
|
|
671
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-blue)]");
|
|
654
672
|
break;
|
|
655
|
-
case
|
|
656
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
673
|
+
case "brown":
|
|
674
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-brown)]");
|
|
657
675
|
break;
|
|
658
|
-
case
|
|
659
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
676
|
+
case "green":
|
|
677
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-green)]");
|
|
660
678
|
break;
|
|
661
|
-
case
|
|
662
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
679
|
+
case "grey":
|
|
680
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-grey)]");
|
|
663
681
|
break;
|
|
664
|
-
case
|
|
665
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
682
|
+
case "sky-blue":
|
|
683
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-sky-blue)]");
|
|
666
684
|
break;
|
|
667
|
-
case
|
|
668
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
685
|
+
case "magenta":
|
|
686
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-magenta)]");
|
|
669
687
|
break;
|
|
670
|
-
case
|
|
671
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
688
|
+
case "orange":
|
|
689
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-orange)]");
|
|
672
690
|
break;
|
|
673
|
-
case
|
|
674
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
691
|
+
case "pink":
|
|
692
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-pink)]");
|
|
675
693
|
break;
|
|
676
|
-
case
|
|
677
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
694
|
+
case "purple":
|
|
695
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-purple)]");
|
|
678
696
|
break;
|
|
679
|
-
case
|
|
680
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
697
|
+
case "red":
|
|
698
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-red)]");
|
|
681
699
|
break;
|
|
682
|
-
case
|
|
683
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
700
|
+
case "violet":
|
|
701
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-violet)]");
|
|
684
702
|
break;
|
|
685
|
-
case
|
|
686
|
-
multilineFillColorClasses = twJoin(multilineFillColorClasses,
|
|
703
|
+
case "yellow":
|
|
704
|
+
multilineFillColorClasses = twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-yellow)]");
|
|
687
705
|
break;
|
|
688
|
-
case
|
|
689
|
-
if (customTheme && customTheme.themeColor &&
|
|
690
|
-
|
|
706
|
+
case "custom":
|
|
707
|
+
if (customTheme && customTheme.themeColor &&
|
|
708
|
+
!customTheme.themeColor.includes("[--theme-color:")) {
|
|
709
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable. Otherwise, please use `customTheme.classes`.");
|
|
710
|
+
}
|
|
691
711
|
multilineFillColorClasses = customTheme.themeColor
|
|
692
712
|
? twMerge(multilineFillColorClasses, customTheme.themeColor)
|
|
693
713
|
: twMerge(multilineFillBaseClasses, customTheme.classes);
|
|
@@ -695,18 +715,76 @@ const getMultilineFillClasses = (theme = 'blue', customTheme) => {
|
|
|
695
715
|
}
|
|
696
716
|
return multilineFillColorClasses;
|
|
697
717
|
};
|
|
698
|
-
const getMultilineFillLiftClasses = (theme =
|
|
699
|
-
return twJoin(getMultilineFillColorClasses(theme, customTheme),
|
|
718
|
+
const getMultilineFillLiftClasses = (theme = "blue", customTheme) => {
|
|
719
|
+
return 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%]");
|
|
700
720
|
};
|
|
701
|
-
const getMultilineFillXClasses = (theme =
|
|
702
|
-
return twJoin(getMultilineFillColorClasses(theme, customTheme),
|
|
721
|
+
const getMultilineFillXClasses = (theme = "blue", customTheme) => {
|
|
722
|
+
return 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%]");
|
|
703
723
|
};
|
|
704
|
-
const getMultilineFillRtlClasses = (theme =
|
|
705
|
-
return twJoin(getMultilineFillXClasses(theme, customTheme),
|
|
724
|
+
const getMultilineFillRtlClasses = (theme = "blue", customTheme) => {
|
|
725
|
+
return twJoin(getMultilineFillXClasses(theme, customTheme), "bg-[position:100%_auto]");
|
|
706
726
|
};
|
|
707
|
-
const getMultilineFillCenterClasses = (theme =
|
|
708
|
-
return twJoin(getMultilineFillXClasses(theme, customTheme),
|
|
727
|
+
const getMultilineFillCenterClasses = (theme = "blue", customTheme) => {
|
|
728
|
+
return twJoin(getMultilineFillXClasses(theme, customTheme), "bg-[position:50%_auto]");
|
|
709
729
|
};
|
|
730
|
+
function getLinkClasses({ customTheme, theme, type }) {
|
|
731
|
+
switch (type) {
|
|
732
|
+
case "static":
|
|
733
|
+
return lineStaticClasses;
|
|
734
|
+
case "ltr":
|
|
735
|
+
return lineLtrClasses;
|
|
736
|
+
case "rtl":
|
|
737
|
+
return lineRtlClasses;
|
|
738
|
+
case "center":
|
|
739
|
+
return lineCenterClasses;
|
|
740
|
+
case "lift":
|
|
741
|
+
return lineLiftClasses;
|
|
742
|
+
case "fill":
|
|
743
|
+
return getFillCenterClasses(theme, customTheme);
|
|
744
|
+
case "fill-ltr":
|
|
745
|
+
return twJoin([
|
|
746
|
+
getFillColorTransitionClasses(theme, customTheme),
|
|
747
|
+
scaleXClasses,
|
|
748
|
+
"after:origin-left",
|
|
749
|
+
]);
|
|
750
|
+
case "fill-rtl":
|
|
751
|
+
return twJoin([
|
|
752
|
+
getFillColorTransitionClasses(theme, customTheme),
|
|
753
|
+
scaleXClasses,
|
|
754
|
+
"after:origin-right",
|
|
755
|
+
]);
|
|
756
|
+
case "fill-lift":
|
|
757
|
+
return twJoin([
|
|
758
|
+
getFillColorTransitionClasses(theme, customTheme),
|
|
759
|
+
scaleYClasses,
|
|
760
|
+
"after:origin-bottom",
|
|
761
|
+
]);
|
|
762
|
+
case "multiline":
|
|
763
|
+
return multilineNormalClasses;
|
|
764
|
+
case "multiline-static":
|
|
765
|
+
return multilineLineStaticClasses;
|
|
766
|
+
case "multiline-ltr":
|
|
767
|
+
return multilineXClasses;
|
|
768
|
+
case "multiline-rtl":
|
|
769
|
+
return multilineLineRtlClasses;
|
|
770
|
+
case "multiline-center":
|
|
771
|
+
return multilineLineCenterClasses;
|
|
772
|
+
case "multiline-lift":
|
|
773
|
+
return multilineLineLiftClasses;
|
|
774
|
+
case "multiline-fill":
|
|
775
|
+
return getMultilineFillClasses(theme, customTheme);
|
|
776
|
+
case "multiline-fill-ltr":
|
|
777
|
+
return getMultilineFillXClasses(theme, customTheme);
|
|
778
|
+
case "multiline-fill-rtl":
|
|
779
|
+
return getMultilineFillRtlClasses(theme, customTheme);
|
|
780
|
+
case "multiline-fill-center":
|
|
781
|
+
return getMultilineFillCenterClasses(theme, customTheme);
|
|
782
|
+
case "multiline-fill-lift":
|
|
783
|
+
return getMultilineFillLiftClasses(theme, customTheme);
|
|
784
|
+
default:
|
|
785
|
+
return lineNormalClasses;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
710
788
|
/**
|
|
711
789
|
* # Link
|
|
712
790
|
*
|
|
@@ -736,54 +814,8 @@ const getMultilineFillCenterClasses = (theme = 'blue', customTheme) => {
|
|
|
736
814
|
* @example
|
|
737
815
|
* <Link href='/about' type='fill-ltr' theme='red' title='About Us'>Learn more about our company</Link>
|
|
738
816
|
*/
|
|
739
|
-
function Link({ as, className, customTheme, theme =
|
|
740
|
-
const
|
|
741
|
-
switch (type) {
|
|
742
|
-
case 'static':
|
|
743
|
-
return lineStaticClasses;
|
|
744
|
-
case 'ltr':
|
|
745
|
-
return lineLtrClasses;
|
|
746
|
-
case 'rtl':
|
|
747
|
-
return lineRtlClasses;
|
|
748
|
-
case 'center':
|
|
749
|
-
return lineCenterClasses;
|
|
750
|
-
case 'lift':
|
|
751
|
-
return lineLiftClasses;
|
|
752
|
-
case 'fill':
|
|
753
|
-
return getFillCenterClasses(theme, customTheme);
|
|
754
|
-
case 'fill-ltr':
|
|
755
|
-
return twJoin([getFillColorTransitionClasses(theme, customTheme), scaleXClasses, 'after:origin-left']);
|
|
756
|
-
case 'fill-rtl':
|
|
757
|
-
return twJoin([getFillColorTransitionClasses(theme, customTheme), scaleXClasses, 'after:origin-right']);
|
|
758
|
-
case 'fill-lift':
|
|
759
|
-
return twJoin([getFillColorTransitionClasses(theme, customTheme), scaleYClasses, 'after:origin-bottom']);
|
|
760
|
-
case 'multiline':
|
|
761
|
-
return multilineNormalClasses;
|
|
762
|
-
case 'multiline-static':
|
|
763
|
-
return multilineLineStaticClasses;
|
|
764
|
-
case 'multiline-ltr':
|
|
765
|
-
return multilineXClasses;
|
|
766
|
-
case 'multiline-rtl':
|
|
767
|
-
return multilineLineRtlClasses;
|
|
768
|
-
case 'multiline-center':
|
|
769
|
-
return multilineLineCenterClasses;
|
|
770
|
-
case 'multiline-lift':
|
|
771
|
-
return multilineLineLiftClasses;
|
|
772
|
-
case 'multiline-fill':
|
|
773
|
-
return getMultilineFillClasses(theme, customTheme);
|
|
774
|
-
case 'multiline-fill-ltr':
|
|
775
|
-
return getMultilineFillXClasses(theme, customTheme);
|
|
776
|
-
case 'multiline-fill-rtl':
|
|
777
|
-
return getMultilineFillRtlClasses(theme, customTheme);
|
|
778
|
-
case 'multiline-fill-center':
|
|
779
|
-
return getMultilineFillCenterClasses(theme, customTheme);
|
|
780
|
-
case 'multiline-fill-lift':
|
|
781
|
-
return getMultilineFillLiftClasses(theme, customTheme);
|
|
782
|
-
default:
|
|
783
|
-
return lineNormalClasses;
|
|
784
|
-
}
|
|
785
|
-
};
|
|
786
|
-
const linkClasses = getLinkClasses();
|
|
817
|
+
function Link({ as, className, customTheme, theme = "blue", type, ...props }) {
|
|
818
|
+
const linkClasses = getLinkClasses({ customTheme, theme, type });
|
|
787
819
|
const LinkElement = as || Anchor;
|
|
788
820
|
return jsx(LinkElement, { ...props, className: twMerge(linkClasses, className) });
|
|
789
821
|
}
|
|
@@ -814,7 +846,9 @@ function Link({ as, className, customTheme, theme = 'blue', type, ...props }) {
|
|
|
814
846
|
*/
|
|
815
847
|
function createLink(config) {
|
|
816
848
|
return function ExtendedLink({ theme, className, customTheme, type, as, ...props }) {
|
|
817
|
-
const finalType = type !== undefined
|
|
849
|
+
const finalType = type !== undefined
|
|
850
|
+
? type
|
|
851
|
+
: config.type, finalTheme = theme !== undefined ? theme : config.defaultTheme;
|
|
818
852
|
const configClassName = config.className;
|
|
819
853
|
const shouldOverrideElement = !Boolean(as) && Boolean(config.as);
|
|
820
854
|
const linkProps = {
|
|
@@ -829,13 +863,17 @@ function createLink(config) {
|
|
|
829
863
|
else if (as) {
|
|
830
864
|
linkProps.as = as;
|
|
831
865
|
}
|
|
832
|
-
if (finalTheme && typeof finalTheme ===
|
|
866
|
+
if (finalTheme && typeof finalTheme === "string" && config.theme &&
|
|
867
|
+
finalTheme in config.theme) {
|
|
833
868
|
const extendedTheme = config.theme[finalTheme];
|
|
834
|
-
if (customTheme)
|
|
835
|
-
return (jsx(Link, { ...linkProps, theme:
|
|
869
|
+
if (customTheme) {
|
|
870
|
+
return (jsx(Link, { ...linkProps, theme: "custom", customTheme: customTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
|
|
871
|
+
}
|
|
836
872
|
let resolvedCustomTheme;
|
|
837
873
|
if (extendedTheme.customTheme.themeColor) {
|
|
838
|
-
const isMultilineType = finalType
|
|
874
|
+
const isMultilineType = finalType
|
|
875
|
+
? finalType.includes("multiline")
|
|
876
|
+
: false;
|
|
839
877
|
resolvedCustomTheme = {
|
|
840
878
|
themeColor: isMultilineType
|
|
841
879
|
? extendedTheme.customTheme.themeColor.multilineFill
|
|
@@ -847,7 +885,7 @@ function createLink(config) {
|
|
|
847
885
|
classes: extendedTheme.customTheme.classes,
|
|
848
886
|
};
|
|
849
887
|
}
|
|
850
|
-
return (jsx(Link, { ...linkProps, theme:
|
|
888
|
+
return (jsx(Link, { ...linkProps, theme: "custom", customTheme: resolvedCustomTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
|
|
851
889
|
}
|
|
852
890
|
return (jsx(Link, { ...linkProps, theme: finalTheme, className: twMerge(configClassName, className), customTheme: customTheme }));
|
|
853
891
|
};
|
|
@@ -1121,32 +1159,44 @@ function Details({ as = 'div', className, ...props }) {
|
|
|
1121
1159
|
}
|
|
1122
1160
|
|
|
1123
1161
|
function DropDownButton({ arrow = true, as, children, className, ...props }) {
|
|
1124
|
-
return (jsxs(MenuButton, { ...props, as: as ||
|
|
1125
|
-
(typeof arrow ===
|
|
1162
|
+
return (jsxs(MenuButton, { ...props, as: as || "button", className: twJoin("group/button", className), children: [children, arrow &&
|
|
1163
|
+
(typeof arrow === "boolean"
|
|
1164
|
+
? (jsx(ChevronDown, { className: "-top-px -mr-1 ml-2 w-4 animate-flip-again group-data-open/button:animate-flip" }))
|
|
1165
|
+
: arrow)] }));
|
|
1126
1166
|
}
|
|
1127
1167
|
function DropDownItem({ as, ...props }) {
|
|
1128
|
-
return jsx(MenuItem, { ...props, as: as ||
|
|
1168
|
+
return jsx(MenuItem, { ...props, as: as || "div" });
|
|
1129
1169
|
}
|
|
1130
1170
|
function DropDownItems({ anchor, children, className, containerClassName, style, ...props }) {
|
|
1131
1171
|
const getAnchorProps = () => {
|
|
1132
|
-
let initialAnchor = {
|
|
1172
|
+
let initialAnchor = {
|
|
1173
|
+
gap: "1rem",
|
|
1174
|
+
padding: "1rem",
|
|
1175
|
+
to: "bottom start",
|
|
1176
|
+
};
|
|
1133
1177
|
if (anchor) {
|
|
1134
|
-
if (typeof anchor ===
|
|
1178
|
+
if (typeof anchor === "string")
|
|
1135
1179
|
initialAnchor.to = anchor;
|
|
1136
|
-
if (typeof anchor ===
|
|
1180
|
+
if (typeof anchor === "object") {
|
|
1137
1181
|
initialAnchor = { ...initialAnchor, ...anchor };
|
|
1182
|
+
}
|
|
1138
1183
|
}
|
|
1139
1184
|
return initialAnchor;
|
|
1140
1185
|
};
|
|
1141
1186
|
const anchorProps = getAnchorProps();
|
|
1142
|
-
return (jsx(MenuItems, { ...props, anchor: anchorProps, className: twMerge(
|
|
1187
|
+
return (jsx(MenuItems, { ...props, anchor: anchorProps, className: twMerge("grid grid-rows-1fr rounded-xl shadow-xl transition-rows duration-500 ease-exponential not-data-open:not-data-enter:not-data-leave:grid-rows-0fr data-closed:grid-rows-0fr", containerClassName), static: props.static, style: { ...style, minWidth: "var(--button-width)" }, transition: true, children: (bag) => (jsx("div", { className: "overflow-y-scroll", children: jsx("div", { className: twMerge("rounded-xl bg-neutral-50/20 px-6 py-5 backdrop-blur-md backdrop-brightness-150", className), children: typeof children === "function" ? children(bag) : children }) })) }));
|
|
1143
1188
|
}
|
|
1144
1189
|
function DropDownSection({ children, label, labelProps, separatorAbove, separatorBelow, ...props }) {
|
|
1145
|
-
const { labelClassName, ...restLabelProps } = {
|
|
1146
|
-
|
|
1190
|
+
const { labelClassName, ...restLabelProps } = {
|
|
1191
|
+
labelClassName: labelProps?.className || "",
|
|
1192
|
+
...labelProps,
|
|
1193
|
+
};
|
|
1194
|
+
return (jsx(MenuSection, { ...props, children: (sectionBag) => (jsxs(Fragment$1, { children: [separatorAbove && jsx(DropDownSeparator, {}), label && (jsx(MenuHeading, { ...restLabelProps, className: (headingBag) => twMerge("text-[larger] font-bold text-current/80", typeof labelClassName === "function"
|
|
1195
|
+
? labelClassName(headingBag)
|
|
1196
|
+
: labelClassName), children: label })), typeof children === "function" ? children(sectionBag) : children, separatorBelow && jsx(DropDownSeparator, {})] })) }));
|
|
1147
1197
|
}
|
|
1148
1198
|
function DropDownSeparator({ as, className, ...props }) {
|
|
1149
|
-
return (jsx(MenuSeparator, { ...props, as: as ||
|
|
1199
|
+
return (jsx(MenuSeparator, { ...props, as: as || "div", className: (bag) => twMerge("my-4 block h-px rounded-full bg-neutral-950/20", typeof className === "function" ? className(bag) : className) }));
|
|
1150
1200
|
}
|
|
1151
1201
|
function DropDown(props) {
|
|
1152
1202
|
return jsx(Menu, { ...props });
|
|
@@ -3460,19 +3510,20 @@ const arrow = (options, deps) => ({
|
|
|
3460
3510
|
|
|
3461
3511
|
function TooltipTrigger({ as, asChild = false, children, ...props }) {
|
|
3462
3512
|
const TooltipTriggerElement = as || Button$1;
|
|
3463
|
-
if (asChild && isValidElement(children))
|
|
3513
|
+
if (asChild && isValidElement(children)) {
|
|
3464
3514
|
return cloneElement(children, props);
|
|
3515
|
+
}
|
|
3465
3516
|
return jsx(TooltipTriggerElement, { ...props, children: children });
|
|
3466
3517
|
}
|
|
3467
3518
|
function TooltipPanel({ as, children, className, style, ...props }) {
|
|
3468
|
-
const TooltipPanelElement = as ||
|
|
3469
|
-
return (jsx(TooltipPanelElement, { ...props, className: twMerge(
|
|
3519
|
+
const TooltipPanelElement = as || "div";
|
|
3520
|
+
return (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 }));
|
|
3470
3521
|
}
|
|
3471
|
-
function Tooltip({ anchor =
|
|
3522
|
+
function Tooltip({ anchor = "top", arrow: arrow$1, arrowClassName, children, delay = 500, offset: offset$1 = 8, onClose, onOpen, portal, }) {
|
|
3472
3523
|
const [isOpen, setIsOpen] = useState(false), timeoutRef = useRef(undefined), arrowRef = useRef(null);
|
|
3473
|
-
const [bodyElement, setBodyElement] = useState(() => typeof window !==
|
|
3524
|
+
const [bodyElement, setBodyElement] = useState(() => typeof window !== "undefined" ? document.body : null);
|
|
3474
3525
|
useEffect(() => {
|
|
3475
|
-
if (typeof window !==
|
|
3526
|
+
if (typeof window !== "undefined" && !bodyElement) {
|
|
3476
3527
|
const documentBody = document.body;
|
|
3477
3528
|
setBodyElement(documentBody);
|
|
3478
3529
|
}
|
|
@@ -3489,10 +3540,12 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3489
3540
|
elements.floating.style.maxWidth = width;
|
|
3490
3541
|
},
|
|
3491
3542
|
}),
|
|
3492
|
-
...(arrowRef.current
|
|
3543
|
+
...(arrowRef.current
|
|
3544
|
+
? [arrow({ element: arrowRef.current })]
|
|
3545
|
+
: []),
|
|
3493
3546
|
],
|
|
3494
3547
|
placement: anchor,
|
|
3495
|
-
strategy: portal ?
|
|
3548
|
+
strategy: portal ? "fixed" : "absolute",
|
|
3496
3549
|
whileElementsMounted: autoUpdate,
|
|
3497
3550
|
open: isOpen,
|
|
3498
3551
|
});
|
|
@@ -3519,37 +3572,41 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3519
3572
|
clearTimeout(timeoutRef.current);
|
|
3520
3573
|
};
|
|
3521
3574
|
}, []);
|
|
3522
|
-
const content = typeof children ===
|
|
3575
|
+
const content = typeof children === "function"
|
|
3576
|
+
? children({ openTooltip, closeTooltip })
|
|
3577
|
+
: children;
|
|
3523
3578
|
const triggerElement = findComponentByType(content, TooltipTrigger), contentElement = findComponentByType(content, TooltipPanel);
|
|
3524
|
-
if (!contentElement)
|
|
3525
|
-
throw new Error(
|
|
3526
|
-
|
|
3527
|
-
|
|
3579
|
+
if (!contentElement) {
|
|
3580
|
+
throw new Error("TooltipPanel must be defined in Tooltip children");
|
|
3581
|
+
}
|
|
3582
|
+
if (!triggerElement && typeof children !== "function") {
|
|
3583
|
+
throw new Error("TooltipTrigger must be provided when not using render prop pattern");
|
|
3584
|
+
}
|
|
3528
3585
|
const arrowStyles = {};
|
|
3529
3586
|
const reversedAnchor = {
|
|
3530
|
-
top:
|
|
3531
|
-
right:
|
|
3532
|
-
bottom:
|
|
3533
|
-
left:
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3587
|
+
top: "bottom",
|
|
3588
|
+
right: "left",
|
|
3589
|
+
bottom: "top",
|
|
3590
|
+
left: "right",
|
|
3591
|
+
"top-start": "bottom left",
|
|
3592
|
+
"top-end": "bottom right",
|
|
3593
|
+
"right-start": "top left",
|
|
3594
|
+
"right-end": "bottom left",
|
|
3595
|
+
"bottom-start": "top left",
|
|
3596
|
+
"bottom-end": "top right",
|
|
3597
|
+
"left-start": "top right",
|
|
3598
|
+
"left-end": "bottom right",
|
|
3542
3599
|
}[placement];
|
|
3543
3600
|
if (middlewareData.arrow && arrow$1) {
|
|
3544
3601
|
const { x, y } = middlewareData.arrow;
|
|
3545
3602
|
const staticSide = {
|
|
3546
|
-
top:
|
|
3547
|
-
right:
|
|
3548
|
-
bottom:
|
|
3549
|
-
left:
|
|
3550
|
-
}[placement.split(
|
|
3603
|
+
top: "bottom",
|
|
3604
|
+
right: "left",
|
|
3605
|
+
bottom: "top",
|
|
3606
|
+
left: "right",
|
|
3607
|
+
}[placement.split("-")[0]];
|
|
3551
3608
|
if (staticSide) {
|
|
3552
|
-
arrowStyles[staticSide] =
|
|
3609
|
+
arrowStyles[staticSide] = "-4px";
|
|
3553
3610
|
if (x != null)
|
|
3554
3611
|
arrowStyles.left = `${x}px`;
|
|
3555
3612
|
if (y != null)
|
|
@@ -3558,68 +3615,68 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3558
3615
|
}
|
|
3559
3616
|
const getArrowLocationClasses = () => {
|
|
3560
3617
|
switch (placement) {
|
|
3561
|
-
case
|
|
3562
|
-
case
|
|
3563
|
-
case
|
|
3564
|
-
return
|
|
3565
|
-
case
|
|
3566
|
-
case
|
|
3567
|
-
case
|
|
3568
|
-
return
|
|
3569
|
-
case
|
|
3570
|
-
case
|
|
3571
|
-
case
|
|
3572
|
-
return
|
|
3573
|
-
case
|
|
3574
|
-
case
|
|
3575
|
-
case
|
|
3576
|
-
return
|
|
3618
|
+
case "bottom":
|
|
3619
|
+
case "bottom-end":
|
|
3620
|
+
case "bottom-start":
|
|
3621
|
+
return "-translate-y-1";
|
|
3622
|
+
case "top":
|
|
3623
|
+
case "top-end":
|
|
3624
|
+
case "top-start":
|
|
3625
|
+
return "rotate-180 translate-y-1";
|
|
3626
|
+
case "left":
|
|
3627
|
+
case "left-end":
|
|
3628
|
+
case "left-start":
|
|
3629
|
+
return "rotate-90 translate-x-2";
|
|
3630
|
+
case "right":
|
|
3631
|
+
case "right-end":
|
|
3632
|
+
case "right-start":
|
|
3633
|
+
return "-rotate-90 -translate-x-2";
|
|
3577
3634
|
}
|
|
3578
3635
|
};
|
|
3579
3636
|
const arrowLocationClasses = getArrowLocationClasses();
|
|
3580
|
-
const handleMouseEnter = e => {
|
|
3637
|
+
const handleMouseEnter = (e) => {
|
|
3581
3638
|
openTooltip();
|
|
3582
3639
|
triggerElement?.props.onMouseEnter?.(e);
|
|
3583
3640
|
};
|
|
3584
|
-
const handleMouseLeave = e => {
|
|
3641
|
+
const handleMouseLeave = (e) => {
|
|
3585
3642
|
triggerElement?.props.onMouseLeave?.(e);
|
|
3586
3643
|
closeTooltip();
|
|
3587
3644
|
};
|
|
3588
|
-
const handleTouchStart = e => {
|
|
3645
|
+
const handleTouchStart = (e) => {
|
|
3589
3646
|
openTooltip();
|
|
3590
3647
|
triggerElement?.props.onTouchStart?.(e);
|
|
3591
3648
|
};
|
|
3592
|
-
const handleFocus = e => {
|
|
3649
|
+
const handleFocus = (e) => {
|
|
3593
3650
|
triggerElement?.props.onFocus?.(e);
|
|
3594
3651
|
openTooltip();
|
|
3595
3652
|
};
|
|
3596
|
-
const handleBlur = e => {
|
|
3653
|
+
const handleBlur = (e) => {
|
|
3597
3654
|
triggerElement?.props.onBlur?.(e);
|
|
3598
3655
|
closeTooltip();
|
|
3599
3656
|
};
|
|
3600
3657
|
const tooltipContent = (jsx(Fragment$1, { children: isOpen &&
|
|
3601
3658
|
contentElement &&
|
|
3602
3659
|
cloneElement(contentElement, {
|
|
3603
|
-
children: (jsxs(Fragment$1, { children: [contentElement.props.children, arrow$1 && (jsx(ArrowSvg, { className: twMerge(
|
|
3604
|
-
...(portal ? {
|
|
3605
|
-
...(isPositioned ? {
|
|
3660
|
+
children: (jsxs(Fragment$1, { children: [contentElement.props.children, arrow$1 && (jsx(ArrowSvg, { className: twMerge("absolute", arrowLocationClasses, arrowClassName), style: arrowStyles, "data-tooltip-arrow": true }))] })),
|
|
3661
|
+
...(portal ? { "data-portal": true } : {}),
|
|
3662
|
+
...(isPositioned ? { "data-ready": true } : {}),
|
|
3606
3663
|
onMouseEnter: openTooltip,
|
|
3607
3664
|
onMouseLeave: closeTooltip,
|
|
3608
3665
|
onTouchStart: handleTouchStart,
|
|
3609
3666
|
ref: (node) => {
|
|
3610
3667
|
refs.setFloating(node);
|
|
3611
3668
|
if (node && arrow$1) {
|
|
3612
|
-
const arrowElement = node.querySelector(
|
|
3669
|
+
const arrowElement = node.querySelector("[data-tooltip-arrow]");
|
|
3613
3670
|
if (arrowElement)
|
|
3614
3671
|
arrowRef.current = arrowElement;
|
|
3615
3672
|
}
|
|
3616
3673
|
},
|
|
3617
|
-
role:
|
|
3674
|
+
role: "tooltip",
|
|
3618
3675
|
style: {
|
|
3619
3676
|
...contentElement.props.style,
|
|
3620
3677
|
...floatingStyles,
|
|
3621
3678
|
transformOrigin: reversedAnchor,
|
|
3622
|
-
pointerEvents:
|
|
3679
|
+
pointerEvents: "none",
|
|
3623
3680
|
},
|
|
3624
3681
|
}) }));
|
|
3625
3682
|
return (jsxs(Fragment$1, { children: [triggerElement &&
|
|
@@ -3629,310 +3686,55 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3629
3686
|
onMouseLeave: handleMouseLeave,
|
|
3630
3687
|
onFocus: handleFocus,
|
|
3631
3688
|
onBlur: handleBlur,
|
|
3632
|
-
|
|
3633
|
-
}), portal
|
|
3689
|
+
"aria-describedby": isOpen ? "tooltip" : undefined,
|
|
3690
|
+
}), portal
|
|
3691
|
+
? bodyElement && createPortal(tooltipContent, bodyElement)
|
|
3692
|
+
: tooltipContent] }));
|
|
3634
3693
|
}
|
|
3635
3694
|
function ArrowSvg({ className, ...props }) {
|
|
3636
|
-
return (jsxs("svg", { viewBox:
|
|
3695
|
+
return (jsxs("svg", { viewBox: "0 0 20 10", className: twMerge("h-2.5 w-5 fill-none", className), ...props, children: [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" }), 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" }), 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" })] }));
|
|
3637
3696
|
}
|
|
3638
3697
|
|
|
3639
3698
|
const specialCharacterRegex = new RegExp(/[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~€‚ƒ„…†‡‰‹‘’“”•–—™›¡¢£¥§©«¬®°±¶º»¿×÷]/);
|
|
3640
|
-
function
|
|
3641
|
-
const [formContext] = useFormContext(), [fieldsetContext] = useFieldsetContext();
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
const VALIDATION_HANDLERS = {
|
|
3651
|
-
email: ({ multiple, value }) => {
|
|
3652
|
-
if (multiple) {
|
|
3653
|
-
const emailList = value.split(',').map(item => item.trim()), notEmailList = [];
|
|
3654
|
-
emailList.forEach(item => {
|
|
3655
|
-
if (!isEmail(item))
|
|
3656
|
-
notEmailList.push(item);
|
|
3657
|
-
});
|
|
3658
|
-
if (notEmailList.length > 0) {
|
|
3659
|
-
const multipleInvalid = notEmailList.length > 1;
|
|
3660
|
-
return `${multipleInvalid ? 'These email addresses are' : 'This email address is'} invalid: ${notEmailList.join(', ')}`;
|
|
3661
|
-
}
|
|
3662
|
-
return;
|
|
3663
|
-
}
|
|
3664
|
-
if (!isEmail(value))
|
|
3665
|
-
return 'This is not a valid email address.';
|
|
3666
|
-
},
|
|
3667
|
-
password: ({ value }) => {
|
|
3668
|
-
const errorMessageList = [];
|
|
3669
|
-
if (options) {
|
|
3670
|
-
const { matchPreviousInput, requireLowercaseCharacter, requireNumber, requireSpecialCharacter, requireUppercaseCharacter, } = options;
|
|
3671
|
-
if (matchPreviousInput && formContext && formContext.length >= 2) {
|
|
3672
|
-
if (isInFieldset && fieldsetContext.fieldList.length > 1) {
|
|
3673
|
-
const currentInputIndex = fieldsetContext.fieldList.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3674
|
-
if (currentInputIndex > 0) {
|
|
3675
|
-
const previousInput = fieldsetContext.fieldList.find((_, index) => index === currentInputIndex - 1);
|
|
3676
|
-
if (previousInput &&
|
|
3677
|
-
isStringField(previousInput) &&
|
|
3678
|
-
previousInput.value !== value)
|
|
3679
|
-
errorMessageList.push('Passwords must match.');
|
|
3680
|
-
}
|
|
3681
|
-
}
|
|
3682
|
-
else {
|
|
3683
|
-
const currentInputIndex = formContext.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3684
|
-
if (currentInputIndex > 0) {
|
|
3685
|
-
const previousInput = formContext.find((_, index) => index === currentInputIndex - 1);
|
|
3686
|
-
if (previousInput &&
|
|
3687
|
-
isStringField(previousInput) &&
|
|
3688
|
-
previousInput.value !== value)
|
|
3689
|
-
errorMessageList.push('Passwords must match.');
|
|
3690
|
-
}
|
|
3691
|
-
}
|
|
3692
|
-
}
|
|
3693
|
-
if (requireLowercaseCharacter && !/[a-z]/g.test(value))
|
|
3694
|
-
errorMessageList.push('You must include a lowercase character.');
|
|
3695
|
-
if (requireNumber && !/[0-9]/g.test(value))
|
|
3696
|
-
errorMessageList.push('You must include a number.');
|
|
3697
|
-
if (requireSpecialCharacter && !specialCharacterRegex.test(value))
|
|
3698
|
-
errorMessageList.push('You must include a special character.');
|
|
3699
|
-
if (requireUppercaseCharacter && !/[A-Z]/g.test(value))
|
|
3700
|
-
errorMessageList.push('You must include an uppercase character.');
|
|
3701
|
-
}
|
|
3702
|
-
return errorMessageList.length > 0 ? errorMessageList.join(' ') : undefined;
|
|
3703
|
-
},
|
|
3704
|
-
tel: ({ value }) => {
|
|
3705
|
-
if (!isPhoneNumber(value))
|
|
3706
|
-
return 'This is not a valid phone number.';
|
|
3707
|
-
},
|
|
3708
|
-
};
|
|
3709
|
-
const onChange = e => {
|
|
3710
|
-
const validation = type ? VALIDATION_HANDLERS[type] : undefined;
|
|
3711
|
-
handleChange({ e, validation });
|
|
3712
|
-
};
|
|
3713
|
-
const onBlur = e => {
|
|
3714
|
-
const format = type ? FORMAT_FUNCTIONS[type] : undefined, validation = type ? VALIDATION_HANDLERS[type] : undefined;
|
|
3715
|
-
handleBlur({ e, format, validation });
|
|
3716
|
-
};
|
|
3717
|
-
return (jsx(Input$1, { ...props, className: bag => twMerge(
|
|
3718
|
-
// Base styles
|
|
3719
|
-
'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',
|
|
3720
|
-
// Pseudo styles
|
|
3721
|
-
'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',
|
|
3722
|
-
// user-invalid styles
|
|
3723
|
-
'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))]',
|
|
3724
|
-
// Custom styles
|
|
3725
|
-
typeof className === 'function' ? className(bag) : className), onBlur: onBlur, onChange: onChange, placeholder: placeholder, type: type, value: fieldContext?.value || '' }));
|
|
3726
|
-
}
|
|
3727
|
-
|
|
3728
|
-
function DateTimeInput({ className, fieldContextID, handleBlur, handleChange, ref, theme, type, ui, ...props }) {
|
|
3729
|
-
const [formContext] = useFormContext(), [fieldsetContext] = useFieldsetContext();
|
|
3699
|
+
function Input({ checked, className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, max, min, name, onBlur, onChange, options, placeholder, ref, required = true, type, value, ...props }) {
|
|
3700
|
+
const [formContext, formContextFunctions] = useFormContext(), [fieldsetContext, fieldsetContextFunctions] = useFieldsetContext(), [errorMessage, setErrorMessage] = useState(undefined);
|
|
3701
|
+
if (type === "password" && !placeholder) {
|
|
3702
|
+
placeholder = "••••••••" + (required && !label ? "*" : "");
|
|
3703
|
+
}
|
|
3704
|
+
if (placeholder === "*")
|
|
3705
|
+
placeholder = name + (required && !label ? "*" : "");
|
|
3706
|
+
if (label === "*")
|
|
3707
|
+
label = name;
|
|
3708
|
+
const uniqueID = useId(), fieldContextID = toLowerCase(name, [, "_"]) + "§" + uniqueID;
|
|
3730
3709
|
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
3731
|
-
const
|
|
3732
|
-
if (!ui)
|
|
3710
|
+
const getFieldContextType = () => {
|
|
3733
3711
|
switch (type) {
|
|
3734
|
-
case
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
case
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
time: {
|
|
3747
|
-
desktop: ['clock', 'dropdown'],
|
|
3748
|
-
mobile: ['rotary', 'clock'],
|
|
3749
|
-
},
|
|
3750
|
-
};
|
|
3751
|
-
break;
|
|
3752
|
-
case 'time':
|
|
3753
|
-
ui = {
|
|
3754
|
-
desktop: ['clock', 'dropdown'],
|
|
3755
|
-
mobile: ['rotary', 'clock'],
|
|
3756
|
-
};
|
|
3757
|
-
break;
|
|
3758
|
-
}
|
|
3759
|
-
const validation = ({ max, min, value }) => {
|
|
3760
|
-
const valueAsTime = new Date(value).getTime();
|
|
3761
|
-
if (min && !(min instanceof Date) && typeof min !== 'number') {
|
|
3762
|
-
if (Array.isArray(min)) {
|
|
3763
|
-
const monthIndex = typeof min[1] === 'number' ? min[1] - 1 : getMonthIndexFromName(min[1]);
|
|
3764
|
-
min = new Date(min[0], monthIndex, min[2]);
|
|
3765
|
-
}
|
|
3766
|
-
else if ('year' in min && 'month' in min && 'day' in min) {
|
|
3767
|
-
const monthIndex = typeof min.month === 'number' ? min.month - 1 : getMonthIndexFromName(min.month);
|
|
3768
|
-
min = new Date(min.year, monthIndex, min.day);
|
|
3769
|
-
}
|
|
3770
|
-
if (valueAsTime < min.getTime())
|
|
3771
|
-
return `Value cannot be lower than ${getUserReadableDate(min)}.`;
|
|
3772
|
-
}
|
|
3773
|
-
if (max && !(max instanceof Date) && typeof max !== 'number') {
|
|
3774
|
-
if (Array.isArray(max)) {
|
|
3775
|
-
const monthIndex = typeof max[1] === 'number' ? max[1] - 1 : getMonthIndexFromName(max[1]);
|
|
3776
|
-
max = new Date(max[0], monthIndex, max[2]);
|
|
3777
|
-
}
|
|
3778
|
-
else if ('year' in max && 'month' in max && 'day' in max) {
|
|
3779
|
-
const monthIndex = typeof max.month === 'number' ? max.month - 1 : getMonthIndexFromName(max.month);
|
|
3780
|
-
max = new Date(max.year, monthIndex, max.day);
|
|
3781
|
-
}
|
|
3782
|
-
if (valueAsTime > max.getTime())
|
|
3783
|
-
return `Value cannot be higher than ${getUserReadableDate(max)}.`;
|
|
3712
|
+
case "email":
|
|
3713
|
+
return "email";
|
|
3714
|
+
case "file":
|
|
3715
|
+
return "file";
|
|
3716
|
+
case "number":
|
|
3717
|
+
return "number";
|
|
3718
|
+
case "tel":
|
|
3719
|
+
return "tel";
|
|
3720
|
+
case "url":
|
|
3721
|
+
return "url";
|
|
3722
|
+
default:
|
|
3723
|
+
return "string";
|
|
3784
3724
|
}
|
|
3785
3725
|
};
|
|
3786
|
-
const
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
const onBlur = e => {
|
|
3790
|
-
handleBlur({ e, validation });
|
|
3791
|
-
};
|
|
3792
|
-
const [selectorIsOpen, setSelectorIsOpen] = useState(false);
|
|
3793
|
-
const toggleSelectorOpen = () => setSelectorIsOpen(previous => !previous);
|
|
3794
|
-
const { refs, floatingStyles, isPositioned, placement, middlewareData } = useFloating({
|
|
3795
|
-
middleware: [
|
|
3796
|
-
offset(8),
|
|
3797
|
-
flip({ padding: 20 }),
|
|
3798
|
-
shift({ padding: 20 }),
|
|
3799
|
-
size({
|
|
3800
|
-
apply({ availableHeight, availableWidth, elements }) {
|
|
3801
|
-
const height = `${Math.max(0, availableHeight) / 16}rem`, width = `${Math.min(418, availableWidth) / 16}rem`;
|
|
3802
|
-
elements.floating.style.maxHeight = height;
|
|
3803
|
-
elements.floating.style.maxWidth = width;
|
|
3804
|
-
},
|
|
3805
|
-
}),
|
|
3806
|
-
],
|
|
3807
|
-
placement: 'top-start',
|
|
3808
|
-
strategy: 'fixed',
|
|
3809
|
-
whileElementsMounted: autoUpdate,
|
|
3810
|
-
open: selectorIsOpen,
|
|
3811
|
-
});
|
|
3812
|
-
const reversedAnchor = {
|
|
3813
|
-
top: 'bottom',
|
|
3814
|
-
right: 'left',
|
|
3815
|
-
bottom: 'top',
|
|
3816
|
-
left: 'right',
|
|
3817
|
-
'top-start': 'bottom left',
|
|
3818
|
-
'top-end': 'bottom right',
|
|
3819
|
-
'right-start': 'top left',
|
|
3820
|
-
'right-end': 'bottom left',
|
|
3821
|
-
'bottom-start': 'top left',
|
|
3822
|
-
'bottom-end': 'top right',
|
|
3823
|
-
'left-start': 'top right',
|
|
3824
|
-
'left-end': 'bottom right',
|
|
3825
|
-
}[placement];
|
|
3826
|
-
return (jsxs(Fragment$1, { children: [jsx(Input$1, { ...props, className: bag => twMerge(
|
|
3827
|
-
// Base styles
|
|
3828
|
-
'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',
|
|
3829
|
-
// Pseudo styles
|
|
3830
|
-
'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',
|
|
3831
|
-
// user-invalid styles
|
|
3832
|
-
'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))]',
|
|
3833
|
-
// Custom styles
|
|
3834
|
-
typeof className === 'function' ? className(bag) : className), onBlur: onBlur, onChange: onChange, onClick: toggleSelectorOpen, ref: node => {
|
|
3835
|
-
refs.setReference(node);
|
|
3836
|
-
return ref;
|
|
3837
|
-
}, type: 'text', value: fieldContext?.value || '' }), jsx(Transition, { as: 'div', className: 'absolute rounded-xl bg-neutral-100 p-4 transition-opacity duration-500 ease-exponential data-closed:opacity-0 data-open:opacity-100', ref: refs.setFloating, show: selectorIsOpen, style: {
|
|
3838
|
-
...floatingStyles,
|
|
3839
|
-
transformOrigin: reversedAnchor,
|
|
3840
|
-
}, transition: true })] }));
|
|
3841
|
-
}
|
|
3842
|
-
|
|
3843
|
-
function NumberInput({ className, fieldContextID, handleBlur, handleChange, options, placeholder, type, ...props }) {
|
|
3844
|
-
const [formContext] = useFormContext(), [fieldsetContext] = useFieldsetContext();
|
|
3845
|
-
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
3846
|
-
const fieldContext = (isInFieldset ? fieldsetContext.fieldList : formContext)?.find(({ id: fieldID }) => fieldID === fieldContextID);
|
|
3847
|
-
const validation = ({ max, min, value }) => {
|
|
3848
|
-
const valueAsNumber = Number(value);
|
|
3849
|
-
if (isNaN(valueAsNumber))
|
|
3850
|
-
return 'This is not a valid number.';
|
|
3851
|
-
if (typeof max === 'number' && valueAsNumber > max)
|
|
3852
|
-
return `Value cannot be higher than ${max}.`;
|
|
3853
|
-
if (typeof min === 'number' && valueAsNumber < min)
|
|
3854
|
-
return `Value cannot be lower than ${min}.`;
|
|
3855
|
-
};
|
|
3856
|
-
const onChange = e => {
|
|
3857
|
-
handleChange({ e, validation });
|
|
3858
|
-
};
|
|
3859
|
-
const onBlur = e => {
|
|
3860
|
-
handleBlur({ e, validation });
|
|
3861
|
-
};
|
|
3862
|
-
return (jsx(Input$1, { ...props, className: bag => twMerge(
|
|
3863
|
-
// Base styles
|
|
3864
|
-
'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',
|
|
3865
|
-
// Pseudo styles
|
|
3866
|
-
'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',
|
|
3867
|
-
// user-invalid styles
|
|
3868
|
-
'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))]',
|
|
3869
|
-
// Custom styles
|
|
3870
|
-
typeof className === 'function' ? className(bag) : className), onBlur: onBlur, onChange: onChange, placeholder: placeholder, type: type, value: fieldContext?.value || '' }));
|
|
3871
|
-
}
|
|
3872
|
-
|
|
3873
|
-
const INPUT_COMPONENTS = {
|
|
3874
|
-
button: TextInput,
|
|
3875
|
-
checkbox: TextInput,
|
|
3876
|
-
color: TextInput,
|
|
3877
|
-
date: DateTimeInput,
|
|
3878
|
-
datetime: DateTimeInput,
|
|
3879
|
-
'datetime-local': DateTimeInput,
|
|
3880
|
-
email: TextInput,
|
|
3881
|
-
file: TextInput,
|
|
3882
|
-
hidden: TextInput,
|
|
3883
|
-
image: TextInput,
|
|
3884
|
-
list: TextInput,
|
|
3885
|
-
month: DateTimeInput,
|
|
3886
|
-
number: NumberInput,
|
|
3887
|
-
password: TextInput,
|
|
3888
|
-
radio: TextInput,
|
|
3889
|
-
range: TextInput,
|
|
3890
|
-
reset: TextInput,
|
|
3891
|
-
search: TextInput,
|
|
3892
|
-
submit: TextInput,
|
|
3893
|
-
tel: TextInput,
|
|
3894
|
-
text: TextInput,
|
|
3895
|
-
time: DateTimeInput,
|
|
3896
|
-
url: TextInput,
|
|
3897
|
-
week: DateTimeInput,
|
|
3898
|
-
year: DateTimeInput,
|
|
3899
|
-
};
|
|
3900
|
-
function Input({ as, checked, className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, max, min, name, onBlur, onChange, options, placeholder, ref, required = true, type = 'text', value, ...props }) {
|
|
3901
|
-
const [formContext, formContextFunctions] = useFormContext(), [fieldsetContext, fieldsetContextFunctions] = useFieldsetContext(), [errorMessage, setErrorMessage] = useState(undefined);
|
|
3902
|
-
if (placeholder === '*')
|
|
3903
|
-
placeholder = name + (required && !label ? '*' : '');
|
|
3904
|
-
if (label === '*')
|
|
3905
|
-
label = name;
|
|
3906
|
-
const uniqueID = useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
|
|
3907
|
-
const [internalController, setInternalController] = useState(undefined), isControlledByForm = formContext !== undefined, isControlledExternally = typeof value !== 'undefined';
|
|
3908
|
-
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
3909
|
-
const fieldContextType = type === 'email'
|
|
3910
|
-
? 'email'
|
|
3911
|
-
: type === 'file'
|
|
3912
|
-
? 'file'
|
|
3913
|
-
: type === 'number'
|
|
3914
|
-
? 'number'
|
|
3915
|
-
: type === 'tel'
|
|
3916
|
-
? 'tel'
|
|
3917
|
-
: type === 'url'
|
|
3918
|
-
? 'url'
|
|
3919
|
-
: 'string';
|
|
3920
|
-
const fieldContext = isControlledByForm
|
|
3921
|
-
? (isInFieldset ? fieldsetContext.fieldList : formContext)?.find(({ id: fieldID }) => fieldID === fieldContextID)
|
|
3922
|
-
: internalController;
|
|
3726
|
+
const fieldContextType = getFieldContextType();
|
|
3727
|
+
const fieldContext = (isInFieldset ? fieldsetContext.fieldList : formContext)
|
|
3728
|
+
?.find(({ id: fieldID }) => fieldID === fieldContextID);
|
|
3923
3729
|
useEffect(() => {
|
|
3924
3730
|
const initialFieldContext = defineField({
|
|
3731
|
+
type: fieldContextType,
|
|
3925
3732
|
id: fieldContextID,
|
|
3926
3733
|
invalid,
|
|
3927
3734
|
name,
|
|
3928
3735
|
required,
|
|
3929
|
-
|
|
3930
|
-
value: value ? `${value}` : defaultValue ? `${defaultValue}` : '',
|
|
3736
|
+
value: value ? `${value}` : defaultValue ? `${defaultValue}` : "",
|
|
3931
3737
|
});
|
|
3932
|
-
if (!isControlledByForm) {
|
|
3933
|
-
setInternalController(initialFieldContext);
|
|
3934
|
-
return;
|
|
3935
|
-
}
|
|
3936
3738
|
if (isInFieldset) {
|
|
3937
3739
|
fieldsetContextFunctions.registerField(initialFieldContext);
|
|
3938
3740
|
return () => {
|
|
@@ -3944,187 +3746,200 @@ function Input({ as, checked, className, defaultValue, description, descriptionP
|
|
|
3944
3746
|
formContextFunctions.removeField(initialFieldContext.id);
|
|
3945
3747
|
};
|
|
3946
3748
|
}, [isInFieldset]);
|
|
3947
|
-
const validateField = (validValue
|
|
3948
|
-
const noValue = !validValue || validValue ===
|
|
3749
|
+
const validateField = (validValue) => {
|
|
3750
|
+
const noValue = !validValue || validValue === "";
|
|
3949
3751
|
if (!required && noValue)
|
|
3950
3752
|
return true;
|
|
3951
3753
|
const errorMessageList = [];
|
|
3952
3754
|
if (noValue) {
|
|
3953
|
-
errorMessageList.push(
|
|
3954
|
-
setErrorMessage(errorMessageList.join(
|
|
3755
|
+
errorMessageList.push("This field is required.");
|
|
3756
|
+
setErrorMessage(errorMessageList.join(" "));
|
|
3955
3757
|
return false;
|
|
3956
3758
|
}
|
|
3957
|
-
|
|
3759
|
+
switch (type) {
|
|
3760
|
+
case "email":
|
|
3761
|
+
if (!isEmail(validValue)) {
|
|
3762
|
+
errorMessageList.push("This is not a valid email.");
|
|
3763
|
+
}
|
|
3764
|
+
break;
|
|
3765
|
+
case "date":
|
|
3766
|
+
const valueAsTime = new Date().getTime();
|
|
3767
|
+
if (min && !(min instanceof Date) && typeof min !== "number") {
|
|
3768
|
+
if (Array.isArray(min)) {
|
|
3769
|
+
const monthIndex = typeof min[1] === "number"
|
|
3770
|
+
? min[1] - 1
|
|
3771
|
+
: getMonthIndexFromName(min[1]);
|
|
3772
|
+
min = new Date(min[0], monthIndex, min[2]);
|
|
3773
|
+
}
|
|
3774
|
+
else if ("year" in min && "month" in min && "day" in min) {
|
|
3775
|
+
const monthIndex = typeof min.month === "number"
|
|
3776
|
+
? min.month - 1
|
|
3777
|
+
: getMonthIndexFromName(min.month);
|
|
3778
|
+
min = new Date(min.year, monthIndex, min.day);
|
|
3779
|
+
}
|
|
3780
|
+
if (valueAsTime < min.getTime()) {
|
|
3781
|
+
errorMessageList.push(`Value cannot be lower than ${getUserReadableDate(min)}.`);
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
if (max && !(max instanceof Date) && typeof max !== "number") {
|
|
3785
|
+
if (Array.isArray(max)) {
|
|
3786
|
+
const monthIndex = typeof max[1] === "number"
|
|
3787
|
+
? max[1] - 1
|
|
3788
|
+
: getMonthIndexFromName(max[1]);
|
|
3789
|
+
max = new Date(max[0], monthIndex, max[2]);
|
|
3790
|
+
}
|
|
3791
|
+
else if ("year" in max && "month" in max && "day" in max) {
|
|
3792
|
+
const monthIndex = typeof max.month === "number"
|
|
3793
|
+
? max.month - 1
|
|
3794
|
+
: getMonthIndexFromName(max.month);
|
|
3795
|
+
max = new Date(max.year, monthIndex, max.day);
|
|
3796
|
+
}
|
|
3797
|
+
if (valueAsTime > max.getTime()) {
|
|
3798
|
+
errorMessageList.push(`Value cannot be higher than ${getUserReadableDate(max)}.`);
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
break;
|
|
3802
|
+
case "number":
|
|
3803
|
+
const valueAsNumber = Number(validValue);
|
|
3804
|
+
if (isNaN(valueAsNumber)) {
|
|
3805
|
+
errorMessageList.push("This is not a valid number.");
|
|
3806
|
+
}
|
|
3807
|
+
if (typeof max === "number" && valueAsNumber > max) {
|
|
3808
|
+
errorMessageList.push(`Value cannot be higher than ${max}.`);
|
|
3809
|
+
}
|
|
3810
|
+
if (typeof min === "number" && valueAsNumber < min) {
|
|
3811
|
+
errorMessageList.push(`Value cannot be lower than ${min}.`);
|
|
3812
|
+
}
|
|
3813
|
+
break;
|
|
3814
|
+
case "password":
|
|
3815
|
+
if (options) {
|
|
3816
|
+
const { matchPreviousInput, requireLowercaseCharacter, requireNumber, requireSpecialCharacter, requireUppercaseCharacter, } = options;
|
|
3817
|
+
if (matchPreviousInput && formContext && formContext.length >= 2) {
|
|
3818
|
+
if (isInFieldset && fieldsetContext.fieldList.length > 1) {
|
|
3819
|
+
const currentInputIndex = fieldsetContext.fieldList.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3820
|
+
if (currentInputIndex > 0) {
|
|
3821
|
+
const previousInput = fieldsetContext.fieldList.find((_, index) => index === currentInputIndex - 1);
|
|
3822
|
+
if (previousInput &&
|
|
3823
|
+
isStringField(previousInput) &&
|
|
3824
|
+
previousInput.value !== validValue) {
|
|
3825
|
+
errorMessageList.push("Passwords must match.");
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
else {
|
|
3830
|
+
const currentInputIndex = formContext.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3831
|
+
if (currentInputIndex > 0) {
|
|
3832
|
+
const previousInput = formContext.find((_, index) => index === currentInputIndex - 1);
|
|
3833
|
+
if (previousInput &&
|
|
3834
|
+
isStringField(previousInput) &&
|
|
3835
|
+
previousInput.value !== validValue) {
|
|
3836
|
+
errorMessageList.push("Passwords must match.");
|
|
3837
|
+
}
|
|
3838
|
+
}
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3841
|
+
if (requireLowercaseCharacter && !/[a-z]/g.test(validValue)) {
|
|
3842
|
+
errorMessageList.push("You must include a lowercase character.");
|
|
3843
|
+
}
|
|
3844
|
+
if (requireNumber && !/[0-9]/g.test(validValue)) {
|
|
3845
|
+
errorMessageList.push("You must include a number.");
|
|
3846
|
+
}
|
|
3847
|
+
if (requireSpecialCharacter && !specialCharacterRegex.test(validValue)) {
|
|
3848
|
+
errorMessageList.push("You must include a special character.");
|
|
3849
|
+
}
|
|
3850
|
+
if (requireUppercaseCharacter && !/[A-Z]/g.test(validValue)) {
|
|
3851
|
+
errorMessageList.push("You must include an uppercase character.");
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
break;
|
|
3855
|
+
case "tel":
|
|
3856
|
+
if (!isPhoneNumber(validValue)) {
|
|
3857
|
+
errorMessageList.push("This is not a valid phone number.");
|
|
3858
|
+
}
|
|
3859
|
+
break;
|
|
3860
|
+
}
|
|
3861
|
+
if (props.maxLength && validValue.length > Number(props.maxLength)) {
|
|
3958
3862
|
errorMessageList.push(`This may not have more than ${props.maxLength} characters.`);
|
|
3959
|
-
|
|
3863
|
+
}
|
|
3864
|
+
if (props.minLength && validValue.length < Number(props.minLength)) {
|
|
3960
3865
|
errorMessageList.push(`This must have at least ${props.minLength} characters.`);
|
|
3961
|
-
if (typeof validation !== 'undefined') {
|
|
3962
|
-
const validationResult = validation({
|
|
3963
|
-
max,
|
|
3964
|
-
min,
|
|
3965
|
-
maxLength: props.maxLength,
|
|
3966
|
-
minLength: props.minLength,
|
|
3967
|
-
multiple: props.multiple,
|
|
3968
|
-
step: props.step,
|
|
3969
|
-
value: validValue,
|
|
3970
|
-
});
|
|
3971
|
-
if (typeof validationResult === 'string')
|
|
3972
|
-
errorMessageList.push(validationResult);
|
|
3973
3866
|
}
|
|
3974
3867
|
if (errorMessageList.length === 0)
|
|
3975
3868
|
return true;
|
|
3976
|
-
setErrorMessage(errorMessageList.join(
|
|
3869
|
+
setErrorMessage(errorMessageList.join(" "));
|
|
3977
3870
|
return false;
|
|
3978
3871
|
};
|
|
3979
|
-
const handleChange = (
|
|
3872
|
+
const handleChange = (e) => {
|
|
3980
3873
|
if (disabled) {
|
|
3981
3874
|
e.preventDefault();
|
|
3982
3875
|
return;
|
|
3983
3876
|
}
|
|
3984
3877
|
const { currentTarget } = e, { value: newValue } = currentTarget;
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
};
|
|
3991
|
-
if (isControlledByForm) {
|
|
3992
|
-
if (isInFieldset) {
|
|
3993
|
-
fieldsetContextFunctions.updateField(fieldContextID, updatedFieldValues);
|
|
3994
|
-
}
|
|
3995
|
-
else {
|
|
3996
|
-
formContextFunctions.updateField(fieldContextID, updatedFieldValues);
|
|
3997
|
-
}
|
|
3878
|
+
if (isInFieldset) {
|
|
3879
|
+
fieldsetContextFunctions.updateField(fieldContextID, {
|
|
3880
|
+
value: newValue,
|
|
3881
|
+
invalid: validateField(newValue) === false,
|
|
3882
|
+
});
|
|
3998
3883
|
}
|
|
3999
3884
|
else {
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
})
|
|
3885
|
+
formContextFunctions.updateField(fieldContextID, {
|
|
3886
|
+
value: newValue,
|
|
3887
|
+
invalid: validateField(newValue) === false,
|
|
3888
|
+
});
|
|
4004
3889
|
}
|
|
4005
3890
|
onChange?.(e);
|
|
4006
3891
|
};
|
|
4007
|
-
const handleBlur = (
|
|
3892
|
+
const handleBlur = (e) => {
|
|
4008
3893
|
if (disabled) {
|
|
4009
3894
|
e.preventDefault();
|
|
4010
3895
|
return;
|
|
4011
3896
|
}
|
|
4012
3897
|
const { currentTarget } = e, { value: newValue } = currentTarget;
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
else {
|
|
4024
|
-
formContextFunctions.updateField(fieldContextID, updatedFieldValues);
|
|
4025
|
-
}
|
|
4026
|
-
}
|
|
4027
|
-
else {
|
|
4028
|
-
setInternalController(previous => ({
|
|
4029
|
-
...previous,
|
|
4030
|
-
...updatedFieldValues,
|
|
4031
|
-
}));
|
|
4032
|
-
}
|
|
4033
|
-
onBlur?.(e);
|
|
4034
|
-
};
|
|
4035
|
-
const cleanFieldProps = fieldProps
|
|
4036
|
-
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !== 'className'))
|
|
4037
|
-
: {};
|
|
4038
|
-
const cleanLabalProps = labelProps
|
|
4039
|
-
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !== 'className'))
|
|
4040
|
-
: {};
|
|
4041
|
-
const cleanDescriptionProps = descriptionProps
|
|
4042
|
-
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== 'className'))
|
|
4043
|
-
: {};
|
|
4044
|
-
const InputComponent = INPUT_COMPONENTS[type];
|
|
4045
|
-
return (jsxs(Field, { ...cleanFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsx(Label, { ...cleanLabalProps, 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 })), jsxs("div", { children: [jsx(InputComponent, { ...props, fieldContextID: fieldContextID, handleBlur: handleBlur, handleChange: handleChange, invalid: invalid, options: options, placeholder: placeholder, required: required, type: type }), fieldContext?.invalid && errorMessage && (jsxs(Tooltip, { anchor: 'top-end', arrow: true, portal: true, children: [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: jsx(ExclamationmarkOctagon, { className: 'absolute top-1/2 left-1/2 size-full -translate-x-1/2 -translate-y-1/2 scale-70' }) }), jsx(TooltipPanel, { children: errorMessage })] }))] }), description && (jsx(Description, { ...cleanDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
|
|
4046
|
-
? descriptionProps?.className(bag)
|
|
4047
|
-
: descriptionProps?.className), children: description }))] }));
|
|
4048
|
-
}
|
|
4049
|
-
|
|
4050
|
-
function extractStringValue(value) {
|
|
4051
|
-
if (Array.isArray(value))
|
|
4052
|
-
return value.join(', ');
|
|
4053
|
-
if (typeof value === 'string')
|
|
4054
|
-
return value;
|
|
4055
|
-
return value.value;
|
|
4056
|
-
}
|
|
4057
|
-
function Select({ defaultValue, description, descriptionProps, disabled, fieldProps, invalid, label, labelProps, multiple, name, onChange, optionList, required, value, ...props }) {
|
|
4058
|
-
const [formContext, formContextFunctions] = useFormContext(), [fieldsetContext, fieldsetContextFunctions] = useFieldsetContext();
|
|
4059
|
-
if (label === '*')
|
|
4060
|
-
label = name;
|
|
4061
|
-
const uniqueID = useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
|
|
4062
|
-
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
4063
|
-
const fieldContext = (isInFieldset ? fieldsetContext.fieldList : formContext)?.find(({ id: fieldID }) => fieldID === fieldContextID);
|
|
4064
|
-
useEffect(() => {
|
|
4065
|
-
const initialFieldContext = multiple
|
|
4066
|
-
? defineField({
|
|
4067
|
-
type: 'array',
|
|
4068
|
-
of: value
|
|
4069
|
-
? value.map(item => ({
|
|
4070
|
-
type: 'string',
|
|
4071
|
-
value: typeof item === 'string' ? item : item.value,
|
|
4072
|
-
}))
|
|
4073
|
-
: defaultValue
|
|
4074
|
-
? defaultValue.map(item => ({
|
|
4075
|
-
type: 'string',
|
|
4076
|
-
value: typeof item === 'string' ? item : item.value,
|
|
4077
|
-
}))
|
|
4078
|
-
: [],
|
|
4079
|
-
id: fieldContextID,
|
|
4080
|
-
invalid,
|
|
4081
|
-
name,
|
|
4082
|
-
required,
|
|
4083
|
-
})
|
|
4084
|
-
: defineField({
|
|
4085
|
-
type: 'string',
|
|
4086
|
-
id: fieldContextID,
|
|
4087
|
-
invalid,
|
|
4088
|
-
name,
|
|
4089
|
-
required,
|
|
4090
|
-
value: value ? extractStringValue(value) : defaultValue ? extractStringValue(defaultValue) : '',
|
|
4091
|
-
});
|
|
4092
|
-
if (isInFieldset) {
|
|
4093
|
-
fieldsetContextFunctions.registerField(initialFieldContext);
|
|
4094
|
-
return () => {
|
|
4095
|
-
fieldsetContextFunctions.removeField(initialFieldContext.id);
|
|
4096
|
-
};
|
|
3898
|
+
if (required)
|
|
3899
|
+
validateField(newValue);
|
|
3900
|
+
let processedValue = newValue;
|
|
3901
|
+
switch (type) {
|
|
3902
|
+
case "email":
|
|
3903
|
+
processedValue = newValue.toLowerCase();
|
|
3904
|
+
break;
|
|
3905
|
+
case "tel":
|
|
3906
|
+
processedValue = formatPhoneNumber(newValue, options);
|
|
3907
|
+
break;
|
|
4097
3908
|
}
|
|
4098
|
-
formContextFunctions.registerField(initialFieldContext);
|
|
4099
|
-
return () => {
|
|
4100
|
-
formContextFunctions.removeField(initialFieldContext.id);
|
|
4101
|
-
};
|
|
4102
|
-
}, [isInFieldset]);
|
|
4103
|
-
const handleChange = (newValue) => {
|
|
4104
|
-
if (disabled)
|
|
4105
|
-
return;
|
|
4106
|
-
const isInvalid = newValue === '' || !newValue;
|
|
4107
3909
|
if (isInFieldset) {
|
|
4108
3910
|
fieldsetContextFunctions.updateField(fieldContextID, {
|
|
4109
|
-
|
|
4110
|
-
value: newValue,
|
|
3911
|
+
value: processedValue,
|
|
4111
3912
|
});
|
|
4112
3913
|
}
|
|
4113
3914
|
else {
|
|
4114
|
-
formContextFunctions.updateField(fieldContextID, {
|
|
3915
|
+
formContextFunctions.updateField(fieldContextID, {
|
|
3916
|
+
value: processedValue,
|
|
3917
|
+
});
|
|
4115
3918
|
}
|
|
4116
|
-
|
|
3919
|
+
onBlur?.(e);
|
|
4117
3920
|
};
|
|
4118
3921
|
const restFieldProps = fieldProps
|
|
4119
|
-
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !==
|
|
3922
|
+
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !== "className"))
|
|
4120
3923
|
: {};
|
|
4121
3924
|
const restLabelProps = labelProps
|
|
4122
|
-
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !==
|
|
3925
|
+
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !== "className"))
|
|
4123
3926
|
: {};
|
|
4124
3927
|
const restDescriptionProps = descriptionProps
|
|
4125
|
-
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !==
|
|
3928
|
+
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== "className"))
|
|
4126
3929
|
: {};
|
|
4127
|
-
return (jsxs(Field, { ...restFieldProps, className: bag => twMerge(
|
|
3930
|
+
return (jsxs(Field, { ...restFieldProps, className: (bag) => twMerge("grid gap-1", typeof fieldProps?.className === "function"
|
|
3931
|
+
? fieldProps?.className(bag)
|
|
3932
|
+
: fieldProps?.className), disabled: disabled, children: [label && (jsx(Label, { ...restLabelProps, className: (bag) => twMerge("text-sm font-medium", required ? 'after:text-ui-red after:content-["_*"]' : "", typeof labelProps?.className === "function"
|
|
3933
|
+
? labelProps?.className(bag)
|
|
3934
|
+
: labelProps?.className), children: label })), jsxs("div", { children: [jsx(Input$1, { ...props, className: (bag) => twMerge(
|
|
3935
|
+
// Base styles
|
|
3936
|
+
"w-full rounded-xl border 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",
|
|
3937
|
+
// Pseudo styles
|
|
3938
|
+
"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",
|
|
3939
|
+
// user-invalid styles
|
|
3940
|
+
"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))]",
|
|
3941
|
+
// Custom styles
|
|
3942
|
+
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 && (jsxs(Tooltip, { anchor: "top-end", arrow: true, portal: true, children: [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: jsx(ExclamationmarkOctagon, { className: "absolute top-1/2 left-1/2 size-full -translate-x-1/2 -translate-y-1/2 scale-70" }) }), jsx(TooltipPanel, { children: errorMessage })] }))] }), description && (jsx(Description, { ...restDescriptionProps, className: (bag) => twMerge("text-xs", typeof descriptionProps?.className === "function"
|
|
4128
3943
|
? descriptionProps?.className(bag)
|
|
4129
3944
|
: descriptionProps?.className), children: description }))] }));
|
|
4130
3945
|
}
|
|
@@ -4635,12 +4450,14 @@ const MAX_PROGRESS = 100;
|
|
|
4635
4450
|
function Video({ autoPlay, className, controls = true, poster, ref, srcSet, title, ...props }) {
|
|
4636
4451
|
// * General/Core
|
|
4637
4452
|
const uniqueID = useId(), figureRef = useRef(null), videoPlayerRef = useRef(null), sortedSrcSet = srcSet.sort((a, b) => a.width - b.width);
|
|
4638
|
-
const primaryPoster = poster
|
|
4639
|
-
|
|
4453
|
+
const primaryPoster = poster
|
|
4454
|
+
? poster.find(({ primary }) => primary)?.src || poster[0].src
|
|
4455
|
+
: "";
|
|
4456
|
+
const preventDefaultEvent = (e) => e.preventDefault();
|
|
4640
4457
|
// * Play/Pause Controls
|
|
4641
4458
|
const [isPlaying, setIsPlaying] = useState(autoPlay);
|
|
4642
4459
|
const togglePlay = useCallback(() => {
|
|
4643
|
-
setIsPlaying(previous => {
|
|
4460
|
+
setIsPlaying((previous) => {
|
|
4644
4461
|
if (!previous)
|
|
4645
4462
|
videoPlayerRef.current?.play();
|
|
4646
4463
|
if (previous)
|
|
@@ -4671,22 +4488,25 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4671
4488
|
}, []);
|
|
4672
4489
|
const enterPictureInPicture = () => videoPlayerRef.current?.requestPictureInPicture();
|
|
4673
4490
|
useEffect(() => {
|
|
4674
|
-
if (typeof window ===
|
|
4491
|
+
if (typeof window === "undefined")
|
|
4675
4492
|
return;
|
|
4676
|
-
document.addEventListener(
|
|
4493
|
+
document.addEventListener("fullscreenchange", updateFullscreenState);
|
|
4677
4494
|
return () => {
|
|
4678
|
-
document.removeEventListener(
|
|
4495
|
+
document.removeEventListener("fullscreenchange", updateFullscreenState);
|
|
4679
4496
|
};
|
|
4680
4497
|
}, []);
|
|
4681
4498
|
// * Progress/Seeking Controls
|
|
4682
|
-
const [progress, setProgress] = useState(0), trackProgressStartTimeRef = useRef(0), [seekIndicator, setSeekIndicator] = useState({
|
|
4499
|
+
const [progress, setProgress] = useState(0), trackProgressStartTimeRef = useRef(0), [seekIndicator, setSeekIndicator] = useState({
|
|
4500
|
+
isInPlayedArea: false,
|
|
4501
|
+
position: 0,
|
|
4502
|
+
}), seekIndicatorMouseDownPositionRef = useRef(0), scrubberRef = useRef(null), [timeRemaining, setTimeRemaining] = useState(0);
|
|
4683
4503
|
const handleTimeUpdate = () => {
|
|
4684
4504
|
const videoPlayer = videoPlayerRef.current;
|
|
4685
4505
|
if (!videoPlayer)
|
|
4686
4506
|
return;
|
|
4687
4507
|
const { currentTime, duration } = videoPlayer;
|
|
4688
4508
|
const newProgress = (currentTime / duration) * 100;
|
|
4689
|
-
setProgress(prev => (Math.abs(prev - newProgress) > 0.1 ? newProgress : prev));
|
|
4509
|
+
setProgress((prev) => (Math.abs(prev - newProgress) > 0.1 ? newProgress : prev));
|
|
4690
4510
|
setTimeRemaining(duration - currentTime);
|
|
4691
4511
|
};
|
|
4692
4512
|
const handleProgressSlider = ({ x }) => {
|
|
@@ -4696,7 +4516,9 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4696
4516
|
const { duration } = videoPlayer, { width } = scrubber.getBoundingClientRect();
|
|
4697
4517
|
videoPlayer.fastSeek(Math.max(Math.min(trackProgressStartTimeRef.current + x / (width / duration), duration - 1), 0));
|
|
4698
4518
|
};
|
|
4699
|
-
const { trackPointerMovement: trackProgress } = usePointerMovement({
|
|
4519
|
+
const { trackPointerMovement: trackProgress } = usePointerMovement({
|
|
4520
|
+
onChange: handleProgressSlider,
|
|
4521
|
+
});
|
|
4700
4522
|
const initiateTrackProgress = (e) => {
|
|
4701
4523
|
const videoPlayer = videoPlayerRef.current;
|
|
4702
4524
|
if (!videoPlayer)
|
|
@@ -4704,7 +4526,7 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4704
4526
|
trackProgress(e);
|
|
4705
4527
|
trackProgressStartTimeRef.current = videoPlayer.currentTime;
|
|
4706
4528
|
};
|
|
4707
|
-
const handleSeekIndicatorMovement = e => {
|
|
4529
|
+
const handleSeekIndicatorMovement = (e) => {
|
|
4708
4530
|
const videoPlayer = videoPlayerRef.current;
|
|
4709
4531
|
if (!videoPlayer)
|
|
4710
4532
|
return;
|
|
@@ -4715,30 +4537,33 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4715
4537
|
setSeekIndicator({ isInPlayedArea, position });
|
|
4716
4538
|
};
|
|
4717
4539
|
const initializeSeeking = () => (seekIndicatorMouseDownPositionRef.current = seekIndicator.position);
|
|
4718
|
-
const handleSeekRelease = e => {
|
|
4540
|
+
const handleSeekRelease = (e) => {
|
|
4719
4541
|
const videoPlayer = videoPlayerRef.current;
|
|
4720
4542
|
if (!videoPlayer)
|
|
4721
4543
|
return;
|
|
4722
4544
|
const { duration } = videoPlayer, { currentTarget } = e, { width } = currentTarget.getBoundingClientRect();
|
|
4723
|
-
if (seekIndicatorMouseDownPositionRef.current === seekIndicator.position)
|
|
4545
|
+
if (seekIndicatorMouseDownPositionRef.current === seekIndicator.position) {
|
|
4724
4546
|
videoPlayer.fastSeek(Math.min(duration / (width / seekIndicatorMouseDownPositionRef.current), duration - 1));
|
|
4547
|
+
}
|
|
4725
4548
|
};
|
|
4726
4549
|
// * Skip Controls
|
|
4727
4550
|
const [skipDuration, setSkipDuration] = useState(10);
|
|
4728
4551
|
const getSkipAmount = () => {
|
|
4729
4552
|
const modifierKeyList = pressedKeyListRef.current;
|
|
4730
4553
|
let skipAmount = 10;
|
|
4731
|
-
if (modifierKeyList.includes(
|
|
4554
|
+
if (modifierKeyList.includes("alt")) {
|
|
4732
4555
|
if (modifierKeyList.length === 1)
|
|
4733
4556
|
skipAmount = 15;
|
|
4734
|
-
if (modifierKeyList.includes(
|
|
4557
|
+
if (modifierKeyList.includes("shift"))
|
|
4735
4558
|
skipAmount = 30;
|
|
4736
|
-
if (modifierKeyList.includes(
|
|
4559
|
+
if (modifierKeyList.includes("meta"))
|
|
4737
4560
|
skipAmount = 5;
|
|
4738
|
-
if (modifierKeyList.includes(
|
|
4561
|
+
if (modifierKeyList.includes("shift") && modifierKeyList.includes("meta"))
|
|
4739
4562
|
skipAmount = 60;
|
|
4740
|
-
if (modifierKeyList.includes(
|
|
4563
|
+
if (modifierKeyList.includes("shift") && modifierKeyList.includes("meta") &&
|
|
4564
|
+
modifierKeyList.includes("ctrl")) {
|
|
4741
4565
|
skipAmount = 90;
|
|
4566
|
+
}
|
|
4742
4567
|
}
|
|
4743
4568
|
if (skipAmount !== skipDuration)
|
|
4744
4569
|
setSkipDuration(skipAmount);
|
|
@@ -4762,7 +4587,7 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4762
4587
|
}, []);
|
|
4763
4588
|
// * Volume Controls
|
|
4764
4589
|
const [volume, setVolume] = useState(1), trackVolumeStartRef = useRef(0);
|
|
4765
|
-
const handleVolumeChange = e => {
|
|
4590
|
+
const handleVolumeChange = (e) => {
|
|
4766
4591
|
const { currentTarget } = e, { volume } = currentTarget;
|
|
4767
4592
|
setVolume(volume);
|
|
4768
4593
|
};
|
|
@@ -4772,7 +4597,9 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4772
4597
|
return;
|
|
4773
4598
|
videoPlayer.volume = Math.max(Math.min(trackVolumeStartRef.current + (y / 96) * -1, 1), 0);
|
|
4774
4599
|
};
|
|
4775
|
-
const { trackPointerMovement: trackVolume } = usePointerMovement({
|
|
4600
|
+
const { trackPointerMovement: trackVolume } = usePointerMovement({
|
|
4601
|
+
onChange: handleVolumeSlider,
|
|
4602
|
+
});
|
|
4776
4603
|
const initiateTrackVolume = (e) => {
|
|
4777
4604
|
const videoPlayer = videoPlayerRef.current;
|
|
4778
4605
|
if (!videoPlayer)
|
|
@@ -4811,23 +4638,23 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4811
4638
|
// * Keyboard Controls
|
|
4812
4639
|
const pressedKeyListRef = useRef([]), [pressedKeyList, setPressedKeyList] = useState([]);
|
|
4813
4640
|
const updateModifierKeys = useCallback(({ metaKey, altKey, shiftKey, ctrlKey, }) => {
|
|
4814
|
-
if ((metaKey && !pressedKeyListRef.current.includes(
|
|
4815
|
-
(altKey && !pressedKeyListRef.current.includes(
|
|
4816
|
-
(shiftKey && !pressedKeyListRef.current.includes(
|
|
4817
|
-
(ctrlKey && !pressedKeyListRef.current.includes(
|
|
4818
|
-
(!metaKey && pressedKeyListRef.current.includes(
|
|
4819
|
-
(!altKey && pressedKeyListRef.current.includes(
|
|
4820
|
-
(!shiftKey && pressedKeyListRef.current.includes(
|
|
4821
|
-
(!ctrlKey && pressedKeyListRef.current.includes(
|
|
4641
|
+
if ((metaKey && !pressedKeyListRef.current.includes("meta")) ||
|
|
4642
|
+
(altKey && !pressedKeyListRef.current.includes("alt")) ||
|
|
4643
|
+
(shiftKey && !pressedKeyListRef.current.includes("shift")) ||
|
|
4644
|
+
(ctrlKey && !pressedKeyListRef.current.includes("ctrl")) ||
|
|
4645
|
+
(!metaKey && pressedKeyListRef.current.includes("meta")) ||
|
|
4646
|
+
(!altKey && pressedKeyListRef.current.includes("alt")) ||
|
|
4647
|
+
(!shiftKey && pressedKeyListRef.current.includes("shift")) ||
|
|
4648
|
+
(!ctrlKey && pressedKeyListRef.current.includes("ctrl"))) {
|
|
4822
4649
|
const newPressedKeyList = [];
|
|
4823
4650
|
if (metaKey)
|
|
4824
|
-
newPressedKeyList.push(
|
|
4651
|
+
newPressedKeyList.push("meta");
|
|
4825
4652
|
if (altKey)
|
|
4826
|
-
newPressedKeyList.push(
|
|
4653
|
+
newPressedKeyList.push("alt");
|
|
4827
4654
|
if (shiftKey)
|
|
4828
|
-
newPressedKeyList.push(
|
|
4655
|
+
newPressedKeyList.push("shift");
|
|
4829
4656
|
if (ctrlKey)
|
|
4830
|
-
newPressedKeyList.push(
|
|
4657
|
+
newPressedKeyList.push("ctrl");
|
|
4831
4658
|
setPressedKeyList(newPressedKeyList);
|
|
4832
4659
|
pressedKeyListRef.current = newPressedKeyList;
|
|
4833
4660
|
getSkipAmount();
|
|
@@ -4836,27 +4663,29 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4836
4663
|
const handleKeydown = useCallback((e) => {
|
|
4837
4664
|
const { key, metaKey, altKey, shiftKey, ctrlKey } = e;
|
|
4838
4665
|
updateModifierKeys({ metaKey, altKey, shiftKey, ctrlKey });
|
|
4839
|
-
if (![
|
|
4666
|
+
if (![" ", "ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown", "f"].includes(key))
|
|
4840
4667
|
return;
|
|
4841
|
-
if ([
|
|
4668
|
+
if ([" ", "ArrowUp", "ArrowDown", "f"].includes(key) && !metaKey &&
|
|
4669
|
+
!altKey && !shiftKey && !ctrlKey) {
|
|
4842
4670
|
e.preventDefault();
|
|
4671
|
+
}
|
|
4843
4672
|
switch (key) {
|
|
4844
|
-
case
|
|
4673
|
+
case " ":
|
|
4845
4674
|
togglePlay();
|
|
4846
4675
|
break;
|
|
4847
|
-
case
|
|
4676
|
+
case "ArrowRight":
|
|
4848
4677
|
skipForward();
|
|
4849
4678
|
break;
|
|
4850
|
-
case
|
|
4679
|
+
case "ArrowLeft":
|
|
4851
4680
|
skipBack();
|
|
4852
4681
|
break;
|
|
4853
|
-
case
|
|
4682
|
+
case "ArrowUp":
|
|
4854
4683
|
increaseVolume();
|
|
4855
4684
|
break;
|
|
4856
|
-
case
|
|
4685
|
+
case "ArrowDown":
|
|
4857
4686
|
decreaseVolume();
|
|
4858
4687
|
break;
|
|
4859
|
-
case
|
|
4688
|
+
case "f":
|
|
4860
4689
|
requestFullscreen();
|
|
4861
4690
|
break;
|
|
4862
4691
|
}
|
|
@@ -4866,11 +4695,11 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4866
4695
|
updateModifierKeys({ metaKey, altKey, shiftKey, ctrlKey });
|
|
4867
4696
|
}, [updateModifierKeys]);
|
|
4868
4697
|
useEffect(() => {
|
|
4869
|
-
if (typeof window ===
|
|
4698
|
+
if (typeof window === "undefined")
|
|
4870
4699
|
return;
|
|
4871
4700
|
const controller = new AbortController(), signal = controller.signal;
|
|
4872
|
-
document.addEventListener(
|
|
4873
|
-
document.addEventListener(
|
|
4701
|
+
document.addEventListener("keydown", handleKeydown, { signal });
|
|
4702
|
+
document.addEventListener("keyup", handleKeyup, { signal });
|
|
4874
4703
|
return () => {
|
|
4875
4704
|
controller.abort();
|
|
4876
4705
|
};
|
|
@@ -4880,22 +4709,25 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4880
4709
|
// * Progressive Enhancement
|
|
4881
4710
|
const progressiveEnhancementSourceLengthRef = useRef(1);
|
|
4882
4711
|
const [progressiveEnhancementList, setProgressiveEnhancementList] = useState(sortedSrcSet.filter((_, index) => index < progressiveEnhancementSourceLengthRef.current));
|
|
4883
|
-
const handleProEnhance = e => {
|
|
4712
|
+
const handleProEnhance = (e) => {
|
|
4884
4713
|
const { currentTarget } = e, { currentSrc, currentTime } = currentTarget;
|
|
4885
|
-
const proEnhanceSrcLength = progressiveEnhancementSourceLengthRef.current +
|
|
4714
|
+
const proEnhanceSrcLength = progressiveEnhancementSourceLengthRef.current +
|
|
4715
|
+
1, updatedProEnhanceList = sortedSrcSet.filter((_, index) => index < proEnhanceSrcLength);
|
|
4886
4716
|
console.log(updatedProEnhanceList);
|
|
4887
4717
|
setProgressiveEnhancementList(updatedProEnhanceList);
|
|
4888
4718
|
progressiveEnhancementSourceLengthRef.current = proEnhanceSrcLength;
|
|
4889
|
-
const srcToCompare = typeof updatedProEnhanceList.at(-1)?.src ===
|
|
4719
|
+
const srcToCompare = typeof updatedProEnhanceList.at(-1)?.src === "string"
|
|
4890
4720
|
? updatedProEnhanceList.at(-1)?.src
|
|
4891
4721
|
: updatedProEnhanceList.at(-1)?.srcGroup;
|
|
4892
4722
|
if (!srcToCompare)
|
|
4893
4723
|
return;
|
|
4894
|
-
if ((Array.isArray(srcToCompare) &&
|
|
4724
|
+
if ((Array.isArray(srcToCompare) &&
|
|
4725
|
+
srcToCompare.every(({ src }) => src !== currentSrc)) ||
|
|
4895
4726
|
(!Array.isArray(srcToCompare) && srcToCompare !== currentSrc)) {
|
|
4896
|
-
const srcType = currentSrc.split(
|
|
4727
|
+
const srcType = currentSrc.split(".").at(-1);
|
|
4897
4728
|
const src = Array.isArray(srcToCompare)
|
|
4898
|
-
? srcToCompare.find(({ src }) => src.split(
|
|
4729
|
+
? srcToCompare.find(({ src }) => src.split(".").at(-1) === srcType)
|
|
4730
|
+
?.src || srcToCompare[0].src
|
|
4899
4731
|
: srcToCompare;
|
|
4900
4732
|
if (!src)
|
|
4901
4733
|
return;
|
|
@@ -4910,50 +4742,60 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4910
4742
|
if (!videoPlayer)
|
|
4911
4743
|
return;
|
|
4912
4744
|
const { videoHeight, videoWidth } = videoPlayer;
|
|
4913
|
-
const canvas = document.createElement(
|
|
4745
|
+
const canvas = document.createElement("canvas"), canvasContext = canvas.getContext("2d");
|
|
4914
4746
|
if (!canvasContext)
|
|
4915
4747
|
return;
|
|
4916
4748
|
canvas.width = videoWidth;
|
|
4917
4749
|
canvas.height = videoHeight;
|
|
4918
4750
|
canvasContext.drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);
|
|
4919
|
-
canvas.toBlob(blob => {
|
|
4751
|
+
canvas.toBlob((blob) => {
|
|
4920
4752
|
if (!blob)
|
|
4921
4753
|
return;
|
|
4922
|
-
const url = URL.createObjectURL(blob), link = document.createElement(
|
|
4754
|
+
const url = URL.createObjectURL(blob), link = document.createElement("a");
|
|
4923
4755
|
link.href = url;
|
|
4924
4756
|
link.download = `${title}-frame-${Date.now()}.jpg`;
|
|
4925
4757
|
document.body.appendChild(link);
|
|
4926
4758
|
link.click();
|
|
4927
4759
|
document.body.removeChild(link);
|
|
4928
4760
|
URL.revokeObjectURL(url);
|
|
4929
|
-
},
|
|
4761
|
+
}, "image/jpeg", 0.9);
|
|
4930
4762
|
};
|
|
4931
|
-
return (jsxs("figure", { ...(showControls ? {
|
|
4763
|
+
return (jsxs("figure", { ...(showControls ? { "data-controls": true } : {}), ...(isFullscreen ? { "data-fullscreen": true } : {}), ...(isPlaying ? { "data-playing": true } : {}), ...Object.fromEntries(pressedKeyList.map((key) => [`data-${key}`, true])), className: twMerge("group/video isolate aspect-video w-full overflow-clip", className), onMouseEnter: displayControls, onMouseLeave: hideControls, ref: figureRef, children: [jsx("video", { ...props, className: "size-full object-cover", onLoad: handleProEnhance, onTimeUpdate: handleTimeUpdate, onVolumeChange: handleVolumeChange, poster: primaryPoster, ref: videoPlayerRef || ref, title: title, children: progressiveEnhancementList.map(({ width, ...source }) => {
|
|
4932
4764
|
if (source.srcGroup) {
|
|
4933
4765
|
const { srcGroup } = source;
|
|
4934
4766
|
return srcGroup.map(({ src, type }) => (jsx("source", { src: src, type: type }, `${title}${type}${width}${uniqueID}`)));
|
|
4935
4767
|
}
|
|
4936
4768
|
const { src, type } = source;
|
|
4937
|
-
return jsx("source", { src: src, type: type }, `${title}${type}${width}${uniqueID}`);
|
|
4938
|
-
}) }), controls && (jsxs("div", { className:
|
|
4769
|
+
return (jsx("source", { src: src, type: type }, `${title}${type}${width}${uniqueID}`));
|
|
4770
|
+
}) }), controls && (jsxs("div", { className: "absolute inset-0 isolate text-neutral-50 opacity-0 transition-opacity duration-1000 ease-exponential select-none group-data-controls/video:opacity-100", children: [jsxs("div", { className: "grid-flow-cols absolute top-1/2 left-1/2 grid -translate-x-1/2 -translate-y-1/2 place-items-center gap-2", children: [jsxs("button", { className: "col-start-1 col-end-2 row-start-0 row-end-1 grid size-16 rounded-full backdrop-blur-[1px] backdrop-brightness-101 transition-[scale,-webkit-backdrop-filter,backdrop-filter] duration-300 ease-exponential active:scale-95 active:backdrop-blur-[2px] active:backdrop-brightness-125 pointer-fine:hover:scale-105 pointer-fine:hover:backdrop-blur-xs pointer-fine:hover:backdrop-brightness-110 pointer-fine:active:scale-95 pointer-fine:active:backdrop-blur-[2px] pointer-fine:active:backdrop-brightness-125", onClick: togglePlay, onContextMenu: preventDefaultEvent, title: isPlaying ? "Pause" : "Play", children: [jsx(PauseFill, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-0 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 transition-[scale,opacity] duration-500 ease-exponential group-data-playing/video:scale-60 group-data-playing/video:opacity-100" }), jsx(PlayFill, { className: "-right-0.5 col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 transition-[scale,opacity] duration-500 ease-exponential group-data-playing/video:scale-0 group-data-playing/video:opacity-0" })] }), jsxs("button", { className: "col-start-0 col-end-1 row-start-0 row-end-1 grid size-12 rounded-full backdrop-blur-[1px] backdrop-brightness-101 transition-[scale,-webkit-backdrop-filter,backdrop-filter] duration-300 ease-exponential active:scale-95 active:backdrop-blur-[2px] active:backdrop-brightness-125 pointer-fine:hover:scale-105 pointer-fine:hover:backdrop-blur-xs pointer-fine:hover:backdrop-brightness-110 pointer-fine:active:scale-95 pointer-fine:active:backdrop-blur-[2px] pointer-fine:active:backdrop-brightness-125", onClick: skipBack, onContextMenu: preventDefaultEvent, title: `Skip Back ${skipDuration} Seconds`, children: [jsx(FiveArrowTriangleheadCounterclockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-meta/video:opacity-100 group-data-alt/video:group-data-meta/video:group-data-ctrl/video:opacity-0 group-data-alt/video:group-data-meta/video:group-data-shift/video:opacity-0" }), jsx(TenArrowTriangleheadCounterclockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:opacity-0 group-data-alt/video:group-data-ctrl/video:opacity-100 group-data-alt/video:group-data-shift/video:group-data-meta/video:group-data-ctrl/video:opacity-0" }), jsx(FifteenArrowTriangleheadCounterclockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:opacity-100 group-data-ctrl/video:opacity-0 group-data-meta/video:opacity-0 group-data-shift/video:opacity-0" }), jsx(ThirtyArrowTriangleheadCounterclockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-shift/video:opacity-100 group-data-alt/video:group-data-ctrl/video:group-data-shift/video:opacity-0 group-data-alt/video:group-data-meta/video:group-data-shift/video:opacity-0" }), jsx(SixtyArrowTriangleheadCounterclockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-shift/video:group-data-meta/video:opacity-100 group-data-alt/video:group-data-shift/video:group-data-meta/video:group-data-ctrl/video:opacity-0" }), jsx(NinetyArrowTriangleheadCounterclockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-shift/video:group-data-meta/video:group-data-ctrl/video:opacity-100" })] }), jsxs("button", { className: "col-start-2 col-end-3 row-start-0 row-end-1 grid size-12 rounded-full backdrop-blur-[1px] backdrop-brightness-101 transition-[scale,-webkit-backdrop-filter,backdrop-filter] duration-300 ease-exponential active:scale-95 active:backdrop-blur-[2px] active:backdrop-brightness-125 pointer-fine:hover:scale-105 pointer-fine:hover:backdrop-blur-xs pointer-fine:hover:backdrop-brightness-110 pointer-fine:active:scale-95 pointer-fine:active:backdrop-blur-[2px] pointer-fine:active:backdrop-brightness-125", onClick: skipForward, onContextMenu: preventDefaultEvent, title: `Skip Forward ${skipDuration} Seconds`, children: [jsx(FiveArrowTriangleheadClockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-meta/video:opacity-100 group-data-alt/video:group-data-meta/video:group-data-ctrl/video:opacity-0 group-data-alt/video:group-data-meta/video:group-data-shift/video:opacity-0" }), jsx(TenArrowTriangleheadClockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:opacity-0 group-data-alt/video:group-data-ctrl/video:opacity-100 group-data-alt/video:group-data-shift/video:group-data-meta/video:group-data-ctrl/video:opacity-0" }), jsx(FifteenArrowTriangleheadClockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:opacity-100 group-data-ctrl/video:opacity-0 group-data-meta/video:opacity-0 group-data-shift/video:opacity-0" }), jsx(ThirtyArrowTriangleheadClockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-shift/video:opacity-100 group-data-alt/video:group-data-ctrl/video:group-data-shift/video:opacity-0 group-data-alt/video:group-data-meta/video:group-data-shift/video:opacity-0" }), jsx(SixtyArrowTriangleheadClockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-shift/video:group-data-meta/video:opacity-100 group-data-alt/video:group-data-shift/video:group-data-meta/video:group-data-ctrl/video:opacity-0" }), jsx(NinetyArrowTriangleheadClockwise, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-60 opacity-0 drop-shadow-[0_.25rem_2rem] drop-shadow-neutral-950/75 group-data-alt/video:group-data-shift/video:group-data-meta/video:group-data-ctrl/video:opacity-100" })] })] }), jsxs("div", { className: "absolute inset-x-2 bottom-2 flex items-center gap-2 rounded-xl bg-neutral-900/50 px-2 py-1 shadow-2xl backdrop-blur-xs backdrop-brightness-110", children: [jsxs("div", { className: "group/scrubber h-2 w-max grow cursor-grab overflow-clip rounded-md bg-neutral-50/50 backdrop-blur-xs backdrop-brightness-110 transition-[height] duration-300 ease-exponential active:h-4 pointer-fine:hover:h-4 pointer-fine:active:h-4", onMouseDown: (e) => {
|
|
4939
4771
|
initiateTrackProgress(e);
|
|
4940
4772
|
initializeSeeking();
|
|
4941
|
-
}, onMouseMove: handleSeekIndicatorMovement, onMouseUp: handleSeekRelease, onTouchStart: initiateTrackProgress, ref: scrubberRef, children: [jsx("div", { "aria-hidden":
|
|
4773
|
+
}, onMouseMove: handleSeekIndicatorMovement, onMouseUp: handleSeekRelease, onTouchStart: initiateTrackProgress, ref: scrubberRef, children: [jsx("div", { "aria-hidden": "true", className: "absolute inset-0 grid transition-cols duration-100 ease-linear", style: { gridTemplateColumns: `${progress / MAX_PROGRESS}fr` }, children: jsx("div", { className: "overflow-hidden", children: jsxs("div", { className: "h-full bg-neutral-50/70 text-[1px] text-transparent backdrop-blur-xs backdrop-brightness-125", children: [progress, "/", MAX_PROGRESS] }) }) }), jsx("div", { ...(seekIndicator.isInPlayedArea
|
|
4774
|
+
? { "data-in-played-area": true }
|
|
4775
|
+
: {}), "aria-hidden": "true", className: "absolute inset-y-0 w-1 cursor-grab bg-neutral-50 opacity-0 transition-opacity duration-300 ease-exponential group-hover/scrubber:opacity-100 data-in-played-area:bg-neutral-500 pointer-coarse:hidden", style: { transform: `translateX(${seekIndicator.position}px)` }, children: "\u00A0" }), jsx("progress", { className: "sr-only", max: MAX_PROGRESS, value: progress })] }), jsx("span", { className: "block text-xs", children: timeRemaining / 60 >= 1
|
|
4942
4776
|
? `${Math.round(timeRemaining / 60)}:${Math.round((timeRemaining / 60 - Math.round(timeRemaining / 60)) * 60)
|
|
4943
4777
|
.toString()
|
|
4944
|
-
.padStart(2,
|
|
4778
|
+
.padStart(2, "0")}`
|
|
4945
4779
|
: Math.round(timeRemaining) === 60
|
|
4946
4780
|
? `1:00`
|
|
4947
|
-
: `0:${Math.round(timeRemaining).toString().padStart(2,
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4781
|
+
: `0:${Math.round(timeRemaining).toString().padStart(2, "0")}` }), jsxs(DropDown, { children: [jsx(DropDownButton, { arrow: false, className: "group/button flex size-6 items-center justify-center rounded-xs transition-transform duration-300 ease-exponential active:scale-95 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", title: "Volume", children: jsxs("svg", { viewBox: "0 0 64 47", className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75 transition-transform duration-300 ease-exponential", style: {
|
|
4782
|
+
translate: `${volume > 0.66
|
|
4783
|
+
? "0"
|
|
4784
|
+
: volume > 0.33
|
|
4785
|
+
? "2px"
|
|
4786
|
+
: volume > 0
|
|
4787
|
+
? "4px"
|
|
4788
|
+
: "6px"} 0`,
|
|
4789
|
+
}, children: [jsx("path", { d: "M25.707,44.076C27.257,44.076 28.39,42.947 28.39,41.387L28.39,4.841C28.39,3.307 27.257,2.025 25.656,2.025C24.542,2.025 23.767,2.512 22.558,3.666L12.393,13.203C12.251,13.345 12.047,13.436 11.818,13.436L4.99,13.436C1.759,13.436 0,15.195 0,18.654L0,27.525C0,30.953 1.759,32.737 4.99,32.737L11.818,32.737C12.047,32.737 12.251,32.808 12.393,32.95L22.558,42.583C23.666,43.615 24.593,44.076 25.707,44.076Z" }), jsx("path", { className: "transition-opacity duration-300 ease-exponential", d: "M36.874,33.192C37.684,33.728 38.797,33.566 39.439,32.64C41.265,30.222 42.371,26.683 42.371,23.026C42.371,19.368 41.265,15.855 39.439,13.411C38.797,12.485 37.684,12.323 36.874,12.885C35.923,13.553 35.761,14.721 36.505,15.713C37.901,17.607 38.662,20.249 38.662,23.026C38.662,25.802 37.876,28.419 36.505,30.338C35.786,31.355 35.923,32.498 36.874,33.192Z", style: { opacity: volume > 0 ? 1 : 0 } }), jsx("path", { className: "transition-opacity duration-300 ease-exponential", d: "M45.738,39.394C46.624,39.981 47.712,39.799 48.354,38.868C51.402,34.69 53.208,28.904 53.208,23.026C53.208,17.148 51.427,11.31 48.354,7.183C47.712,6.252 46.624,6.07 45.738,6.657C44.858,7.249 44.701,8.362 45.399,9.354C48.023,13.032 49.499,17.952 49.499,23.026C49.499,28.099 47.972,32.994 45.399,36.697C44.726,37.689 44.858,38.802 45.738,39.394Z", style: { opacity: volume > 0.33 ? 1 : 0 } }), jsx("path", { className: "transition-opacity duration-300 ease-exponential", d: "M54.679,45.708C55.514,46.32 56.683,46.082 57.315,45.121C61.498,39.091 64,31.447 64,23.026C64,14.604 61.422,6.986 57.315,0.93C56.683,-0.056 55.514,-0.269 54.679,0.343C53.804,0.956 53.668,2.079 54.33,3.071C58.012,8.514 60.342,15.379 60.342,23.026C60.342,30.647 58.012,37.562 54.33,42.98C53.668,43.972 53.804,45.095 54.679,45.708Z", style: { opacity: volume > 0.66 ? 1 : 0 } })] }) }), jsxs(DropDownItems, { anchor: {
|
|
4790
|
+
gap: ".5rem",
|
|
4791
|
+
padding: ".375rem",
|
|
4792
|
+
to: "top",
|
|
4793
|
+
}, className: "bg-neutral-900/50 px-1.5 py-1.5 text-neutral-50 backdrop-blur-xs backdrop-brightness-110", children: [jsx(DropDownItem, { as: "button", className: "flex size-6 items-center justify-center rounded-xs transition-transform duration-300 ease-exponential active:scale-95 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", onClick: increaseVolume, title: "Increase volume", children: jsx(SpeakerPlusFill, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsx(DropDownSeparator, { "aria-label": "Volume slider", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": volume * 100, className: "mx-auto my-2 h-24 w-2 cursor-grab overflow-clip rounded-md bg-neutral-50/50 backdrop-blur-xs backdrop-brightness-110 transition-[width] duration-300 ease-exponential active:w-4 pointer-fine:hover:w-4 pointer-fine:active:w-4", onMouseDown: initiateTrackVolume, onTouchStart: initiateTrackVolume, role: "slider", children: jsx("div", { "aria-hidden": "true", className: "grid size-full rotate-180 transition-rows duration-300 ease-exponential", style: { gridTemplateRows: `${volume}fr` }, children: jsx("div", { className: "overflow-y-hidden", children: jsxs("div", { className: "size-full bg-neutral-50/70 text-[1px] text-transparent backdrop-blur-xs backdrop-brightness-125", children: [volume * 100, "%"] }) }) }) }), jsx(DropDownItem, { as: "button", className: "flex size-6 items-center justify-center rounded-xs transition-transform duration-300 ease-exponential active:scale-95 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", onClick: decreaseVolume, title: "Decrease volume", children: jsx(SpeakerMinusFill, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) })] })] }), jsx("button", { className: "flex size-6 items-center justify-center rounded-xs transition-transform duration-300 ease-exponential active:scale-95 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", onClick: enterPictureInPicture, title: "Enter Picture-in-Picture", children: jsx(RectangleFillOnArrowDownForwardTopleadingRectangle, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsx("button", { className: "flex size-6 items-center justify-center rounded-xs transition-transform duration-300 ease-exponential active:scale-95 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", onClick: handleRemotePlayback, title: "Remote Playback", children: jsx(RectangleTriangleUp, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsxs(DropDown, { children: [jsx(DropDownButton, { arrow: false, className: "flex size-6 items-center justify-center rounded-xs transition-transform duration-300 ease-exponential active:scale-95 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", title: "Other Settings", children: jsx(GearshapeFill, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsx(DropDownItems, { anchor: {
|
|
4794
|
+
gap: ".5rem",
|
|
4795
|
+
padding: ".375rem",
|
|
4796
|
+
to: "top end",
|
|
4797
|
+
}, className: "bg-neutral-900/50 px-1.5 py-1.5 text-neutral-50 backdrop-blur-xs backdrop-brightness-110", children: jsxs(DropDownItem, { as: "button", className: "flex items-center gap-2 rounded-lg px-1.5 py-0.5 text-sm drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75 transition-[scale,background-color,color] duration-300 ease-exponential active:scale-95 data-active:bg-neutral-50/90 data-active:text-neutral-950 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", onClick: captureCurrentFrame, children: [jsx(PhotoBadgeArrowDownFill, { className: "size-5" }), "Capture Current Frame"] }) })] }), jsxs("button", { className: "grid size-6 rounded-xs transition-transform duration-300 ease-exponential active:scale-95 pointer-fine:hover:scale-105 pointer-fine:active:scale-95", onClick: toggleFullscreen, title: `${isFullscreen ? "Exit" : "Enter"} Fullscreen`, children: [jsx(ArrowUpForwardAndArrowDownBackwardRectangle, { className: "col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-0 opacity-0 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75 transition-[scale,opacity] duration-500 ease-exponential group-data-fullscreen/video:scale-80 group-data-fullscreen/video:opacity-100" }), jsx(ArrowDownBackwardAndArrowUpForwardRectangle, { className: "-right-0.5 col-start-0 col-end-1 row-start-0 row-end-1 size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75 transition-[scale,opacity] duration-500 ease-exponential group-data-fullscreen/video:scale-0 group-data-fullscreen/video:opacity-0" })] })] }), jsx("div", { "aria-hidden": "true", className: "absolute inset-0 -z-10 text-[1px] text-transparent", onClick: togglePlay, onMouseMove: handleMouseMoveControls, onMouseLeave: clearMouseMoveControlsTimeout, children: isPlaying ? "Pause" : "Play" })] }))] }));
|
|
4798
|
+
}
|
|
4799
|
+
|
|
4800
|
+
export { Anchor, Button, Details, DetailsBody, DetailsSummary, DropDown, DropDownButton, DropDownItem, DropDownItems, DropDownSection, DropDownSeparator, Fieldset, Form, Ghost, Heading, IFrame, Input, Link, Modal, ModalClose, ModalDialog, ModalTitle, ModalTrigger, SubmitButton, Textarea, Time, Tooltip, TooltipPanel, TooltipTrigger, Video, createButton, createLink, getLinkClasses };
|
|
4959
4801
|
//# sourceMappingURL=components.esm.js.map
|