:sidebar_item — add visual + state primitives (glyph, meta, blocked, kind)
Canonical-grep proof
$ git grep -n "kind: :sidebar_item" packages/live_ui/lib/live_ui/renderer.ex
packages/live_ui/lib/live_ui/renderer.ex:<line>: def render(%{element: %Element{kind: :sidebar_item}} = ...)
Renderer clause exists (PR #179); constructor accepts label + children + selected? / item_intent opts. But does NOT accept ariston's 4 visual+state primitives that the operator-surface sidebar relies on.
Divergence (ariston consumer vs canonical)
Ariston's operator-surface sidebar items (ariston-ui/lib/ariston_ui_web/live/operator_surface_live.ex:948-965) pass 4 primitives that have no canonical path:
| Aspect |
Ariston-side |
Canonical |
Impact |
| Glyph |
"glyph" => item.glyph (Unicode glyph or icon name) prepended to label visually |
no glyph attr |
Sidebar items render without their distinguishing glyph |
| Meta text |
"meta" => meta_string (trailing right-aligned metadata like "12" or "3h") |
no meta attr |
Trailing meta column disappears |
| Blocked state |
"blocked" => true|false (renders item as disabled / muted) |
no blocked attr |
Cannot represent blocked-but-visible items |
| Kind |
"kind" => "channel"|"dm"|"build"|... (semantic category for styling) |
no kind attr |
Cannot vary visual treatment by item category |
Proposed extension
Add 4 optional attrs to :sidebar_item:
@spec sidebar_item(label, [child], opts) :: Element.t()
def sidebar_item(label, children \\ [], opts \\ [])
# Existing opts: selected?, item_intent, id
# NEW opts:
# glyph: optional Unicode glyph or icon name (string)
# meta: optional trailing metadata text (string)
# blocked?: boolean (semantic disabled state distinct from interactive disabled)
# kind: optional semantic category atom (`:channel`, `:dm`, `:build`, etc.)
In the renderer clauses (live_ui + ash_ui): emit <span data-live-ui-sidebar-item-glyph>{glyph}</span> + <span data-live-ui-sidebar-item-meta>{meta}</span> slots; set data-live-ui-sidebar-item-blocked={blocked?} + data-live-ui-sidebar-item-kind={kind} on the button or <li> for CSS targeting.
Status
Ariston PR #351 currently DROPS these 4 attrs. ariston's sidebar items lose their glyphs (visual distinction), meta column (unread count etc.), blocked state styling, and per-kind visual treatment.
Cross-references
Sibling issues this batch:
:top_strip event-wiring attrs
:unread_badge a11y label
:sidebar_item— add visual + state primitives (glyph, meta, blocked, kind)Canonical-grep proof
Renderer clause exists (PR #179); constructor accepts
label+children+selected?/item_intentopts. But does NOT accept ariston's 4 visual+state primitives that the operator-surface sidebar relies on.Divergence (ariston consumer vs canonical)
Ariston's operator-surface sidebar items (
ariston-ui/lib/ariston_ui_web/live/operator_surface_live.ex:948-965) pass 4 primitives that have no canonical path:"glyph" => item.glyph(Unicode glyph or icon name) prepended to label visually"meta" => meta_string(trailing right-aligned metadata like "12" or "3h")"blocked" => true|false(renders item as disabled / muted)"kind" => "channel"|"dm"|"build"|...(semantic category for styling)Proposed extension
Add 4 optional attrs to
:sidebar_item:In the renderer clauses (live_ui + ash_ui): emit
<span data-live-ui-sidebar-item-glyph>{glyph}</span>+<span data-live-ui-sidebar-item-meta>{meta}</span>slots; setdata-live-ui-sidebar-item-blocked={blocked?}+data-live-ui-sidebar-item-kind={kind}on the button or<li>for CSS targeting.Status
Ariston PR #351 currently DROPS these 4 attrs. ariston's sidebar items lose their glyphs (visual distinction), meta column (unread count etc.), blocked state styling, and per-kind visual treatment.
Cross-references
101bae98)a32fb5519fb9)lib/ariston_ui_web/live/operator_surface_live.ex:948-965Sibling issues this batch:
:top_stripevent-wiring attrs:unread_badgea11y label