UEA-PRODEM

This commit is contained in:
2026-06-10 12:14:46 -03:00
parent f54126b9d8
commit 9947565694
5319 changed files with 148520 additions and 129332 deletions
+13 -13
View File
@@ -3,7 +3,7 @@
<div align="center">
<br />
<a href="https://github.com/dcastil/tailwind-merge">
<img src="https://github.com/dcastil/tailwind-merge/raw/v3.4.0/assets/logo.svg" alt="tailwind-merge" height="150px" />
<img src="https://github.com/dcastil/tailwind-merge/raw/v3.6.0/assets/logo.svg" alt="tailwind-merge" height="150px" />
</a>
</div>
@@ -18,21 +18,21 @@ twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
// → 'hover:bg-dark-red p-3 bg-[#B91C1C]'
```
- Supports Tailwind v4.0 up to v4.1 (if you use Tailwind v3, use [tailwind-merge v2.6.0](https://github.com/dcastil/tailwind-merge/tree/v2.6.0))
- Supports Tailwind v4.0 up to v4.3 (if you use Tailwind v3, use [tailwind-merge v2.6.0](https://github.com/dcastil/tailwind-merge/tree/v2.6.0))
- Works in all modern browsers and maintained Node versions
- Fully typed
- [Check bundle size on Bundlephobia](https://bundlephobia.com/package/tailwind-merge)
## Get started
- [What is it for](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/what-is-it-for.md)
- [When and how to use it](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/when-and-how-to-use-it.md)
- [Features](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/features.md)
- [Limitations](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/limitations.md)
- [Configuration](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/configuration.md)
- [Recipes](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/recipes.md)
- [API reference](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/api-reference.md)
- [Writing plugins](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/writing-plugins.md)
- [Versioning](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/versioning.md)
- [Contributing](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/contributing.md)
- [Similar packages](https://github.com/dcastil/tailwind-merge/tree/v3.4.0/docs/similar-packages.md)
- [What is it for](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/what-is-it-for.md)
- [When and how to use it](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/when-and-how-to-use-it.md)
- [Features](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/features.md)
- [Limitations](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/limitations.md)
- [Configuration](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/configuration.md)
- [Recipes](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/recipes.md)
- [API reference](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/api-reference.md)
- [Writing plugins](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/writing-plugins.md)
- [Versioning](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/versioning.md)
- [Contributing](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/contributing.md)
- [Similar packages](https://github.com/dcastil/tailwind-merge/blob/v3.6.0/docs/similar-packages.md)
+292 -41
View File
@@ -351,15 +351,27 @@ const createConfigUtils = config => ({
cache: createLruCache(config.cacheSize),
parseClassName: createParseClassName(config),
sortModifiers: createSortModifiers(config),
postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config),
...createClassGroupUtils(config)
});
const createPostfixLookupClassGroupIds = config => {
const lookup = Object.create(null);
const classGroupIds = config.postfixLookupClassGroups;
if (classGroupIds) {
for (let i = 0; i < classGroupIds.length; i++) {
lookup[classGroupIds[i]] = true;
}
}
return lookup;
};
const SPLIT_CLASSES_REGEX = /\s+/;
const mergeClassList = (classList, configUtils) => {
const {
parseClassName,
getClassGroupId,
getConflictingClassGroupIds,
sortModifiers
sortModifiers,
postfixLookupClassGroupIds
} = configUtils;
/**
* Set of classGroupIds in following format:
@@ -385,7 +397,18 @@ const mergeClassList = (classList, configUtils) => {
continue;
}
let hasPostfixModifier = !!maybePostfixModifierPosition;
let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
let classGroupId;
if (hasPostfixModifier) {
const baseClassNameWithoutPostfix = baseClassName.substring(0, maybePostfixModifierPosition);
classGroupId = getClassGroupId(baseClassNameWithoutPostfix);
const classGroupIdWithPostfix = classGroupId && postfixLookupClassGroupIds[classGroupId] ? getClassGroupId(baseClassName) : undefined;
if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {
classGroupId = classGroupIdWithPostfix;
hasPostfixModifier = false;
}
} else {
classGroupId = getClassGroupId(baseClassName);
}
if (!classGroupId) {
if (!hasPostfixModifier) {
// Not a Tailwind class
@@ -494,7 +517,7 @@ const fromTheme = key => {
};
const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
const fractionRegex = /^\d+\/\d+$/;
const fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/;
const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
@@ -516,10 +539,13 @@ const isNever = () => false;
const isShadow = value => shadowRegex.test(value);
const isImage = value => imageRegex.test(value);
const isAnyNonArbitrary = value => !isArbitraryValue(value) && !isArbitraryVariable(value);
const isNamedContainerQuery = value => value.startsWith('@container') && (value[10] === '/' && value[11] !== undefined || value[11] === 's' && value[16] !== undefined && value.startsWith('-size/', 10) || value[11] === 'n' && value[18] !== undefined && value.startsWith('-normal/', 10));
const isArbitrarySize = value => getIsArbitraryValue(value, isLabelSize, isNever);
const isArbitraryValue = value => arbitraryValueRegex.test(value);
const isArbitraryLength = value => getIsArbitraryValue(value, isLabelLength, isLengthOnly);
const isArbitraryNumber = value => getIsArbitraryValue(value, isLabelNumber, isNumber);
const isArbitraryWeight = value => getIsArbitraryValue(value, isLabelWeight, isAny);
const isArbitraryFamilyName = value => getIsArbitraryValue(value, isLabelFamilyName, isNever);
const isArbitraryPosition = value => getIsArbitraryValue(value, isLabelPosition, isNever);
const isArbitraryImage = value => getIsArbitraryValue(value, isLabelImage, isImage);
const isArbitraryShadow = value => getIsArbitraryValue(value, isLabelShadow, isShadow);
@@ -530,6 +556,7 @@ const isArbitraryVariablePosition = value => getIsArbitraryVariable(value, isLab
const isArbitraryVariableSize = value => getIsArbitraryVariable(value, isLabelSize);
const isArbitraryVariableImage = value => getIsArbitraryVariable(value, isLabelImage);
const isArbitraryVariableShadow = value => getIsArbitraryVariable(value, isLabelShadow, true);
const isArbitraryVariableWeight = value => getIsArbitraryVariable(value, isLabelWeight, true);
// Helpers
const getIsArbitraryValue = (value, testLabel, testValue) => {
const result = arbitraryValueRegex.exec(value);
@@ -558,11 +585,13 @@ const isLabelSize = label => label === 'length' || label === 'size' || label ===
const isLabelLength = label => label === 'length';
const isLabelNumber = label => label === 'number';
const isLabelFamilyName = label => label === 'family-name';
const isLabelWeight = label => label === 'number' || label === 'weight';
const isLabelShadow = label => label === 'shadow';
const validators = /*#__PURE__*/Object.defineProperty({
__proto__: null,
isAny,
isAnyNonArbitrary,
isArbitraryFamilyName,
isArbitraryImage,
isArbitraryLength,
isArbitraryNumber,
@@ -577,8 +606,11 @@ const validators = /*#__PURE__*/Object.defineProperty({
isArbitraryVariablePosition,
isArbitraryVariableShadow,
isArbitraryVariableSize,
isArbitraryVariableWeight,
isArbitraryWeight,
isFraction,
isInteger,
isNamedContainerQuery,
isNumber,
isPercent,
isTshirtSize
@@ -642,6 +674,8 @@ const getDefaultConfig = () => {
const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch', 'center-safe', 'end-safe'];
const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()];
const scaleSizing = () => [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
const scaleSizingInline = () => [isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
const scaleSizingBlock = () => [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];
const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {
position: [isArbitraryVariable, isArbitraryValue]
@@ -707,6 +741,18 @@ const getDefaultConfig = () => {
* @deprecated since Tailwind CSS v4.0.0
*/
container: ['container'],
/**
* Container Type
* @see https://tailwindcss.com/docs/responsive-design#container-queries
*/
'container-type': [{
'@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue]
}],
/**
* Container Name
* @see https://tailwindcss.com/docs/responsive-design#named-containers
*/
'container-named': [isNamedContainerQuery],
/**
* Columns
* @see https://tailwindcss.com/docs/columns
@@ -840,40 +886,66 @@ const getDefaultConfig = () => {
*/
position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],
/**
* Top / Right / Bottom / Left
* Inset
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
inset: [{
inset: scaleInset()
}],
/**
* Right / Left
* Inset Inline
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-x': [{
'inset-x': scaleInset()
}],
/**
* Top / Bottom
* Inset Block
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-y': [{
'inset-y': scaleInset()
}],
/**
* Start
* Inset Inline Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-s` in next major release
*/
start: [{
'inset-s': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-s-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
start: scaleInset()
}],
/**
* End
* Inset Inline End
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-e` in next major release
*/
end: [{
'inset-e': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-e-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
end: scaleInset()
}],
/**
* Inset Block Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-bs': [{
'inset-bs': scaleInset()
}],
/**
* Inset Block End
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-be': [{
'inset-be': scaleInset()
}],
/**
* Top
* @see https://tailwindcss.com/docs/top-right-bottom-left
@@ -1140,33 +1212,47 @@ const getDefaultConfig = () => {
p: scaleUnambiguousSpacing()
}],
/**
* Padding X
* Padding Inline
* @see https://tailwindcss.com/docs/padding
*/
px: [{
px: scaleUnambiguousSpacing()
}],
/**
* Padding Y
* Padding Block
* @see https://tailwindcss.com/docs/padding
*/
py: [{
py: scaleUnambiguousSpacing()
}],
/**
* Padding Start
* Padding Inline Start
* @see https://tailwindcss.com/docs/padding
*/
ps: [{
ps: scaleUnambiguousSpacing()
}],
/**
* Padding End
* Padding Inline End
* @see https://tailwindcss.com/docs/padding
*/
pe: [{
pe: scaleUnambiguousSpacing()
}],
/**
* Padding Block Start
* @see https://tailwindcss.com/docs/padding
*/
pbs: [{
pbs: scaleUnambiguousSpacing()
}],
/**
* Padding Block End
* @see https://tailwindcss.com/docs/padding
*/
pbe: [{
pbe: scaleUnambiguousSpacing()
}],
/**
* Padding Top
* @see https://tailwindcss.com/docs/padding
@@ -1203,33 +1289,47 @@ const getDefaultConfig = () => {
m: scaleMargin()
}],
/**
* Margin X
* Margin Inline
* @see https://tailwindcss.com/docs/margin
*/
mx: [{
mx: scaleMargin()
}],
/**
* Margin Y
* Margin Block
* @see https://tailwindcss.com/docs/margin
*/
my: [{
my: scaleMargin()
}],
/**
* Margin Start
* Margin Inline Start
* @see https://tailwindcss.com/docs/margin
*/
ms: [{
ms: scaleMargin()
}],
/**
* Margin End
* Margin Inline End
* @see https://tailwindcss.com/docs/margin
*/
me: [{
me: scaleMargin()
}],
/**
* Margin Block Start
* @see https://tailwindcss.com/docs/margin
*/
mbs: [{
mbs: scaleMargin()
}],
/**
* Margin Block End
* @see https://tailwindcss.com/docs/margin
*/
mbe: [{
mbe: scaleMargin()
}],
/**
* Margin Top
* @see https://tailwindcss.com/docs/margin
@@ -1292,6 +1392,48 @@ const getDefaultConfig = () => {
size: [{
size: scaleSizing()
}],
/**
* Inline Size
* @see https://tailwindcss.com/docs/width
*/
'inline-size': [{
inline: ['auto', ...scaleSizingInline()]
}],
/**
* Min-Inline Size
* @see https://tailwindcss.com/docs/min-width
*/
'min-inline-size': [{
'min-inline': ['auto', ...scaleSizingInline()]
}],
/**
* Max-Inline Size
* @see https://tailwindcss.com/docs/max-width
*/
'max-inline-size': [{
'max-inline': ['none', ...scaleSizingInline()]
}],
/**
* Block Size
* @see https://tailwindcss.com/docs/height
*/
'block-size': [{
block: ['auto', ...scaleSizingBlock()]
}],
/**
* Min-Block Size
* @see https://tailwindcss.com/docs/min-height
*/
'min-block-size': [{
'min-block': ['auto', ...scaleSizingBlock()]
}],
/**
* Max-Block Size
* @see https://tailwindcss.com/docs/max-height
*/
'max-block-size': [{
'max-block': ['none', ...scaleSizingBlock()]
}],
/**
* Width
* @see https://tailwindcss.com/docs/width
@@ -1364,7 +1506,7 @@ const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/font-weight
*/
'font-weight': [{
font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber]
font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight]
}],
/**
* Font Stretch
@@ -1378,7 +1520,14 @@ const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/font-family
*/
'font-family': [{
font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont]
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont]
}],
/**
* Font Feature Settings
* @see https://tailwindcss.com/docs/font-feature-settings
*/
'font-features': [{
'font-features': [isArbitraryValue]
}],
/**
* Font Variant Numeric
@@ -1532,6 +1681,13 @@ const getDefaultConfig = () => {
indent: [{
indent: scaleUnambiguousSpacing()
}],
/**
* Tab Size
* @see https://tailwindcss.com/docs/tab-size
*/
'tab-size': [{
tab: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
/**
* Vertical Alignment
* @see https://tailwindcss.com/docs/vertical-align
@@ -1797,33 +1953,47 @@ const getDefaultConfig = () => {
border: scaleBorderWidth()
}],
/**
* Border Width X
* Border Width Inline
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-x': [{
'border-x': scaleBorderWidth()
}],
/**
* Border Width Y
* Border Width Block
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-y': [{
'border-y': scaleBorderWidth()
}],
/**
* Border Width Start
* Border Width Inline Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-s': [{
'border-s': scaleBorderWidth()
}],
/**
* Border Width End
* Border Width Inline End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-e': [{
'border-e': scaleBorderWidth()
}],
/**
* Border Width Block Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-bs': [{
'border-bs': scaleBorderWidth()
}],
/**
* Border Width Block End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-be': [{
'border-be': scaleBorderWidth()
}],
/**
* Border Width Top
* @see https://tailwindcss.com/docs/border-width
@@ -1898,33 +2068,47 @@ const getDefaultConfig = () => {
border: scaleColor()
}],
/**
* Border Color X
* Border Color Inline
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-x': [{
'border-x': scaleColor()
}],
/**
* Border Color Y
* Border Color Block
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-y': [{
'border-y': scaleColor()
}],
/**
* Border Color S
* Border Color Inline Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-s': [{
'border-s': scaleColor()
}],
/**
* Border Color E
* Border Color Inline End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-e': [{
'border-e': scaleColor()
}],
/**
* Border Color Block Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-bs': [{
'border-bs': scaleColor()
}],
/**
* Border Color Block End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-be': [{
'border-be': scaleColor()
}],
/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
@@ -2711,6 +2895,13 @@ const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/translate
*/
'translate-none': ['translate-none'],
/**
* Zoom
* @see https://tailwindcss.com/docs/zoom
*/
zoom: [{
zoom: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
// ---------------------
// --- Interactivity ---
// ---------------------
@@ -2777,6 +2968,34 @@ const getDefaultConfig = () => {
'scroll-behavior': [{
scroll: ['auto', 'smooth']
}],
/**
* Scrollbar Thumb Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-thumb-color': [{
'scrollbar-thumb': scaleColor()
}],
/**
* Scrollbar Track Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-track-color': [{
'scrollbar-track': scaleColor()
}],
/**
* Scrollbar Gutter
* @see https://tailwindcss.com/docs/scrollbar-gutter
*/
'scrollbar-gutter': [{
'scrollbar-gutter': ['auto', 'stable', 'both']
}],
/**
* Scrollbar Width
* @see https://tailwindcss.com/docs/scrollbar-width
*/
'scrollbar-w': [{
scrollbar: ['auto', 'thin', 'none']
}],
/**
* Scroll Margin
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2785,33 +3004,47 @@ const getDefaultConfig = () => {
'scroll-m': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin X
* Scroll Margin Inline
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mx': [{
'scroll-mx': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Y
* Scroll Margin Block
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-my': [{
'scroll-my': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Start
* Scroll Margin Inline Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-ms': [{
'scroll-ms': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin End
* Scroll Margin Inline End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-me': [{
'scroll-me': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbs': [{
'scroll-mbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbe': [{
'scroll-mbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Top
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2848,33 +3081,47 @@ const getDefaultConfig = () => {
'scroll-p': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding X
* Scroll Padding Inline
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-px': [{
'scroll-px': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Y
* Scroll Padding Block
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-py': [{
'scroll-py': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Start
* Scroll Padding Inline Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-ps': [{
'scroll-ps': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding End
* Scroll Padding Inline End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pe': [{
'scroll-pe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbs': [{
'scroll-pbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbe': [{
'scroll-pbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Top
* @see https://tailwindcss.com/docs/scroll-padding
@@ -3007,17 +3254,18 @@ const getDefaultConfig = () => {
}]
},
conflictingClassGroups: {
'container-named': ['container-type'],
overflow: ['overflow-x', 'overflow-y'],
overscroll: ['overscroll-x', 'overscroll-y'],
inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],
inset: ['inset-x', 'inset-y', 'inset-bs', 'inset-be', 'start', 'end', 'top', 'right', 'bottom', 'left'],
'inset-x': ['right', 'left'],
'inset-y': ['top', 'bottom'],
flex: ['basis', 'grow', 'shrink'],
gap: ['gap-x', 'gap-y'],
p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],
p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
px: ['pr', 'pl'],
py: ['pt', 'pb'],
m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],
m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
mx: ['mr', 'ml'],
my: ['mt', 'mb'],
size: ['w', 'h'],
@@ -3037,18 +3285,18 @@ const getDefaultConfig = () => {
'rounded-b': ['rounded-br', 'rounded-bl'],
'rounded-l': ['rounded-tl', 'rounded-bl'],
'border-spacing': ['border-spacing-x', 'border-spacing-y'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-bs', 'border-w-be', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w-x': ['border-w-r', 'border-w-l'],
'border-w-y': ['border-w-t', 'border-w-b'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-bs', 'border-color-be', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color-x': ['border-color-r', 'border-color-l'],
'border-color-y': ['border-color-t', 'border-color-b'],
translate: ['translate-x', 'translate-y', 'translate-none'],
'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-mx': ['scroll-mr', 'scroll-ml'],
'scroll-my': ['scroll-mt', 'scroll-mb'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-px': ['scroll-pr', 'scroll-pl'],
'scroll-py': ['scroll-pt', 'scroll-pb'],
touch: ['touch-x', 'touch-y', 'touch-pz'],
@@ -3059,6 +3307,7 @@ const getDefaultConfig = () => {
conflictingClassGroupModifiers: {
'font-size': ['leading']
},
postfixLookupClassGroups: ['container-type'],
orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
};
};
@@ -3081,11 +3330,13 @@ const mergeConfigs = (baseConfig, {
overrideConfigProperties(baseConfig.classGroups, override.classGroups);
overrideConfigProperties(baseConfig.conflictingClassGroups, override.conflictingClassGroups);
overrideConfigProperties(baseConfig.conflictingClassGroupModifiers, override.conflictingClassGroupModifiers);
overrideProperty(baseConfig, 'postfixLookupClassGroups', override.postfixLookupClassGroups);
overrideProperty(baseConfig, 'orderSensitiveModifiers', override.orderSensitiveModifiers);
mergeConfigProperties(baseConfig.theme, extend.theme);
mergeConfigProperties(baseConfig.classGroups, extend.classGroups);
mergeConfigProperties(baseConfig.conflictingClassGroups, extend.conflictingClassGroups);
mergeConfigProperties(baseConfig.conflictingClassGroupModifiers, extend.conflictingClassGroupModifiers);
mergeArrayProperties(baseConfig, extend, 'postfixLookupClassGroups');
mergeArrayProperties(baseConfig, extend, 'orderSensitiveModifiers');
return baseConfig;
};
File diff suppressed because one or more lines are too long
+292 -41
View File
@@ -345,15 +345,27 @@ const createConfigUtils = config => ({
cache: createLruCache(config.cacheSize),
parseClassName: createParseClassName(config),
sortModifiers: createSortModifiers(config),
postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config),
...createClassGroupUtils(config)
});
const createPostfixLookupClassGroupIds = config => {
const lookup = Object.create(null);
const classGroupIds = config.postfixLookupClassGroups;
if (classGroupIds) {
for (let i = 0; i < classGroupIds.length; i++) {
lookup[classGroupIds[i]] = true;
}
}
return lookup;
};
const SPLIT_CLASSES_REGEX = /\s+/;
const mergeClassList = (classList, configUtils) => {
const {
parseClassName,
getClassGroupId,
getConflictingClassGroupIds,
sortModifiers
sortModifiers,
postfixLookupClassGroupIds
} = configUtils;
/**
* Set of classGroupIds in following format:
@@ -379,7 +391,18 @@ const mergeClassList = (classList, configUtils) => {
continue;
}
let hasPostfixModifier = !!maybePostfixModifierPosition;
let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
let classGroupId;
if (hasPostfixModifier) {
const baseClassNameWithoutPostfix = baseClassName.substring(0, maybePostfixModifierPosition);
classGroupId = getClassGroupId(baseClassNameWithoutPostfix);
const classGroupIdWithPostfix = classGroupId && postfixLookupClassGroupIds[classGroupId] ? getClassGroupId(baseClassName) : undefined;
if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {
classGroupId = classGroupIdWithPostfix;
hasPostfixModifier = false;
}
} else {
classGroupId = getClassGroupId(baseClassName);
}
if (!classGroupId) {
if (!hasPostfixModifier) {
// Not a Tailwind class
@@ -488,7 +511,7 @@ const fromTheme = key => {
};
const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
const fractionRegex = /^\d+\/\d+$/;
const fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/;
const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
@@ -510,10 +533,13 @@ const isNever = () => false;
const isShadow = value => shadowRegex.test(value);
const isImage = value => imageRegex.test(value);
const isAnyNonArbitrary = value => !isArbitraryValue(value) && !isArbitraryVariable(value);
const isNamedContainerQuery = value => value.startsWith('@container') && (value[10] === '/' && value[11] !== undefined || value[11] === 's' && value[16] !== undefined && value.startsWith('-size/', 10) || value[11] === 'n' && value[18] !== undefined && value.startsWith('-normal/', 10));
const isArbitrarySize = value => getIsArbitraryValue(value, isLabelSize, isNever);
const isArbitraryValue = value => arbitraryValueRegex.test(value);
const isArbitraryLength = value => getIsArbitraryValue(value, isLabelLength, isLengthOnly);
const isArbitraryNumber = value => getIsArbitraryValue(value, isLabelNumber, isNumber);
const isArbitraryWeight = value => getIsArbitraryValue(value, isLabelWeight, isAny);
const isArbitraryFamilyName = value => getIsArbitraryValue(value, isLabelFamilyName, isNever);
const isArbitraryPosition = value => getIsArbitraryValue(value, isLabelPosition, isNever);
const isArbitraryImage = value => getIsArbitraryValue(value, isLabelImage, isImage);
const isArbitraryShadow = value => getIsArbitraryValue(value, isLabelShadow, isShadow);
@@ -524,6 +550,7 @@ const isArbitraryVariablePosition = value => getIsArbitraryVariable(value, isLab
const isArbitraryVariableSize = value => getIsArbitraryVariable(value, isLabelSize);
const isArbitraryVariableImage = value => getIsArbitraryVariable(value, isLabelImage);
const isArbitraryVariableShadow = value => getIsArbitraryVariable(value, isLabelShadow, true);
const isArbitraryVariableWeight = value => getIsArbitraryVariable(value, isLabelWeight, true);
// Helpers
const getIsArbitraryValue = (value, testLabel, testValue) => {
const result = arbitraryValueRegex.exec(value);
@@ -552,11 +579,13 @@ const isLabelSize = label => label === 'length' || label === 'size' || label ===
const isLabelLength = label => label === 'length';
const isLabelNumber = label => label === 'number';
const isLabelFamilyName = label => label === 'family-name';
const isLabelWeight = label => label === 'number' || label === 'weight';
const isLabelShadow = label => label === 'shadow';
const validators = /*#__PURE__*/Object.defineProperty({
__proto__: null,
isAny,
isAnyNonArbitrary,
isArbitraryFamilyName,
isArbitraryImage,
isArbitraryLength,
isArbitraryNumber,
@@ -571,8 +600,11 @@ const validators = /*#__PURE__*/Object.defineProperty({
isArbitraryVariablePosition,
isArbitraryVariableShadow,
isArbitraryVariableSize,
isArbitraryVariableWeight,
isArbitraryWeight,
isFraction,
isInteger,
isNamedContainerQuery,
isNumber,
isPercent,
isTshirtSize
@@ -636,6 +668,8 @@ const getDefaultConfig = () => {
const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch', 'center-safe', 'end-safe'];
const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()];
const scaleSizing = () => [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
const scaleSizingInline = () => [isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
const scaleSizingBlock = () => [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];
const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];
const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {
position: [isArbitraryVariable, isArbitraryValue]
@@ -701,6 +735,18 @@ const getDefaultConfig = () => {
* @deprecated since Tailwind CSS v4.0.0
*/
container: ['container'],
/**
* Container Type
* @see https://tailwindcss.com/docs/responsive-design#container-queries
*/
'container-type': [{
'@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue]
}],
/**
* Container Name
* @see https://tailwindcss.com/docs/responsive-design#named-containers
*/
'container-named': [isNamedContainerQuery],
/**
* Columns
* @see https://tailwindcss.com/docs/columns
@@ -834,40 +880,66 @@ const getDefaultConfig = () => {
*/
position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],
/**
* Top / Right / Bottom / Left
* Inset
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
inset: [{
inset: scaleInset()
}],
/**
* Right / Left
* Inset Inline
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-x': [{
'inset-x': scaleInset()
}],
/**
* Top / Bottom
* Inset Block
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-y': [{
'inset-y': scaleInset()
}],
/**
* Start
* Inset Inline Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-s` in next major release
*/
start: [{
'inset-s': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-s-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
start: scaleInset()
}],
/**
* End
* Inset Inline End
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-e` in next major release
*/
end: [{
'inset-e': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-e-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
end: scaleInset()
}],
/**
* Inset Block Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-bs': [{
'inset-bs': scaleInset()
}],
/**
* Inset Block End
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-be': [{
'inset-be': scaleInset()
}],
/**
* Top
* @see https://tailwindcss.com/docs/top-right-bottom-left
@@ -1134,33 +1206,47 @@ const getDefaultConfig = () => {
p: scaleUnambiguousSpacing()
}],
/**
* Padding X
* Padding Inline
* @see https://tailwindcss.com/docs/padding
*/
px: [{
px: scaleUnambiguousSpacing()
}],
/**
* Padding Y
* Padding Block
* @see https://tailwindcss.com/docs/padding
*/
py: [{
py: scaleUnambiguousSpacing()
}],
/**
* Padding Start
* Padding Inline Start
* @see https://tailwindcss.com/docs/padding
*/
ps: [{
ps: scaleUnambiguousSpacing()
}],
/**
* Padding End
* Padding Inline End
* @see https://tailwindcss.com/docs/padding
*/
pe: [{
pe: scaleUnambiguousSpacing()
}],
/**
* Padding Block Start
* @see https://tailwindcss.com/docs/padding
*/
pbs: [{
pbs: scaleUnambiguousSpacing()
}],
/**
* Padding Block End
* @see https://tailwindcss.com/docs/padding
*/
pbe: [{
pbe: scaleUnambiguousSpacing()
}],
/**
* Padding Top
* @see https://tailwindcss.com/docs/padding
@@ -1197,33 +1283,47 @@ const getDefaultConfig = () => {
m: scaleMargin()
}],
/**
* Margin X
* Margin Inline
* @see https://tailwindcss.com/docs/margin
*/
mx: [{
mx: scaleMargin()
}],
/**
* Margin Y
* Margin Block
* @see https://tailwindcss.com/docs/margin
*/
my: [{
my: scaleMargin()
}],
/**
* Margin Start
* Margin Inline Start
* @see https://tailwindcss.com/docs/margin
*/
ms: [{
ms: scaleMargin()
}],
/**
* Margin End
* Margin Inline End
* @see https://tailwindcss.com/docs/margin
*/
me: [{
me: scaleMargin()
}],
/**
* Margin Block Start
* @see https://tailwindcss.com/docs/margin
*/
mbs: [{
mbs: scaleMargin()
}],
/**
* Margin Block End
* @see https://tailwindcss.com/docs/margin
*/
mbe: [{
mbe: scaleMargin()
}],
/**
* Margin Top
* @see https://tailwindcss.com/docs/margin
@@ -1286,6 +1386,48 @@ const getDefaultConfig = () => {
size: [{
size: scaleSizing()
}],
/**
* Inline Size
* @see https://tailwindcss.com/docs/width
*/
'inline-size': [{
inline: ['auto', ...scaleSizingInline()]
}],
/**
* Min-Inline Size
* @see https://tailwindcss.com/docs/min-width
*/
'min-inline-size': [{
'min-inline': ['auto', ...scaleSizingInline()]
}],
/**
* Max-Inline Size
* @see https://tailwindcss.com/docs/max-width
*/
'max-inline-size': [{
'max-inline': ['none', ...scaleSizingInline()]
}],
/**
* Block Size
* @see https://tailwindcss.com/docs/height
*/
'block-size': [{
block: ['auto', ...scaleSizingBlock()]
}],
/**
* Min-Block Size
* @see https://tailwindcss.com/docs/min-height
*/
'min-block-size': [{
'min-block': ['auto', ...scaleSizingBlock()]
}],
/**
* Max-Block Size
* @see https://tailwindcss.com/docs/max-height
*/
'max-block-size': [{
'max-block': ['none', ...scaleSizingBlock()]
}],
/**
* Width
* @see https://tailwindcss.com/docs/width
@@ -1358,7 +1500,7 @@ const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/font-weight
*/
'font-weight': [{
font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber]
font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight]
}],
/**
* Font Stretch
@@ -1372,7 +1514,14 @@ const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/font-family
*/
'font-family': [{
font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont]
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont]
}],
/**
* Font Feature Settings
* @see https://tailwindcss.com/docs/font-feature-settings
*/
'font-features': [{
'font-features': [isArbitraryValue]
}],
/**
* Font Variant Numeric
@@ -1526,6 +1675,13 @@ const getDefaultConfig = () => {
indent: [{
indent: scaleUnambiguousSpacing()
}],
/**
* Tab Size
* @see https://tailwindcss.com/docs/tab-size
*/
'tab-size': [{
tab: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
/**
* Vertical Alignment
* @see https://tailwindcss.com/docs/vertical-align
@@ -1791,33 +1947,47 @@ const getDefaultConfig = () => {
border: scaleBorderWidth()
}],
/**
* Border Width X
* Border Width Inline
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-x': [{
'border-x': scaleBorderWidth()
}],
/**
* Border Width Y
* Border Width Block
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-y': [{
'border-y': scaleBorderWidth()
}],
/**
* Border Width Start
* Border Width Inline Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-s': [{
'border-s': scaleBorderWidth()
}],
/**
* Border Width End
* Border Width Inline End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-e': [{
'border-e': scaleBorderWidth()
}],
/**
* Border Width Block Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-bs': [{
'border-bs': scaleBorderWidth()
}],
/**
* Border Width Block End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-be': [{
'border-be': scaleBorderWidth()
}],
/**
* Border Width Top
* @see https://tailwindcss.com/docs/border-width
@@ -1892,33 +2062,47 @@ const getDefaultConfig = () => {
border: scaleColor()
}],
/**
* Border Color X
* Border Color Inline
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-x': [{
'border-x': scaleColor()
}],
/**
* Border Color Y
* Border Color Block
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-y': [{
'border-y': scaleColor()
}],
/**
* Border Color S
* Border Color Inline Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-s': [{
'border-s': scaleColor()
}],
/**
* Border Color E
* Border Color Inline End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-e': [{
'border-e': scaleColor()
}],
/**
* Border Color Block Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-bs': [{
'border-bs': scaleColor()
}],
/**
* Border Color Block End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-be': [{
'border-be': scaleColor()
}],
/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
@@ -2705,6 +2889,13 @@ const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/translate
*/
'translate-none': ['translate-none'],
/**
* Zoom
* @see https://tailwindcss.com/docs/zoom
*/
zoom: [{
zoom: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
// ---------------------
// --- Interactivity ---
// ---------------------
@@ -2771,6 +2962,34 @@ const getDefaultConfig = () => {
'scroll-behavior': [{
scroll: ['auto', 'smooth']
}],
/**
* Scrollbar Thumb Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-thumb-color': [{
'scrollbar-thumb': scaleColor()
}],
/**
* Scrollbar Track Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-track-color': [{
'scrollbar-track': scaleColor()
}],
/**
* Scrollbar Gutter
* @see https://tailwindcss.com/docs/scrollbar-gutter
*/
'scrollbar-gutter': [{
'scrollbar-gutter': ['auto', 'stable', 'both']
}],
/**
* Scrollbar Width
* @see https://tailwindcss.com/docs/scrollbar-width
*/
'scrollbar-w': [{
scrollbar: ['auto', 'thin', 'none']
}],
/**
* Scroll Margin
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2779,33 +2998,47 @@ const getDefaultConfig = () => {
'scroll-m': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin X
* Scroll Margin Inline
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mx': [{
'scroll-mx': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Y
* Scroll Margin Block
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-my': [{
'scroll-my': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Start
* Scroll Margin Inline Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-ms': [{
'scroll-ms': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin End
* Scroll Margin Inline End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-me': [{
'scroll-me': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbs': [{
'scroll-mbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbe': [{
'scroll-mbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Top
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2842,33 +3075,47 @@ const getDefaultConfig = () => {
'scroll-p': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding X
* Scroll Padding Inline
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-px': [{
'scroll-px': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Y
* Scroll Padding Block
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-py': [{
'scroll-py': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Start
* Scroll Padding Inline Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-ps': [{
'scroll-ps': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding End
* Scroll Padding Inline End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pe': [{
'scroll-pe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbs': [{
'scroll-pbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbe': [{
'scroll-pbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Top
* @see https://tailwindcss.com/docs/scroll-padding
@@ -3001,17 +3248,18 @@ const getDefaultConfig = () => {
}]
},
conflictingClassGroups: {
'container-named': ['container-type'],
overflow: ['overflow-x', 'overflow-y'],
overscroll: ['overscroll-x', 'overscroll-y'],
inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],
inset: ['inset-x', 'inset-y', 'inset-bs', 'inset-be', 'start', 'end', 'top', 'right', 'bottom', 'left'],
'inset-x': ['right', 'left'],
'inset-y': ['top', 'bottom'],
flex: ['basis', 'grow', 'shrink'],
gap: ['gap-x', 'gap-y'],
p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],
p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
px: ['pr', 'pl'],
py: ['pt', 'pb'],
m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],
m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
mx: ['mr', 'ml'],
my: ['mt', 'mb'],
size: ['w', 'h'],
@@ -3031,18 +3279,18 @@ const getDefaultConfig = () => {
'rounded-b': ['rounded-br', 'rounded-bl'],
'rounded-l': ['rounded-tl', 'rounded-bl'],
'border-spacing': ['border-spacing-x', 'border-spacing-y'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-bs', 'border-w-be', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w-x': ['border-w-r', 'border-w-l'],
'border-w-y': ['border-w-t', 'border-w-b'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-bs', 'border-color-be', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color-x': ['border-color-r', 'border-color-l'],
'border-color-y': ['border-color-t', 'border-color-b'],
translate: ['translate-x', 'translate-y', 'translate-none'],
'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-mx': ['scroll-mr', 'scroll-ml'],
'scroll-my': ['scroll-mt', 'scroll-mb'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-px': ['scroll-pr', 'scroll-pl'],
'scroll-py': ['scroll-pt', 'scroll-pb'],
touch: ['touch-x', 'touch-y', 'touch-pz'],
@@ -3053,6 +3301,7 @@ const getDefaultConfig = () => {
conflictingClassGroupModifiers: {
'font-size': ['leading']
},
postfixLookupClassGroups: ['container-type'],
orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
};
};
@@ -3075,11 +3324,13 @@ const mergeConfigs = (baseConfig, {
overrideConfigProperties(baseConfig.classGroups, override.classGroups);
overrideConfigProperties(baseConfig.conflictingClassGroups, override.conflictingClassGroups);
overrideConfigProperties(baseConfig.conflictingClassGroupModifiers, override.conflictingClassGroupModifiers);
overrideProperty(baseConfig, 'postfixLookupClassGroups', override.postfixLookupClassGroups);
overrideProperty(baseConfig, 'orderSensitiveModifiers', override.orderSensitiveModifiers);
mergeConfigProperties(baseConfig.theme, extend.theme);
mergeConfigProperties(baseConfig.classGroups, extend.classGroups);
mergeConfigProperties(baseConfig.conflictingClassGroups, extend.conflictingClassGroups);
mergeConfigProperties(baseConfig.conflictingClassGroupModifiers, extend.conflictingClassGroupModifiers);
mergeArrayProperties(baseConfig, extend, 'postfixLookupClassGroups');
mergeArrayProperties(baseConfig, extend, 'orderSensitiveModifiers');
return baseConfig;
};
File diff suppressed because one or more lines are too long
+307 -42
View File
@@ -370,15 +370,27 @@ var createConfigUtils = function createConfigUtils(config) {
return _extends({
cache: createLruCache(config.cacheSize),
parseClassName: createParseClassName(config),
sortModifiers: createSortModifiers(config)
sortModifiers: createSortModifiers(config),
postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config)
}, createClassGroupUtils(config));
};
var createPostfixLookupClassGroupIds = function createPostfixLookupClassGroupIds(config) {
var lookup = Object.create(null);
var classGroupIds = config.postfixLookupClassGroups;
if (classGroupIds) {
for (var i = 0; i < classGroupIds.length; i++) {
lookup[classGroupIds[i]] = true;
}
}
return lookup;
};
var SPLIT_CLASSES_REGEX = /\s+/;
var mergeClassList = function mergeClassList(classList, configUtils) {
var parseClassName = configUtils.parseClassName,
getClassGroupId = configUtils.getClassGroupId,
getConflictingClassGroupIds = configUtils.getConflictingClassGroupIds,
sortModifiers = configUtils.sortModifiers;
sortModifiers = configUtils.sortModifiers,
postfixLookupClassGroupIds = configUtils.postfixLookupClassGroupIds;
/**
* Set of classGroupIds in following format:
* `{importantModifier}{variantModifiers}{classGroupId}`
@@ -402,7 +414,18 @@ var mergeClassList = function mergeClassList(classList, configUtils) {
continue;
}
var hasPostfixModifier = !!maybePostfixModifierPosition;
var classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
var classGroupId = void 0;
if (hasPostfixModifier) {
var baseClassNameWithoutPostfix = baseClassName.substring(0, maybePostfixModifierPosition);
classGroupId = getClassGroupId(baseClassNameWithoutPostfix);
var classGroupIdWithPostfix = classGroupId && postfixLookupClassGroupIds[classGroupId] ? getClassGroupId(baseClassName) : undefined;
if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {
classGroupId = classGroupIdWithPostfix;
hasPostfixModifier = false;
}
} else {
classGroupId = getClassGroupId(baseClassName);
}
if (!classGroupId) {
if (!hasPostfixModifier) {
// Not a Tailwind class
@@ -521,7 +544,7 @@ var fromTheme = function fromTheme(key) {
};
var arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
var arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
var fractionRegex = /^\d+\/\d+$/;
var fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/;
var tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
var lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
var colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
@@ -566,6 +589,9 @@ var isImage = function isImage(value) {
var isAnyNonArbitrary = function isAnyNonArbitrary(value) {
return !isArbitraryValue(value) && !isArbitraryVariable(value);
};
var isNamedContainerQuery = function isNamedContainerQuery(value) {
return value.startsWith('@container') && (value[10] === '/' && value[11] !== undefined || value[11] === 's' && value[16] !== undefined && value.startsWith('-size/', 10) || value[11] === 'n' && value[18] !== undefined && value.startsWith('-normal/', 10));
};
var isArbitrarySize = function isArbitrarySize(value) {
return getIsArbitraryValue(value, isLabelSize, isNever);
};
@@ -578,6 +604,12 @@ var isArbitraryLength = function isArbitraryLength(value) {
var isArbitraryNumber = function isArbitraryNumber(value) {
return getIsArbitraryValue(value, isLabelNumber, isNumber);
};
var isArbitraryWeight = function isArbitraryWeight(value) {
return getIsArbitraryValue(value, isLabelWeight, isAny);
};
var isArbitraryFamilyName = function isArbitraryFamilyName(value) {
return getIsArbitraryValue(value, isLabelFamilyName, isNever);
};
var isArbitraryPosition = function isArbitraryPosition(value) {
return getIsArbitraryValue(value, isLabelPosition, isNever);
};
@@ -608,6 +640,9 @@ var isArbitraryVariableImage = function isArbitraryVariableImage(value) {
var isArbitraryVariableShadow = function isArbitraryVariableShadow(value) {
return getIsArbitraryVariable(value, isLabelShadow, true);
};
var isArbitraryVariableWeight = function isArbitraryVariableWeight(value) {
return getIsArbitraryVariable(value, isLabelWeight, true);
};
// Helpers
var getIsArbitraryValue = function getIsArbitraryValue(value, testLabel, testValue) {
var result = arbitraryValueRegex.exec(value);
@@ -651,6 +686,9 @@ var isLabelNumber = function isLabelNumber(label) {
var isLabelFamilyName = function isLabelFamilyName(label) {
return label === 'family-name';
};
var isLabelWeight = function isLabelWeight(label) {
return label === 'number' || label === 'weight';
};
var isLabelShadow = function isLabelShadow(label) {
return label === 'shadow';
};
@@ -658,6 +696,7 @@ var validators = /*#__PURE__*/Object.defineProperty({
__proto__: null,
isAny: isAny,
isAnyNonArbitrary: isAnyNonArbitrary,
isArbitraryFamilyName: isArbitraryFamilyName,
isArbitraryImage: isArbitraryImage,
isArbitraryLength: isArbitraryLength,
isArbitraryNumber: isArbitraryNumber,
@@ -672,8 +711,11 @@ var validators = /*#__PURE__*/Object.defineProperty({
isArbitraryVariablePosition: isArbitraryVariablePosition,
isArbitraryVariableShadow: isArbitraryVariableShadow,
isArbitraryVariableSize: isArbitraryVariableSize,
isArbitraryVariableWeight: isArbitraryVariableWeight,
isArbitraryWeight: isArbitraryWeight,
isFraction: isFraction,
isInteger: isInteger,
isNamedContainerQuery: isNamedContainerQuery,
isNumber: isNumber,
isPercent: isPercent,
isTshirtSize: isTshirtSize
@@ -767,6 +809,12 @@ var getDefaultConfig = function getDefaultConfig() {
var scaleSizing = function scaleSizing() {
return [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit'].concat(scaleUnambiguousSpacing());
};
var scaleSizingInline = function scaleSizingInline() {
return [isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit'].concat(scaleUnambiguousSpacing());
};
var scaleSizingBlock = function scaleSizingBlock() {
return [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit'].concat(scaleUnambiguousSpacing());
};
var scaleColor = function scaleColor() {
return [themeColor, isArbitraryVariable, isArbitraryValue];
};
@@ -862,6 +910,18 @@ var getDefaultConfig = function getDefaultConfig() {
* @deprecated since Tailwind CSS v4.0.0
*/
container: ['container'],
/**
* Container Type
* @see https://tailwindcss.com/docs/responsive-design#container-queries
*/
'container-type': [{
'@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue]
}],
/**
* Container Name
* @see https://tailwindcss.com/docs/responsive-design#named-containers
*/
'container-named': [isNamedContainerQuery],
/**
* Columns
* @see https://tailwindcss.com/docs/columns
@@ -995,40 +1055,66 @@ var getDefaultConfig = function getDefaultConfig() {
*/
position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],
/**
* Top / Right / Bottom / Left
* Inset
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
inset: [{
inset: scaleInset()
}],
/**
* Right / Left
* Inset Inline
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-x': [{
'inset-x': scaleInset()
}],
/**
* Top / Bottom
* Inset Block
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-y': [{
'inset-y': scaleInset()
}],
/**
* Start
* Inset Inline Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-s` in next major release
*/
start: [{
'inset-s': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-s-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
start: scaleInset()
}],
/**
* End
* Inset Inline End
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-e` in next major release
*/
end: [{
'inset-e': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-e-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
end: scaleInset()
}],
/**
* Inset Block Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-bs': [{
'inset-bs': scaleInset()
}],
/**
* Inset Block End
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-be': [{
'inset-be': scaleInset()
}],
/**
* Top
* @see https://tailwindcss.com/docs/top-right-bottom-left
@@ -1295,33 +1381,47 @@ var getDefaultConfig = function getDefaultConfig() {
p: scaleUnambiguousSpacing()
}],
/**
* Padding X
* Padding Inline
* @see https://tailwindcss.com/docs/padding
*/
px: [{
px: scaleUnambiguousSpacing()
}],
/**
* Padding Y
* Padding Block
* @see https://tailwindcss.com/docs/padding
*/
py: [{
py: scaleUnambiguousSpacing()
}],
/**
* Padding Start
* Padding Inline Start
* @see https://tailwindcss.com/docs/padding
*/
ps: [{
ps: scaleUnambiguousSpacing()
}],
/**
* Padding End
* Padding Inline End
* @see https://tailwindcss.com/docs/padding
*/
pe: [{
pe: scaleUnambiguousSpacing()
}],
/**
* Padding Block Start
* @see https://tailwindcss.com/docs/padding
*/
pbs: [{
pbs: scaleUnambiguousSpacing()
}],
/**
* Padding Block End
* @see https://tailwindcss.com/docs/padding
*/
pbe: [{
pbe: scaleUnambiguousSpacing()
}],
/**
* Padding Top
* @see https://tailwindcss.com/docs/padding
@@ -1358,33 +1458,47 @@ var getDefaultConfig = function getDefaultConfig() {
m: scaleMargin()
}],
/**
* Margin X
* Margin Inline
* @see https://tailwindcss.com/docs/margin
*/
mx: [{
mx: scaleMargin()
}],
/**
* Margin Y
* Margin Block
* @see https://tailwindcss.com/docs/margin
*/
my: [{
my: scaleMargin()
}],
/**
* Margin Start
* Margin Inline Start
* @see https://tailwindcss.com/docs/margin
*/
ms: [{
ms: scaleMargin()
}],
/**
* Margin End
* Margin Inline End
* @see https://tailwindcss.com/docs/margin
*/
me: [{
me: scaleMargin()
}],
/**
* Margin Block Start
* @see https://tailwindcss.com/docs/margin
*/
mbs: [{
mbs: scaleMargin()
}],
/**
* Margin Block End
* @see https://tailwindcss.com/docs/margin
*/
mbe: [{
mbe: scaleMargin()
}],
/**
* Margin Top
* @see https://tailwindcss.com/docs/margin
@@ -1447,6 +1561,48 @@ var getDefaultConfig = function getDefaultConfig() {
size: [{
size: scaleSizing()
}],
/**
* Inline Size
* @see https://tailwindcss.com/docs/width
*/
'inline-size': [{
inline: ['auto'].concat(scaleSizingInline())
}],
/**
* Min-Inline Size
* @see https://tailwindcss.com/docs/min-width
*/
'min-inline-size': [{
'min-inline': ['auto'].concat(scaleSizingInline())
}],
/**
* Max-Inline Size
* @see https://tailwindcss.com/docs/max-width
*/
'max-inline-size': [{
'max-inline': ['none'].concat(scaleSizingInline())
}],
/**
* Block Size
* @see https://tailwindcss.com/docs/height
*/
'block-size': [{
block: ['auto'].concat(scaleSizingBlock())
}],
/**
* Min-Block Size
* @see https://tailwindcss.com/docs/min-height
*/
'min-block-size': [{
'min-block': ['auto'].concat(scaleSizingBlock())
}],
/**
* Max-Block Size
* @see https://tailwindcss.com/docs/max-height
*/
'max-block-size': [{
'max-block': ['none'].concat(scaleSizingBlock())
}],
/**
* Width
* @see https://tailwindcss.com/docs/width
@@ -1519,7 +1675,7 @@ var getDefaultConfig = function getDefaultConfig() {
* @see https://tailwindcss.com/docs/font-weight
*/
'font-weight': [{
font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber]
font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight]
}],
/**
* Font Stretch
@@ -1533,7 +1689,14 @@ var getDefaultConfig = function getDefaultConfig() {
* @see https://tailwindcss.com/docs/font-family
*/
'font-family': [{
font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont]
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont]
}],
/**
* Font Feature Settings
* @see https://tailwindcss.com/docs/font-feature-settings
*/
'font-features': [{
'font-features': [isArbitraryValue]
}],
/**
* Font Variant Numeric
@@ -1687,6 +1850,13 @@ var getDefaultConfig = function getDefaultConfig() {
indent: [{
indent: scaleUnambiguousSpacing()
}],
/**
* Tab Size
* @see https://tailwindcss.com/docs/tab-size
*/
'tab-size': [{
tab: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
/**
* Vertical Alignment
* @see https://tailwindcss.com/docs/vertical-align
@@ -1952,33 +2122,47 @@ var getDefaultConfig = function getDefaultConfig() {
border: scaleBorderWidth()
}],
/**
* Border Width X
* Border Width Inline
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-x': [{
'border-x': scaleBorderWidth()
}],
/**
* Border Width Y
* Border Width Block
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-y': [{
'border-y': scaleBorderWidth()
}],
/**
* Border Width Start
* Border Width Inline Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-s': [{
'border-s': scaleBorderWidth()
}],
/**
* Border Width End
* Border Width Inline End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-e': [{
'border-e': scaleBorderWidth()
}],
/**
* Border Width Block Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-bs': [{
'border-bs': scaleBorderWidth()
}],
/**
* Border Width Block End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-be': [{
'border-be': scaleBorderWidth()
}],
/**
* Border Width Top
* @see https://tailwindcss.com/docs/border-width
@@ -2053,33 +2237,47 @@ var getDefaultConfig = function getDefaultConfig() {
border: scaleColor()
}],
/**
* Border Color X
* Border Color Inline
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-x': [{
'border-x': scaleColor()
}],
/**
* Border Color Y
* Border Color Block
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-y': [{
'border-y': scaleColor()
}],
/**
* Border Color S
* Border Color Inline Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-s': [{
'border-s': scaleColor()
}],
/**
* Border Color E
* Border Color Inline End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-e': [{
'border-e': scaleColor()
}],
/**
* Border Color Block Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-bs': [{
'border-bs': scaleColor()
}],
/**
* Border Color Block End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-be': [{
'border-be': scaleColor()
}],
/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
@@ -2866,6 +3064,13 @@ var getDefaultConfig = function getDefaultConfig() {
* @see https://tailwindcss.com/docs/translate
*/
'translate-none': ['translate-none'],
/**
* Zoom
* @see https://tailwindcss.com/docs/zoom
*/
zoom: [{
zoom: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
// ---------------------
// --- Interactivity ---
// ---------------------
@@ -2932,6 +3137,34 @@ var getDefaultConfig = function getDefaultConfig() {
'scroll-behavior': [{
scroll: ['auto', 'smooth']
}],
/**
* Scrollbar Thumb Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-thumb-color': [{
'scrollbar-thumb': scaleColor()
}],
/**
* Scrollbar Track Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-track-color': [{
'scrollbar-track': scaleColor()
}],
/**
* Scrollbar Gutter
* @see https://tailwindcss.com/docs/scrollbar-gutter
*/
'scrollbar-gutter': [{
'scrollbar-gutter': ['auto', 'stable', 'both']
}],
/**
* Scrollbar Width
* @see https://tailwindcss.com/docs/scrollbar-width
*/
'scrollbar-w': [{
scrollbar: ['auto', 'thin', 'none']
}],
/**
* Scroll Margin
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2940,33 +3173,47 @@ var getDefaultConfig = function getDefaultConfig() {
'scroll-m': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin X
* Scroll Margin Inline
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mx': [{
'scroll-mx': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Y
* Scroll Margin Block
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-my': [{
'scroll-my': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Start
* Scroll Margin Inline Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-ms': [{
'scroll-ms': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin End
* Scroll Margin Inline End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-me': [{
'scroll-me': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbs': [{
'scroll-mbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbe': [{
'scroll-mbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Top
* @see https://tailwindcss.com/docs/scroll-margin
@@ -3003,33 +3250,47 @@ var getDefaultConfig = function getDefaultConfig() {
'scroll-p': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding X
* Scroll Padding Inline
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-px': [{
'scroll-px': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Y
* Scroll Padding Block
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-py': [{
'scroll-py': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Start
* Scroll Padding Inline Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-ps': [{
'scroll-ps': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding End
* Scroll Padding Inline End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pe': [{
'scroll-pe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbs': [{
'scroll-pbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbe': [{
'scroll-pbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Top
* @see https://tailwindcss.com/docs/scroll-padding
@@ -3162,17 +3423,18 @@ var getDefaultConfig = function getDefaultConfig() {
}]
},
conflictingClassGroups: {
'container-named': ['container-type'],
overflow: ['overflow-x', 'overflow-y'],
overscroll: ['overscroll-x', 'overscroll-y'],
inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],
inset: ['inset-x', 'inset-y', 'inset-bs', 'inset-be', 'start', 'end', 'top', 'right', 'bottom', 'left'],
'inset-x': ['right', 'left'],
'inset-y': ['top', 'bottom'],
flex: ['basis', 'grow', 'shrink'],
gap: ['gap-x', 'gap-y'],
p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],
p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
px: ['pr', 'pl'],
py: ['pt', 'pb'],
m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],
m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
mx: ['mr', 'ml'],
my: ['mt', 'mb'],
size: ['w', 'h'],
@@ -3192,18 +3454,18 @@ var getDefaultConfig = function getDefaultConfig() {
'rounded-b': ['rounded-br', 'rounded-bl'],
'rounded-l': ['rounded-tl', 'rounded-bl'],
'border-spacing': ['border-spacing-x', 'border-spacing-y'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-bs', 'border-w-be', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w-x': ['border-w-r', 'border-w-l'],
'border-w-y': ['border-w-t', 'border-w-b'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-bs', 'border-color-be', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color-x': ['border-color-r', 'border-color-l'],
'border-color-y': ['border-color-t', 'border-color-b'],
translate: ['translate-x', 'translate-y', 'translate-none'],
'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-mx': ['scroll-mr', 'scroll-ml'],
'scroll-my': ['scroll-mt', 'scroll-mb'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-px': ['scroll-pr', 'scroll-pl'],
'scroll-py': ['scroll-pt', 'scroll-pb'],
touch: ['touch-x', 'touch-y', 'touch-pz'],
@@ -3214,6 +3476,7 @@ var getDefaultConfig = function getDefaultConfig() {
conflictingClassGroupModifiers: {
'font-size': ['leading']
},
postfixLookupClassGroups: ['container-type'],
orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
};
};
@@ -3237,11 +3500,13 @@ var mergeConfigs = function mergeConfigs(baseConfig, _ref) {
overrideConfigProperties(baseConfig.classGroups, override.classGroups);
overrideConfigProperties(baseConfig.conflictingClassGroups, override.conflictingClassGroups);
overrideConfigProperties(baseConfig.conflictingClassGroupModifiers, override.conflictingClassGroupModifiers);
overrideProperty(baseConfig, 'postfixLookupClassGroups', override.postfixLookupClassGroups);
overrideProperty(baseConfig, 'orderSensitiveModifiers', override.orderSensitiveModifiers);
mergeConfigProperties(baseConfig.theme, extend.theme);
mergeConfigProperties(baseConfig.classGroups, extend.classGroups);
mergeConfigProperties(baseConfig.conflictingClassGroups, extend.conflictingClassGroups);
mergeConfigProperties(baseConfig.conflictingClassGroupModifiers, extend.conflictingClassGroupModifiers);
mergeArrayProperties(baseConfig, extend, 'postfixLookupClassGroups');
mergeArrayProperties(baseConfig, extend, 'orderSensitiveModifiers');
return baseConfig;
};
File diff suppressed because one or more lines are too long
+307 -42
View File
@@ -364,15 +364,27 @@ var createConfigUtils = function createConfigUtils(config) {
return _extends({
cache: createLruCache(config.cacheSize),
parseClassName: createParseClassName(config),
sortModifiers: createSortModifiers(config)
sortModifiers: createSortModifiers(config),
postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config)
}, createClassGroupUtils(config));
};
var createPostfixLookupClassGroupIds = function createPostfixLookupClassGroupIds(config) {
var lookup = Object.create(null);
var classGroupIds = config.postfixLookupClassGroups;
if (classGroupIds) {
for (var i = 0; i < classGroupIds.length; i++) {
lookup[classGroupIds[i]] = true;
}
}
return lookup;
};
var SPLIT_CLASSES_REGEX = /\s+/;
var mergeClassList = function mergeClassList(classList, configUtils) {
var parseClassName = configUtils.parseClassName,
getClassGroupId = configUtils.getClassGroupId,
getConflictingClassGroupIds = configUtils.getConflictingClassGroupIds,
sortModifiers = configUtils.sortModifiers;
sortModifiers = configUtils.sortModifiers,
postfixLookupClassGroupIds = configUtils.postfixLookupClassGroupIds;
/**
* Set of classGroupIds in following format:
* `{importantModifier}{variantModifiers}{classGroupId}`
@@ -396,7 +408,18 @@ var mergeClassList = function mergeClassList(classList, configUtils) {
continue;
}
var hasPostfixModifier = !!maybePostfixModifierPosition;
var classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
var classGroupId = void 0;
if (hasPostfixModifier) {
var baseClassNameWithoutPostfix = baseClassName.substring(0, maybePostfixModifierPosition);
classGroupId = getClassGroupId(baseClassNameWithoutPostfix);
var classGroupIdWithPostfix = classGroupId && postfixLookupClassGroupIds[classGroupId] ? getClassGroupId(baseClassName) : undefined;
if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {
classGroupId = classGroupIdWithPostfix;
hasPostfixModifier = false;
}
} else {
classGroupId = getClassGroupId(baseClassName);
}
if (!classGroupId) {
if (!hasPostfixModifier) {
// Not a Tailwind class
@@ -515,7 +538,7 @@ var fromTheme = function fromTheme(key) {
};
var arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
var arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
var fractionRegex = /^\d+\/\d+$/;
var fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/;
var tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
var lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
var colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
@@ -560,6 +583,9 @@ var isImage = function isImage(value) {
var isAnyNonArbitrary = function isAnyNonArbitrary(value) {
return !isArbitraryValue(value) && !isArbitraryVariable(value);
};
var isNamedContainerQuery = function isNamedContainerQuery(value) {
return value.startsWith('@container') && (value[10] === '/' && value[11] !== undefined || value[11] === 's' && value[16] !== undefined && value.startsWith('-size/', 10) || value[11] === 'n' && value[18] !== undefined && value.startsWith('-normal/', 10));
};
var isArbitrarySize = function isArbitrarySize(value) {
return getIsArbitraryValue(value, isLabelSize, isNever);
};
@@ -572,6 +598,12 @@ var isArbitraryLength = function isArbitraryLength(value) {
var isArbitraryNumber = function isArbitraryNumber(value) {
return getIsArbitraryValue(value, isLabelNumber, isNumber);
};
var isArbitraryWeight = function isArbitraryWeight(value) {
return getIsArbitraryValue(value, isLabelWeight, isAny);
};
var isArbitraryFamilyName = function isArbitraryFamilyName(value) {
return getIsArbitraryValue(value, isLabelFamilyName, isNever);
};
var isArbitraryPosition = function isArbitraryPosition(value) {
return getIsArbitraryValue(value, isLabelPosition, isNever);
};
@@ -602,6 +634,9 @@ var isArbitraryVariableImage = function isArbitraryVariableImage(value) {
var isArbitraryVariableShadow = function isArbitraryVariableShadow(value) {
return getIsArbitraryVariable(value, isLabelShadow, true);
};
var isArbitraryVariableWeight = function isArbitraryVariableWeight(value) {
return getIsArbitraryVariable(value, isLabelWeight, true);
};
// Helpers
var getIsArbitraryValue = function getIsArbitraryValue(value, testLabel, testValue) {
var result = arbitraryValueRegex.exec(value);
@@ -645,6 +680,9 @@ var isLabelNumber = function isLabelNumber(label) {
var isLabelFamilyName = function isLabelFamilyName(label) {
return label === 'family-name';
};
var isLabelWeight = function isLabelWeight(label) {
return label === 'number' || label === 'weight';
};
var isLabelShadow = function isLabelShadow(label) {
return label === 'shadow';
};
@@ -652,6 +690,7 @@ var validators = /*#__PURE__*/Object.defineProperty({
__proto__: null,
isAny: isAny,
isAnyNonArbitrary: isAnyNonArbitrary,
isArbitraryFamilyName: isArbitraryFamilyName,
isArbitraryImage: isArbitraryImage,
isArbitraryLength: isArbitraryLength,
isArbitraryNumber: isArbitraryNumber,
@@ -666,8 +705,11 @@ var validators = /*#__PURE__*/Object.defineProperty({
isArbitraryVariablePosition: isArbitraryVariablePosition,
isArbitraryVariableShadow: isArbitraryVariableShadow,
isArbitraryVariableSize: isArbitraryVariableSize,
isArbitraryVariableWeight: isArbitraryVariableWeight,
isArbitraryWeight: isArbitraryWeight,
isFraction: isFraction,
isInteger: isInteger,
isNamedContainerQuery: isNamedContainerQuery,
isNumber: isNumber,
isPercent: isPercent,
isTshirtSize: isTshirtSize
@@ -761,6 +803,12 @@ var getDefaultConfig = function getDefaultConfig() {
var scaleSizing = function scaleSizing() {
return [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit'].concat(scaleUnambiguousSpacing());
};
var scaleSizingInline = function scaleSizingInline() {
return [isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit'].concat(scaleUnambiguousSpacing());
};
var scaleSizingBlock = function scaleSizingBlock() {
return [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit'].concat(scaleUnambiguousSpacing());
};
var scaleColor = function scaleColor() {
return [themeColor, isArbitraryVariable, isArbitraryValue];
};
@@ -856,6 +904,18 @@ var getDefaultConfig = function getDefaultConfig() {
* @deprecated since Tailwind CSS v4.0.0
*/
container: ['container'],
/**
* Container Type
* @see https://tailwindcss.com/docs/responsive-design#container-queries
*/
'container-type': [{
'@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue]
}],
/**
* Container Name
* @see https://tailwindcss.com/docs/responsive-design#named-containers
*/
'container-named': [isNamedContainerQuery],
/**
* Columns
* @see https://tailwindcss.com/docs/columns
@@ -989,40 +1049,66 @@ var getDefaultConfig = function getDefaultConfig() {
*/
position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],
/**
* Top / Right / Bottom / Left
* Inset
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
inset: [{
inset: scaleInset()
}],
/**
* Right / Left
* Inset Inline
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-x': [{
'inset-x': scaleInset()
}],
/**
* Top / Bottom
* Inset Block
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-y': [{
'inset-y': scaleInset()
}],
/**
* Start
* Inset Inline Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-s` in next major release
*/
start: [{
'inset-s': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-s-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
start: scaleInset()
}],
/**
* End
* Inset Inline End
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-e` in next major release
*/
end: [{
'inset-e': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-e-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
end: scaleInset()
}],
/**
* Inset Block Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-bs': [{
'inset-bs': scaleInset()
}],
/**
* Inset Block End
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-be': [{
'inset-be': scaleInset()
}],
/**
* Top
* @see https://tailwindcss.com/docs/top-right-bottom-left
@@ -1289,33 +1375,47 @@ var getDefaultConfig = function getDefaultConfig() {
p: scaleUnambiguousSpacing()
}],
/**
* Padding X
* Padding Inline
* @see https://tailwindcss.com/docs/padding
*/
px: [{
px: scaleUnambiguousSpacing()
}],
/**
* Padding Y
* Padding Block
* @see https://tailwindcss.com/docs/padding
*/
py: [{
py: scaleUnambiguousSpacing()
}],
/**
* Padding Start
* Padding Inline Start
* @see https://tailwindcss.com/docs/padding
*/
ps: [{
ps: scaleUnambiguousSpacing()
}],
/**
* Padding End
* Padding Inline End
* @see https://tailwindcss.com/docs/padding
*/
pe: [{
pe: scaleUnambiguousSpacing()
}],
/**
* Padding Block Start
* @see https://tailwindcss.com/docs/padding
*/
pbs: [{
pbs: scaleUnambiguousSpacing()
}],
/**
* Padding Block End
* @see https://tailwindcss.com/docs/padding
*/
pbe: [{
pbe: scaleUnambiguousSpacing()
}],
/**
* Padding Top
* @see https://tailwindcss.com/docs/padding
@@ -1352,33 +1452,47 @@ var getDefaultConfig = function getDefaultConfig() {
m: scaleMargin()
}],
/**
* Margin X
* Margin Inline
* @see https://tailwindcss.com/docs/margin
*/
mx: [{
mx: scaleMargin()
}],
/**
* Margin Y
* Margin Block
* @see https://tailwindcss.com/docs/margin
*/
my: [{
my: scaleMargin()
}],
/**
* Margin Start
* Margin Inline Start
* @see https://tailwindcss.com/docs/margin
*/
ms: [{
ms: scaleMargin()
}],
/**
* Margin End
* Margin Inline End
* @see https://tailwindcss.com/docs/margin
*/
me: [{
me: scaleMargin()
}],
/**
* Margin Block Start
* @see https://tailwindcss.com/docs/margin
*/
mbs: [{
mbs: scaleMargin()
}],
/**
* Margin Block End
* @see https://tailwindcss.com/docs/margin
*/
mbe: [{
mbe: scaleMargin()
}],
/**
* Margin Top
* @see https://tailwindcss.com/docs/margin
@@ -1441,6 +1555,48 @@ var getDefaultConfig = function getDefaultConfig() {
size: [{
size: scaleSizing()
}],
/**
* Inline Size
* @see https://tailwindcss.com/docs/width
*/
'inline-size': [{
inline: ['auto'].concat(scaleSizingInline())
}],
/**
* Min-Inline Size
* @see https://tailwindcss.com/docs/min-width
*/
'min-inline-size': [{
'min-inline': ['auto'].concat(scaleSizingInline())
}],
/**
* Max-Inline Size
* @see https://tailwindcss.com/docs/max-width
*/
'max-inline-size': [{
'max-inline': ['none'].concat(scaleSizingInline())
}],
/**
* Block Size
* @see https://tailwindcss.com/docs/height
*/
'block-size': [{
block: ['auto'].concat(scaleSizingBlock())
}],
/**
* Min-Block Size
* @see https://tailwindcss.com/docs/min-height
*/
'min-block-size': [{
'min-block': ['auto'].concat(scaleSizingBlock())
}],
/**
* Max-Block Size
* @see https://tailwindcss.com/docs/max-height
*/
'max-block-size': [{
'max-block': ['none'].concat(scaleSizingBlock())
}],
/**
* Width
* @see https://tailwindcss.com/docs/width
@@ -1513,7 +1669,7 @@ var getDefaultConfig = function getDefaultConfig() {
* @see https://tailwindcss.com/docs/font-weight
*/
'font-weight': [{
font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber]
font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight]
}],
/**
* Font Stretch
@@ -1527,7 +1683,14 @@ var getDefaultConfig = function getDefaultConfig() {
* @see https://tailwindcss.com/docs/font-family
*/
'font-family': [{
font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont]
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont]
}],
/**
* Font Feature Settings
* @see https://tailwindcss.com/docs/font-feature-settings
*/
'font-features': [{
'font-features': [isArbitraryValue]
}],
/**
* Font Variant Numeric
@@ -1681,6 +1844,13 @@ var getDefaultConfig = function getDefaultConfig() {
indent: [{
indent: scaleUnambiguousSpacing()
}],
/**
* Tab Size
* @see https://tailwindcss.com/docs/tab-size
*/
'tab-size': [{
tab: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
/**
* Vertical Alignment
* @see https://tailwindcss.com/docs/vertical-align
@@ -1946,33 +2116,47 @@ var getDefaultConfig = function getDefaultConfig() {
border: scaleBorderWidth()
}],
/**
* Border Width X
* Border Width Inline
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-x': [{
'border-x': scaleBorderWidth()
}],
/**
* Border Width Y
* Border Width Block
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-y': [{
'border-y': scaleBorderWidth()
}],
/**
* Border Width Start
* Border Width Inline Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-s': [{
'border-s': scaleBorderWidth()
}],
/**
* Border Width End
* Border Width Inline End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-e': [{
'border-e': scaleBorderWidth()
}],
/**
* Border Width Block Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-bs': [{
'border-bs': scaleBorderWidth()
}],
/**
* Border Width Block End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-be': [{
'border-be': scaleBorderWidth()
}],
/**
* Border Width Top
* @see https://tailwindcss.com/docs/border-width
@@ -2047,33 +2231,47 @@ var getDefaultConfig = function getDefaultConfig() {
border: scaleColor()
}],
/**
* Border Color X
* Border Color Inline
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-x': [{
'border-x': scaleColor()
}],
/**
* Border Color Y
* Border Color Block
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-y': [{
'border-y': scaleColor()
}],
/**
* Border Color S
* Border Color Inline Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-s': [{
'border-s': scaleColor()
}],
/**
* Border Color E
* Border Color Inline End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-e': [{
'border-e': scaleColor()
}],
/**
* Border Color Block Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-bs': [{
'border-bs': scaleColor()
}],
/**
* Border Color Block End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-be': [{
'border-be': scaleColor()
}],
/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
@@ -2860,6 +3058,13 @@ var getDefaultConfig = function getDefaultConfig() {
* @see https://tailwindcss.com/docs/translate
*/
'translate-none': ['translate-none'],
/**
* Zoom
* @see https://tailwindcss.com/docs/zoom
*/
zoom: [{
zoom: [isInteger, isArbitraryVariable, isArbitraryValue]
}],
// ---------------------
// --- Interactivity ---
// ---------------------
@@ -2926,6 +3131,34 @@ var getDefaultConfig = function getDefaultConfig() {
'scroll-behavior': [{
scroll: ['auto', 'smooth']
}],
/**
* Scrollbar Thumb Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-thumb-color': [{
'scrollbar-thumb': scaleColor()
}],
/**
* Scrollbar Track Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-track-color': [{
'scrollbar-track': scaleColor()
}],
/**
* Scrollbar Gutter
* @see https://tailwindcss.com/docs/scrollbar-gutter
*/
'scrollbar-gutter': [{
'scrollbar-gutter': ['auto', 'stable', 'both']
}],
/**
* Scrollbar Width
* @see https://tailwindcss.com/docs/scrollbar-width
*/
'scrollbar-w': [{
scrollbar: ['auto', 'thin', 'none']
}],
/**
* Scroll Margin
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2934,33 +3167,47 @@ var getDefaultConfig = function getDefaultConfig() {
'scroll-m': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin X
* Scroll Margin Inline
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mx': [{
'scroll-mx': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Y
* Scroll Margin Block
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-my': [{
'scroll-my': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Start
* Scroll Margin Inline Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-ms': [{
'scroll-ms': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin End
* Scroll Margin Inline End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-me': [{
'scroll-me': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbs': [{
'scroll-mbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Block End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbe': [{
'scroll-mbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Margin Top
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2997,33 +3244,47 @@ var getDefaultConfig = function getDefaultConfig() {
'scroll-p': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding X
* Scroll Padding Inline
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-px': [{
'scroll-px': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Y
* Scroll Padding Block
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-py': [{
'scroll-py': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Start
* Scroll Padding Inline Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-ps': [{
'scroll-ps': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding End
* Scroll Padding Inline End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pe': [{
'scroll-pe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbs': [{
'scroll-pbs': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Block End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbe': [{
'scroll-pbe': scaleUnambiguousSpacing()
}],
/**
* Scroll Padding Top
* @see https://tailwindcss.com/docs/scroll-padding
@@ -3156,17 +3417,18 @@ var getDefaultConfig = function getDefaultConfig() {
}]
},
conflictingClassGroups: {
'container-named': ['container-type'],
overflow: ['overflow-x', 'overflow-y'],
overscroll: ['overscroll-x', 'overscroll-y'],
inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],
inset: ['inset-x', 'inset-y', 'inset-bs', 'inset-be', 'start', 'end', 'top', 'right', 'bottom', 'left'],
'inset-x': ['right', 'left'],
'inset-y': ['top', 'bottom'],
flex: ['basis', 'grow', 'shrink'],
gap: ['gap-x', 'gap-y'],
p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],
p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
px: ['pr', 'pl'],
py: ['pt', 'pb'],
m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],
m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
mx: ['mr', 'ml'],
my: ['mt', 'mb'],
size: ['w', 'h'],
@@ -3186,18 +3448,18 @@ var getDefaultConfig = function getDefaultConfig() {
'rounded-b': ['rounded-br', 'rounded-bl'],
'rounded-l': ['rounded-tl', 'rounded-bl'],
'border-spacing': ['border-spacing-x', 'border-spacing-y'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-bs', 'border-w-be', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],
'border-w-x': ['border-w-r', 'border-w-l'],
'border-w-y': ['border-w-t', 'border-w-b'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-bs', 'border-color-be', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],
'border-color-x': ['border-color-r', 'border-color-l'],
'border-color-y': ['border-color-t', 'border-color-b'],
translate: ['translate-x', 'translate-y', 'translate-none'],
'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],
'scroll-mx': ['scroll-mr', 'scroll-ml'],
'scroll-my': ['scroll-mt', 'scroll-mb'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],
'scroll-px': ['scroll-pr', 'scroll-pl'],
'scroll-py': ['scroll-pt', 'scroll-pb'],
touch: ['touch-x', 'touch-y', 'touch-pz'],
@@ -3208,6 +3470,7 @@ var getDefaultConfig = function getDefaultConfig() {
conflictingClassGroupModifiers: {
'font-size': ['leading']
},
postfixLookupClassGroups: ['container-type'],
orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']
};
};
@@ -3231,11 +3494,13 @@ var mergeConfigs = function mergeConfigs(baseConfig, _ref) {
overrideConfigProperties(baseConfig.classGroups, override.classGroups);
overrideConfigProperties(baseConfig.conflictingClassGroups, override.conflictingClassGroups);
overrideConfigProperties(baseConfig.conflictingClassGroupModifiers, override.conflictingClassGroupModifiers);
overrideProperty(baseConfig, 'postfixLookupClassGroups', override.postfixLookupClassGroups);
overrideProperty(baseConfig, 'orderSensitiveModifiers', override.orderSensitiveModifiers);
mergeConfigProperties(baseConfig.theme, extend.theme);
mergeConfigProperties(baseConfig.classGroups, extend.classGroups);
mergeConfigProperties(baseConfig.conflictingClassGroups, extend.conflictingClassGroups);
mergeConfigProperties(baseConfig.conflictingClassGroupModifiers, extend.conflictingClassGroupModifiers);
mergeArrayProperties(baseConfig, extend, 'postfixLookupClassGroups');
mergeArrayProperties(baseConfig, extend, 'orderSensitiveModifiers');
return baseConfig;
};
File diff suppressed because one or more lines are too long
+290 -44
View File
File diff suppressed because one or more lines are too long
+20 -20
View File
@@ -1,6 +1,6 @@
{
"name": "tailwind-merge",
"version": "3.4.0",
"version": "3.6.0",
"description": "Merge Tailwind CSS classes without style conflicts",
"keywords": [
"tailwindcss",
@@ -62,29 +62,29 @@
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.28.4",
"@babel/preset-env": "^7.28.3",
"@codspeed/vitest-plugin": "^5.0.1",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-typescript": "^12.1.4",
"@types/node": "^24.9.2",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/eslint-plugin": "^1.3.15",
"@babel/core": "^7.29.0",
"@babel/preset-env": "^7.29.3",
"@codspeed/vitest-plugin": "^5.4.0",
"@rollup/plugin-babel": "^7.0.0",
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-typescript": "^12.3.0",
"@types/node": "^24.12.2",
"@vitest/coverage-v8": "^4.1.5",
"@vitest/eslint-plugin": "^1.6.16",
"babel-plugin-annotate-pure-calls": "^0.5.0",
"babel-plugin-polyfill-regenerator": "^0.6.5",
"eslint": "^9.37.0",
"babel-plugin-polyfill-regenerator": "^0.6.8",
"eslint": "^9.39.4",
"eslint-plugin-import": "^2.32.0",
"globby": "^11.1.0",
"prettier": "^3.6.2",
"rollup": "^4.52.4",
"rollup-plugin-delete": "^3.0.1",
"rollup-plugin-dts": "^6.2.3",
"globby": "^16.2.0",
"prettier": "^3.8.3",
"rollup": "^4.60.2",
"rollup-plugin-delete": "^3.0.2",
"rollup-plugin-dts": "^6.4.1",
"tslib": "^2.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.45.0",
"vitest": "^3.2.4",
"zx": "^8.8.4"
"typescript-eslint": "^8.59.1",
"vitest": "^4.1.5",
"zx": "^8.8.5"
},
"publishConfig": {
"provenance": true
+15 -1
View File
@@ -2,7 +2,7 @@ import { createClassGroupUtils } from './class-group-utils'
import { createLruCache } from './lru-cache'
import { createParseClassName } from './parse-class-name'
import { createSortModifiers } from './sort-modifiers'
import { AnyConfig } from './types'
import { AnyClassGroupIds, AnyConfig } from './types'
export type ConfigUtils = ReturnType<typeof createConfigUtils>
@@ -10,5 +10,19 @@ export const createConfigUtils = (config: AnyConfig) => ({
cache: createLruCache<string, string>(config.cacheSize),
parseClassName: createParseClassName(config),
sortModifiers: createSortModifiers(config),
postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config),
...createClassGroupUtils(config),
})
const createPostfixLookupClassGroupIds = (config: AnyConfig) => {
const lookup: Partial<Record<AnyClassGroupIds, true>> = Object.create(null)
const classGroupIds = config.postfixLookupClassGroups
if (classGroupIds) {
for (let i = 0; i < classGroupIds.length; i++) {
lookup[classGroupIds[i]!] = true
}
}
return lookup
}
+261 -36
View File
@@ -3,6 +3,7 @@ import { Config, DefaultClassGroupIds, DefaultThemeGroupIds } from './types'
import {
isAny,
isAnyNonArbitrary,
isArbitraryFamilyName,
isArbitraryImage,
isArbitraryLength,
isArbitraryNumber,
@@ -17,8 +18,11 @@ import {
isArbitraryVariablePosition,
isArbitraryVariableShadow,
isArbitraryVariableSize,
isArbitraryVariableWeight,
isArbitraryWeight,
isFraction,
isInteger,
isNamedContainerQuery,
isNumber,
isPercent,
isTshirtSize,
@@ -134,6 +138,33 @@ export const getDefaultConfig = () => {
'fit',
...scaleUnambiguousSpacing(),
] as const
const scaleSizingInline = () =>
[
isFraction,
'screen',
'full',
'dvw',
'lvw',
'svw',
'min',
'max',
'fit',
...scaleUnambiguousSpacing(),
] as const
const scaleSizingBlock = () =>
[
isFraction,
'screen',
'full',
'lh',
'dvh',
'lvh',
'svh',
'min',
'max',
'fit',
...scaleUnambiguousSpacing(),
] as const
const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue] as const
const scaleBgPosition = () =>
[
@@ -262,6 +293,18 @@ export const getDefaultConfig = () => {
* @deprecated since Tailwind CSS v4.0.0
*/
container: ['container'],
/**
* Container Type
* @see https://tailwindcss.com/docs/responsive-design#container-queries
*/
'container-type': [
{ '@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue] },
],
/**
* Container Name
* @see https://tailwindcss.com/docs/responsive-design#named-containers
*/
'container-named': [isNamedContainerQuery],
/**
* Columns
* @see https://tailwindcss.com/docs/columns
@@ -387,30 +430,60 @@ export const getDefaultConfig = () => {
*/
position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],
/**
* Top / Right / Bottom / Left
* Inset
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
inset: [{ inset: scaleInset() }],
/**
* Right / Left
* Inset Inline
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-x': [{ 'inset-x': scaleInset() }],
/**
* Top / Bottom
* Inset Block
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-y': [{ 'inset-y': scaleInset() }],
/**
* Start
* Inset Inline Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-s` in next major release
*/
start: [{ start: scaleInset() }],
start: [
{
'inset-s': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-s-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
start: scaleInset(),
},
],
/**
* End
* Inset Inline End
* @see https://tailwindcss.com/docs/top-right-bottom-left
* @todo class group will be renamed to `inset-e` in next major release
*/
end: [
{
'inset-e': scaleInset(),
/**
* @deprecated since Tailwind CSS v4.2.0 in favor of `inset-e-*` utilities.
* @see https://github.com/tailwindlabs/tailwindcss/pull/19613
*/
end: scaleInset(),
},
],
/**
* Inset Block Start
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
end: [{ end: scaleInset() }],
'inset-bs': [{ 'inset-bs': scaleInset() }],
/**
* Inset Block End
* @see https://tailwindcss.com/docs/top-right-bottom-left
*/
'inset-be': [{ 'inset-be': scaleInset() }],
/**
* Top
* @see https://tailwindcss.com/docs/top-right-bottom-left
@@ -626,25 +699,35 @@ export const getDefaultConfig = () => {
*/
p: [{ p: scaleUnambiguousSpacing() }],
/**
* Padding X
* Padding Inline
* @see https://tailwindcss.com/docs/padding
*/
px: [{ px: scaleUnambiguousSpacing() }],
/**
* Padding Y
* Padding Block
* @see https://tailwindcss.com/docs/padding
*/
py: [{ py: scaleUnambiguousSpacing() }],
/**
* Padding Start
* Padding Inline Start
* @see https://tailwindcss.com/docs/padding
*/
ps: [{ ps: scaleUnambiguousSpacing() }],
/**
* Padding End
* Padding Inline End
* @see https://tailwindcss.com/docs/padding
*/
pe: [{ pe: scaleUnambiguousSpacing() }],
/**
* Padding Block Start
* @see https://tailwindcss.com/docs/padding
*/
pbs: [{ pbs: scaleUnambiguousSpacing() }],
/**
* Padding Block End
* @see https://tailwindcss.com/docs/padding
*/
pbe: [{ pbe: scaleUnambiguousSpacing() }],
/**
* Padding Top
* @see https://tailwindcss.com/docs/padding
@@ -671,25 +754,35 @@ export const getDefaultConfig = () => {
*/
m: [{ m: scaleMargin() }],
/**
* Margin X
* Margin Inline
* @see https://tailwindcss.com/docs/margin
*/
mx: [{ mx: scaleMargin() }],
/**
* Margin Y
* Margin Block
* @see https://tailwindcss.com/docs/margin
*/
my: [{ my: scaleMargin() }],
/**
* Margin Start
* Margin Inline Start
* @see https://tailwindcss.com/docs/margin
*/
ms: [{ ms: scaleMargin() }],
/**
* Margin End
* Margin Inline End
* @see https://tailwindcss.com/docs/margin
*/
me: [{ me: scaleMargin() }],
/**
* Margin Block Start
* @see https://tailwindcss.com/docs/margin
*/
mbs: [{ mbs: scaleMargin() }],
/**
* Margin Block End
* @see https://tailwindcss.com/docs/margin
*/
mbe: [{ mbe: scaleMargin() }],
/**
* Margin Top
* @see https://tailwindcss.com/docs/margin
@@ -740,6 +833,36 @@ export const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/width#setting-both-width-and-height
*/
size: [{ size: scaleSizing() }],
/**
* Inline Size
* @see https://tailwindcss.com/docs/width
*/
'inline-size': [{ inline: ['auto', ...scaleSizingInline()] }],
/**
* Min-Inline Size
* @see https://tailwindcss.com/docs/min-width
*/
'min-inline-size': [{ 'min-inline': ['auto', ...scaleSizingInline()] }],
/**
* Max-Inline Size
* @see https://tailwindcss.com/docs/max-width
*/
'max-inline-size': [{ 'max-inline': ['none', ...scaleSizingInline()] }],
/**
* Block Size
* @see https://tailwindcss.com/docs/height
*/
'block-size': [{ block: ['auto', ...scaleSizingBlock()] }],
/**
* Min-Block Size
* @see https://tailwindcss.com/docs/min-height
*/
'min-block-size': [{ 'min-block': ['auto', ...scaleSizingBlock()] }],
/**
* Max-Block Size
* @see https://tailwindcss.com/docs/max-height
*/
'max-block-size': [{ 'max-block': ['none', ...scaleSizingBlock()] }],
/**
* Width
* @see https://tailwindcss.com/docs/width
@@ -819,7 +942,11 @@ export const getDefaultConfig = () => {
* Font Weight
* @see https://tailwindcss.com/docs/font-weight
*/
'font-weight': [{ font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber] }],
'font-weight': [
{
font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight],
},
],
/**
* Font Stretch
* @see https://tailwindcss.com/docs/font-stretch
@@ -845,7 +972,14 @@ export const getDefaultConfig = () => {
* Font Family
* @see https://tailwindcss.com/docs/font-family
*/
'font-family': [{ font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont] }],
'font-family': [
{ font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont] },
],
/**
* Font Feature Settings
* @see https://tailwindcss.com/docs/font-feature-settings
*/
'font-features': [{ 'font-features': [isArbitraryValue] }],
/**
* Font Variant Numeric
* @see https://tailwindcss.com/docs/font-variant-numeric
@@ -991,6 +1125,11 @@ export const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/text-indent
*/
indent: [{ indent: scaleUnambiguousSpacing() }],
/**
* Tab Size
* @see https://tailwindcss.com/docs/tab-size
*/
'tab-size': [{ tab: [isInteger, isArbitraryVariable, isArbitraryValue] }],
/**
* Vertical Alignment
* @see https://tailwindcss.com/docs/vertical-align
@@ -1217,25 +1356,35 @@ export const getDefaultConfig = () => {
*/
'border-w': [{ border: scaleBorderWidth() }],
/**
* Border Width X
* Border Width Inline
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-x': [{ 'border-x': scaleBorderWidth() }],
/**
* Border Width Y
* Border Width Block
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-y': [{ 'border-y': scaleBorderWidth() }],
/**
* Border Width Start
* Border Width Inline Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-s': [{ 'border-s': scaleBorderWidth() }],
/**
* Border Width End
* Border Width Inline End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-e': [{ 'border-e': scaleBorderWidth() }],
/**
* Border Width Block Start
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-bs': [{ 'border-bs': scaleBorderWidth() }],
/**
* Border Width Block End
* @see https://tailwindcss.com/docs/border-width
*/
'border-w-be': [{ 'border-be': scaleBorderWidth() }],
/**
* Border Width Top
* @see https://tailwindcss.com/docs/border-width
@@ -1292,25 +1441,35 @@ export const getDefaultConfig = () => {
*/
'border-color': [{ border: scaleColor() }],
/**
* Border Color X
* Border Color Inline
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-x': [{ 'border-x': scaleColor() }],
/**
* Border Color Y
* Border Color Block
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-y': [{ 'border-y': scaleColor() }],
/**
* Border Color S
* Border Color Inline Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-s': [{ 'border-s': scaleColor() }],
/**
* Border Color E
* Border Color Inline End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-e': [{ 'border-e': scaleColor() }],
/**
* Border Color Block Start
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-bs': [{ 'border-bs': scaleColor() }],
/**
* Border Color Block End
* @see https://tailwindcss.com/docs/border-color
*/
'border-color-be': [{ 'border-be': scaleColor() }],
/**
* Border Color Top
* @see https://tailwindcss.com/docs/border-color
@@ -1945,6 +2104,11 @@ export const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/translate
*/
'translate-none': ['translate-none'],
/**
* Zoom
* @see https://tailwindcss.com/docs/zoom
*/
zoom: [{ zoom: [isInteger, isArbitraryVariable, isArbitraryValue] }],
// ---------------------
// --- Interactivity ---
@@ -2040,31 +2204,61 @@ export const getDefaultConfig = () => {
* @see https://tailwindcss.com/docs/scroll-behavior
*/
'scroll-behavior': [{ scroll: ['auto', 'smooth'] }],
/**
* Scrollbar Thumb Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-thumb-color': [{ 'scrollbar-thumb': scaleColor() }],
/**
* Scrollbar Track Color
* @see https://tailwindcss.com/docs/scrollbar-color
*/
'scrollbar-track-color': [{ 'scrollbar-track': scaleColor() }],
/**
* Scrollbar Gutter
* @see https://tailwindcss.com/docs/scrollbar-gutter
*/
'scrollbar-gutter': [{ 'scrollbar-gutter': ['auto', 'stable', 'both'] }],
/**
* Scrollbar Width
* @see https://tailwindcss.com/docs/scrollbar-width
*/
'scrollbar-w': [{ scrollbar: ['auto', 'thin', 'none'] }],
/**
* Scroll Margin
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-m': [{ 'scroll-m': scaleUnambiguousSpacing() }],
/**
* Scroll Margin X
* Scroll Margin Inline
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mx': [{ 'scroll-mx': scaleUnambiguousSpacing() }],
/**
* Scroll Margin Y
* Scroll Margin Block
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-my': [{ 'scroll-my': scaleUnambiguousSpacing() }],
/**
* Scroll Margin Start
* Scroll Margin Inline Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-ms': [{ 'scroll-ms': scaleUnambiguousSpacing() }],
/**
* Scroll Margin End
* Scroll Margin Inline End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-me': [{ 'scroll-me': scaleUnambiguousSpacing() }],
/**
* Scroll Margin Block Start
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbs': [{ 'scroll-mbs': scaleUnambiguousSpacing() }],
/**
* Scroll Margin Block End
* @see https://tailwindcss.com/docs/scroll-margin
*/
'scroll-mbe': [{ 'scroll-mbe': scaleUnambiguousSpacing() }],
/**
* Scroll Margin Top
* @see https://tailwindcss.com/docs/scroll-margin
@@ -2091,25 +2285,35 @@ export const getDefaultConfig = () => {
*/
'scroll-p': [{ 'scroll-p': scaleUnambiguousSpacing() }],
/**
* Scroll Padding X
* Scroll Padding Inline
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-px': [{ 'scroll-px': scaleUnambiguousSpacing() }],
/**
* Scroll Padding Y
* Scroll Padding Block
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-py': [{ 'scroll-py': scaleUnambiguousSpacing() }],
/**
* Scroll Padding Start
* Scroll Padding Inline Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-ps': [{ 'scroll-ps': scaleUnambiguousSpacing() }],
/**
* Scroll Padding End
* Scroll Padding Inline End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pe': [{ 'scroll-pe': scaleUnambiguousSpacing() }],
/**
* Scroll Padding Block Start
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbs': [{ 'scroll-pbs': scaleUnambiguousSpacing() }],
/**
* Scroll Padding Block End
* @see https://tailwindcss.com/docs/scroll-padding
*/
'scroll-pbe': [{ 'scroll-pbe': scaleUnambiguousSpacing() }],
/**
* Scroll Padding Top
* @see https://tailwindcss.com/docs/scroll-padding
@@ -2232,17 +2436,29 @@ export const getDefaultConfig = () => {
'forced-color-adjust': [{ 'forced-color-adjust': ['auto', 'none'] }],
},
conflictingClassGroups: {
'container-named': ['container-type'],
overflow: ['overflow-x', 'overflow-y'],
overscroll: ['overscroll-x', 'overscroll-y'],
inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],
inset: [
'inset-x',
'inset-y',
'inset-bs',
'inset-be',
'start',
'end',
'top',
'right',
'bottom',
'left',
],
'inset-x': ['right', 'left'],
'inset-y': ['top', 'bottom'],
flex: ['basis', 'grow', 'shrink'],
gap: ['gap-x', 'gap-y'],
p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],
p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],
px: ['pr', 'pl'],
py: ['pt', 'pb'],
m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],
m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],
mx: ['mr', 'ml'],
my: ['mt', 'mb'],
size: ['w', 'h'],
@@ -2288,6 +2504,8 @@ export const getDefaultConfig = () => {
'border-w-y',
'border-w-s',
'border-w-e',
'border-w-bs',
'border-w-be',
'border-w-t',
'border-w-r',
'border-w-b',
@@ -2300,6 +2518,8 @@ export const getDefaultConfig = () => {
'border-color-y',
'border-color-s',
'border-color-e',
'border-color-bs',
'border-color-be',
'border-color-t',
'border-color-r',
'border-color-b',
@@ -2314,6 +2534,8 @@ export const getDefaultConfig = () => {
'scroll-my',
'scroll-ms',
'scroll-me',
'scroll-mbs',
'scroll-mbe',
'scroll-mt',
'scroll-mr',
'scroll-mb',
@@ -2326,6 +2548,8 @@ export const getDefaultConfig = () => {
'scroll-py',
'scroll-ps',
'scroll-pe',
'scroll-pbs',
'scroll-pbe',
'scroll-pt',
'scroll-pr',
'scroll-pb',
@@ -2341,6 +2565,7 @@ export const getDefaultConfig = () => {
conflictingClassGroupModifiers: {
'font-size': ['leading'],
},
postfixLookupClassGroups: ['container-type'],
orderSensitiveModifiers: [
'*',
'**',
+27 -7
View File
@@ -4,8 +4,13 @@ import { IMPORTANT_MODIFIER } from './parse-class-name'
const SPLIT_CLASSES_REGEX = /\s+/
export const mergeClassList = (classList: string, configUtils: ConfigUtils) => {
const { parseClassName, getClassGroupId, getConflictingClassGroupIds, sortModifiers } =
configUtils
const {
parseClassName,
getClassGroupId,
getConflictingClassGroupIds,
sortModifiers,
postfixLookupClassGroupIds,
} = configUtils
/**
* Set of classGroupIds in following format:
@@ -36,11 +41,26 @@ export const mergeClassList = (classList: string, configUtils: ConfigUtils) => {
}
let hasPostfixModifier = !!maybePostfixModifierPosition
let classGroupId = getClassGroupId(
hasPostfixModifier
? baseClassName.substring(0, maybePostfixModifierPosition)
: baseClassName,
)
let classGroupId: ReturnType<typeof getClassGroupId>
if (hasPostfixModifier) {
const baseClassNameWithoutPostfix = baseClassName.substring(
0,
maybePostfixModifierPosition,
)
classGroupId = getClassGroupId(baseClassNameWithoutPostfix)
const classGroupIdWithPostfix =
classGroupId && postfixLookupClassGroupIds[classGroupId]
? getClassGroupId(baseClassName)
: undefined
if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {
classGroupId = classGroupIdWithPostfix
hasPostfixModifier = false
}
} else {
classGroupId = getClassGroupId(baseClassName)
}
if (!classGroupId) {
if (!hasPostfixModifier) {
+2
View File
@@ -25,6 +25,7 @@ export const mergeConfigs = <ClassGroupIds extends string, ThemeGroupIds extends
baseConfig.conflictingClassGroupModifiers,
override.conflictingClassGroupModifiers,
)
overrideProperty(baseConfig, 'postfixLookupClassGroups', override.postfixLookupClassGroups)
overrideProperty(baseConfig, 'orderSensitiveModifiers', override.orderSensitiveModifiers)
mergeConfigProperties(baseConfig.theme, extend.theme)
@@ -34,6 +35,7 @@ export const mergeConfigs = <ClassGroupIds extends string, ThemeGroupIds extends
baseConfig.conflictingClassGroupModifiers,
extend.conflictingClassGroupModifiers,
)
mergeArrayProperties(baseConfig, extend, 'postfixLookupClassGroups')
mergeArrayProperties(baseConfig, extend, 'orderSensitiveModifiers')
return baseConfig
+1 -1
View File
@@ -9,7 +9,7 @@
*/
export type ClassNameValue = ClassNameArray | string | null | undefined | 0 | 0n | false
type ClassNameArray = ClassNameValue[]
type ClassNameArray = readonly ClassNameValue[]
export const twJoin = (...classLists: ClassNameValue[]): string => {
let index = 0
+61 -9
View File
@@ -2,8 +2,7 @@
* Type the tailwind-merge configuration adheres to.
*/
export interface Config<ClassGroupIds extends string, ThemeGroupIds extends string>
extends ConfigStaticPart,
ConfigGroupsPart<ClassGroupIds, ThemeGroupIds> {}
extends ConfigStaticPart, ConfigGroupsPart<ClassGroupIds, ThemeGroupIds> {}
/**
* The static part of the tailwind-merge configuration. When merging multiple configurations, the properties of this interface are always overridden.
@@ -75,7 +74,7 @@ export interface ParsedClassName {
*
* This property is prefixed with "maybe" because tailwind-merge does not know whether something is a postfix modifier or part of the base class since it's possible to configure Tailwind CSS classes which include a `/` in the base class name.
*
* If a `maybePostfixModifierPosition` is present, tailwind-merge first tries to match the `baseClassName` without the possible postfix modifier to a class group. If that fails, it tries again with the possible postfix modifier.
* If a `maybePostfixModifierPosition` is present, tailwind-merge first tries to match the `baseClassName` without the possible postfix modifier to a class group. If that fails or the matched class group is configured in `postfixLookupClassGroups`, it tries again with the possible postfix modifier.
*
* @example 11 // for `bg-gray-100/50`
*/
@@ -124,6 +123,14 @@ interface ConfigGroupsPart<ClassGroupIds extends string, ThemeGroupIds extends s
conflictingClassGroupModifiers: NoInfer<
Partial<Record<ClassGroupIds, readonly ClassGroupIds[]>>
>
/**
* Class group IDs which should be resolved again with their postfix modifier attached.
*
* This is needed when a slash can make the full class name belong to a different class group than the part before the slash.
*
* @example ['container-type'] // `@container-size/sidebar` should resolve differently from `@container-size`
*/
postfixLookupClassGroups?: readonly NoInferString<ClassGroupIds>[]
/**
* Modifiers whose order among multiple modifiers should be preserved because their order changes which element gets targeted.
*
@@ -135,14 +142,23 @@ interface ConfigGroupsPart<ClassGroupIds extends string, ThemeGroupIds extends s
/**
* Type of the configuration object that can be passed to `extendTailwindMerge`.
*/
export interface ConfigExtension<ClassGroupIds extends string, ThemeGroupIds extends string>
extends Partial<ConfigStaticPart> {
override?: PartialPartial<ConfigGroupsPart<ClassGroupIds, ThemeGroupIds>>
extend?: PartialPartial<ConfigGroupsPart<ClassGroupIds, ThemeGroupIds>>
export interface ConfigExtension<
ClassGroupIds extends string,
ThemeGroupIds extends string,
> extends Partial<ConfigStaticPart> {
override?: PartialConfigGroupsPart<ClassGroupIds, ThemeGroupIds>
extend?: PartialConfigGroupsPart<ClassGroupIds, ThemeGroupIds>
}
type PartialPartial<T> = {
[P in keyof T]?: T[P] extends any[] ? T[P] : Partial<T[P]>
interface PartialConfigGroupsPart<ClassGroupIds extends string, ThemeGroupIds extends string> {
theme?: NoInfer<Partial<ThemeObject<ThemeGroupIds>>>
classGroups?: NoInfer<Partial<Record<ClassGroupIds, ClassGroup<ThemeGroupIds>>>>
conflictingClassGroups?: NoInfer<Partial<Record<ClassGroupIds, readonly ClassGroupIds[]>>>
conflictingClassGroupModifiers?: NoInfer<
Partial<Record<ClassGroupIds, readonly ClassGroupIds[]>>
>
postfixLookupClassGroups?: readonly NoInferString<ClassGroupIds>[]
orderSensitiveModifiers?: string[]
}
export type ThemeObject<ThemeGroupIds extends string> = Record<
@@ -172,6 +188,13 @@ type ClassObject<ThemeGroupIds extends string> = Record<
*/
export type NoInfer<T> = [T][T extends any ? 0 : never]
/**
* Special-purpose NoInfer variant for string unions used in array item positions.
*
* The NoInfer helper above doesn't prevent inference from array items in all cases, so this keeps config arrays like `postfixLookupClassGroups` from defining or narrowing class group IDs. Once tailwind-merge only supports TypeScript 5.4 and newer, this can be replaced with TypeScript's built-in NoInfer utility type.
*/
type NoInferString<T extends string> = T extends infer S ? S & string : never
/**
* Theme group IDs included in the default configuration of tailwind-merge.
*
@@ -236,9 +259,12 @@ export type DefaultClassGroupIds =
| 'bg-position'
| 'bg-repeat'
| 'bg-size'
| 'block-size'
| 'blur'
| 'border-collapse'
| 'border-color-b'
| 'border-color-be'
| 'border-color-bs'
| 'border-color-e'
| 'border-color-l'
| 'border-color-r'
@@ -252,6 +278,8 @@ export type DefaultClassGroupIds =
| 'border-spacing'
| 'border-style'
| 'border-w-b'
| 'border-w-be'
| 'border-w-bs'
| 'border-w-e'
| 'border-w-l'
| 'border-w-r'
@@ -277,6 +305,8 @@ export type DefaultClassGroupIds =
| 'color-scheme'
| 'columns'
| 'container'
| 'container-named'
| 'container-type'
| 'content'
| 'contrast'
| 'cursor'
@@ -301,6 +331,7 @@ export type DefaultClassGroupIds =
| 'flex'
| 'float'
| 'font-family'
| 'font-features'
| 'font-size'
| 'font-smoothing'
| 'font-stretch'
@@ -331,10 +362,13 @@ export type DefaultClassGroupIds =
| 'hue-rotate'
| 'hyphens'
| 'indent'
| 'inline-size'
| 'inset-ring-color'
| 'inset-ring-w'
| 'inset-shadow-color'
| 'inset-shadow'
| 'inset-be'
| 'inset-bs'
| 'inset-x'
| 'inset-y'
| 'inset'
@@ -401,11 +435,17 @@ export type DefaultClassGroupIds =
| 'mask-repeat'
| 'mask-size'
| 'mask-type'
| 'max-block-size'
| 'max-h'
| 'max-inline-size'
| 'max-w'
| 'mb'
| 'mbe'
| 'mbs'
| 'me'
| 'min-block-size'
| 'min-h'
| 'min-inline-size'
| 'min-w'
| 'mix-blend'
| 'ml'
@@ -430,6 +470,7 @@ export type DefaultClassGroupIds =
| 'overscroll'
| 'p'
| 'pb'
| 'pbe'
| 'pe'
| 'perspective-origin'
| 'perspective'
@@ -442,6 +483,7 @@ export type DefaultClassGroupIds =
| 'position'
| 'pr'
| 'ps'
| 'pbs'
| 'pt'
| 'px'
| 'py'
@@ -480,21 +522,29 @@ export type DefaultClassGroupIds =
| 'scale-y'
| 'scale-z'
| 'scale'
| 'scrollbar-gutter'
| 'scrollbar-thumb-color'
| 'scrollbar-track-color'
| 'scrollbar-w'
| 'scroll-behavior'
| 'scroll-m'
| 'scroll-mb'
| 'scroll-mbe'
| 'scroll-me'
| 'scroll-ml'
| 'scroll-mr'
| 'scroll-mbs'
| 'scroll-ms'
| 'scroll-mt'
| 'scroll-mx'
| 'scroll-my'
| 'scroll-p'
| 'scroll-pb'
| 'scroll-pbe'
| 'scroll-pe'
| 'scroll-pl'
| 'scroll-pr'
| 'scroll-pbs'
| 'scroll-ps'
| 'scroll-pt'
| 'scroll-px'
@@ -521,6 +571,7 @@ export type DefaultClassGroupIds =
| 'stroke-w'
| 'stroke'
| 'table-layout'
| 'tab-size'
| 'text-alignment'
| 'text-color'
| 'text-decoration-color'
@@ -555,6 +606,7 @@ export type DefaultClassGroupIds =
| 'whitespace'
| 'will-change'
| 'wrap'
| 'zoom'
| 'z'
export type AnyClassGroupIds = string
+17 -1
View File
@@ -1,6 +1,6 @@
const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i
const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i
const fractionRegex = /^\d+\/\d+$/
const fractionRegex = /^\d+(?:\.\d+)?\/\d+(?:\.\d+)?$/
const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/
const lengthUnitRegex =
/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/
@@ -37,6 +37,12 @@ const isImage = (value: string) => imageRegex.test(value)
export const isAnyNonArbitrary = (value: string) =>
!isArbitraryValue(value) && !isArbitraryVariable(value)
export const isNamedContainerQuery = (value: string) =>
value.startsWith('@container') &&
((value[10] === '/' && value[11] !== undefined) ||
(value[11] === 's' && value[16] !== undefined && value.startsWith('-size/', 10)) ||
(value[11] === 'n' && value[18] !== undefined && value.startsWith('-normal/', 10)))
export const isArbitrarySize = (value: string) => getIsArbitraryValue(value, isLabelSize, isNever)
export const isArbitraryValue = (value: string) => arbitraryValueRegex.test(value)
@@ -47,6 +53,11 @@ export const isArbitraryLength = (value: string) =>
export const isArbitraryNumber = (value: string) =>
getIsArbitraryValue(value, isLabelNumber, isNumber)
export const isArbitraryWeight = (value: string) => getIsArbitraryValue(value, isLabelWeight, isAny)
export const isArbitraryFamilyName = (value: string) =>
getIsArbitraryValue(value, isLabelFamilyName, isNever)
export const isArbitraryPosition = (value: string) =>
getIsArbitraryValue(value, isLabelPosition, isNever)
@@ -74,6 +85,9 @@ export const isArbitraryVariableImage = (value: string) =>
export const isArbitraryVariableShadow = (value: string) =>
getIsArbitraryVariable(value, isLabelShadow, true)
export const isArbitraryVariableWeight = (value: string) =>
getIsArbitraryVariable(value, isLabelWeight, true)
// Helpers
const getIsArbitraryValue = (
@@ -125,4 +139,6 @@ const isLabelNumber = (label: string) => label === 'number'
const isLabelFamilyName = (label: string) => label === 'family-name'
const isLabelWeight = (label: string) => label === 'number' || label === 'weight'
const isLabelShadow = (label: string) => label === 'shadow'