Socket
Socket
Sign inDemoInstall

tailwind-merge

Package Overview
Dependencies
Maintainers
1
Versions
276
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tailwind-merge - npm Package Compare versions

Comparing version 0.7.1 to 0.8.0

dist/types/create-tailwind-merge.d.ts

576

dist/index.js

@@ -129,31 +129,113 @@ import HLRU from 'hashlru';

function createPrefixUtils(config) {
const prefixToIndexMap = Object.fromEntries(config.prefixes.flatMap(prefix => getPrefixesRecursively('', prefix)).map((prefix, index) => [prefix, index]));
function createConfigUtils(config) {
return _extends({
cache: getLruCache(config.cacheSize)
}, createClassUtils(config));
}
function isPrefixValid(maybePrefix) {
return prefixToIndexMap[maybePrefix] !== undefined;
}
const SPLIT_CLASSES_REGEX = /\s+/;
const IMPORTANT_MODIFIER = '!'; // Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`
// I'd prefer to use a negative lookbehind for all supported labels, but lookbheinds don't have good browser support yet. More info: https://caniuse.com/js-regexp-lookbehind
function comparePrefixes(firstPrefix, secondPrefix) {
return prefixToIndexMap[firstPrefix] - prefixToIndexMap[secondPrefix];
}
const PREFIX_SEPARATOR_REGEX = /:(?![^[]*\])/;
const PREFIX_SEPARATOR = ':';
function mergeClassList(classList, configUtils) {
const {
getClassGroupId,
getConflictingClassGroupIds
} = configUtils;
/**
* Set of classGroupIds in following format:
* `{importantModifier}{variantPrefixes}{classGroupId}`
* @example 'float'
* @example 'hover:focus:bg-color'
* @example '!md:pr'
*/
return {
isPrefixValid,
comparePrefixes
};
const classGroupsInConflict = new Set();
return classList.trim().split(SPLIT_CLASSES_REGEX).map(originalClassName => {
const prefixes = originalClassName.split(PREFIX_SEPARATOR_REGEX);
const classNameWithImportantModifier = prefixes.pop();
const hasImportantModifier = classNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);
const className = hasImportantModifier ? classNameWithImportantModifier.substring(1) : classNameWithImportantModifier;
const classGroupId = getClassGroupId(className);
if (!classGroupId) {
return {
isTailwindClass: false,
originalClassName
};
}
const variantPrefix = prefixes.length === 0 ? '' : prefixes.sort().concat('').join(PREFIX_SEPARATOR);
const fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;
return {
isTailwindClass: true,
prefix: fullPrefix,
classGroupId,
originalClassName
};
}).reverse() // Last class in conflict wins, so we need to filter conflicting classes in reverse order.
.filter(parsed => {
if (!parsed.isTailwindClass) {
return true;
}
const {
prefix,
classGroupId
} = parsed;
const classId = `${prefix}:${classGroupId}`;
if (classGroupsInConflict.has(classId)) {
return false;
}
classGroupsInConflict.add(classId);
getConflictingClassGroupIds(classGroupId).forEach(group => classGroupsInConflict.add(`${prefix}:${group}`));
return true;
}).reverse().map(parsed => parsed.originalClassName).join(' ');
}
function getPrefixesRecursively(path, prefixPart) {
if (typeof prefixPart === 'string') {
return path.concat(prefixPart);
function createTailwindMerge(...createConfig) {
let configUtils;
let cacheGet;
let cacheSet;
let functionToCall = initTailwindMerge;
function initTailwindMerge(classList) {
const [firstCreateConfig, ...restCreateConfig] = createConfig;
const config = restCreateConfig.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), firstCreateConfig());
configUtils = createConfigUtils(config);
cacheGet = configUtils.cache.get;
cacheSet = configUtils.cache.set;
functionToCall = tailwindMerge;
return tailwindMerge(classList);
}
return Object.entries(prefixPart).flatMap(([pathPart, nextPrefixParts]) => nextPrefixParts.flatMap(nextPrefixPart => getPrefixesRecursively(`${path}${pathPart}-`, nextPrefixPart)));
}
function tailwindMerge(classList) {
const cachedResult = cacheGet(classList);
function createConfigUtils(config) {
return _extends({
cache: getLruCache(config.cacheSize)
}, createPrefixUtils(config), createClassUtils(config));
if (cachedResult) {
return cachedResult;
}
const result = mergeClassList(classList, configUtils);
cacheSet(classList, result);
return result;
}
return function callTailwindMerge() {
let classList = '';
let temp; // Credits → https://github.com/lukeed/clsx/blob/v1.1.1/src/index.js
for (let index = 0; index < arguments.length; index += 1) {
if (temp = arguments[index]) {
classList && (classList += ' ');
classList += temp;
}
}
return functionToCall(classList);
};
}

@@ -197,33 +279,48 @@

const SIZES_SIMPLE = ['sm', 'md', 'lg', 'xl', '2xl'];
const SIZES_EXTENDED = ['3xl', '4xl', '5xl', '6xl', '7xl'];
const OVERSCROLL = ['auto', 'contain', 'none'];
const OVERFLOW = ['auto', 'hidden', 'visible', 'scroll'];
const LENGTH = [isLength];
const LENGTH_WITH_AUTO = ['auto', isLength];
const LENGTH_WITH_EMPTY = ['', isLength];
const INTEGER = [isInteger];
const INTEGER_WITH_AUTO = ['auto', isInteger];
const ANY = [isAny];
const POSITIONS = ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];
const ROUNDED = ['none', '', ...SIZES_SIMPLE, '3xl', 'full', isCustomLength];
const BORDER_STYLES = ['solid', 'dashed', 'dotted', 'double', 'none'];
const BLEND_MODES = [{
blend: ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity']
}];
const ALIGN = ['start', 'end', 'center', 'between', 'around', 'evenly'];
const ZERO_AND_EMPTY = ['', '0'];
const PSEUDO_VARIANTS = [// Positional
'first', 'last', 'only', 'odd', 'even', 'first-of-type', 'last-of-type', 'only-of-type', // State
'visited', 'target', // Forms
'default', 'checked', 'indeterminate', 'placeholder-shown', 'autofill', 'required', 'valid', 'invalid', 'in-range', 'out-of-range', 'read-only', // Content
'empty', // Interactive
'focus-within', 'hover', 'focus', 'focus-visible', 'active', 'disabled'];
var validators = {
__proto__: null,
isLength: isLength,
isCustomLength: isCustomLength,
isInteger: isInteger,
isCustomValue: isCustomValue,
isAny: isAny
};
function getDefaultConfig() {
const getSizesSimple = () => ['sm', 'md', 'lg', 'xl', '2xl'];
const getSizesExtended = () => ['3xl', '4xl', '5xl', '6xl', '7xl'];
const getOverscroll = () => ['auto', 'contain', 'none'];
const getOverflow = () => ['auto', 'hidden', 'visible', 'scroll'];
const getLength = () => [isLength];
const getLengthWithAuto = () => ['auto', isLength];
const getLengthWithEmpty = () => ['', isLength];
const getInteger = () => [isInteger];
const getIntegerWithAuto = () => ['auto', isInteger];
const getAny = () => [isAny];
const getPositions = () => ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];
const getRounded = () => ['none', '', ...getSizesSimple(), '3xl', 'full', isCustomLength];
const getBorderStyles = () => ['solid', 'dashed', 'dotted', 'double', 'none'];
const getBlendModes = () => [{
blend: ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity']
}];
const getAlign = () => ['start', 'end', 'center', 'between', 'around', 'evenly'];
const getZeroAndEmpty = () => ['', '0'];
return {
cacheSize: 500,
prefixes: [...SIZES_SIMPLE, 'dark', 'motion-safe', 'motion-reduce', 'before', 'after', 'first-letter', 'first-line', 'selection', 'marker', ...PSEUDO_VARIANTS, {
group: PSEUDO_VARIANTS,
peer: PSEUDO_VARIANTS
}],
classGroups: {

@@ -295,3 +392,3 @@ // Layout

'object-position': [{
object: POSITIONS
object: getPositions()
}],

@@ -304,3 +401,3 @@

overflow: [{
overflow: OVERFLOW
overflow: getOverflow()
}],

@@ -313,3 +410,3 @@

'overflow-x': [{
'overflow-x': OVERFLOW
'overflow-x': getOverflow()
}],

@@ -322,3 +419,3 @@

'overflow-y': [{
'overflow-y': OVERFLOW
'overflow-y': getOverflow()
}],

@@ -331,3 +428,3 @@

overscroll: [{
overscroll: OVERSCROLL
overscroll: getOverscroll()
}],

@@ -340,3 +437,3 @@

'overscroll-x': [{
'overscroll-x': OVERSCROLL
'overscroll-x': getOverscroll()
}],

@@ -349,3 +446,3 @@

'overscroll-y': [{
'overscroll-y': OVERSCROLL
'overscroll-y': getOverscroll()
}],

@@ -364,3 +461,3 @@

inset: [{
inset: LENGTH_WITH_AUTO
inset: getLengthWithAuto()
}],

@@ -373,3 +470,3 @@

'inset-x': [{
'inset-x': LENGTH_WITH_AUTO
'inset-x': getLengthWithAuto()
}],

@@ -382,3 +479,3 @@

'inset-y': [{
'inset-y': LENGTH_WITH_AUTO
'inset-y': getLengthWithAuto()
}],

@@ -391,3 +488,3 @@

top: [{
top: LENGTH_WITH_AUTO
top: getLengthWithAuto()
}],

@@ -400,3 +497,3 @@

right: [{
right: LENGTH_WITH_AUTO
right: getLengthWithAuto()
}],

@@ -409,3 +506,3 @@

bottom: [{
bottom: LENGTH_WITH_AUTO
bottom: getLengthWithAuto()
}],

@@ -418,3 +515,3 @@

left: [{
left: LENGTH_WITH_AUTO
left: getLengthWithAuto()
}],

@@ -433,3 +530,3 @@

z: [{
z: LENGTH
z: getLength()
}],

@@ -491,3 +588,3 @@ // Flexbox and Grid

'grid-cols': [{
'grid-cols': ANY
'grid-cols': getAny()
}],

@@ -501,3 +598,3 @@

col: ['auto', {
span: INTEGER
span: getInteger()
}]

@@ -511,3 +608,3 @@ }],

'col-start': [{
'col-start': INTEGER_WITH_AUTO
'col-start': getIntegerWithAuto()
}],

@@ -520,3 +617,3 @@

'col-end': [{
'col-end': INTEGER_WITH_AUTO
'col-end': getIntegerWithAuto()
}],

@@ -529,3 +626,3 @@

'grid-rows': [{
'grid-rows': ANY
'grid-rows': getAny()
}],

@@ -539,3 +636,3 @@

row: ['auto', {
span: INTEGER
span: getInteger()
}]

@@ -549,3 +646,3 @@ }],

'row-start': [{
'row-start': INTEGER_WITH_AUTO
'row-start': getIntegerWithAuto()
}],

@@ -558,3 +655,3 @@

'row-end': [{
'row-end': INTEGER_WITH_AUTO
'row-end': getIntegerWithAuto()
}],

@@ -591,3 +688,3 @@

gap: [{
gap: LENGTH
gap: getLength()
}],

@@ -600,3 +697,3 @@

'gap-x': [{
'gap-x': LENGTH
'gap-x': getLength()
}],

@@ -609,3 +706,3 @@

'gap-y': [{
'gap-y': LENGTH
'gap-y': getLength()
}],

@@ -618,3 +715,3 @@

'justify-content': [{
justify: ALIGN
justify: getAlign()
}],

@@ -643,3 +740,3 @@

'align-content': [{
content: ALIGN
content: getAlign()
}],

@@ -668,3 +765,3 @@

'place-content': [{
'place-content': [...ALIGN, 'stretch']
'place-content': [...getAlign(), 'stretch']
}],

@@ -694,3 +791,3 @@

p: [{
p: LENGTH
p: getLength()
}],

@@ -703,3 +800,3 @@

px: [{
px: LENGTH
px: getLength()
}],

@@ -712,3 +809,3 @@

py: [{
py: LENGTH
py: getLength()
}],

@@ -721,3 +818,3 @@

pt: [{
pt: LENGTH
pt: getLength()
}],

@@ -730,3 +827,3 @@

pr: [{
pr: LENGTH
pr: getLength()
}],

@@ -739,3 +836,3 @@

pb: [{
pb: LENGTH
pb: getLength()
}],

@@ -748,3 +845,3 @@

pl: [{
pl: LENGTH
pl: getLength()
}],

@@ -757,3 +854,3 @@

m: [{
m: LENGTH_WITH_AUTO
m: getLengthWithAuto()
}],

@@ -766,3 +863,3 @@

mx: [{
mx: LENGTH_WITH_AUTO
mx: getLengthWithAuto()
}],

@@ -775,3 +872,3 @@

my: [{
my: LENGTH_WITH_AUTO
my: getLengthWithAuto()
}],

@@ -784,3 +881,3 @@

mt: [{
mt: LENGTH_WITH_AUTO
mt: getLengthWithAuto()
}],

@@ -793,3 +890,3 @@

mr: [{
mr: LENGTH_WITH_AUTO
mr: getLengthWithAuto()
}],

@@ -802,3 +899,3 @@

mb: [{
mb: LENGTH_WITH_AUTO
mb: getLengthWithAuto()
}],

@@ -811,3 +908,3 @@

ml: [{
ml: LENGTH_WITH_AUTO
ml: getLengthWithAuto()
}],

@@ -820,3 +917,3 @@

'space-x': [{
'space-x': LENGTH
'space-x': getLength()
}],

@@ -835,3 +932,3 @@

'space-y': [{
'space-y': LENGTH
'space-y': getLength()
}],

