Skip to content

feat(item-list): add compact lists with shared sidebar presentation - #636

Open
IzumiSy wants to merge 3 commits into
mainfrom
feat/item-list
Open

IzumiSy wants to merge 3 commits into
mainfrom
feat/item-list

Conversation

@IzumiSy

@IzumiSy IzumiSy commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Compact navigation and action lists are useful in page content and tables of contents, not only inside the Sidebar. Rebuilding those rows separately duplicates presentation and makes spacing, active states, and nested lists drift from the Sidebar.

Provide an independent ItemList that works without AppShell, Sidebar, or router providers while keeping route matching, translated labels, and permissions with the caller.

Screen shot

スクリーンショット 2026-10-22 13 59 52

Design Decision

Share presentation without Sidebar behavior

Extract components/internals/item-list-base as the internal presentation layer shared by the public ItemList and the existing Sidebar. The dependency direction is consumer → shared base; ItemList and Sidebar do not depend on each other.

flowchart TD
    ItemList["Public ItemList<br/>components/item-list"] --> Base["Internal item-list-base<br/>components/internals/item-list-base"]
    Sidebar["Sidebar components"] --> Primitives["Sidebar primitives<br/>components/sidebar/primitives.tsx"]
    Primitives --> Base
Loading
  • item-list-base owns the shared ListRoot, ListItem, ListButton, ListSub, and ListLabel primitives: list structure, row styling, nested-list indentation, and render composition. It is not exported from the package root and is not a consumer API.
  • ItemList composes those primitives into independent items, expandable groups, flat sections, and separators, including disabled-link handling. The caller owns route matching, translated labels, permissions, and aria-current.
  • Sidebar primitives and components reuse the same presentation while keeping Sidebar-specific styling, route metadata, icon-rail tooltips and flyouts, and mobile drawer dismissal in the Sidebar layer.

The item-list-base name distinguishes this internal foundation from the public item-list component. Sharing the presentation avoids maintaining two copies without making content lists depend on Sidebar providers or behavior.

Preserve native controls and composition

Use ordinary lists, buttons, and supplied links instead of introducing menu or selection-widget behavior. Linked groups keep navigation separate from expansion, and active styling does not imply current-page or selection semantics.

Let Base UI and rendered components supply their own button defaults. Removing an explicit type: undefined preserves AppShell Button's non-submit default when composed through render, preventing accidental form submissions.

Summary

  • Add ItemList with action/link rows, expandable groups, flat sections, and decorative separators.
  • Reuse the internal presentation in Sidebar while preserving its existing interactions and styling.
  • Add a showcase and hierarchical table-of-contents example, authored documentation, generated documentation, and a minor changeset.
  • Cover list semantics, keyboard interactions, disabled links, composition, and non-submit behavior, including the render={<Button />} regression.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Code Metrics Report

main (eb44189) #636 (01e487d) +/-
Coverage 89.3% 89.3% +0.0%
Test Execution Time 2m32s 2m46s +14s
Details
  |                     | main (eb44189) | #636 (01e487d) |  +/-  |
  |---------------------|----------------|----------------|-------|
+ | Coverage            |          89.3% |          89.3% | +0.0% |
  |   Files             |            227 |            231 |    +4 |
  |   Lines             |           7240 |           7258 |   +18 |
+ |   Covered           |           6470 |           6488 |   +18 |
- | Test Execution Time |          2m32s |          2m46s |  +14s |

Code coverage of files in pull request scope (78.7% → 82.0%, patch 100.0%)

Files Coverage +/- Patch Coverage Status
packages/core/src/components/internals/item-list-base/index.ts 0.0% 0.0% - added
packages/core/src/components/internals/item-list-base/item-list-base.tsx 100.0% +100.0% 100.0% added
packages/core/src/components/item-list/index.ts 0.0% 0.0% - added
packages/core/src/components/item-list/item-list.tsx 100.0% +100.0% 100.0% added
packages/core/src/components/sidebar/primitives.tsx 78.7% 0.0% 100.0% modified
packages/core/src/index.ts 0.0% 0.0% - modified

Reported by octocov

@IzumiSy
IzumiSy marked this pull request as ready for review October 22, 2026 05:01
@IzumiSy
IzumiSy requested a review from a team as a code owner October 22, 2026 05:01
@IzumiSy

IzumiSy commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

# Conflicts:
#	packages/core/src/components/sidebar/primitives.tsx

Co-authored-by: IzumiSy <982850+IzumiSy@users.noreply.github.com>

Copilot AI commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved the conflict and merged main in commit 0452820. The Sidebar and ItemList tests pass.

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