@gaddario98/react-core 2.0.5 → 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.
@@ -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}const CLASS_PART_SEPARATOR = '-';
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
- const classParts = className.split(CLASS_PART_SEPARATOR);
10
- // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and remove it from classParts.
11
- if (classParts[0] === '' && classParts.length !== 1) {
12
- classParts.shift();
38
+ if (className.startsWith('[') && className.endsWith(']')) {
39
+ return getGroupIdForArbitraryProperty(className);
13
40
  }
14
- return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className);
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
- const conflicts = conflictingClassGroups[classGroupId] || [];
18
- if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) {
19
- return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]];
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 conflicts;
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
- if (classParts.length === 0) {
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[0];
73
+ const currentClassPart = classParts[startIndex];
33
74
  const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
34
- const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : undefined;
35
- if (classGroupFromNextClassPart) {
36
- return classGroupFromNextClassPart;
75
+ if (nextClassPartObject) {
76
+ const result = getGroupRecursive(classParts, startIndex + 1, nextClassPartObject);
77
+ if (result) return result;
37
78
  }
38
- if (classPartObject.validators.length === 0) {
79
+ const validators = classPartObject.validators;
80
+ if (validators === null) {
39
81
  return undefined;
40
82
  }
41
- const classRest = classParts.join(CLASS_PART_SEPARATOR);
42
- return classPartObject.validators.find(({
43
- validator
44
- }) => validator(classRest))?.classGroupId;
45
- };
46
- const arbitraryPropertyRegex = /^\[(.+)\]$/;
47
- const getGroupIdForArbitraryProperty = className => {
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
- const classMap = {
66
- nextPart: new Map(),
67
- validators: []
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
- processClassesRecursively(classGroups[classGroupId], classMap, classGroupId, theme);
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.forEach(classDefinition => {
76
- if (typeof classDefinition === 'string') {
77
- const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);
78
- classPartObjectToEdit.classGroupId = classGroupId;
79
- return;
80
- }
81
- if (typeof classDefinition === 'function') {
82
- if (isThemeGetter(classDefinition)) {
83
- processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
84
- return;
85
- }
86
- classPartObject.validators.push({
87
- validator: classDefinition,
88
- classGroupId
89
- });
90
- return;
91
- }
92
- Object.entries(classDefinition).forEach(([key, classGroup]) => {
93
- processClassesRecursively(classGroup, getPart(classPartObject, key), classGroupId, theme);
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 currentClassPartObject = classPartObject;
99
- path.split(CLASS_PART_SEPARATOR).forEach(pathPart => {
100
- if (!currentClassPartObject.nextPart.has(pathPart)) {
101
- currentClassPartObject.nextPart.set(pathPart, {
102
- nextPart: new Map(),
103
- validators: []
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
- currentClassPartObject = currentClassPartObject.nextPart.get(pathPart);
107
- });
108
- return currentClassPartObject;
176
+ current = next;
177
+ }
178
+ return current;
109
179
  };
110
- const isThemeGetter = func => func.isThemeGetter;
180
+ // Type guard maintains monomorphic check
181
+ const isThemeGetter = func => 'isThemeGetter' in func && func.isThemeGetter === true;
111
182
 
112
- // LRU cache inspired from hashlru (https://github.com/dominictarr/hashlru/blob/v1.0.4/index.js) but object replaced with Map to improve performance
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 = new Map();
122
- let previousCache = new Map();
192
+ let cache = Object.create(null);
193
+ let previousCache = Object.create(null);
123
194
  const update = (key, value) => {
124
- cache.set(key, value);
195
+ cache[key] = value;
125
196
  cacheSize++;
126
197
  if (cacheSize > maxCacheSize) {
127
198
  cacheSize = 0;
128
199
  previousCache = cache;
129
- cache = new Map();
200
+ cache = Object.create(null);
130
201
  }
131
202
  };
132
203
  return {
133
204
  get(key) {
134
- let value = cache.get(key);
205
+ let value = cache[key];
135
206
  if (value !== undefined) {
136
207
  return value;
137
208
  }
138
- if ((value = previousCache.get(key)) !== undefined) {
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.has(key)) {
145
- cache.set(key, value);
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 MODIFIER_SEPARATOR_LENGTH = MODIFIER_SEPARATOR.length;
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
- for (let index = 0; index < className.length; index++) {
173
- let currentCharacter = className[index];
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 + MODIFIER_SEPARATOR_LENGTH;
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
- bracketDepth++;
187
- } else if (currentCharacter === ']') {
188
- bracketDepth--;
189
- } else if (currentCharacter === '(') {
190
- parenDepth++;
191
- } else if (currentCharacter === ')') {
192
- parenDepth--;
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.substring(fullPrefix.length)) : {
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
- const orderSensitiveModifiers = Object.fromEntries(config.orderSensitiveModifiers.map(modifier => [modifier, true]));
247
- const sortModifiers = modifiers => {
248
- if (modifiers.length <= 1) {
249
- return modifiers;
250
- }
251
- const sortedModifiers = [];
252
- let unsortedModifiers = [];
253
- modifiers.forEach(modifier => {
254
- const isPositionSensitive = modifier[0] === '[' || orderSensitiveModifiers[modifier];
255
- if (isPositionSensitive) {
256
- sortedModifiers.push(...unsortedModifiers.sort(), modifier);
257
- unsortedModifiers = [];
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
- unsortedModifiers.push(modifier);
332
+ // Regular modifier - add to current segment for batch sorting
333
+ currentSegment.push(modifier);
260
334
  }
261
- });
262
- sortedModifiers.push(...unsortedModifiers.sort());
263
- return sortedModifiers;
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
- const variantModifier = sortModifiers(modifiers).join(':');
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.includes(classId)) {
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
- function twJoin() {
426
+ const twJoin = (...classLists) => {
349
427
  let index = 0;
350
428
  let argument;
351
429
  let resolvedValue;
352
430
  let string = '';
353
- while (index < arguments.length) {
354
- if (argument = arguments[index++]) {
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
- function createTailwindMerge(createConfigFirst, ...createConfigRest) {
458
+ const createTailwindMerge = (createConfigFirst, ...createConfigRest) => {
380
459
  let configUtils;
381
460
  let cacheGet;
382
461
  let cacheSet;
383
- let functionToCall = initTailwindMerge;
384
- function initTailwindMerge(classList) {
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
- function tailwindMerge(classList) {
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
  };