Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

objectui: SidebarRail is the one untyped button the #4045 lint rule cannot reach (Shadcn no-touch zone) — observation #4451

Closed as not planned

Description

@yinlianghui

Found while implementing #4045 (PR #4450 — the object-ui/button-has-type lint rule plus the 114-site population fix). Not fixed there, and deliberately so; filing it so the residual is on the record rather than in a PR body.

Fact

packages/components/src/ui/sidebar.tsx:314 (SidebarRail) renders a plain button element with no type:

    <button
      ref={ref}
      data-sidebar="rail"
      aria-label="Toggle Sidebar"
      tabIndex={-1}
      onClick={toggleSidebar}
      title="Toggle Sidebar"
      ...

After #4045 this is the only untyped plain button left in the repo's lint surface. Measured: with the rule's src/ui ignore removed it is the single additional firing; with the ignore in place eslint packages/components/src/ui/sidebar.tsx reports 0 button-has-type messages.

Why #4045 did not fix it

packages/components/src/ui/** is the upstream Shadcn zone — overwritten by the sync script and never hand-edited (AGENTS.md §5 #7). #4045's counting rules excluded it for exactly that reason, and the rule's ignore list mirrors those counting rules, so the gate does not demand an edit the repo forbids. Patching it in-tree would be reverted by the next shadcn:update without anyone noticing.

Why this is observation-class, not a defect card

The generic risk is the #3344 family's: an untyped button defaults to type="submit" and submits any form it is composed into. But nobody has been shown to hit this one — SidebarRail is app-shell chrome (the sidebar's drag/toggle rail), and it being rendered inside a form element is not a composition anyone has demonstrated. Unlike the metadata-composed renderers (drawer, tree-view, navigation-overlay, which #4045 did fix), its mount point is not author-controlled through JSON.

Severity judged at filing time is unreliable in both directions (objectstack#4949), so this is filed plainly for triage rather than graded here.

Shape if it is ever worth fixing

Upstream, not here — the fix belongs in the Shadcn source the sync script pulls from, or in a packages/components/src/custom/ wrapper per AGENTS.md #7 if the rail ever needs local behaviour. A third option is to narrow the rule's src/ui ignore to a per-file eslint-disable so the zone is covered by default and each exception is explicit; that trades a bigger diff in a no-touch zone for visibility, and is a judgement call for whoever owns the Shadcn sync policy.


Generated by Claude Code

Activity

  1. added theissue type on Aug 17, 2026
  2. os-steve commented on Aug 17, 2026

    @os-steve
    Collaborator

    Concentrated finding round (unified triage seat, 2026-08-17): closed not planned. One untyped button inside the Shadcn no-touch zone, outside any form in practice (a sidebar rail toggle), recorded as the lint rule's one unreachable site. Patching inside the no-touch zone costs more governance than the residual risk warrants.

    Reopen trigger: SidebarRail is ever rendered inside a form (the implicit-submit hazard becomes real), or the shadcn declarative-patch mechanism (#4996 family) makes the one-line type="button" patch cheap and governed. Maintainer veto: reopen is free.


    Generated by Claude Code

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

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions