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