Skip to content

Add experimental NativeAccordion (LV JS, no Zag) - #134

Draft
karim-semmoud wants to merge 15 commits into
mainfrom
cursor/native-accordion-9681
Draft

Add experimental NativeAccordion (LV JS, no Zag)#134
karim-semmoud wants to merge 15 commits into
mainfrom
cursor/native-accordion-9681

Conversation

@karim-semmoud

@karim-semmoud karim-semmoud commented Aug 30, 2026

Copy link
Copy Markdown
Member

Summary

Experimental Corex.NativeAccordion (LV JS pipes, no Zag) plus full doc surface mirroring Accordion (minus animation).

Component

  • Same data-scope="accordion" anatomy / Design CSS
  • Uncontrolled by default (works in controller / dead views); controlled open state is opt-in via handle_toggle/4
  • Keyboard is HEEx-only JS.exec/3: JS.exec(%JS{}, "data-nav-*", to: ":focus[data-nav-*]") on phx-window-keydown, with neighbor JS.focus stored on each trigger. No handle_event, no hook, no JS file
  • Focused triggers preventDefault Arrow/Home/End so the page does not scroll while moving focus
  • Uncontrolled collapsible: false opens without toggle_attr (open item cannot close); playground Collapsible / Multiple switches reset open values like Accordion
  • Unique role="region" landmark names (aria-labelledby trigger + hidden accordion id label) so axe landmark-unique passes with repeated demo copy

Docs (e2e)

  • Playground / Anatomy / API / Events / Patterns / Style
  • Controlled demo on Patterns
  • DocA11yRoutes + DocComponentWallaby coverage for matrix policy
  • Stable ids on anatomy/style demos

Tests / CI

  • Unit + LiveViewTest + Wallaby DocComponent suite
  • HTML asserts preventDefault, non-collapsible click encoding, and 3-arg JS.exec
  • Axe on native-accordion doc pages (unique region landmarks)

Demo

native_accordion_collapsible_playground_demo.mp4

Collapsible off leaves a single open item
Clicking the open item does not close it when collapsible is off
Clicking another item opens it and closes the previous
Collapsible on allows closing the open item

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

cursoragent and others added 15 commits August 30, 2026 03:14
Introduce Corex.NativeAccordion with the same accordion anatomy and Design
CSS scope, driven by LiveView JS command pipes and controlled assigns.
Includes an e2e playground plus LiveViewTest coverage (no Wallaby).

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Mirror Accordion doc pages (playground, anatomy, api, events, patterns,
style), move controlled demos to Patterns, reshape playground to a single
canvas with orientation controls, and fix ArrowUp via on_keydown + focus pin
with orientation/RTL-aware arrow mapping.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Register native_accordion in component_wire and HEEx-only splits, alias it to
accordion CSS, ignore JS.t opaque dialyzer contracts, and allow LV-only
on_value_change / on_keydown without client counterparts.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Split complex State helpers, normalize LV param keys once, flatten JS
toggle nesting, and use static ~S/~W sigils in tests so MIX_ENV=test
mix lint exits clean.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Add DocA11yRoutes and a DocComponentWallaby suite so DocPageMatrix entries
satisfy DocDemoCoveragePolicyTest without a custom pilot Wallaby module.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Compile neighbor JS.focus onto triggers and window-keydown keymap on the
root so arrows work without handle_event. Default to uncontrolled, drop
the focus pin, and uniquify region landmark names for axe.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Call Phoenix.LiveView.JS.exec/3 from HEEx with a JS struct as the
first argument and a native :focus selector so keyboard nav stays
client-only. Drop exec_nav, Keymap, and Trigger modules.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Keep the 3-arg :focus[data-nav-*] encoding check on the playground
LiveView HTML, and run axe on native-accordion doc pages so unique
region landmarks stay covered.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
LiveView phx-window-keydown does not preventDefault, so Arrow/Home/End
still scrolled the page. Cancel those keys on the focused trigger.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Client toggle_item only opened/closed via toggle_attr, so the
playground Collapsible switch had no effect. Non-collapsible mode
now opens without toggling closed, and the playground resets open
values when multiple/collapsible change.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
Integration phx_new matrix failed once on mix deps.get
(repo.hex.pm closed); unrelated to NativeAccordion changes.

Co-authored-by: Karim Semmoud <karim-semmoud@users.noreply.github.com>
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.

2 participants