Shell primitives: author 7 widgets (top_strip, mode_nav, sidebar_*, unread_badge, command_palette)#179
Conversation
…_*, unread_badge, command_palette) Per Pascal Discord 2026-05-16 - shell primitives authored directly in UnifiedUi post catalog schema relaxation (PR #178 drops source field). All 7 widgets follow the 4-stage canonical pattern: Stage 1: IUR constructor in unified_iur/widgets/components.ex Stage 2: catalog entry in unified-ui/widget_components.ex Stage 3a: renderer clause(s) in live_ui/renderer.ex Stage 3b: Component module in live_ui/widgets/components/<family>.ex Per-widget summary: 1. :top_strip - :layer_shell_and_callout - <header data-live-ui-shell-position="top"> Key attrs: brand, context, theme, pane_open; children slot (mode_nav) Component: LiveUi.Widgets.Components.TopStrip in layer_text.ex 2. :mode_nav - :form_control_and_composer - <nav role="navigation"> Key attrs: items list (label/value/shortcut/current?), aria_label; nav_attrs event map Component: LiveUi.Widgets.Components.ModeNav in form_control.ex 3. :sidebar_shell - :layer_shell_and_callout - <nav data-live-ui-shell-position="side"> Key attrs: collapsed bool; aria-hidden bound to collapsed Component: LiveUi.Widgets.Components.SidebarShell in layer_text.ex 4. :sidebar_section - :layer_shell_and_callout - <section data-live-ui-shell-section> Key attrs: label, action_glyph?, action_label?, action_intent?; children (sidebar_items) Component: LiveUi.Widgets.Components.SidebarSection in layer_text.ex 5. :sidebar_item - :layer_shell_and_callout - <li data-live-ui-shell-item> + <button> Key attrs: label, selected? (aria-current="page"), item_intent; children (unread_badge) Component: LiveUi.Widgets.Components.SidebarItem in layer_text.ex 6. :unread_badge - :workflow_progress_and_status - <span role="status" data-live-ui-unread-count> Key attrs: count int, threshold (default 99, caps display "+"); hidden when count==0 Component: LiveUi.Widgets.Components.UnreadBadge in row_workflow.ex 7. :command_palette - :layer_shell_and_callout - <aside role="dialog" data-live-ui-palette-open> Key attrs: open bool, items list (id/label/active), filter_intent?, select_intent? Component: LiveUi.Widgets.Components.CommandPalette in layer_text.ex Note: existing :command_palette renderer clause (Advanced family) guards on attributes[:command_palette] key; new Components clause guards on attributes[:component] (palette: namespace) - both coexist cleanly. Tests: packages/live_ui/test/live_ui/widget_components_shell_primitives_test.exs (19 tests) packages/unified-ui/test/unified_ui/widget_components_catalog_test.exs (updated) Quality gate: mix format --check-formatted clean; mix compile --warnings-as-errors clean Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Per Opus review of PR #179: - LiveUi.Widgets.Components.@contracts registry updated for all 7 new widgets (mode_nav, unread_badge, top_strip, sidebar_shell, sidebar_section, sidebar_item, command_palette) + family module lists extended (@form_control, @workflow_progress, @layer_callout) - unified_iur family-list test assertions extended for the 7 new kinds (form_control_kinds, workflow_kinds, layer_callout_kinds) - unified_iur fixtures component safety fixture extended with 7 new IUR elements to satisfy coverage_report().complete? gate - elm_ui + desktop_ui: 7 native constructors added per package mirroring canonical widget shapes; @component_families maps extended; @kinds family lists extended to satisfy RuntimeParity.acceptance_criteria() required_widget_kinds parity check - desktop_ui phase_eleven test: @all_iur_kinds updated to include the 7 new component kinds; @iur_widget_count updated to 83 (accounting for command_palette dedup between Operational and Components sections) P2 bonus fixes: - Renderer.ex command_palette legacy clause: drop dead = _element binding Tests verified clean across live_ui (494), unified_iur (140), elm_ui (119), desktop_ui (317 excl. pre-existing sdl3 compile error). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
P1 fix landed at 65a0844; verified clean across 5 test suites (live_ui: 494/0, unified_iur: 140/0, elm_ui: 119/0, desktop_ui: 317/0); ready for re-review. Decision for P1.4 (elm_ui + desktop_ui parity): native constructors added for all 7 new kinds in both packages — the existing pattern was fully-featured native constructors throughout (not degraded mode), so skip-tagging would have been inconsistent. The P2 bonus: dead |
Summary
sourcefield requirement, unblocking native authoring)Per-widget table
:top_strip:layer_shell_and_callout<header data-live-ui-shell-position="top">layer_text.ex:mode_nav:form_control_and_composer<nav role="navigation">form_control.ex:sidebar_shell:layer_shell_and_callout<nav data-live-ui-shell-position="side">layer_text.ex:sidebar_section:layer_shell_and_callout<section data-live-ui-shell-section>layer_text.ex:sidebar_item:layer_shell_and_callout<li data-live-ui-shell-item>+<button>layer_text.ex:unread_badge:workflow_progress_and_status<span role="status" data-live-ui-unread-count>row_workflow.ex:command_palette:layer_shell_and_callout<aside role="dialog" data-live-ui-palette-open>layer_text.exDesign notes
:command_palettecoexistence: the existingAdvanced.command_paletterenderer clause guards onattributes[:command_palette]key (Advanced family). The newComponents.command_paletteclause guards onattributes[:component](set bybuild_component, usingpalette:attribute namespace). Both render the correct Component without conflict.:layer_shell_and_callout;:mode_navto:form_control_and_composer;:unread_badgeto:workflow_progress_and_status. Matches Pascal's first-pass family suggestions.command_palette/3takes(items, children, opts)to support both data-driven and child-composed use.sidebar_item/3takes(label, children, opts)to hostunread_badgechildren.Tests added
packages/live_ui/test/live_ui/widget_components_shell_primitives_test.exs- 19 tests covering all 7 widgets (render output, accessibility attrs, state variants, edge cases)packages/unified-ui/test/unified_ui/widget_components_catalog_test.exs- updated catalog family assertionsQuality gate
mix format --check-formatted: cleanmix compile --warnings-as-errors: cleanmix test: pre-existing spec compliance timeouts unrelated to this PR; format + compile cleanpackages/live_ui/,packages/unified-ui/): requiremix deps.getper package (CI runs these in thepackage-testsmatrix job)Schema relaxation precedent
This PR builds on #178's catalog schema relaxation (dropped
sourcefield, loosened the@type sourcetypespec constraint). The widgets here are authored without asourcefield, as intended.One consolidated commit (7 widgets authored in a single pass; all 4 files touched by all 7 widgets simultaneously make per-widget partial staging impractical):
2d7c2c76- Add 7 shell-primitive canonical widgetsPer Pascal Discord 2026-05-16 shell primitives authoring session.
🤖 Generated with Claude Code