tw-merge
Version:
Merge CSS utility classes without style conflicts - small and zero config
136 lines (120 loc) • 5.82 kB
text/typescript
import {
RuleSet,
uniqueRule,
simpleRule,
cardinalRules,
cardinalRule,
arbitraryRule,
conflictRule,
} from "./rules";
const DISPLAY =
"block|inline-block|inline-flex|inline-table|inline-grid|inline|flex|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|flow-root|grid|contents|list-item|hidden";
const ISOLATION = "isolate|isolation-auto";
const OBJECT_FIT = "contain|cover|fill|none|scale-down";
const BG_AND_OBJECT_POSITION =
"bottom|center|left|left-bottom|left-top|right|right-bottom|right-top|top";
const POSITION = "static|fixed|absolute|relative|sticky";
const VISIBILITY = "visible|invisible|collapse";
const FLEX_DIRECTION = "row|row-reverse|col|col-reverse";
const FLEX_WRAP = "wrap|wrap-reverse|nowrap";
const ALIGN_CONTENT =
"normal|center|start|end|between|around|evenly|baseline|stretch";
const FONT_AND_SHADOW_SIZE = "xs|sm|base|md|lg|xl|[\\d.]+xl|inner|none";
const FONT_SMOOTHING = "antialiased|subpixel-antialiased";
const FONT_STYLE = "italic|not-italic";
const FONT_WEIGHT =
"thin|extralight|light|normal|medium|semibold|bold|extrabold|black";
const LIST_STYLE_POSITION = "inside|outside";
const TEXT_ALIGN = "left|center|right|justify|start|end";
const TEXT_DECORATION = "underline|overline|line-through|no-underline";
const TEXT_DECORATION_STYLE = "solid|double|dotted|dashed|wavy";
const TEXT_TRANSFORM = "uppercase|lowercase|capitalize|normal-case";
const TEXT_OVERFLOW = "truncate|text-ellipsis|text-clip";
const BG_ATTACHMENT = "fixed|local|scroll";
const BG_REPEAT =
"repeat|no-repeat|repeat-x|repeat-y|repeat-round|repeat-space";
const BG_SIZE = "auto|cover|contain";
const BORDER_AND_OUTLINE_STYLE = "solid|dashed|dotted|double|hidden|none";
const FVN_FIGURE = "lining-nums|oldstyle-nums";
const FVN_SPACING = "proportional-nums|tabular-nums";
const FVN_FRACTION = "diagonal-fractions|stacked-fractions";
const SCROLL_BEHAVIOR = "auto|smooth";
const SCROLL_SNAP_ALIGN = "start|end|center|none";
const SCROLL_SNAP_STOP = "normal|always";
const SCROLL_SNAP_TYPE = "none|x|y|both|mandatory|proximity";
// TODO: text-<something>/20 should override line-height (leading)
// TODO: ^ same with opacities and other trailing slash values
// TODO: text-decoration-thickness (conflicts with text-decoration-color and there are custom values: auto and from-font)
export function tailwind(): RuleSet {
return [
// these rules are at the top because they need to run before others
conflictRule({
"inset-x": "left|right",
"inset-y": "top|bottom",
inset: "inset-x|inset-y|start|end|left|right|top|bottom",
"sr-only": "not-sr-only",
"not-sr-only": "sr-only",
"normal-nums":
"ordinal|slashed-zero|lining-nums|oldstyle-nums|proportional-nums|tabular-nums|diagonal-fractions|stacked-fractons",
ordinal: "normal-nums",
"slashed-zero": "normal-nums",
"lining-nums": "normal-nums",
"oldstyle-nums": "normal-nums",
"proportional-nums": "normal-nums",
"tabular-nums": "normal-nums",
"diagonal-fractions": "normal-nums",
"stacked-fractons": "normal-nums",
"bg-gradient": "bg-none",
"bg-none": "bg-gradient",
}),
uniqueRule([
DISPLAY,
ISOLATION,
POSITION,
VISIBILITY,
FONT_SMOOTHING,
FONT_STYLE,
FVN_FIGURE,
FVN_SPACING,
FVN_FRACTION,
TEXT_DECORATION,
TEXT_TRANSFORM,
TEXT_OVERFLOW,
]),
uniqueRule([
["content", ALIGN_CONTENT],
["list", LIST_STYLE_POSITION],
["decoration", TEXT_DECORATION_STYLE],
["border", BORDER_AND_OUTLINE_STYLE],
["divide", BORDER_AND_OUTLINE_STYLE],
["outline|outline", BORDER_AND_OUTLINE_STYLE],
["shadow", FONT_AND_SHADOW_SIZE],
["font", FONT_WEIGHT],
["object", OBJECT_FIT, BG_AND_OBJECT_POSITION],
]),
uniqueRule([
[
"scroll",
SCROLL_BEHAVIOR,
SCROLL_SNAP_ALIGN,
SCROLL_SNAP_STOP,
SCROLL_SNAP_TYPE,
],
["bg", BG_ATTACHMENT, BG_AND_OBJECT_POSITION, BG_REPEAT, BG_SIZE],
["text", TEXT_ALIGN, FONT_AND_SHADOW_SIZE],
["flex", FLEX_DIRECTION, FLEX_WRAP],
]),
conflictRule({ flex: "basis|grow|shrink" }),
// -----------------------------------------------------------------
simpleRule(
"accent|align|animate|aspect|auto-cols|auto-rows|backdrop-blur|backdrop-brightness|backdrop-contrast|backdrop-grayscale|backdrop-hue-rotate|backdrop-invert|backdrop-opacity|backdrop-saturate|backdrop-sepia|basis|bg-blend|bg-clip|bg-origin|bg-none|bg-gradient|bg|blur|border-collapse|border-spacing|bottom|box-decoration|box|break-after|break-before|break-inside|break|brightness|caption|caret|clear|col-end|col-start|columns|col|content|contrast|cursor|decoration|delay|divide-x-reverse|divide-x|divide-y-reverse|divide-y|divide|drop-shadow|duration|ease|end|fill|flex|float|grayscale|grid-cols|grid-flow|grid-rows|grow|hue-rotate|hyphens|h|indent|invert|items|justify-items|justify-self|justify|leading|left|line-clamp|list-image|list|max-h|max-w|min-h|min-w|mix-blend|opacity|order|origin|outline-offset|place-content|place-items|place-self|pointer-events|resize|right|ring-inset|rotate|row-end|row-start|row|saturate|select|self|sepia|shadow|shrink|skew-x|skew-y|space-x-reverse|space-x|space-y-reverse|space-y|start|table|top|touch|tracking|transition|translate-x|translate-y|underline-offset|whitespace|will-change|w|z"
),
simpleRule("text|outline|ring-offset|ring|from|via|to|stroke|font", {
byType: true,
}),
cardinalRule("border", { byType: true }),
...cardinalRules("rounded|gap|inset|scale|overflow|overscroll"),
...cardinalRules("p|m|scroll-m|scroll-p", { dash: false }),
arbitraryRule(),
];
}