### Installation commands Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Commands to install tailwind-merge using different package managers. ```sh npm add tailwind-merge yarn add tailwind-merge pnpm add tailwind-merge bun add tailwind-merge ``` -------------------------------- ### Manual dry run example Source: https://github.com/dcastil/tailwind-merge/blob/main/agents/release-workflow.md Example of how to run the release commenter workflow manually with a dry run option. ```bash gh workflow run comment-released-prs-and-issues.yml \ -f head_tag=v3.4.1 \ -f dry_run=true ``` -------------------------------- ### fromTheme usage example Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md Example of using fromTheme with custom class and theme group IDs. ```typescript type AdditionalClassGroupIds = 'badge' | 'badge-color' type AdditionalThemeGroupIds = 'custom-color' extendTailwindMerge({ extend: { theme: { 'custom-color': ['primary', 'secondary'], }, classGroups: { badge: [{ badge: [fromTheme('text')] }], 'badge-color': [{ badge: [fromTheme('custom-color')] }], }, }, }) ``` -------------------------------- ### Example of merging configurations with mergeConfigs Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md An example demonstrating how to use mergeConfigs within createTailwindMerge to override and extend existing class groups, and add new ones. ```typescript const twMerge = createTailwindMerge(getDefaultConfig, (config) => mergeConfigs<'shadow' | 'animate' | 'prose'>(config, { override: { classGroups: { // ↓ Overriding existing class group shadow: [{ shadow: ['100', '200', '300', '400', '500'] }], }, }, extend: { classGroups: { // ↓ Adding value to existing class group animate: ['animate-shimmer'], // ↓ Adding new class group prose: [{ prose: ['', validators.isTshirtSize] }], }, }, }), ) ``` -------------------------------- ### extendTailwindMerge Configuration Example Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md Demonstrates how to extend tailwind-merge with custom configurations for class groups and modifiers. ```javascript const twMerge = extendTailwindMerge({ classGroups: { // ↓ …classes from groups with these IDs // In this case `twMerge('aspect-w-5 aspect-none') → 'aspect-none'` 'aspect-reset': ['aspect-w', 'aspect-h'], }, // ↓ Conflicts between the postfix modifier of a group and a different class group to // extend or create conflictingClassGroupModifiers: { // You probably won't need this, but it follows the same shape as // `conflictingClassGroups`. }, // ↓ Class group IDs which should be resolved again with their postfix modifier attached. // Extends default value. postfixLookupClassGroups: ['aspect-reset'], // ↓ Modifiers whose order among multiple modifiers should be preserved because their // order changes which element gets targeted. Extends default value. orderSensitiveModifiers: ['before'], }) ``` -------------------------------- ### Position Class Group Example Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md An example of a class group for Tailwind's position utility classes. ```typescript const positionClassGroup = ['static', 'fixed', 'absolute', 'relative', 'sticky'] ``` -------------------------------- ### Example Usage Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md Demonstrates how to use validators with custom configurations. ```typescript const paddingClassGroup = [{ p: [validators.isNumber] }] const customImageGroup = [{ 'custom-img': [validators.isArbitraryImage] }] ``` -------------------------------- ### Fetch active GitHub sponsors Source: https://github.com/dcastil/tailwind-merge/blob/main/agents/release-workflow.md GraphQL query to fetch active GitHub sponsors in order of their start date. ```bash gh api graphql -f query='query($login:String!){ user(login:$login){ sponsorshipsAsMaintainer(first:100, activeOnly:true, includePrivate:false, orderBy:{field:CREATED_AT, direction:ASC}){ nodes{ sponsorEntity{ ... on User{ login } ... on Organization{ login } } } } } }' -F login=dcastil ``` -------------------------------- ### extendTailwindMerge usage example Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md An example demonstrating how to use extendTailwindMerge with custom class group IDs, theme group IDs, and configuration overrides/extensions. ```typescript type AdditionalClassGroupIds = 'aspect-w' | 'aspect-h' | 'aspect-reset' type AdditionalThemeGroupIds = never const twMerge = extendTailwindMerge({ // ↓ Optional cache size // Here we're disabling the cache cacheSize: 0, // ↓ Optional prefix from TaiLwind config prefix: 'tw', // ↓ Optional config overrides // Only elements from the second level onwards are overridden override: { // ↓ Theme scales to override theme: { colors: ['black', 'white', 'yellow-500'], }, // ↓ Class groups to override classGroups: { // ↓ The `shadow` key here is the class group ID // ↓ Creates group of classes which have conflicting styles // Classes here: shadow-100, shadow-200, shadow-300, shadow-400, shadow-500 shadow: [{ shadow: ['100', '200', '300', '400', '500'] }], }, // ↓ Conflicts across different groups to override conflictingClassGroups: { // ↓ ID of class group which creates a conflict with… // ↓ …classes from groups with these IDs // Here we remove the default conflict between the font-size and leading class // groups. 'font-size': [], }, // ↓ Conflicts between the postfix modifier of a group and a different class group to // override conflictingClassGroupModifiers: { // You probably won't need this, but it follows the same shape as // `conflictingClassGroups`. }, // ↓ Class group IDs which should be resolved again with their postfix modifier attached. // Overrides default value. postfixLookupClassGroups: ['container-type'], // ↓ Modifiers whose order among multiple modifiers should be preserved because their // order changes which element gets targeted. Overrides default value. orderSensitiveModifiers: ['before'], }, // ↓ Optional config extensions // Follows same shape as the `override` object. extend: { // ↓ Theme scales to extend or create theme: { spacing: ['sm', 'md', 'lg'], }, // ↓ Class groups to extend or create classGroups: { // ↓ The `animate` key here is the class group ID // ↓ Adds class animate-shimmer to existing group with ID `animate` or creates // new class group if it doesn't exist. animate: ['animate-shimmer'], // ↓ Functions can also be used to match classes // They take the class part value as argument and return a boolean defining whether // it is a match. // Here we accept all string classes starting with `aspec-w-` followed by a number. 'aspect-w': [{ 'aspect-w': [(value) => Boolean(value) && !isNaN(value)] }], 'aspect-h': [{ 'aspect-h': [(value) => Boolean(value) && !isNaN(value)] }], 'aspect-reset': ['aspect-none'], // ↓ You can also use validators exported by tailwind-merge 'prose-size': [{ prose: ['base', validators.isTshirtSize] }], }, // ↓ Conflicts across different groups to extend or create conflictingClassGroups: { // ↓ ID of class group which creates a conflict with… ``` -------------------------------- ### Example of creating a custom merge function with createTailwindMerge Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md An example demonstrating how to use createTailwindMerge to create a custom twMerge function by extending the default configuration with custom class groups, conflicting class groups, and modifiers. ```typescript // ↓ Callback passed to `createTailwindMerge` is called when // `twMerge` gets called the first time. const twMerge = createTailwindMerge(() => { const defaultConfig = getDefaultConfig() return { cacheSize: 0, classGroups: { ...defaultConfig.classGroups, badge: ['badge', 'badge-pill', { 'badge-dot': ['', 'sm', 'lg'] }], 'icon-size': [{ icon: ['auto', (value) => Number(value) >= 16] }], card: ['card-sm', 'card-md', 'card-lg'], }, conflictingClassGroups: { ...defaultConfig.conflictingClassGroups, badge: ['icon-size'], }, conflictingClassGroupModifiers: { ...defaultConfig.conflictingClassGroupModifiers, card: ['icon-size'], }, postfixLookupClassGroups: defaultConfig.postfixLookupClassGroups, orderSensitiveModifiers: [...defaultConfig.orderSensitiveModifiers, 'before'], } }) ``` -------------------------------- ### Fill Class Group Example with Arbitrary Value Validator Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md An example of a class group for Tailwind's fill utility classes, including a validator for arbitrary values. ```typescript const isArbitraryValue = (classPart: string) => /^[\[.+\]]$/.test(classPart) const fillClassGroup = [{ fill: ['current', isArbitraryValue] }] ``` -------------------------------- ### Overflow Class Group Example with Nested Object Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md An example of a class group using a nested object structure for Tailwind's overflow utility classes. ```typescript const overflowClassGroup = [{ overflow: ['auto', 'hidden', 'visible', 'scroll'] }] ``` -------------------------------- ### Using multiple createConfig functions with createTailwindMerge Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md An example showing how to use multiple createConfig functions with createTailwindMerge, including combining configurations from third-party plugins. ```typescript const twMerge = createTailwindMerge(getDefaultConfig, withSomePlugin, (config) => ({ // ↓ Config returned by `withSomePlugin` ...config, classGroups: { ...config.classGroups, mySpecialClassGroup: [{ special: ['1', '2'] }], }, })) ``` -------------------------------- ### Basic Usage Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/README.md Example of merging Tailwind CSS classes using twMerge. ```typescript import { twMerge } from 'tailwind-merge' twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]') // → 'hover:bg-dark-red p-3 bg-[#B91C1C]' ``` -------------------------------- ### Shape of tailwind-merge config Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Example structure of the tailwind-merge configuration object. ```typescript const tailwindMergeConfig = { // ↓ Set how many values should be stored in cache. cacheSize: 500, // ↓ Optional prefix from Tailwind config prefix: 'tw', theme: { // Theme scales are defined here }, classGroups: { // Class groups are defined here }, conflictingClassGroups: { // Conflicts between class groups are defined here }, conflictingClassGroupModifiers: { // Conflicts between postfix modifier of a class group and another class group are defined here }, postfixLookupClassGroups: [ // Class group IDs which should be resolved again with their postfix modifier attached ], orderSensitiveModifiers: [ // Modifiers whose order among multiple modifiers should be preserved because their order // changes which element gets targeted. ], } ``` -------------------------------- ### Extending the tailwind-merge config Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Example of using `extendTailwindMerge` to override and extend the default configuration, including theme, class groups, and conflicts. ```typescript import { extendTailwindMerge } from 'tailwind-merge' const twMerge = extendTailwindMerge<'badge' | 'icon-size' | 'card'>({ // ↓ Override elements from the default config // It has the same shape as the `extend` object, so we're going to skip it here. override: {}, // ↓ Extend values from the default config extend: { // ↓ Add values to existing theme scale or create a new one theme: { spacing: ['sm', 'md', 'lg'], }, // ↓ Add values to existing class groups or define new ones classGroups: { badge: ['badge', 'badge-pill', { 'badge-dot': ['', 'sm', 'lg'] }], 'icon-size': [{ icon: ['auto', (value) => Number(value) >= 16] }], card: ['card-sm', 'card-md', 'card-lg'], }, // ↓ Here you can define additional conflicts across class groups conflictingClassGroups: { badge: ['icon-size'], }, // ↓ Define conflicts between postfix modifiers and class groups conflictingClassGroupModifiers: { card: ['icon-size'], }, // ↓ Define order-sensitive modifiers orderSensitiveModifiers: ['custom-variant'], }, }) ``` -------------------------------- ### Filter Class Group Example with DEFAULT value Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md An example of a class group for Tailwind's filter utility classes, using an empty string to indicate the DEFAULT value. ```typescript // ↓ Resolves to filter and filter-none const filterClassGroup = [{ filter: ['', 'none'] }] ``` -------------------------------- ### Adding custom spacing values Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Example of how to configure tailwind-merge to recognize custom spacing variables defined in Tailwind CSS. ```css /* In your CSS or Tailwind config */ @theme { --spacing-gutter: 1.5rem; --spacing-section: 5rem; } ``` ```typescript const customTwMerge = extendTailwindMerge({ extend: { theme: { spacing: ['gutter', 'section'], }, }, }) // Now works with custom spacing values across all spacing utilities customTwMerge('p-4 p-gutter') // → 'p-gutter' customTwMerge('mt-section mt-4') // → 'mt-4' customTwMerge('gap-2 gap-gutter') // → 'gap-gutter' ``` -------------------------------- ### Custom Tailwind Merge Configuration Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Example of creating a custom `twMerge` function using `createTailwindMerge` with specific cache size, theme, class groups, and conflicting class groups. ```typescript import { createTailwindMerge } from 'tailwind-merge' const twMerge = createTailwindMerge(() => ({ cacheSize: 500, theme: {}, classGroups: { badge: ['badge', 'badge-pill', { 'badge-dot': ['', 'sm', 'lg'] }], 'icon-size': [{ icon: ['auto', (value) => Number(value) >= 16] }], card: ['card-sm', 'card-md', 'card-lg'], }, conflictingClassGroups: { badge: ['icon-size'], }, conflictingClassGroupModifiers: { card: ['icon-size'], }, orderSensitiveModifiers: [], })) ``` -------------------------------- ### Adding custom font sizes Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Example of how to configure tailwind-merge to recognize custom font size variables defined in Tailwind CSS. ```css /* In your CSS or Tailwind config */ @theme { --text-huge: 100px; } ``` ```typescript import { extendTailwindMerge } from 'tailwind-merge' const customTwMerge = extendTailwindMerge({ extend: { theme: { // ↓ `text` is the key of the namespace `--text-*` // ↓ `huge` is the variable name without the namespace prefix text: ['huge'], }, }, }) // Now tailwind-merge correctly handles your custom font size customTwMerge('text-lg text-huge') // → 'text-huge' customTwMerge('text-huge text-sm') // → 'text-sm' ``` -------------------------------- ### Defining asymmetric conflicts Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Example of how to define conflicting class groups in tailwind-merge configuration. ```typescript const conflictingClassGroups = { // \includegraphics{ px creates a conflict with pr and pl px: ['pr', 'pl'], } ``` -------------------------------- ### TypeScript types for `extendTailwindMerge` Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Example demonstrating how to use generic arguments with `extendTailwindMerge` to define additional class group and theme group IDs in TypeScript. ```typescript import { extendTailwindMerge } from 'tailwind-merge' type AdditionalClassGroupIDs = 'class-a' | 'class-b' type AdditionalThemeGroupIDs = 'theme-c' | 'theme-d' const twMerge = extendTailwindMerge< // ↓ Add additional class group IDs as the first generic argument AdditionalClassGroupIDs, // ↓ Optionally, you can add additional theme group IDs as the second generic argument AdditionalThemeGroupIDs >({ extend: { theme: { // ↓ Works because we defined 'theme-c' as additional theme group ID 'theme-c': […], // ↓ Works because we defined 'theme-d' as additional theme group ID 'theme-d': […], }, classGroups: { // ↓ Works because it's part of the default additional class group IDs shadow: […], // ↓ Works because we defined 'class-a' as additional class group ID 'class-a': […], // ↓ Works because we defined 'class-b' as additional class group ID 'class-b': […], // ↓ Type […] is not assignable to type […]. // Object literal may only specify known properties, and ''not-defined'' does not exist in type […]. ts(2322) 'not-defined': [], }, }, }) ``` ```typescript import { extendTailwindMerge } from 'tailwind-merge' const twMerge = extendTailwindMerge(/* anything goes here */) ``` -------------------------------- ### Class Group Conflict Resolution Example Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Demonstrates how tailwind-merge resolves conflicts within a class group, keeping the last class. ```typescript twMerge('static sticky relative') // → 'relative' ``` -------------------------------- ### Wrapping twMerge with a custom function Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md Example of how to wrap the twMerge function with your own function, utilizing the ClassNameValue type. ```typescript function myWrappedTwMerge(...args: ClassNameValue[]) { doSomething() return twMerge(...args) } ``` -------------------------------- ### Extend Tailwind Merge with Custom Shadow Scale Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/recipes.md Configure tailwind-merge to resolve conflicts with custom shadow scales by extending the default theme. This example adds custom shadow values '100', '200', and '300' to the theme configuration. ```javascript import { extendTailwindMerge } from 'tailwind-merge' const twMerge = extendTailwindMerge({ extend: { theme: { // We only need to define the custom scale values without the `shadow-` prefix when adding them to the theme object shadow: ['100', '200', '300'], }, }, }) ``` -------------------------------- ### Extending tailwind-merge with custom class groups Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md Example of how to extend tailwind-merge with custom class groups that accept numbers, fractions, arbitrary values, t-shirt sizes, or any value. ```typescript import { extendTailwindMerge, validators } from 'tailwind-merge' const twMerge = extendTailwindMerge({ extend: { classGroups: { // Custom size classes that accept numbers or fractions 'custom-size': [{ size: [validators.isNumber, validators.isFraction] }], // Custom image classes 'hero-image': [{ 'hero-img': [validators.isArbitraryImage] }], // Custom spacing with T-shirt sizes 'custom-gap': [{ gap: [validators.isTshirtSize] }], // Accept any value (use with caution) 'theme-color': [{ theme: [validators.isAny] }], }, }, }) ``` -------------------------------- ### twJoin usage example Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md Function to join className strings conditionally without resolving conflicts. It is used internally within twMerge and is a direct subset of clsx. ```typescript twJoin( 'border border-red-500', hasBackground && 'bg-red-100', hasLargeText && 'text-lg', hasLargeSpacing && ['p-2', hasLargeText ? 'leading-8' : 'leading-7'], ) ``` -------------------------------- ### Fetch draft release Source: https://github.com/dcastil/tailwind-merge/blob/main/agents/release-workflow.md Command to fetch details of a draft release from GitHub. ```bash gh release view --json tagName,name,isDraft,body,url,createdAt,targetCommitish ``` -------------------------------- ### Using Tailwind Merge Plugins Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Demonstrates how to integrate third-party plugins with both `extendTailwindMerge` and `createTailwindMerge`. ```typescript import { extendTailwindMerge, createTailwindMerge } from 'tailwind-merge' import { withMagic } from 'tailwind-merge-magic-plugin' import { withMoreMagic } from 'tailwind-merge-more-magic-plugin' // With your own config const twMerge1 = extendTailwindMerge({ … }, withMagic, withMoreMagic) // Only using plugin with default config const twMerge2 = extendTailwindMerge(withMagic, withMoreMagic) // Using `createTailwindMerge` const twMerge3 = createTailwindMerge(() => ({ … }), withMagic, withMoreMagic) ``` -------------------------------- ### Note about custom colors Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Demonstrates that custom colors in the `--color-*` namespace do not require explicit configuration in tailwind-merge. ```css /* In your CSS or Tailwind config */ @theme { --color-brand-primary: #3b82f6; --color-brand-secondary: #8b5cf6; } ``` ```typescript import { twMerge } from 'tailwind-merge' // Works without any configuration twMerge('bg-blue-500 bg-brand-primary') // → 'bg-brand-primary' twMerge('text-brand-primary text-brand-secondary') // → 'text-brand-secondary' twMerge('border-custom-color border-brand-primary') // → 'border-brand-primary' ``` -------------------------------- ### Core Commands Source: https://github.com/dcastil/tailwind-merge/blob/main/AGENTS.md A list of core commands used for development and maintenance within the repository, managed by pnpm. ```bash pnpm install --frozen-lockfile pnpm lint pnpm test pnpm test:watch pnpm build pnpm test:exports pnpm bench ``` -------------------------------- ### Support Custom Colors Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/features.md Resolves conflicts for custom color utilities. ```ts twMerge('text-red text-secret-sauce') // → 'text-secret-sauce' ``` -------------------------------- ### Bump package versions Source: https://github.com/dcastil/tailwind-merge/blob/main/agents/release-workflow.md Command to bump package versions using pnpm, which also handles lifecycle scripts and version commit/tag. ```bash pnpm version ``` -------------------------------- ### Support Arbitrary Values Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/features.md Handles arbitrary values including CSS variables and grid configurations. ```ts twMerge('bg-black bg-(--my-color) bg-[color:var(--mystery-var)]') // → 'bg-[color:var(--mystery-var)]' twMerge('grid-cols-[1fr,auto] grid-cols-2') // → 'grid-cols-2' ``` -------------------------------- ### Handling Arbitrary Values in text-* Classes Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/limitations.md Use explicit labels for arbitrary values when tailwind-merge cannot automatically distinguish between font-size and text-color. ```ts // ✅ Clear cases (no label needed) twMerge('text-[12px] text-[16px]') // → 'text-[16px]' (detected as font-size) twMerge('text-[#ff0000] text-[#00ff00]') // → 'text-[#00ff00]' (detected as color) // ⚠️ Ambiguous cases (label recommended) twMerge('text-[theme(myCustomScale.value)] text-lg') // → 'text-[theme(myCustomScale.value)] text-lg' (without label, defaults to color interpretation) // ✅ Use explicit label for clarity twMerge('text-[length:theme(myCustomScale.value)] text-lg') // → 'text-lg' ``` -------------------------------- ### Check whether private active sponsors exist Source: https://github.com/dcastil/tailwind-merge/blob/main/agents/release-workflow.md GraphQL query to check the total count of public and all (including private) active sponsors. ```bash gh api graphql -f query='query($login:String!){ user(login:$login){ public: sponsorshipsAsMaintainer(first:100, activeOnly:true, includePrivate:false){ totalCount } all: sponsorshipsAsMaintainer(first:100, activeOnly:true, includePrivate:true){ totalCount } } }' -F login=dcastil ``` -------------------------------- ### Allow Class Refinements Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/features.md Shows how non-conflicting classes are preserved. ```ts twMerge('p-3 px-5') // → 'p-3 px-5' twMerge('inset-x-4 right-4') // → 'inset-x-4 right-4' ``` -------------------------------- ### Combining Multiple createConfig Functions Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/api-reference.md Shows how to combine multiple createConfig functions, including third-party plugins, with extendTailwindMerge. ```javascript const twMerge = extendTailwindMerge({ … }, withSomePlugin) ``` -------------------------------- ### React Component Class Conflict Example Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/what-is-it-for.md Demonstrates a common issue where Tailwind CSS classes in a component string fail to override due to CSS cascade rules. ```jsx // React components with JSX syntax used in this example function MyGenericInput(props) { const className = `border rounded px-2 py-1 ${props.className || ''}` return } function MyOneOffInput(props) { return ( ) } ``` -------------------------------- ### Postfix lookup class groups Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/configuration.md Configuration for class groups where the slash belongs to the full class name. ```typescript const postfixLookupClassGroups = ['container-type'] ``` -------------------------------- ### Automatic Arbitrary Value Detection Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/features.md Shows how the library automatically detects types for common arbitrary value formats. ```ts // Length detected by calc() function twMerge('text-[calc(1rem+2px)] text-lg') // → 'text-lg' // Length detected by unit twMerge('text-[14px] text-[16px]') // → 'text-[16px]' // Color detected by hex format twMerge('text-[#ff0000] text-[#00ff00]') // → 'text-[#00ff00]' // Color detected by color function twMerge('bg-[rgb(255,0,0)] bg-[hsl(0,100%,50%)]') // → 'bg-[hsl(0,100%,50%)]' ``` -------------------------------- ### Toggle internal styles with props Source: https://github.com/dcastil/tailwind-merge/blob/main/docs/when-and-how-to-use-it.md Implement component variants using props to toggle internal styles as an alternative to dynamic class merging. ```jsx // React components with JSX syntax used in this example function Button({ variant = 'primary', isFullWidth, ...props }) { return