Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tailwind Merge Laravel Laravel Package

gehrisandro/tailwind-merge-laravel

Merge Tailwind CSS classes in Laravel and automatically resolve conflicts (later classes win). Ideal for Blade components and directives. PHP/Laravel port of tailwind-merge. Supports Tailwind v3.0–v3.3 (Laravel 10+).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require gehrisandro/tailwind-merge-laravel
    

    No additional steps required for basic usage.

  2. First Use Case: In a Blade component, replace static class attributes with twMerge:

    <!-- components/Button.blade.php -->
    <button {{ $attributes->twMerge('px-4 py-2 bg-blue-500 text-white rounded') }}>
        {{ $slot }}
    </button>
    

    Usage in a view:

    <x-button class="bg-green-500 hover:bg-green-600">Click</x-button>
    

    Output:

    <button class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600">Click</button>
    

Key Starting Points

  • Facade: TailwindMerge::merge('class1 class2')
  • Blade Directive: @twMerge('class1 class2')
  • Helper: twMerge('class1 class2')
  • Component Attributes: $attributes->twMerge('base-classes')

Implementation Patterns

1. Component-Driven Workflows

Base Component Pattern

<!-- components/Card.blade.php -->
<div {{ $attributes->twMerge('p-6 rounded-lg shadow-md') }}>
    {{ $slot }}
</div>

Usage:

<x-card class="bg-blue-100 border border-blue-200">
    Content with merged classes
</x-card>

Multi-Element Merging

<!-- components/Alert.blade.php -->
<div {{ $attributes->withoutTwMergeClasses()->twMerge('p-4 rounded') }}>
    <div {{ $attributes->twMergeFor('icon', 'h-5 w-5') }}></div>
    <div>{{ $slot }}</div>
</div>

Usage:

<x-alert class="bg-yellow-100" class:icon="text-yellow-500">
    Warning!
</x-alert>

2. Dynamic Class Resolution

Stateful Components

<!-- components/Toggle.blade.php -->
<button
    {{ $attributes->twMerge(
        'px-4 py-2 rounded',
        $active ? 'bg-green-500 text-white' : 'bg-gray-200 text-gray-800'
    ) }}
>
    {{ $slot }}
</button>

Theming Systems

<!-- components/ThemeButton.blade.php -->
<button
    {{ $attributes->twMerge(
        'px-4 py-2 rounded',
        config('theme.colors.primary') . '-500 text-white'
    ) }}
>
    {{ $slot }}
</button>

3. Integration with Existing Code

Legacy Class Attributes

<div class="{{ twMerge('bg-white p-4', $legacyClasses) }}">
    <!-- Content -->
</div>

Form Builders

// In a Form Request or Controller
$mergedClasses = twMerge('border border-gray-300', $userInput['classes'] ?? '');
return view('form', ['classes' => $mergedClasses]);

4. Configuration-Driven Extensions

Custom Tailwind Config

// config/tailwind-merge.php
return [
    'classGroups' => [
        'custom-colors' => [
            ['bg' => ['brand-primary', 'brand-secondary']],
            ['text' => ['brand-primary', 'brand-secondary']],
        ],
    ],
];

Usage:

<x-button class="bg-brand-primary">Brand Button</x-button>

Gotchas and Tips

Pitfalls

  1. Non-Tailwind Classes:

    • Non-Tailwind classes (e.g., custom-class) are preserved but may cause unexpected behavior if they conflict with Tailwind’s internal parsing.
    • Fix: Explicitly list them in classGroups or prefix them (e.g., tw-custom-class).
  2. Arbitrary Values:

    • Classes like z-[999] or w-[calc(100%-2rem)] are resolved last but may conflict with non-arbitrary classes.
    • Tip: Place arbitrary values at the end of your class string for predictable results.
  3. Blade Directive Caching:

    • @twMerge directives are not cached by default. For performance-critical views, use the facade or helper instead:
      {{ TailwindMerge::merge('classes') }}
      
  4. Component Attributes Limitation:

    • $attributes->merge() is unsupported. Always use twMerge for class merging in components.
  5. Dark Mode Conflicts:

    • Dark mode classes (dark:bg-gray-800) are resolved independently. Override them explicitly:
      <div class="{{ twMerge('bg-white dark:bg-gray-800', '!bg-red-500') }}">
          <!-- Forces bg-red-500 even in dark mode -->
      </div>
      

Debugging Tips

  1. Inspect Merged Output: Use dd(twMerge('classes')) to debug the merged result before rendering.

  2. Validate Tailwind Config: If merging fails, ensure your tailwind.config.js aligns with the package’s assumptions (e.g., no conflicting color names like bg-primary when primary is a font-weight class).

  3. Check for Typos: The package is strict about Tailwind class syntax. Validate classes using the Tailwind CSS Playground.

  4. Custom Class Groups: For unsupported classes, extend classGroups in config/tailwind-merge.php:

    'classGroups' => [
        'my-custom' => [
            ['my-prefix' => ['class1', 'class2']],
        ],
    ],
    

Performance Optimizations

  1. Cache Facade Results: Cache merged classes in a service or view composer for reusable components:

    // app/View/Composers/TailwindMerger.php
    public function compose($view)
    {
        $view->with('mergedClasses', Cache::remember('merged.classes', now()->addHours(1), function () {
            return twMerge('base-classes', $dynamicClasses);
        }));
    }
    
  2. Avoid Redundant Merging: Merge classes once in the component and pass the result to child components:

    <!-- Parent Component -->
    <x-child classes="{{ twMerge('base-classes', $parentClasses) }}" />
    

Extension Points

  1. Custom Merge Logic: Override the merge behavior by extending the underlying TailwindMerge class:

    use TailwindMerge\Laravel\Facades\TailwindMerge;
    
    class CustomTailwindMerge extends TailwindMerge
    {
        protected function resolveConflicts(array $classes): array
        {
            // Custom logic here
            return parent::resolveConflicts($classes);
        }
    }
    

    Bind it in a service provider:

    $this->app->bind('tailwind-merge', function () {
        return new CustomTailwindMerge();
    });
    
  2. Blade Directive Aliases: Register additional directives in AppServiceProvider:

    Blade::directive('merge', function ($expression) {
        return "<?php echo twMerge({$expression}); ?>";
    });
    

    Usage:

    @merge('classes')
    
  3. Integration with Livewire/Alpine: Use twMerge in Alpine.js or Livewire components to dynamically update classes:

    <div x-data="{ active: false }" x-bind:class="twMerge('p-4', active ? 'bg-green-500' : 'bg-gray-200')">
        Toggle me
    </div>
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony