Current section
Files
Jump to
Current section
Files
docs/behaviours.md
# Library behaviours
These ship in the hooks bundle and install themselves on import. No page-local
`phx-hook` and no extra `Hooks` entry. Markup is enough.
```js
import LanternHooks from "../../deps/lantern_ui/priv/static/lantern_ui_hooks.js"
```
Rebuild the bundle after editing `assets/js/` with `npm run build` and commit
`priv/static/lantern_ui_hooks.js`.
## List keyboard nav
`data-lantern-list-nav` on the list, `data-lantern-list-item` on each row.
While focus is inside the list: `j` / `ArrowDown` and `k` / `ArrowUp` move a
roving tabindex, `Home` / `End` jump, `Enter` activates the item's own link
(or clicks the item). The focused row gets a visible ring.
```heex
<ul data-lantern-list-nav>
<li :for={row <- @rows} data-lantern-list-item>
<.link navigate={~p"/tickets/#{row}"}>{row.title}</.link>
</li>
</ul>
```
Do not bind `j`/`k` on a typing target (`input`, `textarea`, `select`,
`contenteditable`) — those keys stay characters there.
## Persist open/collapsed
`data-lantern-persist="<key>"` stores `open` / `closed` in `localStorage`
(`lantern:persist:<key>`). Failures (quota, private mode) are ignored.
On a `<details>`:
```heex
<details data-lantern-persist="hub:filters">
<summary>Filters</summary>
...
</details>
```
On any other element, add a toggle (and optional panel):
```heex
<div data-lantern-persist="hub:side" data-open="true">
<button type="button" data-lantern-persist-toggle aria-expanded="true">
Inspector
</button>
<div data-lantern-persist-panel>
...
</div>
</div>
```
`side_panel` in a consuming app can keep a temporary page-local hook until it
switches to this attribute. Same key space; do not write both to the same key.
## Overlay placement
Popover, dropdown, select, menu, date picker, and autocomplete panels are
positioned with `@floating-ui/dom` (flip + shift), bundled into the hooks
file. Consumers do not add that dependency themselves.