@vritti/quantum-ui 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Button2.js +2 -1
- package/dist/Button2.js.map +1 -1
- package/dist/Checkbox.js +3 -5
- package/dist/Checkbox.js.map +1 -1
- package/dist/DatePicker.js +416 -139
- package/dist/DatePicker.js.map +1 -1
- package/dist/Form.js.map +1 -1
- package/dist/Label.js +1 -1
- package/dist/Label.js.map +1 -1
- package/dist/OTPField.js +1 -1
- package/dist/OTPField.js.map +1 -1
- package/dist/PasswordField.js +3 -16
- package/dist/PasswordField.js.map +1 -1
- package/dist/PhoneField.js +23 -7
- package/dist/PhoneField.js.map +1 -1
- package/dist/Sonner.js +1249 -0
- package/dist/Sonner.js.map +1 -0
- package/dist/Spinner.js +1 -12
- package/dist/Spinner.js.map +1 -1
- package/dist/ThemeToggle.js +2 -2
- package/dist/ThemeToggle.js.map +1 -1
- package/dist/assets/quantum-ui.css +41 -10
- package/dist/axios.js +186 -59
- package/dist/axios.js.map +1 -1
- package/dist/circle-check-big.js +18 -0
- package/dist/circle-check-big.js.map +1 -0
- package/dist/components/Progress.js +61 -2
- package/dist/components/Progress.js.map +1 -1
- package/dist/components/Sonner.js +3 -0
- package/dist/components/Sonner.js.map +1 -0
- package/dist/createLucideIcon.js +4 -4
- package/dist/createLucideIcon.js.map +1 -1
- package/dist/field.js +2 -36
- package/dist/field.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/index2.js +130 -54
- package/dist/index2.js.map +1 -1
- package/dist/index3.js +1 -103
- package/dist/index3.js.map +1 -1
- package/dist/index4.js +36 -35
- package/dist/index4.js.map +1 -1
- package/dist/index5.js +303 -3
- package/dist/index5.js.map +1 -1
- package/dist/lib/components/Sonner/Sonner.d.ts +5 -0
- package/dist/lib/components/Sonner/Sonner.d.ts.map +1 -0
- package/dist/lib/components/Sonner/index.d.ts +4 -0
- package/dist/lib/components/Sonner/index.d.ts.map +1 -0
- package/dist/lib/components/Sonner/toast.d.ts +29 -0
- package/dist/lib/components/Sonner/toast.d.ts.map +1 -0
- package/dist/lib/components/index.d.ts +1 -0
- package/dist/lib/components/index.d.ts.map +1 -1
- package/dist/lib/utils/axios.d.ts +5 -0
- package/dist/lib/utils/axios.d.ts.map +1 -1
- package/dist/loader-circle.js +15 -0
- package/dist/loader-circle.js.map +1 -0
- package/dist/shadcn/index.d.ts +1 -0
- package/dist/shadcn/index.d.ts.map +1 -1
- package/dist/shadcn/shadcnSonner/index.d.ts +2 -0
- package/dist/shadcn/shadcnSonner/index.d.ts.map +1 -0
- package/dist/shadcn/shadcnSonner/sonner.d.ts +4 -0
- package/dist/shadcn/shadcnSonner/sonner.d.ts.map +1 -0
- package/dist/toast.js +72 -0
- package/dist/toast.js.map +1 -0
- package/dist/utils/axios.js +1 -0
- package/dist/utils/axios.js.map +1 -1
- package/dist/utils.js +229 -150
- package/dist/utils.js.map +1 -1
- package/package.json +38 -32
- package/dist/index6.js +0 -246
- package/dist/index6.js.map +0 -1
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
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}
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Concatenates two arrays faster than the array spread operator.
|
|
5
|
+
*/
|
|
6
|
+
const concatArrays = (array1, array2) => {
|
|
7
|
+
// Pre-allocate for better V8 optimization
|
|
8
|
+
const combinedArray = new Array(array1.length + array2.length);
|
|
9
|
+
for (let i = 0; i < array1.length; i++) {
|
|
10
|
+
combinedArray[i] = array1[i];
|
|
11
|
+
}
|
|
12
|
+
for (let i = 0; i < array2.length; i++) {
|
|
13
|
+
combinedArray[array1.length + i] = array2[i];
|
|
14
|
+
}
|
|
15
|
+
return combinedArray;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Factory function ensures consistent object shapes
|
|
19
|
+
const createClassValidatorObject = (classGroupId, validator) => ({
|
|
20
|
+
classGroupId,
|
|
21
|
+
validator
|
|
22
|
+
});
|
|
23
|
+
// Factory ensures consistent ClassPartObject shape
|
|
24
|
+
const createClassPartObject = (nextPart = new Map(), validators = null, classGroupId) => ({
|
|
25
|
+
nextPart,
|
|
26
|
+
validators,
|
|
27
|
+
classGroupId
|
|
28
|
+
});
|
|
3
29
|
const CLASS_PART_SEPARATOR = '-';
|
|
30
|
+
const EMPTY_CONFLICTS = [];
|
|
31
|
+
// I use two dots here because one dot is used as prefix for class groups in plugins
|
|
32
|
+
const ARBITRARY_PROPERTY_PREFIX = 'arbitrary..';
|
|
4
33
|
const createClassGroupUtils = config => {
|
|
5
34
|
const classMap = createClassMap(config);
|
|
6
35
|
const {
|
|
@@ -8,54 +37,73 @@ const createClassGroupUtils = config => {
|
|
|
8
37
|
conflictingClassGroupModifiers
|
|
9
38
|
} = config;
|
|
10
39
|
const getClassGroupId = className => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (classParts[0] === '' && classParts.length !== 1) {
|
|
14
|
-
classParts.shift();
|
|
40
|
+
if (className.startsWith('[') && className.endsWith(']')) {
|
|
41
|
+
return getGroupIdForArbitraryProperty(className);
|
|
15
42
|
}
|
|
16
|
-
|
|
43
|
+
const classParts = className.split(CLASS_PART_SEPARATOR);
|
|
44
|
+
// Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and skip it.
|
|
45
|
+
const startIndex = classParts[0] === '' && classParts.length > 1 ? 1 : 0;
|
|
46
|
+
return getGroupRecursive(classParts, startIndex, classMap);
|
|
17
47
|
};
|
|
18
48
|
const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
49
|
+
if (hasPostfixModifier) {
|
|
50
|
+
const modifierConflicts = conflictingClassGroupModifiers[classGroupId];
|
|
51
|
+
const baseConflicts = conflictingClassGroups[classGroupId];
|
|
52
|
+
if (modifierConflicts) {
|
|
53
|
+
if (baseConflicts) {
|
|
54
|
+
// Merge base conflicts with modifier conflicts
|
|
55
|
+
return concatArrays(baseConflicts, modifierConflicts);
|
|
56
|
+
}
|
|
57
|
+
// Only modifier conflicts
|
|
58
|
+
return modifierConflicts;
|
|
59
|
+
}
|
|
60
|
+
// Fall back to without postfix if no modifier conflicts
|
|
61
|
+
return baseConflicts || EMPTY_CONFLICTS;
|
|
22
62
|
}
|
|
23
|
-
return
|
|
63
|
+
return conflictingClassGroups[classGroupId] || EMPTY_CONFLICTS;
|
|
24
64
|
};
|
|
25
65
|
return {
|
|
26
66
|
getClassGroupId,
|
|
27
67
|
getConflictingClassGroupIds
|
|
28
68
|
};
|
|
29
69
|
};
|
|
30
|
-
const getGroupRecursive = (classParts, classPartObject) => {
|
|
31
|
-
|
|
70
|
+
const getGroupRecursive = (classParts, startIndex, classPartObject) => {
|
|
71
|
+
const classPathsLength = classParts.length - startIndex;
|
|
72
|
+
if (classPathsLength === 0) {
|
|
32
73
|
return classPartObject.classGroupId;
|
|
33
74
|
}
|
|
34
|
-
const currentClassPart = classParts[
|
|
75
|
+
const currentClassPart = classParts[startIndex];
|
|
35
76
|
const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return
|
|
77
|
+
if (nextClassPartObject) {
|
|
78
|
+
const result = getGroupRecursive(classParts, startIndex + 1, nextClassPartObject);
|
|
79
|
+
if (result) return result;
|
|
39
80
|
}
|
|
40
|
-
|
|
81
|
+
const validators = classPartObject.validators;
|
|
82
|
+
if (validators === null) {
|
|
41
83
|
return undefined;
|
|
42
84
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (arbitraryPropertyRegex.test(className)) {
|
|
51
|
-
const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1];
|
|
52
|
-
const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(':'));
|
|
53
|
-
if (property) {
|
|
54
|
-
// I use two dots here because one dot is used as prefix for class groups in plugins
|
|
55
|
-
return 'arbitrary..' + property;
|
|
85
|
+
// Build classRest string efficiently by joining from startIndex onwards
|
|
86
|
+
const classRest = startIndex === 0 ? classParts.join(CLASS_PART_SEPARATOR) : classParts.slice(startIndex).join(CLASS_PART_SEPARATOR);
|
|
87
|
+
const validatorsLength = validators.length;
|
|
88
|
+
for (let i = 0; i < validatorsLength; i++) {
|
|
89
|
+
const validatorObj = validators[i];
|
|
90
|
+
if (validatorObj.validator(classRest)) {
|
|
91
|
+
return validatorObj.classGroupId;
|
|
56
92
|
}
|
|
57
93
|
}
|
|
94
|
+
return undefined;
|
|
58
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* Get the class group ID for an arbitrary property.
|
|
98
|
+
*
|
|
99
|
+
* @param className - The class name to get the group ID for. Is expected to be string starting with `[` and ending with `]`.
|
|
100
|
+
*/
|
|
101
|
+
const getGroupIdForArbitraryProperty = className => className.slice(1, -1).indexOf(':') === -1 ? undefined : (() => {
|
|
102
|
+
const content = className.slice(1, -1);
|
|
103
|
+
const colonIndex = content.indexOf(':');
|
|
104
|
+
const property = content.slice(0, colonIndex);
|
|
105
|
+
return property ? ARBITRARY_PROPERTY_PREFIX + property : undefined;
|
|
106
|
+
})();
|
|
59
107
|
/**
|
|
60
108
|
* Exported for testing only
|
|
61
109
|
*/
|
|
@@ -64,54 +112,77 @@ const createClassMap = config => {
|
|
|
64
112
|
theme,
|
|
65
113
|
classGroups
|
|
66
114
|
} = config;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
115
|
+
return processClassGroups(classGroups, theme);
|
|
116
|
+
};
|
|
117
|
+
// Split into separate functions to maintain monomorphic call sites
|
|
118
|
+
const processClassGroups = (classGroups, theme) => {
|
|
119
|
+
const classMap = createClassPartObject();
|
|
71
120
|
for (const classGroupId in classGroups) {
|
|
72
|
-
|
|
121
|
+
const group = classGroups[classGroupId];
|
|
122
|
+
processClassesRecursively(group, classMap, classGroupId, theme);
|
|
73
123
|
}
|
|
74
124
|
return classMap;
|
|
75
125
|
};
|
|
76
126
|
const processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
|
|
77
|
-
classGroup.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
127
|
+
const len = classGroup.length;
|
|
128
|
+
for (let i = 0; i < len; i++) {
|
|
129
|
+
const classDefinition = classGroup[i];
|
|
130
|
+
processClassDefinition(classDefinition, classPartObject, classGroupId, theme);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
// Split into separate functions for each type to maintain monomorphic call sites
|
|
134
|
+
const processClassDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
|
|
135
|
+
if (typeof classDefinition === 'string') {
|
|
136
|
+
processStringDefinition(classDefinition, classPartObject, classGroupId);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (typeof classDefinition === 'function') {
|
|
140
|
+
processFunctionDefinition(classDefinition, classPartObject, classGroupId, theme);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
processObjectDefinition(classDefinition, classPartObject, classGroupId, theme);
|
|
144
|
+
};
|
|
145
|
+
const processStringDefinition = (classDefinition, classPartObject, classGroupId) => {
|
|
146
|
+
const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);
|
|
147
|
+
classPartObjectToEdit.classGroupId = classGroupId;
|
|
148
|
+
};
|
|
149
|
+
const processFunctionDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
|
|
150
|
+
if (isThemeGetter(classDefinition)) {
|
|
151
|
+
processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (classPartObject.validators === null) {
|
|
155
|
+
classPartObject.validators = [];
|
|
156
|
+
}
|
|
157
|
+
classPartObject.validators.push(createClassValidatorObject(classGroupId, classDefinition));
|
|
158
|
+
};
|
|
159
|
+
const processObjectDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
|
|
160
|
+
const entries = Object.entries(classDefinition);
|
|
161
|
+
const len = entries.length;
|
|
162
|
+
for (let i = 0; i < len; i++) {
|
|
163
|
+
const [key, value] = entries[i];
|
|
164
|
+
processClassesRecursively(value, getPart(classPartObject, key), classGroupId, theme);
|
|
165
|
+
}
|
|
98
166
|
};
|
|
99
167
|
const getPart = (classPartObject, path) => {
|
|
100
|
-
let
|
|
101
|
-
path.split(CLASS_PART_SEPARATOR)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
168
|
+
let current = classPartObject;
|
|
169
|
+
const parts = path.split(CLASS_PART_SEPARATOR);
|
|
170
|
+
const len = parts.length;
|
|
171
|
+
for (let i = 0; i < len; i++) {
|
|
172
|
+
const part = parts[i];
|
|
173
|
+
let next = current.nextPart.get(part);
|
|
174
|
+
if (!next) {
|
|
175
|
+
next = createClassPartObject();
|
|
176
|
+
current.nextPart.set(part, next);
|
|
107
177
|
}
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
return
|
|
178
|
+
current = next;
|
|
179
|
+
}
|
|
180
|
+
return current;
|
|
111
181
|
};
|
|
112
|
-
|
|
182
|
+
// Type guard maintains monomorphic check
|
|
183
|
+
const isThemeGetter = func => 'isThemeGetter' in func && func.isThemeGetter === true;
|
|
113
184
|
|
|
114
|
-
// LRU cache
|
|
185
|
+
// LRU cache implementation using plain objects for simplicity
|
|
115
186
|
const createLruCache = maxCacheSize => {
|
|
116
187
|
if (maxCacheSize < 1) {
|
|
117
188
|
return {
|
|
@@ -120,31 +191,31 @@ const createLruCache = maxCacheSize => {
|
|
|
120
191
|
};
|
|
121
192
|
}
|
|
122
193
|
let cacheSize = 0;
|
|
123
|
-
let cache =
|
|
124
|
-
let previousCache =
|
|
194
|
+
let cache = Object.create(null);
|
|
195
|
+
let previousCache = Object.create(null);
|
|
125
196
|
const update = (key, value) => {
|
|
126
|
-
cache
|
|
197
|
+
cache[key] = value;
|
|
127
198
|
cacheSize++;
|
|
128
199
|
if (cacheSize > maxCacheSize) {
|
|
129
200
|
cacheSize = 0;
|
|
130
201
|
previousCache = cache;
|
|
131
|
-
cache =
|
|
202
|
+
cache = Object.create(null);
|
|
132
203
|
}
|
|
133
204
|
};
|
|
134
205
|
return {
|
|
135
206
|
get(key) {
|
|
136
|
-
let value = cache
|
|
207
|
+
let value = cache[key];
|
|
137
208
|
if (value !== undefined) {
|
|
138
209
|
return value;
|
|
139
210
|
}
|
|
140
|
-
if ((value = previousCache
|
|
211
|
+
if ((value = previousCache[key]) !== undefined) {
|
|
141
212
|
update(key, value);
|
|
142
213
|
return value;
|
|
143
214
|
}
|
|
144
215
|
},
|
|
145
216
|
set(key, value) {
|
|
146
|
-
if (cache
|
|
147
|
-
cache
|
|
217
|
+
if (key in cache) {
|
|
218
|
+
cache[key] = value;
|
|
148
219
|
} else {
|
|
149
220
|
update(key, value);
|
|
150
221
|
}
|
|
@@ -153,7 +224,15 @@ const createLruCache = maxCacheSize => {
|
|
|
153
224
|
};
|
|
154
225
|
const IMPORTANT_MODIFIER = '!';
|
|
155
226
|
const MODIFIER_SEPARATOR = ':';
|
|
156
|
-
const
|
|
227
|
+
const EMPTY_MODIFIERS = [];
|
|
228
|
+
// Pre-allocated result object shape for consistency
|
|
229
|
+
const createResultObject = (modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition, isExternal) => ({
|
|
230
|
+
modifiers,
|
|
231
|
+
hasImportantModifier,
|
|
232
|
+
baseClassName,
|
|
233
|
+
maybePostfixModifierPosition,
|
|
234
|
+
isExternal
|
|
235
|
+
});
|
|
157
236
|
const createParseClassName = config => {
|
|
158
237
|
const {
|
|
159
238
|
prefix,
|
|
@@ -166,17 +245,19 @@ const createParseClassName = config => {
|
|
|
166
245
|
* @see https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js
|
|
167
246
|
*/
|
|
168
247
|
let parseClassName = className => {
|
|
248
|
+
// Use simple array with push for better performance
|
|
169
249
|
const modifiers = [];
|
|
170
250
|
let bracketDepth = 0;
|
|
171
251
|
let parenDepth = 0;
|
|
172
252
|
let modifierStart = 0;
|
|
173
253
|
let postfixModifierPosition;
|
|
174
|
-
|
|
175
|
-
|
|
254
|
+
const len = className.length;
|
|
255
|
+
for (let index = 0; index < len; index++) {
|
|
256
|
+
const currentCharacter = className[index];
|
|
176
257
|
if (bracketDepth === 0 && parenDepth === 0) {
|
|
177
258
|
if (currentCharacter === MODIFIER_SEPARATOR) {
|
|
178
259
|
modifiers.push(className.slice(modifierStart, index));
|
|
179
|
-
modifierStart = index +
|
|
260
|
+
modifierStart = index + 1;
|
|
180
261
|
continue;
|
|
181
262
|
}
|
|
182
263
|
if (currentCharacter === '/') {
|
|
@@ -184,37 +265,31 @@ const createParseClassName = config => {
|
|
|
184
265
|
continue;
|
|
185
266
|
}
|
|
186
267
|
}
|
|
187
|
-
if (currentCharacter === '[')
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
268
|
+
if (currentCharacter === '[') bracketDepth++;else if (currentCharacter === ']') bracketDepth--;else if (currentCharacter === '(') parenDepth++;else if (currentCharacter === ')') parenDepth--;
|
|
269
|
+
}
|
|
270
|
+
const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.slice(modifierStart);
|
|
271
|
+
// Inline important modifier check
|
|
272
|
+
let baseClassName = baseClassNameWithImportantModifier;
|
|
273
|
+
let hasImportantModifier = false;
|
|
274
|
+
if (baseClassNameWithImportantModifier.endsWith(IMPORTANT_MODIFIER)) {
|
|
275
|
+
baseClassName = baseClassNameWithImportantModifier.slice(0, -1);
|
|
276
|
+
hasImportantModifier = true;
|
|
277
|
+
} else if (
|
|
278
|
+
/**
|
|
279
|
+
* In Tailwind CSS v3 the important modifier was at the start of the base class name. This is still supported for legacy reasons.
|
|
280
|
+
* @see https://github.com/dcastil/tailwind-merge/issues/513#issuecomment-2614029864
|
|
281
|
+
*/
|
|
282
|
+
baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER)) {
|
|
283
|
+
baseClassName = baseClassNameWithImportantModifier.slice(1);
|
|
284
|
+
hasImportantModifier = true;
|
|
196
285
|
}
|
|
197
|
-
const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.substring(modifierStart);
|
|
198
|
-
const baseClassName = stripImportantModifier(baseClassNameWithImportantModifier);
|
|
199
|
-
const hasImportantModifier = baseClassName !== baseClassNameWithImportantModifier;
|
|
200
286
|
const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined;
|
|
201
|
-
return
|
|
202
|
-
modifiers,
|
|
203
|
-
hasImportantModifier,
|
|
204
|
-
baseClassName,
|
|
205
|
-
maybePostfixModifierPosition
|
|
206
|
-
};
|
|
287
|
+
return createResultObject(modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition);
|
|
207
288
|
};
|
|
208
289
|
if (prefix) {
|
|
209
290
|
const fullPrefix = prefix + MODIFIER_SEPARATOR;
|
|
210
291
|
const parseClassNameOriginal = parseClassName;
|
|
211
|
-
parseClassName = className => className.startsWith(fullPrefix) ? parseClassNameOriginal(className.
|
|
212
|
-
isExternal: true,
|
|
213
|
-
modifiers: [],
|
|
214
|
-
hasImportantModifier: false,
|
|
215
|
-
baseClassName: className,
|
|
216
|
-
maybePostfixModifierPosition: undefined
|
|
217
|
-
};
|
|
292
|
+
parseClassName = className => className.startsWith(fullPrefix) ? parseClassNameOriginal(className.slice(fullPrefix.length)) : createResultObject(EMPTY_MODIFIERS, false, className, undefined, true);
|
|
218
293
|
}
|
|
219
294
|
if (experimentalParseClassName) {
|
|
220
295
|
const parseClassNameOriginal = parseClassName;
|
|
@@ -225,19 +300,6 @@ const createParseClassName = config => {
|
|
|
225
300
|
}
|
|
226
301
|
return parseClassName;
|
|
227
302
|
};
|
|
228
|
-
const stripImportantModifier = baseClassName => {
|
|
229
|
-
if (baseClassName.endsWith(IMPORTANT_MODIFIER)) {
|
|
230
|
-
return baseClassName.substring(0, baseClassName.length - 1);
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* In Tailwind CSS v3 the important modifier was at the start of the base class name. This is still supported for legacy reasons.
|
|
234
|
-
* @see https://github.com/dcastil/tailwind-merge/issues/513#issuecomment-2614029864
|
|
235
|
-
*/
|
|
236
|
-
if (baseClassName.startsWith(IMPORTANT_MODIFIER)) {
|
|
237
|
-
return baseClassName.substring(1);
|
|
238
|
-
}
|
|
239
|
-
return baseClassName;
|
|
240
|
-
};
|
|
241
303
|
|
|
242
304
|
/**
|
|
243
305
|
* Sorts modifiers according to following schema:
|
|
@@ -245,26 +307,41 @@ const stripImportantModifier = baseClassName => {
|
|
|
245
307
|
* - When an arbitrary variant appears, it must be preserved which modifiers are before and after it
|
|
246
308
|
*/
|
|
247
309
|
const createSortModifiers = config => {
|
|
248
|
-
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
310
|
+
// Pre-compute weights for all known modifiers for O(1) comparison
|
|
311
|
+
const modifierWeights = new Map();
|
|
312
|
+
// Assign weights to sensitive modifiers (highest priority, but preserve order)
|
|
313
|
+
config.orderSensitiveModifiers.forEach((mod, index) => {
|
|
314
|
+
modifierWeights.set(mod, 1000000 + index); // High weights for sensitive mods
|
|
315
|
+
});
|
|
316
|
+
return modifiers => {
|
|
317
|
+
const result = [];
|
|
318
|
+
let currentSegment = [];
|
|
319
|
+
// Process modifiers in one pass
|
|
320
|
+
for (let i = 0; i < modifiers.length; i++) {
|
|
321
|
+
const modifier = modifiers[i];
|
|
322
|
+
// Check if modifier is sensitive (starts with '[' or in orderSensitiveModifiers)
|
|
323
|
+
const isArbitrary = modifier[0] === '[';
|
|
324
|
+
const isOrderSensitive = modifierWeights.has(modifier);
|
|
325
|
+
if (isArbitrary || isOrderSensitive) {
|
|
326
|
+
// Sort and flush current segment alphabetically
|
|
327
|
+
if (currentSegment.length > 0) {
|
|
328
|
+
currentSegment.sort();
|
|
329
|
+
result.push(...currentSegment);
|
|
330
|
+
currentSegment = [];
|
|
331
|
+
}
|
|
332
|
+
result.push(modifier);
|
|
260
333
|
} else {
|
|
261
|
-
|
|
334
|
+
// Regular modifier - add to current segment for batch sorting
|
|
335
|
+
currentSegment.push(modifier);
|
|
262
336
|
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
|
|
337
|
+
}
|
|
338
|
+
// Sort and add any remaining segment items
|
|
339
|
+
if (currentSegment.length > 0) {
|
|
340
|
+
currentSegment.sort();
|
|
341
|
+
result.push(...currentSegment);
|
|
342
|
+
}
|
|
343
|
+
return result;
|
|
266
344
|
};
|
|
267
|
-
return sortModifiers;
|
|
268
345
|
};
|
|
269
346
|
const createConfigUtils = config => ({
|
|
270
347
|
cache: createLruCache(config.cacheSize),
|
|
@@ -319,10 +396,11 @@ const mergeClassList = (classList, configUtils) => {
|
|
|
319
396
|
}
|
|
320
397
|
hasPostfixModifier = false;
|
|
321
398
|
}
|
|
322
|
-
|
|
399
|
+
// Fast path: skip sorting for empty or single modifier
|
|
400
|
+
const variantModifier = modifiers.length === 0 ? '' : modifiers.length === 1 ? modifiers[0] : sortModifiers(modifiers).join(':');
|
|
323
401
|
const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;
|
|
324
402
|
const classId = modifierId + classGroupId;
|
|
325
|
-
if (classGroupsInConflict.
|
|
403
|
+
if (classGroupsInConflict.indexOf(classId) > -1) {
|
|
326
404
|
// Tailwind class omitted due to conflict
|
|
327
405
|
continue;
|
|
328
406
|
}
|
|
@@ -347,13 +425,13 @@ const mergeClassList = (classList, configUtils) => {
|
|
|
347
425
|
*
|
|
348
426
|
* Original code has MIT license: Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
|
|
349
427
|
*/
|
|
350
|
-
|
|
428
|
+
const twJoin = (...classLists) => {
|
|
351
429
|
let index = 0;
|
|
352
430
|
let argument;
|
|
353
431
|
let resolvedValue;
|
|
354
432
|
let string = '';
|
|
355
|
-
while (index <
|
|
356
|
-
if (argument =
|
|
433
|
+
while (index < classLists.length) {
|
|
434
|
+
if (argument = classLists[index++]) {
|
|
357
435
|
if (resolvedValue = toValue(argument)) {
|
|
358
436
|
string && (string += ' ');
|
|
359
437
|
string += resolvedValue;
|
|
@@ -361,8 +439,9 @@ function twJoin() {
|
|
|
361
439
|
}
|
|
362
440
|
}
|
|
363
441
|
return string;
|
|
364
|
-
}
|
|
442
|
+
};
|
|
365
443
|
const toValue = mix => {
|
|
444
|
+
// Fast path for strings
|
|
366
445
|
if (typeof mix === 'string') {
|
|
367
446
|
return mix;
|
|
368
447
|
}
|
|
@@ -378,20 +457,20 @@ const toValue = mix => {
|
|
|
378
457
|
}
|
|
379
458
|
return string;
|
|
380
459
|
};
|
|
381
|
-
|
|
460
|
+
const createTailwindMerge = (createConfigFirst, ...createConfigRest) => {
|
|
382
461
|
let configUtils;
|
|
383
462
|
let cacheGet;
|
|
384
463
|
let cacheSet;
|
|
385
|
-
let functionToCall
|
|
386
|
-
|
|
464
|
+
let functionToCall;
|
|
465
|
+
const initTailwindMerge = classList => {
|
|
387
466
|
const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());
|
|
388
467
|
configUtils = createConfigUtils(config);
|
|
389
468
|
cacheGet = configUtils.cache.get;
|
|
390
469
|
cacheSet = configUtils.cache.set;
|
|
391
470
|
functionToCall = tailwindMerge;
|
|
392
471
|
return tailwindMerge(classList);
|
|
393
|
-
}
|
|
394
|
-
|
|
472
|
+
};
|
|
473
|
+
const tailwindMerge = classList => {
|
|
395
474
|
const cachedResult = cacheGet(classList);
|
|
396
475
|
if (cachedResult) {
|
|
397
476
|
return cachedResult;
|
|
@@ -399,13 +478,13 @@ function createTailwindMerge(createConfigFirst, ...createConfigRest) {
|
|
|
399
478
|
const result = mergeClassList(classList, configUtils);
|
|
400
479
|
cacheSet(classList, result);
|
|
401
480
|
return result;
|
|
402
|
-
}
|
|
403
|
-
return function callTailwindMerge() {
|
|
404
|
-
return functionToCall(twJoin.apply(null, arguments));
|
|
405
481
|
};
|
|
406
|
-
|
|
482
|
+
functionToCall = initTailwindMerge;
|
|
483
|
+
return (...args) => functionToCall(twJoin(...args));
|
|
484
|
+
};
|
|
485
|
+
const fallbackThemeArr = [];
|
|
407
486
|
const fromTheme = key => {
|
|
408
|
-
const themeGetter = theme => theme[key] ||
|
|
487
|
+
const themeGetter = theme => theme[key] || fallbackThemeArr;
|
|
409
488
|
themeGetter.isThemeGetter = true;
|
|
410
489
|
return themeGetter;
|
|
411
490
|
};
|