TailwindMerge for Laravel

repository·main·Indexed 43 days ago

https://github.com/gehrisandro/tailwind-merge-laravel

A PHP port of the tailwind-merge utility for Laravel 10+ that resolves Tailwind CSS class conflicts. It provides a @twMerge Blade directive, a TailwindMerge Facade, a twMerge global helper, and ComponentAttributeBag macros like twMerge() and twMergeFor() to enable flexible class overriding in Blade components.

Tokens
2.1K
Snippets
13
Records
13
Agent score
56%

What's inside TailwindMerge for Laravel

  1. Use TailwindMerge in Laravel Blade Components

    main

    To allow overriding classes in Blade components, use the $attributes->twMerge() method inside your component template. This resolves conflicts by ensuring classes passed from the parent view take precedence over the component's default classes.

    Note: Do not use $attributes->merge(['class' => '...']) as it is not supported due to Laravel limitations.

    Example: Basic Component

    Component (circle.blade.php):

    <div {{ $attributes->twMerge('w-10 h-10 rounded-full bg-red-500') }}></div>

    Usage (your-view.blade.php):

    <x-circle class="bg-blue-500" />

    Output:

    <div class="w-10 h-10 rounded-full bg-blue-500"></div>
    // circle.blade.php
    <div {{ $attributes->twMerge('w-10 h-10 rounded-full bg-red-500') }}></div>
  2. Merge classes on multiple elements in Blade

    main

    By default, Laravel only allows merging classes on the root element. You can use twMergeFor() to target specific sub-elements within a component using the class:xyz attribute syntax.

    Important: You must call withoutTwMergeClasses() on the main attributes bag to prevent all class:xyz attributes from being rendered as literal attributes in the HTML output.

    Example

    Component (button.blade.php):

    <button {{ $attributes->withoutTwMergeClasses()->twMerge('p-2 bg-gray-900 text-white') }}>
        <svg {{ $attributes->twMergeFor('icon', 'h-4 text-gray-500') }} viewBox="0 0 448 512"><path d="..."/></svg>
        {{ $slot }}
    </button>

    Usage:

    <x-button class="bg-blue-900" class:icon="text-blue-500">
      Click Me
    </x-button>

    Output:

    <button class="p-2 bg-blue-900 text-white">
      <svg class="h-4 text-blue-500" viewBox="0 0 448 512"><path d="..."/></svg>
      Click Me
    </button>
    <button {{ $attributes->withoutTwMergeClasses()->twMerge('p-2 bg-gray-900 text-white') }}>
        <svg {{ $attributes->twMergeFor('icon', 'h-4 text-gray-500') }} viewBox="0 0 448 512"><path d="..."/></svg>
        
        {{ $slot }}
    </button>
  3. Modify the TailwindMerge merge process

    main

    If you use custom Tailwind classes (e.g., custom font sizes or colors) that TailwindMerge doesn't recognize, you can modify the classGroups in config/tailwind-merge.php. This allows you to define how custom classes should conflict and resolve.

    Example: Adding a custom font size group

    // config/tailwind-merge.php
    return [
        'classGroups' => [
            'font-size' => [
                ['text' => ['very-large']]
            ],
        ],
    ];
    // config/tailwind-merge.php
    return [
      'classGroups' => [
          'font-size' => [
              ['text' => ['very-large']]
          ],
      ],
    ];
  4. Configure the Tailwind Merge package

    main

    You can publish the package configuration file to your application's config directory using the following command:

    php artisan vendor:publish --tag=tailwind-merge-config

    (Note: While the exact tag isn't explicitly named in the code, the provider uses publishes to map the config file to config_path('tailwind-merge.php').)

    The configuration is loaded via config('tailwind-merge', []) and is used to initialize the TailwindMerge instance.

    php artisan vendor:publish
  5. Use TailwindMerge via Facade or Helper

    main

    Outside of Blade components or directives, you can merge classes using the TailwindMerge Facade or the twMerge global helper.

    Using the Facade

    use TailwindMerge\
    Laravel\Facades\TailwindMerge;
    
    TailwindMerge::merge('w-10 h-10 rounded-full bg-red-500 bg-blue-500');

    Using the Helper

    twMerge('w-10 h-10 rounded-full bg-red-500 bg-blue-500');
    use TailwindMerge\Laravel\Facades\TailwindMerge;
    
    TailwindMerge::merge('w-10 h-10 rounded-full bg-red-500 bg-blue-500');
  6. Use the @twMerge Blade directive

    main

    The package provides a @twMerge directive for use directly in Blade views. It accepts a single string or multiple arguments.

    {{-- Single argument --}}
    @twMerge('w-10 h-10 rounded-full bg-red-500 bg-blue-500')
    
    {{-- Multiple arguments --}}
    @twMerge('w-10 h-10 rounded-full bg-red-500', 'bg-blue-500')

    You can rename this directive or disable it in config/tailwind-merge.php using the blade_directive key.

    @twMerge('w-10 h-10 rounded-full bg-red-500', 'bg-blue-500')
  7. Register the Tailwind Merge Blade directive

    main

    The package allows you to use a Blade directive to merge Tailwind classes directly in your templates. By default, the directive name is @twMerge.

    You can customize the directive name in your config/tailwind-merge.php file using the blade_directive key. If set to null, the directive will not be registered.

    <div @twMerge('bg-red-500 p-4', 'bg-blue-500')></div>
  8. Use the TailwindMerge facade to merge Tailwind classes

    main

    The TailwindMerge facade provides a static interface to the underlying Tailwind Merge utility. You can use the merge method to resolve class conflicts by passing multiple strings of Tailwind CSS classes as arguments. It returns a single string containing the merged classes with conflicts resolved.

    use TailwindMerge\Laravel\Facades\TailwindMerge;
    
    $merged = TailwindMerge::merge('px-2 py-1', 'p-4', 'text-red-500 text-blue-500');
    // Result will have conflicts resolved based on Tailwind Merge logic
  9. Use ComponentAttributeBag macros for Tailwind merging

    main

    The package extends Laravel's ComponentAttributeBag with several macros to simplify class merging within Blade components.

    twMerge(...$args)

    Merges provided arguments with the existing class attribute on the attribute bag. It updates the class key in place.

    twMergeFor(string $for, ...$args)

    Merges provided arguments with a specific attribute key, typically used for dynamic class bindings like class:some-condition. It returns only the class attribute.

    withoutTwMergeClasses()

    Filters the attribute bag to remove any attributes that start with class: (used for conditional class bindings).

    // Inside a Blade component template
    <x-button {{ $attributes->twMerge('px-4 py-2', 'bg-blue-500') }} />
    
    // Using twMergeFor for conditional classes
    <x-button {{ $attributes->twMergeFor('active', 'text-white') }} />
    
    // Removing conditional class bindings
    <x-button {{ $attributes->withoutTwMergeClasses() }} />