Skip to content

flux:date-picker type="input" always renders red invalid border (Blaze folds $invalid into truthy placeholder) #2622

@angus-mcritchie

Description

@angus-mcritchie

Flux version

v2.14.1 (Flux Pro v2.14.1)

Livewire version

v4.3.0

Tailwind version

v4.3.0

Browser and Operating System

Chrome / Edge / Firefox on Linux + macOS

What is the problem?

<flux:date-picker type="input" /> always renders with border-red-500 on the trigger, regardless of validation state. The type="button" variant is unaffected.

This happens because Blaze (livewire/blaze v1.0.12) folds the $invalid attribute into a BLAZE_PLACEHOLDER_N_ string at compile time. That placeholder is truthy in PHP and reaches the match expression in flux-pro/stubs/resources/views/flux/date-picker/input/variants/custom.blade.php:

->add(match ($variant) {
    'outline' => $invalid ? 'border-red-500' : 'shadow-xs border-zinc-200 border-b-zinc-300/80 ...',
    ...
})

The truthy branch wins, border-red-500 gets baked into the rendered HTML, and restorePlaceholders() runs after — but only on textual output, not values consumed in PHP control flow. So the red class survives.

I confirmed by logging inside custom.blade.php:

$invalid = "BLAZE_PLACEHOLDER_1_" (string)

…even when the call site passes :invalid="false". The data-invalid attribute on the trigger is not set (as you'd expect, since there's no actual error), but border-red-500 is in the live DOM class list anyway.

Likely fix: add invalid (and probably clearable, dropdown) to the @blaze(unsafe: [...]) list in flux:date-picker/index.blade.php so Blaze leaves those attributes alone when they're consumed inside PHP control flow downstream. Same class of bug as #2564 (flux:error folded as static hidden HTML).

Code snippets to replicate the problem

<?php

use Livewire\Component;

new class extends Component {
    public ?string $date = null;
}; ?>

<div class="p-8 dark">
    <flux:date-picker type="input" wire:model="date" label="From" with-today clearable />
</div>

Load the page. Inspect the <ui-date-picker-trigger> element — its class list contains border-red-500 and its computed border-color is oklch(0.637 0.237 25.331) (Tailwind's red-500).

For comparison, <flux:date-picker type="button" wire:model="date" /> renders correctly because button.blade.php uses @if ($invalid) data-invalid @endif on the actual <button> (a real element that Blaze restores cleanly), rather than baking the class string up front.

Screenshots/ screen recordings of the problem

Computed style on the trigger (dark mode):

borderColor: oklch(0.637 0.237 25.331)   // red-500
borderWidth: 1px
data-invalid: (absent)
class: "... border-red-500"

A workaround in our app (until this lands upstream) — CSS reset on the trigger when data-invalid is absent:

ui-date-picker-trigger:not([data-invalid]) {
    border-color: var(--color-zinc-200) !important;
    border-bottom-color: color-mix(in oklch, var(--color-zinc-300), transparent 20%) !important;
}

.dark ui-date-picker-trigger:not([data-invalid]) {
    border-color: rgb(255 255 255 / 0.1) !important;
    border-bottom-color: rgb(255 255 255 / 0.1) !important;
}

How do you expect it to work?

With no validation error on the bound property and no explicit :invalid="true", the trigger should render with the default border-zinc-200 dark:border-white/10 border, matching flux:input type="date" and flux:date-picker type="button".

Please confirm (incomplete submissions will not be addressed)

  • I have provided easy and step-by-step instructions to reproduce the bug.
  • I have provided code samples as text and NOT images.
  • I understand my bug report will be closed if I haven't met the criteria above.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions