mado-ui 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components.esm.js +1329 -0
- package/dist/components.esm.js.map +1 -0
- package/dist/components.js +1343 -0
- package/dist/components.js.map +1 -0
- package/dist/hooks.esm.js +73 -0
- package/dist/hooks.esm.js.map +1 -0
- package/dist/hooks.js +80 -0
- package/dist/hooks.js.map +1 -0
- package/dist/icons.esm.js +416 -0
- package/dist/icons.esm.js.map +1 -0
- package/dist/icons.js +520 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +1 -3
- package/dist/index.esm.js +5 -447
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +4 -484
- package/dist/index.js.map +1 -1
- package/dist/types.esm.js +2 -0
- package/dist/types.esm.js.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.esm.js +751 -0
- package/dist/utils.esm.js.map +1 -0
- package/dist/utils.js +790 -0
- package/dist/utils.js.map +1 -0
- package/package.json +35 -4
|
@@ -0,0 +1,1343 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var tailwindMerge = require('tailwind-merge');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var react$1 = require('@headlessui/react');
|
|
7
|
+
var reactDom = require('react-dom');
|
|
8
|
+
|
|
9
|
+
const integerList = Array.from({ length: 100 }, (_, i) => `${i + 1}`);
|
|
10
|
+
const twMerge = tailwindMerge.extendTailwindMerge({
|
|
11
|
+
extend: {
|
|
12
|
+
theme: {
|
|
13
|
+
color: [
|
|
14
|
+
{
|
|
15
|
+
ui: [
|
|
16
|
+
'red',
|
|
17
|
+
'orange',
|
|
18
|
+
'yellow',
|
|
19
|
+
'green',
|
|
20
|
+
'sky-blue',
|
|
21
|
+
'blue',
|
|
22
|
+
'violet',
|
|
23
|
+
'magenta',
|
|
24
|
+
'purple',
|
|
25
|
+
'brown',
|
|
26
|
+
'grey',
|
|
27
|
+
'pink',
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
classGroups: {
|
|
33
|
+
animate: [
|
|
34
|
+
{
|
|
35
|
+
animate: [
|
|
36
|
+
'bounce',
|
|
37
|
+
'double-spin',
|
|
38
|
+
'drop-in',
|
|
39
|
+
'flip',
|
|
40
|
+
'flip-again',
|
|
41
|
+
'grid-rows',
|
|
42
|
+
'heartbeat',
|
|
43
|
+
'ping',
|
|
44
|
+
'pulse',
|
|
45
|
+
'slide-up',
|
|
46
|
+
'spin',
|
|
47
|
+
'wave',
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
'animation-direction': [
|
|
52
|
+
{
|
|
53
|
+
'animation-direction': ['normal', 'reverse', 'alternate', 'alternate-reverse'],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
'animation-fill': [
|
|
57
|
+
{
|
|
58
|
+
'animation-fill': ['none', 'forwards', 'backwards', 'both'],
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
'animation-iteration': [
|
|
62
|
+
{
|
|
63
|
+
'animation-iteration': [...integerList, 'infinite'],
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
'animation-state': [
|
|
67
|
+
{
|
|
68
|
+
'animation-state': ['running', 'paused'],
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
'grid-cols': [
|
|
72
|
+
{
|
|
73
|
+
'grid-cols': ['0fr', '1fr'],
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
'grid-rows': [
|
|
77
|
+
{
|
|
78
|
+
'grid-rows': ['0fr', '1fr'],
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
transition: ['transition-rows'],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
/** The current date as a Date object */
|
|
87
|
+
const d = new Date();
|
|
88
|
+
/** The current minute of the current hour */
|
|
89
|
+
const minutes = d.getMinutes();
|
|
90
|
+
/** The current year */
|
|
91
|
+
d.getFullYear();
|
|
92
|
+
/** An array of the names of month in order */
|
|
93
|
+
const monthNamesList = [
|
|
94
|
+
'January',
|
|
95
|
+
'February',
|
|
96
|
+
'March',
|
|
97
|
+
'April',
|
|
98
|
+
'May',
|
|
99
|
+
'June',
|
|
100
|
+
'July',
|
|
101
|
+
'August',
|
|
102
|
+
'September',
|
|
103
|
+
'October',
|
|
104
|
+
'November',
|
|
105
|
+
'December',
|
|
106
|
+
];
|
|
107
|
+
/** An array of the names of the days of the week in order */
|
|
108
|
+
const weekdayNamesList = [
|
|
109
|
+
'Sunday',
|
|
110
|
+
'Monday',
|
|
111
|
+
'Tuesday',
|
|
112
|
+
'Wednesday',
|
|
113
|
+
'Thursday',
|
|
114
|
+
'Friday',
|
|
115
|
+
'Saturday',
|
|
116
|
+
];
|
|
117
|
+
/** The name of the current month */
|
|
118
|
+
getMonthName();
|
|
119
|
+
/** The name of the current day of the week */
|
|
120
|
+
getWeekdayName();
|
|
121
|
+
/**
|
|
122
|
+
* ### Get Date
|
|
123
|
+
* - Returns the date with two digits
|
|
124
|
+
* @param {number|Date} date The date to get date
|
|
125
|
+
* @returns {string} The date with two digits
|
|
126
|
+
*/
|
|
127
|
+
function getDate(date = d) {
|
|
128
|
+
if (typeof date !== 'number')
|
|
129
|
+
date = date.getDate();
|
|
130
|
+
let formattedDate = date.toString();
|
|
131
|
+
if (formattedDate.length === 1)
|
|
132
|
+
formattedDate = `0${formattedDate}`;
|
|
133
|
+
return formattedDate;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* ### Get Hours
|
|
137
|
+
* - Returns the hours with two digits
|
|
138
|
+
* @param {number|Date} hours The date to get hours
|
|
139
|
+
* @returns {string} The hours with two digits
|
|
140
|
+
*/
|
|
141
|
+
function getHours(hours = d) {
|
|
142
|
+
if (typeof hours !== 'number')
|
|
143
|
+
hours = hours.getHours();
|
|
144
|
+
let formattedHours = hours.toString();
|
|
145
|
+
if (formattedHours.length === 1)
|
|
146
|
+
formattedHours = `0${formattedHours}`;
|
|
147
|
+
return formattedHours;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* ### Get Milliseconds
|
|
151
|
+
* - Returns the milliseconds with two digits
|
|
152
|
+
* @param {number|Date} milliseconds The date to get milliseconds
|
|
153
|
+
* @returns {string} The milliseconds with two digits
|
|
154
|
+
*/
|
|
155
|
+
function getMilliseconds(milliseconds = d) {
|
|
156
|
+
if (typeof milliseconds !== 'number')
|
|
157
|
+
milliseconds = milliseconds.getMilliseconds();
|
|
158
|
+
let formattedMilliseconds = minutes.toString();
|
|
159
|
+
if (formattedMilliseconds.length === 1)
|
|
160
|
+
formattedMilliseconds = `0${formattedMilliseconds}`;
|
|
161
|
+
return formattedMilliseconds;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* ### Get Minutes
|
|
165
|
+
* - Returns the minutes with two digits
|
|
166
|
+
* @param {number|Date} minutes The date to get minutes
|
|
167
|
+
* @returns {string} The minutes with two digits
|
|
168
|
+
*/
|
|
169
|
+
function getMinutes(minutes = d) {
|
|
170
|
+
if (typeof minutes !== 'number')
|
|
171
|
+
minutes = minutes.getMinutes();
|
|
172
|
+
let formattedMinutes = minutes.toString();
|
|
173
|
+
if (formattedMinutes.length === 1)
|
|
174
|
+
formattedMinutes = `0${formattedMinutes}`;
|
|
175
|
+
return formattedMinutes;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* ### Get Month
|
|
179
|
+
* - Returns the month with two digits
|
|
180
|
+
* @param {number|Date} month The date to get month
|
|
181
|
+
* @returns {string} The month with two digits
|
|
182
|
+
*/
|
|
183
|
+
function getMonth(month = d) {
|
|
184
|
+
if (typeof month !== 'number')
|
|
185
|
+
month = month.getMonth() + 1;
|
|
186
|
+
let formattedMonth = month.toString();
|
|
187
|
+
if (formattedMonth.length === 1)
|
|
188
|
+
formattedMonth = `0${formattedMonth}`;
|
|
189
|
+
return formattedMonth;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* ### Get Month Name
|
|
193
|
+
* - Returns the name of the specified month
|
|
194
|
+
* @param {Date} date A Date object representing the month to get the name of the month from. (Preset to the current date)
|
|
195
|
+
* @returns {MonthName} The name of the specified month
|
|
196
|
+
*/
|
|
197
|
+
function getMonthName(date = d) {
|
|
198
|
+
if (typeof date === 'number')
|
|
199
|
+
return monthNamesList[date];
|
|
200
|
+
return monthNamesList[date.getMonth()];
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* ### Get Seconds
|
|
204
|
+
* - Returns the seconds with two digits
|
|
205
|
+
* @param {number|Date} seconds The date to get seconds
|
|
206
|
+
* @returns {string} The seconds with two digits
|
|
207
|
+
*/
|
|
208
|
+
function getSeconds(seconds = d) {
|
|
209
|
+
if (typeof seconds !== 'number')
|
|
210
|
+
seconds = seconds.getSeconds();
|
|
211
|
+
let formattedSeconds = seconds.toString();
|
|
212
|
+
if (formattedSeconds.length === 1)
|
|
213
|
+
formattedSeconds = `0${formattedSeconds}`;
|
|
214
|
+
return formattedSeconds;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* ### Get Weekday Name
|
|
218
|
+
* - Returns the weekday name of the specified day
|
|
219
|
+
* @param {number | Date} weekday A Date object or number representing the day to get the weekday name from. (Preset to the current date)
|
|
220
|
+
* @returns {WeekdayName} The name of the specified weekday
|
|
221
|
+
*/
|
|
222
|
+
function getWeekdayName(weekday = d) {
|
|
223
|
+
if (typeof weekday === 'number')
|
|
224
|
+
return weekdayNamesList[weekday];
|
|
225
|
+
// Return the name of the day of the week
|
|
226
|
+
return weekdayNamesList[weekday.getDay()];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function findComponentByType(children, componentType) {
|
|
230
|
+
const childrenArray = react.Children.toArray(children);
|
|
231
|
+
for (const child of childrenArray) {
|
|
232
|
+
if (react.isValidElement(child) && child.type === componentType)
|
|
233
|
+
return child;
|
|
234
|
+
}
|
|
235
|
+
for (const child of childrenArray) {
|
|
236
|
+
if (react.isValidElement(child)) {
|
|
237
|
+
if (child.type === react.Fragment && child.props.children) {
|
|
238
|
+
const found = findComponentByType(child.props.children, componentType);
|
|
239
|
+
if (found)
|
|
240
|
+
return found;
|
|
241
|
+
}
|
|
242
|
+
else if (child.props.children) {
|
|
243
|
+
const found = findComponentByType(child.props.children, componentType);
|
|
244
|
+
if (found)
|
|
245
|
+
return found;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function easeOutExpo(time, start, end, duration) {
|
|
253
|
+
return time == duration ? start + end : end * (-Math.pow(2, (-10 * time) / duration) + 1) + start;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
257
|
+
/**
|
|
258
|
+
* # Is Email
|
|
259
|
+
* Checks whether the specified string is in email format
|
|
260
|
+
*/
|
|
261
|
+
function isEmail(email) {
|
|
262
|
+
return emailRegex.test(email);
|
|
263
|
+
}
|
|
264
|
+
const telRegex = /(?:\+1\s|1\s|)?\d{3}\.\d{3}\.\d{4}|(?:\+1\s|1\s|)?\d{3}-\d{3}-\d{4}|(?:\+1\s|1\s|)?\(\d{3}\) \d{3}-\d{4}|(?:\+1\s|1\s|\+1|1|)?\d{10}/;
|
|
265
|
+
/**
|
|
266
|
+
* # Is Phone Number
|
|
267
|
+
* Checks whether the specified string is in phone number format
|
|
268
|
+
*/
|
|
269
|
+
function isPhoneNumber(tel) {
|
|
270
|
+
return telRegex.test(tel);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* # Format Phone Number
|
|
275
|
+
* Converts any string containing at least 10 numbers to a formatted phone number
|
|
276
|
+
* @param {string} string
|
|
277
|
+
* @returns {string} string formatted (000) 000-0000
|
|
278
|
+
*/
|
|
279
|
+
function formatPhoneNumber(string, countryCode) {
|
|
280
|
+
return (`${`+${countryCode} ` }` +
|
|
281
|
+
string
|
|
282
|
+
.replace(/\D/g, '')
|
|
283
|
+
.slice(-10)
|
|
284
|
+
.split('')
|
|
285
|
+
.map((char, index) => {
|
|
286
|
+
if (index === 0)
|
|
287
|
+
return `(${char}`;
|
|
288
|
+
if (index === 2)
|
|
289
|
+
return `${char}) `;
|
|
290
|
+
if (index === 5)
|
|
291
|
+
return `${char}-`;
|
|
292
|
+
return char;
|
|
293
|
+
})
|
|
294
|
+
.join(''));
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* # To Lower Case
|
|
298
|
+
* Converts a string to lowercase, and offers easy string replacements for creating snake case, kebab case, or your own.
|
|
299
|
+
* @param str - The string to convert to lowercase.
|
|
300
|
+
* @param options - Configuration options.
|
|
301
|
+
* @param options[0] - The delimiter to split the string. Defaults to space.
|
|
302
|
+
* @param options[1] - The string to join the parts back together. Defaults to space.
|
|
303
|
+
* @returns The lowercase version of the input string, with the replacements, if provided.
|
|
304
|
+
*/
|
|
305
|
+
function toLowerCase(str, [delimiter, joiner]) {
|
|
306
|
+
return str.toLowerCase().replaceAll(delimiter || ' ', joiner || ' ');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function twSort(className) {
|
|
310
|
+
return className;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function Anchor({ className, disabled, href, onClick, ref, target, rel, ...props }) {
|
|
314
|
+
const isExternal = `${href}`.startsWith('http'), hasHash = `${href}`.includes('#');
|
|
315
|
+
const handleClick = e => {
|
|
316
|
+
if (disabled)
|
|
317
|
+
return e.preventDefault();
|
|
318
|
+
onClick?.(e);
|
|
319
|
+
setTimeout(() => history.replaceState({}, document.title, location.pathname), 100);
|
|
320
|
+
};
|
|
321
|
+
return (jsxRuntime.jsx("a", { ref: ref, ...props, "aria-disabled": disabled, className: twMerge(className, disabled && 'pointer-events-none'), href: href, target: target || (isExternal ? '_blank' : '_self'), onClick: hasHash ? handleClick : onClick, rel: rel !== undefined
|
|
322
|
+
? rel === 'nofollow'
|
|
323
|
+
? `${rel} noreferrer noopener`
|
|
324
|
+
: `${rel} prefetch`
|
|
325
|
+
: isExternal
|
|
326
|
+
? 'nofollow noreferrer noopener'
|
|
327
|
+
: 'prefetch' }));
|
|
328
|
+
}
|
|
329
|
+
// * Styles
|
|
330
|
+
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');
|
|
331
|
+
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');
|
|
332
|
+
const lineClasses = tailwindMerge.twJoin(lineStaticClasses, 'whitespace-nowrap transition-transform after:transition-transform after:ease-exponential');
|
|
333
|
+
const scaleXClasses = 'after:scale-x-0 pointer-fine:hover:after:scale-x-100 active:after:scale-x-100';
|
|
334
|
+
const scaleYClasses = 'after:scale-y-0 pointer-fine:hover:after:scale-y-100 active:after:scale-y-100';
|
|
335
|
+
const lineNormalClasses = tailwindMerge.twJoin([
|
|
336
|
+
lineClasses,
|
|
337
|
+
scaleYClasses,
|
|
338
|
+
'after:origin-bottom after:translate-y-0.5 active:after:translate-y-0 pointer-fine:hover:after:translate-y-0',
|
|
339
|
+
]);
|
|
340
|
+
const lineLtrClasses = tailwindMerge.twJoin([lineClasses, scaleXClasses, 'after:origin-left']);
|
|
341
|
+
const lineRtlClasses = tailwindMerge.twJoin([lineClasses, scaleXClasses, 'after:origin-right']);
|
|
342
|
+
const lineCenterClasses = tailwindMerge.twJoin([lineClasses, scaleXClasses]);
|
|
343
|
+
const lineLiftClasses = tailwindMerge.twJoin([
|
|
344
|
+
lineClasses,
|
|
345
|
+
scaleYClasses,
|
|
346
|
+
'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',
|
|
347
|
+
]);
|
|
348
|
+
const fillClasses = tailwindMerge.twJoin(baseClasses, 'whitespace-nowrap transition-[transform_color] after:top-1/2 after:h-[calc(100%+0.05rem)] after:w-[calc(100%+0.25rem)] after:-translate-y-1/2 after:rounded after:ease-exponential active:text-zinc-50 pointer-fine:hover:text-zinc-50');
|
|
349
|
+
// Define theme-specific fill color transition classes
|
|
350
|
+
const getFillColorTransitionClasses = (theme = 'blue') => {
|
|
351
|
+
switch (theme) {
|
|
352
|
+
case 'brown':
|
|
353
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-brown after:transition-transform contrast-more:after:bg-ui-brown');
|
|
354
|
+
case 'green':
|
|
355
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-green after:transition-transform contrast-more:after:bg-ui-green');
|
|
356
|
+
case 'grey':
|
|
357
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-grey after:transition-transform contrast-more:after:bg-ui-grey');
|
|
358
|
+
case 'sky-blue':
|
|
359
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-sky-blue after:transition-transform contrast-more:after:bg-ui-sky-blue');
|
|
360
|
+
case 'magenta':
|
|
361
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-magenta after:transition-transform contrast-more:after:bg-ui-magenta');
|
|
362
|
+
case 'neutral':
|
|
363
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-zinc-700 after:transition-transform contrast-more:after:bg-zinc-700 dark:after:bg-zinc-300 dark:contrast-more:after:bg-zinc-300');
|
|
364
|
+
case 'orange':
|
|
365
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-orange after:transition-transform contrast-more:after:bg-ui-orange');
|
|
366
|
+
case 'pink':
|
|
367
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-pink after:transition-transform contrast-more:after:bg-ui-pink');
|
|
368
|
+
case 'purple':
|
|
369
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-purple after:transition-transform contrast-more:after:bg-ui-purple');
|
|
370
|
+
case 'red':
|
|
371
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-red after:transition-transform contrast-more:after:bg-ui-red');
|
|
372
|
+
case 'violet':
|
|
373
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-violet after:transition-transform contrast-more:after:bg-ui-violet');
|
|
374
|
+
case 'yellow':
|
|
375
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-yellow after:transition-transform contrast-more:after:bg-ui-yellow');
|
|
376
|
+
case 'blue':
|
|
377
|
+
default:
|
|
378
|
+
return tailwindMerge.twJoin(fillClasses, 'after:bg-ui-blue after:transition-transform contrast-more:after:bg-ui-blue');
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
// Define theme-specific fill center classes
|
|
382
|
+
const getFillCenterClasses = (theme = 'blue') => {
|
|
383
|
+
switch (theme) {
|
|
384
|
+
case 'brown':
|
|
385
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-brown/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-brown pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-brown');
|
|
386
|
+
case 'green':
|
|
387
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-green/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-green pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-green');
|
|
388
|
+
case 'grey':
|
|
389
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-grey/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-grey pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-grey');
|
|
390
|
+
case 'sky-blue':
|
|
391
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-sky-blue/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-sky-blue pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-sky-blue');
|
|
392
|
+
case 'magenta':
|
|
393
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-magenta/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-magenta pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-magenta');
|
|
394
|
+
case 'neutral':
|
|
395
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-zinc-700/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-zinc-700 dark:after:bg-zinc-300/0 dark:active:after:bg-zinc-300 pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-zinc-700 dark:pointer-fine:hover:after:bg-zinc-300');
|
|
396
|
+
case 'orange':
|
|
397
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-orange/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-orange pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-orange');
|
|
398
|
+
case 'pink':
|
|
399
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-pink/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-pink pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-pink');
|
|
400
|
+
case 'purple':
|
|
401
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-purple/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-purple pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-purple');
|
|
402
|
+
case 'red':
|
|
403
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-red/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-red pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-red');
|
|
404
|
+
case 'violet':
|
|
405
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-violet/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-violet pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-violet');
|
|
406
|
+
case 'yellow':
|
|
407
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-yellow/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-yellow pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-yellow');
|
|
408
|
+
case 'blue':
|
|
409
|
+
default:
|
|
410
|
+
return tailwindMerge.twJoin(fillClasses, 'after:scale-x-50 after:scale-y-[0.25] after:bg-ui-blue/0 after:transition-[transform_background-color] active:after:scale-x-100 active:after:scale-y-100 active:after:bg-ui-blue pointer-fine:hover:after:scale-x-100 pointer-fine:hover:after:scale-y-100 pointer-fine:hover:after:bg-ui-blue');
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
const multilineBaseClasses = twSort('bg-linear-to-r from-current to-current bg-no-repeat active:scale-95');
|
|
414
|
+
const multilineLineStaticClasses = 'underline';
|
|
415
|
+
const multilineNormalClasses = twSort('underline-offset-1 active:underline pointer-fine:hover:underline');
|
|
416
|
+
const multilineClasses = tailwindMerge.twJoin(multilineBaseClasses, 'duration-500 ease-exponential');
|
|
417
|
+
const multilineLineClasses = tailwindMerge.twJoin(multilineClasses, 'bg-[position:0%_100%] px-px pb-px transition-[background-size]');
|
|
418
|
+
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]');
|
|
419
|
+
const multilineLineRtlClasses = tailwindMerge.twJoin([multilineXClasses, 'bg-[position:100%_100%]']);
|
|
420
|
+
const multilineLineCenterClasses = tailwindMerge.twJoin([multilineXClasses, 'bg-[position:50%_100%]']);
|
|
421
|
+
const multilineLineLiftClasses = tailwindMerge.twJoin(multilineLineClasses, 'bg-[size:auto_0px] focus-visible:bg-[size:auto_2px] active:bg-[size:auto_2px] pointer-fine:hover:bg-[size:auto_2px]');
|
|
422
|
+
const multilineFillBaseClasses = tailwindMerge.twJoin(multilineBaseClasses, 'rounded px-0.5 py-0.75 focus-visible:text-zinc-50 active:text-zinc-50 pointer-fine:hover:text-zinc-50');
|
|
423
|
+
const getMultilineFillColorClasses = (theme = 'blue') => {
|
|
424
|
+
switch (theme) {
|
|
425
|
+
case 'brown':
|
|
426
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-brown to-ui-brown transition-[background-size_color] contrast-more:from-ui-brown contrast-more:to-ui-brown');
|
|
427
|
+
case 'green':
|
|
428
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-green to-ui-green transition-[background-size_color] contrast-more:from-ui-green contrast-more:to-ui-green');
|
|
429
|
+
case 'grey':
|
|
430
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-grey to-ui-grey transition-[background-size_color] contrast-more:from-ui-grey contrast-more:to-ui-grey');
|
|
431
|
+
case 'sky-blue':
|
|
432
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-sky-blue to-ui-sky-blue transition-[background-size_color] contrast-more:from-ui-sky-blue contrast-more:to-ui-sky-blue');
|
|
433
|
+
case 'magenta':
|
|
434
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-magenta to-ui-magenta transition-[background-size_color] contrast-more:from-ui-magenta contrast-more:to-ui-magenta');
|
|
435
|
+
case 'neutral':
|
|
436
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-zinc-700 to-zinc-700 transition-[background-size_color] contrast-more:from-zinc-700 contrast-more:to-zinc-700 dark:from-zinc-300 dark:to-zinc-300 dark:contrast-more:from-zinc-300 dark:contrast-more:to-zinc-300');
|
|
437
|
+
case 'orange':
|
|
438
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-orange to-ui-orange transition-[background-size_color] contrast-more:from-ui-orange contrast-more:to-ui-orange');
|
|
439
|
+
case 'pink':
|
|
440
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-pink to-ui-pink transition-[background-size_color] contrast-more:from-ui-pink contrast-more:to-ui-pink');
|
|
441
|
+
case 'purple':
|
|
442
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-purple to-ui-purple transition-[background-size_color] contrast-more:from-ui-purple contrast-more:to-ui-purple');
|
|
443
|
+
case 'red':
|
|
444
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-red to-ui-red transition-[background-size_color] contrast-more:from-ui-red contrast-more:to-ui-red');
|
|
445
|
+
case 'violet':
|
|
446
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-violet to-ui-violet transition-[background-size_color] contrast-more:from-ui-violet contrast-more:to-ui-violet');
|
|
447
|
+
case 'yellow':
|
|
448
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-yellow to-ui-yellow transition-[background-size_color] contrast-more:from-ui-yellow contrast-more:to-ui-yellow');
|
|
449
|
+
case 'blue':
|
|
450
|
+
default:
|
|
451
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-blue to-ui-blue transition-[background-size_color] contrast-more:from-ui-blue contrast-more:to-ui-blue');
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
// Define theme-specific multiline fill classes
|
|
455
|
+
const getMultilineFillClasses = (theme = 'blue') => {
|
|
456
|
+
switch (theme) {
|
|
457
|
+
case 'brown':
|
|
458
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-brown/0 to-ui-brown/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-brown focus-visible:to-ui-brown focus-visible:bg-[size:100%_100%] active:from-ui-brown active:to-ui-brown active:bg-[size:100%_100%] contrast-more:from-ui-brown/0 contrast-more:to-ui-brown/0 focus-visible:contrast-more:from-ui-brown focus-visible:contrast-more:to-ui-brown active:contrast-more:from-ui-brown active:contrast-more:to-ui-brown pointer-fine:hover:from-ui-brown pointer-fine:hover:to-ui-brown pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-brown pointer-fine:hover:contrast-more:to-ui-brown');
|
|
459
|
+
case 'green':
|
|
460
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-green/0 to-ui-green/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-green focus-visible:to-ui-green focus-visible:bg-[size:100%_100%] active:from-ui-green active:to-ui-green active:bg-[size:100%_100%] contrast-more:from-ui-green/0 contrast-more:to-ui-green/0 focus-visible:contrast-more:from-ui-green focus-visible:contrast-more:to-ui-green active:contrast-more:from-ui-green active:contrast-more:to-ui-green pointer-fine:hover:from-ui-green pointer-fine:hover:to-ui-green pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-green pointer-fine:hover:contrast-more:to-ui-green');
|
|
461
|
+
case 'grey':
|
|
462
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-grey/0 to-ui-grey/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-grey focus-visible:to-ui-grey focus-visible:bg-[size:100%_100%] active:from-ui-grey active:to-ui-grey active:bg-[size:100%_100%] contrast-more:from-ui-grey/0 contrast-more:to-ui-grey/0 focus-visible:contrast-more:from-ui-grey focus-visible:contrast-more:to-ui-grey active:contrast-more:from-ui-grey active:contrast-more:to-ui-grey pointer-fine:hover:from-ui-grey pointer-fine:hover:to-ui-grey pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-grey pointer-fine:hover:contrast-more:to-ui-grey');
|
|
463
|
+
case 'sky-blue':
|
|
464
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-sky-blue/0 to-ui-sky-blue/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-sky-blue focus-visible:to-ui-sky-blue focus-visible:bg-[size:100%_100%] active:from-ui-sky-blue active:to-ui-sky-blue active:bg-[size:100%_100%] contrast-more:from-ui-sky-blue/0 contrast-more:to-ui-sky-blue/0 focus-visible:contrast-more:from-ui-sky-blue focus-visible:contrast-more:to-ui-sky-blue active:contrast-more:from-ui-sky-blue active:contrast-more:to-ui-sky-blue pointer-fine:hover:from-ui-sky-blue pointer-fine:hover:to-ui-sky-blue pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-sky-blue pointer-fine:hover:contrast-more:to-ui-sky-blue');
|
|
465
|
+
case 'magenta':
|
|
466
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-magenta/0 to-ui-magenta/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-magenta focus-visible:to-ui-magenta focus-visible:bg-[size:100%_100%] active:from-ui-magenta active:to-ui-magenta active:bg-[size:100%_100%] contrast-more:from-ui-magenta/0 contrast-more:to-ui-magenta/0 focus-visible:contrast-more:from-ui-magenta focus-visible:contrast-more:to-ui-magenta active:contrast-more:from-ui-magenta active:contrast-more:to-ui-magenta pointer-fine:hover:from-ui-magenta pointer-fine:hover:to-ui-magenta pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-magenta pointer-fine:hover:contrast-more:to-ui-magenta');
|
|
467
|
+
case 'neutral':
|
|
468
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-zinc-700/0 to-zinc-700/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-zinc-700 focus-visible:to-zinc-700 focus-visible:bg-[size:100%_100%] active:from-zinc-700 active:to-zinc-700 active:bg-[size:100%_100%] contrast-more:from-zinc-700/0 contrast-more:to-zinc-700/0 focus-visible:contrast-more:from-zinc-700 focus-visible:contrast-more:to-zinc-700 active:contrast-more:from-zinc-700 active:contrast-more:to-zinc-700 dark:from-zinc-300/0 dark:to-zinc-300/0 dark:focus-visible:from-zinc-300 dark:focus-visible:to-zinc-300 dark:active:from-zinc-300 dark:active:to-zinc-300 dark:contrast-more:from-zinc-300/0 dark:contrast-more:to-zinc-300/0 dark:focus-visible:contrast-more:from-zinc-300 dark:focus-visible:contrast-more:to-zinc-300 dark:active:contrast-more:from-zinc-300 dark:active:contrast-more:to-zinc-300 pointer-fine:hover:from-zinc-700 pointer-fine:hover:to-zinc-700 pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-zinc-700 pointer-fine:hover:contrast-more:to-zinc-700 dark:pointer-fine:hover:from-zinc-300 dark:pointer-fine:hover:to-zinc-300 dark:pointer-fine:hover:contrast-more:from-zinc-300 dark:pointer-fine:hover:contrast-more:to-zinc-300');
|
|
469
|
+
case 'orange':
|
|
470
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-orange/0 to-ui-orange/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-orange focus-visible:to-ui-orange focus-visible:bg-[size:100%_100%] active:from-ui-orange active:to-ui-orange active:bg-[size:100%_100%] contrast-more:from-ui-orange/0 contrast-more:to-ui-orange/0 focus-visible:contrast-more:from-ui-orange focus-visible:contrast-more:to-ui-orange active:contrast-more:from-ui-orange active:contrast-more:to-ui-orange pointer-fine:hover:from-ui-orange pointer-fine:hover:to-ui-orange pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-orange pointer-fine:hover:contrast-more:to-ui-orange');
|
|
471
|
+
case 'pink':
|
|
472
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-pink/0 to-ui-pink/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-pink focus-visible:to-ui-pink focus-visible:bg-[size:100%_100%] active:from-ui-pink active:to-ui-pink active:bg-[size:100%_100%] contrast-more:from-ui-pink/0 contrast-more:to-ui-pink/0 focus-visible:contrast-more:from-ui-pink focus-visible:contrast-more:to-ui-pink active:contrast-more:from-ui-pink active:contrast-more:to-ui-pink pointer-fine:hover:from-ui-pink pointer-fine:hover:to-ui-pink pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-pink pointer-fine:hover:contrast-more:to-ui-pink');
|
|
473
|
+
case 'purple':
|
|
474
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-purple/0 to-ui-purple/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-purple focus-visible:to-ui-purple focus-visible:bg-[size:100%_100%] active:from-ui-purple active:to-ui-purple active:bg-[size:100%_100%] contrast-more:from-ui-purple/0 contrast-more:to-ui-purple/0 focus-visible:contrast-more:from-ui-purple focus-visible:contrast-more:to-ui-purple active:contrast-more:from-ui-purple active:contrast-more:to-ui-purple pointer-fine:hover:from-ui-purple pointer-fine:hover:to-ui-purple pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-purple pointer-fine:hover:contrast-more:to-ui-purple');
|
|
475
|
+
case 'red':
|
|
476
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-red/0 to-ui-red/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-red focus-visible:to-ui-red focus-visible:bg-[size:100%_100%] active:from-ui-red active:to-ui-red active:bg-[size:100%_100%] contrast-more:from-ui-red/0 contrast-more:to-ui-red/0 focus-visible:contrast-more:from-ui-red focus-visible:contrast-more:to-ui-red active:contrast-more:from-ui-red active:contrast-more:to-ui-red pointer-fine:hover:from-ui-red pointer-fine:hover:to-ui-red pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-red pointer-fine:hover:contrast-more:to-ui-red');
|
|
477
|
+
case 'violet':
|
|
478
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-violet/0 to-ui-violet/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-violet focus-visible:to-ui-violet focus-visible:bg-[size:100%_100%] active:from-ui-violet active:to-ui-violet active:bg-[size:100%_100%] contrast-more:from-ui-violet/0 contrast-more:to-ui-violet/0 focus-visible:contrast-more:from-ui-violet focus-visible:contrast-more:to-ui-violet active:contrast-more:from-ui-violet active:contrast-more:to-ui-violet pointer-fine:hover:from-ui-violet pointer-fine:hover:to-ui-violet pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-violet pointer-fine:hover:contrast-more:to-ui-violet');
|
|
479
|
+
case 'yellow':
|
|
480
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-yellow/0 to-ui-yellow/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-yellow focus-visible:to-ui-yellow focus-visible:bg-[size:100%_100%] active:from-ui-yellow active:to-ui-yellow active:bg-[size:100%_100%] contrast-more:from-ui-yellow/0 contrast-more:to-ui-yellow/0 focus-visible:contrast-more:from-ui-yellow focus-visible:contrast-more:to-ui-yellow active:contrast-more:from-ui-yellow active:contrast-more:to-ui-yellow pointer-fine:hover:from-ui-yellow pointer-fine:hover:to-ui-yellow pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-yellow pointer-fine:hover:contrast-more:to-ui-yellow');
|
|
481
|
+
case 'blue':
|
|
482
|
+
default:
|
|
483
|
+
return tailwindMerge.twJoin(multilineFillBaseClasses, 'from-ui-blue/0 to-ui-blue/0 bg-[size:50%_0px] bg-[position:50%_50%] transition-[background-size_background-image_color] focus-visible:from-ui-blue focus-visible:to-ui-blue focus-visible:bg-[size:100%_100%] active:from-ui-blue active:to-ui-blue active:bg-[size:100%_100%] contrast-more:from-ui-blue/0 contrast-more:to-ui-blue/0 focus-visible:contrast-more:from-ui-blue focus-visible:contrast-more:to-ui-blue active:contrast-more:from-ui-blue active:contrast-more:to-ui-blue pointer-fine:hover:from-ui-blue pointer-fine:hover:to-ui-blue pointer-fine:hover:bg-[size:100%_100%] pointer-fine:hover:contrast-more:from-ui-blue pointer-fine:hover:contrast-more:to-ui-blue');
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
const getMultilineFillLiftClasses = (theme = 'blue') => {
|
|
487
|
+
return tailwindMerge.twJoin(getMultilineFillColorClasses(theme), 'bg-[size:auto_0px] bg-[position:50%_100%] focus-visible:bg-[size:auto_100%] active:bg-[size:auto_100%] pointer-fine:hover:bg-[size:auto_100%]');
|
|
488
|
+
};
|
|
489
|
+
const getMultilineFillXClasses = (theme = 'blue') => {
|
|
490
|
+
return tailwindMerge.twJoin(getMultilineFillColorClasses(theme), 'bg-[size:0%_100%] focus-visible:bg-[size:100%_100%] active:bg-[size:100%_100%] pointer-fine:hover:bg-[size:100%_100%]');
|
|
491
|
+
};
|
|
492
|
+
const getMultilineFillRtlClasses = (theme = 'blue') => {
|
|
493
|
+
return tailwindMerge.twJoin(getMultilineFillXClasses(theme), 'bg-[position:100%_auto]');
|
|
494
|
+
};
|
|
495
|
+
const getMultilineFillCenterClasses = (theme = 'blue') => {
|
|
496
|
+
return tailwindMerge.twJoin(getMultilineFillXClasses(theme), 'bg-[position:50%_auto]');
|
|
497
|
+
};
|
|
498
|
+
/**
|
|
499
|
+
* # Link
|
|
500
|
+
*
|
|
501
|
+
* - A component for rendering links with various styles and options.
|
|
502
|
+
* - Utilizes the Next.js `Link` component and provides additional functionality.
|
|
503
|
+
*
|
|
504
|
+
* ---
|
|
505
|
+
*
|
|
506
|
+
* ## Styles
|
|
507
|
+
*
|
|
508
|
+
* This component includes various classes to style the link. The styles are divided into two types:
|
|
509
|
+
*
|
|
510
|
+
* - Line styles: These styles add a line underneath the link, and include variations for different positions and orientations.
|
|
511
|
+
* - Fill styles: These styles add a background color behind the link, and include variations for different positions and orientations.
|
|
512
|
+
* - Multiline styles: These styles seek to accomplish the same as the line and fill styles, while offering multiline support.
|
|
513
|
+
*
|
|
514
|
+
* ---
|
|
515
|
+
*
|
|
516
|
+
* ## Examples
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* <Link href='/about' type='ltr' title='About Us'>Learn more about our company</Link>
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* <Link href='/about' type='fill-ltr' title='About Us'>Learn more about our company</Link>
|
|
523
|
+
*
|
|
524
|
+
* @example
|
|
525
|
+
* <Link href='/about' type='fill-ltr' theme='red' title='About Us'>Learn more about our company</Link>
|
|
526
|
+
*/
|
|
527
|
+
function Link({ as, className, ref, theme = 'blue', type, ...props }) {
|
|
528
|
+
const getLinkClasses = () => {
|
|
529
|
+
switch (type) {
|
|
530
|
+
case 'static':
|
|
531
|
+
return lineStaticClasses;
|
|
532
|
+
case 'ltr':
|
|
533
|
+
return lineLtrClasses;
|
|
534
|
+
case 'rtl':
|
|
535
|
+
return lineRtlClasses;
|
|
536
|
+
case 'center':
|
|
537
|
+
return lineCenterClasses;
|
|
538
|
+
case 'lift':
|
|
539
|
+
return lineLiftClasses;
|
|
540
|
+
case 'fill':
|
|
541
|
+
return getFillCenterClasses(theme);
|
|
542
|
+
case 'fill-ltr':
|
|
543
|
+
return tailwindMerge.twJoin([getFillColorTransitionClasses(theme), scaleXClasses, 'after:origin-left']);
|
|
544
|
+
case 'fill-rtl':
|
|
545
|
+
return tailwindMerge.twJoin([getFillColorTransitionClasses(theme), scaleXClasses, 'after:origin-right']);
|
|
546
|
+
case 'fill-lift':
|
|
547
|
+
return tailwindMerge.twJoin([getFillColorTransitionClasses(theme), scaleYClasses, 'after:origin-bottom']);
|
|
548
|
+
case 'multiline':
|
|
549
|
+
return multilineNormalClasses;
|
|
550
|
+
case 'multiline-static':
|
|
551
|
+
return multilineLineStaticClasses;
|
|
552
|
+
case 'multiline-ltr':
|
|
553
|
+
return multilineXClasses;
|
|
554
|
+
case 'multiline-rtl':
|
|
555
|
+
return multilineLineRtlClasses;
|
|
556
|
+
case 'multiline-center':
|
|
557
|
+
return multilineLineCenterClasses;
|
|
558
|
+
case 'multiline-lift':
|
|
559
|
+
return multilineLineLiftClasses;
|
|
560
|
+
case 'multiline-fill':
|
|
561
|
+
return getMultilineFillClasses(theme);
|
|
562
|
+
case 'multiline-fill-ltr':
|
|
563
|
+
return getMultilineFillXClasses(theme);
|
|
564
|
+
case 'multiline-fill-rtl':
|
|
565
|
+
return getMultilineFillRtlClasses(theme);
|
|
566
|
+
case 'multiline-fill-center':
|
|
567
|
+
return getMultilineFillCenterClasses(theme);
|
|
568
|
+
case 'multiline-fill-lift':
|
|
569
|
+
return getMultilineFillLiftClasses(theme);
|
|
570
|
+
default:
|
|
571
|
+
return lineNormalClasses;
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
const linkClasses = getLinkClasses();
|
|
575
|
+
const LinkElement = as || Anchor;
|
|
576
|
+
return jsxRuntime.jsx(LinkElement, { ...props, className: twMerge(linkClasses, className), ref: ref });
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* # Button
|
|
581
|
+
* - A pre-styled button with utility props for easy customization depending on use case.
|
|
582
|
+
*/
|
|
583
|
+
function Button({ className, padding = 'md', rounded = 'lg', theme = 'blue', ref, ...props }) {
|
|
584
|
+
const getPaddingClasses = () => {
|
|
585
|
+
switch (padding) {
|
|
586
|
+
case 'xs':
|
|
587
|
+
return 'px-2 py-0.5';
|
|
588
|
+
case 'sm':
|
|
589
|
+
return 'px-4 py-1';
|
|
590
|
+
case 'md':
|
|
591
|
+
return 'px-6 py-1.5';
|
|
592
|
+
case 'lg':
|
|
593
|
+
return 'px-8 py-2';
|
|
594
|
+
case 'xl':
|
|
595
|
+
return 'px-12 py-3';
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
const getRoundedClasses = () => {
|
|
599
|
+
switch (rounded) {
|
|
600
|
+
case 'xs':
|
|
601
|
+
return 'rounded-sm';
|
|
602
|
+
case 'sm':
|
|
603
|
+
return 'rounded-md';
|
|
604
|
+
case 'md':
|
|
605
|
+
return 'rounded-lg';
|
|
606
|
+
case 'lg':
|
|
607
|
+
return 'rounded-xl';
|
|
608
|
+
case 'xl':
|
|
609
|
+
return 'rounded-3xl';
|
|
610
|
+
case 'full':
|
|
611
|
+
return 'rounded-full';
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
const getThemeClasses = () => {
|
|
615
|
+
const classList = [];
|
|
616
|
+
switch (theme) {
|
|
617
|
+
case 'blue':
|
|
618
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-blue/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-blue before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
619
|
+
break;
|
|
620
|
+
case 'blue-gradient':
|
|
621
|
+
classList.push(twSort('bg-ui-blue text-white shadow-lg shadow-ui-blue/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
622
|
+
break;
|
|
623
|
+
case 'brown':
|
|
624
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-brown/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-brown before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
625
|
+
break;
|
|
626
|
+
case 'brown-gradient':
|
|
627
|
+
classList.push(twSort('bg-ui-brown text-white shadow-lg shadow-ui-brown/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
628
|
+
break;
|
|
629
|
+
case 'green':
|
|
630
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-green/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-green before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
631
|
+
break;
|
|
632
|
+
case 'green-gradient':
|
|
633
|
+
classList.push(twSort('bg-ui-green text-white shadow-lg shadow-ui-green/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
634
|
+
break;
|
|
635
|
+
case 'grey':
|
|
636
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-grey/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-grey before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
637
|
+
break;
|
|
638
|
+
case 'grey-gradient':
|
|
639
|
+
classList.push(twSort('bg-ui-grey text-white shadow-lg shadow-ui-grey/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
640
|
+
break;
|
|
641
|
+
case 'sky-blue':
|
|
642
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-sky-blue/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-sky-blue before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
643
|
+
break;
|
|
644
|
+
case 'sky-blue-gradient':
|
|
645
|
+
classList.push(twSort('bg-ui-sky-blue text-white shadow-lg shadow-ui-sky-blue/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
646
|
+
break;
|
|
647
|
+
case 'magenta':
|
|
648
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-magenta/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-magenta before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
649
|
+
break;
|
|
650
|
+
case 'magenta-gradient':
|
|
651
|
+
classList.push(twSort('bg-ui-magenta text-white shadow-lg shadow-ui-magenta/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
652
|
+
break;
|
|
653
|
+
case 'neutral':
|
|
654
|
+
classList.push(twSort('pointer-fine:active:before:brightness-90text-white dark bg-zinc-200 text-black before:absolute before:inset-0 before:rounded-[inherit] before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 dark:bg-zinc-800 pointer-fine:hover:before:brightness-110'));
|
|
655
|
+
break;
|
|
656
|
+
case 'neutral-gradient':
|
|
657
|
+
classList.push(twSort('dark bg-linear-to-t from-zinc-300 via-zinc-200 to-zinc-100 text-black before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 dark:from-zinc-900 dark:via-zinc-800 dark:to-zinc-700 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
658
|
+
break;
|
|
659
|
+
case 'orange':
|
|
660
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-orange/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-orange before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
661
|
+
break;
|
|
662
|
+
case 'orange-gradient':
|
|
663
|
+
classList.push(twSort('bg-ui-orange text-white shadow-lg shadow-ui-orange/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
664
|
+
break;
|
|
665
|
+
case 'pink':
|
|
666
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-pink/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-pink before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
667
|
+
break;
|
|
668
|
+
case 'pink-gradient':
|
|
669
|
+
classList.push(twSort('before:to-white/75/75 bg-ui-pink text-white shadow-lg shadow-ui-pink/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
670
|
+
break;
|
|
671
|
+
case 'purple':
|
|
672
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-purple/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-purple before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
673
|
+
break;
|
|
674
|
+
case 'purple-gradient':
|
|
675
|
+
classList.push(twSort('bg-ui-purple text-white shadow-lg shadow-ui-purple/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
676
|
+
break;
|
|
677
|
+
case 'red':
|
|
678
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-red/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-red before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
679
|
+
break;
|
|
680
|
+
case 'red-gradient':
|
|
681
|
+
classList.push(twSort('bg-ui-red text-white shadow-lg shadow-ui-red/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
682
|
+
break;
|
|
683
|
+
case 'violet':
|
|
684
|
+
classList.push(twSort('text-white shadow-lg shadow-ui-violet/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-violet before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
685
|
+
break;
|
|
686
|
+
case 'violet-gradient':
|
|
687
|
+
classList.push(twSort('bg-ui-violet text-white shadow-lg shadow-ui-violet/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black/75 before:via-transparent before:to-white/75 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
688
|
+
break;
|
|
689
|
+
case 'yellow':
|
|
690
|
+
classList.push(twSort('text-black shadow-lg shadow-ui-yellow/25 transition-transform before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:bg-ui-yellow before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
691
|
+
break;
|
|
692
|
+
case 'yellow-gradient':
|
|
693
|
+
classList.push(twSort('bg-ui-yellow text-black shadow-lg shadow-ui-yellow/25 transition-transform before:absolute before:inset-0 before:rounded-[inherit] before:bg-linear-to-t before:from-black before:via-black/50 before:to-white/50 before:opacity-75 before:mix-blend-soft-light before:transition-[filter] before:duration-300 before:ease-exponential active:before:brightness-90 pointer-fine:hover:before:brightness-110 pointer-fine:active:before:brightness-90'));
|
|
694
|
+
break;
|
|
695
|
+
}
|
|
696
|
+
return classList.join(' ');
|
|
697
|
+
};
|
|
698
|
+
const paddingClasses = getPaddingClasses(), roundedClasses = getRoundedClasses(), themeClasses = getThemeClasses();
|
|
699
|
+
const buttonClasses = twMerge([
|
|
700
|
+
'block w-fit min-w-fit text-center font-semibold duration-300 ease-exponential focus-visible:scale-101 active:scale-95 pointer-fine:hover:scale-101 pointer-fine:active:scale-99',
|
|
701
|
+
paddingClasses,
|
|
702
|
+
roundedClasses,
|
|
703
|
+
themeClasses,
|
|
704
|
+
className,
|
|
705
|
+
]);
|
|
706
|
+
return 'href' in props && typeof props.href === 'string' ? (jsxRuntime.jsx(Anchor, { ref: ref, ...props, className: buttonClasses })) : (jsxRuntime.jsx(react$1.Button, { ref: ref, ...props, className: buttonClasses }));
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
function createFastContext(defaultInitialState) {
|
|
710
|
+
function useStoreData(initialState = defaultInitialState) {
|
|
711
|
+
const store = react.useRef(initialState), get = () => store.current, subscribers = react.useRef(new Set());
|
|
712
|
+
const set = (value) => {
|
|
713
|
+
if (typeof value === 'function') {
|
|
714
|
+
store.current = value(store.current);
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
store.current = value;
|
|
718
|
+
}
|
|
719
|
+
subscribers.current.forEach(callback => callback());
|
|
720
|
+
};
|
|
721
|
+
const subscribe = (callback) => {
|
|
722
|
+
subscribers.current.add(callback);
|
|
723
|
+
return () => subscribers.current.delete(callback);
|
|
724
|
+
};
|
|
725
|
+
return {
|
|
726
|
+
get,
|
|
727
|
+
set,
|
|
728
|
+
subscribe,
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
const StoreContext = react.createContext(null);
|
|
732
|
+
function Provider({ initialValue = defaultInitialState, ...props }) {
|
|
733
|
+
return jsxRuntime.jsx(StoreContext.Provider, { value: useStoreData(initialValue), ...props });
|
|
734
|
+
}
|
|
735
|
+
function useStore(selector, initialValue) {
|
|
736
|
+
const store = react.useContext(StoreContext);
|
|
737
|
+
if (!store) {
|
|
738
|
+
const localStoreValue = initialValue !== undefined ? initialValue : defaultInitialState;
|
|
739
|
+
const selectedValue = selector(localStoreValue);
|
|
740
|
+
const noOpSet = () => console.warn('Attempting to set store value outside of Provider');
|
|
741
|
+
return [selectedValue, noOpSet];
|
|
742
|
+
}
|
|
743
|
+
const state = react.useSyncExternalStore(store.subscribe, () => selector(store.get()), () => selector(initialValue !== undefined ? initialValue : defaultInitialState));
|
|
744
|
+
return [state, store.set];
|
|
745
|
+
}
|
|
746
|
+
return {
|
|
747
|
+
Provider,
|
|
748
|
+
useStore,
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* # Define Field
|
|
754
|
+
*
|
|
755
|
+
* This is a helper function to define a field in a form context with type safety.
|
|
756
|
+
*/
|
|
757
|
+
function defineField(fieldDefinition) {
|
|
758
|
+
return fieldDefinition;
|
|
759
|
+
}
|
|
760
|
+
const { Provider: Provider$1, useStore: useStore$1 } = createFastContext([]);
|
|
761
|
+
function FormContextProvider({ children }) {
|
|
762
|
+
return jsxRuntime.jsx(Provider$1, { children: children });
|
|
763
|
+
}
|
|
764
|
+
function useFormContext() {
|
|
765
|
+
return useStore$1(store => store);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
const DEFAULT_STATUS = 'incomplete';
|
|
769
|
+
const { Provider, useStore } = createFastContext(DEFAULT_STATUS);
|
|
770
|
+
function FormStatusProvider({ children, initialStatus = DEFAULT_STATUS, }) {
|
|
771
|
+
return (jsxRuntime.jsx(react.Suspense, { children: jsxRuntime.jsx(Provider, { initialValue: initialStatus, children: children }) }));
|
|
772
|
+
}
|
|
773
|
+
function useFormStatus() {
|
|
774
|
+
return useStore(store => store);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
function validateField$1(value, { required, type }) {
|
|
778
|
+
const noValue = !value || value === '';
|
|
779
|
+
if (!required && noValue)
|
|
780
|
+
return true;
|
|
781
|
+
if (noValue)
|
|
782
|
+
return false;
|
|
783
|
+
switch (type) {
|
|
784
|
+
case 'email':
|
|
785
|
+
return isEmail(value);
|
|
786
|
+
case 'number':
|
|
787
|
+
return !isNaN(Number(value));
|
|
788
|
+
case 'tel':
|
|
789
|
+
return isPhoneNumber(value);
|
|
790
|
+
default:
|
|
791
|
+
return true;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
function Input({ checked, className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, name, onBlur, onChange, placeholder, ref, required = true, type, value, ...props }) {
|
|
795
|
+
const [formContext, setFormContext] = useFormContext();
|
|
796
|
+
if (placeholder === '*')
|
|
797
|
+
placeholder = name + (required && !label ? '*' : '');
|
|
798
|
+
if (label === '*')
|
|
799
|
+
label = name;
|
|
800
|
+
const uniqueID = react.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
|
|
801
|
+
if (Boolean(formContext?.find(field => field.id === fieldContextID)?.invalid))
|
|
802
|
+
invalid = true;
|
|
803
|
+
const getFieldContextType = () => {
|
|
804
|
+
switch (type) {
|
|
805
|
+
case 'email':
|
|
806
|
+
return 'email';
|
|
807
|
+
case 'file':
|
|
808
|
+
return 'file';
|
|
809
|
+
case 'number':
|
|
810
|
+
return 'number';
|
|
811
|
+
case 'tel':
|
|
812
|
+
return 'tel';
|
|
813
|
+
case 'url':
|
|
814
|
+
return 'url';
|
|
815
|
+
default:
|
|
816
|
+
return 'string';
|
|
817
|
+
}
|
|
818
|
+
};
|
|
819
|
+
const fieldContextType = getFieldContextType();
|
|
820
|
+
const initialFieldContext = defineField({
|
|
821
|
+
type: fieldContextType,
|
|
822
|
+
id: fieldContextID,
|
|
823
|
+
invalid,
|
|
824
|
+
name,
|
|
825
|
+
required,
|
|
826
|
+
value: value ? `${value}` : defaultValue ? `${defaultValue}` : '',
|
|
827
|
+
});
|
|
828
|
+
react.useEffect(() => {
|
|
829
|
+
if (!setFormContext)
|
|
830
|
+
return;
|
|
831
|
+
setFormContext(prevContext => {
|
|
832
|
+
const otherFields = (prevContext || []).filter(field => field.id !== initialFieldContext.id);
|
|
833
|
+
return [...otherFields, initialFieldContext];
|
|
834
|
+
});
|
|
835
|
+
return () => {
|
|
836
|
+
setFormContext(prevContext => (prevContext || []).filter(field => field.id !== initialFieldContext.id));
|
|
837
|
+
};
|
|
838
|
+
}, [setFormContext]);
|
|
839
|
+
const fieldContext = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id) || initialFieldContext;
|
|
840
|
+
const debounceTimerRef = react.useRef(undefined);
|
|
841
|
+
const handleChange = e => {
|
|
842
|
+
if (disabled) {
|
|
843
|
+
e.preventDefault();
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
clearTimeout(debounceTimerRef.current);
|
|
847
|
+
const { currentTarget } = e, { value: newValue } = currentTarget;
|
|
848
|
+
setFormContext?.(prevContext => {
|
|
849
|
+
if (!prevContext)
|
|
850
|
+
return [];
|
|
851
|
+
const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
852
|
+
if (!field)
|
|
853
|
+
throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
|
|
854
|
+
const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
|
|
855
|
+
const updatedField = { ...field, value: newValue };
|
|
856
|
+
return [...otherFields, updatedField];
|
|
857
|
+
});
|
|
858
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
859
|
+
const field = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
860
|
+
if (!field)
|
|
861
|
+
return;
|
|
862
|
+
const invalid = validateField$1(newValue, field) === false;
|
|
863
|
+
if (invalid !== field.invalid)
|
|
864
|
+
setFormContext?.(prevContext => {
|
|
865
|
+
if (!prevContext)
|
|
866
|
+
return [];
|
|
867
|
+
const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
868
|
+
if (!field)
|
|
869
|
+
throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
|
|
870
|
+
const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
|
|
871
|
+
const updatedField = { ...field, invalid };
|
|
872
|
+
return [...otherFields, updatedField];
|
|
873
|
+
});
|
|
874
|
+
}, 500);
|
|
875
|
+
onChange?.(e);
|
|
876
|
+
};
|
|
877
|
+
const handleBlur = e => {
|
|
878
|
+
if (disabled) {
|
|
879
|
+
e.preventDefault();
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
const { currentTarget } = e, { value: newValue } = currentTarget;
|
|
883
|
+
switch (type) {
|
|
884
|
+
case 'email':
|
|
885
|
+
setFormContext?.(prevContext => {
|
|
886
|
+
if (!prevContext)
|
|
887
|
+
return [];
|
|
888
|
+
const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
889
|
+
if (!field)
|
|
890
|
+
throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
|
|
891
|
+
const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
|
|
892
|
+
const updatedField = { ...field, value: newValue.toLowerCase() };
|
|
893
|
+
return [...otherFields, updatedField];
|
|
894
|
+
});
|
|
895
|
+
break;
|
|
896
|
+
case 'tel':
|
|
897
|
+
setFormContext?.(prevContext => {
|
|
898
|
+
if (!prevContext)
|
|
899
|
+
return [];
|
|
900
|
+
const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
901
|
+
if (!field)
|
|
902
|
+
throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
|
|
903
|
+
const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
|
|
904
|
+
const updatedField = { ...field, value: formatPhoneNumber(newValue, '1') };
|
|
905
|
+
return [...otherFields, updatedField];
|
|
906
|
+
});
|
|
907
|
+
break;
|
|
908
|
+
}
|
|
909
|
+
onBlur?.(e);
|
|
910
|
+
};
|
|
911
|
+
const restFieldProps = fieldProps
|
|
912
|
+
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !== 'className'))
|
|
913
|
+
: {};
|
|
914
|
+
const restLabelProps = labelProps
|
|
915
|
+
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !== 'className'))
|
|
916
|
+
: {};
|
|
917
|
+
const restDescriptionProps = descriptionProps
|
|
918
|
+
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== 'className'))
|
|
919
|
+
: {};
|
|
920
|
+
return (jsxRuntime.jsxs(react$1.Field, { ...restFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react$1.Label, { ...restLabelProps, className: bag => twMerge('text-sm font-medium', required ? 'after:text-ui-red after:content-["_*"]' : '', typeof labelProps?.className === 'function' ? labelProps?.className(bag) : labelProps?.className), children: label })), jsxRuntime.jsx(react$1.Input, { ...props, className: bag => twMerge(
|
|
921
|
+
// Base styles
|
|
922
|
+
'rounded-xl border-1 border-neutral-500/50 bg-neutral-100 py-1 pl-2 text-neutral-950 outline-offset-1 outline-ui-sky-blue/95 transition-[background-color] duration-300 ease-exponential dark:bg-neutral-700 dark:text-neutral-50',
|
|
923
|
+
// Pseudo styles
|
|
924
|
+
'focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800',
|
|
925
|
+
// user-invalid styles
|
|
926
|
+
'user-invalid:border-ui-red user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-100))] user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-800))] dark:user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))] user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-100))] user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))]',
|
|
927
|
+
// Custom styles
|
|
928
|
+
typeof className === 'function' ? className(bag) : className), id: fieldContext?.id, invalid: invalid, onBlur: handleBlur, onChange: handleChange, placeholder: placeholder, ref: ref, required: required, type: type, value: fieldContext?.value }), description && (jsxRuntime.jsx(react$1.Description, { ...restDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
|
|
929
|
+
? descriptionProps?.className(bag)
|
|
930
|
+
: descriptionProps?.className), children: description }))] }));
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
function SubmitButton({ children, className, error, incomplete, loading, success, theme, type = 'submit', ref, ...props }) {
|
|
934
|
+
const [formStatus] = useFormStatus();
|
|
935
|
+
const getFormStatusButtonClasses = () => {
|
|
936
|
+
switch (formStatus) {
|
|
937
|
+
case 'loading':
|
|
938
|
+
return twSort('animate-pulse cursor-wait text-lg leading-6 font-black tracking-widest');
|
|
939
|
+
case 'error':
|
|
940
|
+
case 'success':
|
|
941
|
+
return 'cursor-not-allowed';
|
|
942
|
+
default:
|
|
943
|
+
return undefined;
|
|
944
|
+
}
|
|
945
|
+
};
|
|
946
|
+
const formStatusButtonClasses = getFormStatusButtonClasses();
|
|
947
|
+
const getFormStatusButtonTheme = () => {
|
|
948
|
+
switch (formStatus) {
|
|
949
|
+
case 'incomplete':
|
|
950
|
+
return 'grey';
|
|
951
|
+
case 'loading':
|
|
952
|
+
return 'blue';
|
|
953
|
+
case 'error':
|
|
954
|
+
return 'red';
|
|
955
|
+
case 'success':
|
|
956
|
+
return 'green';
|
|
957
|
+
default:
|
|
958
|
+
return theme;
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
const formStatusButtonTheme = getFormStatusButtonTheme();
|
|
962
|
+
const getButtonText = () => {
|
|
963
|
+
switch (formStatus) {
|
|
964
|
+
case 'incomplete':
|
|
965
|
+
return incomplete || 'Complete Form';
|
|
966
|
+
case 'loading':
|
|
967
|
+
return (loading || (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: 'inline-block animate-wave animation-delay-300', children: "\u2022" }), jsxRuntime.jsx("span", { className: 'inline-block animate-wave animation-delay-150', children: "\u2022" }), jsxRuntime.jsx("span", { className: 'inline-block animate-wave', children: "\u2022" })] })));
|
|
968
|
+
case 'error':
|
|
969
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [error || 'Error', ' ', jsxRuntime.jsx("span", { className: 'absolute top-1/2 ml-1.5 translate-y-[calc(-50%-1.5px)] text-2xl', children: "\u00D7" })] }));
|
|
970
|
+
case 'success':
|
|
971
|
+
return success || 'Successfully Submitted';
|
|
972
|
+
default:
|
|
973
|
+
return children || 'Submit';
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
const buttonText = getButtonText();
|
|
977
|
+
return (jsxRuntime.jsx(Button, { ...props, className: twMerge([formStatusButtonClasses, 'w-full', className]), ref: ref, theme: formStatusButtonTheme, type: type, children: buttonText }));
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
function validateField(value, { required }) {
|
|
981
|
+
const noValue = !value || value === '';
|
|
982
|
+
if (!required && noValue)
|
|
983
|
+
return true;
|
|
984
|
+
if (noValue)
|
|
985
|
+
return false;
|
|
986
|
+
return true;
|
|
987
|
+
}
|
|
988
|
+
function Textarea({ className, defaultValue, description, descriptionProps, disabled, fieldProps, invalid = true, label, labelProps, name, onBlur, onChange, placeholder, ref, required = true, value, ...props }) {
|
|
989
|
+
const [formContext, setFormContext] = useFormContext();
|
|
990
|
+
if (placeholder === '*')
|
|
991
|
+
placeholder = name + (required && !label ? '*' : '');
|
|
992
|
+
if (label === '*')
|
|
993
|
+
label = name;
|
|
994
|
+
const uniqueID = react.useId(), fieldContextID = toLowerCase(name, [, '_']) + '§' + uniqueID;
|
|
995
|
+
if (Boolean(formContext?.find(field => field.id === fieldContextID)?.invalid))
|
|
996
|
+
invalid = true;
|
|
997
|
+
const initialFieldContext = defineField({
|
|
998
|
+
type: 'textarea',
|
|
999
|
+
id: fieldContextID,
|
|
1000
|
+
invalid,
|
|
1001
|
+
name,
|
|
1002
|
+
required,
|
|
1003
|
+
value: value ? `${value}` : defaultValue ? `${defaultValue}` : '',
|
|
1004
|
+
});
|
|
1005
|
+
react.useEffect(() => {
|
|
1006
|
+
if (!setFormContext)
|
|
1007
|
+
return;
|
|
1008
|
+
setFormContext(prevContext => {
|
|
1009
|
+
const otherFields = (prevContext || []).filter(field => field.id !== initialFieldContext.id);
|
|
1010
|
+
return [...otherFields, initialFieldContext];
|
|
1011
|
+
});
|
|
1012
|
+
return () => {
|
|
1013
|
+
setFormContext(prevContext => (prevContext || []).filter(field => field.id !== initialFieldContext.id));
|
|
1014
|
+
};
|
|
1015
|
+
}, [setFormContext]);
|
|
1016
|
+
const fieldContext = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id) || initialFieldContext;
|
|
1017
|
+
const debounceTimerRef = react.useRef(undefined);
|
|
1018
|
+
const handleChange = e => {
|
|
1019
|
+
if (disabled) {
|
|
1020
|
+
e.preventDefault();
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
clearTimeout(debounceTimerRef.current);
|
|
1024
|
+
const { currentTarget } = e, { value: newValue } = currentTarget;
|
|
1025
|
+
setFormContext?.(prevContext => {
|
|
1026
|
+
if (!prevContext)
|
|
1027
|
+
return [];
|
|
1028
|
+
const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
1029
|
+
if (!field)
|
|
1030
|
+
throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
|
|
1031
|
+
const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
|
|
1032
|
+
const updatedField = { ...field, value: newValue };
|
|
1033
|
+
return [...otherFields, updatedField];
|
|
1034
|
+
});
|
|
1035
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
1036
|
+
const field = formContext?.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
1037
|
+
if (!field)
|
|
1038
|
+
return;
|
|
1039
|
+
const invalid = validateField(newValue, field) === false;
|
|
1040
|
+
if (invalid !== field.invalid)
|
|
1041
|
+
setFormContext?.(prevContext => {
|
|
1042
|
+
if (!prevContext)
|
|
1043
|
+
return [];
|
|
1044
|
+
const field = prevContext.find(({ id: fieldID }) => fieldID === initialFieldContext.id);
|
|
1045
|
+
if (!field)
|
|
1046
|
+
throw new Error(`Field with id "${initialFieldContext.id}" not found in form context.`);
|
|
1047
|
+
const otherFields = prevContext.filter(({ id: fieldID }) => fieldID !== initialFieldContext.id);
|
|
1048
|
+
const updatedField = { ...field, invalid };
|
|
1049
|
+
return [...otherFields, updatedField];
|
|
1050
|
+
});
|
|
1051
|
+
}, 500);
|
|
1052
|
+
onChange?.(e);
|
|
1053
|
+
};
|
|
1054
|
+
const restFieldProps = fieldProps
|
|
1055
|
+
? Object.fromEntries(Object.entries(fieldProps).filter(([key]) => key !== 'className'))
|
|
1056
|
+
: {};
|
|
1057
|
+
const restLabelProps = labelProps
|
|
1058
|
+
? Object.fromEntries(Object.entries(labelProps).filter(([key]) => key !== 'className'))
|
|
1059
|
+
: {};
|
|
1060
|
+
const restDescriptionProps = descriptionProps
|
|
1061
|
+
? Object.fromEntries(Object.entries(descriptionProps).filter(([key]) => key !== 'className'))
|
|
1062
|
+
: {};
|
|
1063
|
+
return (jsxRuntime.jsxs(react$1.Field, { ...restFieldProps, className: bag => twMerge('grid gap-1', typeof fieldProps?.className === 'function' ? fieldProps?.className(bag) : fieldProps?.className), disabled: disabled, children: [label && (jsxRuntime.jsx(react$1.Label, { ...restLabelProps, className: bag => twMerge('text-sm font-medium', required ? 'after:text-ui-red after:content-["_*"]' : '', typeof labelProps?.className === 'function' ? labelProps?.className(bag) : labelProps?.className), children: label })), jsxRuntime.jsx(react$1.Textarea, { ...props, className: bag => twMerge(
|
|
1064
|
+
// Base styles
|
|
1065
|
+
'field-sizing-content resize-none rounded-xl border-1 border-neutral-500/50 bg-neutral-100 py-1 pl-2 text-neutral-950 outline-offset-1 outline-ui-sky-blue/95 transition-[background-color] duration-300 ease-exponential dark:bg-neutral-700 dark:text-neutral-50',
|
|
1066
|
+
// Pseudo styles
|
|
1067
|
+
'focus-visible:bg-neutral-50 focus-visible:outline-3 active:bg-neutral-200 dark:focus-visible:bg-neutral-600 dark:active:bg-neutral-800 pointer-fine:hover:bg-neutral-50 pointer-fine:active:bg-neutral-200 dark:pointer-fine:hover:bg-neutral-600 dark:pointer-fine:active:bg-neutral-800',
|
|
1068
|
+
// user-invalid styles
|
|
1069
|
+
'user-invalid:border-ui-red user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-100))] user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:bg-[color-mix(in_oklab,var(--color-ui-red)_20%,var(--color-neutral-800))] dark:user-invalid:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))] user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-100))] user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-100))] user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-100))] dark:user-invalid:pointer-fine:hover:bg-[color-mix(in_oklab,var(--color-ui-red)_10%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:focus-visible:bg-[color-mix(in_oklab,var(--color-ui-red)_1%,var(--color-neutral-800))] dark:user-invalid:pointer-fine:active:bg-[color-mix(in_oklab,var(--color-ui-red)_25%,var(--color-neutral-800))]',
|
|
1070
|
+
// Custom styles
|
|
1071
|
+
typeof className === 'function' ? className(bag) : className), id: fieldContext?.id, invalid: invalid, onChange: handleChange, placeholder: placeholder, ref: ref, required: required, value: fieldContext?.value }), description && (jsxRuntime.jsx(react$1.Description, { ...restDescriptionProps, className: bag => twMerge('text-xs', typeof descriptionProps?.className === 'function'
|
|
1072
|
+
? descriptionProps?.className(bag)
|
|
1073
|
+
: descriptionProps?.className), children: description }))] }));
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// import { findComponentByType } from '../../utils'
|
|
1077
|
+
function FormComponent({ as, children, className, handleSubmit, onError, onSubmit, onSuccess, ...props }) {
|
|
1078
|
+
const [formContext] = useFormContext(), [formStatus, setFormStatus] = useFormStatus();
|
|
1079
|
+
// const submitButton = findComponentByType(children, SubmitButton)
|
|
1080
|
+
react.useEffect(() => {
|
|
1081
|
+
if (!formContext)
|
|
1082
|
+
return;
|
|
1083
|
+
if (formStatus !== 'incomplete' && formContext.find(({ invalid }) => invalid))
|
|
1084
|
+
setFormStatus?.('incomplete');
|
|
1085
|
+
if (formStatus !== 'ready' && formContext.every(({ invalid }) => !invalid))
|
|
1086
|
+
setFormStatus?.('ready');
|
|
1087
|
+
}, [formContext]);
|
|
1088
|
+
const processSubmit = handleSubmit ||
|
|
1089
|
+
(async (e) => {
|
|
1090
|
+
e.preventDefault();
|
|
1091
|
+
e.stopPropagation();
|
|
1092
|
+
setFormStatus?.('loading');
|
|
1093
|
+
const response = await onSubmit?.({ event: e, formContext });
|
|
1094
|
+
if (response && ('error' in response || response.status === 'error')) {
|
|
1095
|
+
setFormStatus?.('error');
|
|
1096
|
+
onError?.({ event: e, error: response.error || 'An error occurred when submitting the form.' });
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
if ((response && response.status === 'success') || !response) {
|
|
1100
|
+
setFormStatus?.('success');
|
|
1101
|
+
onSuccess?.({ event: e });
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
const FormElement = as || 'form';
|
|
1105
|
+
return (jsxRuntime.jsx(FormElement, { ...props, className: twMerge(className, 'grid gap-3'), onSubmit: processSubmit, children: children }));
|
|
1106
|
+
}
|
|
1107
|
+
function Form({ controlled = 'auto', initialStatus = 'incomplete', ...props }) {
|
|
1108
|
+
const FormContextOrNotProvider = controlled === 'auto' ? FormContextProvider : react.Fragment;
|
|
1109
|
+
return (jsxRuntime.jsx(FormStatusProvider, { initialStatus: initialStatus, children: jsxRuntime.jsx(FormContextOrNotProvider, { children: jsxRuntime.jsx(FormComponent, { ...props }) }) }));
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
function Ghost({ children, className, ...props }) {
|
|
1113
|
+
return (jsxRuntime.jsx("div", { ...props, className: twMerge('block w-24 max-w-full animate-pulse rounded bg-white/50', className), children: children || jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u00A0" }) }));
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
function getTextFromChildren(children) {
|
|
1117
|
+
let text = '';
|
|
1118
|
+
react.Children.forEach(children, child => {
|
|
1119
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
1120
|
+
text += child;
|
|
1121
|
+
}
|
|
1122
|
+
else if (react.isValidElement(child)) {
|
|
1123
|
+
text += getTextFromChildren(child.props.children);
|
|
1124
|
+
}
|
|
1125
|
+
});
|
|
1126
|
+
return text;
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* # Heading
|
|
1130
|
+
* A heading component that renders HTML heading elements (h1-h6) with appropriate styling.
|
|
1131
|
+
* Automatically generates an ID for the heading based on its content if none is provided.
|
|
1132
|
+
*/
|
|
1133
|
+
function Heading({ as = 'h2', children, customize, className, id, ref, ...props }) {
|
|
1134
|
+
const H = as;
|
|
1135
|
+
const targetableID = id || getTextFromChildren(children).replace(/\s+/g, '-').toLowerCase();
|
|
1136
|
+
const getBaseClasses = () => {
|
|
1137
|
+
switch (as) {
|
|
1138
|
+
case 'h1':
|
|
1139
|
+
return customize?.h1 || twSort('pb-2.5 text-6xl font-black last:pb-0');
|
|
1140
|
+
case 'h3':
|
|
1141
|
+
return customize?.h3 || twSort('pb-2 text-4xl font-extralight last:pb-0');
|
|
1142
|
+
case 'h4':
|
|
1143
|
+
return customize?.h4 || twSort('pb-2 text-3xl font-extrabold last:pb-0');
|
|
1144
|
+
case 'h5':
|
|
1145
|
+
return customize?.h5 || twSort('pb-1.5 text-2xl font-semibold last:pb-0');
|
|
1146
|
+
case 'h6':
|
|
1147
|
+
return customize?.h6 || twSort('pb-1 text-xl font-bold last:pb-0');
|
|
1148
|
+
default:
|
|
1149
|
+
return customize?.h2 || twSort('pb-2.5 text-5xl font-medium last:pb-0');
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
const baseClasses = getBaseClasses();
|
|
1153
|
+
return (jsxRuntime.jsx(H, { ref: ref, id: targetableID, ...props, className: twMerge(baseClasses, className), children: children }));
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
function xmark(props) {
|
|
1157
|
+
return (jsxRuntime.jsx("svg", { viewBox: '0 0 64 64', ...props, children: jsxRuntime.jsx("path", { d: 'M1,63c0.7,0.7,1.6,1,2.6,1s1.9-0.3,2.6-1L32,37.1L57.8,63c0.7,0.7,1.5,1,2.5,1c1,0,1.9-0.3,2.6-1c0.7-0.7,1-1.6,1-2.6 c0-1-0.3-1.8-1-2.5L37.1,32L63,6.2c0.7-0.7,1-1.6,1-2.6S63.7,1.7,63,1c-0.7-0.7-1.6-1-2.6-1c-1,0-1.8,0.3-2.5,1L32,26.9L6.2,1 C5.5,0.3,4.6,0,3.6,0C2.6,0,1.7,0.3,1,1C0.3,1.7,0,2.6,0,3.6c0,1,0.3,1.9,1,2.6L26.9,32L1,57.8c-0.7,0.7-1,1.5-1,2.6 C0,61.4,0.3,62.3,1,63z' }) }));
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
function ModalTrigger({ as, ...props }) {
|
|
1161
|
+
const Element = as || react$1.Button;
|
|
1162
|
+
return jsxRuntime.jsx(Element, { ...props });
|
|
1163
|
+
}
|
|
1164
|
+
function ModalDialog(props) {
|
|
1165
|
+
return jsxRuntime.jsx("div", { ...props });
|
|
1166
|
+
}
|
|
1167
|
+
function Modal({ children, className, onClose, onOpen, place = 'bottom' }) {
|
|
1168
|
+
const [bodyElement, setBodyElement] = react.useState(null);
|
|
1169
|
+
react.useEffect(() => {
|
|
1170
|
+
if (!bodyElement && typeof window !== 'undefined')
|
|
1171
|
+
setBodyElement(document.body);
|
|
1172
|
+
}, [bodyElement]);
|
|
1173
|
+
const [isOpen, setIsOpen] = react.useState(false);
|
|
1174
|
+
const dialogPanelRef = react.useRef(null), dragMoveBoxRef = react.useRef(null),
|
|
1175
|
+
// lastTouchYRef = useRef(0),
|
|
1176
|
+
startDragCoords = react.useRef({ x: 0, y: 0 });
|
|
1177
|
+
const [allowDragClose, setAllowDragClose] = react.useState(false), [readyToClose, setReadyToClose] = react.useState(false);
|
|
1178
|
+
const openModal = () => {
|
|
1179
|
+
console.log('open');
|
|
1180
|
+
setIsOpen(true);
|
|
1181
|
+
onOpen?.();
|
|
1182
|
+
};
|
|
1183
|
+
const closeModal = () => {
|
|
1184
|
+
console.log('close');
|
|
1185
|
+
setIsOpen(false);
|
|
1186
|
+
onClose?.();
|
|
1187
|
+
};
|
|
1188
|
+
const enableClose = (clientX, clientY) => {
|
|
1189
|
+
startDragCoords.current.x = clientX;
|
|
1190
|
+
startDragCoords.current.y = clientY;
|
|
1191
|
+
dialogPanelRef.current.style.transitionDuration = '0s';
|
|
1192
|
+
setAllowDragClose(true);
|
|
1193
|
+
};
|
|
1194
|
+
const enableTouchClose = e => {
|
|
1195
|
+
const { touches } = e, touch = touches[0], { clientY } = touch;
|
|
1196
|
+
enableClose(0, clientY);
|
|
1197
|
+
};
|
|
1198
|
+
const enableMouseClose = e => {
|
|
1199
|
+
const { clientX, clientY } = e;
|
|
1200
|
+
enableClose(clientX, clientY);
|
|
1201
|
+
};
|
|
1202
|
+
const handleMove = (clientX, clientY) => {
|
|
1203
|
+
if (!dialogPanelRef.current)
|
|
1204
|
+
return;
|
|
1205
|
+
let deltaX = clientX - startDragCoords.current.x, deltaY = clientY - startDragCoords.current.y;
|
|
1206
|
+
if (deltaX > 0)
|
|
1207
|
+
deltaX = easeOutExpo(Math.abs(deltaX), 0, 25, 5000);
|
|
1208
|
+
if (deltaX < 0)
|
|
1209
|
+
deltaX = -easeOutExpo(Math.abs(deltaX), 0, 25, 5000);
|
|
1210
|
+
if (deltaY < 0)
|
|
1211
|
+
deltaY = -easeOutExpo(Math.abs(deltaY), 0, 25, 2000);
|
|
1212
|
+
if (deltaY >= 100 && !readyToClose) {
|
|
1213
|
+
setReadyToClose(true);
|
|
1214
|
+
}
|
|
1215
|
+
else if (deltaY < 100 && readyToClose) {
|
|
1216
|
+
setReadyToClose(false);
|
|
1217
|
+
}
|
|
1218
|
+
const greaterThanMediaSmall = innerWidth > 640;
|
|
1219
|
+
dialogPanelRef.current.style.translate = `calc(-50% + ${deltaX}px) ${greaterThanMediaSmall ? `calc(-50% + ${deltaY}px)` : `${deltaY}px`}`;
|
|
1220
|
+
};
|
|
1221
|
+
const handleMouseMove = e => {
|
|
1222
|
+
if (!allowDragClose)
|
|
1223
|
+
return;
|
|
1224
|
+
const { clientX, clientY } = e;
|
|
1225
|
+
handleMove(clientX, clientY);
|
|
1226
|
+
};
|
|
1227
|
+
const disableDragClose = (clientY) => {
|
|
1228
|
+
const deltaY = clientY - startDragCoords.current.y;
|
|
1229
|
+
dialogPanelRef.current.style.transitionDuration = '';
|
|
1230
|
+
if (deltaY >= 100) {
|
|
1231
|
+
closeModal();
|
|
1232
|
+
setReadyToClose(false);
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
setTimeout(() => (dialogPanelRef.current.style.removeProperty('translate'), 50));
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
const disableMouseDragClose = e => {
|
|
1239
|
+
if (allowDragClose)
|
|
1240
|
+
setAllowDragClose(false);
|
|
1241
|
+
const { clientY } = e;
|
|
1242
|
+
disableDragClose(clientY);
|
|
1243
|
+
};
|
|
1244
|
+
const content = typeof children === 'function' ? children({ openModal, closeModal }) : children;
|
|
1245
|
+
const dialogElement = findComponentByType(content, ModalDialog);
|
|
1246
|
+
if (!dialogElement)
|
|
1247
|
+
throw new Error('ModalDialog must be defined in Modal children');
|
|
1248
|
+
let triggerElement = null;
|
|
1249
|
+
if (typeof children !== 'function') {
|
|
1250
|
+
triggerElement = findComponentByType(content, ModalTrigger);
|
|
1251
|
+
if (!triggerElement)
|
|
1252
|
+
throw new Error('ModalTrigger must be provided when not using render prop pattern');
|
|
1253
|
+
}
|
|
1254
|
+
else {
|
|
1255
|
+
triggerElement = findComponentByType(content, ModalTrigger);
|
|
1256
|
+
}
|
|
1257
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [allowDragClose &&
|
|
1258
|
+
bodyElement &&
|
|
1259
|
+
reactDom.createPortal(jsxRuntime.jsx("div", { ref: dragMoveBoxRef, className: 'z-99 pointer-coarse:hidden fixed inset-0 h-dvh w-screen bg-transparent active:cursor-grabbing', onMouseMove: handleMouseMove, onMouseUp: disableMouseDragClose }), bodyElement), triggerElement &&
|
|
1260
|
+
react.cloneElement(triggerElement, { onClick: openModal }), jsxRuntime.jsxs(react$1.Dialog, { open: isOpen, onClose: closeModal, className: [
|
|
1261
|
+
'isolate z-50',
|
|
1262
|
+
place === 'bottom' &&
|
|
1263
|
+
'after:fixed after:inset-x-0 after:bottom-0 after:-z-10 after:h-16 after:bg-neutral-50 sm:after:hidden',
|
|
1264
|
+
].join(' '), children: [jsxRuntime.jsx(react$1.DialogBackdrop, { transition: true, className: [
|
|
1265
|
+
'duration-750 ease-exponential data-closed:opacity-0 fixed inset-0 cursor-pointer transition-[opacity_background-color_backdrop-filter_-webkit-backdrop-filter] delay-100',
|
|
1266
|
+
readyToClose
|
|
1267
|
+
? 'bg-neutral-50/5 backdrop-blur-[1px] dark:bg-neutral-950/5'
|
|
1268
|
+
: 'bg-neutral-50/25 backdrop-blur-sm dark:bg-neutral-950/25',
|
|
1269
|
+
].join(' '), children: jsxRuntime.jsx(Button, { theme: 'blue', padding: 'none', rounded: 'full', className: 'group/button pointer-fine:hover:w-20 fixed right-4 top-4 h-7 w-7 overflow-x-hidden transition-[scale_width_filter]', children: jsxRuntime.jsxs("div", { className: 'pointer-fine:group-hover/button:-translate-x-0.5 ease-exponential absolute right-1 top-1 flex items-center gap-1 pt-px transition-transform duration-300', children: [jsxRuntime.jsxs("span", { className: 'block text-xs font-medium uppercase leading-none text-neutral-50', children: ["Close", jsxRuntime.jsx("span", { className: 'sr-only', children: " Modal" })] }), jsxRuntime.jsx(xmark, { className: '-top-px block size-5 rotate-90 scale-75 fill-white stroke-white stroke-1 transition-transform duration-300 ease-in-out group-hover/button:rotate-0' })] }) }) }), jsxRuntime.jsxs(react$1.DialogPanel, { ref: dialogPanelRef, transition: true, className: twMerge('duration-750 ease-exponential data-closed:opacity-0 data-closed:scale-50 fixed left-1/2 -translate-x-1/2 overflow-y-scroll bg-neutral-50 p-4 shadow-[0_-15px_50px_-12px] shadow-neutral-950/25 transition-[transform_translate_opacity] sm:w-[calc(100vw-2rem)] sm:max-w-fit sm:p-6 sm:shadow-2xl lg:p-8 dark:bg-neutral-900', place === 'center'
|
|
1270
|
+
? 'data-enter:translate-y-[calc(-50%+12rem)] data-leave:translate-y-[calc(-50%-8rem)] top-1/2 -translate-y-1/2 rounded-2xl'
|
|
1271
|
+
: 'rounded-t-4xl pointer-fine:top-1/2 pointer-fine:bottom-auto pointer-fine:-translate-y-1/2 pointer-fine:rounded-2xl data-enter:translate-y-full sm:data-enter:translate-y-[calc(-50%+12rem)] data-leave:translate-y-full sm:data-leave:translate-y-[calc(-50%-8rem)] sm:data-open:-translate-y-1/2 bottom-0 h-fit max-h-[calc(100dvh-4rem)] translate-y-0 sm:bottom-auto sm:top-1/2 sm:rounded-b-2xl sm:rounded-t-2xl', className), children: [jsxRuntime.jsx("button", { onTouchStart: enableTouchClose, onMouseDown: enableMouseClose, className: [
|
|
1272
|
+
'after:ease-exponential absolute inset-x-0 top-0 z-10 flex h-6 cursor-grab items-center justify-center after:h-1 after:w-8 after:rounded-full after:transition-[transform_background-color] after:duration-500 active:cursor-grabbing',
|
|
1273
|
+
readyToClose
|
|
1274
|
+
? 'after:scale-x-200 after:scale-y-200 after:bg-ui-blue'
|
|
1275
|
+
: 'after:bg-ui-grey/50 active:after:bg-ui-grey pointer-fine:hover:after:scale-x-125 pointer-fine:hover:after:bg-neutral-500/75 pointer-fine:active:after:scale-x-150 pointer-fine:active:after:bg-ui-grey active:after:scale-x-150 active:after:scale-y-125',
|
|
1276
|
+
].join(' '), children: jsxRuntime.jsx("span", { className: 'sr-only', children: "Drag down to close" }) }), dialogElement] })] })] }));
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
function Time({ children, dateObject, dateTime, day, hours, milliseconds, minutes, month, seconds, year, ref, ...props }) {
|
|
1280
|
+
const [date, setDate] = react.useState(dateObject || undefined);
|
|
1281
|
+
const getDateAndTime = () => {
|
|
1282
|
+
if (dateTime)
|
|
1283
|
+
return dateTime;
|
|
1284
|
+
if (!date)
|
|
1285
|
+
return '';
|
|
1286
|
+
const currentYear = date.getFullYear(), currentMonth = getMonth(date), currentDay = getDate(date), currentHour = getHours(date), currentMinute = getMinutes(date), currentSecond = getSeconds(date), currentMillisecond = getMilliseconds(date);
|
|
1287
|
+
return [currentYear, currentMonth, currentDay, currentHour, currentMinute, currentSecond, currentMillisecond].join('-');
|
|
1288
|
+
};
|
|
1289
|
+
const dateAndTime = getDateAndTime();
|
|
1290
|
+
const getDateDisplay = () => {
|
|
1291
|
+
if (children)
|
|
1292
|
+
return children;
|
|
1293
|
+
if (dateAndTime === '')
|
|
1294
|
+
return '';
|
|
1295
|
+
const [dtYear, dtMonth, dtDay, dtHour, dtMinute, dtSecond, dtMillisecond] = dateAndTime.split('-').map(Number);
|
|
1296
|
+
return [
|
|
1297
|
+
day && dtDay,
|
|
1298
|
+
month && [getMonthName(Number(dtMonth) - 1), month && year && ','].filter(Boolean).join(''),
|
|
1299
|
+
year && dtYear,
|
|
1300
|
+
hours &&
|
|
1301
|
+
minutes &&
|
|
1302
|
+
[
|
|
1303
|
+
'at',
|
|
1304
|
+
hours && dtHour,
|
|
1305
|
+
hours && minutes && ':',
|
|
1306
|
+
minutes && dtMinute,
|
|
1307
|
+
minutes && seconds && ':',
|
|
1308
|
+
seconds && dtSecond,
|
|
1309
|
+
seconds && milliseconds && '.',
|
|
1310
|
+
milliseconds && dtMillisecond,
|
|
1311
|
+
]
|
|
1312
|
+
.filter(Boolean)
|
|
1313
|
+
.join(''),
|
|
1314
|
+
]
|
|
1315
|
+
.filter(Boolean)
|
|
1316
|
+
.join(' ');
|
|
1317
|
+
};
|
|
1318
|
+
const dateDisplay = getDateDisplay();
|
|
1319
|
+
react.useEffect(() => {
|
|
1320
|
+
if (date === undefined &&
|
|
1321
|
+
dateObject === undefined &&
|
|
1322
|
+
dateTime === undefined &&
|
|
1323
|
+
typeof window !== 'undefined' &&
|
|
1324
|
+
(dateAndTime === '' || dateDisplay === ''))
|
|
1325
|
+
setDate(new Date());
|
|
1326
|
+
}, [date, setDate, dateAndTime, dateDisplay, dateObject, dateTime]);
|
|
1327
|
+
return (jsxRuntime.jsx("time", { dateTime: dateAndTime, ref: ref, ...props, children: dateDisplay }));
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
exports.Anchor = Anchor;
|
|
1331
|
+
exports.Button = Button;
|
|
1332
|
+
exports.Form = Form;
|
|
1333
|
+
exports.Ghost = Ghost;
|
|
1334
|
+
exports.Heading = Heading;
|
|
1335
|
+
exports.Input = Input;
|
|
1336
|
+
exports.Link = Link;
|
|
1337
|
+
exports.Modal = Modal;
|
|
1338
|
+
exports.ModalDialog = ModalDialog;
|
|
1339
|
+
exports.ModalTrigger = ModalTrigger;
|
|
1340
|
+
exports.SubmitButton = SubmitButton;
|
|
1341
|
+
exports.Textarea = Textarea;
|
|
1342
|
+
exports.Time = Time;
|
|
1343
|
+
//# sourceMappingURL=components.js.map
|