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.1.2 to 0.2.0

125

dist/index.js

@@ -15,3 +15,3 @@ import HLRU from 'hashlru';

if (classParts[0] === '' && classParts.length > 1) {
if (classParts[0] === '' && classParts.length !== 1) {
classParts.shift();

@@ -195,2 +195,5 @@ }

}
function isCustomValue(classPart) {
return customValueRegex.test(classPart);
}
function isAny() {

@@ -205,4 +208,5 @@ return true;

const LENGTH = [isLength];
const MARGIN = ['auto', isLength];
const LENGTH_WITH_AUTO = ['auto', isLength];
const INTEGER = [isInteger];
const INTEGER_WITH_AUTO = ['auto', isInteger];
const ANY = [isAny];

@@ -215,6 +219,7 @@ const POSITIONS = ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];

}];
const ALIGN = ['start', 'end', 'center', 'between', 'around', 'evenly'];
function getDefaultConfig() {
return {
cacheSize: 500,
prefixes: [...SIZES_SIMPLE, 'dark', 'motion-safe', 'motion-reduce', 'first', 'last', 'odd', 'even', 'visited', 'checked', 'group-hover', 'group-focus', 'focus-within', 'hover', 'focus', 'focus-visible', 'active', 'disabled'],
prefixes: [...SIZES_SIMPLE, 'dark', 'motion-safe', 'motion-reduce', 'first', 'last', 'odd', 'even', 'visited', 'checked', 'group-hover', 'group-focus', 'focus-within', 'hover', 'focus', 'focus-visible', 'active', 'disabled', 'before', 'after', 'first-letter', 'first-line', 'selection', 'marker', 'only', 'first-of-type', 'last-of-type', 'only-of-type', 'target', 'default', 'indeterminate', 'placeholder-shown', 'autofill', 'required', 'valid', 'invalid', 'in-range', 'out-of-range', 'peer-hover', 'peer-focus', 'peer-checked', 'peer-disabled'],
dynamicClasses: {

@@ -303,3 +308,3 @@ // Layout

[{
x: LENGTH
x: LENGTH_WITH_AUTO
}],

@@ -311,3 +316,3 @@ /**

[{
y: LENGTH
y: LENGTH_WITH_AUTO
}],

@@ -318,3 +323,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
top: [

@@ -325,3 +330,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
right: [

@@ -332,3 +337,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
bottom: [

@@ -339,3 +344,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
left: [

@@ -346,3 +351,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
z: [

@@ -426,3 +431,3 @@ /**

[{
start: ['auto', isInteger]
start: INTEGER_WITH_AUTO
}],

@@ -434,3 +439,3 @@ /**

[{
end: ['auto', isInteger]
end: INTEGER_WITH_AUTO
}]],

@@ -450,3 +455,3 @@ row: [

[{
start: ['auto', isInteger]
start: INTEGER_WITH_AUTO
}],

@@ -458,3 +463,3 @@ /**

[{
end: ['auto', isInteger]
end: INTEGER_WITH_AUTO
}]],

@@ -501,3 +506,3 @@ auto: [

*/
['start', 'end', 'center', 'between', 'around', 'evenly'],
ALIGN,
/**

@@ -522,3 +527,8 @@ * Justify Items

*/
['center', 'start', 'end', 'between', 'around', 'evenly']],
ALIGN,
/**
* Content
* @see https://tailwindcss.com/docs/just-in-time-mode#content-utilities
*/
[isCustomValue]],
items: [

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

[{
content: ['center', 'start', 'end', 'between', 'around', 'evenly', 'stretch']
content: [...ALIGN, 'stretch']
}],

@@ -607,3 +617,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mx: [

@@ -614,3 +624,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
my: [

@@ -621,3 +631,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mt: [

@@ -628,3 +638,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mr: [

@@ -635,3 +645,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mb: [

@@ -642,3 +652,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
ml: [

@@ -649,3 +659,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
space: [

@@ -713,3 +723,3 @@ /**

[{
h: ['full', 'screen', isLength]
h: LENGTH
}]],

@@ -721,3 +731,3 @@ h: [

*/
['auto', isLength]],
LENGTH_WITH_AUTO],
// Typography

@@ -1007,2 +1017,30 @@ font: [

/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
*/
[{
t: ANY
}],
/**
* Border Color Right
* @see https://tailwindcss.com/docs/border-color
*/
[{
r: ANY
}],
/**
* Border Color Bottom
* @see https://tailwindcss.com/docs/border-color
*/
[{
b: ANY
}],
/**
* Border Color Left
* @see https://tailwindcss.com/docs/border-color
*/
[{
l: ANY
}],
/**
* Border Color

@@ -1397,3 +1435,9 @@ * @see https://tailwindcss.com/docs/border-color

*/
LENGTH]
LENGTH],
caret: [
/**
* Caret Color
* @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities
*/
ANY]
},

@@ -1584,2 +1628,8 @@ standaloneClasses: [// Layout

'dynamicClasses.border.4'],
// Border Color
'dynamicClasses.border.12': [// Border Color Top
'dynamicClasses.border.8', // Border Color Right
'dynamicClasses.border.9', // Border Color Bottom
'dynamicClasses.border.10', // Border Color Left
'dynamicClasses.border.11'],
// Ring Width

@@ -1608,5 +1658,7 @@ 'dynamicClasses.ring.0': [// Ring Width

// Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`
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
const PREFIX_SEPARATOR_REGEX = /:(?![^\s[]*\])/;
const PREFIX_SEPARATOR_REGEX = /:(?![^[]*\])/;
const PREFIX_SEPARATOR = ':';

@@ -1616,10 +1668,12 @@ function mergeClassList(classList, configUtils) {

* Set of classGroupIds in following format:
* - No prefix: `:classGroupId`
* - With prefix: `prefix:classGroupId`
* `{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(/\s+/).map(originalClassName => {
const prefixes = originalClassName.split(PREFIX_SEPARATOR_REGEX);
return classList.trim().split(SPLIT_CLASSES_REGEX).map(originalClassName => {
const hasImportantModifier = originalClassName.startsWith(IMPORTANT_MODIFIER);
const classNameWithoutImportant = hasImportantModifier ? originalClassName.substring(1) : originalClassName;
const prefixes = classNameWithoutImportant.split(PREFIX_SEPARATOR_REGEX);
const className = prefixes.pop();

@@ -1636,6 +1690,7 @@ const arePrefixesValid = prefixes.every(configUtils.prefix.isValid);

prefixes.sort(configUtils.prefix.compare);
const variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(configUtils.prefix.compare).concat('').join(PREFIX_SEPARATOR);
const fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;
return {
isTailwindClass: true,
prefix: prefixes.join(PREFIX_SEPARATOR),
prefix: fullPrefix,
classGroupId,

@@ -1642,0 +1697,0 @@ originalClassName

@@ -15,3 +15,3 @@ import HLRU from 'hashlru';

if (classParts[0] === '' && classParts.length > 1) {
if (classParts[0] === '' && classParts.length !== 1) {
classParts.shift();

@@ -197,2 +197,5 @@ }

}
function isCustomValue(classPart) {
return customValueRegex.test(classPart);
}
function isAny() {

@@ -207,4 +210,5 @@ return true;

var LENGTH = [isLength];
var MARGIN = ['auto', isLength];
var LENGTH_WITH_AUTO = ['auto', isLength];
var INTEGER = [isInteger];
var INTEGER_WITH_AUTO = ['auto', isInteger];
var ANY = [isAny];

@@ -217,6 +221,7 @@ var POSITIONS = ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];

}];
var ALIGN = ['start', 'end', 'center', 'between', 'around', 'evenly'];
function getDefaultConfig() {
return {
cacheSize: 500,
prefixes: [].concat(SIZES_SIMPLE, ['dark', 'motion-safe', 'motion-reduce', 'first', 'last', 'odd', 'even', 'visited', 'checked', 'group-hover', 'group-focus', 'focus-within', 'hover', 'focus', 'focus-visible', 'active', 'disabled']),
prefixes: [].concat(SIZES_SIMPLE, ['dark', 'motion-safe', 'motion-reduce', 'first', 'last', 'odd', 'even', 'visited', 'checked', 'group-hover', 'group-focus', 'focus-within', 'hover', 'focus', 'focus-visible', 'active', 'disabled', 'before', 'after', 'first-letter', 'first-line', 'selection', 'marker', 'only', 'first-of-type', 'last-of-type', 'only-of-type', 'target', 'default', 'indeterminate', 'placeholder-shown', 'autofill', 'required', 'valid', 'invalid', 'in-range', 'out-of-range', 'peer-hover', 'peer-focus', 'peer-checked', 'peer-disabled']),
dynamicClasses: {

@@ -305,3 +310,3 @@ // Layout

[{
x: LENGTH
x: LENGTH_WITH_AUTO
}],

@@ -313,3 +318,3 @@ /**

[{
y: LENGTH
y: LENGTH_WITH_AUTO
}],

@@ -320,3 +325,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
top: [

@@ -327,3 +332,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
right: [

@@ -334,3 +339,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
bottom: [

@@ -341,3 +346,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
left: [

@@ -348,3 +353,3 @@ /**

*/
LENGTH],
LENGTH_WITH_AUTO],
z: [

@@ -428,3 +433,3 @@ /**

[{
start: ['auto', isInteger]
start: INTEGER_WITH_AUTO
}],

@@ -436,3 +441,3 @@ /**

[{
end: ['auto', isInteger]
end: INTEGER_WITH_AUTO
}]],

@@ -452,3 +457,3 @@ row: [

[{
start: ['auto', isInteger]
start: INTEGER_WITH_AUTO
}],

@@ -460,3 +465,3 @@ /**

[{
end: ['auto', isInteger]
end: INTEGER_WITH_AUTO
}]],

@@ -503,3 +508,3 @@ auto: [

*/
['start', 'end', 'center', 'between', 'around', 'evenly'],
ALIGN,
/**

@@ -524,3 +529,8 @@ * Justify Items

*/
['center', 'start', 'end', 'between', 'around', 'evenly']],
ALIGN,
/**
* Content
* @see https://tailwindcss.com/docs/just-in-time-mode#content-utilities
*/
[isCustomValue]],
items: [

@@ -544,3 +554,3 @@ /**

[{
content: ['center', 'start', 'end', 'between', 'around', 'evenly', 'stretch']
content: [].concat(ALIGN, ['stretch'])
}],

@@ -609,3 +619,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mx: [

@@ -616,3 +626,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
my: [

@@ -623,3 +633,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mt: [

@@ -630,3 +640,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mr: [

@@ -637,3 +647,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
mb: [

@@ -644,3 +654,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
ml: [

@@ -651,3 +661,3 @@ /**

*/
MARGIN],
LENGTH_WITH_AUTO],
space: [

@@ -715,3 +725,3 @@ /**

[{
h: ['full', 'screen', isLength]
h: LENGTH
}]],

@@ -723,3 +733,3 @@ h: [

*/
['auto', isLength]],
LENGTH_WITH_AUTO],
// Typography

@@ -1009,2 +1019,30 @@ font: [

/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
*/
[{
t: ANY
}],
/**
* Border Color Right
* @see https://tailwindcss.com/docs/border-color
*/
[{
r: ANY
}],
/**
* Border Color Bottom
* @see https://tailwindcss.com/docs/border-color
*/
[{
b: ANY
}],
/**
* Border Color Left
* @see https://tailwindcss.com/docs/border-color
*/
[{
l: ANY
}],
/**
* Border Color

@@ -1399,3 +1437,9 @@ * @see https://tailwindcss.com/docs/border-color

*/
LENGTH]
LENGTH],
caret: [
/**
* Caret Color
* @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities
*/
ANY]
},

@@ -1586,2 +1630,8 @@ standaloneClasses: [// Layout

'dynamicClasses.border.4'],
// Border Color
'dynamicClasses.border.12': [// Border Color Top
'dynamicClasses.border.8', // Border Color Right
'dynamicClasses.border.9', // Border Color Bottom
'dynamicClasses.border.10', // Border Color Left
'dynamicClasses.border.11'],
// Ring Width

@@ -1612,5 +1662,7 @@ 'dynamicClasses.ring.0': [// Ring Width

// Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`
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
var PREFIX_SEPARATOR_REGEX = /:(?![^\s[]*\])/;
var PREFIX_SEPARATOR_REGEX = /:(?![^[]*\])/;
var PREFIX_SEPARATOR = ':';

@@ -1620,10 +1672,12 @@ function mergeClassList(classList, configUtils) {

* Set of classGroupIds in following format:
* - No prefix: `:classGroupId`
* - With prefix: `prefix:classGroupId`
* `{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(/\s+/).map(function (originalClassName) {
var prefixes = originalClassName.split(PREFIX_SEPARATOR_REGEX);
return classList.trim().split(SPLIT_CLASSES_REGEX).map(function (originalClassName) {
var hasImportantModifier = originalClassName.startsWith(IMPORTANT_MODIFIER);
var classNameWithoutImportant = hasImportantModifier ? originalClassName.substring(1) : originalClassName;
var prefixes = classNameWithoutImportant.split(PREFIX_SEPARATOR_REGEX);
var className = prefixes.pop();

@@ -1640,6 +1694,7 @@ var arePrefixesValid = prefixes.every(configUtils.prefix.isValid);

prefixes.sort(configUtils.prefix.compare);
var variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(configUtils.prefix.compare).concat('').join(PREFIX_SEPARATOR);
var fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;
return {
isTailwindClass: true,
prefix: prefixes.join(PREFIX_SEPARATOR),
prefix: fullPrefix,
classGroupId: classGroupId,

@@ -1646,0 +1701,0 @@ originalClassName: originalClassName

export declare function isLength(classPart: string): boolean;
export declare function isInteger(classPart: string): boolean;
export declare function isCustomValue(classPart: string): boolean;
export declare function isAny(): boolean;

@@ -1,5 +0,5 @@

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

@@ -22,10 +22,10 @@ readonly decoration: readonly [readonly ["slice", "clone"]];

readonly inset: readonly [readonly [{
readonly x: readonly [typeof isLength];
readonly x: readonly ["auto", typeof isLength];
}], readonly [{
readonly y: readonly [typeof isLength];
}], readonly [typeof isLength]];
readonly top: readonly [readonly [typeof isLength]];
readonly right: readonly [readonly [typeof isLength]];
readonly bottom: readonly [readonly [typeof isLength]];
readonly left: readonly [readonly [typeof isLength]];
readonly y: readonly ["auto", typeof isLength];
}], readonly ["auto", typeof isLength]];
readonly top: readonly [readonly ["auto", typeof isLength]];
readonly right: readonly [readonly ["auto", typeof isLength]];
readonly bottom: readonly [readonly ["auto", typeof isLength]];
readonly left: readonly [readonly ["auto", typeof isLength]];
readonly z: readonly [readonly [typeof isLength]];

@@ -74,7 +74,7 @@ readonly flex: readonly [readonly ["row", "row-reverse", "col", "col-reverse"], readonly ["wrap", "wrap-reverse", "nowrap"], readonly ["1", "auto", "initial", "none"], readonly [{

}]];
readonly content: readonly [readonly ["center", "start", "end", "between", "around", "evenly"]];
readonly content: readonly [readonly ["start", "end", "center", "between", "around", "evenly"], readonly [typeof isCustomValue]];
readonly items: readonly [readonly ["start", "end", "center", "baseline", "stretch"]];
readonly self: readonly [readonly ["auto", "start", "end", "center", "stretch"]];
readonly place: readonly [readonly [{
readonly content: readonly ["center", "start", "end", "between", "around", "evenly", "stretch"];
readonly content: readonly ["start", "end", "center", "between", "around", "evenly", "stretch"];
}], readonly [{

@@ -115,3 +115,3 @@ readonly items: readonly ["start", "end", "center", "stretch"];

}], readonly [{
readonly h: readonly ["full", "screen", typeof isLength];
readonly h: readonly [typeof isLength];
}]];

@@ -175,3 +175,11 @@ readonly h: readonly [readonly ["auto", typeof isLength]];

readonly opacity: readonly [typeof isInteger];
}], readonly ["solid", "dashed", "dotted", "double", "none"], readonly ["collapse", "separate"], readonly [typeof isAny]];
}], readonly ["solid", "dashed", "dotted", "double", "none"], readonly ["collapse", "separate"], readonly [{
readonly t: readonly [typeof isAny];
}], readonly [{
readonly r: readonly [typeof isAny];
}], readonly [{
readonly b: readonly [typeof isAny];
}], readonly [{
readonly l: readonly [typeof isAny];
}], readonly [typeof isAny]];
readonly divide: readonly [readonly ["x-reverse"], readonly [{

@@ -264,2 +272,3 @@ readonly x: readonly [typeof isLength];

readonly stroke: readonly [readonly ["current"], readonly [typeof isLength]];
readonly caret: readonly [readonly [typeof isAny]];
};

@@ -290,2 +299,3 @@ readonly standaloneClasses: readonly [readonly ["container"], readonly ["block", "inline-block", "inline", "flex", "inline-flex", "table", "inline-table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row-group", "table-row", "flow-root", "grid", "inline-grid", "contents", "list-item", "hidden"], readonly ["isolate", "isolation-auto"], readonly ["static", "fixed", "absolute", "relative", "sticky"], readonly ["visible", "invisible"], readonly ["antialiased", "subpixel-antialiased"], readonly ["italic", "not-italic"], readonly ["normal-nums", "ordinal", "slashed-zero", "lining-nums", "oldstyle-nums", "tabular-nums", "diagonal-nums", "stacked-fractons"], readonly ["underline", "line-through", "no-underline"], readonly ["uppercase", "lowercase", "capitalize", "normal-case"], readonly ["truncate", "overflow-ellipsis", "overflow-clip"], readonly ["appearance-none"], readonly ["fill-current"], readonly ["sr-only", "not-sr-only"]];

readonly 'dynamicClasses.border.0': readonly ["dynamicClasses.border.1", "dynamicClasses.border.2", "dynamicClasses.border.3", "dynamicClasses.border.4"];
readonly 'dynamicClasses.border.12': readonly ["dynamicClasses.border.8", "dynamicClasses.border.9", "dynamicClasses.border.10", "dynamicClasses.border.11"];
readonly 'dynamicClasses.ring.0': readonly ["dynamicClasses.ring.0", "dynamicClasses.shadow.0"];

@@ -292,0 +302,0 @@ readonly 'dynamicClasses.shadow.0': readonly ["dynamicClasses.ring.0", "dynamicClasses.shadow.0"];

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

@@ -35,2 +35,3 @@ "keywords": [

},
"sideEffects": false,
"scripts": {

@@ -37,0 +38,0 @@ "build": "rm -rf dist/* && microbundle --strict --no-compress --format modern,esm,cjs",

@@ -12,3 +12,6 @@ # tailwind-merge

- Supports Tailwind v2.0.0 up to v2.2.4
- Supports Tailwind v2.0.0 up to v2.2.4, support for newer version will be added continuously
- Works in Node >=12 and all modern browsers
- Fully typed
- [3.9 kB minified + gzipped](https://bundlephobia.com/package/tailwind-merge)

@@ -88,5 +91,12 @@ ## What is it for

### Preserves non-Tailwind-related classes
### Supports important modifier
```ts
twMerge('!p-3 !p-4 p-5') // → '!p-4 p-5'
twMerge('!right-2 !-inset-x-1') // → '!-inset-x-1'
```
### Preserves non-Tailwind classes
```ts
twMerge('p-5 p-2 my-non-tailwind-class p-4') // → 'my-non-tailwind-class p-4'

@@ -93,0 +103,0 @@ ```

@@ -30,3 +30,3 @@ import { ClassGroupId, Config, DynamicClassGroup, DynamicClassValidator } from './types'

// 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.
if (classParts[0] === '' && classParts.length > 1) {
if (classParts[0] === '' && classParts.length !== 1) {
classParts.shift()

@@ -33,0 +33,0 @@ }

@@ -30,4 +30,8 @@ const customValueRegex = /^\[(.+)\]$/

export function isCustomValue(classPart: string) {
return customValueRegex.test(classPart)
}
export function isAny() {
return true
}

@@ -1,2 +0,2 @@

import { isAny, isInteger, isLength } from './config-validators'
import { isAny, isCustomValue, isInteger, isLength } from './config-validators'

@@ -8,4 +8,5 @@ const SIZES_SIMPLE = ['sm', 'md', 'lg', 'xl', '2xl'] as const

const LENGTH = [isLength] as const
const MARGIN = ['auto', isLength] as const
const LENGTH_WITH_AUTO = ['auto', isLength] as const
const INTEGER = [isInteger] as const
const INTEGER_WITH_AUTO = ['auto', isInteger] as const
const ANY = [isAny] as const

@@ -47,2 +48,3 @@ const POSITIONS = [

] as const
const ALIGN = ['start', 'end', 'center', 'between', 'around', 'evenly'] as const

@@ -71,2 +73,26 @@ export function getDefaultConfig() {

'disabled',
'before',
'after',
'first-letter',
'first-line',
'selection',
'marker',
'only',
'first-of-type',
'last-of-type',
'only-of-type',
'target',
'default',
'indeterminate',
'placeholder-shown',
'autofill',
'required',
'valid',
'invalid',
'in-range',
'out-of-range',
'peer-hover',
'peer-focus',
'peer-checked',
'peer-disabled',
],

@@ -154,3 +180,3 @@ dynamicClasses: {

*/
[{ x: LENGTH }],
[{ x: LENGTH_WITH_AUTO }],
/**

@@ -160,3 +186,3 @@ * Top / Bottom

*/
[{ y: LENGTH }],
[{ y: LENGTH_WITH_AUTO }],
/**

@@ -166,3 +192,3 @@ * Top / Right / Bottom / Left

*/
LENGTH,
LENGTH_WITH_AUTO,
],

@@ -174,3 +200,3 @@ top: [

*/
LENGTH,
LENGTH_WITH_AUTO,
],

@@ -182,3 +208,3 @@ right: [

*/
LENGTH,
LENGTH_WITH_AUTO,
],

@@ -190,3 +216,3 @@ bottom: [

*/
LENGTH,
LENGTH_WITH_AUTO,
],

@@ -198,3 +224,3 @@ left: [

*/
LENGTH,
LENGTH_WITH_AUTO,
],

@@ -270,3 +296,3 @@ z: [

*/
[{ start: ['auto', isInteger] }],
[{ start: INTEGER_WITH_AUTO }],
/**

@@ -276,3 +302,3 @@ * Grid Column End

*/
[{ end: ['auto', isInteger] }],
[{ end: INTEGER_WITH_AUTO }],
],

@@ -289,3 +315,3 @@ row: [

*/
[{ start: ['auto', isInteger] }],
[{ start: INTEGER_WITH_AUTO }],
/**

@@ -295,3 +321,3 @@ * Grid Row End

*/
[{ end: ['auto', isInteger] }],
[{ end: INTEGER_WITH_AUTO }],
],

@@ -332,3 +358,3 @@ auto: [

*/
['start', 'end', 'center', 'between', 'around', 'evenly'],
ALIGN,
/**

@@ -350,3 +376,8 @@ * Justify Items

*/
['center', 'start', 'end', 'between', 'around', 'evenly'],
ALIGN,
/**
* Content
* @see https://tailwindcss.com/docs/just-in-time-mode#content-utilities
*/
[isCustomValue],
],

@@ -372,3 +403,3 @@ items: [

*/
[{ content: ['center', 'start', 'end', 'between', 'around', 'evenly', 'stretch'] }],
[{ content: [...ALIGN, 'stretch'] }],
/**

@@ -440,3 +471,3 @@ * Place Items

*/
MARGIN,
LENGTH_WITH_AUTO,
],

@@ -448,3 +479,3 @@ mx: [

*/
MARGIN,
LENGTH_WITH_AUTO,
],

@@ -456,3 +487,3 @@ my: [

*/
MARGIN,
LENGTH_WITH_AUTO,
],

@@ -464,3 +495,3 @@ mt: [

*/
MARGIN,
LENGTH_WITH_AUTO,
],

@@ -472,3 +503,3 @@ mr: [

*/
MARGIN,
LENGTH_WITH_AUTO,
],

@@ -480,3 +511,3 @@ mb: [

*/
MARGIN,
LENGTH_WITH_AUTO,
],

@@ -488,3 +519,3 @@ ml: [

*/
MARGIN,
LENGTH_WITH_AUTO,
],

@@ -557,3 +588,3 @@ space: [

*/
[{ h: ['full', 'screen', isLength] }],
[{ h: LENGTH }],
],

@@ -565,3 +596,3 @@ h: [

*/
['auto', isLength],
LENGTH_WITH_AUTO,
],

@@ -836,2 +867,22 @@ // Typography

/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
*/
[{ t: ANY }],
/**
* Border Color Right
* @see https://tailwindcss.com/docs/border-color
*/
[{ r: ANY }],
/**
* Border Color Bottom
* @see https://tailwindcss.com/docs/border-color
*/
[{ b: ANY }],
/**
* Border Color Left
* @see https://tailwindcss.com/docs/border-color
*/
[{ l: ANY }],
/**
* Border Color

@@ -1223,2 +1274,9 @@ * @see https://tailwindcss.com/docs/border-color

],
caret: [
/**
* Caret Color
* @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities
*/
ANY,
],
},

@@ -1526,2 +1584,13 @@ standaloneClasses: [

],
// Border Color
'dynamicClasses.border.12': [
// Border Color Top
'dynamicClasses.border.8',
// Border Color Right
'dynamicClasses.border.9',
// Border Color Bottom
'dynamicClasses.border.10',
// Border Color Left
'dynamicClasses.border.11',
],
// Ring Width

@@ -1528,0 +1597,0 @@ 'dynamicClasses.ring.0': [

import { ConfigUtils } from './config/config-utils'
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
const PREFIX_SEPARATOR_REGEX = /:(?![^\s[]*\])/
const PREFIX_SEPARATOR_REGEX = /:(?![^[]*\])/
const PREFIX_SEPARATOR = ':'

@@ -11,6 +13,6 @@

* Set of classGroupIds in following format:
* - No prefix: `:classGroupId`
* - With prefix: `prefix:classGroupId`
* `{importantModifier}{variantPrefixes}{classGroupId}`
* @example ':standaloneClasses.1'
* @example 'hover:focus:dynamicClasses.bg.2'
* @example '!md:dynamicClasses.bg.0'
*/

@@ -22,5 +24,10 @@ const classGroupsInConflict = new Set<string>()

.trim()
.split(/\s+/)
.split(SPLIT_CLASSES_REGEX)
.map((originalClassName) => {
const prefixes = originalClassName.split(PREFIX_SEPARATOR_REGEX)
const hasImportantModifier = originalClassName.startsWith(IMPORTANT_MODIFIER)
const classNameWithoutImportant = hasImportantModifier
? originalClassName.substring(1)
: originalClassName
const prefixes = classNameWithoutImportant.split(PREFIX_SEPARATOR_REGEX)
const className = prefixes.pop()!

@@ -40,7 +47,17 @@

prefixes.sort(configUtils.prefix.compare)
const variantPrefix =
prefixes.length === 0
? ''
: prefixes
.sort(configUtils.prefix.compare)
.concat('')
.join(PREFIX_SEPARATOR)
const fullPrefix = hasImportantModifier
? IMPORTANT_MODIFIER + variantPrefix
: variantPrefix
return {
isTailwindClass: true as const,
prefix: prefixes.join(PREFIX_SEPARATOR),
prefix: fullPrefix,
classGroupId,

@@ -47,0 +64,0 @@ originalClassName,

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