@@ -867,4 +964,4 @@

'max-w': [{
'max-w': ['0', 'none', ...SIZES_SIMPLE, ...SIZES_EXTENDED, 'full', 'min', 'max', 'prose', {
screen: SIZES_SIMPLE
'max-w': ['0', 'none', ...getSizesSimple(), ...getSizesExtended(), 'full', 'min', 'max', 'prose', {
screen: getSizesSimple()
}]

@@ -878,3 +975,3 @@ }],

h: [{
h: LENGTH_WITH_AUTO
h: getLengthWithAuto()
}],

@@ -895,3 +992,3 @@

'max-h': [{
'max-h': LENGTH
'max-h': getLength()
}],

@@ -905,3 +1002,3 @@ // Typography

'font-family': [{
font: ANY
font: getAny()
}],

@@ -914,3 +1011,3 @@

'font-size': [{
text: ['xs', ...SIZES_SIMPLE, 'base', ...SIZES_EXTENDED, '8xl', '9xl', isCustomLength]
text: ['xs', ...getSizesSimple(), 'base', ...getSizesExtended(), '8xl', '9xl', isCustomLength]
}],

@@ -1011,3 +1108,3 @@

'placeholder-color': [{
placeholder: ANY
placeholder: getAny()
}],

@@ -1020,3 +1117,3 @@

'placeholder-opacity': [{
'placeholder-opacity': INTEGER
'placeholder-opacity': getInteger()
}],

@@ -1037,3 +1134,3 @@

'text-color': [{
text: ANY
text: getAny()
}],

@@ -1046,3 +1143,3 @@

'text-opacity': [{
'text-opacity': INTEGER
'text-opacity': getInteger()
}],

@@ -1114,3 +1211,3 @@

'bg-opacity': [{
'bg-opacity': INTEGER
'bg-opacity': getInteger()
}],

@@ -1131,3 +1228,3 @@

'bg-position': [{
bg: POSITIONS
bg: getPositions()
}],

@@ -1168,3 +1265,3 @@

'bg-blend': [{
bg: BLEND_MODES
bg: getBlendModes()
}],

@@ -1177,3 +1274,3 @@

'bg-color': [{
bg: ANY
bg: getAny()
}],

@@ -1186,3 +1283,3 @@

'gradient-from': [{
from: ANY
from: getAny()
}],

@@ -1195,3 +1292,3 @@

'gradient-via': [{
via: ANY
via: getAny()
}],

@@ -1204,3 +1301,3 @@

'gradient-to': [{
to: ANY
to: getAny()
}],

@@ -1214,3 +1311,3 @@ // Borders

rounded: [{
rounded: ROUNDED
rounded: getRounded()
}],

@@ -1223,3 +1320,3 @@

'rounded-t': [{
'rounded-t': ROUNDED
'rounded-t': getRounded()
}],

@@ -1232,3 +1329,3 @@

'rounded-r': [{
'rounded-r': ROUNDED
'rounded-r': getRounded()
}],

@@ -1241,3 +1338,3 @@

'rounded-b': [{
'rounded-b': ROUNDED
'rounded-b': getRounded()
}],

@@ -1250,3 +1347,3 @@

'rounded-l': [{
'rounded-l': ROUNDED
'rounded-l': getRounded()
}],

@@ -1259,3 +1356,3 @@

'rounded-tl': [{
'rounded-tl': ROUNDED
'rounded-tl': getRounded()
}],

@@ -1268,3 +1365,3 @@

'rounded-tr': [{
'rounded-tr': ROUNDED
'rounded-tr': getRounded()
}],

@@ -1277,3 +1374,3 @@

'rounded-br': [{
'rounded-br': ROUNDED
'rounded-br': getRounded()
}],

@@ -1286,3 +1383,3 @@

'rounded-bl': [{
'rounded-bl': ROUNDED
'rounded-bl': getRounded()
}],

@@ -1295,3 +1392,3 @@

'border-w': [{
border: LENGTH_WITH_EMPTY
border: getLengthWithEmpty()
}],

@@ -1304,3 +1401,3 @@

'border-w-t': [{
'border-t': LENGTH_WITH_EMPTY
'border-t': getLengthWithEmpty()
}],

@@ -1313,3 +1410,3 @@

'border-w-r': [{
'border-r': LENGTH_WITH_EMPTY
'border-r': getLengthWithEmpty()
}],

@@ -1322,3 +1419,3 @@

'border-w-b': [{
'border-b': LENGTH_WITH_EMPTY
'border-b': getLengthWithEmpty()
}],

@@ -1331,3 +1428,3 @@

'border-w-l': [{
'border-l': LENGTH_WITH_EMPTY
'border-l': getLengthWithEmpty()
}],

@@ -1340,3 +1437,3 @@

'border-opacity': [{
'border-opacity': INTEGER
'border-opacity': getInteger()
}],

@@ -1349,3 +1446,3 @@

'border-style': [{
border: BORDER_STYLES
border: getBorderStyles()
}],

@@ -1358,3 +1455,3 @@

'divide-x': [{
'divide-x': LENGTH_WITH_EMPTY
'divide-x': getLengthWithEmpty()
}],

@@ -1373,3 +1470,3 @@

'divide-y': [{
'divide-y': LENGTH_WITH_EMPTY
'divide-y': getLengthWithEmpty()
}],

@@ -1388,3 +1485,3 @@

'divide-opacity': [{
'divide-opacity': INTEGER
'divide-opacity': getInteger()
}],

@@ -1397,3 +1494,3 @@

'divide-style': [{
divide: BORDER_STYLES
divide: getBorderStyles()
}],

@@ -1406,3 +1503,3 @@

'border-color': [{
border: ANY
border: getAny()
}],

@@ -1415,3 +1512,3 @@

'border-color-t': [{
'border-t': ANY
'border-t': getAny()
}],

@@ -1424,3 +1521,3 @@

'border-color-r': [{
'border-r': ANY
'border-r': getAny()
}],

@@ -1433,3 +1530,3 @@

'border-color-b': [{
'border-b': ANY
'border-b': getAny()
}],

@@ -1442,3 +1539,3 @@

'border-color-l': [{
'border-l': ANY
'border-l': getAny()
}],

@@ -1451,3 +1548,3 @@

'divide-color': [{
divide: ANY
divide: getAny()
}],

@@ -1460,3 +1557,3 @@

'ring-w': [{
ring: LENGTH_WITH_EMPTY
ring: getLengthWithEmpty()
}],

@@ -1475,3 +1572,3 @@

'ring-color': [{
ring: ANY
ring: getAny()
}],

@@ -1484,3 +1581,3 @@

'ring-opacity': [{
'ring-opacity': INTEGER
'ring-opacity': getInteger()
}],

@@ -1493,3 +1590,3 @@

'ring-offset-w': [{
'ring-offset': LENGTH
'ring-offset': getLength()
}],

@@ -1502,3 +1599,3 @@

'ring-offset-color': [{
'ring-offset': ANY
'ring-offset': getAny()
}],

@@ -1512,3 +1609,3 @@ // Effects

shadow: [{
shadow: ['', ...SIZES_SIMPLE, 'inner', 'none']
shadow: ['', ...getSizesSimple(), 'inner', 'none']
}],

@@ -1521,3 +1618,3 @@

opacity: [{
opacity: INTEGER
opacity: getInteger()
}],

@@ -1530,3 +1627,3 @@

'mix-blend': [{
'mix-blend': BLEND_MODES
'mix-blend': getBlendModes()
}],

@@ -1548,3 +1645,3 @@ // Filters

blur: [{
blur: ['none', '', ...SIZES_SIMPLE, '3xl', isCustomLength]
blur: ['none', '', ...getSizesSimple(), '3xl', isCustomLength]
}],

@@ -1557,3 +1654,3 @@

brightness: [{
brightness: INTEGER
brightness: getInteger()
}],

@@ -1566,3 +1663,3 @@

contrast: [{
contrast: INTEGER
contrast: getInteger()
}],

@@ -1575,3 +1672,3 @@

'drop-shadow': [{
'drop-shadow': ['', ...SIZES_SIMPLE, 'none']
'drop-shadow': ['', ...getSizesSimple(), 'none']
}],

@@ -1584,3 +1681,3 @@

grayscale: [{
grayscale: ZERO_AND_EMPTY
grayscale: getZeroAndEmpty()
}],

@@ -1593,3 +1690,3 @@

'hue-rotate': [{
'hue-rotate': INTEGER
'hue-rotate': getInteger()
}],

@@ -1602,3 +1699,3 @@

invert: [{
invert: ZERO_AND_EMPTY
invert: getZeroAndEmpty()
}],

@@ -1611,3 +1708,3 @@

saturate: [{
saturate: INTEGER
saturate: getInteger()
}],

@@ -1620,3 +1717,3 @@

sepia: [{
sepia: ZERO_AND_EMPTY
sepia: getZeroAndEmpty()
}],

@@ -1637,3 +1734,3 @@

'backdrop-blur': [{
'backdrop-blur': ['none', '', ...SIZES_SIMPLE, '3xl']
'backdrop-blur': ['none', '', ...getSizesSimple(), '3xl']
}],

@@ -1646,3 +1743,3 @@

'backdrop-brightness': [{
'backdrop-brightness': INTEGER
'backdrop-brightness': getInteger()
}],

@@ -1655,3 +1752,3 @@

'backdrop-contrast': [{
'backdrop-contrast': INTEGER
'backdrop-contrast': getInteger()
}],

@@ -1664,3 +1761,3 @@

'backdrop-grayscale': [{
'backdrop-grayscale': ZERO_AND_EMPTY
'backdrop-grayscale': getZeroAndEmpty()
}],

@@ -1673,3 +1770,3 @@

'backdrop-hue-rotate': [{
'backdrop-hue-rotate': INTEGER
'backdrop-hue-rotate': getInteger()
}],

@@ -1682,3 +1779,3 @@

'backdrop-invert': [{
'backdrop-invert': ZERO_AND_EMPTY
'backdrop-invert': getZeroAndEmpty()
}],

@@ -1691,3 +1788,3 @@

'backdrop-opacity': [{
'backdrop-opacity': INTEGER
'backdrop-opacity': getInteger()
}],

@@ -1700,3 +1797,3 @@

'backdrop-saturate': [{
'backdrop-saturate': INTEGER
'backdrop-saturate': getInteger()
}],

@@ -1709,3 +1806,3 @@

'backdrop-sepia': [{
'backdrop-sepia': ZERO_AND_EMPTY
'backdrop-sepia': getZeroAndEmpty()
}],

@@ -1744,3 +1841,3 @@ // Tables

duration: [{
duration: INTEGER
duration: getInteger()
}],

@@ -1761,3 +1858,3 @@

delay: [{
delay: INTEGER
delay: getInteger()
}],

@@ -1795,3 +1892,3 @@

scale: [{
scale: INTEGER
scale: getInteger()
}],

@@ -1804,3 +1901,3 @@

'scale-x': [{
'scale-x': INTEGER
'scale-x': getInteger()
}],

@@ -1813,3 +1910,3 @@

'scale-y': [{
'scale-y': INTEGER
'scale-y': getInteger()
}],

@@ -1822,3 +1919,3 @@

rotate: [{
rotate: INTEGER
rotate: getInteger()
}],

@@ -1831,3 +1928,3 @@

'translate-x': [{
'translate-x': LENGTH
'translate-x': getLength()
}],

@@ -1840,3 +1937,3 @@

'translate-y': [{
'translate-y': LENGTH
'translate-y': getLength()
}],

@@ -1849,3 +1946,3 @@

'skew-x': [{
'skew-x': INTEGER
'skew-x': getInteger()
}],

@@ -1858,3 +1955,3 @@

'skew-y': [{
'skew-y': INTEGER
'skew-y': getInteger()
}],

@@ -1929,3 +2026,3 @@ // Interactivity

'stroke-w': [{
stroke: LENGTH
stroke: getLength()
}],

@@ -1954,3 +2051,3 @@ // Accessibility

'caret-color': [{
caret: ANY
caret: getAny()
}]

@@ -1992,113 +2089,46 @@ },

const SPLIT_CLASSES_REGEX = /\s+/;
const IMPORTANT_MODIFIER = '!'; // Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`
// I'd prefer to use a negative lookbehind for all supported labels, but lookbheinds don't have good browser support yet. More info: https://caniuse.com/js-regexp-lookbehind
/**
* @param baseConfig Config where other config will be merged into. This object will be mutated.
* @param configExtension Partial config to merge into the `baseConfig`.
*/
function mergeConfigs(baseConfig, configExtension) {
for (const key in configExtension) {
mergePropertyRecursively(baseConfig, key, configExtension[key]);
}
const PREFIX_SEPARATOR_REGEX = /:(?![^[]*\])/;
const PREFIX_SEPARATOR = ':';
function mergeClassList(classList, configUtils) {
const {
isPrefixValid,
getClassGroupId,
comparePrefixes,
getConflictingClassGroupIds
} = configUtils;
/**
* Set of classGroupIds in following format:
* `{importantModifier}{variantPrefixes}{classGroupId}`
* @example ':standaloneClasses.1'
* @example 'hover:focus:dynamicClasses.bg.2'
* @example '!md:dynamicClasses.bg.0'
*/
const classGroupsInConflict = new Set();
return classList.trim().split(SPLIT_CLASSES_REGEX).map(originalClassName => {
const prefixes = originalClassName.split(PREFIX_SEPARATOR_REGEX);
const classNameWithImportantModifier = prefixes.pop();
const hasImportantModifier = classNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);
const className = hasImportantModifier ? classNameWithImportantModifier.substring(1) : classNameWithImportantModifier;
const arePrefixesValid = prefixes.every(isPrefixValid);
const classGroupId = arePrefixesValid ? getClassGroupId(className) : undefined;
if (!classGroupId) {
return {
isTailwindClass: false,
originalClassName
};
}
const variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(comparePrefixes).concat('').join(PREFIX_SEPARATOR);
const fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;
return {
isTailwindClass: true,
prefix: fullPrefix,
classGroupId,
originalClassName
};
}).reverse() // Last class in conflict wins, so we need to filter conflicting classes in reverse order.
.filter(parsed => {
if (!parsed.isTailwindClass) {
return true;
}
const {
prefix,
classGroupId
} = parsed;
const classId = `${prefix}:${classGroupId}`;
if (classGroupsInConflict.has(classId)) {
return false;
}
classGroupsInConflict.add(classId);
getConflictingClassGroupIds(classGroupId).forEach(group => classGroupsInConflict.add(`${prefix}:${group}`));
return true;
}).reverse().map(parsed => parsed.originalClassName).join(' ');
return baseConfig;
}
const hasOwnProperty = Object.prototype.hasOwnProperty;
const overrideTypes = new Set(['string', 'number', 'boolean']);
function createTailwindMerge(createConfig) {
let configUtils;
let cacheGet;
let cacheSet;
let functionToCall = initTailwindMerge;
function mergePropertyRecursively(baseObject, mergeKey, mergeValue) {
if (!hasOwnProperty.call(baseObject, mergeKey) || overrideTypes.has(typeof mergeValue) || mergeValue === null) {
baseObject[mergeKey] = mergeValue;
return;
}
function initTailwindMerge(classList) {
configUtils = createConfigUtils(createConfig(getDefaultConfig));
cacheGet = configUtils.cache.get;
cacheSet = configUtils.cache.set;
functionToCall = tailwindMerge;
return tailwindMerge(classList);
if (Array.isArray(mergeValue) && Array.isArray(baseObject[mergeKey])) {
baseObject[mergeKey] = baseObject[mergeKey].concat(mergeValue);
return;
}
function tailwindMerge(classList) {
const cachedResult = cacheGet(classList);
if (typeof mergeValue === 'object' && typeof baseObject[mergeKey] === 'object') {
if (baseObject[mergeKey] === null) {
baseObject[mergeKey] = mergeValue;
return;
}
if (cachedResult) {
return cachedResult;
for (const nextKey in mergeValue) {
mergePropertyRecursively(baseObject[mergeKey], nextKey, mergeValue[nextKey]);
}
const result = mergeClassList(classList, configUtils);
cacheSet(classList, result);
return result;
}
}
return function callTailwindMerge() {
let classList = '';
let temp; // Credits → https://github.com/lukeed/clsx/blob/v1.1.1/src/index.js
for (let index = 0; index < arguments.length; index += 1) {
if (temp = arguments[index]) {
classList && (classList += ' ');
classList += temp;
}
}
return functionToCall(classList);
};
function extendTailwindMerge(configExtension, ...createConfig) {
return typeof configExtension === 'function' ? createTailwindMerge(getDefaultConfig, configExtension, ...createConfig) : createTailwindMerge(() => mergeConfigs(getDefaultConfig(), configExtension), ...createConfig);
}
const twMerge = createTailwindMerge(defaultConfig => defaultConfig());
const twMerge = createTailwindMerge(getDefaultConfig);
export { createTailwindMerge, twMerge };
export { createTailwindMerge, extendTailwindMerge, getDefaultConfig, mergeConfigs, twMerge, validators };
//# sourceMappingURL=index.js.map

@@ -136,41 +136,119 @@ import HLRU from 'hashlru';

function createPrefixUtils(config) {
var prefixToIndexMap = Object.fromEntries(config.prefixes.flatMap(function (prefix) {
return getPrefixesRecursively('', prefix);
}).map(function (prefix, index) {
return [prefix, index];
}));
function createConfigUtils(config) {
return _extends({
cache: getLruCache(config.cacheSize)
}, createClassUtils(config));
}
function isPrefixValid(maybePrefix) {
return prefixToIndexMap[maybePrefix] !== undefined;
}
var SPLIT_CLASSES_REGEX = /\s+/;
var IMPORTANT_MODIFIER = '!'; // Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`
// I'd prefer to use a negative lookbehind for all supported labels, but lookbheinds don't have good browser support yet. More info: https://caniuse.com/js-regexp-lookbehind
function comparePrefixes(firstPrefix, secondPrefix) {
return prefixToIndexMap[firstPrefix] - prefixToIndexMap[secondPrefix];
}
var PREFIX_SEPARATOR_REGEX = /:(?![^[]*\])/;
var PREFIX_SEPARATOR = ':';
function mergeClassList(classList, configUtils) {
var getClassGroupId = configUtils.getClassGroupId,
getConflictingClassGroupIds = configUtils.getConflictingClassGroupIds;
/**
* Set of classGroupIds in following format:
* `{importantModifier}{variantPrefixes}{classGroupId}`
* @example 'float'
* @example 'hover:focus:bg-color'
* @example '!md:pr'
*/
return {
isPrefixValid: isPrefixValid,
comparePrefixes: comparePrefixes
};
}
var classGroupsInConflict = new Set();
return classList.trim().split(SPLIT_CLASSES_REGEX).map(function (originalClassName) {
var prefixes = originalClassName.split(PREFIX_SEPARATOR_REGEX);
var classNameWithImportantModifier = prefixes.pop();
var hasImportantModifier = classNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);
var className = hasImportantModifier ? classNameWithImportantModifier.substring(1) : classNameWithImportantModifier;
var classGroupId = getClassGroupId(className);
function getPrefixesRecursively(path, prefixPart) {
if (typeof prefixPart === 'string') {
return path.concat(prefixPart);
}
if (!classGroupId) {
return {
isTailwindClass: false,
originalClassName: originalClassName
};
}
return Object.entries(prefixPart).flatMap(function (_ref) {
var pathPart = _ref[0],
nextPrefixParts = _ref[1];
return nextPrefixParts.flatMap(function (nextPrefixPart) {
return getPrefixesRecursively("" + path + pathPart + "-", nextPrefixPart);
var variantPrefix = prefixes.length === 0 ? '' : prefixes.sort().concat('').join(PREFIX_SEPARATOR);
var fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;
return {
isTailwindClass: true,
prefix: fullPrefix,
classGroupId: classGroupId,
originalClassName: originalClassName
};
}).reverse() // Last class in conflict wins, so we need to filter conflicting classes in reverse order.
.filter(function (parsed) {
if (!parsed.isTailwindClass) {
return true;
}
var prefix = parsed.prefix,
classGroupId = parsed.classGroupId;
var classId = prefix + ":" + classGroupId;
if (classGroupsInConflict.has(classId)) {
return false;
}
classGroupsInConflict.add(classId);
getConflictingClassGroupIds(classGroupId).forEach(function (group) {
return classGroupsInConflict.add(prefix + ":" + group);
});
});
return true;
}).reverse().map(function (parsed) {
return parsed.originalClassName;
}).join(' ');
}
function createConfigUtils(config) {
return _extends({
cache: getLruCache(config.cacheSize)
}, createPrefixUtils(config), createClassUtils(config));
function createTailwindMerge() {
var createConfig = [].slice.call(arguments);
var configUtils;
var cacheGet;
var cacheSet;
var functionToCall = initTailwindMerge;
function initTailwindMerge(classList) {
var _createConfig = createConfig,
firstCreateConfig = _createConfig[0],
restCreateConfig = _createConfig.slice(1);
var config = restCreateConfig.reduce(function (previousConfig, createConfigCurrent) {
return createConfigCurrent(previousConfig);
}, firstCreateConfig());
configUtils = createConfigUtils(config);
cacheGet = configUtils.cache.get;
cacheSet = configUtils.cache.set;
functionToCall = tailwindMerge;
return tailwindMerge(classList);
}
function tailwindMerge(classList) {
var cachedResult = cacheGet(classList);
if (cachedResult) {
return cachedResult;
}
var result = mergeClassList(classList, configUtils);
cacheSet(classList, result);
return result;
}
return function callTailwindMerge() {
var classList = '';
var temp; // Credits → https://github.com/lukeed/clsx/blob/v1.1.1/src/index.js
for (var index = 0; index < arguments.length; index += 1) {
if (temp = arguments[index]) {
classList && (classList += ' ');
classList += temp;
}
}
return functionToCall(classList);
};
}

@@ -214,33 +292,80 @@

var SIZES_SIMPLE = ['sm', 'md', 'lg', 'xl', '2xl'];
var SIZES_EXTENDED = ['3xl', '4xl', '5xl', '6xl', '7xl'];
var OVERSCROLL = ['auto', 'contain', 'none'];
var OVERFLOW = ['auto', 'hidden', 'visible', 'scroll'];
var LENGTH = [isLength];
var LENGTH_WITH_AUTO = ['auto', isLength];
var LENGTH_WITH_EMPTY = ['', isLength];
var INTEGER = [isInteger];
var INTEGER_WITH_AUTO = ['auto', isInteger];
var ANY = [isAny];
var POSITIONS = ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];
var ROUNDED = ['none', ''].concat(SIZES_SIMPLE, ['3xl', 'full', isCustomLength]);
var BORDER_STYLES = ['solid', 'dashed', 'dotted', 'double', 'none'];
var BLEND_MODES = [{
blend: ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity']
}];
var ALIGN = ['start', 'end', 'center', 'between', 'around', 'evenly'];
var ZERO_AND_EMPTY = ['', '0'];
var PSEUDO_VARIANTS = [// Positional
'first', 'last', 'only', 'odd', 'even', 'first-of-type', 'last-of-type', 'only-of-type', // State
'visited', 'target', // Forms
'default', 'checked', 'indeterminate', 'placeholder-shown', 'autofill', 'required', 'valid', 'invalid', 'in-range', 'out-of-range', 'read-only', // Content
'empty', // Interactive
'focus-within', 'hover', 'focus', 'focus-visible', 'active', 'disabled'];
var validators = {
__proto__: null,
isLength: isLength,
isCustomLength: isCustomLength,
isInteger: isInteger,
isCustomValue: isCustomValue,
isAny: isAny
};
function getDefaultConfig() {
var getSizesSimple = function getSizesSimple() {
return ['sm', 'md', 'lg', 'xl', '2xl'];
};
var getSizesExtended = function getSizesExtended() {
return ['3xl', '4xl', '5xl', '6xl', '7xl'];
};
var getOverscroll = function getOverscroll() {
return ['auto', 'contain', 'none'];
};
var getOverflow = function getOverflow() {
return ['auto', 'hidden', 'visible', 'scroll'];
};
var getLength = function getLength() {
return [isLength];
};
var getLengthWithAuto = function getLengthWithAuto() {
return ['auto', isLength];
};
var getLengthWithEmpty = function getLengthWithEmpty() {
return ['', isLength];
};
var getInteger = function getInteger() {
return [isInteger];
};
var getIntegerWithAuto = function getIntegerWithAuto() {
return ['auto', isInteger];
};
var getAny = function getAny() {
return [isAny];
};
var getPositions = function getPositions() {
return ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];
};
var getRounded = function getRounded() {
return ['none', ''].concat(getSizesSimple(), ['3xl', 'full', isCustomLength]);
};
var getBorderStyles = function getBorderStyles() {
return ['solid', 'dashed', 'dotted', 'double', 'none'];
};
var getBlendModes = function getBlendModes() {
return [{
blend: ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity']
}];
};
var getAlign = function getAlign() {
return ['start', 'end', 'center', 'between', 'around', 'evenly'];
};
var getZeroAndEmpty = function getZeroAndEmpty() {
return ['', '0'];
};
return {
cacheSize: 500,
prefixes: [].concat(SIZES_SIMPLE, ['dark', 'motion-safe', 'motion-reduce', 'before', 'after', 'first-letter', 'first-line', 'selection', 'marker'], PSEUDO_VARIANTS, [{
group: PSEUDO_VARIANTS,
peer: PSEUDO_VARIANTS
}]),
classGroups: {

@@ -312,3 +437,3 @@ // Layout

'object-position': [{
object: POSITIONS
object: getPositions()
}],

@@ -321,3 +446,3 @@

overflow: [{
overflow: OVERFLOW
overflow: getOverflow()
}],

@@ -330,3 +455,3 @@

'overflow-x': [{
'overflow-x': OVERFLOW
'overflow-x': getOverflow()
}],

@@ -339,3 +464,3 @@

'overflow-y': [{
'overflow-y': OVERFLOW
'overflow-y': getOverflow()
}],

@@ -348,3 +473,3 @@

overscroll: [{
overscroll: OVERSCROLL
overscroll: getOverscroll()
}],

@@ -357,3 +482,3 @@

'overscroll-x': [{
'overscroll-x': OVERSCROLL
'overscroll-x': getOverscroll()
}],

@@ -366,3 +491,3 @@

'overscroll-y': [{
'overscroll-y': OVERSCROLL
'overscroll-y': getOverscroll()
}],

@@ -381,3 +506,3 @@

inset: [{
inset: LENGTH_WITH_AUTO
inset: getLengthWithAuto()
}],

@@ -390,3 +515,3 @@

'inset-x': [{
'inset-x': LENGTH_WITH_AUTO
'inset-x': getLengthWithAuto()
}],

@@ -399,3 +524,3 @@

'inset-y': [{
'inset-y': LENGTH_WITH_AUTO
'inset-y': getLengthWithAuto()
}],

@@ -408,3 +533,3 @@

top: [{
top: LENGTH_WITH_AUTO
top: getLengthWithAuto()
}],

@@ -417,3 +542,3 @@

right: [{
right: LENGTH_WITH_AUTO
right: getLengthWithAuto()
}],

@@ -426,3 +551,3 @@

bottom: [{
bottom: LENGTH_WITH_AUTO
bottom: getLengthWithAuto()
}],

@@ -435,3 +560,3 @@

left: [{
left: LENGTH_WITH_AUTO
left: getLengthWithAuto()
}],

@@ -450,3 +575,3 @@

z: [{
z: LENGTH
z: getLength()
}],

@@ -508,3 +633,3 @@ // Flexbox and Grid

'grid-cols': [{
'grid-cols': ANY
'grid-cols': getAny()
}],

@@ -518,3 +643,3 @@

col: ['auto', {
span: INTEGER
span: getInteger()
}]

@@ -528,3 +653,3 @@ }],

'col-start': [{
'col-start': INTEGER_WITH_AUTO
'col-start': getIntegerWithAuto()
}],

@@ -537,3 +662,3 @@

'col-end': [{
'col-end': INTEGER_WITH_AUTO
'col-end': getIntegerWithAuto()
}],

@@ -546,3 +671,3 @@

'grid-rows': [{
'grid-rows': ANY
'grid-rows': getAny()
}],

@@ -556,3 +681,3 @@

row: ['auto', {
span: INTEGER
span: getInteger()
}]

@@ -566,3 +691,3 @@ }],

'row-start': [{
'row-start': INTEGER_WITH_AUTO
'row-start': getIntegerWithAuto()
}],

@@ -575,3 +700,3 @@

'row-end': [{
'row-end': INTEGER_WITH_AUTO
'row-end': getIntegerWithAuto()
}],

@@ -608,3 +733,3 @@

gap: [{
gap: LENGTH
gap: getLength()
}],

@@ -617,3 +742,3 @@

'gap-x': [{
'gap-x': LENGTH
'gap-x': getLength()
}],

@@ -626,3 +751,3 @@

'gap-y': [{
'gap-y': LENGTH
'gap-y': getLength()
}],

@@ -635,3 +760,3 @@

'justify-content': [{
justify: ALIGN
justify: getAlign()
}],

@@ -660,3 +785,3 @@

'align-content': [{
content: ALIGN
content: getAlign()
}],

@@ -685,3 +810,3 @@

'place-content': [{
'place-content': [].concat(ALIGN, ['stretch'])
'place-content': [].concat(getAlign(), ['stretch'])
}],

@@ -711,3 +836,3 @@

p: [{
p: LENGTH
p: getLength()
}],

@@ -720,3 +845,3 @@

px: [{
px: LENGTH
px: getLength()
}],

@@ -729,3 +854,3 @@

py: [{
py: LENGTH
py: getLength()
}],

@@ -738,3 +863,3 @@

pt: [{
pt: LENGTH
pt: getLength()
}],

@@ -747,3 +872,3 @@

pr: [{
pr: LENGTH
pr: getLength()
}],

@@ -756,3 +881,3 @@

pb: [{
pb: LENGTH
pb: getLength()
}],

@@ -765,3 +890,3 @@

pl: [{
pl: LENGTH
pl: getLength()
}],

@@ -774,3 +899,3 @@

m: [{
m: LENGTH_WITH_AUTO
m: getLengthWithAuto()
}],

@@ -783,3 +908,3 @@

mx: [{
mx: LENGTH_WITH_AUTO
mx: getLengthWithAuto()
}],

@@ -792,3 +917,3 @@

my: [{
my: LENGTH_WITH_AUTO
my: getLengthWithAuto()
}],

@@ -801,3 +926,3 @@

mt: [{
mt: LENGTH_WITH_AUTO
mt: getLengthWithAuto()
}],

@@ -810,3 +935,3 @@

mr: [{
mr: LENGTH_WITH_AUTO
mr: getLengthWithAuto()
}],

@@ -819,3 +944,3 @@

mb: [{
mb: LENGTH_WITH_AUTO
mb: getLengthWithAuto()
}],

@@ -828,3 +953,3 @@

ml: [{
ml: LENGTH_WITH_AUTO
ml: getLengthWithAuto()
}],

@@ -837,3 +962,3 @@

'space-x': [{
'space-x': LENGTH
'space-x': getLength()
}],

@@ -852,3 +977,3 @@

'space-y': [{
'space-y': LENGTH
'space-y': getLength()
}],

@@ -884,4 +1009,4 @@

'max-w': [{
'max-w': ['0', 'none'].concat(SIZES_SIMPLE, SIZES_EXTENDED, ['full', 'min', 'max', 'prose', {
screen: SIZES_SIMPLE
'max-w': ['0', 'none'].concat(getSizesSimple(), getSizesExtended(), ['full', 'min', 'max', 'prose', {
screen: getSizesSimple()
}])

@@ -895,3 +1020,3 @@ }],

h: [{
h: LENGTH_WITH_AUTO
h: getLengthWithAuto()
}],

@@ -912,3 +1037,3 @@

'max-h': [{
'max-h': LENGTH
'max-h': getLength()
}],

@@ -922,3 +1047,3 @@ // Typography

'font-family': [{
font: ANY
font: getAny()
}],

@@ -931,3 +1056,3 @@

'font-size': [{
text: ['xs'].concat(SIZES_SIMPLE, ['base'], SIZES_EXTENDED, ['8xl', '9xl', isCustomLength])
text: ['xs'].concat(getSizesSimple(), ['base'], getSizesExtended(), ['8xl', '9xl', isCustomLength])
}],

@@ -1028,3 +1153,3 @@

'placeholder-color': [{
placeholder: ANY
placeholder: getAny()
}],

@@ -1037,3 +1162,3 @@

'placeholder-opacity': [{
'placeholder-opacity': INTEGER
'placeholder-opacity': getInteger()
}],

@@ -1054,3 +1179,3 @@

'text-color': [{
text: ANY
text: getAny()
}],

@@ -1063,3 +1188,3 @@

'text-opacity': [{
'text-opacity': INTEGER
'text-opacity': getInteger()
}],

@@ -1131,3 +1256,3 @@

'bg-opacity': [{
'bg-opacity': INTEGER
'bg-opacity': getInteger()
}],

@@ -1148,3 +1273,3 @@

'bg-position': [{
bg: POSITIONS
bg: getPositions()
}],

@@ -1185,3 +1310,3 @@

'bg-blend': [{
bg: BLEND_MODES
bg: getBlendModes()
}],

@@ -1194,3 +1319,3 @@

'bg-color': [{
bg: ANY
bg: getAny()
}],

@@ -1203,3 +1328,3 @@

'gradient-from': [{
from: ANY
from: getAny()
}],

@@ -1212,3 +1337,3 @@

'gradient-via': [{
via: ANY
via: getAny()
}],

@@ -1221,3 +1346,3 @@

'gradient-to': [{
to: ANY
to: getAny()
}],

@@ -1231,3 +1356,3 @@ // Borders

rounded: [{
rounded: ROUNDED
rounded: getRounded()
}],

@@ -1240,3 +1365,3 @@

'rounded-t': [{
'rounded-t': ROUNDED
'rounded-t': getRounded()
}],

@@ -1249,3 +1374,3 @@

'rounded-r': [{
'rounded-r': ROUNDED
'rounded-r': getRounded()
}],

@@ -1258,3 +1383,3 @@

'rounded-b': [{
'rounded-b': ROUNDED
'rounded-b': getRounded()
}],

@@ -1267,3 +1392,3 @@

'rounded-l': [{
'rounded-l': ROUNDED
'rounded-l': getRounded()
}],

@@ -1276,3 +1401,3 @@

'rounded-tl': [{
'rounded-tl': ROUNDED
'rounded-tl': getRounded()
}],

@@ -1285,3 +1410,3 @@

'rounded-tr': [{
'rounded-tr': ROUNDED
'rounded-tr': getRounded()
}],

@@ -1294,3 +1419,3 @@

'rounded-br': [{
'rounded-br': ROUNDED
'rounded-br': getRounded()
}],

@@ -1303,3 +1428,3 @@

'rounded-bl': [{
'rounded-bl': ROUNDED
'rounded-bl': getRounded()
}],

@@ -1312,3 +1437,3 @@

'border-w': [{
border: LENGTH_WITH_EMPTY
border: getLengthWithEmpty()
}],

@@ -1321,3 +1446,3 @@

'border-w-t': [{
'border-t': LENGTH_WITH_EMPTY
'border-t': getLengthWithEmpty()
}],

@@ -1330,3 +1455,3 @@

'border-w-r': [{
'border-r': LENGTH_WITH_EMPTY
'border-r': getLengthWithEmpty()
}],

@@ -1339,3 +1464,3 @@

'border-w-b': [{
'border-b': LENGTH_WITH_EMPTY
'border-b': getLengthWithEmpty()
}],

@@ -1348,3 +1473,3 @@

'border-w-l': [{
'border-l': LENGTH_WITH_EMPTY
'border-l': getLengthWithEmpty()
}],

@@ -1357,3 +1482,3 @@

'border-opacity': [{
'border-opacity': INTEGER
'border-opacity': getInteger()
}],

@@ -1366,3 +1491,3 @@

'border-style': [{
border: BORDER_STYLES
border: getBorderStyles()
}],

@@ -1375,3 +1500,3 @@

'divide-x': [{
'divide-x': LENGTH_WITH_EMPTY
'divide-x': getLengthWithEmpty()
}],

@@ -1390,3 +1515,3 @@

'divide-y': [{
'divide-y': LENGTH_WITH_EMPTY
'divide-y': getLengthWithEmpty()
}],

@@ -1405,3 +1530,3 @@

'divide-opacity': [{
'divide-opacity': INTEGER
'divide-opacity': getInteger()
}],

@@ -1414,3 +1539,3 @@

'divide-style': [{
divide: BORDER_STYLES
divide: getBorderStyles()
}],

@@ -1423,3 +1548,3 @@

'border-color': [{
border: ANY
border: getAny()
}],

@@ -1432,3 +1557,3 @@

'border-color-t': [{
'border-t': ANY
'border-t': getAny()
}],

@@ -1441,3 +1566,3 @@

'border-color-r': [{
'border-r': ANY
'border-r': getAny()
}],

@@ -1450,3 +1575,3 @@

'border-color-b': [{
'border-b': ANY
'border-b': getAny()
}],

@@ -1459,3 +1584,3 @@

'border-color-l': [{
'border-l': ANY
'border-l': getAny()
}],

@@ -1468,3 +1593,3 @@

'divide-color': [{
divide: ANY
divide: getAny()
}],

@@ -1477,3 +1602,3 @@

'ring-w': [{
ring: LENGTH_WITH_EMPTY
ring: getLengthWithEmpty()
}],

@@ -1492,3 +1617,3 @@

'ring-color': [{
ring: ANY
ring: getAny()
}],

@@ -1501,3 +1626,3 @@

'ring-opacity': [{
'ring-opacity': INTEGER
'ring-opacity': getInteger()
}],

@@ -1510,3 +1635,3 @@

'ring-offset-w': [{
'ring-offset': LENGTH
'ring-offset': getLength()
}],

@@ -1519,3 +1644,3 @@

'ring-offset-color': [{
'ring-offset': ANY
'ring-offset': getAny()
}],

@@ -1529,3 +1654,3 @@ // Effects

shadow: [{
shadow: [''].concat(SIZES_SIMPLE, ['inner', 'none'])
shadow: [''].concat(getSizesSimple(), ['inner', 'none'])
}],

@@ -1538,3 +1663,3 @@

opacity: [{
opacity: INTEGER
opacity: getInteger()
}],

@@ -1547,3 +1672,3 @@

'mix-blend': [{
'mix-blend': BLEND_MODES
'mix-blend': getBlendModes()
}],

@@ -1565,3 +1690,3 @@ // Filters

blur: [{
blur: ['none', ''].concat(SIZES_SIMPLE, ['3xl', isCustomLength])
blur: ['none', ''].concat(getSizesSimple(), ['3xl', isCustomLength])
}],

@@ -1574,3 +1699,3 @@

brightness: [{
brightness: INTEGER
brightness: getInteger()
}],

@@ -1583,3 +1708,3 @@

contrast: [{
contrast: INTEGER
contrast: getInteger()
}],

@@ -1592,3 +1717,3 @@

'drop-shadow': [{
'drop-shadow': [''].concat(SIZES_SIMPLE, ['none'])
'drop-shadow': [''].concat(getSizesSimple(), ['none'])
}],

@@ -1601,3 +1726,3 @@

grayscale: [{
grayscale: ZERO_AND_EMPTY
grayscale: getZeroAndEmpty()
}],

@@ -1610,3 +1735,3 @@

'hue-rotate': [{
'hue-rotate': INTEGER
'hue-rotate': getInteger()
}],

@@ -1619,3 +1744,3 @@

invert: [{
invert: ZERO_AND_EMPTY
invert: getZeroAndEmpty()
}],

@@ -1628,3 +1753,3 @@

saturate: [{
saturate: INTEGER
saturate: getInteger()
}],

@@ -1637,3 +1762,3 @@

sepia: [{
sepia: ZERO_AND_EMPTY
sepia: getZeroAndEmpty()
}],

@@ -1654,3 +1779,3 @@

'backdrop-blur': [{
'backdrop-blur': ['none', ''].concat(SIZES_SIMPLE, ['3xl'])
'backdrop-blur': ['none', ''].concat(getSizesSimple(), ['3xl'])
}],

@@ -1663,3 +1788,3 @@

'backdrop-brightness': [{
'backdrop-brightness': INTEGER
'backdrop-brightness': getInteger()
}],

@@ -1672,3 +1797,3 @@

'backdrop-contrast': [{
'backdrop-contrast': INTEGER
'backdrop-contrast': getInteger()
}],

@@ -1681,3 +1806,3 @@

'backdrop-grayscale': [{
'backdrop-grayscale': ZERO_AND_EMPTY
'backdrop-grayscale': getZeroAndEmpty()
}],

@@ -1690,3 +1815,3 @@

'backdrop-hue-rotate': [{
'backdrop-hue-rotate': INTEGER
'backdrop-hue-rotate': getInteger()
}],

@@ -1699,3 +1824,3 @@

'backdrop-invert': [{
'backdrop-invert': ZERO_AND_EMPTY
'backdrop-invert': getZeroAndEmpty()
}],

@@ -1708,3 +1833,3 @@

'backdrop-opacity': [{
'backdrop-opacity': INTEGER
'backdrop-opacity': getInteger()
}],

@@ -1717,3 +1842,3 @@

'backdrop-saturate': [{
'backdrop-saturate': INTEGER
'backdrop-saturate': getInteger()
}],

@@ -1726,3 +1851,3 @@

'backdrop-sepia': [{
'backdrop-sepia': ZERO_AND_EMPTY
'backdrop-sepia': getZeroAndEmpty()
}],

@@ -1761,3 +1886,3 @@ // Tables

duration: [{
duration: INTEGER
duration: getInteger()
}],

@@ -1778,3 +1903,3 @@

delay: [{
delay: INTEGER
delay: getInteger()
}],

@@ -1812,3 +1937,3 @@

scale: [{
scale: INTEGER
scale: getInteger()
}],

@@ -1821,3 +1946,3 @@

'scale-x': [{
'scale-x': INTEGER
'scale-x': getInteger()
}],

@@ -1830,3 +1955,3 @@

'scale-y': [{
'scale-y': INTEGER
'scale-y': getInteger()
}],

@@ -1839,3 +1964,3 @@

rotate: [{
rotate: INTEGER
rotate: getInteger()
}],

@@ -1848,3 +1973,3 @@

'translate-x': [{
'translate-x': LENGTH
'translate-x': getLength()
}],

@@ -1857,3 +1982,3 @@

'translate-y': [{
'translate-y': LENGTH
'translate-y': getLength()
}],

@@ -1866,3 +1991,3 @@

'skew-x': [{
'skew-x': INTEGER
'skew-x': getInteger()
}],

@@ -1875,3 +2000,3 @@

'skew-y': [{
'skew-y': INTEGER
'skew-y': getInteger()
}],

@@ -1946,3 +2071,3 @@ // Interactivity

'stroke-w': [{
stroke: LENGTH
stroke: getLength()
}],

@@ -1971,3 +2096,3 @@ // Accessibility

'caret-color': [{
caret: ANY
caret: getAny()
}]

@@ -2009,115 +2134,49 @@ },

var SPLIT_CLASSES_REGEX = /\s+/;
var IMPORTANT_MODIFIER = '!'; // Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`
// I'd prefer to use a negative lookbehind for all supported labels, but lookbheinds don't have good browser support yet. More info: https://caniuse.com/js-regexp-lookbehind
/**
* @param baseConfig Config where other config will be merged into. This object will be mutated.
* @param configExtension Partial config to merge into the `baseConfig`.
*/
function mergeConfigs(baseConfig, configExtension) {
for (var key in configExtension) {
mergePropertyRecursively(baseConfig, key, configExtension[key]);
}
var PREFIX_SEPARATOR_REGEX = /:(?![^[]*\])/;
var PREFIX_SEPARATOR = ':';
function mergeClassList(classList, configUtils) {
var isPrefixValid = configUtils.isPrefixValid,
getClassGroupId = configUtils.getClassGroupId,
comparePrefixes = configUtils.comparePrefixes,
getConflictingClassGroupIds = configUtils.getConflictingClassGroupIds;
/**
* Set of classGroupIds in following format:
* `{importantModifier}{variantPrefixes}{classGroupId}`
* @example ':standaloneClasses.1'
* @example 'hover:focus:dynamicClasses.bg.2'
* @example '!md:dynamicClasses.bg.0'
*/
var classGroupsInConflict = new Set();
return classList.trim().split(SPLIT_CLASSES_REGEX).map(function (originalClassName) {
var prefixes = originalClassName.split(PREFIX_SEPARATOR_REGEX);
var classNameWithImportantModifier = prefixes.pop();
var hasImportantModifier = classNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);
var className = hasImportantModifier ? classNameWithImportantModifier.substring(1) : classNameWithImportantModifier;
var arePrefixesValid = prefixes.every(isPrefixValid);
var classGroupId = arePrefixesValid ? getClassGroupId(className) : undefined;
if (!classGroupId) {
return {
isTailwindClass: false,
originalClassName: originalClassName
};
}
var variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(comparePrefixes).concat('').join(PREFIX_SEPARATOR);
var fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;
return {
isTailwindClass: true,
prefix: fullPrefix,
classGroupId: classGroupId,
originalClassName: originalClassName
};
}).reverse() // Last class in conflict wins, so we need to filter conflicting classes in reverse order.
.filter(function (parsed) {
if (!parsed.isTailwindClass) {
return true;
}
var prefix = parsed.prefix,
classGroupId = parsed.classGroupId;
var classId = prefix + ":" + classGroupId;
if (classGroupsInConflict.has(classId)) {
return false;
}
classGroupsInConflict.add(classId);
getConflictingClassGroupIds(classGroupId).forEach(function (group) {
return classGroupsInConflict.add(prefix + ":" + group);
});
return true;
}).reverse().map(function (parsed) {
return parsed.originalClassName;
}).join(' ');
return baseConfig;
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
var overrideTypes = new Set(['string', 'number', 'boolean']);
function createTailwindMerge(createConfig) {
var configUtils;
var cacheGet;
var cacheSet;
var functionToCall = initTailwindMerge;
function mergePropertyRecursively(baseObject, mergeKey, mergeValue) {
if (!hasOwnProperty.call(baseObject, mergeKey) || overrideTypes.has(typeof mergeValue) || mergeValue === null) {
baseObject[mergeKey] = mergeValue;
return;
}
function initTailwindMerge(classList) {
configUtils = createConfigUtils(createConfig(getDefaultConfig));
cacheGet = configUtils.cache.get;
cacheSet = configUtils.cache.set;
functionToCall = tailwindMerge;
return tailwindMerge(classList);
if (Array.isArray(mergeValue) && Array.isArray(baseObject[mergeKey])) {
baseObject[mergeKey] = baseObject[mergeKey].concat(mergeValue);
return;
}
function tailwindMerge(classList) {
var cachedResult = cacheGet(classList);
if (typeof mergeValue === 'object' && typeof baseObject[mergeKey] === 'object') {
if (baseObject[mergeKey] === null) {
baseObject[mergeKey] = mergeValue;
return;
}
if (cachedResult) {
return cachedResult;
for (var nextKey in mergeValue) {
mergePropertyRecursively(baseObject[mergeKey], nextKey, mergeValue[nextKey]);
}
var result = mergeClassList(classList, configUtils);
cacheSet(classList, result);
return result;
}
}
return function callTailwindMerge() {
var classList = '';
var temp; // Credits → https://github.com/lukeed/clsx/blob/v1.1.1/src/index.js
for (var index = 0; index < arguments.length; index += 1) {
if (temp = arguments[index]) {
classList && (classList += ' ');
classList += temp;
}
}
return functionToCall(classList);
};
function extendTailwindMerge(configExtension) {
var createConfig = [].slice.call(arguments, 1);
return typeof configExtension === 'function' ? createTailwindMerge.apply(void 0, [getDefaultConfig, configExtension].concat(createConfig)) : createTailwindMerge.apply(void 0, [function () {
return mergeConfigs(getDefaultConfig(), configExtension);
}].concat(createConfig));
}
var twMerge = createTailwindMerge(function (defaultConfig) {
return defaultConfig();
});
var twMerge = createTailwindMerge(getDefaultConfig);
export { createTailwindMerge, twMerge };
export { createTailwindMerge, extendTailwindMerge, getDefaultConfig, mergeConfigs, twMerge, validators };
//# sourceMappingURL=index.module.js.map

@@ -6,5 +6,3 @@ import { Config } from './types';

getConflictingClassGroupIds: (classGroupId: string) => readonly string[];
isPrefixValid: (maybePrefix: string) => boolean;
comparePrefixes: (firstPrefix: string, secondPrefix: string) => number;
cache: import("./lru-cache").LruCache<string>;
};

@@ -1,8 +0,4 @@

import { isAny, isCustomLength, isCustomValue, isInteger, isLength } from './config-validators';
import { isAny, isCustomLength, isCustomValue, isInteger, isLength } from './validators';
export declare function getDefaultConfig(): {
readonly cacheSize: 500;
readonly prefixes: readonly ["sm", "md", "lg", "xl", "2xl", "dark", "motion-safe", "motion-reduce", "before", "after", "first-letter", "first-line", "selection", "marker", "first", "last", "only", "odd", "even", "first-of-type", "last-of-type", "only-of-type", "visited", "target", "default", "checked", "indeterminate", "placeholder-shown", "autofill", "required", "valid", "invalid", "in-range", "out-of-range", "read-only", "empty", "focus-within", "hover", "focus", "focus-visible", "active", "disabled", {
readonly group: readonly ["first", "last", "only", "odd", "even", "first-of-type", "last-of-type", "only-of-type", "visited", "target", "default", "checked", "indeterminate", "placeholder-shown", "autofill", "required", "valid", "invalid", "in-range", "out-of-range", "read-only", "empty", "focus-within", "hover", "focus", "focus-visible", "active", "disabled"];
readonly peer: readonly ["first", "last", "only", "odd", "even", "first-of-type", "last-of-type", "only-of-type", "visited", "target", "default", "checked", "indeterminate", "placeholder-shown", "autofill", "required", "valid", "invalid", "in-range", "out-of-range", "read-only", "empty", "focus-within", "hover", "focus", "focus-visible", "active", "disabled"];
}];
readonly classGroups: {

@@ -9,0 +5,0 @@ /**

@@ -1,3 +0,8 @@

import { createTailwindMerge } from './tailwind-merge';
import { createTailwindMerge } from './create-tailwind-merge';
import { getDefaultConfig } from './default-config';
export declare const twMerge: (...classLists: (string | false | null | undefined)[]) => string;
export { createTailwindMerge };
export { createTailwindMerge, getDefaultConfig };
export { extendTailwindMerge } from './extend-tailwind-merge';
export type { Config } from './types';
export * as validators from './validators';
export { mergeConfigs } from './merge-configs';
export interface Config {
/**
* Prefixes which can be prepended to Tailwind CSS classes
* @example ['hover', 'focus']
*/
prefixes: readonly Prefix[];
/**
* Integer indicating size of LRU cache used for memoizing results.

@@ -32,3 +27,2 @@ * - Cache might be up to twice as big as `cacheSize`

}
export declare type Prefix = string | Record<string, readonly Prefix[]>;
export declare type ClassGroup = readonly ClassDefinition[];

@@ -35,0 +29,0 @@ declare type ClassDefinition = string | ClassValidator | ClassObject;

{
"name": "tailwind-merge",
"version": "0.7.1",
"version": "0.8.0",
"description": "Merge Tailwind CSS classes without style conflicts",

@@ -54,17 +54,17 @@ "keywords": [

"devDependencies": {
"@types/jest": "^26.0.24",
"@typescript-eslint/eslint-plugin": "^4.28.3",
"@typescript-eslint/parser": "^4.28.3",
"eslint": "^7.30.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jest": "^24.3.6",
"fp-ts": "^2.10.5",
"jest": "^27.0.6",
"microbundle": "^0.13.3",
"package-build-stats": "^7.2.4",
"@types/jest": "^27.0.2",
"@typescript-eslint/eslint-plugin": "^5.1.0",
"@typescript-eslint/parser": "^5.1.0",
"eslint": "^8.0.1",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-jest": "^25.2.2",
"fp-ts": "^2.11.5",
"jest": "^27.3.1",
"microbundle": "^0.14.1",
"package-build-stats": "^7.3.5",
"prettier": "^2.3.2",
"ts-jest": "^27.0.3",
"typescript": "^4.4.3",
"ts-jest": "^27.0.7",
"typescript": "^4.4.4",
"zx": "^4.0.0"
}
}
<div align="center">
<br />
<a href="https://github.com/dcastil/tailwind-merge">
<!-- AUTOGENERATED START logo-image --><img src="https://github.com/dcastil/tailwind-merge/raw/v0.7.1/assets/logo.svg" alt="tailwind-merge" width="221px" /><!-- AUTOGENERATED END -->
<!-- AUTOGENERATED START logo-image --><img src="https://github.com/dcastil/tailwind-merge/raw/v0.8.0/assets/logo.svg" alt="tailwind-merge" width="221px" /><!-- AUTOGENERATED END -->
</a>

@@ -22,3 +22,3 @@ </div>

- Fully typed
- [<!-- AUTOGENERATED START package-gzip-size -->4.8 kB<!-- AUTOGENERATED END --> minified + gzipped](https://bundlephobia.com/package/tailwind-merge) (<!-- AUTOGENERATED START package-composition -->96.3% self, 3.7% hashlru<!-- AUTOGENERATED END -->)
- [<!-- AUTOGENERATED START package-gzip-size -->4.8 kB<!-- AUTOGENERATED END --> minified + gzipped](https://bundlephobia.com/package/tailwind-merge) (<!-- AUTOGENERATED START package-composition -->96.5% self, 3.5% hashlru<!-- AUTOGENERATED END -->)

@@ -33,3 +33,3 @@ ## Early development

If you use Tailwind with a component-based UI renderer like [React](https://reactjs.org) or [Vue](https://vuejs.org), you're probably familiar with this situation:
If you use Tailwind with a component-based UI renderer like [React](https://reactjs.org) or [Vue](https://vuejs.org), you're probably familiar with the situation that you want to change some styles of a component, but only in one place.

@@ -72,3 +72,3 @@ ```jsx

- Results get cached by default, so you don't need to worry about wasteful rerenders. The library uses a [LRU cache](<https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)>) which stores up to 500 different results. The cache size can be modified or opt-out of by using [`createTailwindMerge()`](#createtailwindmerge).
- Results get cached by default, so you don't need to worry about wasteful re-renders. The library uses a [LRU cache](<https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)>) which stores up to 500 different results. The cache size can be modified or opt-out of by using [`extendTailwindMerge()`](#extendtailwindmerge).
- Expensive computations happen upfront so that `twMerge()` calls without a cache hit stay fast.

@@ -154,12 +154,77 @@ - These computations are called lazily on the first call to `twMerge()` to prevent it from impacting app startup performance if it isn't used initially.

If some of these points don't apply to you, it makes sense to test whether `twMerge()` still works as intended with your custom classes. Otherwise, you can create your own custom merge function with [`createTailwindMerge()`](#createtailwindmerge).
If some of these points don't apply to you, it makes sense to test whether `twMerge()` still works as intended with your custom classes. Otherwise, you can create your own custom merge function with [`extendTailwindMerge()`](#extendtailwindmerge).
### `createTailwindMerge`
### `getDefaultConfig`
```ts
function createTailwindMerge(createConfig: CreateConfig): TailwindMerge
function getDefaultConfig(): Config
```
Function which returns the default config used by tailwind-merge. In fact, `twMerge` is just built like this:
```ts
const twMerge = createTailwindMerge(getDefaultConfig)
```
### `extendTailwindMerge`
```ts
function extendTailwindMerge(
configExtension: Partial<Config>,
...createConfig: Array<(config: Config) => Config>
): TailwindMerge
function extendTailwindMerge(...createConfig: Array<(config: Config) => Config>): TailwindMerge
```
Function to create merge function with custom config.
You provide it a `configExtension` object which gets [merged](#mergeconfigs) with the default config.
```ts
const customTwMerge = extendTailwindMerge({
cacheSize: 0, // ← Disabling cache
prefixes: [
'my-custom-prefix', // ← Adding custom prefix
],
// ↓ Here you define class groups
classGroups: {
// ↓ The `foo` key here is the class group ID
// ↓ Creates group of classes which have conflicting styles
// Classes here: foo, foo-2, bar-baz, bar-baz-1, bar-baz-2
foo: ['foo', 'foo-2', { 'bar-baz': ['', '1', '2'] }],
// ↓ Functions can also be used to match classes.
// Classes here: qux-auto, qux-1000, qux-1001, …
bar: [{ qux: ['auto', (value) => Number(value) >= 1000] }],
},
// ↓ Here you can define additional conflicts across different groups
conflictingClassGroups: {
// ↓ ID of class group which creates a conflict with …
// ↓ … classes from groups with these IDs
foo: ['bar'],
},
})
```
Additionally you can pass multiple `createConfig` functions (more to that in [`createTailwindMerge()`](#createtailwindmerge)) which is convenient if you want to combine your config with third-party plugins.
```ts
const customTwMerge = extendTailwindMerge({ … }, withSomePlugin)
```
If you only use plugins, you can omit the `configExtension` object as well.
```ts
const customTwMerge = extendTailwindMerge(withSomePlugin)
```
### `createTailwindMerge`
```ts
function createTailwindMerge(
...createConfig: [() => Config, ...Array<(config: Config) => Config>]
): TailwindMerge
```
Function to create merge function with custom config. Here you get more control over the config than in [`extendTailwindMerge()`](#extendtailwindmerge).
You need to provide a function which resolves to the config tailwind-merge should use for the new merge function. You can either extend from the default config or create a new one from scratch.

@@ -170,26 +235,15 @@

// `customTwMerge()` gets called the first time.
const customTwMerge = createTailwindMerge((getDefaultConfig) => {
const customTwMerge = createTailwindMerge(() => {
const defaultConfig = getDefaultConfig()
return {
cacheSize: 0, // ← Disabling cache
prefixes: [
...defaultConfig.prefixes,
'my-custom-prefix', // ← Adding custom prefix
],
// ↓ Here you define class groups
cacheSize: 0,
prefixes: [...defaultConfig.prefixes, 'my-custom-prefix'],
classGroups: {
...defaultConfig.classGroups,
// ↓ The `foo` key here is the class group ID
// ↓ Creates group of classes which have conflicting styles
// Classes here: foo, foo-2, bar-baz, bar-baz-1, bar-baz-2
foo: ['foo', 'foo-2', { 'bar-baz': ['', '1', '2'] }],
// ↓ Another group with classes qux-auto, qux-1000, qux-1001, …
bar: [{ qux: ['auto', (value) => Number(value) >= 1000] }],
},
// ↓ Here you can define additional conflicts across different groups
conflictingClassGroups: {
...defaultConfig.conflictingClassGroups,
// ↓ ID of class group which creates a conflict with …
// ↓ … classes from groups with these IDs
foo: ['bar'],

@@ -201,2 +255,103 @@ },

Same as in [`extendTailwindMerge()`](#extendtailwindmerge) you can use multiple `createConfig` functions which is convenient if you want to combine your config with third-party plugins. Just keep in mind that the first `createConfig` function does not get passed any arguments, whereas the subsequent functions get each passed the config from the previous function.
```ts
const customTwMerge = createTailwindMerge(getDefaultConfig, withSomePlugin, (config) => ({
// ↓ Config returned by `withSomePlugin`
...config,
classGroups: {
...config.classGroups,
mySpecialClassGroup: [{ special: ['1', '2'] }],
},
}))
```
But don't merge configs like that. Use [`mergeConfigs()`](#mergeconfigs) instead.
### `mergeConfigs`
```ts
function mergeConfigs(baseConfig: Config, configExtension: Partial<Config>): Config
```
Helper function to merge multiple config objects. Objects are merged, arrays are concatenated, scalar values are overriden and `undefined` does nothing. The function assumes that both parameters are tailwind-merge config objects and shouldn't be used as a generic merge function.
```ts
const customTwMerge = createTailwindMerge(getDefaultConfig, (config) =>
mergeConfigs(config, {
classGroups: {
// ↓ Adding new class group
mySpecialClassGroup: [{ special: ['1', '2'] }],
// ↓ Adding value to existing class group
animate: ['animate-magic'],
},
})
)
```
### `validators`
```ts
interface Validators {
isLength(classPart: string): boolean
isCustomLength(classPart: string): boolean
isInteger(classPart: string): boolean
isCustomValue(classPart: string): boolean
isAny(classPart: string): boolean
}
```
An object containing all the validators used in tailwind-merge. They are useful if you want to use a custom config with [`extendTailwindMerge()`](#extendtailwindmerge) or [`createTailwindMerge()`](#createtailwindmerge). E.g. the `classGroup` for padding is defined as
```ts
const paddingClassGroup = [{ p: [validators.isLength] }]
```
Here is a brief summary for each validator:
- `isLength()` checks whether a class part is a number (`3`, `1.5`), a fraction (`3/4`), a custom length (`[3%]`, `[4px]`, `[length:var(--my-var)]`), or one of the strings `px`, `full` or `screen`.
- `isCustomLength()` checks for custom length values (`[3%]`, `[4px]`, `[length:var(--my-var)]`).
- `isInteger()` checks for integer values (`3`) and custom integer values (`[3]`).
- `isCustomValue()` checks whether the class part is enclosed in brackets (`[something]`)
- `isAny()` always returns true. Be careful with this validator as it might match unwanted classes. I use it primarily to match colors or when I'm ceertain there are no other class groups in a namespace.
### `Config`
```ts
interface Config { … }
```
TypeScript type for config object. Useful if you want to build a `createConfig` function but don't want to define it inline in [`extendTailwindMerge()`](#extendtailwindmerge) or [`createTailwindMerge()`](#createtailwindmerge).
## Writing plugins
This library supports classes of the core Tailwind library out of the box, but not classes of any plugins. But it's possible and hopefully easy to write third-party plugins for tailwind-merge. In case you want to write a plugin, I welcome you to follow these steps:
- Create a package called `tailwind-merge-magic-plugin` with tailwind-merge as peer dependency which exports a function `withMagic` and replace "magic" with your plugin name.
- This function would be ideally a `createConfig` function which takes a config object as argument and returns the modified config object.
- Use the [`validators`](#validators) and [`mergeConfigs()`](#mergeconfigs) from tailwind-merge to extend the config with magic.
Here is an example of how a plugin could look like:
```ts
import { mergeConfigs, validators, Config } from 'tailwind-merge'
export function withMagic(config: Config): Config {
return mergeConfigs(config, {
classGroups: {
magic: [{ magic: ['1', '2'] }],
},
})
}
```
This plugin can then be used like this:
```ts
import { extendTailwindMerge } from 'tailwind-merge'
import { withMagic } from 'tailwind-merge-magic-plugin'
const twMerge = extendTailwindMerge(withMagic)
```
## Versioning

@@ -203,0 +358,0 @@

import { getLruCache } from './lru-cache'
import { Config } from './types'
import { createClassUtils } from './class-utils'
import { createPrefixUtils } from './prefix-utils'

@@ -11,5 +10,4 @@ export type ConfigUtils = ReturnType<typeof createConfigUtils>

cache: getLruCache<string>(config.cacheSize),
...createPrefixUtils(config),
...createClassUtils(config),
}
}

@@ -1,110 +0,57 @@

import { isAny, isCustomLength, isCustomValue, isInteger, isLength } from './config-validators'
import { isAny, isCustomLength, isCustomValue, isInteger, isLength } from './validators'
const SIZES_SIMPLE = ['sm', 'md', 'lg', 'xl', '2xl'] as const
const SIZES_EXTENDED = ['3xl', '4xl', '5xl', '6xl', '7xl'] as const
const OVERSCROLL = ['auto', 'contain', 'none'] as const
const OVERFLOW = ['auto', 'hidden', 'visible', 'scroll'] as const
const LENGTH = [isLength] as const
const LENGTH_WITH_AUTO = ['auto', isLength] as const
const LENGTH_WITH_EMPTY = ['', isLength] as const
const INTEGER = [isInteger] as const
const INTEGER_WITH_AUTO = ['auto', isInteger] as const
const ANY = [isAny] as const
const POSITIONS = [
'bottom',
'center',
'left',
'left-bottom',
'left-top',
'right',
'right-bottom',
'right-top',
'top',
] as const
const ROUNDED = ['none', '', ...SIZES_SIMPLE, '3xl', 'full', isCustomLength] as const
const BORDER_STYLES = ['solid', 'dashed', 'dotted', 'double', 'none'] as const
const BLEND_MODES = [
{
blend: [
'normal',
'multiply',
'screen',
'overlay',
'darken',
'lighten',
'color-dodge',
'color-burn',
'hard-light',
'soft-light',
'difference',
'exclusion',
'hue',
'saturation',
'color',
'luminosity',
],
},
] as const
const ALIGN = ['start', 'end', 'center', 'between', 'around', 'evenly'] as const
const ZERO_AND_EMPTY = ['', '0'] as const
const PSEUDO_VARIANTS = [
// Positional
'first',
'last',
'only',
'odd',
'even',
'first-of-type',
'last-of-type',
'only-of-type',
export function getDefaultConfig() {
const getSizesSimple = () => ['sm', 'md', 'lg', 'xl', '2xl'] as const
const getSizesExtended = () => ['3xl', '4xl', '5xl', '6xl', '7xl'] as const
const getOverscroll = () => ['auto', 'contain', 'none'] as const
const getOverflow = () => ['auto', 'hidden', 'visible', 'scroll'] as const
const getLength = () => [isLength] as const
const getLengthWithAuto = () => ['auto', isLength] as const
const getLengthWithEmpty = () => ['', isLength] as const
const getInteger = () => [isInteger] as const
const getIntegerWithAuto = () => ['auto', isInteger] as const
const getAny = () => [isAny] as const
const getPositions = () =>
[
'bottom',
'center',
'left',
'left-bottom',
'left-top',
'right',
'right-bottom',
'right-top',
'top',
] as const
const getRounded = () =>
['none', '', ...getSizesSimple(), '3xl', 'full', isCustomLength] as const
const getBorderStyles = () => ['solid', 'dashed', 'dotted', 'double', 'none'] as const
const getBlendModes = () =>
[
{
blend: [
'normal',
'multiply',
'screen',
'overlay',
'darken',
'lighten',
'color-dodge',
'color-burn',
'hard-light',
'soft-light',
'difference',
'exclusion',
'hue',
'saturation',
'color',
'luminosity',
],
},
] as const
const getAlign = () => ['start', 'end', 'center', 'between', 'around', 'evenly'] as const
const getZeroAndEmpty = () => ['', '0'] as const
// State
'visited',
'target',
// Forms
'default',
'checked',
'indeterminate',
'placeholder-shown',
'autofill',
'required',
'valid',
'invalid',
'in-range',
'out-of-range',
'read-only',
// Content
'empty',
// Interactive
'focus-within',
'hover',
'focus',
'focus-visible',
'active',
'disabled',
] as const
export function getDefaultConfig() {
return {
cacheSize: 500,
prefixes: [
...SIZES_SIMPLE,
'dark',
'motion-safe',
'motion-reduce',
'before',
'after',
'first-letter',
'first-line',
'selection',
'marker',
...PSEUDO_VARIANTS,
{
group: PSEUDO_VARIANTS,
peer: PSEUDO_VARIANTS,
},
],
classGroups: {

@@ -178,3 +125,3 @@ // Layout

*/
'object-position': [{ object: POSITIONS }],
'object-position': [{ object: getPositions() }],
/**

@@ -184,3 +131,3 @@ * Overflow

*/
overflow: [{ overflow: OVERFLOW }],
overflow: [{ overflow: getOverflow() }],
/**

@@ -190,3 +137,3 @@ * Overflow X

*/
'overflow-x': [{ 'overflow-x': OVERFLOW }],
'overflow-x': [{ 'overflow-x': getOverflow() }],
/**

@@ -196,3 +143,3 @@ * Overflow Y

*/
'overflow-y': [{ 'overflow-y': OVERFLOW }],
'overflow-y': [{ 'overflow-y': getOverflow() }],
/**

@@ -202,3 +149,3 @@ * Overscroll Behavior

*/
overscroll: [{ overscroll: OVERSCROLL }],
overscroll: [{ overscroll: getOverscroll() }],
/**

@@ -208,3 +155,3 @@ * Overscroll Behavior X

*/
'overscroll-x': [{ 'overscroll-x': OVERSCROLL }],
'overscroll-x': [{ 'overscroll-x': getOverscroll() }],
/**

@@ -214,3 +161,3 @@ * Overscroll Behavior Y

*/
'overscroll-y': [{ 'overscroll-y': OVERSCROLL }],
'overscroll-y': [{ 'overscroll-y': getOverscroll() }],
/**

@@ -225,3 +172,3 @@ * Position

*/
inset: [{ inset: LENGTH_WITH_AUTO }],
inset: [{ inset: getLengthWithAuto() }],
/**

@@ -231,3 +178,3 @@ * Right / Left

*/
'inset-x': [{ 'inset-x': LENGTH_WITH_AUTO }],
'inset-x': [{ 'inset-x': getLengthWithAuto() }],
/**

@@ -237,3 +184,3 @@ * Top / Bottom

*/
'inset-y': [{ 'inset-y': LENGTH_WITH_AUTO }],
'inset-y': [{ 'inset-y': getLengthWithAuto() }],
/**

@@ -243,3 +190,3 @@ * Top

*/
top: [{ top: LENGTH_WITH_AUTO }],
top: [{ top: getLengthWithAuto() }],
/**

@@ -249,3 +196,3 @@ * Right

*/
right: [{ right: LENGTH_WITH_AUTO }],
right: [{ right: getLengthWithAuto() }],
/**

@@ -255,3 +202,3 @@ * Bottom

*/
bottom: [{ bottom: LENGTH_WITH_AUTO }],
bottom: [{ bottom: getLengthWithAuto() }],
/**

@@ -261,3 +208,3 @@ * Left

*/
left: [{ left: LENGTH_WITH_AUTO }],
left: [{ left: getLengthWithAuto() }],
/**

@@ -272,3 +219,3 @@ * Visibility

*/
z: [{ z: LENGTH }],
z: [{ z: getLength() }],
// Flexbox and Grid

@@ -309,3 +256,3 @@ /**

*/
'grid-cols': [{ 'grid-cols': ANY }],
'grid-cols': [{ 'grid-cols': getAny() }],
/**

@@ -315,3 +262,3 @@ * Grid Column Start / End

*/
'col-start-end': [{ col: ['auto', { span: INTEGER }] }],
'col-start-end': [{ col: ['auto', { span: getInteger() }] }],
/**

@@ -321,3 +268,3 @@ * Grid Column Start

*/
'col-start': [{ 'col-start': INTEGER_WITH_AUTO }],
'col-start': [{ 'col-start': getIntegerWithAuto() }],
/**

@@ -327,3 +274,3 @@ * Grid Column End

*/
'col-end': [{ 'col-end': INTEGER_WITH_AUTO }],
'col-end': [{ 'col-end': getIntegerWithAuto() }],
/**

@@ -333,3 +280,3 @@ * Grid Template Rows

*/
'grid-rows': [{ 'grid-rows': ANY }],
'grid-rows': [{ 'grid-rows': getAny() }],
/**

@@ -339,3 +286,3 @@ * Grid Row Start / End

*/
'row-start-end': [{ row: ['auto', { span: INTEGER }] }],
'row-start-end': [{ row: ['auto', { span: getInteger() }] }],
/**

@@ -345,3 +292,3 @@ * Grid Row Start

*/
'row-start': [{ 'row-start': INTEGER_WITH_AUTO }],
'row-start': [{ 'row-start': getIntegerWithAuto() }],
/**

@@ -351,3 +298,3 @@ * Grid Row End

*/
'row-end': [{ 'row-end': INTEGER_WITH_AUTO }],
'row-end': [{ 'row-end': getIntegerWithAuto() }],
/**

@@ -372,3 +319,3 @@ * Grid Auto Flow

*/
gap: [{ gap: LENGTH }],
gap: [{ gap: getLength() }],
/**

@@ -378,3 +325,3 @@ * Gap X

*/
'gap-x': [{ 'gap-x': LENGTH }],
'gap-x': [{ 'gap-x': getLength() }],
/**

@@ -384,3 +331,3 @@ * Gap Y

*/
'gap-y': [{ 'gap-y': LENGTH }],
'gap-y': [{ 'gap-y': getLength() }],
/**

@@ -390,3 +337,3 @@ * Justify Content

*/
'justify-content': [{ justify: ALIGN }],
'justify-content': [{ justify: getAlign() }],
/**

@@ -406,3 +353,3 @@ * Justify Items

*/
'align-content': [{ content: ALIGN }],
'align-content': [{ content: getAlign() }],
/**

@@ -422,3 +369,3 @@ * Align Items

*/
'place-content': [{ 'place-content': [...ALIGN, 'stretch'] }],
'place-content': [{ 'place-content': [...getAlign(), 'stretch'] }],
/**

@@ -439,3 +386,3 @@ * Place Items

*/
p: [{ p: LENGTH }],
p: [{ p: getLength() }],
/**

@@ -445,3 +392,3 @@ * Padding X

*/
px: [{ px: LENGTH }],
px: [{ px: getLength() }],
/**

@@ -451,3 +398,3 @@ * Padding Y

*/
py: [{ py: LENGTH }],
py: [{ py: getLength() }],
/**

@@ -457,3 +404,3 @@ * Padding Top

*/
pt: [{ pt: LENGTH }],
pt: [{ pt: getLength() }],
/**

@@ -463,3 +410,3 @@ * Padding Right

*/
pr: [{ pr: LENGTH }],
pr: [{ pr: getLength() }],
/**

@@ -469,3 +416,3 @@ * Padding Bottom

*/
pb: [{ pb: LENGTH }],
pb: [{ pb: getLength() }],
/**

@@ -475,3 +422,3 @@ * Padding Left

*/
pl: [{ pl: LENGTH }],
pl: [{ pl: getLength() }],
/**

@@ -481,3 +428,3 @@ * Margin

*/
m: [{ m: LENGTH_WITH_AUTO }],
m: [{ m: getLengthWithAuto() }],
/**

@@ -487,3 +434,3 @@ * Margin X

*/
mx: [{ mx: LENGTH_WITH_AUTO }],
mx: [{ mx: getLengthWithAuto() }],
/**

@@ -493,3 +440,3 @@ * Margin Y

*/
my: [{ my: LENGTH_WITH_AUTO }],
my: [{ my: getLengthWithAuto() }],
/**

@@ -499,3 +446,3 @@ * Margin Top

*/
mt: [{ mt: LENGTH_WITH_AUTO }],
mt: [{ mt: getLengthWithAuto() }],
/**

@@ -505,3 +452,3 @@ * Margin Right

*/
mr: [{ mr: LENGTH_WITH_AUTO }],
mr: [{ mr: getLengthWithAuto() }],
/**

@@ -511,3 +458,3 @@ * Margin Bottom

*/
mb: [{ mb: LENGTH_WITH_AUTO }],
mb: [{ mb: getLengthWithAuto() }],
/**

@@ -517,3 +464,3 @@ * Margin Left

*/
ml: [{ ml: LENGTH_WITH_AUTO }],
ml: [{ ml: getLengthWithAuto() }],
/**

@@ -523,3 +470,3 @@ * Space Between X

*/
'space-x': [{ 'space-x': LENGTH }],
'space-x': [{ 'space-x': getLength() }],
/**

@@ -534,3 +481,3 @@ * Space Between X Reverse

*/
'space-y': [{ 'space-y': LENGTH }],
'space-y': [{ 'space-y': getLength() }],
/**

@@ -561,4 +508,4 @@ * Space Between Y Reverse

'none',
...SIZES_SIMPLE,
...SIZES_EXTENDED,
...getSizesSimple(),
...getSizesExtended(),
'full',

@@ -568,3 +515,3 @@ 'min',

'prose',
{ screen: SIZES_SIMPLE },
{ screen: getSizesSimple() },
],

@@ -577,3 +524,3 @@ },

*/
h: [{ h: LENGTH_WITH_AUTO }],
h: [{ h: getLengthWithAuto() }],
/**

@@ -588,3 +535,3 @@ * Min-Height

*/
'max-h': [{ 'max-h': LENGTH }],
'max-h': [{ 'max-h': getLength() }],
// Typography

@@ -595,3 +542,3 @@ /**

*/
'font-family': [{ font: ANY }],
'font-family': [{ font: getAny() }],
/**

@@ -605,5 +552,5 @@ * Font Size

'xs',
...SIZES_SIMPLE,
...getSizesSimple(),
'base',
...SIZES_EXTENDED,
...getSizesExtended(),
'8xl',

@@ -712,3 +659,3 @@ '9xl',

*/
'placeholder-color': [{ placeholder: ANY }],
'placeholder-color': [{ placeholder: getAny() }],
/**

@@ -718,3 +665,3 @@ * Placeholder Opacity

*/
'placeholder-opacity': [{ 'placeholder-opacity': INTEGER }],
'placeholder-opacity': [{ 'placeholder-opacity': getInteger() }],
/**

@@ -729,3 +676,3 @@ * Text Alignment

*/
'text-color': [{ text: ANY }],
'text-color': [{ text: getAny() }],
/**

@@ -735,3 +682,3 @@ * Text Opacity

*/
'text-opacity': [{ 'text-opacity': INTEGER }],
'text-opacity': [{ 'text-opacity': getInteger() }],
/**

@@ -784,3 +731,3 @@ * Text Decoration

*/
'bg-opacity': [{ 'bg-opacity': INTEGER }],
'bg-opacity': [{ 'bg-opacity': getInteger() }],
/**

@@ -795,3 +742,3 @@ * Background Origin

*/
'bg-position': [{ bg: POSITIONS }],
'bg-position': [{ bg: getPositions() }],
/**

@@ -818,3 +765,3 @@ * Background Repeat

*/
'bg-blend': [{ bg: BLEND_MODES }],
'bg-blend': [{ bg: getBlendModes() }],
/**

@@ -824,3 +771,3 @@ * Background Color

*/
'bg-color': [{ bg: ANY }],
'bg-color': [{ bg: getAny() }],
/**

@@ -830,3 +777,3 @@ * Gradient Color Stops From

*/
'gradient-from': [{ from: ANY }],
'gradient-from': [{ from: getAny() }],
/**

@@ -836,3 +783,3 @@ * Gradient Color Stops Via

*/
'gradient-via': [{ via: ANY }],
'gradient-via': [{ via: getAny() }],
/**

@@ -842,3 +789,3 @@ * Gradient Color Stops To

*/
'gradient-to': [{ to: ANY }],
'gradient-to': [{ to: getAny() }],
// Borders

@@ -849,3 +796,3 @@ /**

*/
rounded: [{ rounded: ROUNDED }],
rounded: [{ rounded: getRounded() }],
/**

@@ -855,3 +802,3 @@ * Border Radius Top

*/
'rounded-t': [{ 'rounded-t': ROUNDED }],
'rounded-t': [{ 'rounded-t': getRounded() }],
/**

@@ -861,3 +808,3 @@ * Border Radius Right

*/
'rounded-r': [{ 'rounded-r': ROUNDED }],
'rounded-r': [{ 'rounded-r': getRounded() }],
/**

@@ -867,3 +814,3 @@ * Border Radius Bottom

*/
'rounded-b': [{ 'rounded-b': ROUNDED }],
'rounded-b': [{ 'rounded-b': getRounded() }],
/**

@@ -873,3 +820,3 @@ * Border Radius Left

*/
'rounded-l': [{ 'rounded-l': ROUNDED }],
'rounded-l': [{ 'rounded-l': getRounded() }],
/**

@@ -879,3 +826,3 @@ * Border Radius Top Left

*/
'rounded-tl': [{ 'rounded-tl': ROUNDED }],
'rounded-tl': [{ 'rounded-tl': getRounded() }],
/**

@@ -885,3 +832,3 @@ * Border Radius Top Right

*/
'rounded-tr': [{ 'rounded-tr': ROUNDED }],
'rounded-tr': [{ 'rounded-tr': getRounded() }],
/**

@@ -891,3 +838,3 @@ * Border Radius Bottom Right

*/
'rounded-br': [{ 'rounded-br': ROUNDED }],
'rounded-br': [{ 'rounded-br': getRounded() }],
/**

@@ -897,3 +844,3 @@ * Border Radius Bottom Left

*/
'rounded-bl': [{ 'rounded-bl': ROUNDED }],
'rounded-bl': [{ 'rounded-bl': getRounded() }],
/**

@@ -903,3 +850,3 @@ * Border Width

*/
'border-w': [{ border: LENGTH_WITH_EMPTY }],
'border-w': [{ border: getLengthWithEmpty() }],
/**

@@ -909,3 +856,3 @@ * Border Width Top

*/
'border-w-t': [{ 'border-t': LENGTH_WITH_EMPTY }],
'border-w-t': [{ 'border-t': getLengthWithEmpty() }],
/**

@@ -915,3 +862,3 @@ * Border Width Right

*/
'border-w-r': [{ 'border-r': LENGTH_WITH_EMPTY }],
'border-w-r': [{ 'border-r': getLengthWithEmpty() }],
/**

@@ -921,3 +868,3 @@ * Border Width Bottom

*/
'border-w-b': [{ 'border-b': LENGTH_WITH_EMPTY }],
'border-w-b': [{ 'border-b': getLengthWithEmpty() }],
/**

@@ -927,3 +874,3 @@ * Border Width Left

*/
'border-w-l': [{ 'border-l': LENGTH_WITH_EMPTY }],
'border-w-l': [{ 'border-l': getLengthWithEmpty() }],
/**

@@ -933,3 +880,3 @@ * Border Opacity

*/
'border-opacity': [{ 'border-opacity': INTEGER }],
'border-opacity': [{ 'border-opacity': getInteger() }],
/**

@@ -939,3 +886,3 @@ * Border Style

*/
'border-style': [{ border: BORDER_STYLES }],
'border-style': [{ border: getBorderStyles() }],
/**

@@ -945,3 +892,3 @@ * Divide Width X

*/
'divide-x': [{ 'divide-x': LENGTH_WITH_EMPTY }],
'divide-x': [{ 'divide-x': getLengthWithEmpty() }],
/**

@@ -956,3 +903,3 @@ * Divide Width X Reverse

*/
'divide-y': [{ 'divide-y': LENGTH_WITH_EMPTY }],
'divide-y': [{ 'divide-y': getLengthWithEmpty() }],
/**

@@ -967,3 +914,3 @@ * Divide Width Y Reverse

*/
'divide-opacity': [{ 'divide-opacity': INTEGER }],
'divide-opacity': [{ 'divide-opacity': getInteger() }],
/**

@@ -973,3 +920,3 @@ * Divide Style

*/
'divide-style': [{ divide: BORDER_STYLES }],
'divide-style': [{ divide: getBorderStyles() }],
/**

@@ -979,3 +926,3 @@ * Border Color

*/
'border-color': [{ border: ANY }],
'border-color': [{ border: getAny() }],
/**

@@ -985,3 +932,3 @@ * Border Color Top

*/
'border-color-t': [{ 'border-t': ANY }],
'border-color-t': [{ 'border-t': getAny() }],
/**

@@ -991,3 +938,3 @@ * Border Color Right

*/
'border-color-r': [{ 'border-r': ANY }],
'border-color-r': [{ 'border-r': getAny() }],
/**

@@ -997,3 +944,3 @@ * Border Color Bottom

*/
'border-color-b': [{ 'border-b': ANY }],
'border-color-b': [{ 'border-b': getAny() }],
/**

@@ -1003,3 +950,3 @@ * Border Color Left

*/
'border-color-l': [{ 'border-l': ANY }],
'border-color-l': [{ 'border-l': getAny() }],
/**

@@ -1009,3 +956,3 @@ * Divide Color

*/
'divide-color': [{ divide: ANY }],
'divide-color': [{ divide: getAny() }],
/**

@@ -1015,3 +962,3 @@ * Ring Width

*/
'ring-w': [{ ring: LENGTH_WITH_EMPTY }],
'ring-w': [{ ring: getLengthWithEmpty() }],
/**

@@ -1026,3 +973,3 @@ * Ring Width Inset

*/
'ring-color': [{ ring: ANY }],
'ring-color': [{ ring: getAny() }],
/**

@@ -1032,3 +979,3 @@ * Ring Opacity

*/
'ring-opacity': [{ 'ring-opacity': INTEGER }],
'ring-opacity': [{ 'ring-opacity': getInteger() }],
/**

@@ -1038,3 +985,3 @@ * Ring Offset Width

*/
'ring-offset-w': [{ 'ring-offset': LENGTH }],
'ring-offset-w': [{ 'ring-offset': getLength() }],
/**

@@ -1044,3 +991,3 @@ * Ring Offset Color

*/
'ring-offset-color': [{ 'ring-offset': ANY }],
'ring-offset-color': [{ 'ring-offset': getAny() }],
// Effects

@@ -1051,3 +998,3 @@ /**

*/
shadow: [{ shadow: ['', ...SIZES_SIMPLE, 'inner', 'none'] }],
shadow: [{ shadow: ['', ...getSizesSimple(), 'inner', 'none'] }],
/**

@@ -1057,3 +1004,3 @@ * Opacity

*/
opacity: [{ opacity: INTEGER }],
opacity: [{ opacity: getInteger() }],
/**

@@ -1063,3 +1010,3 @@ * Mix Beldn Mode

*/
'mix-blend': [{ 'mix-blend': BLEND_MODES }],
'mix-blend': [{ 'mix-blend': getBlendModes() }],
// Filters

@@ -1075,3 +1022,3 @@ /**

*/
blur: [{ blur: ['none', '', ...SIZES_SIMPLE, '3xl', isCustomLength] }],
blur: [{ blur: ['none', '', ...getSizesSimple(), '3xl', isCustomLength] }],
/**

@@ -1081,3 +1028,3 @@ * Brightness

*/
brightness: [{ brightness: INTEGER }],
brightness: [{ brightness: getInteger() }],
/**

@@ -1087,3 +1034,3 @@ * Contrast

*/
contrast: [{ contrast: INTEGER }],
contrast: [{ contrast: getInteger() }],
/**

@@ -1093,3 +1040,3 @@ * Drop Shadow

*/
'drop-shadow': [{ 'drop-shadow': ['', ...SIZES_SIMPLE, 'none'] }],
'drop-shadow': [{ 'drop-shadow': ['', ...getSizesSimple(), 'none'] }],
/**

@@ -1099,3 +1046,3 @@ * Grayscale

*/
grayscale: [{ grayscale: ZERO_AND_EMPTY }],
grayscale: [{ grayscale: getZeroAndEmpty() }],
/**

@@ -1105,3 +1052,3 @@ * Hue Rotate

*/
'hue-rotate': [{ 'hue-rotate': INTEGER }],
'hue-rotate': [{ 'hue-rotate': getInteger() }],
/**

@@ -1111,3 +1058,3 @@ * Invert

*/
invert: [{ invert: ZERO_AND_EMPTY }],
invert: [{ invert: getZeroAndEmpty() }],
/**

@@ -1117,3 +1064,3 @@ * Saturate

*/
saturate: [{ saturate: INTEGER }],
saturate: [{ saturate: getInteger() }],
/**

@@ -1123,3 +1070,3 @@ * Sepia

*/
sepia: [{ sepia: ZERO_AND_EMPTY }],
sepia: [{ sepia: getZeroAndEmpty() }],
/**

@@ -1134,3 +1081,3 @@ * Backdrop Filter

*/
'backdrop-blur': [{ 'backdrop-blur': ['none', '', ...SIZES_SIMPLE, '3xl'] }],
'backdrop-blur': [{ 'backdrop-blur': ['none', '', ...getSizesSimple(), '3xl'] }],
/**

@@ -1140,3 +1087,3 @@ * Backdrop Brightness

*/
'backdrop-brightness': [{ 'backdrop-brightness': INTEGER }],
'backdrop-brightness': [{ 'backdrop-brightness': getInteger() }],
/**

@@ -1146,3 +1093,3 @@ * Backdrop Contrast

*/
'backdrop-contrast': [{ 'backdrop-contrast': INTEGER }],
'backdrop-contrast': [{ 'backdrop-contrast': getInteger() }],
/**

@@ -1152,3 +1099,3 @@ * Backdrop Grayscale

*/
'backdrop-grayscale': [{ 'backdrop-grayscale': ZERO_AND_EMPTY }],
'backdrop-grayscale': [{ 'backdrop-grayscale': getZeroAndEmpty() }],
/**

@@ -1158,3 +1105,3 @@ * Backdrop Hue Rotate

*/
'backdrop-hue-rotate': [{ 'backdrop-hue-rotate': INTEGER }],
'backdrop-hue-rotate': [{ 'backdrop-hue-rotate': getInteger() }],
/**

@@ -1164,3 +1111,3 @@ * Backdrop Invert

*/
'backdrop-invert': [{ 'backdrop-invert': ZERO_AND_EMPTY }],
'backdrop-invert': [{ 'backdrop-invert': getZeroAndEmpty() }],
/**

@@ -1170,3 +1117,3 @@ * Backdrop Opacity

*/
'backdrop-opacity': [{ 'backdrop-opacity': INTEGER }],
'backdrop-opacity': [{ 'backdrop-opacity': getInteger() }],
/**

@@ -1176,3 +1123,3 @@ * Backdrop Saturate

*/
'backdrop-saturate': [{ 'backdrop-saturate': INTEGER }],
'backdrop-saturate': [{ 'backdrop-saturate': getInteger() }],
/**

@@ -1182,3 +1129,3 @@ * Backdrop Sepia

*/
'backdrop-sepia': [{ 'backdrop-sepia': ZERO_AND_EMPTY }],
'backdrop-sepia': [{ 'backdrop-sepia': getZeroAndEmpty() }],
// Tables

@@ -1207,3 +1154,3 @@ /**

*/
duration: [{ duration: INTEGER }],
duration: [{ duration: getInteger() }],
/**

@@ -1218,3 +1165,3 @@ * Transition Timing Function

*/
delay: [{ delay: INTEGER }],
delay: [{ delay: getInteger() }],
/**

@@ -1254,3 +1201,3 @@ * Animation

*/
scale: [{ scale: INTEGER }],
scale: [{ scale: getInteger() }],
/**

@@ -1260,3 +1207,3 @@ * Scale X

*/
'scale-x': [{ 'scale-x': INTEGER }],
'scale-x': [{ 'scale-x': getInteger() }],
/**

@@ -1266,3 +1213,3 @@ * Scale Y

*/
'scale-y': [{ 'scale-y': INTEGER }],
'scale-y': [{ 'scale-y': getInteger() }],
/**

@@ -1272,3 +1219,3 @@ * Rotate

*/
rotate: [{ rotate: INTEGER }],
rotate: [{ rotate: getInteger() }],
/**

@@ -1278,3 +1225,3 @@ * Translate X

*/
'translate-x': [{ 'translate-x': LENGTH }],
'translate-x': [{ 'translate-x': getLength() }],
/**

@@ -1284,3 +1231,3 @@ * Translate Y

*/
'translate-y': [{ 'translate-y': LENGTH }],
'translate-y': [{ 'translate-y': getLength() }],
/**

@@ -1290,3 +1237,3 @@ * Skew X

*/
'skew-x': [{ 'skew-x': INTEGER }],
'skew-x': [{ 'skew-x': getInteger() }],
/**

@@ -1296,3 +1243,3 @@ * Skew Y

*/
'skew-y': [{ 'skew-y': INTEGER }],
'skew-y': [{ 'skew-y': getInteger() }],
// Interactivity

@@ -1358,3 +1305,3 @@ /**

*/
'stroke-w': [{ stroke: LENGTH }],
'stroke-w': [{ stroke: getLength() }],
// Accessibility

@@ -1376,3 +1323,3 @@ /**

*/
'caret-color': [{ caret: ANY }],
'caret-color': [{ caret: getAny() }],
},

@@ -1379,0 +1326,0 @@ conflictingClassGroups: {

@@ -1,4 +0,10 @@

import { createTailwindMerge } from './tailwind-merge'
import { createTailwindMerge } from './create-tailwind-merge'
import { getDefaultConfig } from './default-config'
export const twMerge = createTailwindMerge((defaultConfig) => defaultConfig())
export { createTailwindMerge }
export const twMerge = createTailwindMerge(getDefaultConfig)
export { createTailwindMerge, getDefaultConfig }
export { extendTailwindMerge } from './extend-tailwind-merge'
export type { Config } from './types'
export * as validators from './validators'
export { mergeConfigs } from './merge-configs'

@@ -11,4 +11,3 @@ import { ConfigUtils } from './config-utils'

export function mergeClassList(classList: string, configUtils: ConfigUtils) {
const { isPrefixValid, getClassGroupId, comparePrefixes, getConflictingClassGroupIds } =
configUtils
const { getClassGroupId, getConflictingClassGroupIds } = configUtils

@@ -18,5 +17,5 @@ /**

* `{importantModifier}{variantPrefixes}{classGroupId}`
* @example ':standaloneClasses.1'
* @example 'hover:focus:dynamicClasses.bg.2'
* @example '!md:dynamicClasses.bg.0'
* @example 'float'
* @example 'hover:focus:bg-color'
* @example '!md:pr'
*/

@@ -39,4 +38,3 @@ const classGroupsInConflict = new Set<string>()

const arePrefixesValid = prefixes.every(isPrefixValid)
const classGroupId = arePrefixesValid ? getClassGroupId(className) : undefined
const classGroupId = getClassGroupId(className)

@@ -51,5 +49,3 @@ if (!classGroupId) {

const variantPrefix =
prefixes.length === 0
? ''
: prefixes.sort(comparePrefixes).concat('').join(PREFIX_SEPARATOR)
prefixes.length === 0 ? '' : prefixes.sort().concat('').join(PREFIX_SEPARATOR)

@@ -56,0 +52,0 @@ const fullPrefix = hasImportantModifier

export interface Config {
/**
* Prefixes which can be prepended to Tailwind CSS classes
* @example ['hover', 'focus']
*/
prefixes: readonly Prefix[]
/**
* Integer indicating size of LRU cache used for memoizing results.

@@ -33,3 +28,2 @@ * - Cache might be up to twice as big as `cacheSize`

export type Prefix = string | Record<string, readonly Prefix[]>
export type ClassGroup = readonly ClassDefinition[]

@@ -36,0 +30,0 @@ type ClassDefinition = string | ClassValidator | ClassObject

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc