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.4.0 to 0.5.0

dist/types/class-utils.d.ts

104

dist/index.js
import HLRU from 'hashlru';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function getLruCache(cacheSize) {
if (cacheSize >= 1) {
return HLRU(cacheSize);
}
return {
get: () => undefined,
set: () => {}
};
}
const CLASS_PART_SEPARATOR = '-';

@@ -11,3 +40,3 @@ function createClassUtils(config) {

function getGroupId(className) {
function getClassGroupId(className) {
const classParts = className.split(CLASS_PART_SEPARATOR); // 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.

@@ -22,3 +51,3 @@

function getConflictingGroupIds(classGroupId) {
function getConflictingClassGroupIds(classGroupId) {
return config.conflictingClassGroups[classGroupId] || [];

@@ -28,4 +57,4 @@ }

return {
getGroupId,
getConflictingGroupIds
getClassGroupId,
getConflictingClassGroupIds
};

@@ -101,7 +130,7 @@ }

function isValid(maybePrefix) {
function isPrefixValid(maybePrefix) {
return prefixToIndexMap[maybePrefix] !== undefined;
}
function compare(firstPrefix, secondPrefix) {
function comparePrefixes(firstPrefix, secondPrefix) {
return prefixToIndexMap[firstPrefix] - prefixToIndexMap[secondPrefix];

@@ -111,4 +140,4 @@ }

return {
isValid,
compare
isPrefixValid,
comparePrefixes
};

@@ -118,6 +147,5 @@ }

function createConfigUtils(config) {
return {
prefix: createPrefixUtils(config),
class: createClassUtils(config)
};
return _extends({
cache: getLruCache(config.cacheSize)
}, createPrefixUtils(config), createClassUtils(config));
}

@@ -1784,13 +1812,2 @@

function getLruCache(cacheSize) {
if (cacheSize >= 1) {
return HLRU(cacheSize);
}
return {
get: () => undefined,
set: () => {}
};
}
const SPLIT_CLASSES_REGEX = /\s+/;

@@ -1803,2 +1820,8 @@ const IMPORTANT_MODIFIER = '!'; // Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`

function mergeClassList(classList, configUtils) {
const {
isPrefixValid,
getClassGroupId,
comparePrefixes,
getConflictingClassGroupIds
} = configUtils;
/**

@@ -1811,2 +1834,3 @@ * Set of classGroupIds in following format:

*/
const classGroupsInConflict = new Set();

@@ -1818,4 +1842,4 @@ return classList.trim().split(SPLIT_CLASSES_REGEX).map(originalClassName => {

const className = prefixes.pop();
const arePrefixesValid = prefixes.every(configUtils.prefix.isValid);
const classGroupId = arePrefixesValid ? configUtils.class.getGroupId(className) : undefined;
const arePrefixesValid = prefixes.every(isPrefixValid);
const classGroupId = arePrefixesValid ? getClassGroupId(className) : undefined;

@@ -1829,3 +1853,3 @@ if (!classGroupId) {

const variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(configUtils.prefix.compare).concat('').join(PREFIX_SEPARATOR);
const variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(comparePrefixes).concat('').join(PREFIX_SEPARATOR);
const fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;

@@ -1855,3 +1879,3 @@ return {

classGroupsInConflict.add(classId);
configUtils.class.getConflictingGroupIds(classGroupId).forEach(group => classGroupsInConflict.add(`${prefix}:${group}`));
getConflictingClassGroupIds(classGroupId).forEach(group => classGroupsInConflict.add(`${prefix}:${group}`));
return true;

@@ -1862,8 +1886,18 @@ }).reverse().map(parsed => parsed.originalClassName).join(' ');

function createTailwindMerge(createConfig) {
const config = createConfig(getDefaultConfig);
const configUtils = createConfigUtils(config);
const cache = getLruCache(config.cacheSize);
return function tailwindMerge(...classLists) {
let configUtils;
let cacheGet;
let cacheSet;
let functionToCall = initTailwindMerge;
function initTailwindMerge(classLists) {
configUtils = createConfigUtils(createConfig(getDefaultConfig));
cacheGet = configUtils.cache.get;
cacheSet = configUtils.cache.set;
functionToCall = tailwindMerge;
return tailwindMerge(classLists);
}
function tailwindMerge(classLists) {
const classList = classLists.filter(Boolean).join(' ');
const cachedResult = cache.get(classList);
const cachedResult = cacheGet(classList);

@@ -1875,4 +1909,8 @@ if (cachedResult) {

const result = mergeClassList(classList, configUtils);
cache.set(classList, result);
cacheSet(classList, result);
return result;
}
return function callTailwindMerge(...classLists) {
return functionToCall(classLists);
};

@@ -1879,0 +1917,0 @@ }

import HLRU from 'hashlru';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function getLruCache(cacheSize) {
if (cacheSize >= 1) {
return HLRU(cacheSize);
}
return {
get: function get() {
return undefined;
},
set: function set() {}
};
}
var CLASS_PART_SEPARATOR = '-';

@@ -11,3 +42,3 @@ function createClassUtils(config) {

function getGroupId(className) {
function getClassGroupId(className) {
var classParts = className.split(CLASS_PART_SEPARATOR); // 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.

@@ -22,3 +53,3 @@

function getConflictingGroupIds(classGroupId) {
function getConflictingClassGroupIds(classGroupId) {
return config.conflictingClassGroups[classGroupId] || [];

@@ -28,4 +59,4 @@ }

return {
getGroupId: getGroupId,
getConflictingGroupIds: getConflictingGroupIds
getClassGroupId: getClassGroupId,
getConflictingClassGroupIds: getConflictingClassGroupIds
};

@@ -108,7 +139,7 @@ }

function isValid(maybePrefix) {
function isPrefixValid(maybePrefix) {
return prefixToIndexMap[maybePrefix] !== undefined;
}
function compare(firstPrefix, secondPrefix) {
function comparePrefixes(firstPrefix, secondPrefix) {
return prefixToIndexMap[firstPrefix] - prefixToIndexMap[secondPrefix];

@@ -118,4 +149,4 @@ }

return {
isValid: isValid,
compare: compare
isPrefixValid: isPrefixValid,
comparePrefixes: comparePrefixes
};

@@ -125,6 +156,5 @@ }

function createConfigUtils(config) {
return {
prefix: createPrefixUtils(config),
"class": createClassUtils(config)
};
return _extends({
cache: getLruCache(config.cacheSize)
}, createPrefixUtils(config), createClassUtils(config));
}

@@ -1791,15 +1821,2 @@

function getLruCache(cacheSize) {
if (cacheSize >= 1) {
return HLRU(cacheSize);
}
return {
get: function get() {
return undefined;
},
set: function set() {}
};
}
var SPLIT_CLASSES_REGEX = /\s+/;

@@ -1812,2 +1829,6 @@ var IMPORTANT_MODIFIER = '!'; // Regex is needed so we don't match against colons in labels for custom values like `text-[color:var(--mystery-var)]`

function mergeClassList(classList, configUtils) {
var isPrefixValid = configUtils.isPrefixValid,
getClassGroupId = configUtils.getClassGroupId,
comparePrefixes = configUtils.comparePrefixes,
getConflictingClassGroupIds = configUtils.getConflictingClassGroupIds;
/**

@@ -1820,2 +1841,3 @@ * Set of classGroupIds in following format:

*/
var classGroupsInConflict = new Set();

@@ -1827,4 +1849,4 @@ return classList.trim().split(SPLIT_CLASSES_REGEX).map(function (originalClassName) {

var className = prefixes.pop();
var arePrefixesValid = prefixes.every(configUtils.prefix.isValid);
var classGroupId = arePrefixesValid ? configUtils["class"].getGroupId(className) : undefined;
var arePrefixesValid = prefixes.every(isPrefixValid);
var classGroupId = arePrefixesValid ? getClassGroupId(className) : undefined;

@@ -1838,3 +1860,3 @@ if (!classGroupId) {

var variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(configUtils.prefix.compare).concat('').join(PREFIX_SEPARATOR);
var variantPrefix = prefixes.length === 0 ? '' : prefixes.sort(comparePrefixes).concat('').join(PREFIX_SEPARATOR);
var fullPrefix = hasImportantModifier ? IMPORTANT_MODIFIER + variantPrefix : variantPrefix;

@@ -1862,3 +1884,3 @@ return {

classGroupsInConflict.add(classId);
configUtils["class"].getConflictingGroupIds(classGroupId).forEach(function (group) {
getConflictingClassGroupIds(classGroupId).forEach(function (group) {
return classGroupsInConflict.add(prefix + ":" + group);

@@ -1873,9 +1895,19 @@ });

function createTailwindMerge(createConfig) {
var config = createConfig(getDefaultConfig);
var configUtils = createConfigUtils(config);
var cache = getLruCache(config.cacheSize);
return function tailwindMerge() {
var classList = [].slice.call(arguments).filter(Boolean).join(' ');
var cachedResult = cache.get(classList);
var configUtils;
var cacheGet;
var cacheSet;
var functionToCall = initTailwindMerge;
function initTailwindMerge(classLists) {
configUtils = createConfigUtils(createConfig(getDefaultConfig));
cacheGet = configUtils.cache.get;
cacheSet = configUtils.cache.set;
functionToCall = tailwindMerge;
return tailwindMerge(classLists);
}
function tailwindMerge(classLists) {
var classList = classLists.filter(Boolean).join(' ');
var cachedResult = cacheGet(classList);
if (cachedResult) {

@@ -1886,4 +1918,8 @@ return cachedResult;

var result = mergeClassList(classList, configUtils);
cache.set(classList, result);
cacheSet(classList, result);
return result;
}
return function callTailwindMerge() {
return functionToCall([].slice.call(arguments));
};

@@ -1890,0 +1926,0 @@ }

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

interface LruCache<T> {
export interface LruCache<T> {
get(key: string): T | undefined;

@@ -6,2 +6,1 @@ set(key: string, value: T): void;

export declare function getLruCache<T>(cacheSize: number): LruCache<T>;
export {};

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

import { ConfigUtils } from './config/config-utils';
import { ConfigUtils } from './config-utils';
export declare function mergeClassList(classList: string, configUtils: ConfigUtils): string;

@@ -1,6 +0,7 @@

import { getDefaultConfig } from './config/default-config';
import { Config } from './config/types';
import { getDefaultConfig } from './default-config';
import { Config } from './types';
declare type CreateConfig = (getDefault: typeof getDefaultConfig) => Config;
declare type TailwindMerge = (...classLists: Array<string | undefined>) => string;
declare type ClassLists = Array<string | undefined>;
declare type TailwindMerge = (...classLists: ClassLists) => string;
export declare function createTailwindMerge(createConfig: CreateConfig): TailwindMerge;
export {};
{
"name": "tailwind-merge",
"version": "0.4.0",
"version": "0.5.0",
"description": "Merge Tailwind CSS classes without style conflicts",

@@ -43,3 +43,3 @@ "keywords": [

"preversion": "git checkout main && git pull",
"version": "yarn build && node scripts/package-build-stats && git add README.md",
"version": "zx scripts/update-readme.js",
"postversion": "git push --follow-tags && open https://github.com/dcastil/tailwind-merge/releases"

@@ -57,2 +57,3 @@ },

"eslint-plugin-jest": "^24.3.6",
"fp-ts": "^2.10.5",
"jest": "^27.0.6",

@@ -63,4 +64,5 @@ "microbundle": "^0.13.3",

"ts-jest": "^27.0.3",
"typescript": "^4.3.5"
"typescript": "^4.3.5",
"zx": "^2.0.0"
}
}
<div align="center">
<br />
<a href="https://github.com/dcastil/tailwind-merge">
<img src="https://github.com/dcastil/tailwind-merge/raw/v0.4.0/assets/logo.svg" alt="tailwind-merge" width="221px" />
<!-- AUTOGENERATED START logo-image --><img src="https://github.com/dcastil/tailwind-merge/raw/v0.5.0/assets/logo.svg" alt="tailwind-merge" width="221px" /><!-- AUTOGENERATED END -->
</a>

@@ -19,6 +19,6 @@ </div>

- Supports Tailwind v2.0.0 up to v2.2.5, support for newer version will be added continuously
- Supports Tailwind v2.0.0 up to v2.2.6, support for newer version will be added continuously
- Works in Node >=12 and all modern browsers
- Fully typed
- [<!-- AUTOGENERATED START package-build-stats:gzipSize -->4.6 kB<!-- AUTOGENERATED END --> minified + gzipped](https://bundlephobia.com/package/tailwind-merge) (<!-- AUTOGENERATED START package-build-stats:composition -->95.9% self, 4.1% hashlru<!-- AUTOGENERATED END -->)
- [<!-- AUTOGENERATED START package-gzip-size -->4.7 kB<!-- AUTOGENERATED END --> minified + gzipped](https://bundlephobia.com/package/tailwind-merge) (<!-- AUTOGENERATED START package-composition -->96.1% self, 3.9% hashlru<!-- AUTOGENERATED END -->)

@@ -65,3 +65,4 @@ ## What is it for

- 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).
- Expensive computations happen during startup time so that `twMerge()` calls without a cache hit stay fast.
- Expensive computations happen upfront so that `twMerge()` calls without a cache hit stay fast.
- 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.

@@ -152,2 +153,4 @@ ### Last conflicting class wins

```ts
// ↓ Callback passed to `createTailwindMerge()` is called when
// `customTwMerge()` gets called the first time.
const customTwMerge = createTailwindMerge((getDefaultConfig) => {

@@ -154,0 +157,0 @@ const defaultConfig = getDefaultConfig()

import HLRU from 'hashlru'
interface LruCache<T> {
// Export is needed because TypeScript complains about an error otherwise:
// Error: …/tailwind-merge/src/config-utils.ts(8,17): semantic error TS4058: Return type of exported function has or is using name 'LruCache' from external module "…/tailwind-merge/src/lru-cache" but cannot be named.
export interface LruCache<T> {
get(key: string): T | undefined

@@ -5,0 +7,0 @@ set(key: string, value: T): void

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

import { ConfigUtils } from './config/config-utils'
import { ConfigUtils } from './config-utils'

@@ -11,2 +11,5 @@ const SPLIT_CLASSES_REGEX = /\s+/

export function mergeClassList(classList: string, configUtils: ConfigUtils) {
const { isPrefixValid, getClassGroupId, comparePrefixes, getConflictingClassGroupIds } =
configUtils
/**

@@ -34,6 +37,4 @@ * Set of classGroupIds in following format:

const arePrefixesValid = prefixes.every(configUtils.prefix.isValid)
const classGroupId = arePrefixesValid
? configUtils.class.getGroupId(className)
: undefined
const arePrefixesValid = prefixes.every(isPrefixValid)
const classGroupId = arePrefixesValid ? getClassGroupId(className) : undefined

@@ -50,6 +51,3 @@ if (!classGroupId) {

? ''
: prefixes
.sort(configUtils.prefix.compare)
.concat('')
.join(PREFIX_SEPARATOR)
: prefixes.sort(comparePrefixes).concat('').join(PREFIX_SEPARATOR)

@@ -83,6 +81,7 @@ const fullPrefix = hasImportantModifier

classGroupsInConflict.add(classId)
configUtils.class
.getConflictingGroupIds(classGroupId)
.forEach((group) => classGroupsInConflict.add(`${prefix}:${group}`))
getConflictingClassGroupIds(classGroupId).forEach((group) =>
classGroupsInConflict.add(`${prefix}:${group}`)
)
return true

@@ -89,0 +88,0 @@ })

@@ -1,18 +0,29 @@

import { createConfigUtils } from './config/config-utils'
import { getDefaultConfig } from './config/default-config'
import { Config } from './config/types'
import { getLruCache } from './lru-cache'
import { createConfigUtils } from './config-utils'
import { getDefaultConfig } from './default-config'
import { Config } from './types'
import { mergeClassList } from './merge-classlist'
type CreateConfig = (getDefault: typeof getDefaultConfig) => Config
type TailwindMerge = (...classLists: Array<string | undefined>) => string
type ClassLists = Array<string | undefined>
type TailwindMerge = (...classLists: ClassLists) => string
type ConfigUtils = ReturnType<typeof createConfigUtils>
export function createTailwindMerge(createConfig: CreateConfig): TailwindMerge {
const config = createConfig(getDefaultConfig)
const configUtils = createConfigUtils(config)
const cache = getLruCache<string>(config.cacheSize)
let configUtils: ConfigUtils
let cacheGet: ConfigUtils['cache']['get']
let cacheSet: ConfigUtils['cache']['set']
let functionToCall = initTailwindMerge
return function tailwindMerge(...classLists) {
function initTailwindMerge(classLists: ClassLists) {
configUtils = createConfigUtils(createConfig(getDefaultConfig))
cacheGet = configUtils.cache.get
cacheSet = configUtils.cache.set
functionToCall = tailwindMerge
return tailwindMerge(classLists)
}
function tailwindMerge(classLists: ClassLists) {
const classList = classLists.filter(Boolean).join(' ')
const cachedResult = cache.get(classList)
const cachedResult = cacheGet(classList)

@@ -24,6 +35,10 @@ if (cachedResult) {

const result = mergeClassList(classList, configUtils)
cache.set(classList, result)
cacheSet(classList, result)
return result
}
return function callTailwindMerge(...classLists) {
return functionToCall(classLists)
}
}

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