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.js
CHANGED
|
@@ -139,7 +139,7 @@ getMonthName();
|
|
|
139
139
|
/** The name of the current day of the week */
|
|
140
140
|
getWeekdayName();
|
|
141
141
|
/**
|
|
142
|
-
*
|
|
142
|
+
* ### Get Date
|
|
143
143
|
* - Returns the date with two digits
|
|
144
144
|
* @param {number|Date} date The date to get date
|
|
145
145
|
* @returns {string} The date with two digits
|
|
@@ -153,7 +153,7 @@ function getDate(date = d) {
|
|
|
153
153
|
return formattedDate;
|
|
154
154
|
}
|
|
155
155
|
/**
|
|
156
|
-
*
|
|
156
|
+
* ### Get Hours
|
|
157
157
|
* - Returns the hours with two digits
|
|
158
158
|
* @param {number|Date} hours The date to get hours
|
|
159
159
|
* @returns {string} The hours with two digits
|
|
@@ -167,7 +167,7 @@ function getHours(hours = d) {
|
|
|
167
167
|
return formattedHours;
|
|
168
168
|
}
|
|
169
169
|
/**
|
|
170
|
-
*
|
|
170
|
+
* ### Get Milliseconds
|
|
171
171
|
* - Returns the milliseconds with two digits
|
|
172
172
|
* @param {number|Date} milliseconds The date to get milliseconds
|
|
173
173
|
* @returns {string} The milliseconds with two digits
|
|
@@ -181,7 +181,7 @@ function getMilliseconds(milliseconds = d) {
|
|
|
181
181
|
return formattedMilliseconds;
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
184
|
-
*
|
|
184
|
+
* ### Get Minutes
|
|
185
185
|
* - Returns the minutes with two digits
|
|
186
186
|
* @param {number|Date} minutes The date to get minutes
|
|
187
187
|
* @returns {string} The minutes with two digits
|
|
@@ -195,7 +195,7 @@ function getMinutes(minutes = d) {
|
|
|
195
195
|
return formattedMinutes;
|
|
196
196
|
}
|
|
197
197
|
/**
|
|
198
|
-
*
|
|
198
|
+
* ### Get Month
|
|
199
199
|
* - Returns the month with two digits
|
|
200
200
|
* @param {number|Date} month The date to get month
|
|
201
201
|
* @returns {string} The month with two digits
|
|
@@ -212,7 +212,7 @@ function getMonthIndexFromName(name) {
|
|
|
212
212
|
return monthNamesList.findIndex(monthName => monthName === name);
|
|
213
213
|
}
|
|
214
214
|
/**
|
|
215
|
-
*
|
|
215
|
+
* ### Get Month Name
|
|
216
216
|
* - Returns the name of the specified month
|
|
217
217
|
* @param {Date} date A Date object representing the month to get the name of the month from. (Preset to the current date)
|
|
218
218
|
* @returns {MonthName} The name of the specified month
|
|
@@ -223,7 +223,7 @@ function getMonthName(date = d) {
|
|
|
223
223
|
return monthNamesList[date.getMonth()];
|
|
224
224
|
}
|
|
225
225
|
/**
|
|
226
|
-
*
|
|
226
|
+
* ### Get Seconds
|
|
227
227
|
* - Returns the seconds with two digits
|
|
228
228
|
* @param {number|Date} seconds The date to get seconds
|
|
229
229
|
* @returns {string} The seconds with two digits
|
|
@@ -237,7 +237,7 @@ function getSeconds(seconds = d) {
|
|
|
237
237
|
return formattedSeconds;
|
|
238
238
|
}
|
|
239
239
|
/**
|
|
240
|
-
*
|
|
240
|
+
* ### Get User Readable Date
|
|
241
241
|
* - Returns a string of the current date in a user-friendly way
|
|
242
242
|
* - Includes `'Yesterday'`, '`Today'`, and `'Tomorrow'`
|
|
243
243
|
* @param date (default: `new Date()`)
|
|
@@ -261,7 +261,7 @@ function getUserReadableDate(date = d) {
|
|
|
261
261
|
return fullDateString;
|
|
262
262
|
}
|
|
263
263
|
/**
|
|
264
|
-
*
|
|
264
|
+
* ### Get Weekday Name
|
|
265
265
|
* - Returns the weekday name of the specified day
|
|
266
266
|
* @param {number | Date} weekday A Date object or number representing the day to get the weekday name from. (Preset to the current date)
|
|
267
267
|
* @returns {WeekdayName} The name of the specified weekday
|
|
@@ -273,7 +273,7 @@ function getWeekdayName(weekday = d) {
|
|
|
273
273
|
return weekdayNamesList[weekday.getDay()];
|
|
274
274
|
}
|
|
275
275
|
/**
|
|
276
|
-
*
|
|
276
|
+
* ### To Full Date String
|
|
277
277
|
* - Returns a formatted string to display the date
|
|
278
278
|
* @param {Date} date (default: `new Date()`)
|
|
279
279
|
* @param {ToFullDateStringOptionsProps} options Change how to display the weekday, month name, day of the month, and year.
|
|
@@ -471,85 +471,93 @@ function twSort(className) {
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
function Anchor({ as, className, disabled, href, onClick, target, rel, ...props }) {
|
|
474
|
-
const isExternal = `${href}`.startsWith(
|
|
475
|
-
const handleClick = e => {
|
|
474
|
+
const isExternal = `${href}`.startsWith("http"), hasHash = `${href}`.includes("#");
|
|
475
|
+
const handleClick = (e) => {
|
|
476
476
|
if (disabled)
|
|
477
477
|
return e.preventDefault();
|
|
478
478
|
onClick?.(e);
|
|
479
479
|
setTimeout(() => history.replaceState({}, document.title, location.pathname), 100);
|
|
480
480
|
};
|
|
481
|
-
const AnchorElement = as ||
|
|
482
|
-
return (jsxRuntime.jsx(AnchorElement, { ...props, "aria-disabled": disabled, className: twMerge(className, disabled &&
|
|
483
|
-
? rel ===
|
|
484
|
-
? `${rel} noreferrer noopener`
|
|
485
|
-
: `${rel} prefetch`
|
|
481
|
+
const AnchorElement = as || "a";
|
|
482
|
+
return (jsxRuntime.jsx(AnchorElement, { ...props, "aria-disabled": disabled, className: twMerge(className, disabled && "pointer-events-none"), href: href, target: target || (isExternal ? "_blank" : "_self"), onClick: hasHash ? handleClick : onClick, rel: rel !== undefined
|
|
483
|
+
? rel === "nofollow" ? `${rel} noreferrer noopener` : `${rel} prefetch`
|
|
486
484
|
: isExternal
|
|
487
|
-
?
|
|
488
|
-
:
|
|
485
|
+
? "nofollow noreferrer noopener"
|
|
486
|
+
: "prefetch" }));
|
|
489
487
|
}
|
|
490
488
|
// * Styles
|
|
491
|
-
const baseClasses = twSort(
|
|
492
|
-
const lineStaticClasses = tailwindMerge.twJoin(baseClasses,
|
|
493
|
-
const lineClasses = tailwindMerge.twJoin(lineStaticClasses,
|
|
494
|
-
const scaleXClasses =
|
|
495
|
-
const scaleYClasses =
|
|
489
|
+
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");
|
|
490
|
+
const lineStaticClasses = tailwindMerge.twJoin(baseClasses, "whitespace-nowrap after:-bottom-0.5 after:w-[calc(100%+0.15rem)] after:rounded-full after:border-1 after:border-current");
|
|
491
|
+
const lineClasses = tailwindMerge.twJoin(lineStaticClasses, "whitespace-nowrap transition-transform after:transition-transform after:ease-exponential");
|
|
492
|
+
const scaleXClasses = "after:scale-x-0 pointer-fine:hover:after:scale-x-100 active:after:scale-x-100";
|
|
493
|
+
const scaleYClasses = "after:scale-y-0 pointer-fine:hover:after:scale-y-100 active:after:scale-y-100";
|
|
496
494
|
const lineNormalClasses = tailwindMerge.twJoin([
|
|
497
495
|
lineClasses,
|
|
498
496
|
scaleYClasses,
|
|
499
|
-
|
|
497
|
+
"after:origin-bottom after:translate-y-0.5 active:after:translate-y-0 pointer-fine:hover:after:translate-y-0",
|
|
498
|
+
]);
|
|
499
|
+
const lineLtrClasses = tailwindMerge.twJoin([
|
|
500
|
+
lineClasses,
|
|
501
|
+
scaleXClasses,
|
|
502
|
+
"after:origin-left",
|
|
503
|
+
]);
|
|
504
|
+
const lineRtlClasses = tailwindMerge.twJoin([
|
|
505
|
+
lineClasses,
|
|
506
|
+
scaleXClasses,
|
|
507
|
+
"after:origin-right",
|
|
500
508
|
]);
|
|
501
|
-
const lineLtrClasses = tailwindMerge.twJoin([lineClasses, scaleXClasses, 'after:origin-left']);
|
|
502
|
-
const lineRtlClasses = tailwindMerge.twJoin([lineClasses, scaleXClasses, 'after:origin-right']);
|
|
503
509
|
const lineCenterClasses = tailwindMerge.twJoin([lineClasses, scaleXClasses]);
|
|
504
510
|
const lineLiftClasses = tailwindMerge.twJoin([
|
|
505
511
|
lineClasses,
|
|
506
512
|
scaleYClasses,
|
|
507
|
-
|
|
513
|
+
"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",
|
|
508
514
|
]);
|
|
509
|
-
const fillClasses = tailwindMerge.twJoin(baseClasses,
|
|
515
|
+
const fillClasses = tailwindMerge.twJoin(baseClasses, "whitespace-nowrap transition-[transform,color] after:top-1/2 after:h-[calc(100%+0.05rem)] after:w-[calc(100%+0.25rem)] after:-translate-y-1/2 after:rounded after:ease-exponential active:text-zinc-50 pointer-fine:hover:text-zinc-50");
|
|
510
516
|
// Define theme-specific fill color transition classes
|
|
511
|
-
const getFillColorTransitionClasses = (theme =
|
|
512
|
-
let fillColorTransitionClasses = tailwindMerge.twJoin(fillClasses,
|
|
517
|
+
const getFillColorTransitionClasses = (theme = "blue", customTheme) => {
|
|
518
|
+
let fillColorTransitionClasses = tailwindMerge.twJoin(fillClasses, "transition-transform after:bg-(--theme-color)");
|
|
513
519
|
switch (theme) {
|
|
514
|
-
case
|
|
515
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
520
|
+
case "blue":
|
|
521
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-blue)]");
|
|
516
522
|
break;
|
|
517
|
-
case
|
|
518
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
523
|
+
case "brown":
|
|
524
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-brow)]");
|
|
519
525
|
break;
|
|
520
|
-
case
|
|
521
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
526
|
+
case "green":
|
|
527
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-green)]");
|
|
522
528
|
break;
|
|
523
|
-
case
|
|
524
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
529
|
+
case "grey":
|
|
530
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-grey)]");
|
|
525
531
|
break;
|
|
526
|
-
case
|
|
527
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
532
|
+
case "sky-blue":
|
|
533
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-sky-blue)]");
|
|
528
534
|
break;
|
|
529
|
-
case
|
|
530
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
535
|
+
case "magenta":
|
|
536
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-magenta)]");
|
|
531
537
|
break;
|
|
532
|
-
case
|
|
533
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
538
|
+
case "orange":
|
|
539
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-orange)]");
|
|
534
540
|
break;
|
|
535
|
-
case
|
|
536
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
541
|
+
case "pink":
|
|
542
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-pink)]");
|
|
537
543
|
break;
|
|
538
|
-
case
|
|
539
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
544
|
+
case "purple":
|
|
545
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-purple)]");
|
|
540
546
|
break;
|
|
541
|
-
case
|
|
542
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
547
|
+
case "red":
|
|
548
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-red)]");
|
|
543
549
|
break;
|
|
544
|
-
case
|
|
545
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
550
|
+
case "violet":
|
|
551
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-violet)]");
|
|
546
552
|
break;
|
|
547
|
-
case
|
|
548
|
-
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses,
|
|
553
|
+
case "yellow":
|
|
554
|
+
fillColorTransitionClasses = tailwindMerge.twJoin(fillColorTransitionClasses, "after:[--theme-color:var(--color-ui-yellow)]");
|
|
549
555
|
break;
|
|
550
|
-
case
|
|
551
|
-
if (customTheme && customTheme.themeColor &&
|
|
552
|
-
|
|
556
|
+
case "custom":
|
|
557
|
+
if (customTheme && customTheme.themeColor &&
|
|
558
|
+
!customTheme.themeColor.includes("after:[--theme-color:")) {
|
|
559
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable on the ::after pseudo element. Otherwise, please use `customTheme.classes`.");
|
|
560
|
+
}
|
|
553
561
|
fillColorTransitionClasses = customTheme.themeColor
|
|
554
562
|
? twMerge(fillColorTransitionClasses, customTheme.themeColor)
|
|
555
563
|
: twMerge(fillClasses, customTheme.classes);
|
|
@@ -558,48 +566,50 @@ const getFillColorTransitionClasses = (theme = 'blue', customTheme) => {
|
|
|
558
566
|
return fillColorTransitionClasses;
|
|
559
567
|
};
|
|
560
568
|
// Define theme-specific fill center classes
|
|
561
|
-
const getFillCenterClasses = (theme =
|
|
562
|
-
let fillCenterColorClasses = tailwindMerge.twJoin(fillClasses,
|
|
569
|
+
const getFillCenterClasses = (theme = "blue", customTheme) => {
|
|
570
|
+
let fillCenterColorClasses = tailwindMerge.twJoin(fillClasses, "after:scale-x-50 after:scale-y-[0.25] after:bg-(--theme-color)/0 after:transition-[transform,background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-(--theme-color) pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-(--theme-color)");
|
|
563
571
|
switch (theme) {
|
|
564
|
-
case
|
|
565
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
572
|
+
case "blue":
|
|
573
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-blue)]");
|
|
566
574
|
break;
|
|
567
|
-
case
|
|
568
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
575
|
+
case "brown":
|
|
576
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-brown)]");
|
|
569
577
|
break;
|
|
570
|
-
case
|
|
571
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
578
|
+
case "green":
|
|
579
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-green)]");
|
|
572
580
|
break;
|
|
573
|
-
case
|
|
574
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
581
|
+
case "grey":
|
|
582
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-grey)]");
|
|
575
583
|
break;
|
|
576
|
-
case
|
|
577
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
584
|
+
case "sky-blue":
|
|
585
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-sky-blue)]");
|
|
578
586
|
break;
|
|
579
|
-
case
|
|
580
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
587
|
+
case "magenta":
|
|
588
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-magenta)]");
|
|
581
589
|
break;
|
|
582
|
-
case
|
|
583
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
590
|
+
case "orange":
|
|
591
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-orange)]");
|
|
584
592
|
break;
|
|
585
|
-
case
|
|
586
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
593
|
+
case "pink":
|
|
594
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-pink)]");
|
|
587
595
|
break;
|
|
588
|
-
case
|
|
589
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
596
|
+
case "purple":
|
|
597
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-purple)]");
|
|
590
598
|
break;
|
|
591
|
-
case
|
|
592
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
599
|
+
case "red":
|
|
600
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-red)]");
|
|
593
601
|
break;
|
|
594
|
-
case
|
|
595
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
602
|
+
case "violet":
|
|
603
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-violet)]");
|
|
596
604
|
break;
|
|
597
|
-
case
|
|
598
|
-
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses,
|
|
605
|
+
case "yellow":
|
|
606
|
+
fillCenterColorClasses = tailwindMerge.twJoin(fillCenterColorClasses, "after:[--theme-color:var(--color-ui-yellow)]");
|
|
599
607
|
break;
|
|
600
|
-
case
|
|
601
|
-
if (customTheme && customTheme.themeColor &&
|
|
602
|
-
|
|
608
|
+
case "custom":
|
|
609
|
+
if (customTheme && customTheme.themeColor &&
|
|
610
|
+
!customTheme.themeColor.includes("after:[--theme-color:")) {
|
|
611
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable on the ::after pseudo element. Otherwise, please use `customTheme.classes`.");
|
|
612
|
+
}
|
|
603
613
|
fillCenterColorClasses = customTheme.themeColor
|
|
604
614
|
? twMerge(fillCenterColorClasses, customTheme.themeColor)
|
|
605
615
|
: twMerge(fillClasses, customTheme.classes);
|
|
@@ -607,58 +617,66 @@ const getFillCenterClasses = (theme = 'blue', customTheme) => {
|
|
|
607
617
|
}
|
|
608
618
|
return fillCenterColorClasses;
|
|
609
619
|
};
|
|
610
|
-
const multilineBaseClasses = twSort(
|
|
611
|
-
const multilineLineStaticClasses =
|
|
612
|
-
const multilineNormalClasses = twSort(
|
|
613
|
-
const multilineClasses = tailwindMerge.twJoin(multilineBaseClasses,
|
|
614
|
-
const multilineLineClasses = tailwindMerge.twJoin(multilineClasses,
|
|
615
|
-
const multilineXClasses = tailwindMerge.twJoin(multilineLineClasses,
|
|
616
|
-
const multilineLineRtlClasses = tailwindMerge.twJoin([
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
const
|
|
621
|
-
|
|
620
|
+
const multilineBaseClasses = twSort("bg-linear-to-r from-current to-current bg-no-repeat active:scale-95");
|
|
621
|
+
const multilineLineStaticClasses = "underline";
|
|
622
|
+
const multilineNormalClasses = twSort("underline-offset-1 active:underline pointer-fine:hover:underline");
|
|
623
|
+
const multilineClasses = tailwindMerge.twJoin(multilineBaseClasses, "duration-500 ease-exponential");
|
|
624
|
+
const multilineLineClasses = tailwindMerge.twJoin(multilineClasses, "bg-[position:0%_100%] px-px pb-px transition-[background-size]");
|
|
625
|
+
const multilineXClasses = tailwindMerge.twJoin(multilineLineClasses, "bg-[size:0%_2px] focus-visible:bg-[size:100%_2px] active:bg-[size:100%_2px] pointer-fine:hover:bg-[size:100%_2px]");
|
|
626
|
+
const multilineLineRtlClasses = tailwindMerge.twJoin([
|
|
627
|
+
multilineXClasses,
|
|
628
|
+
"bg-[position:100%_100%]",
|
|
629
|
+
]);
|
|
630
|
+
const multilineLineCenterClasses = tailwindMerge.twJoin([
|
|
631
|
+
multilineXClasses,
|
|
632
|
+
"bg-[position:50%_100%]",
|
|
633
|
+
]);
|
|
634
|
+
const multilineLineLiftClasses = tailwindMerge.twJoin(multilineLineClasses, "bg-[size:auto_0px] focus-visible:bg-[size:auto_2px] active:bg-[size:auto_2px] pointer-fine:hover:bg-[size:auto_2px]");
|
|
635
|
+
const multilineFillBaseClasses = tailwindMerge.twJoin(multilineBaseClasses, "rounded px-0.5 py-0.75 focus-visible:text-zinc-50 active:text-zinc-50 pointer-fine:hover:text-zinc-50");
|
|
636
|
+
const getMultilineFillColorClasses = (theme = "blue", customTheme) => {
|
|
637
|
+
let multilineFillColorClasses = tailwindMerge.twJoin(multilineFillBaseClasses, "from-(--theme-color) to-(--theme-color) transition-[background-size,color]");
|
|
622
638
|
switch (theme) {
|
|
623
|
-
case
|
|
624
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
639
|
+
case "blue":
|
|
640
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-blue)]");
|
|
625
641
|
break;
|
|
626
|
-
case
|
|
627
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
642
|
+
case "brown":
|
|
643
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-brown)]");
|
|
628
644
|
break;
|
|
629
|
-
case
|
|
630
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
645
|
+
case "green":
|
|
646
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-green)]");
|
|
631
647
|
break;
|
|
632
|
-
case
|
|
633
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
648
|
+
case "grey":
|
|
649
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-grey)]");
|
|
634
650
|
break;
|
|
635
|
-
case
|
|
636
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
651
|
+
case "sky-blue":
|
|
652
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-sky-blue)]");
|
|
637
653
|
break;
|
|
638
|
-
case
|
|
639
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
654
|
+
case "magenta":
|
|
655
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-magenta)]");
|
|
640
656
|
break;
|
|
641
|
-
case
|
|
642
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
657
|
+
case "orange":
|
|
658
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-orange)]");
|
|
643
659
|
break;
|
|
644
|
-
case
|
|
645
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
660
|
+
case "pink":
|
|
661
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-pink)]");
|
|
646
662
|
break;
|
|
647
|
-
case
|
|
648
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
663
|
+
case "purple":
|
|
664
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-purple)]");
|
|
649
665
|
break;
|
|
650
|
-
case
|
|
651
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
666
|
+
case "red":
|
|
667
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-red)]");
|
|
652
668
|
break;
|
|
653
|
-
case
|
|
654
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
669
|
+
case "violet":
|
|
670
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-violet)]");
|
|
655
671
|
break;
|
|
656
|
-
case
|
|
657
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
672
|
+
case "yellow":
|
|
673
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-yellow)]");
|
|
658
674
|
break;
|
|
659
|
-
case
|
|
660
|
-
if (customTheme && customTheme.themeColor &&
|
|
661
|
-
|
|
675
|
+
case "custom":
|
|
676
|
+
if (customTheme && customTheme.themeColor &&
|
|
677
|
+
!customTheme.themeColor.includes("[--theme-color:")) {
|
|
678
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable. Otherwise, please use `customTheme.classes`.");
|
|
679
|
+
}
|
|
662
680
|
multilineFillColorClasses = customTheme.themeColor
|
|
663
681
|
? twMerge(multilineFillColorClasses, customTheme.themeColor)
|
|
664
682
|
: twMerge(multilineFillBaseClasses, customTheme.classes);
|
|
@@ -666,48 +684,50 @@ const getMultilineFillColorClasses = (theme = 'blue', customTheme) => {
|
|
|
666
684
|
}
|
|
667
685
|
return multilineFillColorClasses;
|
|
668
686
|
};
|
|
669
|
-
const getMultilineFillClasses = (theme =
|
|
670
|
-
let multilineFillColorClasses = tailwindMerge.twJoin(multilineFillBaseClasses,
|
|
687
|
+
const getMultilineFillClasses = (theme = "blue", customTheme) => {
|
|
688
|
+
let multilineFillColorClasses = tailwindMerge.twJoin(multilineFillBaseClasses, "from-(--theme-color)/0 to-(--theme-color)/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size,background-image,color] focus-visible:from-(--theme-color) focus-visible:to-(--theme-color) focus-visible:bg-[size:100%_100%] active:from-(--theme-color) active:to-(--theme-color) active:bg-[size:100%_100%] contrast-more:from-(--theme-color)/0 pointer-fine:hover:from-(--theme-color) pointer-fine:hover:to-(--theme-color) pointer-fine:hover:bg-[size:100%_100%]");
|
|
671
689
|
switch (theme) {
|
|
672
|
-
case
|
|
673
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
690
|
+
case "blue":
|
|
691
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-blue)]");
|
|
674
692
|
break;
|
|
675
|
-
case
|
|
676
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
693
|
+
case "brown":
|
|
694
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-brown)]");
|
|
677
695
|
break;
|
|
678
|
-
case
|
|
679
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
696
|
+
case "green":
|
|
697
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-green)]");
|
|
680
698
|
break;
|
|
681
|
-
case
|
|
682
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
699
|
+
case "grey":
|
|
700
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-grey)]");
|
|
683
701
|
break;
|
|
684
|
-
case
|
|
685
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
702
|
+
case "sky-blue":
|
|
703
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-sky-blue)]");
|
|
686
704
|
break;
|
|
687
|
-
case
|
|
688
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
705
|
+
case "magenta":
|
|
706
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-magenta)]");
|
|
689
707
|
break;
|
|
690
|
-
case
|
|
691
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
708
|
+
case "orange":
|
|
709
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-orange)]");
|
|
692
710
|
break;
|
|
693
|
-
case
|
|
694
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
711
|
+
case "pink":
|
|
712
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-pink)]");
|
|
695
713
|
break;
|
|
696
|
-
case
|
|
697
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
714
|
+
case "purple":
|
|
715
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-purple)]");
|
|
698
716
|
break;
|
|
699
|
-
case
|
|
700
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
717
|
+
case "red":
|
|
718
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-red)]");
|
|
701
719
|
break;
|
|
702
|
-
case
|
|
703
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
720
|
+
case "violet":
|
|
721
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-violet)]");
|
|
704
722
|
break;
|
|
705
|
-
case
|
|
706
|
-
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses,
|
|
723
|
+
case "yellow":
|
|
724
|
+
multilineFillColorClasses = tailwindMerge.twJoin(multilineFillColorClasses, "[--theme-color:var(--color-ui-yellow)]");
|
|
707
725
|
break;
|
|
708
|
-
case
|
|
709
|
-
if (customTheme && customTheme.themeColor &&
|
|
710
|
-
|
|
726
|
+
case "custom":
|
|
727
|
+
if (customTheme && customTheme.themeColor &&
|
|
728
|
+
!customTheme.themeColor.includes("[--theme-color:")) {
|
|
729
|
+
throw new Error("`customTheme.themeColor` must modify the `--theme-color` variable. Otherwise, please use `customTheme.classes`.");
|
|
730
|
+
}
|
|
711
731
|
multilineFillColorClasses = customTheme.themeColor
|
|
712
732
|
? twMerge(multilineFillColorClasses, customTheme.themeColor)
|
|
713
733
|
: twMerge(multilineFillBaseClasses, customTheme.classes);
|
|
@@ -715,18 +735,76 @@ const getMultilineFillClasses = (theme = 'blue', customTheme) => {
|
|
|
715
735
|
}
|
|
716
736
|
return multilineFillColorClasses;
|
|
717
737
|
};
|
|
718
|
-
const getMultilineFillLiftClasses = (theme =
|
|
719
|
-
return tailwindMerge.twJoin(getMultilineFillColorClasses(theme, customTheme),
|
|
738
|
+
const getMultilineFillLiftClasses = (theme = "blue", customTheme) => {
|
|
739
|
+
return tailwindMerge.twJoin(getMultilineFillColorClasses(theme, customTheme), "bg-[size:auto_0px] bg-[position:50%_100%] focus-visible:bg-[size:auto_100%] active:bg-[size:auto_100%] pointer-fine:hover:bg-[size:auto_100%]");
|
|
720
740
|
};
|
|
721
|
-
const getMultilineFillXClasses = (theme =
|
|
722
|
-
return tailwindMerge.twJoin(getMultilineFillColorClasses(theme, customTheme),
|
|
741
|
+
const getMultilineFillXClasses = (theme = "blue", customTheme) => {
|
|
742
|
+
return tailwindMerge.twJoin(getMultilineFillColorClasses(theme, customTheme), "bg-[size:0%_100%] focus-visible:bg-[size:100%_100%] active:bg-[size:100%_100%] pointer-fine:hover:bg-[size:100%_100%]");
|
|
723
743
|
};
|
|
724
|
-
const getMultilineFillRtlClasses = (theme =
|
|
725
|
-
return tailwindMerge.twJoin(getMultilineFillXClasses(theme, customTheme),
|
|
744
|
+
const getMultilineFillRtlClasses = (theme = "blue", customTheme) => {
|
|
745
|
+
return tailwindMerge.twJoin(getMultilineFillXClasses(theme, customTheme), "bg-[position:100%_auto]");
|
|
726
746
|
};
|
|
727
|
-
const getMultilineFillCenterClasses = (theme =
|
|
728
|
-
return tailwindMerge.twJoin(getMultilineFillXClasses(theme, customTheme),
|
|
747
|
+
const getMultilineFillCenterClasses = (theme = "blue", customTheme) => {
|
|
748
|
+
return tailwindMerge.twJoin(getMultilineFillXClasses(theme, customTheme), "bg-[position:50%_auto]");
|
|
729
749
|
};
|
|
750
|
+
function getLinkClasses({ customTheme, theme, type }) {
|
|
751
|
+
switch (type) {
|
|
752
|
+
case "static":
|
|
753
|
+
return lineStaticClasses;
|
|
754
|
+
case "ltr":
|
|
755
|
+
return lineLtrClasses;
|
|
756
|
+
case "rtl":
|
|
757
|
+
return lineRtlClasses;
|
|
758
|
+
case "center":
|
|
759
|
+
return lineCenterClasses;
|
|
760
|
+
case "lift":
|
|
761
|
+
return lineLiftClasses;
|
|
762
|
+
case "fill":
|
|
763
|
+
return getFillCenterClasses(theme, customTheme);
|
|
764
|
+
case "fill-ltr":
|
|
765
|
+
return tailwindMerge.twJoin([
|
|
766
|
+
getFillColorTransitionClasses(theme, customTheme),
|
|
767
|
+
scaleXClasses,
|
|
768
|
+
"after:origin-left",
|
|
769
|
+
]);
|
|
770
|
+
case "fill-rtl":
|
|
771
|
+
return tailwindMerge.twJoin([
|
|
772
|
+
getFillColorTransitionClasses(theme, customTheme),
|
|
773
|
+
scaleXClasses,
|
|
774
|
+
"after:origin-right",
|
|
775
|
+
]);
|
|
776
|
+
case "fill-lift":
|
|
777
|
+
return tailwindMerge.twJoin([
|
|
778
|
+
getFillColorTransitionClasses(theme, customTheme),
|
|
779
|
+
scaleYClasses,
|
|
780
|
+
"after:origin-bottom",
|
|
781
|
+
]);
|
|
782
|
+
case "multiline":
|
|
783
|
+
return multilineNormalClasses;
|
|
784
|
+
case "multiline-static":
|
|
785
|
+
return multilineLineStaticClasses;
|
|
786
|
+
case "multiline-ltr":
|
|
787
|
+
return multilineXClasses;
|
|
788
|
+
case "multiline-rtl":
|
|
789
|
+
return multilineLineRtlClasses;
|
|
790
|
+
case "multiline-center":
|
|
791
|
+
return multilineLineCenterClasses;
|
|
792
|
+
case "multiline-lift":
|
|
793
|
+
return multilineLineLiftClasses;
|
|
794
|
+
case "multiline-fill":
|
|
795
|
+
return getMultilineFillClasses(theme, customTheme);
|
|
796
|
+
case "multiline-fill-ltr":
|
|
797
|
+
return getMultilineFillXClasses(theme, customTheme);
|
|
798
|
+
case "multiline-fill-rtl":
|
|
799
|
+
return getMultilineFillRtlClasses(theme, customTheme);
|
|
800
|
+
case "multiline-fill-center":
|
|
801
|
+
return getMultilineFillCenterClasses(theme, customTheme);
|
|
802
|
+
case "multiline-fill-lift":
|
|
803
|
+
return getMultilineFillLiftClasses(theme, customTheme);
|
|
804
|
+
default:
|
|
805
|
+
return lineNormalClasses;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
730
808
|
/**
|
|
731
809
|
* # Link
|
|
732
810
|
*
|
|
@@ -756,54 +834,8 @@ const getMultilineFillCenterClasses = (theme = 'blue', customTheme) => {
|
|
|
756
834
|
* @example
|
|
757
835
|
* <Link href='/about' type='fill-ltr' theme='red' title='About Us'>Learn more about our company</Link>
|
|
758
836
|
*/
|
|
759
|
-
function Link({ as, className, customTheme, theme =
|
|
760
|
-
const
|
|
761
|
-
switch (type) {
|
|
762
|
-
case 'static':
|
|
763
|
-
return lineStaticClasses;
|
|
764
|
-
case 'ltr':
|
|
765
|
-
return lineLtrClasses;
|
|
766
|
-
case 'rtl':
|
|
767
|
-
return lineRtlClasses;
|
|
768
|
-
case 'center':
|
|
769
|
-
return lineCenterClasses;
|
|
770
|
-
case 'lift':
|
|
771
|
-
return lineLiftClasses;
|
|
772
|
-
case 'fill':
|
|
773
|
-
return getFillCenterClasses(theme, customTheme);
|
|
774
|
-
case 'fill-ltr':
|
|
775
|
-
return tailwindMerge.twJoin([getFillColorTransitionClasses(theme, customTheme), scaleXClasses, 'after:origin-left']);
|
|
776
|
-
case 'fill-rtl':
|
|
777
|
-
return tailwindMerge.twJoin([getFillColorTransitionClasses(theme, customTheme), scaleXClasses, 'after:origin-right']);
|
|
778
|
-
case 'fill-lift':
|
|
779
|
-
return tailwindMerge.twJoin([getFillColorTransitionClasses(theme, customTheme), scaleYClasses, 'after:origin-bottom']);
|
|
780
|
-
case 'multiline':
|
|
781
|
-
return multilineNormalClasses;
|
|
782
|
-
case 'multiline-static':
|
|
783
|
-
return multilineLineStaticClasses;
|
|
784
|
-
case 'multiline-ltr':
|
|
785
|
-
return multilineXClasses;
|
|
786
|
-
case 'multiline-rtl':
|
|
787
|
-
return multilineLineRtlClasses;
|
|
788
|
-
case 'multiline-center':
|
|
789
|
-
return multilineLineCenterClasses;
|
|
790
|
-
case 'multiline-lift':
|
|
791
|
-
return multilineLineLiftClasses;
|
|
792
|
-
case 'multiline-fill':
|
|
793
|
-
return getMultilineFillClasses(theme, customTheme);
|
|
794
|
-
case 'multiline-fill-ltr':
|
|
795
|
-
return getMultilineFillXClasses(theme, customTheme);
|
|
796
|
-
case 'multiline-fill-rtl':
|
|
797
|
-
return getMultilineFillRtlClasses(theme, customTheme);
|
|
798
|
-
case 'multiline-fill-center':
|
|
799
|
-
return getMultilineFillCenterClasses(theme, customTheme);
|
|
800
|
-
case 'multiline-fill-lift':
|
|
801
|
-
return getMultilineFillLiftClasses(theme, customTheme);
|
|
802
|
-
default:
|
|
803
|
-
return lineNormalClasses;
|
|
804
|
-
}
|
|
805
|
-
};
|
|
806
|
-
const linkClasses = getLinkClasses();
|
|
837
|
+
function Link({ as, className, customTheme, theme = "blue", type, ...props }) {
|
|
838
|
+
const linkClasses = getLinkClasses({ customTheme, theme, type });
|
|
807
839
|
const LinkElement = as || Anchor;
|
|
808
840
|
return jsxRuntime.jsx(LinkElement, { ...props, className: twMerge(linkClasses, className) });
|
|
809
841
|
}
|
|
@@ -834,7 +866,9 @@ function Link({ as, className, customTheme, theme = 'blue', type, ...props }) {
|
|
|
834
866
|
*/
|
|
835
867
|
function createLink(config) {
|
|
836
868
|
return function ExtendedLink({ theme, className, customTheme, type, as, ...props }) {
|
|
837
|
-
const finalType = type !== undefined
|
|
869
|
+
const finalType = type !== undefined
|
|
870
|
+
? type
|
|
871
|
+
: config.type, finalTheme = theme !== undefined ? theme : config.defaultTheme;
|
|
838
872
|
const configClassName = config.className;
|
|
839
873
|
const shouldOverrideElement = !Boolean(as) && Boolean(config.as);
|
|
840
874
|
const linkProps = {
|
|
@@ -849,13 +883,17 @@ function createLink(config) {
|
|
|
849
883
|
else if (as) {
|
|
850
884
|
linkProps.as = as;
|
|
851
885
|
}
|
|
852
|
-
if (finalTheme && typeof finalTheme ===
|
|
886
|
+
if (finalTheme && typeof finalTheme === "string" && config.theme &&
|
|
887
|
+
finalTheme in config.theme) {
|
|
853
888
|
const extendedTheme = config.theme[finalTheme];
|
|
854
|
-
if (customTheme)
|
|
855
|
-
return (jsxRuntime.jsx(Link, { ...linkProps, theme:
|
|
889
|
+
if (customTheme) {
|
|
890
|
+
return (jsxRuntime.jsx(Link, { ...linkProps, theme: "custom", customTheme: customTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
|
|
891
|
+
}
|
|
856
892
|
let resolvedCustomTheme;
|
|
857
893
|
if (extendedTheme.customTheme.themeColor) {
|
|
858
|
-
const isMultilineType = finalType
|
|
894
|
+
const isMultilineType = finalType
|
|
895
|
+
? finalType.includes("multiline")
|
|
896
|
+
: false;
|
|
859
897
|
resolvedCustomTheme = {
|
|
860
898
|
themeColor: isMultilineType
|
|
861
899
|
? extendedTheme.customTheme.themeColor.multilineFill
|
|
@@ -867,7 +905,7 @@ function createLink(config) {
|
|
|
867
905
|
classes: extendedTheme.customTheme.classes,
|
|
868
906
|
};
|
|
869
907
|
}
|
|
870
|
-
return (jsxRuntime.jsx(Link, { ...linkProps, theme:
|
|
908
|
+
return (jsxRuntime.jsx(Link, { ...linkProps, theme: "custom", customTheme: resolvedCustomTheme, className: twMerge(configClassName, extendedTheme.className, className) }));
|
|
871
909
|
}
|
|
872
910
|
return (jsxRuntime.jsx(Link, { ...linkProps, theme: finalTheme, className: twMerge(configClassName, className), customTheme: customTheme }));
|
|
873
911
|
};
|
|
@@ -1141,32 +1179,44 @@ function Details({ as = 'div', className, ...props }) {
|
|
|
1141
1179
|
}
|
|
1142
1180
|
|
|
1143
1181
|
function DropDownButton({ arrow = true, as, children, className, ...props }) {
|
|
1144
|
-
return (jsxRuntime.jsxs(react.MenuButton, { ...props, as: as ||
|
|
1145
|
-
(typeof arrow ===
|
|
1182
|
+
return (jsxRuntime.jsxs(react.MenuButton, { ...props, as: as || "button", className: tailwindMerge.twJoin("group/button", className), children: [children, arrow &&
|
|
1183
|
+
(typeof arrow === "boolean"
|
|
1184
|
+
? (jsxRuntime.jsx(ChevronDown, { className: "-top-px -mr-1 ml-2 w-4 animate-flip-again group-data-open/button:animate-flip" }))
|
|
1185
|
+
: arrow)] }));
|
|
1146
1186
|
}
|
|
1147
1187
|
function DropDownItem({ as, ...props }) {
|
|
1148
|
-
return jsxRuntime.jsx(react.MenuItem, { ...props, as: as ||
|
|
1188
|
+
return jsxRuntime.jsx(react.MenuItem, { ...props, as: as || "div" });
|
|
1149
1189
|
}
|
|
1150
1190
|
function DropDownItems({ anchor, children, className, containerClassName, style, ...props }) {
|
|
1151
1191
|
const getAnchorProps = () => {
|
|
1152
|
-
let initialAnchor = {
|
|
1192
|
+
let initialAnchor = {
|
|
1193
|
+
gap: "1rem",
|
|
1194
|
+
padding: "1rem",
|
|
1195
|
+
to: "bottom start",
|
|
1196
|
+
};
|
|
1153
1197
|
if (anchor) {
|
|
1154
|
-
if (typeof anchor ===
|
|
1198
|
+
if (typeof anchor === "string")
|
|
1155
1199
|
initialAnchor.to = anchor;
|
|
1156
|
-
if (typeof anchor ===
|
|
1200
|
+
if (typeof anchor === "object") {
|
|
1157
1201
|
initialAnchor = { ...initialAnchor, ...anchor };
|
|
1202
|
+
}
|
|
1158
1203
|
}
|
|
1159
1204
|
return initialAnchor;
|
|
1160
1205
|
};
|
|
1161
1206
|
const anchorProps = getAnchorProps();
|
|
1162
|
-
return (jsxRuntime.jsx(react.MenuItems, { ...props, anchor: anchorProps, className: twMerge(
|
|
1207
|
+
return (jsxRuntime.jsx(react.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) => (jsxRuntime.jsx("div", { className: "overflow-y-scroll", children: jsxRuntime.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 }) })) }));
|
|
1163
1208
|
}
|
|
1164
1209
|
function DropDownSection({ children, label, labelProps, separatorAbove, separatorBelow, ...props }) {
|
|
1165
|
-
const { labelClassName, ...restLabelProps } = {
|
|
1166
|
-
|
|
1210
|
+
const { labelClassName, ...restLabelProps } = {
|
|
1211
|
+
labelClassName: labelProps?.className || "",
|
|
1212
|
+
...labelProps,
|
|
1213
|
+
};
|
|
1214
|
+
return (jsxRuntime.jsx(react.MenuSection, { ...props, children: (sectionBag) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [separatorAbove && jsxRuntime.jsx(DropDownSeparator, {}), label && (jsxRuntime.jsx(react.MenuHeading, { ...restLabelProps, className: (headingBag) => twMerge("text-[larger] font-bold text-current/80", typeof labelClassName === "function"
|
|
1215
|
+
? labelClassName(headingBag)
|
|
1216
|
+
: labelClassName), children: label })), typeof children === "function" ? children(sectionBag) : children, separatorBelow && jsxRuntime.jsx(DropDownSeparator, {})] })) }));
|
|
1167
1217
|
}
|
|
1168
1218
|
function DropDownSeparator({ as, className, ...props }) {
|
|
1169
|
-
return (jsxRuntime.jsx(react.MenuSeparator, { ...props, as: as ||
|
|
1219
|
+
return (jsxRuntime.jsx(react.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) }));
|
|
1170
1220
|
}
|
|
1171
1221
|
function DropDown(props) {
|
|
1172
1222
|
return jsxRuntime.jsx(react.Menu, { ...props });
|
|
@@ -3480,19 +3530,20 @@ const arrow = (options, deps) => ({
|
|
|
3480
3530
|
|
|
3481
3531
|
function TooltipTrigger({ as, asChild = false, children, ...props }) {
|
|
3482
3532
|
const TooltipTriggerElement = as || react.Button;
|
|
3483
|
-
if (asChild && React.isValidElement(children))
|
|
3533
|
+
if (asChild && React.isValidElement(children)) {
|
|
3484
3534
|
return React.cloneElement(children, props);
|
|
3535
|
+
}
|
|
3485
3536
|
return jsxRuntime.jsx(TooltipTriggerElement, { ...props, children: children });
|
|
3486
3537
|
}
|
|
3487
3538
|
function TooltipPanel({ as, children, className, style, ...props }) {
|
|
3488
|
-
const TooltipPanelElement = as ||
|
|
3489
|
-
return (jsxRuntime.jsx(TooltipPanelElement, { ...props, className: twMerge(
|
|
3539
|
+
const TooltipPanelElement = as || "div";
|
|
3540
|
+
return (jsxRuntime.jsx(TooltipPanelElement, { ...props, className: twMerge("absolute top-0 left-0 z-50 w-max rounded-md bg-neutral-50 px-2 py-1 text-sm text-neutral-950 opacity-0 shadow-lg outline-1 outline-neutral-400 data-portal:fixed data-ready:animate-fade-in dark:bg-neutral-800 dark:text-neutral-50 dark:shadow-none dark:-outline-offset-1 dark:outline-neutral-600", className), style: style, children: children }));
|
|
3490
3541
|
}
|
|
3491
|
-
function Tooltip({ anchor =
|
|
3542
|
+
function Tooltip({ anchor = "top", arrow: arrow$1, arrowClassName, children, delay = 500, offset: offset$1 = 8, onClose, onOpen, portal, }) {
|
|
3492
3543
|
const [isOpen, setIsOpen] = React.useState(false), timeoutRef = React.useRef(undefined), arrowRef = React.useRef(null);
|
|
3493
|
-
const [bodyElement, setBodyElement] = React.useState(() => typeof window !==
|
|
3544
|
+
const [bodyElement, setBodyElement] = React.useState(() => typeof window !== "undefined" ? document.body : null);
|
|
3494
3545
|
React.useEffect(() => {
|
|
3495
|
-
if (typeof window !==
|
|
3546
|
+
if (typeof window !== "undefined" && !bodyElement) {
|
|
3496
3547
|
const documentBody = document.body;
|
|
3497
3548
|
setBodyElement(documentBody);
|
|
3498
3549
|
}
|
|
@@ -3509,10 +3560,12 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3509
3560
|
elements.floating.style.maxWidth = width;
|
|
3510
3561
|
},
|
|
3511
3562
|
}),
|
|
3512
|
-
...(arrowRef.current
|
|
3563
|
+
...(arrowRef.current
|
|
3564
|
+
? [arrow({ element: arrowRef.current })]
|
|
3565
|
+
: []),
|
|
3513
3566
|
],
|
|
3514
3567
|
placement: anchor,
|
|
3515
|
-
strategy: portal ?
|
|
3568
|
+
strategy: portal ? "fixed" : "absolute",
|
|
3516
3569
|
whileElementsMounted: autoUpdate,
|
|
3517
3570
|
open: isOpen,
|
|
3518
3571
|
});
|
|
@@ -3539,37 +3592,41 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3539
3592
|
clearTimeout(timeoutRef.current);
|
|
3540
3593
|
};
|
|
3541
3594
|
}, []);
|
|
3542
|
-
const content = typeof children ===
|
|
3595
|
+
const content = typeof children === "function"
|
|
3596
|
+
? children({ openTooltip, closeTooltip })
|
|
3597
|
+
: children;
|
|
3543
3598
|
const triggerElement = findComponentByType(content, TooltipTrigger), contentElement = findComponentByType(content, TooltipPanel);
|
|
3544
|
-
if (!contentElement)
|
|
3545
|
-
throw new Error(
|
|
3546
|
-
|
|
3547
|
-
|
|
3599
|
+
if (!contentElement) {
|
|
3600
|
+
throw new Error("TooltipPanel must be defined in Tooltip children");
|
|
3601
|
+
}
|
|
3602
|
+
if (!triggerElement && typeof children !== "function") {
|
|
3603
|
+
throw new Error("TooltipTrigger must be provided when not using render prop pattern");
|
|
3604
|
+
}
|
|
3548
3605
|
const arrowStyles = {};
|
|
3549
3606
|
const reversedAnchor = {
|
|
3550
|
-
top:
|
|
3551
|
-
right:
|
|
3552
|
-
bottom:
|
|
3553
|
-
left:
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3607
|
+
top: "bottom",
|
|
3608
|
+
right: "left",
|
|
3609
|
+
bottom: "top",
|
|
3610
|
+
left: "right",
|
|
3611
|
+
"top-start": "bottom left",
|
|
3612
|
+
"top-end": "bottom right",
|
|
3613
|
+
"right-start": "top left",
|
|
3614
|
+
"right-end": "bottom left",
|
|
3615
|
+
"bottom-start": "top left",
|
|
3616
|
+
"bottom-end": "top right",
|
|
3617
|
+
"left-start": "top right",
|
|
3618
|
+
"left-end": "bottom right",
|
|
3562
3619
|
}[placement];
|
|
3563
3620
|
if (middlewareData.arrow && arrow$1) {
|
|
3564
3621
|
const { x, y } = middlewareData.arrow;
|
|
3565
3622
|
const staticSide = {
|
|
3566
|
-
top:
|
|
3567
|
-
right:
|
|
3568
|
-
bottom:
|
|
3569
|
-
left:
|
|
3570
|
-
}[placement.split(
|
|
3623
|
+
top: "bottom",
|
|
3624
|
+
right: "left",
|
|
3625
|
+
bottom: "top",
|
|
3626
|
+
left: "right",
|
|
3627
|
+
}[placement.split("-")[0]];
|
|
3571
3628
|
if (staticSide) {
|
|
3572
|
-
arrowStyles[staticSide] =
|
|
3629
|
+
arrowStyles[staticSide] = "-4px";
|
|
3573
3630
|
if (x != null)
|
|
3574
3631
|
arrowStyles.left = `${x}px`;
|
|
3575
3632
|
if (y != null)
|
|
@@ -3578,68 +3635,68 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3578
3635
|
}
|
|
3579
3636
|
const getArrowLocationClasses = () => {
|
|
3580
3637
|
switch (placement) {
|
|
3581
|
-
case
|
|
3582
|
-
case
|
|
3583
|
-
case
|
|
3584
|
-
return
|
|
3585
|
-
case
|
|
3586
|
-
case
|
|
3587
|
-
case
|
|
3588
|
-
return
|
|
3589
|
-
case
|
|
3590
|
-
case
|
|
3591
|
-
case
|
|
3592
|
-
return
|
|
3593
|
-
case
|
|
3594
|
-
case
|
|
3595
|
-
case
|
|
3596
|
-
return
|
|
3638
|
+
case "bottom":
|
|
3639
|
+
case "bottom-end":
|
|
3640
|
+
case "bottom-start":
|
|
3641
|
+
return "-translate-y-1";
|
|
3642
|
+
case "top":
|
|
3643
|
+
case "top-end":
|
|
3644
|
+
case "top-start":
|
|
3645
|
+
return "rotate-180 translate-y-1";
|
|
3646
|
+
case "left":
|
|
3647
|
+
case "left-end":
|
|
3648
|
+
case "left-start":
|
|
3649
|
+
return "rotate-90 translate-x-2";
|
|
3650
|
+
case "right":
|
|
3651
|
+
case "right-end":
|
|
3652
|
+
case "right-start":
|
|
3653
|
+
return "-rotate-90 -translate-x-2";
|
|
3597
3654
|
}
|
|
3598
3655
|
};
|
|
3599
3656
|
const arrowLocationClasses = getArrowLocationClasses();
|
|
3600
|
-
const handleMouseEnter = e => {
|
|
3657
|
+
const handleMouseEnter = (e) => {
|
|
3601
3658
|
openTooltip();
|
|
3602
3659
|
triggerElement?.props.onMouseEnter?.(e);
|
|
3603
3660
|
};
|
|
3604
|
-
const handleMouseLeave = e => {
|
|
3661
|
+
const handleMouseLeave = (e) => {
|
|
3605
3662
|
triggerElement?.props.onMouseLeave?.(e);
|
|
3606
3663
|
closeTooltip();
|
|
3607
3664
|
};
|
|
3608
|
-
const handleTouchStart = e => {
|
|
3665
|
+
const handleTouchStart = (e) => {
|
|
3609
3666
|
openTooltip();
|
|
3610
3667
|
triggerElement?.props.onTouchStart?.(e);
|
|
3611
3668
|
};
|
|
3612
|
-
const handleFocus = e => {
|
|
3669
|
+
const handleFocus = (e) => {
|
|
3613
3670
|
triggerElement?.props.onFocus?.(e);
|
|
3614
3671
|
openTooltip();
|
|
3615
3672
|
};
|
|
3616
|
-
const handleBlur = e => {
|
|
3673
|
+
const handleBlur = (e) => {
|
|
3617
3674
|
triggerElement?.props.onBlur?.(e);
|
|
3618
3675
|
closeTooltip();
|
|
3619
3676
|
};
|
|
3620
3677
|
const tooltipContent = (jsxRuntime.jsx(jsxRuntime.Fragment, { children: isOpen &&
|
|
3621
3678
|
contentElement &&
|
|
3622
3679
|
React.cloneElement(contentElement, {
|
|
3623
|
-
children: (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [contentElement.props.children, arrow$1 && (jsxRuntime.jsx(ArrowSvg, { className: twMerge(
|
|
3624
|
-
...(portal ? {
|
|
3625
|
-
...(isPositioned ? {
|
|
3680
|
+
children: (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [contentElement.props.children, arrow$1 && (jsxRuntime.jsx(ArrowSvg, { className: twMerge("absolute", arrowLocationClasses, arrowClassName), style: arrowStyles, "data-tooltip-arrow": true }))] })),
|
|
3681
|
+
...(portal ? { "data-portal": true } : {}),
|
|
3682
|
+
...(isPositioned ? { "data-ready": true } : {}),
|
|
3626
3683
|
onMouseEnter: openTooltip,
|
|
3627
3684
|
onMouseLeave: closeTooltip,
|
|
3628
3685
|
onTouchStart: handleTouchStart,
|
|
3629
3686
|
ref: (node) => {
|
|
3630
3687
|
refs.setFloating(node);
|
|
3631
3688
|
if (node && arrow$1) {
|
|
3632
|
-
const arrowElement = node.querySelector(
|
|
3689
|
+
const arrowElement = node.querySelector("[data-tooltip-arrow]");
|
|
3633
3690
|
if (arrowElement)
|
|
3634
3691
|
arrowRef.current = arrowElement;
|
|
3635
3692
|
}
|
|
3636
3693
|
},
|
|
3637
|
-
role:
|
|
3694
|
+
role: "tooltip",
|
|
3638
3695
|
style: {
|
|
3639
3696
|
...contentElement.props.style,
|
|
3640
3697
|
...floatingStyles,
|
|
3641
3698
|
transformOrigin: reversedAnchor,
|
|
3642
|
-
pointerEvents:
|
|
3699
|
+
pointerEvents: "none",
|
|
3643
3700
|
},
|
|
3644
3701
|
}) }));
|
|
3645
3702
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [triggerElement &&
|
|
@@ -3649,310 +3706,55 @@ function Tooltip({ anchor = 'top', arrow: arrow$1, arrowClassName, children, del
|
|
|
3649
3706
|
onMouseLeave: handleMouseLeave,
|
|
3650
3707
|
onFocus: handleFocus,
|
|
3651
3708
|
onBlur: handleBlur,
|
|
3652
|
-
|
|
3653
|
-
}), portal
|
|
3709
|
+
"aria-describedby": isOpen ? "tooltip" : undefined,
|
|
3710
|
+
}), portal
|
|
3711
|
+
? bodyElement && ReactDOM.createPortal(tooltipContent, bodyElement)
|
|
3712
|
+
: tooltipContent] }));
|
|
3654
3713
|
}
|
|
3655
3714
|
function ArrowSvg({ className, ...props }) {
|
|
3656
|
-
return (jsxRuntime.jsxs("svg", { viewBox:
|
|
3715
|
+
return (jsxRuntime.jsxs("svg", { viewBox: "0 0 20 10", className: twMerge("h-2.5 w-5 fill-none", className), ...props, children: [jsxRuntime.jsx("path", { d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z", className: "fill-neutral-50 dark:fill-neutral-800" }), jsxRuntime.jsx("path", { d: "M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z", className: "fill-neutral-400 dark:fill-none" }), jsxRuntime.jsx("path", { d: "M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z", className: "dark:fill-neutral-600" })] }));
|
|
3657
3716
|
}
|
|
3658
3717
|
|
|
3659
3718
|
const specialCharacterRegex = new RegExp(/[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~€‚ƒ„…†‡‰‹‘’“”•–—™›¡¢£¥§©«¬®°±¶º»¿×÷]/);
|
|
3660
|
-
function
|
|
3661
|
-
const [formContext] = useFormContext(), [fieldsetContext] = useFieldsetContext();
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
const VALIDATION_HANDLERS = {
|
|
3671
|
-
email: ({ multiple, value }) => {
|
|
3672
|
-
if (multiple) {
|
|
3673
|
-
const emailList = value.split(',').map(item => item.trim()), notEmailList = [];
|
|
3674
|
-
emailList.forEach(item => {
|
|
3675
|
-
if (!isEmail(item))
|
|
3676
|
-
notEmailList.push(item);
|
|
3677
|
-
});
|
|
3678
|
-
if (notEmailList.length > 0) {
|
|
3679
|
-
const multipleInvalid = notEmailList.length > 1;
|
|
3680
|
-
return `${multipleInvalid ? 'These email addresses are' : 'This email address is'} invalid: ${notEmailList.join(', ')}`;
|
|
3681
|
-
}
|
|
3682
|
-
return;
|
|
3683
|
-
}
|
|
3684
|
-
if (!isEmail(value))
|
|
3685
|
-
return 'This is not a valid email address.';
|
|
3686
|
-
},
|
|
3687
|
-
password: ({ value }) => {
|
|
3688
|
-
const errorMessageList = [];
|
|
3689
|
-
if (options) {
|
|
3690
|
-
const { matchPreviousInput, requireLowercaseCharacter, requireNumber, requireSpecialCharacter, requireUppercaseCharacter, } = options;
|
|
3691
|
-
if (matchPreviousInput && formContext && formContext.length >= 2) {
|
|
3692
|
-
if (isInFieldset && fieldsetContext.fieldList.length > 1) {
|
|
3693
|
-
const currentInputIndex = fieldsetContext.fieldList.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3694
|
-
if (currentInputIndex > 0) {
|
|
3695
|
-
const previousInput = fieldsetContext.fieldList.find((_, index) => index === currentInputIndex - 1);
|
|
3696
|
-
if (previousInput &&
|
|
3697
|
-
isStringField(previousInput) &&
|
|
3698
|
-
previousInput.value !== value)
|
|
3699
|
-
errorMessageList.push('Passwords must match.');
|
|
3700
|
-
}
|
|
3701
|
-
}
|
|
3702
|
-
else {
|
|
3703
|
-
const currentInputIndex = formContext.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3704
|
-
if (currentInputIndex > 0) {
|
|
3705
|
-
const previousInput = formContext.find((_, index) => index === currentInputIndex - 1);
|
|
3706
|
-
if (previousInput &&
|
|
3707
|
-
isStringField(previousInput) &&
|
|
3708
|
-
previousInput.value !== value)
|
|
3709
|
-
errorMessageList.push('Passwords must match.');
|
|
3710
|
-
}
|
|
3711
|
-
}
|
|
3712
|
-
}
|
|
3713
|
-
if (requireLowercaseCharacter && !/[a-z]/g.test(value))
|
|
3714
|
-
errorMessageList.push('You must include a lowercase character.');
|
|
3715
|
-
if (requireNumber && !/[0-9]/g.test(value))
|
|
3716
|
-
errorMessageList.push('You must include a number.');
|
|
3717
|
-
if (requireSpecialCharacter && !specialCharacterRegex.test(value))
|
|
3718
|
-
errorMessageList.push('You must include a special character.');
|
|
3719
|
-
if (requireUppercaseCharacter && !/[A-Z]/g.test(value))
|
|
3720
|
-
errorMessageList.push('You must include an uppercase character.');
|
|
3721
|
-
}
|
|
3722
|
-
return errorMessageList.length > 0 ? errorMessageList.join(' ') : undefined;
|
|
3723
|
-
},
|
|
3724
|
-
tel: ({ value }) => {
|
|
3725
|
-
if (!isPhoneNumber(value))
|
|
3726
|
-
return 'This is not a valid phone number.';
|
|
3727
|
-
},
|
|
3728
|
-
};
|
|
3729
|
-
const onChange = e => {
|
|
3730
|
-
const validation = type ? VALIDATION_HANDLERS[type] : undefined;
|
|
3731
|
-
handleChange({ e, validation });
|
|
3732
|
-
};
|
|
3733
|
-
const onBlur = e => {
|
|
3734
|
-
const format = type ? FORMAT_FUNCTIONS[type] : undefined, validation = type ? VALIDATION_HANDLERS[type] : undefined;
|
|
3735
|
-
handleBlur({ e, format, validation });
|
|
3736
|
-
};
|
|
3737
|
-
return (jsxRuntime.jsx(react.Input, { ...props, className: bag => twMerge(
|
|
3738
|
-
// Base styles
|
|
3739
|
-
'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',
|
|
3740
|
-
// Pseudo styles
|
|
3741
|
-
'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',
|
|
3742
|
-
// user-invalid styles
|
|
3743
|
-
'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))]',
|
|
3744
|
-
// Custom styles
|
|
3745
|
-
typeof className === 'function' ? className(bag) : className), onBlur: onBlur, onChange: onChange, placeholder: placeholder, type: type, value: fieldContext?.value || '' }));
|
|
3746
|
-
}
|
|
3747
|
-
|
|
3748
|
-
function DateTimeInput({ className, fieldContextID, handleBlur, handleChange, ref, theme, type, ui, ...props }) {
|
|
3749
|
-
const [formContext] = useFormContext(), [fieldsetContext] = useFieldsetContext();
|
|
3719
|
+
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 }) {
|
|
3720
|
+
const [formContext, formContextFunctions] = useFormContext(), [fieldsetContext, fieldsetContextFunctions] = useFieldsetContext(), [errorMessage, setErrorMessage] = React.useState(undefined);
|
|
3721
|
+
if (type === "password" && !placeholder) {
|
|
3722
|
+
placeholder = "••••••••" + (required && !label ? "*" : "");
|
|
3723
|
+
}
|
|
3724
|
+
if (placeholder === "*")
|
|
3725
|
+
placeholder = name + (required && !label ? "*" : "");
|
|
3726
|
+
if (label === "*")
|
|
3727
|
+
label = name;
|
|
3728
|
+
const uniqueID = React.useId(), fieldContextID = toLowerCase(name, [, "_"]) + "§" + uniqueID;
|
|
3750
3729
|
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
3751
|
-
const
|
|
3752
|
-
if (!ui)
|
|
3730
|
+
const getFieldContextType = () => {
|
|
3753
3731
|
switch (type) {
|
|
3754
|
-
case
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
case
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
time: {
|
|
3767
|
-
desktop: ['clock', 'dropdown'],
|
|
3768
|
-
mobile: ['rotary', 'clock'],
|
|
3769
|
-
},
|
|
3770
|
-
};
|
|
3771
|
-
break;
|
|
3772
|
-
case 'time':
|
|
3773
|
-
ui = {
|
|
3774
|
-
desktop: ['clock', 'dropdown'],
|
|
3775
|
-
mobile: ['rotary', 'clock'],
|
|
3776
|
-
};
|
|
3777
|
-
break;
|
|
3778
|
-
}
|
|
3779
|
-
const validation = ({ max, min, value }) => {
|
|
3780
|
-
const valueAsTime = new Date(value).getTime();
|
|
3781
|
-
if (min && !(min instanceof Date) && typeof min !== 'number') {
|
|
3782
|
-
if (Array.isArray(min)) {
|
|
3783
|
-
const monthIndex = typeof min[1] === 'number' ? min[1] - 1 : getMonthIndexFromName(min[1]);
|
|
3784
|
-
min = new Date(min[0], monthIndex, min[2]);
|
|
3785
|
-
}
|
|
3786
|
-
else if ('year' in min && 'month' in min && 'day' in min) {
|
|
3787
|
-
const monthIndex = typeof min.month === 'number' ? min.month - 1 : getMonthIndexFromName(min.month);
|
|
3788
|
-
min = new Date(min.year, monthIndex, min.day);
|
|
3789
|
-
}
|
|
3790
|
-
if (valueAsTime < min.getTime())
|
|
3791
|
-
return `Value cannot be lower than ${getUserReadableDate(min)}.`;
|
|
3792
|
-
}
|
|
3793
|
-
if (max && !(max instanceof Date) && typeof max !== 'number') {
|
|
3794
|
-
if (Array.isArray(max)) {
|
|
3795
|
-
const monthIndex = typeof max[1] === 'number' ? max[1] - 1 : getMonthIndexFromName(max[1]);
|
|
3796
|
-
max = new Date(max[0], monthIndex, max[2]);
|
|
3797
|
-
}
|
|
3798
|
-
else if ('year' in max && 'month' in max && 'day' in max) {
|
|
3799
|
-
const monthIndex = typeof max.month === 'number' ? max.month - 1 : getMonthIndexFromName(max.month);
|
|
3800
|
-
max = new Date(max.year, monthIndex, max.day);
|
|
3801
|
-
}
|
|
3802
|
-
if (valueAsTime > max.getTime())
|
|
3803
|
-
return `Value cannot be higher than ${getUserReadableDate(max)}.`;
|
|
3732
|
+
case "email":
|
|
3733
|
+
return "email";
|
|
3734
|
+
case "file":
|
|
3735
|
+
return "file";
|
|
3736
|
+
case "number":
|
|
3737
|
+
return "number";
|
|
3738
|
+
case "tel":
|
|
3739
|
+
return "tel";
|
|
3740
|
+
case "url":
|
|
3741
|
+
return "url";
|
|
3742
|
+
default:
|
|
3743
|
+
return "string";
|
|
3804
3744
|
}
|
|
3805
3745
|
};
|
|
3806
|
-
const
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
const onBlur = e => {
|
|
3810
|
-
handleBlur({ e, validation });
|
|
3811
|
-
};
|
|
3812
|
-
const [selectorIsOpen, setSelectorIsOpen] = React.useState(false);
|
|
3813
|
-
const toggleSelectorOpen = () => setSelectorIsOpen(previous => !previous);
|
|
3814
|
-
const { refs, floatingStyles, isPositioned, placement, middlewareData } = useFloating({
|
|
3815
|
-
middleware: [
|
|
3816
|
-
offset(8),
|
|
3817
|
-
flip({ padding: 20 }),
|
|
3818
|
-
shift({ padding: 20 }),
|
|
3819
|
-
size({
|
|
3820
|
-
apply({ availableHeight, availableWidth, elements }) {
|
|
3821
|
-
const height = `${Math.max(0, availableHeight) / 16}rem`, width = `${Math.min(418, availableWidth) / 16}rem`;
|
|
3822
|
-
elements.floating.style.maxHeight = height;
|
|
3823
|
-
elements.floating.style.maxWidth = width;
|
|
3824
|
-
},
|
|
3825
|
-
}),
|
|
3826
|
-
],
|
|
3827
|
-
placement: 'top-start',
|
|
3828
|
-
strategy: 'fixed',
|
|
3829
|
-
whileElementsMounted: autoUpdate,
|
|
3830
|
-
open: selectorIsOpen,
|
|
3831
|
-
});
|
|
3832
|
-
const reversedAnchor = {
|
|
3833
|
-
top: 'bottom',
|
|
3834
|
-
right: 'left',
|
|
3835
|
-
bottom: 'top',
|
|
3836
|
-
left: 'right',
|
|
3837
|
-
'top-start': 'bottom left',
|
|
3838
|
-
'top-end': 'bottom right',
|
|
3839
|
-
'right-start': 'top left',
|
|
3840
|
-
'right-end': 'bottom left',
|
|
3841
|
-
'bottom-start': 'top left',
|
|
3842
|
-
'bottom-end': 'top right',
|
|
3843
|
-
'left-start': 'top right',
|
|
3844
|
-
'left-end': 'bottom right',
|
|
3845
|
-
}[placement];
|
|
3846
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(react.Input, { ...props, className: bag => twMerge(
|
|
3847
|
-
// Base styles
|
|
3848
|
-
'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',
|
|
3849
|
-
// Pseudo styles
|
|
3850
|
-
'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',
|
|
3851
|
-
// user-invalid styles
|
|
3852
|
-
'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))]',
|
|
3853
|
-
// Custom styles
|
|
3854
|
-
typeof className === 'function' ? className(bag) : className), onBlur: onBlur, onChange: onChange, onClick: toggleSelectorOpen, ref: node => {
|
|
3855
|
-
refs.setReference(node);
|
|
3856
|
-
return ref;
|
|
3857
|
-
}, type: 'text', value: fieldContext?.value || '' }), jsxRuntime.jsx(react.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: {
|
|
3858
|
-
...floatingStyles,
|
|
3859
|
-
transformOrigin: reversedAnchor,
|
|
3860
|
-
}, transition: true })] }));
|
|
3861
|
-
}
|
|
3862
|
-
|
|
3863
|
-
function NumberInput({ className, fieldContextID, handleBlur, handleChange, options, placeholder, type, ...props }) {
|
|
3864
|
-
const [formContext] = useFormContext(), [fieldsetContext] = useFieldsetContext();
|
|
3865
|
-
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
3866
|
-
const fieldContext = (isInFieldset ? fieldsetContext.fieldList : formContext)?.find(({ id: fieldID }) => fieldID === fieldContextID);
|
|
3867
|
-
const validation = ({ max, min, value }) => {
|
|
3868
|
-
const valueAsNumber = Number(value);
|
|
3869
|
-
if (isNaN(valueAsNumber))
|
|
3870
|
-
return 'This is not a valid number.';
|
|
3871
|
-
if (typeof max === 'number' && valueAsNumber > max)
|
|
3872
|
-
return `Value cannot be higher than ${max}.`;
|
|
3873
|
-
if (typeof min === 'number' && valueAsNumber < min)
|
|
3874
|
-
return `Value cannot be lower than ${min}.`;
|
|
3875
|
-
};
|
|
3876
|
-
const onChange = e => {
|
|
3877
|
-
handleChange({ e, validation });
|
|
3878
|
-
};
|
|
3879
|
-
const onBlur = e => {
|
|
3880
|
-
handleBlur({ e, validation });
|
|
3881
|
-
};
|
|
3882
|
-
return (jsxRuntime.jsx(react.Input, { ...props, className: bag => twMerge(
|
|
3883
|
-
// Base styles
|
|
3884
|
-
'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',
|
|
3885
|
-
// Pseudo styles
|
|
3886
|
-
'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',
|
|
3887
|
-
// user-invalid styles
|
|
3888
|
-
'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))]',
|
|
3889
|
-
// Custom styles
|
|
3890
|
-
typeof className === 'function' ? className(bag) : className), onBlur: onBlur, onChange: onChange, placeholder: placeholder, type: type, value: fieldContext?.value || '' }));
|
|
3891
|
-
}
|
|
3892
|
-
|
|
3893
|
-
const INPUT_COMPONENTS = {
|
|
3894
|
-
button: TextInput,
|
|
3895
|
-
checkbox: TextInput,
|
|
3896
|
-
color: TextInput,
|
|
3897
|
-
date: DateTimeInput,
|
|
3898
|
-
datetime: DateTimeInput,
|
|
3899
|
-
'datetime-local': DateTimeInput,
|
|
3900
|
-
email: TextInput,
|
|
3901
|
-
file: TextInput,
|
|
3902
|
-
hidden: TextInput,
|
|
3903
|
-
image: TextInput,
|
|
3904
|
-
list: TextInput,
|
|
3905
|
-
month: DateTimeInput,
|
|
3906
|
-
number: NumberInput,
|
|
3907
|
-
password: TextInput,
|
|
3908
|
-
radio: TextInput,
|
|
3909
|
-
range: TextInput,
|
|
3910
|
-
reset: TextInput,
|
|
3911
|
-
search: TextInput,
|
|
3912
|
-
submit: TextInput,
|
|
3913
|
-
tel: TextInput,
|
|
3914
|
-
text: TextInput,
|
|
3915
|
-
time: DateTimeInput,
|
|
3916
|
-
url: TextInput,
|
|
3917
|
-
week: DateTimeInput,
|
|
3918
|
-
year: DateTimeInput,
|
|
3919
|
-
};
|
|
3920
|
-
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 }) {
|
|
3921
|
-
const [formContext, formContextFunctions] = useFormContext(), [fieldsetContext, fieldsetContextFunctions] = useFieldsetContext(), [errorMessage, setErrorMessage] = React.useState(undefined);
|
|
3922
|
-
if (placeholder === '*')
|
|
3923
|
-
placeholder = name + (required && !label ? '*' : '');
|
|
3924
|
-
if (label === '*')
|
|
3925
|
-
label = name;
|
|
3926
|
-
const uniqueID = React.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
|
|
3927
|
-
const [internalController, setInternalController] = React.useState(undefined), isControlledByForm = formContext !== undefined, isControlledExternally = typeof value !== 'undefined';
|
|
3928
|
-
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
3929
|
-
const fieldContextType = type === 'email'
|
|
3930
|
-
? 'email'
|
|
3931
|
-
: type === 'file'
|
|
3932
|
-
? 'file'
|
|
3933
|
-
: type === 'number'
|
|
3934
|
-
? 'number'
|
|
3935
|
-
: type === 'tel'
|
|
3936
|
-
? 'tel'
|
|
3937
|
-
: type === 'url'
|
|
3938
|
-
? 'url'
|
|
3939
|
-
: 'string';
|
|
3940
|
-
const fieldContext = isControlledByForm
|
|
3941
|
-
? (isInFieldset ? fieldsetContext.fieldList : formContext)?.find(({ id: fieldID }) => fieldID === fieldContextID)
|
|
3942
|
-
: internalController;
|
|
3746
|
+
const fieldContextType = getFieldContextType();
|
|
3747
|
+
const fieldContext = (isInFieldset ? fieldsetContext.fieldList : formContext)
|
|
3748
|
+
?.find(({ id: fieldID }) => fieldID === fieldContextID);
|
|
3943
3749
|
React.useEffect(() => {
|
|
3944
3750
|
const initialFieldContext = defineField({
|
|
3751
|
+
type: fieldContextType,
|
|
3945
3752
|
id: fieldContextID,
|
|
3946
3753
|
invalid,
|
|
3947
3754
|
name,
|
|
3948
3755
|
required,
|
|
3949
|
-
|
|
3950
|
-
value: value ? `${value}` : defaultValue ? `${defaultValue}` : '',
|
|
3756
|
+
value: value ? `${value}` : defaultValue ? `${defaultValue}` : "",
|
|
3951
3757
|
});
|
|
3952
|
-
if (!isControlledByForm) {
|
|
3953
|
-
setInternalController(initialFieldContext);
|
|
3954
|
-
return;
|
|
3955
|
-
}
|
|
3956
3758
|
if (isInFieldset) {
|
|
3957
3759
|
fieldsetContextFunctions.registerField(initialFieldContext);
|
|
3958
3760
|
return () => {
|
|
@@ -3964,187 +3766,200 @@ function Input({ as, checked, className, defaultValue, description, descriptionP
|
|
|
3964
3766
|
formContextFunctions.removeField(initialFieldContext.id);
|
|
3965
3767
|
};
|
|
3966
3768
|
}, [isInFieldset]);
|
|
3967
|
-
const validateField = (validValue
|
|
3968
|
-
const noValue = !validValue || validValue ===
|
|
3769
|
+
const validateField = (validValue) => {
|
|
3770
|
+
const noValue = !validValue || validValue === "";
|
|
3969
3771
|
if (!required && noValue)
|
|
3970
3772
|
return true;
|
|
3971
3773
|
const errorMessageList = [];
|
|
3972
3774
|
if (noValue) {
|
|
3973
|
-
errorMessageList.push(
|
|
3974
|
-
setErrorMessage(errorMessageList.join(
|
|
3775
|
+
errorMessageList.push("This field is required.");
|
|
3776
|
+
setErrorMessage(errorMessageList.join(" "));
|
|
3975
3777
|
return false;
|
|
3976
3778
|
}
|
|
3977
|
-
|
|
3779
|
+
switch (type) {
|
|
3780
|
+
case "email":
|
|
3781
|
+
if (!isEmail(validValue)) {
|
|
3782
|
+
errorMessageList.push("This is not a valid email.");
|
|
3783
|
+
}
|
|
3784
|
+
break;
|
|
3785
|
+
case "date":
|
|
3786
|
+
const valueAsTime = new Date().getTime();
|
|
3787
|
+
if (min && !(min instanceof Date) && typeof min !== "number") {
|
|
3788
|
+
if (Array.isArray(min)) {
|
|
3789
|
+
const monthIndex = typeof min[1] === "number"
|
|
3790
|
+
? min[1] - 1
|
|
3791
|
+
: getMonthIndexFromName(min[1]);
|
|
3792
|
+
min = new Date(min[0], monthIndex, min[2]);
|
|
3793
|
+
}
|
|
3794
|
+
else if ("year" in min && "month" in min && "day" in min) {
|
|
3795
|
+
const monthIndex = typeof min.month === "number"
|
|
3796
|
+
? min.month - 1
|
|
3797
|
+
: getMonthIndexFromName(min.month);
|
|
3798
|
+
min = new Date(min.year, monthIndex, min.day);
|
|
3799
|
+
}
|
|
3800
|
+
if (valueAsTime < min.getTime()) {
|
|
3801
|
+
errorMessageList.push(`Value cannot be lower than ${getUserReadableDate(min)}.`);
|
|
3802
|
+
}
|
|
3803
|
+
}
|
|
3804
|
+
if (max && !(max instanceof Date) && typeof max !== "number") {
|
|
3805
|
+
if (Array.isArray(max)) {
|
|
3806
|
+
const monthIndex = typeof max[1] === "number"
|
|
3807
|
+
? max[1] - 1
|
|
3808
|
+
: getMonthIndexFromName(max[1]);
|
|
3809
|
+
max = new Date(max[0], monthIndex, max[2]);
|
|
3810
|
+
}
|
|
3811
|
+
else if ("year" in max && "month" in max && "day" in max) {
|
|
3812
|
+
const monthIndex = typeof max.month === "number"
|
|
3813
|
+
? max.month - 1
|
|
3814
|
+
: getMonthIndexFromName(max.month);
|
|
3815
|
+
max = new Date(max.year, monthIndex, max.day);
|
|
3816
|
+
}
|
|
3817
|
+
if (valueAsTime > max.getTime()) {
|
|
3818
|
+
errorMessageList.push(`Value cannot be higher than ${getUserReadableDate(max)}.`);
|
|
3819
|
+
}
|
|
3820
|
+
}
|
|
3821
|
+
break;
|
|
3822
|
+
case "number":
|
|
3823
|
+
const valueAsNumber = Number(validValue);
|
|
3824
|
+
if (isNaN(valueAsNumber)) {
|
|
3825
|
+
errorMessageList.push("This is not a valid number.");
|
|
3826
|
+
}
|
|
3827
|
+
if (typeof max === "number" && valueAsNumber > max) {
|
|
3828
|
+
errorMessageList.push(`Value cannot be higher than ${max}.`);
|
|
3829
|
+
}
|
|
3830
|
+
if (typeof min === "number" && valueAsNumber < min) {
|
|
3831
|
+
errorMessageList.push(`Value cannot be lower than ${min}.`);
|
|
3832
|
+
}
|
|
3833
|
+
break;
|
|
3834
|
+
case "password":
|
|
3835
|
+
if (options) {
|
|
3836
|
+
const { matchPreviousInput, requireLowercaseCharacter, requireNumber, requireSpecialCharacter, requireUppercaseCharacter, } = options;
|
|
3837
|
+
if (matchPreviousInput && formContext && formContext.length >= 2) {
|
|
3838
|
+
if (isInFieldset && fieldsetContext.fieldList.length > 1) {
|
|
3839
|
+
const currentInputIndex = fieldsetContext.fieldList.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3840
|
+
if (currentInputIndex > 0) {
|
|
3841
|
+
const previousInput = fieldsetContext.fieldList.find((_, index) => index === currentInputIndex - 1);
|
|
3842
|
+
if (previousInput &&
|
|
3843
|
+
isStringField(previousInput) &&
|
|
3844
|
+
previousInput.value !== validValue) {
|
|
3845
|
+
errorMessageList.push("Passwords must match.");
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
else {
|
|
3850
|
+
const currentInputIndex = formContext.findIndex(({ id: fieldID }) => fieldID === fieldContext?.id);
|
|
3851
|
+
if (currentInputIndex > 0) {
|
|
3852
|
+
const previousInput = formContext.find((_, index) => index === currentInputIndex - 1);
|
|
3853
|
+
if (previousInput &&
|
|
3854
|
+
isStringField(previousInput) &&
|
|
3855
|
+
previousInput.value !== validValue) {
|
|
3856
|
+
errorMessageList.push("Passwords must match.");
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
if (requireLowercaseCharacter && !/[a-z]/g.test(validValue)) {
|
|
3862
|
+
errorMessageList.push("You must include a lowercase character.");
|
|
3863
|
+
}
|
|
3864
|
+
if (requireNumber && !/[0-9]/g.test(validValue)) {
|
|
3865
|
+
errorMessageList.push("You must include a number.");
|
|
3866
|
+
}
|
|
3867
|
+
if (requireSpecialCharacter && !specialCharacterRegex.test(validValue)) {
|
|
3868
|
+
errorMessageList.push("You must include a special character.");
|
|
3869
|
+
}
|
|
3870
|
+
if (requireUppercaseCharacter && !/[A-Z]/g.test(validValue)) {
|
|
3871
|
+
errorMessageList.push("You must include an uppercase character.");
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
break;
|
|
3875
|
+
case "tel":
|
|
3876
|
+
if (!isPhoneNumber(validValue)) {
|
|
3877
|
+
errorMessageList.push("This is not a valid phone number.");
|
|
3878
|
+
}
|
|
3879
|
+
break;
|
|
3880
|
+
}
|
|
3881
|
+
if (props.maxLength && validValue.length > Number(props.maxLength)) {
|
|
3978
3882
|
errorMessageList.push(`This may not have more than ${props.maxLength} characters.`);
|
|
3979
|
-
|
|
3883
|
+
}
|
|
3884
|
+
if (props.minLength && validValue.length < Number(props.minLength)) {
|
|
3980
3885
|
errorMessageList.push(`This must have at least ${props.minLength} characters.`);
|
|
3981
|
-
if (typeof validation !== 'undefined') {
|
|
3982
|
-
const validationResult = validation({
|
|
3983
|
-
max,
|
|
3984
|
-
min,
|
|
3985
|
-
maxLength: props.maxLength,
|
|
3986
|
-
minLength: props.minLength,
|
|
3987
|
-
multiple: props.multiple,
|
|
3988
|
-
step: props.step,
|
|
3989
|
-
value: validValue,
|
|
3990
|
-
});
|
|
3991
|
-
if (typeof validationResult === 'string')
|
|
3992
|
-
errorMessageList.push(validationResult);
|
|
3993
3886
|
}
|
|
3994
3887
|
if (errorMessageList.length === 0)
|
|
3995
3888
|
return true;
|
|
3996
|
-
setErrorMessage(errorMessageList.join(
|
|
3889
|
+
setErrorMessage(errorMessageList.join(" "));
|
|
3997
3890
|
return false;
|
|
3998
3891
|
};
|
|
3999
|
-
const handleChange = (
|
|
3892
|
+
const handleChange = (e) => {
|
|
4000
3893
|
if (disabled) {
|
|
4001
3894
|
e.preventDefault();
|
|
4002
3895
|
return;
|
|
4003
3896
|
}
|
|
4004
3897
|
const { currentTarget } = e, { value: newValue } = currentTarget;
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
};
|
|
4011
|
-
if (isControlledByForm) {
|
|
4012
|
-
if (isInFieldset) {
|
|
4013
|
-
fieldsetContextFunctions.updateField(fieldContextID, updatedFieldValues);
|
|
4014
|
-
}
|
|
4015
|
-
else {
|
|
4016
|
-
formContextFunctions.updateField(fieldContextID, updatedFieldValues);
|
|
4017
|
-
}
|
|
3898
|
+
if (isInFieldset) {
|
|
3899
|
+
fieldsetContextFunctions.updateField(fieldContextID, {
|
|
3900
|
+
value: newValue,
|
|
3901
|
+
invalid: validateField(newValue) === false,
|
|
3902
|
+
});
|
|
4018
3903
|
}
|
|
4019
3904
|
else {
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
})
|
|
3905
|
+
formContextFunctions.updateField(fieldContextID, {
|
|
3906
|
+
value: newValue,
|
|
3907
|
+
invalid: validateField(newValue) === false,
|
|
3908
|
+
});
|
|
4024
3909
|
}
|
|
4025
3910
|
onChange?.(e);
|
|
4026
3911
|
};
|
|
4027
|
-
const handleBlur = (
|
|
3912
|
+
const handleBlur = (e) => {
|
|
4028
3913
|
if (disabled) {
|
|
4029
3914
|
e.preventDefault();
|
|
4030
3915
|
return;
|
|
4031
3916
|
}
|
|
4032
3917
|
const { currentTarget } = e, { value: newValue } = currentTarget;
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
else {
|
|
4044
|
-
formContextFunctions.updateField(fieldContextID, updatedFieldValues);
|
|
4045
|
-
}
|
|
4046
|
-
}
|
|
4047
|
-
else {
|
|
4048
|
-
setInternalController(previous => ({
|
|
4049
|
-
...previous,
|
|
4050
|
-
...updatedFieldValues,
|
|
4051
|
-
}));
|
|
4052
|
-
}
|
|
4053
|
-
onBlur?.(e);
|
|
4054
|
-
};
|
|
4055
|
-
const cleanFieldProps = fieldProps
|
|
4056
|
-
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !== 'className'))
|
|
4057
|
-
: {};
|
|
4058
|
-
const cleanLabalProps = labelProps
|
|
4059
|
-
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !== 'className'))
|
|
4060
|
-
: {};
|
|
4061
|
-
const cleanDescriptionProps = descriptionProps
|
|
4062
|
-
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== 'className'))
|
|
4063
|
-
: {};
|
|
4064
|
-
const InputComponent = INPUT_COMPONENTS[type];
|
|
4065
|
-
return (jsxRuntime.jsxs(react.Field, { ...cleanFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react.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 })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(InputComponent, { ...props, fieldContextID: fieldContextID, handleBlur: handleBlur, handleChange: handleChange, invalid: invalid, options: options, placeholder: placeholder, required: required, type: type }), fieldContext?.invalid && errorMessage && (jsxRuntime.jsxs(Tooltip, { anchor: 'top-end', arrow: true, portal: true, children: [jsxRuntime.jsx(TooltipTrigger, { as: Button, className: 'absolute top-1.25 right-1.25 z-10 size-6 min-w-0', padding: 'none', rounded: 'md', theme: 'red', children: jsxRuntime.jsx(ExclamationmarkOctagon, { className: 'absolute top-1/2 left-1/2 size-full -translate-x-1/2 -translate-y-1/2 scale-70' }) }), jsxRuntime.jsx(TooltipPanel, { children: errorMessage })] }))] }), description && (jsxRuntime.jsx(react.Description, { ...cleanDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
|
|
4066
|
-
? descriptionProps?.className(bag)
|
|
4067
|
-
: descriptionProps?.className), children: description }))] }));
|
|
4068
|
-
}
|
|
4069
|
-
|
|
4070
|
-
function extractStringValue(value) {
|
|
4071
|
-
if (Array.isArray(value))
|
|
4072
|
-
return value.join(', ');
|
|
4073
|
-
if (typeof value === 'string')
|
|
4074
|
-
return value;
|
|
4075
|
-
return value.value;
|
|
4076
|
-
}
|
|
4077
|
-
function Select({ defaultValue, description, descriptionProps, disabled, fieldProps, invalid, label, labelProps, multiple, name, onChange, optionList, required, value, ...props }) {
|
|
4078
|
-
const [formContext, formContextFunctions] = useFormContext(), [fieldsetContext, fieldsetContextFunctions] = useFieldsetContext();
|
|
4079
|
-
if (label === '*')
|
|
4080
|
-
label = name;
|
|
4081
|
-
const uniqueID = React.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
|
|
4082
|
-
const isInFieldset = fieldsetContext && !fieldsetContext.decorative;
|
|
4083
|
-
const fieldContext = (isInFieldset ? fieldsetContext.fieldList : formContext)?.find(({ id: fieldID }) => fieldID === fieldContextID);
|
|
4084
|
-
React.useEffect(() => {
|
|
4085
|
-
const initialFieldContext = multiple
|
|
4086
|
-
? defineField({
|
|
4087
|
-
type: 'array',
|
|
4088
|
-
of: value
|
|
4089
|
-
? value.map(item => ({
|
|
4090
|
-
type: 'string',
|
|
4091
|
-
value: typeof item === 'string' ? item : item.value,
|
|
4092
|
-
}))
|
|
4093
|
-
: defaultValue
|
|
4094
|
-
? defaultValue.map(item => ({
|
|
4095
|
-
type: 'string',
|
|
4096
|
-
value: typeof item === 'string' ? item : item.value,
|
|
4097
|
-
}))
|
|
4098
|
-
: [],
|
|
4099
|
-
id: fieldContextID,
|
|
4100
|
-
invalid,
|
|
4101
|
-
name,
|
|
4102
|
-
required,
|
|
4103
|
-
})
|
|
4104
|
-
: defineField({
|
|
4105
|
-
type: 'string',
|
|
4106
|
-
id: fieldContextID,
|
|
4107
|
-
invalid,
|
|
4108
|
-
name,
|
|
4109
|
-
required,
|
|
4110
|
-
value: value ? extractStringValue(value) : defaultValue ? extractStringValue(defaultValue) : '',
|
|
4111
|
-
});
|
|
4112
|
-
if (isInFieldset) {
|
|
4113
|
-
fieldsetContextFunctions.registerField(initialFieldContext);
|
|
4114
|
-
return () => {
|
|
4115
|
-
fieldsetContextFunctions.removeField(initialFieldContext.id);
|
|
4116
|
-
};
|
|
3918
|
+
if (required)
|
|
3919
|
+
validateField(newValue);
|
|
3920
|
+
let processedValue = newValue;
|
|
3921
|
+
switch (type) {
|
|
3922
|
+
case "email":
|
|
3923
|
+
processedValue = newValue.toLowerCase();
|
|
3924
|
+
break;
|
|
3925
|
+
case "tel":
|
|
3926
|
+
processedValue = formatPhoneNumber(newValue, options);
|
|
3927
|
+
break;
|
|
4117
3928
|
}
|
|
4118
|
-
formContextFunctions.registerField(initialFieldContext);
|
|
4119
|
-
return () => {
|
|
4120
|
-
formContextFunctions.removeField(initialFieldContext.id);
|
|
4121
|
-
};
|
|
4122
|
-
}, [isInFieldset]);
|
|
4123
|
-
const handleChange = (newValue) => {
|
|
4124
|
-
if (disabled)
|
|
4125
|
-
return;
|
|
4126
|
-
const isInvalid = newValue === '' || !newValue;
|
|
4127
3929
|
if (isInFieldset) {
|
|
4128
3930
|
fieldsetContextFunctions.updateField(fieldContextID, {
|
|
4129
|
-
|
|
4130
|
-
value: newValue,
|
|
3931
|
+
value: processedValue,
|
|
4131
3932
|
});
|
|
4132
3933
|
}
|
|
4133
3934
|
else {
|
|
4134
|
-
formContextFunctions.updateField(fieldContextID, {
|
|
3935
|
+
formContextFunctions.updateField(fieldContextID, {
|
|
3936
|
+
value: processedValue,
|
|
3937
|
+
});
|
|
4135
3938
|
}
|
|
4136
|
-
|
|
3939
|
+
onBlur?.(e);
|
|
4137
3940
|
};
|
|
4138
3941
|
const restFieldProps = fieldProps
|
|
4139
|
-
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !==
|
|
3942
|
+
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !== "className"))
|
|
4140
3943
|
: {};
|
|
4141
3944
|
const restLabelProps = labelProps
|
|
4142
|
-
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !==
|
|
3945
|
+
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !== "className"))
|
|
4143
3946
|
: {};
|
|
4144
3947
|
const restDescriptionProps = descriptionProps
|
|
4145
|
-
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !==
|
|
3948
|
+
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== "className"))
|
|
4146
3949
|
: {};
|
|
4147
|
-
return (jsxRuntime.jsxs(react.Field, { ...restFieldProps, className: bag => twMerge(
|
|
3950
|
+
return (jsxRuntime.jsxs(react.Field, { ...restFieldProps, className: (bag) => twMerge("grid gap-1", typeof fieldProps?.className === "function"
|
|
3951
|
+
? fieldProps?.className(bag)
|
|
3952
|
+
: fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react.Label, { ...restLabelProps, className: (bag) => twMerge("text-sm font-medium", required ? 'after:text-ui-red after:content-["_*"]' : "", typeof labelProps?.className === "function"
|
|
3953
|
+
? labelProps?.className(bag)
|
|
3954
|
+
: labelProps?.className), children: label })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(react.Input, { ...props, className: (bag) => twMerge(
|
|
3955
|
+
// Base styles
|
|
3956
|
+
"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",
|
|
3957
|
+
// Pseudo styles
|
|
3958
|
+
"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",
|
|
3959
|
+
// user-invalid styles
|
|
3960
|
+
"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))]",
|
|
3961
|
+
// Custom styles
|
|
3962
|
+
typeof className === "function" ? className(bag) : className), invalid: invalid, onBlur: handleBlur, onChange: handleChange, placeholder: placeholder, ref: ref, required: required, type: type, value: fieldContext?.value || "" }), fieldContext?.invalid && errorMessage && (jsxRuntime.jsxs(Tooltip, { anchor: "top-end", arrow: true, portal: true, children: [jsxRuntime.jsx(TooltipTrigger, { as: Button, className: "absolute top-1.25 right-1.25 z-10 size-6 min-w-0", padding: "none", rounded: "md", theme: "red", children: jsxRuntime.jsx(ExclamationmarkOctagon, { className: "absolute top-1/2 left-1/2 size-full -translate-x-1/2 -translate-y-1/2 scale-70" }) }), jsxRuntime.jsx(TooltipPanel, { children: errorMessage })] }))] }), description && (jsxRuntime.jsx(react.Description, { ...restDescriptionProps, className: (bag) => twMerge("text-xs", typeof descriptionProps?.className === "function"
|
|
4148
3963
|
? descriptionProps?.className(bag)
|
|
4149
3964
|
: descriptionProps?.className), children: description }))] }));
|
|
4150
3965
|
}
|
|
@@ -4655,12 +4470,14 @@ const MAX_PROGRESS = 100;
|
|
|
4655
4470
|
function Video({ autoPlay, className, controls = true, poster, ref, srcSet, title, ...props }) {
|
|
4656
4471
|
// * General/Core
|
|
4657
4472
|
const uniqueID = React.useId(), figureRef = React.useRef(null), videoPlayerRef = React.useRef(null), sortedSrcSet = srcSet.sort((a, b) => a.width - b.width);
|
|
4658
|
-
const primaryPoster = poster
|
|
4659
|
-
|
|
4473
|
+
const primaryPoster = poster
|
|
4474
|
+
? poster.find(({ primary }) => primary)?.src || poster[0].src
|
|
4475
|
+
: "";
|
|
4476
|
+
const preventDefaultEvent = (e) => e.preventDefault();
|
|
4660
4477
|
// * Play/Pause Controls
|
|
4661
4478
|
const [isPlaying, setIsPlaying] = React.useState(autoPlay);
|
|
4662
4479
|
const togglePlay = React.useCallback(() => {
|
|
4663
|
-
setIsPlaying(previous => {
|
|
4480
|
+
setIsPlaying((previous) => {
|
|
4664
4481
|
if (!previous)
|
|
4665
4482
|
videoPlayerRef.current?.play();
|
|
4666
4483
|
if (previous)
|
|
@@ -4691,22 +4508,25 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4691
4508
|
}, []);
|
|
4692
4509
|
const enterPictureInPicture = () => videoPlayerRef.current?.requestPictureInPicture();
|
|
4693
4510
|
React.useEffect(() => {
|
|
4694
|
-
if (typeof window ===
|
|
4511
|
+
if (typeof window === "undefined")
|
|
4695
4512
|
return;
|
|
4696
|
-
document.addEventListener(
|
|
4513
|
+
document.addEventListener("fullscreenchange", updateFullscreenState);
|
|
4697
4514
|
return () => {
|
|
4698
|
-
document.removeEventListener(
|
|
4515
|
+
document.removeEventListener("fullscreenchange", updateFullscreenState);
|
|
4699
4516
|
};
|
|
4700
4517
|
}, []);
|
|
4701
4518
|
// * Progress/Seeking Controls
|
|
4702
|
-
const [progress, setProgress] = React.useState(0), trackProgressStartTimeRef = React.useRef(0), [seekIndicator, setSeekIndicator] = React.useState({
|
|
4519
|
+
const [progress, setProgress] = React.useState(0), trackProgressStartTimeRef = React.useRef(0), [seekIndicator, setSeekIndicator] = React.useState({
|
|
4520
|
+
isInPlayedArea: false,
|
|
4521
|
+
position: 0,
|
|
4522
|
+
}), seekIndicatorMouseDownPositionRef = React.useRef(0), scrubberRef = React.useRef(null), [timeRemaining, setTimeRemaining] = React.useState(0);
|
|
4703
4523
|
const handleTimeUpdate = () => {
|
|
4704
4524
|
const videoPlayer = videoPlayerRef.current;
|
|
4705
4525
|
if (!videoPlayer)
|
|
4706
4526
|
return;
|
|
4707
4527
|
const { currentTime, duration } = videoPlayer;
|
|
4708
4528
|
const newProgress = (currentTime / duration) * 100;
|
|
4709
|
-
setProgress(prev => (Math.abs(prev - newProgress) > 0.1 ? newProgress : prev));
|
|
4529
|
+
setProgress((prev) => (Math.abs(prev - newProgress) > 0.1 ? newProgress : prev));
|
|
4710
4530
|
setTimeRemaining(duration - currentTime);
|
|
4711
4531
|
};
|
|
4712
4532
|
const handleProgressSlider = ({ x }) => {
|
|
@@ -4716,7 +4536,9 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4716
4536
|
const { duration } = videoPlayer, { width } = scrubber.getBoundingClientRect();
|
|
4717
4537
|
videoPlayer.fastSeek(Math.max(Math.min(trackProgressStartTimeRef.current + x / (width / duration), duration - 1), 0));
|
|
4718
4538
|
};
|
|
4719
|
-
const { trackPointerMovement: trackProgress } = usePointerMovement({
|
|
4539
|
+
const { trackPointerMovement: trackProgress } = usePointerMovement({
|
|
4540
|
+
onChange: handleProgressSlider,
|
|
4541
|
+
});
|
|
4720
4542
|
const initiateTrackProgress = (e) => {
|
|
4721
4543
|
const videoPlayer = videoPlayerRef.current;
|
|
4722
4544
|
if (!videoPlayer)
|
|
@@ -4724,7 +4546,7 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4724
4546
|
trackProgress(e);
|
|
4725
4547
|
trackProgressStartTimeRef.current = videoPlayer.currentTime;
|
|
4726
4548
|
};
|
|
4727
|
-
const handleSeekIndicatorMovement = e => {
|
|
4549
|
+
const handleSeekIndicatorMovement = (e) => {
|
|
4728
4550
|
const videoPlayer = videoPlayerRef.current;
|
|
4729
4551
|
if (!videoPlayer)
|
|
4730
4552
|
return;
|
|
@@ -4735,30 +4557,33 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4735
4557
|
setSeekIndicator({ isInPlayedArea, position });
|
|
4736
4558
|
};
|
|
4737
4559
|
const initializeSeeking = () => (seekIndicatorMouseDownPositionRef.current = seekIndicator.position);
|
|
4738
|
-
const handleSeekRelease = e => {
|
|
4560
|
+
const handleSeekRelease = (e) => {
|
|
4739
4561
|
const videoPlayer = videoPlayerRef.current;
|
|
4740
4562
|
if (!videoPlayer)
|
|
4741
4563
|
return;
|
|
4742
4564
|
const { duration } = videoPlayer, { currentTarget } = e, { width } = currentTarget.getBoundingClientRect();
|
|
4743
|
-
if (seekIndicatorMouseDownPositionRef.current === seekIndicator.position)
|
|
4565
|
+
if (seekIndicatorMouseDownPositionRef.current === seekIndicator.position) {
|
|
4744
4566
|
videoPlayer.fastSeek(Math.min(duration / (width / seekIndicatorMouseDownPositionRef.current), duration - 1));
|
|
4567
|
+
}
|
|
4745
4568
|
};
|
|
4746
4569
|
// * Skip Controls
|
|
4747
4570
|
const [skipDuration, setSkipDuration] = React.useState(10);
|
|
4748
4571
|
const getSkipAmount = () => {
|
|
4749
4572
|
const modifierKeyList = pressedKeyListRef.current;
|
|
4750
4573
|
let skipAmount = 10;
|
|
4751
|
-
if (modifierKeyList.includes(
|
|
4574
|
+
if (modifierKeyList.includes("alt")) {
|
|
4752
4575
|
if (modifierKeyList.length === 1)
|
|
4753
4576
|
skipAmount = 15;
|
|
4754
|
-
if (modifierKeyList.includes(
|
|
4577
|
+
if (modifierKeyList.includes("shift"))
|
|
4755
4578
|
skipAmount = 30;
|
|
4756
|
-
if (modifierKeyList.includes(
|
|
4579
|
+
if (modifierKeyList.includes("meta"))
|
|
4757
4580
|
skipAmount = 5;
|
|
4758
|
-
if (modifierKeyList.includes(
|
|
4581
|
+
if (modifierKeyList.includes("shift") && modifierKeyList.includes("meta"))
|
|
4759
4582
|
skipAmount = 60;
|
|
4760
|
-
if (modifierKeyList.includes(
|
|
4583
|
+
if (modifierKeyList.includes("shift") && modifierKeyList.includes("meta") &&
|
|
4584
|
+
modifierKeyList.includes("ctrl")) {
|
|
4761
4585
|
skipAmount = 90;
|
|
4586
|
+
}
|
|
4762
4587
|
}
|
|
4763
4588
|
if (skipAmount !== skipDuration)
|
|
4764
4589
|
setSkipDuration(skipAmount);
|
|
@@ -4782,7 +4607,7 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4782
4607
|
}, []);
|
|
4783
4608
|
// * Volume Controls
|
|
4784
4609
|
const [volume, setVolume] = React.useState(1), trackVolumeStartRef = React.useRef(0);
|
|
4785
|
-
const handleVolumeChange = e => {
|
|
4610
|
+
const handleVolumeChange = (e) => {
|
|
4786
4611
|
const { currentTarget } = e, { volume } = currentTarget;
|
|
4787
4612
|
setVolume(volume);
|
|
4788
4613
|
};
|
|
@@ -4792,7 +4617,9 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4792
4617
|
return;
|
|
4793
4618
|
videoPlayer.volume = Math.max(Math.min(trackVolumeStartRef.current + (y / 96) * -1, 1), 0);
|
|
4794
4619
|
};
|
|
4795
|
-
const { trackPointerMovement: trackVolume } = usePointerMovement({
|
|
4620
|
+
const { trackPointerMovement: trackVolume } = usePointerMovement({
|
|
4621
|
+
onChange: handleVolumeSlider,
|
|
4622
|
+
});
|
|
4796
4623
|
const initiateTrackVolume = (e) => {
|
|
4797
4624
|
const videoPlayer = videoPlayerRef.current;
|
|
4798
4625
|
if (!videoPlayer)
|
|
@@ -4831,23 +4658,23 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4831
4658
|
// * Keyboard Controls
|
|
4832
4659
|
const pressedKeyListRef = React.useRef([]), [pressedKeyList, setPressedKeyList] = React.useState([]);
|
|
4833
4660
|
const updateModifierKeys = React.useCallback(({ metaKey, altKey, shiftKey, ctrlKey, }) => {
|
|
4834
|
-
if ((metaKey && !pressedKeyListRef.current.includes(
|
|
4835
|
-
(altKey && !pressedKeyListRef.current.includes(
|
|
4836
|
-
(shiftKey && !pressedKeyListRef.current.includes(
|
|
4837
|
-
(ctrlKey && !pressedKeyListRef.current.includes(
|
|
4838
|
-
(!metaKey && pressedKeyListRef.current.includes(
|
|
4839
|
-
(!altKey && pressedKeyListRef.current.includes(
|
|
4840
|
-
(!shiftKey && pressedKeyListRef.current.includes(
|
|
4841
|
-
(!ctrlKey && pressedKeyListRef.current.includes(
|
|
4661
|
+
if ((metaKey && !pressedKeyListRef.current.includes("meta")) ||
|
|
4662
|
+
(altKey && !pressedKeyListRef.current.includes("alt")) ||
|
|
4663
|
+
(shiftKey && !pressedKeyListRef.current.includes("shift")) ||
|
|
4664
|
+
(ctrlKey && !pressedKeyListRef.current.includes("ctrl")) ||
|
|
4665
|
+
(!metaKey && pressedKeyListRef.current.includes("meta")) ||
|
|
4666
|
+
(!altKey && pressedKeyListRef.current.includes("alt")) ||
|
|
4667
|
+
(!shiftKey && pressedKeyListRef.current.includes("shift")) ||
|
|
4668
|
+
(!ctrlKey && pressedKeyListRef.current.includes("ctrl"))) {
|
|
4842
4669
|
const newPressedKeyList = [];
|
|
4843
4670
|
if (metaKey)
|
|
4844
|
-
newPressedKeyList.push(
|
|
4671
|
+
newPressedKeyList.push("meta");
|
|
4845
4672
|
if (altKey)
|
|
4846
|
-
newPressedKeyList.push(
|
|
4673
|
+
newPressedKeyList.push("alt");
|
|
4847
4674
|
if (shiftKey)
|
|
4848
|
-
newPressedKeyList.push(
|
|
4675
|
+
newPressedKeyList.push("shift");
|
|
4849
4676
|
if (ctrlKey)
|
|
4850
|
-
newPressedKeyList.push(
|
|
4677
|
+
newPressedKeyList.push("ctrl");
|
|
4851
4678
|
setPressedKeyList(newPressedKeyList);
|
|
4852
4679
|
pressedKeyListRef.current = newPressedKeyList;
|
|
4853
4680
|
getSkipAmount();
|
|
@@ -4856,27 +4683,29 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4856
4683
|
const handleKeydown = React.useCallback((e) => {
|
|
4857
4684
|
const { key, metaKey, altKey, shiftKey, ctrlKey } = e;
|
|
4858
4685
|
updateModifierKeys({ metaKey, altKey, shiftKey, ctrlKey });
|
|
4859
|
-
if (![
|
|
4686
|
+
if (![" ", "ArrowRight", "ArrowLeft", "ArrowUp", "ArrowDown", "f"].includes(key))
|
|
4860
4687
|
return;
|
|
4861
|
-
if ([
|
|
4688
|
+
if ([" ", "ArrowUp", "ArrowDown", "f"].includes(key) && !metaKey &&
|
|
4689
|
+
!altKey && !shiftKey && !ctrlKey) {
|
|
4862
4690
|
e.preventDefault();
|
|
4691
|
+
}
|
|
4863
4692
|
switch (key) {
|
|
4864
|
-
case
|
|
4693
|
+
case " ":
|
|
4865
4694
|
togglePlay();
|
|
4866
4695
|
break;
|
|
4867
|
-
case
|
|
4696
|
+
case "ArrowRight":
|
|
4868
4697
|
skipForward();
|
|
4869
4698
|
break;
|
|
4870
|
-
case
|
|
4699
|
+
case "ArrowLeft":
|
|
4871
4700
|
skipBack();
|
|
4872
4701
|
break;
|
|
4873
|
-
case
|
|
4702
|
+
case "ArrowUp":
|
|
4874
4703
|
increaseVolume();
|
|
4875
4704
|
break;
|
|
4876
|
-
case
|
|
4705
|
+
case "ArrowDown":
|
|
4877
4706
|
decreaseVolume();
|
|
4878
4707
|
break;
|
|
4879
|
-
case
|
|
4708
|
+
case "f":
|
|
4880
4709
|
requestFullscreen();
|
|
4881
4710
|
break;
|
|
4882
4711
|
}
|
|
@@ -4886,11 +4715,11 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4886
4715
|
updateModifierKeys({ metaKey, altKey, shiftKey, ctrlKey });
|
|
4887
4716
|
}, [updateModifierKeys]);
|
|
4888
4717
|
React.useEffect(() => {
|
|
4889
|
-
if (typeof window ===
|
|
4718
|
+
if (typeof window === "undefined")
|
|
4890
4719
|
return;
|
|
4891
4720
|
const controller = new AbortController(), signal = controller.signal;
|
|
4892
|
-
document.addEventListener(
|
|
4893
|
-
document.addEventListener(
|
|
4721
|
+
document.addEventListener("keydown", handleKeydown, { signal });
|
|
4722
|
+
document.addEventListener("keyup", handleKeyup, { signal });
|
|
4894
4723
|
return () => {
|
|
4895
4724
|
controller.abort();
|
|
4896
4725
|
};
|
|
@@ -4900,22 +4729,25 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4900
4729
|
// * Progressive Enhancement
|
|
4901
4730
|
const progressiveEnhancementSourceLengthRef = React.useRef(1);
|
|
4902
4731
|
const [progressiveEnhancementList, setProgressiveEnhancementList] = React.useState(sortedSrcSet.filter((_, index) => index < progressiveEnhancementSourceLengthRef.current));
|
|
4903
|
-
const handleProEnhance = e => {
|
|
4732
|
+
const handleProEnhance = (e) => {
|
|
4904
4733
|
const { currentTarget } = e, { currentSrc, currentTime } = currentTarget;
|
|
4905
|
-
const proEnhanceSrcLength = progressiveEnhancementSourceLengthRef.current +
|
|
4734
|
+
const proEnhanceSrcLength = progressiveEnhancementSourceLengthRef.current +
|
|
4735
|
+
1, updatedProEnhanceList = sortedSrcSet.filter((_, index) => index < proEnhanceSrcLength);
|
|
4906
4736
|
console.log(updatedProEnhanceList);
|
|
4907
4737
|
setProgressiveEnhancementList(updatedProEnhanceList);
|
|
4908
4738
|
progressiveEnhancementSourceLengthRef.current = proEnhanceSrcLength;
|
|
4909
|
-
const srcToCompare = typeof updatedProEnhanceList.at(-1)?.src ===
|
|
4739
|
+
const srcToCompare = typeof updatedProEnhanceList.at(-1)?.src === "string"
|
|
4910
4740
|
? updatedProEnhanceList.at(-1)?.src
|
|
4911
4741
|
: updatedProEnhanceList.at(-1)?.srcGroup;
|
|
4912
4742
|
if (!srcToCompare)
|
|
4913
4743
|
return;
|
|
4914
|
-
if ((Array.isArray(srcToCompare) &&
|
|
4744
|
+
if ((Array.isArray(srcToCompare) &&
|
|
4745
|
+
srcToCompare.every(({ src }) => src !== currentSrc)) ||
|
|
4915
4746
|
(!Array.isArray(srcToCompare) && srcToCompare !== currentSrc)) {
|
|
4916
|
-
const srcType = currentSrc.split(
|
|
4747
|
+
const srcType = currentSrc.split(".").at(-1);
|
|
4917
4748
|
const src = Array.isArray(srcToCompare)
|
|
4918
|
-
? srcToCompare.find(({ src }) => src.split(
|
|
4749
|
+
? srcToCompare.find(({ src }) => src.split(".").at(-1) === srcType)
|
|
4750
|
+
?.src || srcToCompare[0].src
|
|
4919
4751
|
: srcToCompare;
|
|
4920
4752
|
if (!src)
|
|
4921
4753
|
return;
|
|
@@ -4930,49 +4762,59 @@ function Video({ autoPlay, className, controls = true, poster, ref, srcSet, titl
|
|
|
4930
4762
|
if (!videoPlayer)
|
|
4931
4763
|
return;
|
|
4932
4764
|
const { videoHeight, videoWidth } = videoPlayer;
|
|
4933
|
-
const canvas = document.createElement(
|
|
4765
|
+
const canvas = document.createElement("canvas"), canvasContext = canvas.getContext("2d");
|
|
4934
4766
|
if (!canvasContext)
|
|
4935
4767
|
return;
|
|
4936
4768
|
canvas.width = videoWidth;
|
|
4937
4769
|
canvas.height = videoHeight;
|
|
4938
4770
|
canvasContext.drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);
|
|
4939
|
-
canvas.toBlob(blob => {
|
|
4771
|
+
canvas.toBlob((blob) => {
|
|
4940
4772
|
if (!blob)
|
|
4941
4773
|
return;
|
|
4942
|
-
const url = URL.createObjectURL(blob), link = document.createElement(
|
|
4774
|
+
const url = URL.createObjectURL(blob), link = document.createElement("a");
|
|
4943
4775
|
link.href = url;
|
|
4944
4776
|
link.download = `${title}-frame-${Date.now()}.jpg`;
|
|
4945
4777
|
document.body.appendChild(link);
|
|
4946
4778
|
link.click();
|
|
4947
4779
|
document.body.removeChild(link);
|
|
4948
4780
|
URL.revokeObjectURL(url);
|
|
4949
|
-
},
|
|
4781
|
+
}, "image/jpeg", 0.9);
|
|
4950
4782
|
};
|
|
4951
|
-
return (jsxRuntime.jsxs("figure", { ...(showControls ? {
|
|
4783
|
+
return (jsxRuntime.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: [jsxRuntime.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 }) => {
|
|
4952
4784
|
if (source.srcGroup) {
|
|
4953
4785
|
const { srcGroup } = source;
|
|
4954
4786
|
return srcGroup.map(({ src, type }) => (jsxRuntime.jsx("source", { src: src, type: type }, `${title}${type}${width}${uniqueID}`)));
|
|
4955
4787
|
}
|
|
4956
4788
|
const { src, type } = source;
|
|
4957
|
-
return jsxRuntime.jsx("source", { src: src, type: type }, `${title}${type}${width}${uniqueID}`);
|
|
4958
|
-
}) }), controls && (jsxRuntime.jsxs("div", { className:
|
|
4789
|
+
return (jsxRuntime.jsx("source", { src: src, type: type }, `${title}${type}${width}${uniqueID}`));
|
|
4790
|
+
}) }), controls && (jsxRuntime.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: [jsxRuntime.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: [jsxRuntime.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: [jsxRuntime.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" }), jsxRuntime.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" })] }), jsxRuntime.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: [jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" })] }), jsxRuntime.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: [jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" }), jsxRuntime.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" })] })] }), jsxRuntime.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: [jsxRuntime.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) => {
|
|
4959
4791
|
initiateTrackProgress(e);
|
|
4960
4792
|
initializeSeeking();
|
|
4961
|
-
}, onMouseMove: handleSeekIndicatorMovement, onMouseUp: handleSeekRelease, onTouchStart: initiateTrackProgress, ref: scrubberRef, children: [jsxRuntime.jsx("div", { "aria-hidden":
|
|
4793
|
+
}, onMouseMove: handleSeekIndicatorMovement, onMouseUp: handleSeekRelease, onTouchStart: initiateTrackProgress, ref: scrubberRef, children: [jsxRuntime.jsx("div", { "aria-hidden": "true", className: "absolute inset-0 grid transition-cols duration-100 ease-linear", style: { gridTemplateColumns: `${progress / MAX_PROGRESS}fr` }, children: jsxRuntime.jsx("div", { className: "overflow-hidden", children: jsxRuntime.jsxs("div", { className: "h-full bg-neutral-50/70 text-[1px] text-transparent backdrop-blur-xs backdrop-brightness-125", children: [progress, "/", MAX_PROGRESS] }) }) }), jsxRuntime.jsx("div", { ...(seekIndicator.isInPlayedArea
|
|
4794
|
+
? { "data-in-played-area": true }
|
|
4795
|
+
: {}), "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" }), jsxRuntime.jsx("progress", { className: "sr-only", max: MAX_PROGRESS, value: progress })] }), jsxRuntime.jsx("span", { className: "block text-xs", children: timeRemaining / 60 >= 1
|
|
4962
4796
|
? `${Math.round(timeRemaining / 60)}:${Math.round((timeRemaining / 60 - Math.round(timeRemaining / 60)) * 60)
|
|
4963
4797
|
.toString()
|
|
4964
|
-
.padStart(2,
|
|
4798
|
+
.padStart(2, "0")}`
|
|
4965
4799
|
: Math.round(timeRemaining) === 60
|
|
4966
4800
|
? `1:00`
|
|
4967
|
-
: `0:${Math.round(timeRemaining).toString().padStart(2,
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4801
|
+
: `0:${Math.round(timeRemaining).toString().padStart(2, "0")}` }), jsxRuntime.jsxs(DropDown, { children: [jsxRuntime.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: jsxRuntime.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: {
|
|
4802
|
+
translate: `${volume > 0.66
|
|
4803
|
+
? "0"
|
|
4804
|
+
: volume > 0.33
|
|
4805
|
+
? "2px"
|
|
4806
|
+
: volume > 0
|
|
4807
|
+
? "4px"
|
|
4808
|
+
: "6px"} 0`,
|
|
4809
|
+
}, children: [jsxRuntime.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" }), jsxRuntime.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 } }), jsxRuntime.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 } }), jsxRuntime.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 } })] }) }), jsxRuntime.jsxs(DropDownItems, { anchor: {
|
|
4810
|
+
gap: ".5rem",
|
|
4811
|
+
padding: ".375rem",
|
|
4812
|
+
to: "top",
|
|
4813
|
+
}, className: "bg-neutral-900/50 px-1.5 py-1.5 text-neutral-50 backdrop-blur-xs backdrop-brightness-110", children: [jsxRuntime.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: jsxRuntime.jsx(SpeakerPlusFill, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsxRuntime.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: jsxRuntime.jsx("div", { "aria-hidden": "true", className: "grid size-full rotate-180 transition-rows duration-300 ease-exponential", style: { gridTemplateRows: `${volume}fr` }, children: jsxRuntime.jsx("div", { className: "overflow-y-hidden", children: jsxRuntime.jsxs("div", { className: "size-full bg-neutral-50/70 text-[1px] text-transparent backdrop-blur-xs backdrop-brightness-125", children: [volume * 100, "%"] }) }) }) }), jsxRuntime.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: jsxRuntime.jsx(SpeakerMinusFill, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) })] })] }), jsxRuntime.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: jsxRuntime.jsx(RectangleFillOnArrowDownForwardTopleadingRectangle, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsxRuntime.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: jsxRuntime.jsx(RectangleTriangleUp, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsxRuntime.jsxs(DropDown, { children: [jsxRuntime.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: jsxRuntime.jsx(GearshapeFill, { className: "size-full scale-80 drop-shadow-[0_.125rem_1rem] drop-shadow-neutral-950/75" }) }), jsxRuntime.jsx(DropDownItems, { anchor: {
|
|
4814
|
+
gap: ".5rem",
|
|
4815
|
+
padding: ".375rem",
|
|
4816
|
+
to: "top end",
|
|
4817
|
+
}, className: "bg-neutral-900/50 px-1.5 py-1.5 text-neutral-50 backdrop-blur-xs backdrop-brightness-110", children: jsxRuntime.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: [jsxRuntime.jsx(PhotoBadgeArrowDownFill, { className: "size-5" }), "Capture Current Frame"] }) })] }), jsxRuntime.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: [jsxRuntime.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" }), jsxRuntime.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" })] })] }), jsxRuntime.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" })] }))] }));
|
|
4976
4818
|
}
|
|
4977
4819
|
|
|
4978
4820
|
exports.Anchor = Anchor;
|
|
@@ -4998,7 +4840,6 @@ exports.ModalClose = ModalClose;
|
|
|
4998
4840
|
exports.ModalDialog = ModalDialog;
|
|
4999
4841
|
exports.ModalTitle = ModalTitle;
|
|
5000
4842
|
exports.ModalTrigger = ModalTrigger;
|
|
5001
|
-
exports.Select = Select;
|
|
5002
4843
|
exports.SubmitButton = SubmitButton;
|
|
5003
4844
|
exports.Textarea = Textarea;
|
|
5004
4845
|
exports.Time = Time;
|
|
@@ -5008,4 +4849,5 @@ exports.TooltipTrigger = TooltipTrigger;
|
|
|
5008
4849
|
exports.Video = Video;
|
|
5009
4850
|
exports.createButton = createButton;
|
|
5010
4851
|
exports.createLink = createLink;
|
|
4852
|
+
exports.getLinkClasses = getLinkClasses;
|
|
5011
4853
|
//# sourceMappingURL=components.js.map
|