Skip to content

finding(docs): core/app-schema.mdx's "Global Actions" snippet imports the wrong same-named MenuItem #6692

Description

@os-sales

Found while implementing #6523 / #6346 (the overlay.ts MenuItem discriminated-union +
onClick fix). Filed unassigned and out of both cards' fence — this is a pre-existing,
unrelated docs/type-naming collision, not something either ruling's diff touches.

What was measured, at c75b928e6

content/docs/core/app-schema.mdx's ## Global Actions section has a real, compiled
ts fence (unlike the plaintext "Schema" blocks elsewhere on this same page):

import type { MenuItem } from '@object-ui/types';

interface AppAction {
  ...
  items?: MenuItem[];     // For type='dropdown' or 'user'
  ...
}

import type { MenuItem } from '@object-ui/types' resolves to the overlay MenuItem
(packages/types/src/overlay.ts, re-exported at index.ts:255 under the bare name
MenuItem) — the discriminated union shared by ui:dropdown-menu/ui:context-menu/
ui:menubar, which #6523 just reshaped.

But the real AppAction.items field — packages/types/src/app.ts:728 — is declared
inside app.ts itself, so MenuItem[] there resolves to app.ts's own local MenuItem
(app.ts:461), a structurally different, legacy navigation-item shape (type?: 'item' | 'group' | 'separator', path, href, badge, hidden — none of which the overlay
MenuItem declares). The barrel re-exports app.ts's version under the renamed
AppMenuItem (index.ts:59) specifically to avoid this collision — but the docs snippet
imports the bare, unrenamed name, so it silently picks up the WRONG same-named type.

Confirmed this is not new: app.ts's own MenuItem and overlay.ts's MenuItem have
always been structurally different (this predates #6523's union split — before it, the
overlay MenuItem was still a single object with label: string required, icon,
disabled, onClick, shortcut, children, separator?: boolean, none of which match
app.ts's type/path/href/badge/hidden shape either).

Why this doesn't block #6523/#6346

The snippet is a bare type reference (items?: MenuItem[]), not an object literal that
instantiates the shape — so it compiles under check-doc-snippet-types.mjs regardless of
which MenuItem it actually resolves to, and #6523's union split doesn't change whether it
compiles. Confirmed unaffected by grepping the diff: the snippet's own text is untouched by
either card.

The open question

Two candidate fixes, not adjudicated here:

  • A — the snippet's import is simply wrong; change it to import type { MenuItem as AppMenuItem } from '@object-ui/types'; (or import from '@object-ui/types''s already-exported
    AppMenuItem name directly) so the reader compiles against the type that's actually there.
  • BAppAction.items itself is questionable: dropdown/user toolbar actions plausibly
    WANT the richer overlay MenuItem (icon, onClick, shortcut, submenu children, divider) more
    than the legacy nav-item shape (path/href/badge) app.ts gives them today — worth
    checking whether header-bar.tsx (the renderer consuming AppAction.items) actually reads
    app.ts's fields or the overlay ones before choosing.

Whichever way, this is a genuine decision (which MenuItem AppAction.items should mean),
not a mechanical fix, so it doesn't qualify for the bounded in-place-fix exemption on the PR
that found it.

Refs: #6523 · #6346 (found while implementing, unrelated to either ruling).

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatneeds-user-decisionpriority:p2

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions