Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

muuucho's avatar
Level 11

Livewrie + tailwind display color problem

In my Livewire 3 + Laravel 10 project, I have installed Tailwind 3.4.4 and the password strength indicator Zxcvbn. The problem is that the colours yellow and lime don't work when passed from the Livewire "controller" to the view, but when I hardcode them to the view they show up. The other colours, red, orange and green work from the "controller". I can see in the debug bar that the strenghtScore is working as expected stepping up from 1 to 4 when I type in a password. But on 1 and 3 no color is displayed in the strength bar. However, they work when I hardcode them (yellow and lime) in the view. How come? Update: The word indicator is working from the controller to the view as expected: Weak, Fair, Good, Strong.

array:4 [
  "data" => array:5 [
    "password" => "aker"
    "passwordConfirmation" => ""
    "strengthScore" => 1
    "strengthLevels" => array:4 [
      1 => "Weak"
      2 => "Fair"
      3 => "Good"
      4 => "Strong"
    ]
    "strengthColors" => array:5 [
      0 => "bg-red-600"
      1 => "bg-yellow-600"
      2 => "bg-orange-600"
      3 => "bg-lime-600"
      4 => "bg-green-600"
    ]
  ]
  "name" => "register-passwords"
  "component" => "App\Livewire\RegisterPasswords"
  "id" => "MtTKj5D60umpgBeQ5FWP"
]

RegisterPasswords.php

<?php

namespace App\Livewire;

use ZxcvbnPhp\Zxcvbn;
use Livewire\Component;
use Illuminate\Support\Str;
use Illuminate\Contracts\View\View;

class RegisterPasswords extends Component
{
    public string $password = '';
    public string $passwordConfirmation = '';
    public int $strengthScore = 0;
    public array $strengthLevels = [
        1 => 'Weak',
        2 => 'Fair',
        3 => 'Good',
        4 => 'Strong',
    ];
    public array $strengthColors = [
        0 => 'bg-red-600',
        1 => 'bg-yellow-600',
        2 => 'bg-orange-600',
        3 => 'bg-lime-600',
        4 => 'bg-green-600',
    ];

    public function updatePassword(): void
    {
        $this->updatedPassword($this->password);
    }

    public function updatedPassword($value): void
    {
        $this->strengthScore = (new Zxcvbn())->passwordStrength($value)['score'];
    }

    public function generatePassword(): void
    {
        $password = Str::password(12);

        $this->setPasswords($password);
    }

    protected function setPasswords($value): void
    {
        $this->password = $value;
        $this->passwordConfirmation = $value;
        $this->updatedPassword($value);
    }

    public function render(): View
    {
        return view('livewire.register-passwords');
    }
}

register-passwords.blade.php

<div>
    <!-- Password -->
    <div class="mt-4">
        <x-input-label for="password" :value="__('Password')" />
        <div class="flex mt-1 mb-2">
            <div class="relative flex-1 col-span-4" x-data="{ show: true }">
                <input class="w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
                       id="password"
                       :type="show ? 'password' : 'text'"
                       name="password"
                       wire:model="password"
                       wire:keyup="updatePassword"
                       required autocomplete="new-password" />
                <button type="button" class="flex absolute inset-y-0 right-0 items-center pr-3" @click="show = !show" :class="{'hidden': !show, 'block': show }">
                    <!-- Heroicon name: eye -->
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" />
                        <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
                    </svg>
                </button>
                <button type="button" class="flex absolute inset-y-0 right-0 items-center pr-3" @click="show = !show" :class="{'block': !show, 'hidden': show }">
                    <!-- Heroicon name: eye-slash -->
                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                        <path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88" />
                    </svg>
                </button>
            </div>
            <div class="flex items-center place-content-end ml-1">
                <x-primary-button wire:click="generatePassword" type="button">Generate</x-primary-button>
            </div>
        </div>
        <span class="text-sm">
            <span class="font-semibold">Password strength:</span> {{ $strengthLevels[$strengthScore] ?? 'Weak' }}
        </span>
        <div>
            <div class="mt-6" aria-hidden="true">
                <div class="overflow-hidden rounded-full bg-gray-200">
                    <div class="h-2 rounded-full {{ $strengthColors[$strengthScore] }}" style="width: {{ $strengthScore === 0 ? 10 : $strengthScore * 25 }}%"></div>
                </div>
            </div>
        </div>
        <div>
            <div class="mt-6" aria-hidden="true">
                <div class="overflow-hidden rounded-full bg-gray-200">
                    <div class="h-2 rounded-full bg-yellow-500" style="width: {{ $strengthScore === 0 ? 10 : $strengthScore * 25 }}%"></div>
                </div>
            </div>
            <div class="mt-6" aria-hidden="true">
                <div class="overflow-hidden rounded-full bg-gray-200">
                    <div class="h-2 rounded-full bg-lime-500" style="width: {{ $strengthScore === 0 ? 10 : $strengthScore * 25 }}%"></div>
                </div>
            </div>
        </div>
        <x-input-error :messages="$errors->get('password')" class="mt-2" />
    </div>
    <!-- Confirm Password -->
    <div class="mt-4">
        <x-input-label for="password_confirmation" :value="__('Confirm Password')" />
        <x-text-input id="password_confirmation" class="block mt-1 w-full"
                      type="password"
                      wire:model="passwordConfirmation"
                      name="password_confirmation" required />
        <x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" />
    </div>
</div>

0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

The issue you're experiencing with the colors bg-yellow-600 and bg-lime-600 not displaying correctly when passed from the Livewire component to the view is likely due to Tailwind CSS's JIT (Just-In-Time) mode not recognizing these classes because they are dynamically generated.

Tailwind CSS's JIT mode only includes the classes it detects in your source files. Since the classes bg-yellow-600 and bg-lime-600 are being generated dynamically in your Livewire component, Tailwind might not be aware of them and thus not include them in the final CSS.

To fix this, you can explicitly include these classes in your Tailwind CSS configuration file to ensure they are always available. Here's how you can do it:

  1. Update your tailwind.config.js file to include the necessary classes in the safelist option:
module.exports = {
  // other configurations...
  safelist: [
    'bg-red-600',
    'bg-yellow-600',
    'bg-orange-600',
    'bg-lime-600',
    'bg-green-600',
  ],
  // other configurations...
};
  1. Rebuild your Tailwind CSS to ensure the safelisted classes are included in the final CSS output.

  2. Verify your Livewire component and Blade view to ensure they are correctly using the classes.

Here is the updated tailwind.config.js file:

module.exports = {
  content: [
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
  safelist: [
    'bg-red-600',
    'bg-yellow-600',
    'bg-orange-600',
    'bg-lime-600',
    'bg-green-600',
  ],
};

After making these changes, rebuild your Tailwind CSS by running the appropriate build command, typically:

npm run dev

or

npm run build

This should ensure that the bg-yellow-600 and bg-lime-600 classes are included in your final CSS, and they should now work correctly when passed from your Livewire component to the view.

1 like
muuucho's avatar
Level 11

Wops, that did the trick! Cheers Larry!

Please or to participate in this conversation.