@mainframework/dropzone 1.0.19 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,2 +1,3466 @@
1
- export { useFileSelector } from "./shared/hooks/useFileSelector";
2
- //# sourceMappingURL=index.js.map
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useRef, memo, useId, useCallback, useState, useMemo } from 'react';
4
+ import './shared/components/FileSelector/tailwind.css';
5
+
6
+ //Use this to quickly get the file extensions
7
+ //Devs can pass their own custom type mappings to override these defaults
8
+ const defaultTypeExtensions = {
9
+ "image/png": ".png",
10
+ "image/jpeg": ".jpeg",
11
+ "image/jpg": ".jpg",
12
+ "image/svg+xml": ".svg",
13
+ "application/pdf": ".pdf",
14
+ "application/msword": ".doc",
15
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
16
+ };
17
+ //This is the attribute that should be present in all svg files
18
+ const xmlns = "<svg xmlns='http://www.w3.org/2000/svg'";
19
+ const maximumUploadCount = 30;
20
+ const maximumFileSize = 5e6; //5 mb's
21
+ const printableMaximumFileSize = "5 Megabytes";
22
+ // HELPER: Extract file ID (filename without extension)
23
+ /*
24
+ * Extracts filename without extension, handling multiple dots correctly.
25
+ * "my.photo.final.png" -> "my.photo.final"
26
+ * "README.md" -> "README"
27
+ * "no-extension" -> "no-extension"
28
+ */
29
+ const getFileId = (fileName) => {
30
+ const lastDotIndex = fileName.lastIndexOf(".");
31
+ return lastDotIndex > 0 ? fileName.slice(0, lastDotIndex) : fileName;
32
+ };
33
+ // BLOB URL REGISTRY - WeakMap for automatic GC cleanup
34
+ /*
35
+ * WeakMap prevents memory leaks by allowing GC to reclaim File objects.
36
+ * No manual cleanup needed when Files are no longer referenced.
37
+ */
38
+ const blobUrlRegistry = new WeakMap();
39
+ const createUrlString = (file) => {
40
+ const existing = blobUrlRegistry.get(file);
41
+ if (existing)
42
+ return existing;
43
+ const url = URL.createObjectURL(file);
44
+ blobUrlRegistry.set(file, url);
45
+ return url;
46
+ };
47
+ const clearBlobFromMemory = (file) => {
48
+ const url = blobUrlRegistry.get(file);
49
+ if (!url)
50
+ return;
51
+ URL.revokeObjectURL(url);
52
+ blobUrlRegistry.delete(file);
53
+ };
54
+ // VALIDATION FUNCTIONS
55
+ /*
56
+ * Checks if file type is in accepted types map.
57
+ * Uses 'in' operator for better performance than Boolean() conversion.
58
+ */
59
+ const isValidFileType = (file, acceptedTypes = defaultTypeExtensions) => file.type in acceptedTypes;
60
+ /*
61
+ * Returns true if ANY file exceeds the maximum size limit.
62
+ * Optimized with for-loop to avoid callback allocations in hot path.
63
+ */
64
+ const checkFilesMaximumSize = (files, max = maximumFileSize) => {
65
+ let i = 0;
66
+ while (i < files.length) {
67
+ if (files[i].size > max)
68
+ return true;
69
+ i++;
70
+ }
71
+ return false;
72
+ };
73
+ // DOCUMENT CREATION
74
+ /*
75
+ * Creates document data object with file metadata.
76
+ * Returns null if file type is not in allowableTypes to prevent invalid state.
77
+ */
78
+ const createDocumentData = (file, allowableTypes = defaultTypeExtensions) => {
79
+ const type = allowableTypes[file.type];
80
+ if (!type)
81
+ return null;
82
+ return {
83
+ id: getFileId(file.name),
84
+ type,
85
+ file,
86
+ url: createUrlString(file),
87
+ };
88
+ };
89
+ /*
90
+ * Optimized SVG xmlns check - only reads first 2KB initially.
91
+ * Avoids toLowerCase() allocation and uses safer regex for replacement.
92
+ */
93
+ const SvgXmlnsAttributeCheck = async (file, allowableTypes = defaultTypeExtensions) => {
94
+ if (file.type !== "image/svg+xml") {
95
+ return createDocumentData(file, allowableTypes);
96
+ }
97
+ // OPTIMIZATION: Only read first 2KB to check for xmlns
98
+ const chunk = file.slice(0, 2048);
99
+ const text = await chunk.text();
100
+ // No toLowerCase() needed - xmlns attribute is case-sensitive in XML
101
+ if (text.includes("xmlns=")) {
102
+ return createDocumentData(file, allowableTypes);
103
+ }
104
+ // Missing the xmlns attribute, add it
105
+ // Need full file content for modification
106
+ const fullText = await file.text();
107
+ // SAFER: Use regex with word boundary instead of simple string replace
108
+ // Handles <svg> without space and various attribute orders
109
+ const svgWithXmlns = fullText.replace(/<svg\b/, xmlns);
110
+ return createDocumentData(new File([svgWithXmlns], file.name, {
111
+ type: file.type,
112
+ }), allowableTypes);
113
+ };
114
+ // FILE RENAMING
115
+ /*
116
+ * Renames a file or blob. Optimized to avoid unnecessary File creation
117
+ * if name already matches.
118
+ */
119
+ const renameFile = (file, name) => file instanceof File && file.name === name ? file : new File([file], name, { type: file.type });
120
+ /*
121
+ * Checks if file needs renaming based on ID comparison.
122
+ * - Handles Blobs (no name) by converting to File
123
+ * - Avoids repeated string operations
124
+ * - Case-sensitive comparison
125
+ */
126
+ const checkFile = (id, file) => {
127
+ // No ID provided, return as-is
128
+ if (!id)
129
+ return file;
130
+ // Handle Blob (not a File subclass)
131
+ if (!(file instanceof File)) {
132
+ return renameFile(file, id);
133
+ }
134
+ // It's a File - check if renaming is needed
135
+ const currentId = getFileId(file.name);
136
+ return id === currentId ? file : renameFile(file, id);
137
+ };
138
+
139
+ const e=e=>"object"==typeof e&&null!==e,t=e=>"function"==typeof e,r$1=e=>e instanceof Date,n=e=>e instanceof RegExp,o=e=>e instanceof Set,f=e=>e instanceof Map,i=e=>e instanceof String||e instanceof Number||e instanceof Boolean,a=e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),s=e=>Object.getPrototypeOf(e),u=e=>null==e||"object"!=typeof e&&"function"!=typeof e,c=(l,y,p=new WeakMap,b={})=>{if(l===y)return true;if("number"==typeof l&&"number"==typeof y&&Number.isNaN(l)&&Number.isNaN(y))return true;if(b.normalizeBoxedPrimitives&&(i(l)&&(l=l.valueOf()),i(y)&&(y=y.valueOf()),u(l)&&u(y)))return l===y;if(u(l)||u(y))return false;if(t(l)||t(y))return l===y;if(!e(l)||!e(y))return false;let g=p.get(l)??(()=>{const e=new WeakMap;return p.set(l,e),e})();const h=g.get(y);if(void 0!==h)return h;g.set(y,true);const w=s(l),A=s(y);let m;return m=Array.isArray(l)&&Array.isArray(y)?((e,t,r,n)=>{if(e.length!==t.length)return false;for(let o=0;o<e.length;o++){if(n.strictSparseArrays){const r=Object.prototype.hasOwnProperty.call(e,o),n=Object.prototype.hasOwnProperty.call(t,o);if(r!==n)return false;if(!r&&!n)continue}if(!c(e[o],t[o],r,n))return false}return true})(l,y,p,b):!Array.isArray(l)&&!Array.isArray(y)&&(r$1(l)&&r$1(y)?((e,t)=>e.getTime()===t.getTime())(l,y):n(l)&&n(y)?((e,t)=>e.source===t.source&&e.flags===t.flags)(l,y):a(l)&&a(y)?((e,t)=>{if(e.constructor!==t.constructor||e.byteLength!==t.byteLength)return false;const r=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),n=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);for(let e=0;e<r.length;e++)if(r[e]!==n[e])return false;return true})(l,y):o(l)&&o(y)?((e,t,r,n)=>{if(e.size!==t.size)return false;const o=Array.from(t),f=new Set;for(const t of e){const e=o.findIndex((e,r)=>!f.has(r)&&t===e);if(-1!==e){f.add(e);continue}let i=false;for(let e=0;e<o.length;e++)if(!f.has(e)&&c(t,o[e],r,n)){f.add(e),i=true;break}if(!i)return false}return true})(l,y,p,b):f(l)&&f(y)?((e,t,r,n)=>{if(e.size!==t.size)return false;const o=Array.from(t),f=new Set;for(const[i,a]of e){if(u(i)){const e=t.get(i);if(void 0===e&&!t.has(i))return false;if(!c(a,e,r,n))return false;continue}let e=false;for(let t=0;t<o.length;t++)if(!f.has(t)){const[s,u]=o[t];if(c(i,s,r,n)&&c(a,u,r,n)){f.add(t),e=true;break}}if(!e)return false}return true})(l,y,p,b):!(!b.allowPrototypeMismatch&&w!==A)&&((e,t,r,n)=>{let o=0;for(const f of Reflect.ownKeys(e)){if(!Object.prototype.hasOwnProperty.call(t,f))return false;if(!c(e[f],t[f],r,n))return false;o++;}return Reflect.ownKeys(t).length===o})(l,y,p,b)),g.set(y,m),m},l=(e,t,r)=>c(e,t,new WeakMap,r);
140
+
141
+ const useCustomCallback = (callback, dependencies) => {
142
+ const refCallback = useRef(callback);
143
+ const refDependencies = useRef(dependencies);
144
+ // Update refs synchronously during render
145
+ if (!dependencies.every((dep, index) => l(dep, refDependencies.current[index]))) {
146
+ refDependencies.current = dependencies;
147
+ refCallback.current = callback;
148
+ }
149
+ // Stable callback, always calls latest callback
150
+ const stableCallback = useRef((...args) => refCallback.current(...args)).current;
151
+ return stableCallback;
152
+ };
153
+
154
+ function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
155
+
156
+ /**
157
+ * Concatenates two arrays faster than the array spread operator.
158
+ */
159
+ const concatArrays = (array1, array2) => {
160
+ // Pre-allocate for better V8 optimization
161
+ const combinedArray = new Array(array1.length + array2.length);
162
+ for (let i = 0; i < array1.length; i++) {
163
+ combinedArray[i] = array1[i];
164
+ }
165
+ for (let i = 0; i < array2.length; i++) {
166
+ combinedArray[array1.length + i] = array2[i];
167
+ }
168
+ return combinedArray;
169
+ };
170
+
171
+ // Factory function ensures consistent object shapes
172
+ const createClassValidatorObject = (classGroupId, validator) => ({
173
+ classGroupId,
174
+ validator
175
+ });
176
+ // Factory ensures consistent ClassPartObject shape
177
+ const createClassPartObject = (nextPart = new Map(), validators = null, classGroupId) => ({
178
+ nextPart,
179
+ validators,
180
+ classGroupId
181
+ });
182
+ const CLASS_PART_SEPARATOR = '-';
183
+ const EMPTY_CONFLICTS = [];
184
+ // I use two dots here because one dot is used as prefix for class groups in plugins
185
+ const ARBITRARY_PROPERTY_PREFIX = 'arbitrary..';
186
+ const createClassGroupUtils = config => {
187
+ const classMap = createClassMap(config);
188
+ const {
189
+ conflictingClassGroups,
190
+ conflictingClassGroupModifiers
191
+ } = config;
192
+ const getClassGroupId = className => {
193
+ if (className.startsWith('[') && className.endsWith(']')) {
194
+ return getGroupIdForArbitraryProperty(className);
195
+ }
196
+ const classParts = className.split(CLASS_PART_SEPARATOR);
197
+ // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and skip it.
198
+ const startIndex = classParts[0] === '' && classParts.length > 1 ? 1 : 0;
199
+ return getGroupRecursive(classParts, startIndex, classMap);
200
+ };
201
+ const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
202
+ if (hasPostfixModifier) {
203
+ const modifierConflicts = conflictingClassGroupModifiers[classGroupId];
204
+ const baseConflicts = conflictingClassGroups[classGroupId];
205
+ if (modifierConflicts) {
206
+ if (baseConflicts) {
207
+ // Merge base conflicts with modifier conflicts
208
+ return concatArrays(baseConflicts, modifierConflicts);
209
+ }
210
+ // Only modifier conflicts
211
+ return modifierConflicts;
212
+ }
213
+ // Fall back to without postfix if no modifier conflicts
214
+ return baseConflicts || EMPTY_CONFLICTS;
215
+ }
216
+ return conflictingClassGroups[classGroupId] || EMPTY_CONFLICTS;
217
+ };
218
+ return {
219
+ getClassGroupId,
220
+ getConflictingClassGroupIds
221
+ };
222
+ };
223
+ const getGroupRecursive = (classParts, startIndex, classPartObject) => {
224
+ const classPathsLength = classParts.length - startIndex;
225
+ if (classPathsLength === 0) {
226
+ return classPartObject.classGroupId;
227
+ }
228
+ const currentClassPart = classParts[startIndex];
229
+ const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
230
+ if (nextClassPartObject) {
231
+ const result = getGroupRecursive(classParts, startIndex + 1, nextClassPartObject);
232
+ if (result) return result;
233
+ }
234
+ const validators = classPartObject.validators;
235
+ if (validators === null) {
236
+ return undefined;
237
+ }
238
+ // Build classRest string efficiently by joining from startIndex onwards
239
+ const classRest = startIndex === 0 ? classParts.join(CLASS_PART_SEPARATOR) : classParts.slice(startIndex).join(CLASS_PART_SEPARATOR);
240
+ const validatorsLength = validators.length;
241
+ for (let i = 0; i < validatorsLength; i++) {
242
+ const validatorObj = validators[i];
243
+ if (validatorObj.validator(classRest)) {
244
+ return validatorObj.classGroupId;
245
+ }
246
+ }
247
+ return undefined;
248
+ };
249
+ /**
250
+ * Get the class group ID for an arbitrary property.
251
+ *
252
+ * @param className - The class name to get the group ID for. Is expected to be string starting with `[` and ending with `]`.
253
+ */
254
+ const getGroupIdForArbitraryProperty = className => className.slice(1, -1).indexOf(':') === -1 ? undefined : (() => {
255
+ const content = className.slice(1, -1);
256
+ const colonIndex = content.indexOf(':');
257
+ const property = content.slice(0, colonIndex);
258
+ return property ? ARBITRARY_PROPERTY_PREFIX + property : undefined;
259
+ })();
260
+ /**
261
+ * Exported for testing only
262
+ */
263
+ const createClassMap = config => {
264
+ const {
265
+ theme,
266
+ classGroups
267
+ } = config;
268
+ return processClassGroups(classGroups, theme);
269
+ };
270
+ // Split into separate functions to maintain monomorphic call sites
271
+ const processClassGroups = (classGroups, theme) => {
272
+ const classMap = createClassPartObject();
273
+ for (const classGroupId in classGroups) {
274
+ const group = classGroups[classGroupId];
275
+ processClassesRecursively(group, classMap, classGroupId, theme);
276
+ }
277
+ return classMap;
278
+ };
279
+ const processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
280
+ const len = classGroup.length;
281
+ for (let i = 0; i < len; i++) {
282
+ const classDefinition = classGroup[i];
283
+ processClassDefinition(classDefinition, classPartObject, classGroupId, theme);
284
+ }
285
+ };
286
+ // Split into separate functions for each type to maintain monomorphic call sites
287
+ const processClassDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
288
+ if (typeof classDefinition === 'string') {
289
+ processStringDefinition(classDefinition, classPartObject, classGroupId);
290
+ return;
291
+ }
292
+ if (typeof classDefinition === 'function') {
293
+ processFunctionDefinition(classDefinition, classPartObject, classGroupId, theme);
294
+ return;
295
+ }
296
+ processObjectDefinition(classDefinition, classPartObject, classGroupId, theme);
297
+ };
298
+ const processStringDefinition = (classDefinition, classPartObject, classGroupId) => {
299
+ const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);
300
+ classPartObjectToEdit.classGroupId = classGroupId;
301
+ };
302
+ const processFunctionDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
303
+ if (isThemeGetter(classDefinition)) {
304
+ processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
305
+ return;
306
+ }
307
+ if (classPartObject.validators === null) {
308
+ classPartObject.validators = [];
309
+ }
310
+ classPartObject.validators.push(createClassValidatorObject(classGroupId, classDefinition));
311
+ };
312
+ const processObjectDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
313
+ const entries = Object.entries(classDefinition);
314
+ const len = entries.length;
315
+ for (let i = 0; i < len; i++) {
316
+ const [key, value] = entries[i];
317
+ processClassesRecursively(value, getPart(classPartObject, key), classGroupId, theme);
318
+ }
319
+ };
320
+ const getPart = (classPartObject, path) => {
321
+ let current = classPartObject;
322
+ const parts = path.split(CLASS_PART_SEPARATOR);
323
+ const len = parts.length;
324
+ for (let i = 0; i < len; i++) {
325
+ const part = parts[i];
326
+ let next = current.nextPart.get(part);
327
+ if (!next) {
328
+ next = createClassPartObject();
329
+ current.nextPart.set(part, next);
330
+ }
331
+ current = next;
332
+ }
333
+ return current;
334
+ };
335
+ // Type guard maintains monomorphic check
336
+ const isThemeGetter = func => 'isThemeGetter' in func && func.isThemeGetter === true;
337
+
338
+ // LRU cache implementation using plain objects for simplicity
339
+ const createLruCache = maxCacheSize => {
340
+ if (maxCacheSize < 1) {
341
+ return {
342
+ get: () => undefined,
343
+ set: () => {}
344
+ };
345
+ }
346
+ let cacheSize = 0;
347
+ let cache = Object.create(null);
348
+ let previousCache = Object.create(null);
349
+ const update = (key, value) => {
350
+ cache[key] = value;
351
+ cacheSize++;
352
+ if (cacheSize > maxCacheSize) {
353
+ cacheSize = 0;
354
+ previousCache = cache;
355
+ cache = Object.create(null);
356
+ }
357
+ };
358
+ return {
359
+ get(key) {
360
+ let value = cache[key];
361
+ if (value !== undefined) {
362
+ return value;
363
+ }
364
+ if ((value = previousCache[key]) !== undefined) {
365
+ update(key, value);
366
+ return value;
367
+ }
368
+ },
369
+ set(key, value) {
370
+ if (key in cache) {
371
+ cache[key] = value;
372
+ } else {
373
+ update(key, value);
374
+ }
375
+ }
376
+ };
377
+ };
378
+ const IMPORTANT_MODIFIER = '!';
379
+ const MODIFIER_SEPARATOR = ':';
380
+ const EMPTY_MODIFIERS = [];
381
+ // Pre-allocated result object shape for consistency
382
+ const createResultObject = (modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition, isExternal) => ({
383
+ modifiers,
384
+ hasImportantModifier,
385
+ baseClassName,
386
+ maybePostfixModifierPosition,
387
+ isExternal
388
+ });
389
+ const createParseClassName = config => {
390
+ const {
391
+ prefix,
392
+ experimentalParseClassName
393
+ } = config;
394
+ /**
395
+ * Parse class name into parts.
396
+ *
397
+ * Inspired by `splitAtTopLevelOnly` used in Tailwind CSS
398
+ * @see https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js
399
+ */
400
+ let parseClassName = className => {
401
+ // Use simple array with push for better performance
402
+ const modifiers = [];
403
+ let bracketDepth = 0;
404
+ let parenDepth = 0;
405
+ let modifierStart = 0;
406
+ let postfixModifierPosition;
407
+ const len = className.length;
408
+ for (let index = 0; index < len; index++) {
409
+ const currentCharacter = className[index];
410
+ if (bracketDepth === 0 && parenDepth === 0) {
411
+ if (currentCharacter === MODIFIER_SEPARATOR) {
412
+ modifiers.push(className.slice(modifierStart, index));
413
+ modifierStart = index + 1;
414
+ continue;
415
+ }
416
+ if (currentCharacter === '/') {
417
+ postfixModifierPosition = index;
418
+ continue;
419
+ }
420
+ }
421
+ if (currentCharacter === '[') bracketDepth++;else if (currentCharacter === ']') bracketDepth--;else if (currentCharacter === '(') parenDepth++;else if (currentCharacter === ')') parenDepth--;
422
+ }
423
+ const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.slice(modifierStart);
424
+ // Inline important modifier check
425
+ let baseClassName = baseClassNameWithImportantModifier;
426
+ let hasImportantModifier = false;
427
+ if (baseClassNameWithImportantModifier.endsWith(IMPORTANT_MODIFIER)) {
428
+ baseClassName = baseClassNameWithImportantModifier.slice(0, -1);
429
+ hasImportantModifier = true;
430
+ } else if (
431
+ /**
432
+ * In Tailwind CSS v3 the important modifier was at the start of the base class name. This is still supported for legacy reasons.
433
+ * @see https://github.com/dcastil/tailwind-merge/issues/513#issuecomment-2614029864
434
+ */
435
+ baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER)) {
436
+ baseClassName = baseClassNameWithImportantModifier.slice(1);
437
+ hasImportantModifier = true;
438
+ }
439
+ const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined;
440
+ return createResultObject(modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition);
441
+ };
442
+ if (prefix) {
443
+ const fullPrefix = prefix + MODIFIER_SEPARATOR;
444
+ const parseClassNameOriginal = parseClassName;
445
+ parseClassName = className => className.startsWith(fullPrefix) ? parseClassNameOriginal(className.slice(fullPrefix.length)) : createResultObject(EMPTY_MODIFIERS, false, className, undefined, true);
446
+ }
447
+ if (experimentalParseClassName) {
448
+ const parseClassNameOriginal = parseClassName;
449
+ parseClassName = className => experimentalParseClassName({
450
+ className,
451
+ parseClassName: parseClassNameOriginal
452
+ });
453
+ }
454
+ return parseClassName;
455
+ };
456
+
457
+ /**
458
+ * Sorts modifiers according to following schema:
459
+ * - Predefined modifiers are sorted alphabetically
460
+ * - When an arbitrary variant appears, it must be preserved which modifiers are before and after it
461
+ */
462
+ const createSortModifiers = config => {
463
+ // Pre-compute weights for all known modifiers for O(1) comparison
464
+ const modifierWeights = new Map();
465
+ // Assign weights to sensitive modifiers (highest priority, but preserve order)
466
+ config.orderSensitiveModifiers.forEach((mod, index) => {
467
+ modifierWeights.set(mod, 1000000 + index); // High weights for sensitive mods
468
+ });
469
+ return modifiers => {
470
+ const result = [];
471
+ let currentSegment = [];
472
+ // Process modifiers in one pass
473
+ for (let i = 0; i < modifiers.length; i++) {
474
+ const modifier = modifiers[i];
475
+ // Check if modifier is sensitive (starts with '[' or in orderSensitiveModifiers)
476
+ const isArbitrary = modifier[0] === '[';
477
+ const isOrderSensitive = modifierWeights.has(modifier);
478
+ if (isArbitrary || isOrderSensitive) {
479
+ // Sort and flush current segment alphabetically
480
+ if (currentSegment.length > 0) {
481
+ currentSegment.sort();
482
+ result.push(...currentSegment);
483
+ currentSegment = [];
484
+ }
485
+ result.push(modifier);
486
+ } else {
487
+ // Regular modifier - add to current segment for batch sorting
488
+ currentSegment.push(modifier);
489
+ }
490
+ }
491
+ // Sort and add any remaining segment items
492
+ if (currentSegment.length > 0) {
493
+ currentSegment.sort();
494
+ result.push(...currentSegment);
495
+ }
496
+ return result;
497
+ };
498
+ };
499
+ const createConfigUtils = config => ({
500
+ cache: createLruCache(config.cacheSize),
501
+ parseClassName: createParseClassName(config),
502
+ sortModifiers: createSortModifiers(config),
503
+ ...createClassGroupUtils(config)
504
+ });
505
+ const SPLIT_CLASSES_REGEX = /\s+/;
506
+ const mergeClassList = (classList, configUtils) => {
507
+ const {
508
+ parseClassName,
509
+ getClassGroupId,
510
+ getConflictingClassGroupIds,
511
+ sortModifiers
512
+ } = configUtils;
513
+ /**
514
+ * Set of classGroupIds in following format:
515
+ * `{importantModifier}{variantModifiers}{classGroupId}`
516
+ * @example 'float'
517
+ * @example 'hover:focus:bg-color'
518
+ * @example 'md:!pr'
519
+ */
520
+ const classGroupsInConflict = [];
521
+ const classNames = classList.trim().split(SPLIT_CLASSES_REGEX);
522
+ let result = '';
523
+ for (let index = classNames.length - 1; index >= 0; index -= 1) {
524
+ const originalClassName = classNames[index];
525
+ const {
526
+ isExternal,
527
+ modifiers,
528
+ hasImportantModifier,
529
+ baseClassName,
530
+ maybePostfixModifierPosition
531
+ } = parseClassName(originalClassName);
532
+ if (isExternal) {
533
+ result = originalClassName + (result.length > 0 ? ' ' + result : result);
534
+ continue;
535
+ }
536
+ let hasPostfixModifier = !!maybePostfixModifierPosition;
537
+ let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
538
+ if (!classGroupId) {
539
+ if (!hasPostfixModifier) {
540
+ // Not a Tailwind class
541
+ result = originalClassName + (result.length > 0 ? ' ' + result : result);
542
+ continue;
543
+ }
544
+ classGroupId = getClassGroupId(baseClassName);
545
+ if (!classGroupId) {
546
+ // Not a Tailwind class
547
+ result = originalClassName + (result.length > 0 ? ' ' + result : result);
548
+ continue;
549
+ }
550
+ hasPostfixModifier = false;
551
+ }
552
+ // Fast path: skip sorting for empty or single modifier
553
+ const variantModifier = modifiers.length === 0 ? '' : modifiers.length === 1 ? modifiers[0] : sortModifiers(modifiers).join(':');
554
+ const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;
555
+ const classId = modifierId + classGroupId;
556
+ if (classGroupsInConflict.indexOf(classId) > -1) {
557
+ // Tailwind class omitted due to conflict
558
+ continue;
559
+ }
560
+ classGroupsInConflict.push(classId);
561
+ const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier);
562
+ for (let i = 0; i < conflictGroups.length; ++i) {
563
+ const group = conflictGroups[i];
564
+ classGroupsInConflict.push(modifierId + group);
565
+ }
566
+ // Tailwind class not in conflict
567
+ result = originalClassName + (result.length > 0 ? ' ' + result : result);
568
+ }
569
+ return result;
570
+ };
571
+
572
+ /**
573
+ * The code in this file is copied from https://github.com/lukeed/clsx and modified to suit the needs of tailwind-merge better.
574
+ *
575
+ * Specifically:
576
+ * - Runtime code from https://github.com/lukeed/clsx/blob/v1.2.1/src/index.js
577
+ * - TypeScript types from https://github.com/lukeed/clsx/blob/v1.2.1/clsx.d.ts
578
+ *
579
+ * Original code has MIT license: Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
580
+ */
581
+ const twJoin = (...classLists) => {
582
+ let index = 0;
583
+ let argument;
584
+ let resolvedValue;
585
+ let string = '';
586
+ while (index < classLists.length) {
587
+ if (argument = classLists[index++]) {
588
+ if (resolvedValue = toValue(argument)) {
589
+ string && (string += ' ');
590
+ string += resolvedValue;
591
+ }
592
+ }
593
+ }
594
+ return string;
595
+ };
596
+ const toValue = mix => {
597
+ // Fast path for strings
598
+ if (typeof mix === 'string') {
599
+ return mix;
600
+ }
601
+ let resolvedValue;
602
+ let string = '';
603
+ for (let k = 0; k < mix.length; k++) {
604
+ if (mix[k]) {
605
+ if (resolvedValue = toValue(mix[k])) {
606
+ string && (string += ' ');
607
+ string += resolvedValue;
608
+ }
609
+ }
610
+ }
611
+ return string;
612
+ };
613
+ const createTailwindMerge = (createConfigFirst, ...createConfigRest) => {
614
+ let configUtils;
615
+ let cacheGet;
616
+ let cacheSet;
617
+ let functionToCall;
618
+ const initTailwindMerge = classList => {
619
+ const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());
620
+ configUtils = createConfigUtils(config);
621
+ cacheGet = configUtils.cache.get;
622
+ cacheSet = configUtils.cache.set;
623
+ functionToCall = tailwindMerge;
624
+ return tailwindMerge(classList);
625
+ };
626
+ const tailwindMerge = classList => {
627
+ const cachedResult = cacheGet(classList);
628
+ if (cachedResult) {
629
+ return cachedResult;
630
+ }
631
+ const result = mergeClassList(classList, configUtils);
632
+ cacheSet(classList, result);
633
+ return result;
634
+ };
635
+ functionToCall = initTailwindMerge;
636
+ return (...args) => functionToCall(twJoin(...args));
637
+ };
638
+ const fallbackThemeArr = [];
639
+ const fromTheme = key => {
640
+ const themeGetter = theme => theme[key] || fallbackThemeArr;
641
+ themeGetter.isThemeGetter = true;
642
+ return themeGetter;
643
+ };
644
+ const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
645
+ const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
646
+ const fractionRegex = /^\d+\/\d+$/;
647
+ const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
648
+ const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
649
+ const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
650
+ // Shadow always begins with x and y offset separated by underscore optionally prepended by inset
651
+ const shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/;
652
+ const imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/;
653
+ const isFraction = value => fractionRegex.test(value);
654
+ const isNumber = value => !!value && !Number.isNaN(Number(value));
655
+ const isInteger = value => !!value && Number.isInteger(Number(value));
656
+ const isPercent = value => value.endsWith('%') && isNumber(value.slice(0, -1));
657
+ const isTshirtSize = value => tshirtUnitRegex.test(value);
658
+ const isAny = () => true;
659
+ const isLengthOnly = value =>
660
+ // `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths.
661
+ // For example, `hsl(0 0% 0%)` would be classified as a length without this check.
662
+ // I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough.
663
+ lengthUnitRegex.test(value) && !colorFunctionRegex.test(value);
664
+ const isNever = () => false;
665
+ const isShadow = value => shadowRegex.test(value);
666
+ const isImage = value => imageRegex.test(value);
667
+ const isAnyNonArbitrary = value => !isArbitraryValue(value) && !isArbitraryVariable(value);
668
+ const isArbitrarySize = value => getIsArbitraryValue(value, isLabelSize, isNever);
669
+ const isArbitraryValue = value => arbitraryValueRegex.test(value);
670
+ const isArbitraryLength = value => getIsArbitraryValue(value, isLabelLength, isLengthOnly);
671
+ const isArbitraryNumber = value => getIsArbitraryValue(value, isLabelNumber, isNumber);
672
+ const isArbitraryWeight = value => getIsArbitraryValue(value, isLabelWeight, isAny);
673
+ const isArbitraryFamilyName = value => getIsArbitraryValue(value, isLabelFamilyName, isNever);
674
+ const isArbitraryPosition = value => getIsArbitraryValue(value, isLabelPosition, isNever);
675
+ const isArbitraryImage = value => getIsArbitraryValue(value, isLabelImage, isImage);
676
+ const isArbitraryShadow = value => getIsArbitraryValue(value, isLabelShadow, isShadow);
677
+ const isArbitraryVariable = value => arbitraryVariableRegex.test(value);
678
+ const isArbitraryVariableLength = value => getIsArbitraryVariable(value, isLabelLength);
679
+ const isArbitraryVariableFamilyName = value => getIsArbitraryVariable(value, isLabelFamilyName);
680
+ const isArbitraryVariablePosition = value => getIsArbitraryVariable(value, isLabelPosition);
681
+ const isArbitraryVariableSize = value => getIsArbitraryVariable(value, isLabelSize);
682
+ const isArbitraryVariableImage = value => getIsArbitraryVariable(value, isLabelImage);
683
+ const isArbitraryVariableShadow = value => getIsArbitraryVariable(value, isLabelShadow, true);
684
+ const isArbitraryVariableWeight = value => getIsArbitraryVariable(value, isLabelWeight, true);
685
+ // Helpers
686
+ const getIsArbitraryValue = (value, testLabel, testValue) => {
687
+ const result = arbitraryValueRegex.exec(value);
688
+ if (result) {
689
+ if (result[1]) {
690
+ return testLabel(result[1]);
691
+ }
692
+ return testValue(result[2]);
693
+ }
694
+ return false;
695
+ };
696
+ const getIsArbitraryVariable = (value, testLabel, shouldMatchNoLabel = false) => {
697
+ const result = arbitraryVariableRegex.exec(value);
698
+ if (result) {
699
+ if (result[1]) {
700
+ return testLabel(result[1]);
701
+ }
702
+ return shouldMatchNoLabel;
703
+ }
704
+ return false;
705
+ };
706
+ // Labels
707
+ const isLabelPosition = label => label === 'position' || label === 'percentage';
708
+ const isLabelImage = label => label === 'image' || label === 'url';
709
+ const isLabelSize = label => label === 'length' || label === 'size' || label === 'bg-size';
710
+ const isLabelLength = label => label === 'length';
711
+ const isLabelNumber = label => label === 'number';
712
+ const isLabelFamilyName = label => label === 'family-name';
713
+ const isLabelWeight = label => label === 'number' || label === 'weight';
714
+ const isLabelShadow = label => label === 'shadow';
715
+ const getDefaultConfig = () => {
716
+ /**
717
+ * Theme getters for theme variable namespaces
718
+ * @see https://tailwindcss.com/docs/theme#theme-variable-namespaces
719
+ */
720
+ /***/
721
+ const themeColor = fromTheme('color');
722
+ const themeFont = fromTheme('font');
723
+ const themeText = fromTheme('text');
724
+ const themeFontWeight = fromTheme('font-weight');
725
+ const themeTracking = fromTheme('tracking');
726
+ const themeLeading = fromTheme('leading');
727
+ const themeBreakpoint = fromTheme('breakpoint');
728
+ const themeContainer = fromTheme('container');
729
+ const themeSpacing = fromTheme('spacing');
730
+ const themeRadius = fromTheme('radius');
731
+ const themeShadow = fromTheme('shadow');
732
+ const themeInsetShadow = fromTheme('inset-shadow');
733
+ const themeTextShadow = fromTheme('text-shadow');
734
+ const themeDropShadow = fromTheme('drop-shadow');
735
+ const themeBlur = fromTheme('blur');
736
+ const themePerspective = fromTheme('perspective');
737
+ const themeAspect = fromTheme('aspect');
738
+ const themeEase = fromTheme('ease');
739
+ const themeAnimate = fromTheme('animate');
740
+ /**
741
+ * Helpers to avoid repeating the same scales
742
+ *
743
+ * We use functions that create a new array every time they're called instead of static arrays.
744
+ * This ensures that users who modify any scale by mutating the array (e.g. with `array.push(element)`) don't accidentally mutate arrays in other parts of the config.
745
+ */
746
+ /***/
747
+ const scaleBreak = () => ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'];
748
+ const scalePosition = () => ['center', 'top', 'bottom', 'left', 'right', 'top-left',
749
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
750
+ 'left-top', 'top-right',
751
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
752
+ 'right-top', 'bottom-right',
753
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
754
+ 'right-bottom', 'bottom-left',
755
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
756
+ 'left-bottom'];
757
+ const scalePositionWithArbitrary = () => [...scalePosition(), isArbitraryVariable, isArbitraryValue];
758
+ const scaleOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'];
759
+ const scaleOverscroll = () => ['auto', 'contain', 'none'];
760
+ const scaleUnambiguousSpacing = () => [isArbitraryVariable, isArbitraryValue, themeSpacing];
761
+ const scaleInset = () => [isFraction, 'full', 'auto', ...scaleUnambiguousSpacing()];
762
+ const scaleGridTemplateColsRows = () => [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue];
763
+ const scaleGridColRowStartAndEnd = () => ['auto', {
764
+ span: ['full', isInteger, isArbitraryVariable, isArbitraryValue]
765
+ }, isInteger, isArbitraryVariable, isArbitraryValue];
766
+ const scaleGridColRowStartOrEnd = () => [isInteger, 'auto', isArbitraryVariable, isArbitraryValue];
767
+ const scaleGridAutoColsRows = () => ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue];
768
+ const scaleAlignPrimaryAxis = () => ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch', 'baseline', 'center-safe', 'end-safe'];
769
+ const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch', 'center-safe', 'end-safe'];
770
+ const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()];
771
+ const scaleSizing = () => [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
772
+ const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];
773
+ const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {
774
+ position: [isArbitraryVariable, isArbitraryValue]
775
+ }];
776
+ const scaleBgRepeat = () => ['no-repeat', {
777
+ repeat: ['', 'x', 'y', 'space', 'round']
778
+ }];
779
+ const scaleBgSize = () => ['auto', 'cover', 'contain', isArbitraryVariableSize, isArbitrarySize, {
780
+ size: [isArbitraryVariable, isArbitraryValue]
781
+ }];
782
+ const scaleGradientStopPosition = () => [isPercent, isArbitraryVariableLength, isArbitraryLength];
783
+ const scaleRadius = () => [
784
+ // Deprecated since Tailwind CSS v4.0.0
785
+ '', 'none', 'full', themeRadius, isArbitraryVariable, isArbitraryValue];
786
+ const scaleBorderWidth = () => ['', isNumber, isArbitraryVariableLength, isArbitraryLength];
787
+ const scaleLineStyle = () => ['solid', 'dashed', 'dotted', 'double'];
788
+ const scaleBlendMode = () => ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'];
789
+ const scaleMaskImagePosition = () => [isNumber, isPercent, isArbitraryVariablePosition, isArbitraryPosition];
790
+ const scaleBlur = () => [
791
+ // Deprecated since Tailwind CSS v4.0.0
792
+ '', 'none', themeBlur, isArbitraryVariable, isArbitraryValue];
793
+ const scaleRotate = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue];
794
+ const scaleScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue];
795
+ const scaleSkew = () => [isNumber, isArbitraryVariable, isArbitraryValue];
796
+ const scaleTranslate = () => [isFraction, 'full', ...scaleUnambiguousSpacing()];
797
+ return {
798
+ cacheSize: 500,
799
+ theme: {
800
+ animate: ['spin', 'ping', 'pulse', 'bounce'],
801
+ aspect: ['video'],
802
+ blur: [isTshirtSize],
803
+ breakpoint: [isTshirtSize],
804
+ color: [isAny],
805
+ container: [isTshirtSize],
806
+ 'drop-shadow': [isTshirtSize],
807
+ ease: ['in', 'out', 'in-out'],
808
+ font: [isAnyNonArbitrary],
809
+ 'font-weight': ['thin', 'extralight', 'light', 'normal', 'medium', 'semibold', 'bold', 'extrabold', 'black'],
810
+ 'inset-shadow': [isTshirtSize],
811
+ leading: ['none', 'tight', 'snug', 'normal', 'relaxed', 'loose'],
812
+ perspective: ['dramatic', 'near', 'normal', 'midrange', 'distant', 'none'],
813
+ radius: [isTshirtSize],
814
+ shadow: [isTshirtSize],
815
+ spacing: ['px', isNumber],
816
+ text: [isTshirtSize],
817
+ 'text-shadow': [isTshirtSize],
818
+ tracking: ['tighter', 'tight', 'normal', 'wide', 'wider', 'widest']
819
+ },
820
+ classGroups: {
821
+ // --------------
822
+ // --- Layout ---
823
+ // --------------
824
+ /**
825
+ * Aspect Ratio
826
+ * @see https://tailwindcss.com/docs/aspect-ratio
827
+ */
828
+ aspect: [{
829
+ aspect: ['auto', 'square', isFraction, isArbitraryValue, isArbitraryVariable, themeAspect]
830
+ }],
831
+ /**
832
+ * Container
833
+ * @see https://tailwindcss.com/docs/container
834
+ * @deprecated since Tailwind CSS v4.0.0
835
+ */
836
+ container: ['container'],
837
+ /**
838
+ * Columns
839
+ * @see https://tailwindcss.com/docs/columns
840
+ */
841
+ columns: [{
842
+ columns: [isNumber, isArbitraryValue, isArbitraryVariable, themeContainer]
843
+ }],
844
+ /**
845
+ * Break After
846
+ * @see https://tailwindcss.com/docs/break-after
847
+ */
848
+ 'break-after': [{
849
+ 'break-after': scaleBreak()
850
+ }],
851
+ /**
852
+ * Break Before
853
+ * @see https://tailwindcss.com/docs/break-before
854
+ */
855
+ 'break-before': [{
856
+ 'break-before': scaleBreak()
857
+ }],
858
+ /**
859
+ * Break Inside
860
+ * @see https://tailwindcss.com/docs/break-inside
861
+ */
862
+ 'break-inside': [{
863
+ 'break-inside': ['auto', 'avoid', 'avoid-page', 'avoid-column']
864
+ }],
865
+ /**
866
+ * Box Decoration Break
867
+ * @see https://tailwindcss.com/docs/box-decoration-break
868
+ */
869
+ 'box-decoration': [{
870
+ 'box-decoration': ['slice', 'clone']
871
+ }],
872
+ /**
873
+ * Box Sizing
874
+ * @see https://tailwindcss.com/docs/box-sizing
875
+ */
876
+ box: [{
877
+ box: ['border', 'content']
878
+ }],
879
+ /**
880
+ * Display
881
+ * @see https://tailwindcss.com/docs/display
882
+ */
883
+ display: ['block', 'inline-block', 'inline', 'flex', 'inline-flex', 'table', 'inline-table', 'table-caption', 'table-cell', 'table-column', 'table-column-group', 'table-footer-group', 'table-header-group', 'table-row-group', 'table-row', 'flow-root', 'grid', 'inline-grid', 'contents', 'list-item', 'hidden'],
884
+ /**
885
+ * Screen Reader Only
886
+ * @see https://tailwindcss.com/docs/display#screen-reader-only
887
+ */
888
+ sr: ['sr-only', 'not-sr-only'],
889
+ /**
890
+ * Floats
891
+ * @see https://tailwindcss.com/docs/float
892
+ */
893
+ float: [{
894
+ float: ['right', 'left', 'none', 'start', 'end']
895
+ }],
896
+ /**
897
+ * Clear
898
+ * @see https://tailwindcss.com/docs/clear
899
+ */
900
+ clear: [{
901
+ clear: ['left', 'right', 'both', 'none', 'start', 'end']
902
+ }],
903
+ /**
904
+ * Isolation
905
+ * @see https://tailwindcss.com/docs/isolation
906
+ */
907
+ isolation: ['isolate', 'isolation-auto'],
908
+ /**
909
+ * Object Fit
910
+ * @see https://tailwindcss.com/docs/object-fit
911
+ */
912
+ 'object-fit': [{
913
+ object: ['contain', 'cover', 'fill', 'none', 'scale-down']
914
+ }],
915
+ /**
916
+ * Object Position
917
+ * @see https://tailwindcss.com/docs/object-position
918
+ */
919
+ 'object-position': [{
920
+ object: scalePositionWithArbitrary()
921
+ }],
922
+ /**
923
+ * Overflow
924
+ * @see https://tailwindcss.com/docs/overflow
925
+ */
926
+ overflow: [{
927
+ overflow: scaleOverflow()
928
+ }],
929
+ /**
930
+ * Overflow X
931
+ * @see https://tailwindcss.com/docs/overflow
932
+ */
933
+ 'overflow-x': [{
934
+ 'overflow-x': scaleOverflow()
935
+ }],
936
+ /**
937
+ * Overflow Y
938
+ * @see https://tailwindcss.com/docs/overflow
939
+ */
940
+ 'overflow-y': [{
941
+ 'overflow-y': scaleOverflow()
942
+ }],
943
+ /**
944
+ * Overscroll Behavior
945
+ * @see https://tailwindcss.com/docs/overscroll-behavior
946
+ */
947
+ overscroll: [{
948
+ overscroll: scaleOverscroll()
949
+ }],
950
+ /**
951
+ * Overscroll Behavior X
952
+ * @see https://tailwindcss.com/docs/overscroll-behavior
953
+ */
954
+ 'overscroll-x': [{
955
+ 'overscroll-x': scaleOverscroll()
956
+ }],
957
+ /**
958
+ * Overscroll Behavior Y
959
+ * @see https://tailwindcss.com/docs/overscroll-behavior
960
+ */
961
+ 'overscroll-y': [{
962
+ 'overscroll-y': scaleOverscroll()
963
+ }],
964
+ /**
965
+ * Position
966
+ * @see https://tailwindcss.com/docs/position
967
+ */
968
+ position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],
969
+ /**
970
+ * Top / Right / Bottom / Left
971
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
972
+ */
973
+ inset: [{
974
+ inset: scaleInset()
975
+ }],
976
+ /**
977
+ * Right / Left
978
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
979
+ */
980
+ 'inset-x': [{
981
+ 'inset-x': scaleInset()
982
+ }],
983
+ /**
984
+ * Top / Bottom
985
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
986
+ */
987
+ 'inset-y': [{
988
+ 'inset-y': scaleInset()
989
+ }],
990
+ /**
991
+ * Start
992
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
993
+ */
994
+ start: [{
995
+ start: scaleInset()
996
+ }],
997
+ /**
998
+ * End
999
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
1000
+ */
1001
+ end: [{
1002
+ end: scaleInset()
1003
+ }],
1004
+ /**
1005
+ * Top
1006
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
1007
+ */
1008
+ top: [{
1009
+ top: scaleInset()
1010
+ }],
1011
+ /**
1012
+ * Right
1013
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
1014
+ */
1015
+ right: [{
1016
+ right: scaleInset()
1017
+ }],
1018
+ /**
1019
+ * Bottom
1020
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
1021
+ */
1022
+ bottom: [{
1023
+ bottom: scaleInset()
1024
+ }],
1025
+ /**
1026
+ * Left
1027
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
1028
+ */
1029
+ left: [{
1030
+ left: scaleInset()
1031
+ }],
1032
+ /**
1033
+ * Visibility
1034
+ * @see https://tailwindcss.com/docs/visibility
1035
+ */
1036
+ visibility: ['visible', 'invisible', 'collapse'],
1037
+ /**
1038
+ * Z-Index
1039
+ * @see https://tailwindcss.com/docs/z-index
1040
+ */
1041
+ z: [{
1042
+ z: [isInteger, 'auto', isArbitraryVariable, isArbitraryValue]
1043
+ }],
1044
+ // ------------------------
1045
+ // --- Flexbox and Grid ---
1046
+ // ------------------------
1047
+ /**
1048
+ * Flex Basis
1049
+ * @see https://tailwindcss.com/docs/flex-basis
1050
+ */
1051
+ basis: [{
1052
+ basis: [isFraction, 'full', 'auto', themeContainer, ...scaleUnambiguousSpacing()]
1053
+ }],
1054
+ /**
1055
+ * Flex Direction
1056
+ * @see https://tailwindcss.com/docs/flex-direction
1057
+ */
1058
+ 'flex-direction': [{
1059
+ flex: ['row', 'row-reverse', 'col', 'col-reverse']
1060
+ }],
1061
+ /**
1062
+ * Flex Wrap
1063
+ * @see https://tailwindcss.com/docs/flex-wrap
1064
+ */
1065
+ 'flex-wrap': [{
1066
+ flex: ['nowrap', 'wrap', 'wrap-reverse']
1067
+ }],
1068
+ /**
1069
+ * Flex
1070
+ * @see https://tailwindcss.com/docs/flex
1071
+ */
1072
+ flex: [{
1073
+ flex: [isNumber, isFraction, 'auto', 'initial', 'none', isArbitraryValue]
1074
+ }],
1075
+ /**
1076
+ * Flex Grow
1077
+ * @see https://tailwindcss.com/docs/flex-grow
1078
+ */
1079
+ grow: [{
1080
+ grow: ['', isNumber, isArbitraryVariable, isArbitraryValue]
1081
+ }],
1082
+ /**
1083
+ * Flex Shrink
1084
+ * @see https://tailwindcss.com/docs/flex-shrink
1085
+ */
1086
+ shrink: [{
1087
+ shrink: ['', isNumber, isArbitraryVariable, isArbitraryValue]
1088
+ }],
1089
+ /**
1090
+ * Order
1091
+ * @see https://tailwindcss.com/docs/order
1092
+ */
1093
+ order: [{
1094
+ order: [isInteger, 'first', 'last', 'none', isArbitraryVariable, isArbitraryValue]
1095
+ }],
1096
+ /**
1097
+ * Grid Template Columns
1098
+ * @see https://tailwindcss.com/docs/grid-template-columns
1099
+ */
1100
+ 'grid-cols': [{
1101
+ 'grid-cols': scaleGridTemplateColsRows()
1102
+ }],
1103
+ /**
1104
+ * Grid Column Start / End
1105
+ * @see https://tailwindcss.com/docs/grid-column
1106
+ */
1107
+ 'col-start-end': [{
1108
+ col: scaleGridColRowStartAndEnd()
1109
+ }],
1110
+ /**
1111
+ * Grid Column Start
1112
+ * @see https://tailwindcss.com/docs/grid-column
1113
+ */
1114
+ 'col-start': [{
1115
+ 'col-start': scaleGridColRowStartOrEnd()
1116
+ }],
1117
+ /**
1118
+ * Grid Column End
1119
+ * @see https://tailwindcss.com/docs/grid-column
1120
+ */
1121
+ 'col-end': [{
1122
+ 'col-end': scaleGridColRowStartOrEnd()
1123
+ }],
1124
+ /**
1125
+ * Grid Template Rows
1126
+ * @see https://tailwindcss.com/docs/grid-template-rows
1127
+ */
1128
+ 'grid-rows': [{
1129
+ 'grid-rows': scaleGridTemplateColsRows()
1130
+ }],
1131
+ /**
1132
+ * Grid Row Start / End
1133
+ * @see https://tailwindcss.com/docs/grid-row
1134
+ */
1135
+ 'row-start-end': [{
1136
+ row: scaleGridColRowStartAndEnd()
1137
+ }],
1138
+ /**
1139
+ * Grid Row Start
1140
+ * @see https://tailwindcss.com/docs/grid-row
1141
+ */
1142
+ 'row-start': [{
1143
+ 'row-start': scaleGridColRowStartOrEnd()
1144
+ }],
1145
+ /**
1146
+ * Grid Row End
1147
+ * @see https://tailwindcss.com/docs/grid-row
1148
+ */
1149
+ 'row-end': [{
1150
+ 'row-end': scaleGridColRowStartOrEnd()
1151
+ }],
1152
+ /**
1153
+ * Grid Auto Flow
1154
+ * @see https://tailwindcss.com/docs/grid-auto-flow
1155
+ */
1156
+ 'grid-flow': [{
1157
+ 'grid-flow': ['row', 'col', 'dense', 'row-dense', 'col-dense']
1158
+ }],
1159
+ /**
1160
+ * Grid Auto Columns
1161
+ * @see https://tailwindcss.com/docs/grid-auto-columns
1162
+ */
1163
+ 'auto-cols': [{
1164
+ 'auto-cols': scaleGridAutoColsRows()
1165
+ }],
1166
+ /**
1167
+ * Grid Auto Rows
1168
+ * @see https://tailwindcss.com/docs/grid-auto-rows
1169
+ */
1170
+ 'auto-rows': [{
1171
+ 'auto-rows': scaleGridAutoColsRows()
1172
+ }],
1173
+ /**
1174
+ * Gap
1175
+ * @see https://tailwindcss.com/docs/gap
1176
+ */
1177
+ gap: [{
1178
+ gap: scaleUnambiguousSpacing()
1179
+ }],
1180
+ /**
1181
+ * Gap X
1182
+ * @see https://tailwindcss.com/docs/gap
1183
+ */
1184
+ 'gap-x': [{
1185
+ 'gap-x': scaleUnambiguousSpacing()
1186
+ }],
1187
+ /**
1188
+ * Gap Y
1189
+ * @see https://tailwindcss.com/docs/gap
1190
+ */
1191
+ 'gap-y': [{
1192
+ 'gap-y': scaleUnambiguousSpacing()
1193
+ }],
1194
+ /**
1195
+ * Justify Content
1196
+ * @see https://tailwindcss.com/docs/justify-content
1197
+ */
1198
+ 'justify-content': [{
1199
+ justify: [...scaleAlignPrimaryAxis(), 'normal']
1200
+ }],
1201
+ /**
1202
+ * Justify Items
1203
+ * @see https://tailwindcss.com/docs/justify-items
1204
+ */
1205
+ 'justify-items': [{
1206
+ 'justify-items': [...scaleAlignSecondaryAxis(), 'normal']
1207
+ }],
1208
+ /**
1209
+ * Justify Self
1210
+ * @see https://tailwindcss.com/docs/justify-self
1211
+ */
1212
+ 'justify-self': [{
1213
+ 'justify-self': ['auto', ...scaleAlignSecondaryAxis()]
1214
+ }],
1215
+ /**
1216
+ * Align Content
1217
+ * @see https://tailwindcss.com/docs/align-content
1218
+ */
1219
+ 'align-content': [{
1220
+ content: ['normal', ...scaleAlignPrimaryAxis()]
1221
+ }],
1222
+ /**
1223
+ * Align Items
1224
+ * @see https://tailwindcss.com/docs/align-items
1225
+ */
1226
+ 'align-items': [{
1227
+ items: [...scaleAlignSecondaryAxis(), {
1228
+ baseline: ['', 'last']
1229
+ }]
1230
+ }],
1231
+ /**
1232
+ * Align Self
1233
+ * @see https://tailwindcss.com/docs/align-self
1234
+ */
1235
+ 'align-self': [{
1236
+ self: ['auto', ...scaleAlignSecondaryAxis(), {
1237
+ baseline: ['', 'last']
1238
+ }]
1239
+ }],
1240
+ /**
1241
+ * Place Content
1242
+ * @see https://tailwindcss.com/docs/place-content
1243
+ */
1244
+ 'place-content': [{
1245
+ 'place-content': scaleAlignPrimaryAxis()
1246
+ }],
1247
+ /**
1248
+ * Place Items
1249
+ * @see https://tailwindcss.com/docs/place-items
1250
+ */
1251
+ 'place-items': [{
1252
+ 'place-items': [...scaleAlignSecondaryAxis(), 'baseline']
1253
+ }],
1254
+ /**
1255
+ * Place Self
1256
+ * @see https://tailwindcss.com/docs/place-self
1257
+ */
1258
+ 'place-self': [{
1259
+ 'place-self': ['auto', ...scaleAlignSecondaryAxis()]
1260
+ }],
1261
+ // Spacing
1262
+ /**
1263
+ * Padding
1264
+ * @see https://tailwindcss.com/docs/padding
1265
+ */
1266
+ p: [{
1267
+ p: scaleUnambiguousSpacing()
1268
+ }],
1269
+ /**
1270
+ * Padding X
1271
+ * @see https://tailwindcss.com/docs/padding
1272
+ */
1273
+ px: [{
1274
+ px: scaleUnambiguousSpacing()
1275
+ }],
1276
+ /**
1277
+ * Padding Y
1278
+ * @see https://tailwindcss.com/docs/padding
1279
+ */
1280
+ py: [{
1281
+ py: scaleUnambiguousSpacing()
1282
+ }],
1283
+ /**
1284
+ * Padding Start
1285
+ * @see https://tailwindcss.com/docs/padding
1286
+ */
1287
+ ps: [{
1288
+ ps: scaleUnambiguousSpacing()
1289
+ }],
1290
+ /**
1291
+ * Padding End
1292
+ * @see https://tailwindcss.com/docs/padding
1293
+ */
1294
+ pe: [{
1295
+ pe: scaleUnambiguousSpacing()
1296
+ }],
1297
+ /**
1298
+ * Padding Top
1299
+ * @see https://tailwindcss.com/docs/padding
1300
+ */
1301
+ pt: [{
1302
+ pt: scaleUnambiguousSpacing()
1303
+ }],
1304
+ /**
1305
+ * Padding Right
1306
+ * @see https://tailwindcss.com/docs/padding
1307
+ */
1308
+ pr: [{
1309
+ pr: scaleUnambiguousSpacing()
1310
+ }],
1311
+ /**
1312
+ * Padding Bottom
1313
+ * @see https://tailwindcss.com/docs/padding
1314
+ */
1315
+ pb: [{
1316
+ pb: scaleUnambiguousSpacing()
1317
+ }],
1318
+ /**
1319
+ * Padding Left
1320
+ * @see https://tailwindcss.com/docs/padding
1321
+ */
1322
+ pl: [{
1323
+ pl: scaleUnambiguousSpacing()
1324
+ }],
1325
+ /**
1326
+ * Margin
1327
+ * @see https://tailwindcss.com/docs/margin
1328
+ */
1329
+ m: [{
1330
+ m: scaleMargin()
1331
+ }],
1332
+ /**
1333
+ * Margin X
1334
+ * @see https://tailwindcss.com/docs/margin
1335
+ */
1336
+ mx: [{
1337
+ mx: scaleMargin()
1338
+ }],
1339
+ /**
1340
+ * Margin Y
1341
+ * @see https://tailwindcss.com/docs/margin
1342
+ */
1343
+ my: [{
1344
+ my: scaleMargin()
1345
+ }],
1346
+ /**
1347
+ * Margin Start
1348
+ * @see https://tailwindcss.com/docs/margin
1349
+ */
1350
+ ms: [{
1351
+ ms: scaleMargin()
1352
+ }],
1353
+ /**
1354
+ * Margin End
1355
+ * @see https://tailwindcss.com/docs/margin
1356
+ */
1357
+ me: [{
1358
+ me: scaleMargin()
1359
+ }],
1360
+ /**
1361
+ * Margin Top
1362
+ * @see https://tailwindcss.com/docs/margin
1363
+ */
1364
+ mt: [{
1365
+ mt: scaleMargin()
1366
+ }],
1367
+ /**
1368
+ * Margin Right
1369
+ * @see https://tailwindcss.com/docs/margin
1370
+ */
1371
+ mr: [{
1372
+ mr: scaleMargin()
1373
+ }],
1374
+ /**
1375
+ * Margin Bottom
1376
+ * @see https://tailwindcss.com/docs/margin
1377
+ */
1378
+ mb: [{
1379
+ mb: scaleMargin()
1380
+ }],
1381
+ /**
1382
+ * Margin Left
1383
+ * @see https://tailwindcss.com/docs/margin
1384
+ */
1385
+ ml: [{
1386
+ ml: scaleMargin()
1387
+ }],
1388
+ /**
1389
+ * Space Between X
1390
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
1391
+ */
1392
+ 'space-x': [{
1393
+ 'space-x': scaleUnambiguousSpacing()
1394
+ }],
1395
+ /**
1396
+ * Space Between X Reverse
1397
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
1398
+ */
1399
+ 'space-x-reverse': ['space-x-reverse'],
1400
+ /**
1401
+ * Space Between Y
1402
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
1403
+ */
1404
+ 'space-y': [{
1405
+ 'space-y': scaleUnambiguousSpacing()
1406
+ }],
1407
+ /**
1408
+ * Space Between Y Reverse
1409
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
1410
+ */
1411
+ 'space-y-reverse': ['space-y-reverse'],
1412
+ // --------------
1413
+ // --- Sizing ---
1414
+ // --------------
1415
+ /**
1416
+ * Size
1417
+ * @see https://tailwindcss.com/docs/width#setting-both-width-and-height
1418
+ */
1419
+ size: [{
1420
+ size: scaleSizing()
1421
+ }],
1422
+ /**
1423
+ * Width
1424
+ * @see https://tailwindcss.com/docs/width
1425
+ */
1426
+ w: [{
1427
+ w: [themeContainer, 'screen', ...scaleSizing()]
1428
+ }],
1429
+ /**
1430
+ * Min-Width
1431
+ * @see https://tailwindcss.com/docs/min-width
1432
+ */
1433
+ 'min-w': [{
1434
+ 'min-w': [themeContainer, 'screen', /** Deprecated. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
1435
+ 'none', ...scaleSizing()]
1436
+ }],
1437
+ /**
1438
+ * Max-Width
1439
+ * @see https://tailwindcss.com/docs/max-width
1440
+ */
1441
+ 'max-w': [{
1442
+ 'max-w': [themeContainer, 'screen', 'none', /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
1443
+ 'prose', /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
1444
+ {
1445
+ screen: [themeBreakpoint]
1446
+ }, ...scaleSizing()]
1447
+ }],
1448
+ /**
1449
+ * Height
1450
+ * @see https://tailwindcss.com/docs/height
1451
+ */
1452
+ h: [{
1453
+ h: ['screen', 'lh', ...scaleSizing()]
1454
+ }],
1455
+ /**
1456
+ * Min-Height
1457
+ * @see https://tailwindcss.com/docs/min-height
1458
+ */
1459
+ 'min-h': [{
1460
+ 'min-h': ['screen', 'lh', 'none', ...scaleSizing()]
1461
+ }],
1462
+ /**
1463
+ * Max-Height
1464
+ * @see https://tailwindcss.com/docs/max-height
1465
+ */
1466
+ 'max-h': [{
1467
+ 'max-h': ['screen', 'lh', ...scaleSizing()]
1468
+ }],
1469
+ // ------------------
1470
+ // --- Typography ---
1471
+ // ------------------
1472
+ /**
1473
+ * Font Size
1474
+ * @see https://tailwindcss.com/docs/font-size
1475
+ */
1476
+ 'font-size': [{
1477
+ text: ['base', themeText, isArbitraryVariableLength, isArbitraryLength]
1478
+ }],
1479
+ /**
1480
+ * Font Smoothing
1481
+ * @see https://tailwindcss.com/docs/font-smoothing
1482
+ */
1483
+ 'font-smoothing': ['antialiased', 'subpixel-antialiased'],
1484
+ /**
1485
+ * Font Style
1486
+ * @see https://tailwindcss.com/docs/font-style
1487
+ */
1488
+ 'font-style': ['italic', 'not-italic'],
1489
+ /**
1490
+ * Font Weight
1491
+ * @see https://tailwindcss.com/docs/font-weight
1492
+ */
1493
+ 'font-weight': [{
1494
+ font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight]
1495
+ }],
1496
+ /**
1497
+ * Font Stretch
1498
+ * @see https://tailwindcss.com/docs/font-stretch
1499
+ */
1500
+ 'font-stretch': [{
1501
+ 'font-stretch': ['ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', 'normal', 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded', isPercent, isArbitraryValue]
1502
+ }],
1503
+ /**
1504
+ * Font Family
1505
+ * @see https://tailwindcss.com/docs/font-family
1506
+ */
1507
+ 'font-family': [{
1508
+ font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont]
1509
+ }],
1510
+ /**
1511
+ * Font Variant Numeric
1512
+ * @see https://tailwindcss.com/docs/font-variant-numeric
1513
+ */
1514
+ 'fvn-normal': ['normal-nums'],
1515
+ /**
1516
+ * Font Variant Numeric
1517
+ * @see https://tailwindcss.com/docs/font-variant-numeric
1518
+ */
1519
+ 'fvn-ordinal': ['ordinal'],
1520
+ /**
1521
+ * Font Variant Numeric
1522
+ * @see https://tailwindcss.com/docs/font-variant-numeric
1523
+ */
1524
+ 'fvn-slashed-zero': ['slashed-zero'],
1525
+ /**
1526
+ * Font Variant Numeric
1527
+ * @see https://tailwindcss.com/docs/font-variant-numeric
1528
+ */
1529
+ 'fvn-figure': ['lining-nums', 'oldstyle-nums'],
1530
+ /**
1531
+ * Font Variant Numeric
1532
+ * @see https://tailwindcss.com/docs/font-variant-numeric
1533
+ */
1534
+ 'fvn-spacing': ['proportional-nums', 'tabular-nums'],
1535
+ /**
1536
+ * Font Variant Numeric
1537
+ * @see https://tailwindcss.com/docs/font-variant-numeric
1538
+ */
1539
+ 'fvn-fraction': ['diagonal-fractions', 'stacked-fractions'],
1540
+ /**
1541
+ * Letter Spacing
1542
+ * @see https://tailwindcss.com/docs/letter-spacing
1543
+ */
1544
+ tracking: [{
1545
+ tracking: [themeTracking, isArbitraryVariable, isArbitraryValue]
1546
+ }],
1547
+ /**
1548
+ * Line Clamp
1549
+ * @see https://tailwindcss.com/docs/line-clamp
1550
+ */
1551
+ 'line-clamp': [{
1552
+ 'line-clamp': [isNumber, 'none', isArbitraryVariable, isArbitraryNumber]
1553
+ }],
1554
+ /**
1555
+ * Line Height
1556
+ * @see https://tailwindcss.com/docs/line-height
1557
+ */
1558
+ leading: [{
1559
+ leading: [/** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
1560
+ themeLeading, ...scaleUnambiguousSpacing()]
1561
+ }],
1562
+ /**
1563
+ * List Style Image
1564
+ * @see https://tailwindcss.com/docs/list-style-image
1565
+ */
1566
+ 'list-image': [{
1567
+ 'list-image': ['none', isArbitraryVariable, isArbitraryValue]
1568
+ }],
1569
+ /**
1570
+ * List Style Position
1571
+ * @see https://tailwindcss.com/docs/list-style-position
1572
+ */
1573
+ 'list-style-position': [{
1574
+ list: ['inside', 'outside']
1575
+ }],
1576
+ /**
1577
+ * List Style Type
1578
+ * @see https://tailwindcss.com/docs/list-style-type
1579
+ */
1580
+ 'list-style-type': [{
1581
+ list: ['disc', 'decimal', 'none', isArbitraryVariable, isArbitraryValue]
1582
+ }],
1583
+ /**
1584
+ * Text Alignment
1585
+ * @see https://tailwindcss.com/docs/text-align
1586
+ */
1587
+ 'text-alignment': [{
1588
+ text: ['left', 'center', 'right', 'justify', 'start', 'end']
1589
+ }],
1590
+ /**
1591
+ * Placeholder Color
1592
+ * @deprecated since Tailwind CSS v3.0.0
1593
+ * @see https://v3.tailwindcss.com/docs/placeholder-color
1594
+ */
1595
+ 'placeholder-color': [{
1596
+ placeholder: scaleColor()
1597
+ }],
1598
+ /**
1599
+ * Text Color
1600
+ * @see https://tailwindcss.com/docs/text-color
1601
+ */
1602
+ 'text-color': [{
1603
+ text: scaleColor()
1604
+ }],
1605
+ /**
1606
+ * Text Decoration
1607
+ * @see https://tailwindcss.com/docs/text-decoration
1608
+ */
1609
+ 'text-decoration': ['underline', 'overline', 'line-through', 'no-underline'],
1610
+ /**
1611
+ * Text Decoration Style
1612
+ * @see https://tailwindcss.com/docs/text-decoration-style
1613
+ */
1614
+ 'text-decoration-style': [{
1615
+ decoration: [...scaleLineStyle(), 'wavy']
1616
+ }],
1617
+ /**
1618
+ * Text Decoration Thickness
1619
+ * @see https://tailwindcss.com/docs/text-decoration-thickness
1620
+ */
1621
+ 'text-decoration-thickness': [{
1622
+ decoration: [isNumber, 'from-font', 'auto', isArbitraryVariable, isArbitraryLength]
1623
+ }],
1624
+ /**
1625
+ * Text Decoration Color
1626
+ * @see https://tailwindcss.com/docs/text-decoration-color
1627
+ */
1628
+ 'text-decoration-color': [{
1629
+ decoration: scaleColor()
1630
+ }],
1631
+ /**
1632
+ * Text Underline Offset
1633
+ * @see https://tailwindcss.com/docs/text-underline-offset
1634
+ */
1635
+ 'underline-offset': [{
1636
+ 'underline-offset': [isNumber, 'auto', isArbitraryVariable, isArbitraryValue]
1637
+ }],
1638
+ /**
1639
+ * Text Transform
1640
+ * @see https://tailwindcss.com/docs/text-transform
1641
+ */
1642
+ 'text-transform': ['uppercase', 'lowercase', 'capitalize', 'normal-case'],
1643
+ /**
1644
+ * Text Overflow
1645
+ * @see https://tailwindcss.com/docs/text-overflow
1646
+ */
1647
+ 'text-overflow': ['truncate', 'text-ellipsis', 'text-clip'],
1648
+ /**
1649
+ * Text Wrap
1650
+ * @see https://tailwindcss.com/docs/text-wrap
1651
+ */
1652
+ 'text-wrap': [{
1653
+ text: ['wrap', 'nowrap', 'balance', 'pretty']
1654
+ }],
1655
+ /**
1656
+ * Text Indent
1657
+ * @see https://tailwindcss.com/docs/text-indent
1658
+ */
1659
+ indent: [{
1660
+ indent: scaleUnambiguousSpacing()
1661
+ }],
1662
+ /**
1663
+ * Vertical Alignment
1664
+ * @see https://tailwindcss.com/docs/vertical-align
1665
+ */
1666
+ 'vertical-align': [{
1667
+ align: ['baseline', 'top', 'middle', 'bottom', 'text-top', 'text-bottom', 'sub', 'super', isArbitraryVariable, isArbitraryValue]
1668
+ }],
1669
+ /**
1670
+ * Whitespace
1671
+ * @see https://tailwindcss.com/docs/whitespace
1672
+ */
1673
+ whitespace: [{
1674
+ whitespace: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces']
1675
+ }],
1676
+ /**
1677
+ * Word Break
1678
+ * @see https://tailwindcss.com/docs/word-break
1679
+ */
1680
+ break: [{
1681
+ break: ['normal', 'words', 'all', 'keep']
1682
+ }],
1683
+ /**
1684
+ * Overflow Wrap
1685
+ * @see https://tailwindcss.com/docs/overflow-wrap
1686
+ */
1687
+ wrap: [{
1688
+ wrap: ['break-word', 'anywhere', 'normal']
1689
+ }],
1690
+ /**
1691
+ * Hyphens
1692
+ * @see https://tailwindcss.com/docs/hyphens
1693
+ */
1694
+ hyphens: [{
1695
+ hyphens: ['none', 'manual', 'auto']
1696
+ }],
1697
+ /**
1698
+ * Content
1699
+ * @see https://tailwindcss.com/docs/content
1700
+ */
1701
+ content: [{
1702
+ content: ['none', isArbitraryVariable, isArbitraryValue]
1703
+ }],
1704
+ // -------------------
1705
+ // --- Backgrounds ---
1706
+ // -------------------
1707
+ /**
1708
+ * Background Attachment
1709
+ * @see https://tailwindcss.com/docs/background-attachment
1710
+ */
1711
+ 'bg-attachment': [{
1712
+ bg: ['fixed', 'local', 'scroll']
1713
+ }],
1714
+ /**
1715
+ * Background Clip
1716
+ * @see https://tailwindcss.com/docs/background-clip
1717
+ */
1718
+ 'bg-clip': [{
1719
+ 'bg-clip': ['border', 'padding', 'content', 'text']
1720
+ }],
1721
+ /**
1722
+ * Background Origin
1723
+ * @see https://tailwindcss.com/docs/background-origin
1724
+ */
1725
+ 'bg-origin': [{
1726
+ 'bg-origin': ['border', 'padding', 'content']
1727
+ }],
1728
+ /**
1729
+ * Background Position
1730
+ * @see https://tailwindcss.com/docs/background-position
1731
+ */
1732
+ 'bg-position': [{
1733
+ bg: scaleBgPosition()
1734
+ }],
1735
+ /**
1736
+ * Background Repeat
1737
+ * @see https://tailwindcss.com/docs/background-repeat
1738
+ */
1739
+ 'bg-repeat': [{
1740
+ bg: scaleBgRepeat()
1741
+ }],
1742
+ /**
1743
+ * Background Size
1744
+ * @see https://tailwindcss.com/docs/background-size
1745
+ */
1746
+ 'bg-size': [{
1747
+ bg: scaleBgSize()
1748
+ }],
1749
+ /**
1750
+ * Background Image
1751
+ * @see https://tailwindcss.com/docs/background-image
1752
+ */
1753
+ 'bg-image': [{
1754
+ bg: ['none', {
1755
+ linear: [{
1756
+ to: ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']
1757
+ }, isInteger, isArbitraryVariable, isArbitraryValue],
1758
+ radial: ['', isArbitraryVariable, isArbitraryValue],
1759
+ conic: [isInteger, isArbitraryVariable, isArbitraryValue]
1760
+ }, isArbitraryVariableImage, isArbitraryImage]
1761
+ }],
1762
+ /**
1763
+ * Background Color
1764
+ * @see https://tailwindcss.com/docs/background-color
1765
+ */
1766
+ 'bg-color': [{
1767
+ bg: scaleColor()
1768
+ }],
1769
+ /**
1770
+ * Gradient Color Stops From Position
1771
+ * @see https://tailwindcss.com/docs/gradient-color-stops
1772
+ */
1773
+ 'gradient-from-pos': [{
1774
+ from: scaleGradientStopPosition()
1775
+ }],
1776
+ /**
1777
+ * Gradient Color Stops Via Position
1778
+ * @see https://tailwindcss.com/docs/gradient-color-stops
1779
+ */
1780
+ 'gradient-via-pos': [{
1781
+ via: scaleGradientStopPosition()
1782
+ }],
1783
+ /**
1784
+ * Gradient Color Stops To Position
1785
+ * @see https://tailwindcss.com/docs/gradient-color-stops
1786
+ */
1787
+ 'gradient-to-pos': [{
1788
+ to: scaleGradientStopPosition()
1789
+ }],
1790
+ /**
1791
+ * Gradient Color Stops From
1792
+ * @see https://tailwindcss.com/docs/gradient-color-stops
1793
+ */
1794
+ 'gradient-from': [{
1795
+ from: scaleColor()
1796
+ }],
1797
+ /**
1798
+ * Gradient Color Stops Via
1799
+ * @see https://tailwindcss.com/docs/gradient-color-stops
1800
+ */
1801
+ 'gradient-via': [{
1802
+ via: scaleColor()
1803
+ }],
1804
+ /**
1805
+ * Gradient Color Stops To
1806
+ * @see https://tailwindcss.com/docs/gradient-color-stops
1807
+ */
1808
+ 'gradient-to': [{
1809
+ to: scaleColor()
1810
+ }],
1811
+ // ---------------
1812
+ // --- Borders ---
1813
+ // ---------------
1814
+ /**
1815
+ * Border Radius
1816
+ * @see https://tailwindcss.com/docs/border-radius
1817
+ */
1818
+ rounded: [{
1819
+ rounded: scaleRadius()
1820
+ }],
1821
+ /**
1822
+ * Border Radius Start
1823
+ * @see https://tailwindcss.com/docs/border-radius
1824
+ */
1825
+ 'rounded-s': [{
1826
+ 'rounded-s': scaleRadius()
1827
+ }],
1828
+ /**
1829
+ * Border Radius End
1830
+ * @see https://tailwindcss.com/docs/border-radius
1831
+ */
1832
+ 'rounded-e': [{
1833
+ 'rounded-e': scaleRadius()
1834
+ }],
1835
+ /**
1836
+ * Border Radius Top
1837
+ * @see https://tailwindcss.com/docs/border-radius
1838
+ */
1839
+ 'rounded-t': [{
1840
+ 'rounded-t': scaleRadius()
1841
+ }],
1842
+ /**
1843
+ * Border Radius Right
1844
+ * @see https://tailwindcss.com/docs/border-radius
1845
+ */
1846
+ 'rounded-r': [{
1847
+ 'rounded-r': scaleRadius()
1848
+ }],
1849
+ /**
1850
+ * Border Radius Bottom
1851
+ * @see https://tailwindcss.com/docs/border-radius
1852
+ */
1853
+ 'rounded-b': [{
1854
+ 'rounded-b': scaleRadius()
1855
+ }],
1856
+ /**
1857
+ * Border Radius Left
1858
+ * @see https://tailwindcss.com/docs/border-radius
1859
+ */
1860
+ 'rounded-l': [{
1861
+ 'rounded-l': scaleRadius()
1862
+ }],
1863
+ /**
1864
+ * Border Radius Start Start
1865
+ * @see https://tailwindcss.com/docs/border-radius
1866
+ */
1867
+ 'rounded-ss': [{
1868
+ 'rounded-ss': scaleRadius()
1869
+ }],
1870
+ /**
1871
+ * Border Radius Start End
1872
+ * @see https://tailwindcss.com/docs/border-radius
1873
+ */
1874
+ 'rounded-se': [{
1875
+ 'rounded-se': scaleRadius()
1876
+ }],
1877
+ /**
1878
+ * Border Radius End End
1879
+ * @see https://tailwindcss.com/docs/border-radius
1880
+ */
1881
+ 'rounded-ee': [{
1882
+ 'rounded-ee': scaleRadius()
1883
+ }],
1884
+ /**
1885
+ * Border Radius End Start
1886
+ * @see https://tailwindcss.com/docs/border-radius
1887
+ */
1888
+ 'rounded-es': [{
1889
+ 'rounded-es': scaleRadius()
1890
+ }],
1891
+ /**
1892
+ * Border Radius Top Left
1893
+ * @see https://tailwindcss.com/docs/border-radius
1894
+ */
1895
+ 'rounded-tl': [{
1896
+ 'rounded-tl': scaleRadius()
1897
+ }],
1898
+ /**
1899
+ * Border Radius Top Right
1900
+ * @see https://tailwindcss.com/docs/border-radius
1901
+ */
1902
+ 'rounded-tr': [{
1903
+ 'rounded-tr': scaleRadius()
1904
+ }],
1905
+ /**
1906
+ * Border Radius Bottom Right
1907
+ * @see https://tailwindcss.com/docs/border-radius
1908
+ */
1909
+ 'rounded-br': [{
1910
+ 'rounded-br': scaleRadius()
1911
+ }],
1912
+ /**
1913
+ * Border Radius Bottom Left
1914
+ * @see https://tailwindcss.com/docs/border-radius
1915
+ */
1916
+ 'rounded-bl': [{
1917
+ 'rounded-bl': scaleRadius()
1918
+ }],
1919
+ /**
1920
+ * Border Width
1921
+ * @see https://tailwindcss.com/docs/border-width
1922
+ */
1923
+ 'border-w': [{
1924
+ border: scaleBorderWidth()
1925
+ }],
1926
+ /**
1927
+ * Border Width X
1928
+ * @see https://tailwindcss.com/docs/border-width
1929
+ */
1930
+ 'border-w-x': [{
1931
+ 'border-x': scaleBorderWidth()
1932
+ }],
1933
+ /**
1934
+ * Border Width Y
1935
+ * @see https://tailwindcss.com/docs/border-width
1936
+ */
1937
+ 'border-w-y': [{
1938
+ 'border-y': scaleBorderWidth()
1939
+ }],
1940
+ /**
1941
+ * Border Width Start
1942
+ * @see https://tailwindcss.com/docs/border-width
1943
+ */
1944
+ 'border-w-s': [{
1945
+ 'border-s': scaleBorderWidth()
1946
+ }],
1947
+ /**
1948
+ * Border Width End
1949
+ * @see https://tailwindcss.com/docs/border-width
1950
+ */
1951
+ 'border-w-e': [{
1952
+ 'border-e': scaleBorderWidth()
1953
+ }],
1954
+ /**
1955
+ * Border Width Top
1956
+ * @see https://tailwindcss.com/docs/border-width
1957
+ */
1958
+ 'border-w-t': [{
1959
+ 'border-t': scaleBorderWidth()
1960
+ }],
1961
+ /**
1962
+ * Border Width Right
1963
+ * @see https://tailwindcss.com/docs/border-width
1964
+ */
1965
+ 'border-w-r': [{
1966
+ 'border-r': scaleBorderWidth()
1967
+ }],
1968
+ /**
1969
+ * Border Width Bottom
1970
+ * @see https://tailwindcss.com/docs/border-width
1971
+ */
1972
+ 'border-w-b': [{
1973
+ 'border-b': scaleBorderWidth()
1974
+ }],
1975
+ /**
1976
+ * Border Width Left
1977
+ * @see https://tailwindcss.com/docs/border-width
1978
+ */
1979
+ 'border-w-l': [{
1980
+ 'border-l': scaleBorderWidth()
1981
+ }],
1982
+ /**
1983
+ * Divide Width X
1984
+ * @see https://tailwindcss.com/docs/border-width#between-children
1985
+ */
1986
+ 'divide-x': [{
1987
+ 'divide-x': scaleBorderWidth()
1988
+ }],
1989
+ /**
1990
+ * Divide Width X Reverse
1991
+ * @see https://tailwindcss.com/docs/border-width#between-children
1992
+ */
1993
+ 'divide-x-reverse': ['divide-x-reverse'],
1994
+ /**
1995
+ * Divide Width Y
1996
+ * @see https://tailwindcss.com/docs/border-width#between-children
1997
+ */
1998
+ 'divide-y': [{
1999
+ 'divide-y': scaleBorderWidth()
2000
+ }],
2001
+ /**
2002
+ * Divide Width Y Reverse
2003
+ * @see https://tailwindcss.com/docs/border-width#between-children
2004
+ */
2005
+ 'divide-y-reverse': ['divide-y-reverse'],
2006
+ /**
2007
+ * Border Style
2008
+ * @see https://tailwindcss.com/docs/border-style
2009
+ */
2010
+ 'border-style': [{
2011
+ border: [...scaleLineStyle(), 'hidden', 'none']
2012
+ }],
2013
+ /**
2014
+ * Divide Style
2015
+ * @see https://tailwindcss.com/docs/border-style#setting-the-divider-style
2016
+ */
2017
+ 'divide-style': [{
2018
+ divide: [...scaleLineStyle(), 'hidden', 'none']
2019
+ }],
2020
+ /**
2021
+ * Border Color
2022
+ * @see https://tailwindcss.com/docs/border-color
2023
+ */
2024
+ 'border-color': [{
2025
+ border: scaleColor()
2026
+ }],
2027
+ /**
2028
+ * Border Color X
2029
+ * @see https://tailwindcss.com/docs/border-color
2030
+ */
2031
+ 'border-color-x': [{
2032
+ 'border-x': scaleColor()
2033
+ }],
2034
+ /**
2035
+ * Border Color Y
2036
+ * @see https://tailwindcss.com/docs/border-color
2037
+ */
2038
+ 'border-color-y': [{
2039
+ 'border-y': scaleColor()
2040
+ }],
2041
+ /**
2042
+ * Border Color S
2043
+ * @see https://tailwindcss.com/docs/border-color
2044
+ */
2045
+ 'border-color-s': [{
2046
+ 'border-s': scaleColor()
2047
+ }],
2048
+ /**
2049
+ * Border Color E
2050
+ * @see https://tailwindcss.com/docs/border-color
2051
+ */
2052
+ 'border-color-e': [{
2053
+ 'border-e': scaleColor()
2054
+ }],
2055
+ /**
2056
+ * Border Color Top
2057
+ * @see https://tailwindcss.com/docs/border-color
2058
+ */
2059
+ 'border-color-t': [{
2060
+ 'border-t': scaleColor()
2061
+ }],
2062
+ /**
2063
+ * Border Color Right
2064
+ * @see https://tailwindcss.com/docs/border-color
2065
+ */
2066
+ 'border-color-r': [{
2067
+ 'border-r': scaleColor()
2068
+ }],
2069
+ /**
2070
+ * Border Color Bottom
2071
+ * @see https://tailwindcss.com/docs/border-color
2072
+ */
2073
+ 'border-color-b': [{
2074
+ 'border-b': scaleColor()
2075
+ }],
2076
+ /**
2077
+ * Border Color Left
2078
+ * @see https://tailwindcss.com/docs/border-color
2079
+ */
2080
+ 'border-color-l': [{
2081
+ 'border-l': scaleColor()
2082
+ }],
2083
+ /**
2084
+ * Divide Color
2085
+ * @see https://tailwindcss.com/docs/divide-color
2086
+ */
2087
+ 'divide-color': [{
2088
+ divide: scaleColor()
2089
+ }],
2090
+ /**
2091
+ * Outline Style
2092
+ * @see https://tailwindcss.com/docs/outline-style
2093
+ */
2094
+ 'outline-style': [{
2095
+ outline: [...scaleLineStyle(), 'none', 'hidden']
2096
+ }],
2097
+ /**
2098
+ * Outline Offset
2099
+ * @see https://tailwindcss.com/docs/outline-offset
2100
+ */
2101
+ 'outline-offset': [{
2102
+ 'outline-offset': [isNumber, isArbitraryVariable, isArbitraryValue]
2103
+ }],
2104
+ /**
2105
+ * Outline Width
2106
+ * @see https://tailwindcss.com/docs/outline-width
2107
+ */
2108
+ 'outline-w': [{
2109
+ outline: ['', isNumber, isArbitraryVariableLength, isArbitraryLength]
2110
+ }],
2111
+ /**
2112
+ * Outline Color
2113
+ * @see https://tailwindcss.com/docs/outline-color
2114
+ */
2115
+ 'outline-color': [{
2116
+ outline: scaleColor()
2117
+ }],
2118
+ // ---------------
2119
+ // --- Effects ---
2120
+ // ---------------
2121
+ /**
2122
+ * Box Shadow
2123
+ * @see https://tailwindcss.com/docs/box-shadow
2124
+ */
2125
+ shadow: [{
2126
+ shadow: [
2127
+ // Deprecated since Tailwind CSS v4.0.0
2128
+ '', 'none', themeShadow, isArbitraryVariableShadow, isArbitraryShadow]
2129
+ }],
2130
+ /**
2131
+ * Box Shadow Color
2132
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color
2133
+ */
2134
+ 'shadow-color': [{
2135
+ shadow: scaleColor()
2136
+ }],
2137
+ /**
2138
+ * Inset Box Shadow
2139
+ * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow
2140
+ */
2141
+ 'inset-shadow': [{
2142
+ 'inset-shadow': ['none', themeInsetShadow, isArbitraryVariableShadow, isArbitraryShadow]
2143
+ }],
2144
+ /**
2145
+ * Inset Box Shadow Color
2146
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color
2147
+ */
2148
+ 'inset-shadow-color': [{
2149
+ 'inset-shadow': scaleColor()
2150
+ }],
2151
+ /**
2152
+ * Ring Width
2153
+ * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring
2154
+ */
2155
+ 'ring-w': [{
2156
+ ring: scaleBorderWidth()
2157
+ }],
2158
+ /**
2159
+ * Ring Width Inset
2160
+ * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings
2161
+ * @deprecated since Tailwind CSS v4.0.0
2162
+ * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158
2163
+ */
2164
+ 'ring-w-inset': ['ring-inset'],
2165
+ /**
2166
+ * Ring Color
2167
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color
2168
+ */
2169
+ 'ring-color': [{
2170
+ ring: scaleColor()
2171
+ }],
2172
+ /**
2173
+ * Ring Offset Width
2174
+ * @see https://v3.tailwindcss.com/docs/ring-offset-width
2175
+ * @deprecated since Tailwind CSS v4.0.0
2176
+ * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158
2177
+ */
2178
+ 'ring-offset-w': [{
2179
+ 'ring-offset': [isNumber, isArbitraryLength]
2180
+ }],
2181
+ /**
2182
+ * Ring Offset Color
2183
+ * @see https://v3.tailwindcss.com/docs/ring-offset-color
2184
+ * @deprecated since Tailwind CSS v4.0.0
2185
+ * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158
2186
+ */
2187
+ 'ring-offset-color': [{
2188
+ 'ring-offset': scaleColor()
2189
+ }],
2190
+ /**
2191
+ * Inset Ring Width
2192
+ * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring
2193
+ */
2194
+ 'inset-ring-w': [{
2195
+ 'inset-ring': scaleBorderWidth()
2196
+ }],
2197
+ /**
2198
+ * Inset Ring Color
2199
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color
2200
+ */
2201
+ 'inset-ring-color': [{
2202
+ 'inset-ring': scaleColor()
2203
+ }],
2204
+ /**
2205
+ * Text Shadow
2206
+ * @see https://tailwindcss.com/docs/text-shadow
2207
+ */
2208
+ 'text-shadow': [{
2209
+ 'text-shadow': ['none', themeTextShadow, isArbitraryVariableShadow, isArbitraryShadow]
2210
+ }],
2211
+ /**
2212
+ * Text Shadow Color
2213
+ * @see https://tailwindcss.com/docs/text-shadow#setting-the-shadow-color
2214
+ */
2215
+ 'text-shadow-color': [{
2216
+ 'text-shadow': scaleColor()
2217
+ }],
2218
+ /**
2219
+ * Opacity
2220
+ * @see https://tailwindcss.com/docs/opacity
2221
+ */
2222
+ opacity: [{
2223
+ opacity: [isNumber, isArbitraryVariable, isArbitraryValue]
2224
+ }],
2225
+ /**
2226
+ * Mix Blend Mode
2227
+ * @see https://tailwindcss.com/docs/mix-blend-mode
2228
+ */
2229
+ 'mix-blend': [{
2230
+ 'mix-blend': [...scaleBlendMode(), 'plus-darker', 'plus-lighter']
2231
+ }],
2232
+ /**
2233
+ * Background Blend Mode
2234
+ * @see https://tailwindcss.com/docs/background-blend-mode
2235
+ */
2236
+ 'bg-blend': [{
2237
+ 'bg-blend': scaleBlendMode()
2238
+ }],
2239
+ /**
2240
+ * Mask Clip
2241
+ * @see https://tailwindcss.com/docs/mask-clip
2242
+ */
2243
+ 'mask-clip': [{
2244
+ 'mask-clip': ['border', 'padding', 'content', 'fill', 'stroke', 'view']
2245
+ }, 'mask-no-clip'],
2246
+ /**
2247
+ * Mask Composite
2248
+ * @see https://tailwindcss.com/docs/mask-composite
2249
+ */
2250
+ 'mask-composite': [{
2251
+ mask: ['add', 'subtract', 'intersect', 'exclude']
2252
+ }],
2253
+ /**
2254
+ * Mask Image
2255
+ * @see https://tailwindcss.com/docs/mask-image
2256
+ */
2257
+ 'mask-image-linear-pos': [{
2258
+ 'mask-linear': [isNumber]
2259
+ }],
2260
+ 'mask-image-linear-from-pos': [{
2261
+ 'mask-linear-from': scaleMaskImagePosition()
2262
+ }],
2263
+ 'mask-image-linear-to-pos': [{
2264
+ 'mask-linear-to': scaleMaskImagePosition()
2265
+ }],
2266
+ 'mask-image-linear-from-color': [{
2267
+ 'mask-linear-from': scaleColor()
2268
+ }],
2269
+ 'mask-image-linear-to-color': [{
2270
+ 'mask-linear-to': scaleColor()
2271
+ }],
2272
+ 'mask-image-t-from-pos': [{
2273
+ 'mask-t-from': scaleMaskImagePosition()
2274
+ }],
2275
+ 'mask-image-t-to-pos': [{
2276
+ 'mask-t-to': scaleMaskImagePosition()
2277
+ }],
2278
+ 'mask-image-t-from-color': [{
2279
+ 'mask-t-from': scaleColor()
2280
+ }],
2281
+ 'mask-image-t-to-color': [{
2282
+ 'mask-t-to': scaleColor()
2283
+ }],
2284
+ 'mask-image-r-from-pos': [{
2285
+ 'mask-r-from': scaleMaskImagePosition()
2286
+ }],
2287
+ 'mask-image-r-to-pos': [{
2288
+ 'mask-r-to': scaleMaskImagePosition()
2289
+ }],
2290
+ 'mask-image-r-from-color': [{
2291
+ 'mask-r-from': scaleColor()
2292
+ }],
2293
+ 'mask-image-r-to-color': [{
2294
+ 'mask-r-to': scaleColor()
2295
+ }],
2296
+ 'mask-image-b-from-pos': [{
2297
+ 'mask-b-from': scaleMaskImagePosition()
2298
+ }],
2299
+ 'mask-image-b-to-pos': [{
2300
+ 'mask-b-to': scaleMaskImagePosition()
2301
+ }],
2302
+ 'mask-image-b-from-color': [{
2303
+ 'mask-b-from': scaleColor()
2304
+ }],
2305
+ 'mask-image-b-to-color': [{
2306
+ 'mask-b-to': scaleColor()
2307
+ }],
2308
+ 'mask-image-l-from-pos': [{
2309
+ 'mask-l-from': scaleMaskImagePosition()
2310
+ }],
2311
+ 'mask-image-l-to-pos': [{
2312
+ 'mask-l-to': scaleMaskImagePosition()
2313
+ }],
2314
+ 'mask-image-l-from-color': [{
2315
+ 'mask-l-from': scaleColor()
2316
+ }],
2317
+ 'mask-image-l-to-color': [{
2318
+ 'mask-l-to': scaleColor()
2319
+ }],
2320
+ 'mask-image-x-from-pos': [{
2321
+ 'mask-x-from': scaleMaskImagePosition()
2322
+ }],
2323
+ 'mask-image-x-to-pos': [{
2324
+ 'mask-x-to': scaleMaskImagePosition()
2325
+ }],
2326
+ 'mask-image-x-from-color': [{
2327
+ 'mask-x-from': scaleColor()
2328
+ }],
2329
+ 'mask-image-x-to-color': [{
2330
+ 'mask-x-to': scaleColor()
2331
+ }],
2332
+ 'mask-image-y-from-pos': [{
2333
+ 'mask-y-from': scaleMaskImagePosition()
2334
+ }],
2335
+ 'mask-image-y-to-pos': [{
2336
+ 'mask-y-to': scaleMaskImagePosition()
2337
+ }],
2338
+ 'mask-image-y-from-color': [{
2339
+ 'mask-y-from': scaleColor()
2340
+ }],
2341
+ 'mask-image-y-to-color': [{
2342
+ 'mask-y-to': scaleColor()
2343
+ }],
2344
+ 'mask-image-radial': [{
2345
+ 'mask-radial': [isArbitraryVariable, isArbitraryValue]
2346
+ }],
2347
+ 'mask-image-radial-from-pos': [{
2348
+ 'mask-radial-from': scaleMaskImagePosition()
2349
+ }],
2350
+ 'mask-image-radial-to-pos': [{
2351
+ 'mask-radial-to': scaleMaskImagePosition()
2352
+ }],
2353
+ 'mask-image-radial-from-color': [{
2354
+ 'mask-radial-from': scaleColor()
2355
+ }],
2356
+ 'mask-image-radial-to-color': [{
2357
+ 'mask-radial-to': scaleColor()
2358
+ }],
2359
+ 'mask-image-radial-shape': [{
2360
+ 'mask-radial': ['circle', 'ellipse']
2361
+ }],
2362
+ 'mask-image-radial-size': [{
2363
+ 'mask-radial': [{
2364
+ closest: ['side', 'corner'],
2365
+ farthest: ['side', 'corner']
2366
+ }]
2367
+ }],
2368
+ 'mask-image-radial-pos': [{
2369
+ 'mask-radial-at': scalePosition()
2370
+ }],
2371
+ 'mask-image-conic-pos': [{
2372
+ 'mask-conic': [isNumber]
2373
+ }],
2374
+ 'mask-image-conic-from-pos': [{
2375
+ 'mask-conic-from': scaleMaskImagePosition()
2376
+ }],
2377
+ 'mask-image-conic-to-pos': [{
2378
+ 'mask-conic-to': scaleMaskImagePosition()
2379
+ }],
2380
+ 'mask-image-conic-from-color': [{
2381
+ 'mask-conic-from': scaleColor()
2382
+ }],
2383
+ 'mask-image-conic-to-color': [{
2384
+ 'mask-conic-to': scaleColor()
2385
+ }],
2386
+ /**
2387
+ * Mask Mode
2388
+ * @see https://tailwindcss.com/docs/mask-mode
2389
+ */
2390
+ 'mask-mode': [{
2391
+ mask: ['alpha', 'luminance', 'match']
2392
+ }],
2393
+ /**
2394
+ * Mask Origin
2395
+ * @see https://tailwindcss.com/docs/mask-origin
2396
+ */
2397
+ 'mask-origin': [{
2398
+ 'mask-origin': ['border', 'padding', 'content', 'fill', 'stroke', 'view']
2399
+ }],
2400
+ /**
2401
+ * Mask Position
2402
+ * @see https://tailwindcss.com/docs/mask-position
2403
+ */
2404
+ 'mask-position': [{
2405
+ mask: scaleBgPosition()
2406
+ }],
2407
+ /**
2408
+ * Mask Repeat
2409
+ * @see https://tailwindcss.com/docs/mask-repeat
2410
+ */
2411
+ 'mask-repeat': [{
2412
+ mask: scaleBgRepeat()
2413
+ }],
2414
+ /**
2415
+ * Mask Size
2416
+ * @see https://tailwindcss.com/docs/mask-size
2417
+ */
2418
+ 'mask-size': [{
2419
+ mask: scaleBgSize()
2420
+ }],
2421
+ /**
2422
+ * Mask Type
2423
+ * @see https://tailwindcss.com/docs/mask-type
2424
+ */
2425
+ 'mask-type': [{
2426
+ 'mask-type': ['alpha', 'luminance']
2427
+ }],
2428
+ /**
2429
+ * Mask Image
2430
+ * @see https://tailwindcss.com/docs/mask-image
2431
+ */
2432
+ 'mask-image': [{
2433
+ mask: ['none', isArbitraryVariable, isArbitraryValue]
2434
+ }],
2435
+ // ---------------
2436
+ // --- Filters ---
2437
+ // ---------------
2438
+ /**
2439
+ * Filter
2440
+ * @see https://tailwindcss.com/docs/filter
2441
+ */
2442
+ filter: [{
2443
+ filter: [
2444
+ // Deprecated since Tailwind CSS v3.0.0
2445
+ '', 'none', isArbitraryVariable, isArbitraryValue]
2446
+ }],
2447
+ /**
2448
+ * Blur
2449
+ * @see https://tailwindcss.com/docs/blur
2450
+ */
2451
+ blur: [{
2452
+ blur: scaleBlur()
2453
+ }],
2454
+ /**
2455
+ * Brightness
2456
+ * @see https://tailwindcss.com/docs/brightness
2457
+ */
2458
+ brightness: [{
2459
+ brightness: [isNumber, isArbitraryVariable, isArbitraryValue]
2460
+ }],
2461
+ /**
2462
+ * Contrast
2463
+ * @see https://tailwindcss.com/docs/contrast
2464
+ */
2465
+ contrast: [{
2466
+ contrast: [isNumber, isArbitraryVariable, isArbitraryValue]
2467
+ }],
2468
+ /**
2469
+ * Drop Shadow
2470
+ * @see https://tailwindcss.com/docs/drop-shadow
2471
+ */
2472
+ 'drop-shadow': [{
2473
+ 'drop-shadow': [
2474
+ // Deprecated since Tailwind CSS v4.0.0
2475
+ '', 'none', themeDropShadow, isArbitraryVariableShadow, isArbitraryShadow]
2476
+ }],
2477
+ /**
2478
+ * Drop Shadow Color
2479
+ * @see https://tailwindcss.com/docs/filter-drop-shadow#setting-the-shadow-color
2480
+ */
2481
+ 'drop-shadow-color': [{
2482
+ 'drop-shadow': scaleColor()
2483
+ }],
2484
+ /**
2485
+ * Grayscale
2486
+ * @see https://tailwindcss.com/docs/grayscale
2487
+ */
2488
+ grayscale: [{
2489
+ grayscale: ['', isNumber, isArbitraryVariable, isArbitraryValue]
2490
+ }],
2491
+ /**
2492
+ * Hue Rotate
2493
+ * @see https://tailwindcss.com/docs/hue-rotate
2494
+ */
2495
+ 'hue-rotate': [{
2496
+ 'hue-rotate': [isNumber, isArbitraryVariable, isArbitraryValue]
2497
+ }],
2498
+ /**
2499
+ * Invert
2500
+ * @see https://tailwindcss.com/docs/invert
2501
+ */
2502
+ invert: [{
2503
+ invert: ['', isNumber, isArbitraryVariable, isArbitraryValue]
2504
+ }],
2505
+ /**
2506
+ * Saturate
2507
+ * @see https://tailwindcss.com/docs/saturate
2508
+ */
2509
+ saturate: [{
2510
+ saturate: [isNumber, isArbitraryVariable, isArbitraryValue]
2511
+ }],
2512
+ /**
2513
+ * Sepia
2514
+ * @see https://tailwindcss.com/docs/sepia
2515
+ */
2516
+ sepia: [{
2517
+ sepia: ['', isNumber, isArbitraryVariable, isArbitraryValue]
2518
+ }],
2519
+ /**
2520
+ * Backdrop Filter
2521
+ * @see https://tailwindcss.com/docs/backdrop-filter
2522
+ */
2523
+ 'backdrop-filter': [{
2524
+ 'backdrop-filter': [
2525
+ // Deprecated since Tailwind CSS v3.0.0
2526
+ '', 'none', isArbitraryVariable, isArbitraryValue]
2527
+ }],
2528
+ /**
2529
+ * Backdrop Blur
2530
+ * @see https://tailwindcss.com/docs/backdrop-blur
2531
+ */
2532
+ 'backdrop-blur': [{
2533
+ 'backdrop-blur': scaleBlur()
2534
+ }],
2535
+ /**
2536
+ * Backdrop Brightness
2537
+ * @see https://tailwindcss.com/docs/backdrop-brightness
2538
+ */
2539
+ 'backdrop-brightness': [{
2540
+ 'backdrop-brightness': [isNumber, isArbitraryVariable, isArbitraryValue]
2541
+ }],
2542
+ /**
2543
+ * Backdrop Contrast
2544
+ * @see https://tailwindcss.com/docs/backdrop-contrast
2545
+ */
2546
+ 'backdrop-contrast': [{
2547
+ 'backdrop-contrast': [isNumber, isArbitraryVariable, isArbitraryValue]
2548
+ }],
2549
+ /**
2550
+ * Backdrop Grayscale
2551
+ * @see https://tailwindcss.com/docs/backdrop-grayscale
2552
+ */
2553
+ 'backdrop-grayscale': [{
2554
+ 'backdrop-grayscale': ['', isNumber, isArbitraryVariable, isArbitraryValue]
2555
+ }],
2556
+ /**
2557
+ * Backdrop Hue Rotate
2558
+ * @see https://tailwindcss.com/docs/backdrop-hue-rotate
2559
+ */
2560
+ 'backdrop-hue-rotate': [{
2561
+ 'backdrop-hue-rotate': [isNumber, isArbitraryVariable, isArbitraryValue]
2562
+ }],
2563
+ /**
2564
+ * Backdrop Invert
2565
+ * @see https://tailwindcss.com/docs/backdrop-invert
2566
+ */
2567
+ 'backdrop-invert': [{
2568
+ 'backdrop-invert': ['', isNumber, isArbitraryVariable, isArbitraryValue]
2569
+ }],
2570
+ /**
2571
+ * Backdrop Opacity
2572
+ * @see https://tailwindcss.com/docs/backdrop-opacity
2573
+ */
2574
+ 'backdrop-opacity': [{
2575
+ 'backdrop-opacity': [isNumber, isArbitraryVariable, isArbitraryValue]
2576
+ }],
2577
+ /**
2578
+ * Backdrop Saturate
2579
+ * @see https://tailwindcss.com/docs/backdrop-saturate
2580
+ */
2581
+ 'backdrop-saturate': [{
2582
+ 'backdrop-saturate': [isNumber, isArbitraryVariable, isArbitraryValue]
2583
+ }],
2584
+ /**
2585
+ * Backdrop Sepia
2586
+ * @see https://tailwindcss.com/docs/backdrop-sepia
2587
+ */
2588
+ 'backdrop-sepia': [{
2589
+ 'backdrop-sepia': ['', isNumber, isArbitraryVariable, isArbitraryValue]
2590
+ }],
2591
+ // --------------
2592
+ // --- Tables ---
2593
+ // --------------
2594
+ /**
2595
+ * Border Collapse
2596
+ * @see https://tailwindcss.com/docs/border-collapse
2597
+ */
2598
+ 'border-collapse': [{
2599
+ border: ['collapse', 'separate']
2600
+ }],
2601
+ /**
2602
+ * Border Spacing
2603
+ * @see https://tailwindcss.com/docs/border-spacing
2604
+ */
2605
+ 'border-spacing': [{
2606
+ 'border-spacing': scaleUnambiguousSpacing()
2607
+ }],
2608
+ /**
2609
+ * Border Spacing X
2610
+ * @see https://tailwindcss.com/docs/border-spacing
2611
+ */
2612
+ 'border-spacing-x': [{
2613
+ 'border-spacing-x': scaleUnambiguousSpacing()
2614
+ }],
2615
+ /**
2616
+ * Border Spacing Y
2617
+ * @see https://tailwindcss.com/docs/border-spacing
2618
+ */
2619
+ 'border-spacing-y': [{
2620
+ 'border-spacing-y': scaleUnambiguousSpacing()
2621
+ }],
2622
+ /**
2623
+ * Table Layout
2624
+ * @see https://tailwindcss.com/docs/table-layout
2625
+ */
2626
+ 'table-layout': [{
2627
+ table: ['auto', 'fixed']
2628
+ }],
2629
+ /**
2630
+ * Caption Side
2631
+ * @see https://tailwindcss.com/docs/caption-side
2632
+ */
2633
+ caption: [{
2634
+ caption: ['top', 'bottom']
2635
+ }],
2636
+ // ---------------------------------
2637
+ // --- Transitions and Animation ---
2638
+ // ---------------------------------
2639
+ /**
2640
+ * Transition Property
2641
+ * @see https://tailwindcss.com/docs/transition-property
2642
+ */
2643
+ transition: [{
2644
+ transition: ['', 'all', 'colors', 'opacity', 'shadow', 'transform', 'none', isArbitraryVariable, isArbitraryValue]
2645
+ }],
2646
+ /**
2647
+ * Transition Behavior
2648
+ * @see https://tailwindcss.com/docs/transition-behavior
2649
+ */
2650
+ 'transition-behavior': [{
2651
+ transition: ['normal', 'discrete']
2652
+ }],
2653
+ /**
2654
+ * Transition Duration
2655
+ * @see https://tailwindcss.com/docs/transition-duration
2656
+ */
2657
+ duration: [{
2658
+ duration: [isNumber, 'initial', isArbitraryVariable, isArbitraryValue]
2659
+ }],
2660
+ /**
2661
+ * Transition Timing Function
2662
+ * @see https://tailwindcss.com/docs/transition-timing-function
2663
+ */
2664
+ ease: [{
2665
+ ease: ['linear', 'initial', themeEase, isArbitraryVariable, isArbitraryValue]
2666
+ }],
2667
+ /**
2668
+ * Transition Delay
2669
+ * @see https://tailwindcss.com/docs/transition-delay
2670
+ */
2671
+ delay: [{
2672
+ delay: [isNumber, isArbitraryVariable, isArbitraryValue]
2673
+ }],
2674
+ /**
2675
+ * Animation
2676
+ * @see https://tailwindcss.com/docs/animation
2677
+ */
2678
+ animate: [{
2679
+ animate: ['none', themeAnimate, isArbitraryVariable, isArbitraryValue]
2680
+ }],
2681
+ // ------------------
2682
+ // --- Transforms ---
2683
+ // ------------------
2684
+ /**
2685
+ * Backface Visibility
2686
+ * @see https://tailwindcss.com/docs/backface-visibility
2687
+ */
2688
+ backface: [{
2689
+ backface: ['hidden', 'visible']
2690
+ }],
2691
+ /**
2692
+ * Perspective
2693
+ * @see https://tailwindcss.com/docs/perspective
2694
+ */
2695
+ perspective: [{
2696
+ perspective: [themePerspective, isArbitraryVariable, isArbitraryValue]
2697
+ }],
2698
+ /**
2699
+ * Perspective Origin
2700
+ * @see https://tailwindcss.com/docs/perspective-origin
2701
+ */
2702
+ 'perspective-origin': [{
2703
+ 'perspective-origin': scalePositionWithArbitrary()
2704
+ }],
2705
+ /**
2706
+ * Rotate
2707
+ * @see https://tailwindcss.com/docs/rotate
2708
+ */
2709
+ rotate: [{
2710
+ rotate: scaleRotate()
2711
+ }],
2712
+ /**
2713
+ * Rotate X
2714
+ * @see https://tailwindcss.com/docs/rotate
2715
+ */
2716
+ 'rotate-x': [{
2717
+ 'rotate-x': scaleRotate()
2718
+ }],
2719
+ /**
2720
+ * Rotate Y
2721
+ * @see https://tailwindcss.com/docs/rotate
2722
+ */
2723
+ 'rotate-y': [{
2724
+ 'rotate-y': scaleRotate()
2725
+ }],
2726
+ /**
2727
+ * Rotate Z
2728
+ * @see https://tailwindcss.com/docs/rotate
2729
+ */
2730
+ 'rotate-z': [{
2731
+ 'rotate-z': scaleRotate()
2732
+ }],
2733
+ /**
2734
+ * Scale
2735
+ * @see https://tailwindcss.com/docs/scale
2736
+ */
2737
+ scale: [{
2738
+ scale: scaleScale()
2739
+ }],
2740
+ /**
2741
+ * Scale X
2742
+ * @see https://tailwindcss.com/docs/scale
2743
+ */
2744
+ 'scale-x': [{
2745
+ 'scale-x': scaleScale()
2746
+ }],
2747
+ /**
2748
+ * Scale Y
2749
+ * @see https://tailwindcss.com/docs/scale
2750
+ */
2751
+ 'scale-y': [{
2752
+ 'scale-y': scaleScale()
2753
+ }],
2754
+ /**
2755
+ * Scale Z
2756
+ * @see https://tailwindcss.com/docs/scale
2757
+ */
2758
+ 'scale-z': [{
2759
+ 'scale-z': scaleScale()
2760
+ }],
2761
+ /**
2762
+ * Scale 3D
2763
+ * @see https://tailwindcss.com/docs/scale
2764
+ */
2765
+ 'scale-3d': ['scale-3d'],
2766
+ /**
2767
+ * Skew
2768
+ * @see https://tailwindcss.com/docs/skew
2769
+ */
2770
+ skew: [{
2771
+ skew: scaleSkew()
2772
+ }],
2773
+ /**
2774
+ * Skew X
2775
+ * @see https://tailwindcss.com/docs/skew
2776
+ */
2777
+ 'skew-x': [{
2778
+ 'skew-x': scaleSkew()
2779
+ }],
2780
+ /**
2781
+ * Skew Y
2782
+ * @see https://tailwindcss.com/docs/skew
2783
+ */
2784
+ 'skew-y': [{
2785
+ 'skew-y': scaleSkew()
2786
+ }],
2787
+ /**
2788
+ * Transform
2789
+ * @see https://tailwindcss.com/docs/transform
2790
+ */
2791
+ transform: [{
2792
+ transform: [isArbitraryVariable, isArbitraryValue, '', 'none', 'gpu', 'cpu']
2793
+ }],
2794
+ /**
2795
+ * Transform Origin
2796
+ * @see https://tailwindcss.com/docs/transform-origin
2797
+ */
2798
+ 'transform-origin': [{
2799
+ origin: scalePositionWithArbitrary()
2800
+ }],
2801
+ /**
2802
+ * Transform Style
2803
+ * @see https://tailwindcss.com/docs/transform-style
2804
+ */
2805
+ 'transform-style': [{
2806
+ transform: ['3d', 'flat']
2807
+ }],
2808
+ /**
2809
+ * Translate
2810
+ * @see https://tailwindcss.com/docs/translate
2811
+ */
2812
+ translate: [{
2813
+ translate: scaleTranslate()
2814
+ }],
2815
+ /**
2816
+ * Translate X
2817
+ * @see https://tailwindcss.com/docs/translate
2818
+ */
2819
+ 'translate-x': [{
2820
+ 'translate-x': scaleTranslate()
2821
+ }],
2822
+ /**
2823
+ * Translate Y
2824
+ * @see https://tailwindcss.com/docs/translate
2825
+ */
2826
+ 'translate-y': [{
2827
+ 'translate-y': scaleTranslate()
2828
+ }],
2829
+ /**
2830
+ * Translate Z
2831
+ * @see https://tailwindcss.com/docs/translate
2832
+ */
2833
+ 'translate-z': [{
2834
+ 'translate-z': scaleTranslate()
2835
+ }],
2836
+ /**
2837
+ * Translate None
2838
+ * @see https://tailwindcss.com/docs/translate
2839
+ */
2840
+ 'translate-none': ['translate-none'],
2841
+ // ---------------------
2842
+ // --- Interactivity ---
2843
+ // ---------------------
2844
+ /**
2845
+ * Accent Color
2846
+ * @see https://tailwindcss.com/docs/accent-color
2847
+ */
2848
+ accent: [{
2849
+ accent: scaleColor()
2850
+ }],
2851
+ /**
2852
+ * Appearance
2853
+ * @see https://tailwindcss.com/docs/appearance
2854
+ */
2855
+ appearance: [{
2856
+ appearance: ['none', 'auto']
2857
+ }],
2858
+ /**
2859
+ * Caret Color
2860
+ * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities
2861
+ */
2862
+ 'caret-color': [{
2863
+ caret: scaleColor()
2864
+ }],
2865
+ /**
2866
+ * Color Scheme
2867
+ * @see https://tailwindcss.com/docs/color-scheme
2868
+ */
2869
+ 'color-scheme': [{
2870
+ scheme: ['normal', 'dark', 'light', 'light-dark', 'only-dark', 'only-light']
2871
+ }],
2872
+ /**
2873
+ * Cursor
2874
+ * @see https://tailwindcss.com/docs/cursor
2875
+ */
2876
+ cursor: [{
2877
+ cursor: ['auto', 'default', 'pointer', 'wait', 'text', 'move', 'help', 'not-allowed', 'none', 'context-menu', 'progress', 'cell', 'crosshair', 'vertical-text', 'alias', 'copy', 'no-drop', 'grab', 'grabbing', 'all-scroll', 'col-resize', 'row-resize', 'n-resize', 'e-resize', 's-resize', 'w-resize', 'ne-resize', 'nw-resize', 'se-resize', 'sw-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', isArbitraryVariable, isArbitraryValue]
2878
+ }],
2879
+ /**
2880
+ * Field Sizing
2881
+ * @see https://tailwindcss.com/docs/field-sizing
2882
+ */
2883
+ 'field-sizing': [{
2884
+ 'field-sizing': ['fixed', 'content']
2885
+ }],
2886
+ /**
2887
+ * Pointer Events
2888
+ * @see https://tailwindcss.com/docs/pointer-events
2889
+ */
2890
+ 'pointer-events': [{
2891
+ 'pointer-events': ['auto', 'none']
2892
+ }],
2893
+ /**
2894
+ * Resize
2895
+ * @see https://tailwindcss.com/docs/resize
2896
+ */
2897
+ resize: [{
2898
+ resize: ['none', '', 'y', 'x']
2899
+ }],
2900
+ /**
2901
+ * Scroll Behavior
2902
+ * @see https://tailwindcss.com/docs/scroll-behavior
2903
+ */
2904
+ 'scroll-behavior': [{
2905
+ scroll: ['auto', 'smooth']
2906
+ }],
2907
+ /**
2908
+ * Scroll Margin
2909
+ * @see https://tailwindcss.com/docs/scroll-margin
2910
+ */
2911
+ 'scroll-m': [{
2912
+ 'scroll-m': scaleUnambiguousSpacing()
2913
+ }],
2914
+ /**
2915
+ * Scroll Margin X
2916
+ * @see https://tailwindcss.com/docs/scroll-margin
2917
+ */
2918
+ 'scroll-mx': [{
2919
+ 'scroll-mx': scaleUnambiguousSpacing()
2920
+ }],
2921
+ /**
2922
+ * Scroll Margin Y
2923
+ * @see https://tailwindcss.com/docs/scroll-margin
2924
+ */
2925
+ 'scroll-my': [{
2926
+ 'scroll-my': scaleUnambiguousSpacing()
2927
+ }],
2928
+ /**
2929
+ * Scroll Margin Start
2930
+ * @see https://tailwindcss.com/docs/scroll-margin
2931
+ */
2932
+ 'scroll-ms': [{
2933
+ 'scroll-ms': scaleUnambiguousSpacing()
2934
+ }],
2935
+ /**
2936
+ * Scroll Margin End
2937
+ * @see https://tailwindcss.com/docs/scroll-margin
2938
+ */
2939
+ 'scroll-me': [{
2940
+ 'scroll-me': scaleUnambiguousSpacing()
2941
+ }],
2942
+ /**
2943
+ * Scroll Margin Top
2944
+ * @see https://tailwindcss.com/docs/scroll-margin
2945
+ */
2946
+ 'scroll-mt': [{
2947
+ 'scroll-mt': scaleUnambiguousSpacing()
2948
+ }],
2949
+ /**
2950
+ * Scroll Margin Right
2951
+ * @see https://tailwindcss.com/docs/scroll-margin
2952
+ */
2953
+ 'scroll-mr': [{
2954
+ 'scroll-mr': scaleUnambiguousSpacing()
2955
+ }],
2956
+ /**
2957
+ * Scroll Margin Bottom
2958
+ * @see https://tailwindcss.com/docs/scroll-margin
2959
+ */
2960
+ 'scroll-mb': [{
2961
+ 'scroll-mb': scaleUnambiguousSpacing()
2962
+ }],
2963
+ /**
2964
+ * Scroll Margin Left
2965
+ * @see https://tailwindcss.com/docs/scroll-margin
2966
+ */
2967
+ 'scroll-ml': [{
2968
+ 'scroll-ml': scaleUnambiguousSpacing()
2969
+ }],
2970
+ /**
2971
+ * Scroll Padding
2972
+ * @see https://tailwindcss.com/docs/scroll-padding
2973
+ */
2974
+ 'scroll-p': [{
2975
+ 'scroll-p': scaleUnambiguousSpacing()
2976
+ }],
2977
+ /**
2978
+ * Scroll Padding X
2979
+ * @see https://tailwindcss.com/docs/scroll-padding
2980
+ */
2981
+ 'scroll-px': [{
2982
+ 'scroll-px': scaleUnambiguousSpacing()
2983
+ }],
2984
+ /**
2985
+ * Scroll Padding Y
2986
+ * @see https://tailwindcss.com/docs/scroll-padding
2987
+ */
2988
+ 'scroll-py': [{
2989
+ 'scroll-py': scaleUnambiguousSpacing()
2990
+ }],
2991
+ /**
2992
+ * Scroll Padding Start
2993
+ * @see https://tailwindcss.com/docs/scroll-padding
2994
+ */
2995
+ 'scroll-ps': [{
2996
+ 'scroll-ps': scaleUnambiguousSpacing()
2997
+ }],
2998
+ /**
2999
+ * Scroll Padding End
3000
+ * @see https://tailwindcss.com/docs/scroll-padding
3001
+ */
3002
+ 'scroll-pe': [{
3003
+ 'scroll-pe': scaleUnambiguousSpacing()
3004
+ }],
3005
+ /**
3006
+ * Scroll Padding Top
3007
+ * @see https://tailwindcss.com/docs/scroll-padding
3008
+ */
3009
+ 'scroll-pt': [{
3010
+ 'scroll-pt': scaleUnambiguousSpacing()
3011
+ }],
3012
+ /**
3013
+ * Scroll Padding Right
3014
+ * @see https://tailwindcss.com/docs/scroll-padding
3015
+ */
3016
+ 'scroll-pr': [{
3017
+ 'scroll-pr': scaleUnambiguousSpacing()
3018
+ }],
3019
+ /**
3020
+ * Scroll Padding Bottom
3021
+ * @see https://tailwindcss.com/docs/scroll-padding
3022
+ */
3023
+ 'scroll-pb': [{
3024
+ 'scroll-pb': scaleUnambiguousSpacing()
3025
+ }],
3026
+ /**
3027
+ * Scroll Padding Left
3028
+ * @see https://tailwindcss.com/docs/scroll-padding
3029
+ */
3030
+ 'scroll-pl': [{
3031
+ 'scroll-pl': scaleUnambiguousSpacing()
3032
+ }],
3033
+ /**
3034
+ * Scroll Snap Align
3035
+ * @see https://tailwindcss.com/docs/scroll-snap-align
3036
+ */
3037
+ 'snap-align': [{
3038
+ snap: ['start', 'end', 'center', 'align-none']
3039
+ }],
3040
+ /**
3041
+ * Scroll Snap Stop
3042
+ * @see https://tailwindcss.com/docs/scroll-snap-stop
3043
+ */
3044
+ 'snap-stop': [{
3045
+ snap: ['normal', 'always']
3046
+ }],
3047
+ /**
3048
+ * Scroll Snap Type
3049
+ * @see https://tailwindcss.com/docs/scroll-snap-type
3050
+ */
3051
+ 'snap-type': [{
3052
+ snap: ['none', 'x', 'y', 'both']
3053
+ }],
3054
+ /**
3055
+ * Scroll Snap Type Strictness
3056
+ * @see https://tailwindcss.com/docs/scroll-snap-type
3057
+ */
3058
+ 'snap-strictness': [{
3059
+ snap: ['mandatory', 'proximity']
3060
+ }],
3061
+ /**
3062
+ * Touch Action
3063
+ * @see https://tailwindcss.com/docs/touch-action
3064
+ */
3065
+ touch: [{
3066
+ touch: ['auto', 'none', 'manipulation']
3067
+ }],
3068
+ /**
3069
+ * Touch Action X
3070
+ * @see https://tailwindcss.com/docs/touch-action
3071
+ */
3072
+ 'touch-x': [{
3073
+ 'touch-pan': ['x', 'left', 'right']
3074
+ }],
3075
+ /**
3076
+ * Touch Action Y
3077
+ * @see https://tailwindcss.com/docs/touch-action
3078
+ */
3079
+ 'touch-y': [{
3080
+ 'touch-pan': ['y', 'up', 'down']
3081
+ }],
3082
+ /**
3083
+ * Touch Action Pinch Zoom
3084
+ * @see https://tailwindcss.com/docs/touch-action
3085
+ */
3086
+ 'touch-pz': ['touch-pinch-zoom'],
3087
+ /**
3088
+ * User Select
3089
+ * @see https://tailwindcss.com/docs/user-select
3090
+ */
3091
+ select: [{
3092
+ select: ['none', 'text', 'all', 'auto']
3093
+ }],
3094
+ /**
3095
+ * Will Change
3096
+ * @see https://tailwindcss.com/docs/will-change
3097
+ */
3098
+ 'will-change': [{
3099
+ 'will-change': ['auto', 'scroll', 'contents', 'transform', isArbitraryVariable, isArbitraryValue]
3100
+ }],
3101
+ // -----------
3102
+ // --- SVG ---
3103
+ // -----------
3104
+ /**
3105
+ * Fill
3106
+ * @see https://tailwindcss.com/docs/fill
3107
+ */
3108
+ fill: [{
3109
+ fill: ['none', ...scaleColor()]
3110
+ }],
3111
+ /**
3112
+ * Stroke Width
3113
+ * @see https://tailwindcss.com/docs/stroke-width
3114
+ */
3115
+ 'stroke-w': [{
3116
+ stroke: [isNumber, isArbitraryVariableLength, isArbitraryLength, isArbitraryNumber]
3117
+ }],
3118
+ /**
3119
+ * Stroke
3120
+ * @see https://tailwindcss.com/docs/stroke
3121
+ */
3122
+ stroke: [{
3123
+ stroke: ['none', ...scaleColor()]
3124
+ }],
3125
+ // ---------------------
3126
+ // --- Accessibility ---
3127
+ // ---------------------
3128
+ /**
3129
+ * Forced Color Adjust
3130
+ * @see https://tailwindcss.com/docs/forced-color-adjust
3131
+ */
3132
+ 'forced-color-adjust': [{
3133
+ 'forced-color-adjust': ['auto', 'none']
3134
+ }]
3135
+ },
3136
+ conflictingClassGroups: {
3137
+ overflow: ['overflow-x', 'overflow-y'],
3138
+ overscroll: ['overscroll-x', 'overscroll-y'],
3139
+ inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],
3140
+ 'inset-x': ['right', 'left'],
3141
+ 'inset-y': ['top', 'bottom'],
3142
+ flex: ['basis', 'grow', 'shrink'],
3143
+ gap: ['gap-x', 'gap-y'],
3144
+ p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],
3145
+ px: ['pr', 'pl'],
3146
+ py: ['pt', 'pb'],
3147
+ m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],
3148
+ mx: ['mr', 'ml'],
3149
+ my: ['mt', 'mb'],
3150
+ size: ['w', 'h'],
3151
+ 'font-size': ['leading'],
3152
+ 'fvn-normal': ['fvn-ordinal', 'fvn-slashed-zero', 'fvn-figure', 'fvn-spacing', 'fvn-fraction'],
3153
+ 'fvn-ordinal': ['fvn-normal'],
3154
+ 'fvn-slashed-zero': ['fvn-normal'],
3155
+ 'fvn-figure': ['fvn-normal'],
3156
+ 'fvn-spacing': ['fvn-normal'],
3157
+ 'fvn-fraction': ['fvn-normal'],
3158
+ 'line-clamp': ['display', 'overflow'],
3159
+ rounded: ['rounded-s', 'rounded-e', 'rounded-t', 'rounded-r', 'rounded-b', 'rounded-l', 'rounded-ss', 'rounded-se', 'rounded-ee', 'rounded-es', 'rounded-tl', 'rounded-tr', 'rounded-br', 'rounded-bl'],
3160
+ 'rounded-s': ['rounded-ss', 'rounded-es'],
3161
+ 'rounded-e': ['rounded-se', 'rounded-ee'],
3162
+ 'rounded-t': ['rounded-tl', 'rounded-tr'],
3163
+ 'rounded-r': ['rounded-tr', 'rounded-br'],
3164
+ 'rounded-b': ['rounded-br', 'rounded-bl'],
3165
+ 'rounded-l': ['rounded-tl', 'rounded-bl'],
3166
+ 'border-spacing': ['border-spacing-x', 'border-spacing-y'],
3167
+ 'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
3168
+ 'border-w-x': ['border-w-r', 'border-w-l'],
3169
+ 'border-w-y': ['border-w-t', 'border-w-b'],
3170
+ 'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
3171
+ 'border-color-x': ['border-color-r', 'border-color-l'],
3172
+ 'border-color-y': ['border-color-t', 'border-color-b'],
3173
+ translate: ['translate-x', 'translate-y', 'translate-none'],
3174
+ 'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
3175
+ 'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
3176
+ 'scroll-mx': ['scroll-mr', 'scroll-ml'],
3177
+ 'scroll-my': ['scroll-mt', 'scroll-mb'],
3178
+ 'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
3179
+ 'scroll-px': ['scroll-pr', 'scroll-pl'],
3180
+ 'scroll-py': ['scroll-pt', 'scroll-pb'],
3181
+ touch: ['touch-x', 'touch-y', 'touch-pz'],
3182
+ 'touch-x': ['touch'],
3183
+ 'touch-y': ['touch'],
3184
+ 'touch-pz': ['touch']
3185
+ },
3186
+ conflictingClassGroupModifiers: {
3187
+ 'font-size': ['leading']
3188
+ },
3189
+ orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
3190
+ };
3191
+ };
3192
+ const twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);
3193
+
3194
+ const mergeStyles = (...inputs) => twMerge(clsx(inputs));
3195
+
3196
+ const withDragDefaults = (handler) => {
3197
+ return (e) => {
3198
+ e.preventDefault();
3199
+ e.stopPropagation();
3200
+ handler(e);
3201
+ };
3202
+ };
3203
+
3204
+ if (typeof window !== "undefined") {
3205
+ import('./shared/components/FileSelector/tailwind.css');
3206
+ }
3207
+ const defaultAcceptTypes = ".png, .jpg, .jpeg, .pdf, .svg, image/svg+xml, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document";
3208
+ const defaultInputClassName = "hiddenInput";
3209
+ const defaultClickableAreaClassName = "dropzone border-dashed border-2 border-gray-500 p-4 rounded-md text-center cursor-pointer bg-inherit hover:border-gray-400 text-inherit font-bold py-2 px-4";
3210
+ const defaultDropZoneWrapperClassName = "flex flex-col min-h-[120px] border border-gray-300 rounded-md shadow-md";
3211
+ const defaultMessageParagraphClassName = "text-center text-gray-600";
3212
+ const defaultMessageParagraph = "Drag 'n' drop some files here, or click to select files";
3213
+ const defaultAriaLabel = "File upload drop zone";
3214
+ const defaultAriaDescribedBy = undefined;
3215
+ const defaultAriaLabelButton = "Choose files to upload";
3216
+ const FileSelectorComponent = ({ inputId, acceptTypes = defaultAcceptTypes, messageParagraph = defaultMessageParagraph, inputClassName, clickableAreaClassName, dropZoneWrapperClassName, messageParagraphClassName, ariaLabel = defaultAriaLabel, ariaDescribedBy = defaultAriaDescribedBy, ariaLabelButton = defaultAriaLabelButton, ariaLabelledBy, // New prop for button
3217
+ onChange, onDragOver, onDrop, onDragEnter, onDragLeave, }) => {
3218
+ const fileInputRef = useRef(null);
3219
+ const messageId = useId();
3220
+ //Note, eslint doesn't like that I'm wrapping the anonymous function in withDragDefaults. Ignore for now
3221
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3222
+ const internalOnClick = useCallback(withDragDefaults(() => {
3223
+ fileInputRef.current?.click();
3224
+ }), []);
3225
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3226
+ const internalOnDrop = useCallback(withDragDefaults((e) => {
3227
+ onDrop(e);
3228
+ }), [onDrop]);
3229
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3230
+ const internalOnDragOver = useCallback(withDragDefaults((e) => {
3231
+ onDragOver(e);
3232
+ }), [onDragOver]);
3233
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3234
+ const internalOnDragEnter = useCallback(withDragDefaults((e) => {
3235
+ onDragEnter(e);
3236
+ }), [onDragEnter]);
3237
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3238
+ const internalOnDragLeave = useCallback(withDragDefaults((e) => {
3239
+ onDragLeave(e);
3240
+ }), [onDragLeave]);
3241
+ const inputClasses = mergeStyles(defaultInputClassName, inputClassName);
3242
+ const resolvedClickableAreaClassName = mergeStyles(clickableAreaClassName ?? defaultClickableAreaClassName, "w-full h-full flex-1 min-h-0");
3243
+ const resolvedDropZoneWrapperClassName = mergeStyles(dropZoneWrapperClassName ?? defaultDropZoneWrapperClassName);
3244
+ const resolvedMessageParagraphClassName = mergeStyles(messageParagraphClassName ?? defaultMessageParagraphClassName);
3245
+ const resolvedInputId = inputId ?? messageId;
3246
+ return (jsxs("div", { role: "group", "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, className: resolvedDropZoneWrapperClassName, draggable: false, children: [jsx("button", { type: "button", className: resolvedClickableAreaClassName, onClick: internalOnClick, onDragOver: internalOnDragOver, onDrop: internalOnDrop, onDragEnter: internalOnDragEnter, onDragLeave: internalOnDragLeave, draggable: false, "aria-label": ariaLabelButton, "aria-labelledby": ariaLabelledBy ?? messageId, "aria-controls": resolvedInputId, "aria-haspopup": "dialog", children: jsx("p", { id: messageId, className: resolvedMessageParagraphClassName, children: messageParagraph }) }), jsx("input", { ref: fileInputRef, id: resolvedInputId, type: "file", className: inputClasses, onChange: onChange, accept: acceptTypes, multiple: true, "aria-hidden": "true", tabIndex: -1 })] }));
3247
+ };
3248
+ const FileSelector = memo(FileSelectorComponent);
3249
+ FileSelector.displayName = "FileSelector";
3250
+
3251
+ const useFileSelector = ({ maximumUploadCount: maximumUploadCount$1 = maximumUploadCount, maximumFileSize: maximumFileSize$1 = maximumFileSize, acceptedTypes = defaultTypeExtensions, } = {}) => {
3252
+ //State
3253
+ //Trigger a re-render
3254
+ const [, setUpdateTrigger] = useState(0);
3255
+ const [validFiles, SetValidFiles] = useState([]);
3256
+ const [invalidFiles, SetInvalidFiles] = useState([]);
3257
+ //Refs
3258
+ const maxUploadErrorRef = useRef({
3259
+ status: false,
3260
+ message: "",
3261
+ });
3262
+ const maxFileSizeErrorRef = useRef({
3263
+ status: false,
3264
+ message: "",
3265
+ });
3266
+ const setMaximumUploadsExceeded = useCallback((status = false, fileCount, maximumUploads) => {
3267
+ maxUploadErrorRef.current.status = status;
3268
+ maxUploadErrorRef.current.message = status
3269
+ ? `You have attempted to upload ${fileCount} files. The maximum allowable uploads for this feature is ${maximumUploads}`
3270
+ : "";
3271
+ setUpdateTrigger((state) => (state += 1));
3272
+ }, []);
3273
+ const setMaximumFileSizeExceeded = useCallback((status = false) => {
3274
+ maxFileSizeErrorRef.current.status = status;
3275
+ maxFileSizeErrorRef.current.message = status
3276
+ ? `You have attempted upload a file(s) that exceeds the maximum size of ${printableMaximumFileSize}`
3277
+ : "";
3278
+ setUpdateTrigger((state) => (state += 1));
3279
+ }, []);
3280
+ const clearBlobs = useCustomCallback(() => {
3281
+ //Remove any blobs created in memory
3282
+ let i = 0;
3283
+ while (i < validFiles.length) {
3284
+ const file = validFiles[i].file;
3285
+ if (file instanceof File) {
3286
+ clearBlobFromMemory(file);
3287
+ }
3288
+ i++;
3289
+ }
3290
+ }, [validFiles]);
3291
+ const clearCache = useCustomCallback(() => {
3292
+ //Clear any blobs held in memory
3293
+ clearBlobs();
3294
+ SetInvalidFiles([]);
3295
+ SetValidFiles([]);
3296
+ }, [clearBlobs]);
3297
+ const onCancel = useCustomCallback(() => {
3298
+ clearCache();
3299
+ }, [clearCache]);
3300
+ const getValidFileStreams = useCallback(() => (validFiles.length ? validFiles.map(({ file }) => file) : []), [validFiles]);
3301
+ //Main Engine to deal with files
3302
+ const processFiles = useCustomCallback((files) => {
3303
+ const maxFileSizeCheck = checkFilesMaximumSize(files, maximumFileSize$1) && !maxFileSizeErrorRef.current.status;
3304
+ const maxUploadCountCheck = typeof maximumUploadCount$1 !== "undefined"
3305
+ ? !maxUploadErrorRef.current.status && files.length > maximumUploadCount$1
3306
+ : false;
3307
+ if (maxFileSizeCheck || maxUploadCountCheck) {
3308
+ if (maxFileSizeCheck)
3309
+ setMaximumFileSizeExceeded(true);
3310
+ if (maxUploadCountCheck)
3311
+ setMaximumUploadsExceeded(true, files.length, maximumUploadCount$1);
3312
+ onCancel();
3313
+ }
3314
+ else {
3315
+ const valid = [];
3316
+ const invalid = [];
3317
+ let i = 0;
3318
+ while (i < files.length) {
3319
+ const file = files[i];
3320
+ if (isValidFileType(file, acceptedTypes)) {
3321
+ valid.push(SvgXmlnsAttributeCheck(file, acceptedTypes));
3322
+ }
3323
+ else {
3324
+ invalid.push(file);
3325
+ }
3326
+ i++;
3327
+ }
3328
+ if (valid.length > 0) {
3329
+ Promise.all(valid)
3330
+ .then((results) => {
3331
+ const filteredResults = [];
3332
+ let j = 0;
3333
+ while (j < results.length) {
3334
+ const result = results[j];
3335
+ if (result !== null) {
3336
+ filteredResults.push(result);
3337
+ }
3338
+ j++;
3339
+ }
3340
+ SetValidFiles(filteredResults);
3341
+ })
3342
+ .catch((error) => {
3343
+ console.error("File processing error:", error);
3344
+ // Optionally expose error state to engineers
3345
+ SetInvalidFiles(invalid.concat(files)); // Treat all as invalid on error
3346
+ });
3347
+ }
3348
+ if (invalid.length > 0) {
3349
+ SetInvalidFiles(invalid);
3350
+ }
3351
+ }
3352
+ }, [
3353
+ acceptedTypes,
3354
+ maximumFileSize$1,
3355
+ maximumUploadCount$1,
3356
+ setMaximumFileSizeExceeded,
3357
+ setMaximumUploadsExceeded,
3358
+ onCancel,
3359
+ ]);
3360
+ const onRemoveFile = useCustomCallback((index) => {
3361
+ const updatedValidFiles = [];
3362
+ let i = 0;
3363
+ while (i < validFiles.length) {
3364
+ if (i === index) {
3365
+ const file = validFiles[i].file;
3366
+ if (file instanceof File) {
3367
+ clearBlobFromMemory(file);
3368
+ }
3369
+ }
3370
+ else {
3371
+ updatedValidFiles.push(validFiles[i]);
3372
+ }
3373
+ i++;
3374
+ }
3375
+ SetValidFiles(updatedValidFiles);
3376
+ }, [validFiles]);
3377
+ const onIdChange = useCallback((index, id, files) => {
3378
+ const updatedValidFiles = files.map((fileData, i) => {
3379
+ if (i === index) {
3380
+ const renamedFile = checkFile(id, fileData.file);
3381
+ return { ...fileData, file: renamedFile, id };
3382
+ }
3383
+ return fileData;
3384
+ });
3385
+ SetValidFiles(updatedValidFiles);
3386
+ }, []);
3387
+ const onInputChange = useCustomCallback((event) => {
3388
+ const files = Array.from(event.target.files || []);
3389
+ processFiles(files);
3390
+ }, [processFiles]);
3391
+ //Drag and Drop
3392
+ const onDrop = useCustomCallback((e) => {
3393
+ e.preventDefault();
3394
+ processFiles(Array.from(e.dataTransfer.files));
3395
+ }, [processFiles]);
3396
+ const onDragOver = useCallback((e) => {
3397
+ e.preventDefault();
3398
+ e.dataTransfer.dropEffect = "copy";
3399
+ }, []);
3400
+ const onDragEnter = useCallback((e) => {
3401
+ e.preventDefault();
3402
+ const { classList } = e.currentTarget;
3403
+ classList.add("border-yellow-400");
3404
+ classList.remove("border-silver-600");
3405
+ }, []);
3406
+ const onDragLeave = useCallback((e) => {
3407
+ e.preventDefault();
3408
+ const currentTarget = e.currentTarget;
3409
+ const timeoutId = setTimeout(() => {
3410
+ if (currentTarget && !currentTarget.contains(e.relatedTarget)) {
3411
+ const { classList } = currentTarget;
3412
+ classList.remove("border-yellow-400");
3413
+ classList.add("border-silver-600");
3414
+ }
3415
+ clearTimeout(timeoutId);
3416
+ }, 200);
3417
+ }, []);
3418
+ // const FileSelectorRef = useRef(() => (
3419
+ // <FileSelector
3420
+ // acceptTypes={acceptTypes}
3421
+ // onChange={onInputChange}
3422
+ // onDragOver={onDragOver}
3423
+ // onDrop={onDrop}
3424
+ // onDragEnter={onDragEnter}
3425
+ // onDragLeave={onDragLeave}
3426
+ // />
3427
+ // ));
3428
+ // In useFileSelector.ts, create a wrapper component
3429
+ const createFileSelectorComponent = (handlers) => {
3430
+ // Return a component that accepts only the visual/accessibility props
3431
+ const Component = (props) => (jsx(FileSelector, { ...props, onChange: handlers.onInputChange, onDragOver: handlers.onDragOver, onDrop: handlers.onDrop, onDragEnter: handlers.onDragEnter, onDragLeave: handlers.onDragLeave }));
3432
+ Component.displayName = "FileSelectorWrapper"; // <-- fix the ESLint warning
3433
+ return Component;
3434
+ };
3435
+ // Then in the hook's return:
3436
+ const BoundFileSelector = useMemo(() => createFileSelectorComponent({
3437
+ onInputChange,
3438
+ onDragOver,
3439
+ onDrop,
3440
+ onDragEnter,
3441
+ onDragLeave,
3442
+ }), [onInputChange, onDragOver, onDrop, onDragEnter, onDragLeave]);
3443
+ return {
3444
+ //Properties
3445
+ validFiles,
3446
+ invalidFiles,
3447
+ //Methods
3448
+ clearCache,
3449
+ getValidFileStreams,
3450
+ onCancel,
3451
+ onIdChange,
3452
+ onRemoveFile,
3453
+ clearBlobs,
3454
+ clearBlob: clearBlobFromMemory,
3455
+ //Errors
3456
+ maxUploadError: maxUploadErrorRef.current,
3457
+ maxFileSizeError: maxFileSizeErrorRef.current,
3458
+ setMaximumFileSizeExceeded,
3459
+ setMaximumUploadsExceeded,
3460
+ //Component - Export the FileSelector
3461
+ FileSelector: BoundFileSelector,
3462
+ };
3463
+ };
3464
+
3465
+ export { useFileSelector };
3466
+ //# sourceMappingURL=index.js.map