Skip to content

Unify popup open/dismiss/positioning across dropdowns, pickers, and Popover #49

@KucharczykL

Description

@KucharczykL

Context

Follow-up to #28. While removing the inline-handler/window.* contract, the
filter-bar and YearPicker work surfaced that the "anchored layer that opens,
closes on Escape / outside-click" pattern is reimplemented several times with
three different mechanisms.

Current popup/dismiss implementations

  • Hand-rolled (vanilla TS):
    • ts/elements/dropdown.ts — toggle + outside-click (click, no Escape)
    • ts/elements/search-select.ts — outside-click (click) + Escape (in keydown)
    • ts/elements/date-range-picker.ts — Escape + outside-click (mousedown)
    • ts/elements/year-picker.ts — Escape + outside-click via bindPopupDismiss
      (popup is appended to document.body, so it passes the popup as an extra
      "inside" root)
  • Flowbite-driven: Popover (data-popover-target / data-popover) and the
    navbar dropdowns — separate engine, separate dismiss behaviour.

#28 already took the first incremental step: extracted Escape + outside-click into
bindPopupDismiss(options) in ts/utils.ts, adopted by date-range-picker.ts and
year-picker.ts. dropdown.ts and search-select.ts were left alone there because
they use click (not mousedown) and have differing Escape handling — migrating
them is behavioural and was out of #28's scope.

Goal

Decide whether a single popup primitive should own:

  1. open/close state,
  2. dismiss (Escape + outside-click), and
  3. optional anchored positioning,

and have all of the above adopt it — including reconsidering whether the two
Flowbite-driven cases (Popover, navbar dropdowns) fold in or stay on Flowbite.

Tasks (proposed)

  • Migrate dropdown.ts and search-select.ts onto bindPopupDismiss
    (normalising click vs mousedown and Escape behaviour).
  • Evaluate adding optional anchored-positioning to the shared helper (or a
    sibling helper) so hand-rolled popups stop duplicating placement math.
  • Decide the fate of Flowbite Popover + navbar dropdowns: unify or keep.

Notes / non-goals

  • This is a quality/DRY refactor, not a behaviour change for end users.
  • Vendored UMD globals (htmx, Alpine, Flowbite, Datepicker) stay classic
    by design.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions