Skip to content

Fix Airbnb dark mode and rework the picker input - #159

Closed
Willis1776 wants to merge 1 commit into
coolsam726:mainfrom
Willis1776:fix/dark-airbnb-theme-and-picker-ux
Closed

Willis1776 wants to merge 1 commit into
coolsam726:mainfrom
Willis1776:fix/dark-airbnb-theme-and-picker-ux

Conversation

@Willis1776

Copy link
Copy Markdown

Summary

Fixes four related issues with the non-native Flatpickr field.

Airbnb theme is unreadable in dark mode. The upstream Airbnb theme is light-only (near-black text on white), but resources/css/index.css forces a dark surface onto .dark .flatpickr-calendar, so the text stayed dark on dark. A dark palette now lives in resources/css/themes/airbnb.css.

Because bin/build.js overwrites resources/dist/themes/ from node_modules on every build, hand-editing the dist theme would not survive. The build now appends any matching resources/css/themes/<theme>.css to the copied theme, so the mechanism is reusable for the other light-only themes.

The first click on a day was swallowed. Clicking a day blurs the input, and the blur handler ran commitManualInput() → fp.clear() → redraw(). That replaced the day element between mousedown and mouseup, so the click never landed on a day and the selection needed a second click. Three fixes:

  • mousedown inside the calendar is preventDefaulted so focus never leaves the input (the year/time inputs and month dropdown are excluded, since they must stay focusable)
  • blur is ignored while the picker is open — onClose already commits
  • commitManualInput no longer calls clear() when there is nothing to clear

Calendar prefix icon. prefixIcon defaults to heroicon-o-calendar-days, and clicking any prefix or suffix affix toggles the calendar. Prefix/suffix actions keep their own click behaviour.

Selected dates as removable tags. Each date renders as a Filament fi-badge inside the input with its own remove button — on by default for multiple pickers, ->tags() / ->tags(false) to override. Tags share the input's wrapping row so the field stays one row tall, and the input is left empty rather than repeating the dates as a joined comma string.

Linked issues

Test plan

  • composer test — 161 pass (11 new render tests in tests/FlatpickrRenderTest.php)
  • composer analyse — no errors
  • vendor/bin/pint --test — passes
  • Verified in a browser against the real rendered markup and Filament's compiled theme.css:
    • Confirmed the swallow mechanism (clear() while open leaves the day element with isConnected: false), then confirmed a single click selects after the fix
    • AM/PM toggle, hour input focus and spinner arrows still work through the mousedown guard
    • Prefix icon opens and closes the calendar
    • Three single clicks → three tags; removing the middle tag → 2026-08-05,2026-08-10; removing all → empty
    • Field height stays 36px (one row, same as a plain Filament input) when empty, at 1 tag and at 5 tags; tags wrap and the field grows only when squeezed to 340px
    • Airbnb dark mode computed colours: day text #404848 → #e5e7eb, weekday rgba(0,0,0,.54) → rgba(229,231,235,.6), month/year #3c3f40 → #e5e7eb; light mode values unchanged

Notes for reviewers

  • The affixes are bound by the Alpine component rather than through Filament's x-on:focus-input.stop convention (what TagsInput uses). That convention needs an Alpine root somewhere above the input wrapper, which a schema does not guarantee — it silently did nothing in a bare harness. The component's own element always has x-data.
  • resources/dist/ is committed, so the rebuilt components/flatpickr.js, flatpickr.css and themes/airbnb.css are part of the diff. themes/default.css was deliberately left alone.
  • Only Airbnb has dark overrides. light, confetti and the material_* themes have the same problem and can reuse the new build hook.

🤖 Generated with Claude Code

Four related issues with the non-native picker:

Airbnb theme in dark mode. The upstream Airbnb theme is light only, but
index.css forces a dark surface onto `.dark .flatpickr-calendar`, leaving
near-black text on it. Dark overrides now live in
resources/css/themes/airbnb.css. Because bin/build.js overwrites
resources/dist/themes from node_modules on every build, it now appends any
matching resources/css/themes/<theme>.css to the copied theme, so the fixes
survive a rebuild.

First click on a day was swallowed. Clicking a day blurs the input, and the
blur handler ran commitManualInput() -> fp.clear() -> redraw(), replacing the
day element between mousedown and mouseup so the click never landed. Mousedown
inside the calendar is now prevented so focus never leaves the input (except
for the year/time inputs and month dropdown, which must stay focusable), blur
is ignored while the picker is open since onClose already commits, and
commitManualInput no longer clears when there is nothing to clear.

Calendar prefix icon. prefixIcon defaults to heroicon-o-calendar-days and
clicking any prefix or suffix affix toggles the calendar. The affixes are bound
by the Alpine component rather than through Filament's `focus-input`
convention, which needs an Alpine root above the input wrapper that a schema
does not guarantee.

Date tags. Selected dates render as `fi-badge` tags inside the input, each with
its own remove button, on by default for multiple pickers and toggleable with
`tags()`. Tags share the input's wrapping row so the field stays one row tall,
and the input itself is left empty rather than repeating the dates as a joined
string.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Willis1776

Copy link
Copy Markdown
Author

Opened against the wrong repository by mistake — reopening on my own fork. Sorry for the noise.

@Willis1776 Willis1776 closed this Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant