Skip to content

Extension: :tabs count badge per tab #188

Description

@ty13r

Context

Audited under ariston-ui Wave AshUI-3.7 comp-fidelity audit. The :tabs canonical widget is missing a count badge per tab — comps show "Feed (12)", "Threads (3)", "Tasks (1)" across Chat feed, Pane 3, and Talk surfaces.

Canonical-kind grep proof:

Comp gap (audit finding implied; extension table line 242)

Comps show tab labels with trailing count badges across multiple surfaces:

  • Chat feed: "Feed (12)" + "Threads (3)" + "Tasks (1)" (unread feed items / open threads / open tasks)
  • Pane 3 (Bundle / Sources / History): item counts per tab
  • Talk thread sub-tabs: similar count badges

Currently ariston-ui works around with custom HEEx tab rendering instead of canonical :tabs.

Proposed extension

Adding optional count attr per tab item:

tabs:
  items: [
    %{
      id: term(),
      label: String.t(),
      count: integer() | nil   # NEW; default nil; when set, renders count badge after label
    }
  ]
  active_tab: term()
  on_change: Interaction.t()

Default value rationale

  • count: nil = no badge rendered (default behavior preserved)

Open questions for Pascal

  1. Canonical authority: is :tabs in unified_iur/widgets.ex still the canonical definition, or should this extension first migrate :tabs into the new widget_components.ex catalog (PR Catalog schema relaxation: drop source field (per Pascal Discord 2026-05-16) #178/Shell primitives: author 7 widgets (top_strip, mode_nav, sidebar_*, unread_badge, command_palette) #179 pattern)?
  2. Badge style: same as proposed for :segmented_button_group count badge (sibling issue) — should both use the same visual primitive? Possibly compose with :unread_badge?
  3. Active vs inactive count rendering: do active tabs show count differently (e.g., bolder)? Comp suggests visually consistent.
  4. Zero-count: hide badge entirely, render "0", or render "—"? Mirrors :segmented_button_group decision.
  5. Cap (e.g., "99+"): spec-it explicitly or leave consumer-side?
  6. Multi-counter per tab: some tabs in comp show "Inbox (3 / 12)" with two numbers (unread / total). Extension scope creep or in scope?
  7. ARIA: redundant text in tab label is OK (count is meaningful UI text); badge can be aria-hidden="true" since label includes the count. Same convention as :segmented_button_group.

ARIA implications

  • Tab label: includes count text in accessible name (count is meaningful for tab selection)
  • Badge element: <span class="live-ui-tabs-item-count" aria-hidden="true">{count}</span>

Cross-references

  • Comp-audit: ariston-ui docs/wave-ashui-3-7-comp-fidelity-audit.md extension table line 242
  • Audit findings: implied across Chat (CH-3), Talk (TLK-2), Pane 3 tab consumption
  • Sibling: :segmented_button_group count extension proposal
  • :unread_badge precedent: packages/unified-ui/lib/unified_ui/widget_components.ex:204 (composition consideration per Q2)
  • Wave 3.7-A retrospective: ariston-ui docs/wave-ashui-3-7-a-retrospective.md

Status

DRAFT extension proposal — Pascal's design call on canonical authority (Q1) and :unread_badge composition (Q2) determines the implementation shape and scope.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions