Uh oh!
There was an error while loading. Please reload this page.
docs(layout): app-shell.mdx 导航示例改真实 NavItem 键,删两个被丢弃的 prop (#4793) - #4819
Conversation
…p two phantom props (#4793) The page's two SidebarNav examples were 2/3 wrong per item. `NavItem` declares `title` / `href` / `icon`, where `icon` is a COMPONENT rendered as `<item.icon />` (SidebarNav.tsx:60, :109). The examples wrote `label` (9 occurrences) and a quoted icon name (7 occurrences); only `href` was right. Copied verbatim they produced rows that navigate correctly but render no text at all (`<span>{item.title}</span>` on undefined), no icon, and a collapsed-sidebar tooltip of `undefined`. The Complete Example additionally passed two props SidebarNavProps does not declare. SidebarNav destructures a fixed key list with no rest element, so `header={{ logo, title }}` and `footer={…}` were built and dropped — the logo, the sidebar title and the "Upgrade Plan" button they promised could never appear. `header` is rewritten onto `title`, the one real branding prop; the logo is directed to the `navbar` slot, which the page already demonstrates. Shape follows packages/layout/README.md as fixed in #3999 / PR #4792, including the `NavItem[]` annotation — that annotation is what turns this whole class of typo back into a compile error at the keyboard instead of a blank sidebar. Pinned by packages/layout/src/__tests__/app-shell-docs-nav-example.test.ts: the example arrays are real type-checked TypeScript (compiled by the package's tsconfig.test.json), asserted to appear verbatim in the MDX, plus three page-wide scans rejecting a quoted `icon:`, an item-level `label:`, and any `<SidebarNav>` prop absent from SidebarNavProps — the last reads its expected key list out of SidebarNav.tsx, so it cannot rot. Scan surface is this one page. Untouched on purpose: the toggle / SidebarTrigger prose PR #4805 just rewrote, the h-14 and padding numbers pinned by #3914, and the Accessibility section. Whether SidebarNav should GAIN header/footer slots is a product enhancement, left for the maintainer. Fixes#4793 Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
commented
Aug 16, 2026
【PM 验收 · ACCEPT】objectui 分片 PM(session_01GTRjn8xBqp75dk7kFupVRt),#4793 app-shell.mdx 导航示例修正。 实物核验:3 文件;基线恰为 PR #4805 合并提交(前置门兑现);改后 mdx 项级 CI 终态(PM 亲读):head 6f378cc 全部 19 项 completed、零 failure。 扩界裁决(两处均采纳,记账): 验收要点:9/7/1 三组计数全归零且逐处核过 NavGroup 合法用法未误伤;编译级钉子的空集守卫(P5 反向验证里它正是防「什么都没扫到的空绿」的那条)设计正确;P1 预判 TS2741 实测 TS2353 的错误码偏差如实记账(excess-property 先于必填缺失报出),方向无误。searchEnabled TypeError 隐患随本单收口:dev 拒绝在 SidebarNav.tsx 加 lenient-consumer 兜底、修 producer(文档)的判断符合 AGENTS.md #0.1,PM 裁定不再为此立代码卡 —— NavItem.title 必填 + 本 PR 的编译钉已把该路径钉死在书写处。 回传处置:#4817(README AppShell header 幻影 prop)下轮晋级;#4818(AppShellBranding.logo 零读取方)进 findings 池;#4808 查重命中不开孪生单,正确。 处置:undraft + auto-merge(SQUASH)。 Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
…ectstack-ai#4817) (objectstack-ai#4828) * docs(layout): README AppShell examples pass `navbar`, not a phantom `header` (objectstack-ai#4817) `packages/layout/README.md` taught `<AppShell header={…}>`. `AppShellProps` (src/AppShell.tsx:25-40) has never declared `header`; the top bar's only entry point is `navbar`, which is what fills the `<header>` element AppShell renders itself (`:248`-`:249`). The component destructures a fixed key list with no rest element (`:233-241`), so the node was built and dropped with no warning: every reader who copied this npm landing page got a permanently empty top bar. Two more fences on the same page had the same defect. "Usage with React Router" passed `header={…}` too, and "Customization" taught `headerClassName` / `sidebarClassName` — there is no per-slot className at all, `className` lands on `<main>` (`:256`), and the navbar/sidebar are nodes the caller builds and styles. Adds an `AppShellProps` key table to the README and pins all of it, following the shape PR objectstack-ai#4819 used for app-shell.mdx: the expected prop names are READ OUT OF the interface on every run, never hardcoded, so the table can't rot into "update the test". The scan surface is packages/layout/README.md's `<AppShell …>` opening tags and nothing else — SidebarNav's surface stays with readme-sidebar-nav-example.test.ts (objectstack-ai#3999), app-shell.mdx's with app-shell-docs-nav-example.test.ts (objectstack-ai#4793). Co-authored-by: Claude <noreply@anthropic.com> * docs(layout): AppShellProps 表的 branding 行不再声称 logo 生效 (objectstack-ai#4817) The row I had just written credited `branding.logo` with being applied, but `useAppShellBranding` (AppShell.tsx:122-231) reads only `primaryColor`, `accentColor`, `favicon` and `title` — `logo` has no reader at all, which is the open objectui#4818. Documenting it as working would have baked that false claim into the npm landing page, so the row now names exactly the four keys the hook acts on and what each one does. Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Fixes#4793
前置门(已过)
本单与 PR #4805(#3946+#3947)同文件。等其落 main 后才开工:
d44279598即 #4805 的合并提交,worktree 以该显式 sha 建立。#4805 刚改写的 toggle / SidebarTrigger 散文、#3914 钉过的h-14与 padding 数值、Accessibility 段 —— 三处零触碰,可在 diff 里核。三组计数的前后对照
label:titleicon:headerproptitle="ObjectUI"footerprop9 处
label逐一核对过不是 NavGroup 的合法组级键:本页 9 处全部落在items:数组内、与href同级,即 NavItem;NavGroup.label在本页零出现(同目录 sidebar-nav.mdx 那 5 处才是合法用法,本 PR 不碰)。7 处图标映射:
home→Home、users→Users、settings→Settings(Basic Usage 3 处);layout-dashboard→LayoutDashboard、folder→Folder、users→Users、settings→Settings(Complete Example 4 处)。href本来就是对的,一个字符没动。形态照 #3999 / PR #4792 在 packages/layout/README.md 的定型抄,含
NavItem[]类型标注 —— README 里那句话说得最准:标注才是把这一整类笔误变回「在键盘上就编译报错」而不是「运行时空侧栏」的东西。header为什么改成title而不是删掉SidebarNavProps里唯一能表达它的真实 prop 是title(扁平NavItem[]上方的分区标签,默认'Application')。所以header={{ logo, title }}的 title 那一半有真实去处,直接删会连带删掉一个真 prop 的演示;logo 那一半侧栏没有任何插槽,本页 Navbar Content 段早就演示了 logo 放navbar的写法,正文补了一句指过去,避免读者找不到 logo 去哪了。「要不要给 SidebarNav 加 header / footer 插槽」是产品增强,不在本单范围,留维护者定。 本 PR 只做「文档停止承诺组件没有的东西」。
派单枚举的是 9/7/1。实测同一个示例里还有两处同类事实,一并改了,理由与 PR #4805 那次 6-vs-3 披露相同 —— 中间态会发出一个自相矛盾的页面:
footer={…}与header是同一个事实:SidebarNavProps同样没有它,组件解构同样无 rest,那个 "Upgrade Plan" 按钮同样永不出现。只修 header 会让同一段示例继续教另一个被丢弃的 prop,而且本 PR 新加的 props 钉子会当场判它红。AvatarFallback与Bell却从未导入。我本来就要重写这一行的 import(要加 lucide),留两个未定义标识符在刚改过的 import 旁边说不过去,所以补齐(AvatarFallback进 components,Bell进 lucide)。两处都零耦合,认为超界的话单独回退这两点即可,但不建议中间态落地。
钉子(新增,扫描面只覆盖本页)
新增
packages/layout/src/__tests__/app-shell-docs-nav-example.test.ts,照 PR #4792 的readme-sidebar-nav-example.test.ts同构建。#4793 正文说「PR #4792 的钉子只覆盖 packages/layout/README.md,够不到 content/docs —— 防回潮缺口如实存在」:本 PR 把这一页补上了,但只补这一页,整棵 docs 树对源码的钉子仍是 #3786 的题。三半各管一类事实:
NavItem,icon放真 lucide 组件,由本包tsconfig.test.json编译。这一半才抓得住icon: 'home':合法键下的值类型错,任何键名检查都看不见。另有一个SidebarNavProps类型的 props 对象,专管header/footer这类键错。icon:、项级label:、以及 SidebarNavProps 未声明的 prop。最后一条的期望键表是每次运行从SidebarNav.tsx现读的,所以它不会烂成「顺手改测试」。扫描面的边界写在文件头注释里:
icon:不许是字符串这条绝不能推广到 docs 树 ——page-header的icon本来就声明成字符串(图标名),这是关于这个组件这个 prop 在这一页的事实。项级label:那条也留了 NavGroup 豁免(fence 里出现NavGroup就跳过),免得以后有人加合法的分组示例被误伤。反向验证(先预判后跑;有一处预判偏差,如实记)
方向预判:全部是普通的「红」,没有 inversion —— 钉子的示例块是标注过的
NavItem[],旧形状是「表达不出来」而不是「读不到」,所以恢复旧形状必然编译红。照 PR #4792 的 B+C 教训把键错与值错分开证:title改成label(键没了)'label' does not exist in type 'NavItem'—— 预判的错误码不对,方向(红)对icon: Home改成icon: 'home'(只错值)Type 'string' is not assignable to type 'ComponentType'✅label与title并存(纯多余键)header加回SidebarNavProps'header' does not exist in type 'SidebarNavProps'✅P1 的预判偏差值得写下来:
label顶掉title时 TypeScript 报的是多余属性 TS2353,不是我预判的缺属性 TS2741 —— 对象字面量的 excess-property 检查先于必填缺失报出来。结论方向没变(照抄旧示例编译就是红),但 P1 和 P3 因此撞成同一个错误码,真正把「值错」单独证出来的只有 P2。这一点如实记,免得下一个人以为 P1/P3 是两个独立信号。P5 里
NavItem[]标注那条测试是经它自己的空集守卫变红的(no fence on the page declares navItems at all),不是逐 fence 判红 —— 旧 mdx 把数组内联进 JSX,压根没有const navItems声明。这正是那个守卫存在的理由:没有它,该断言会因为「什么都没扫到」而空绿。反向验证全程按 AGENTS.md:先 commit 再还原,
git checkout 分支名 -- 路径,未用git stash;跑完工作树已还原干净(git status --porcelain空)。验证记录(实测输出)
重活全程走
flock -w 3600 /tmp/os-heavy-verify.lock+NODE_OPTIONS=--max-old-space-size=4096,未起任何 dev 服务。changeset 按门实测判,不靠猜:presence 门只数发版包的
src/,content/docs的 mdx 不计入 —— 未加 changeset 时它明确点名packages/layout/src/__tests__/app-shell-docs-nav-example.test.ts一个文件而报红。本改动没碰任何包的运行时源码,只有文档页和钉住它的测试,所以按 AGENTS.md 的一等写法用空 frontmatter 显式声明「不发版」,门随即转绿并确认Every one of them has an EMPTY frontmatter — declared as releasing nothing。按
doc-version-claims棘轮要求,本次没有向 mdx 新增任何版本字面量。明确没碰的东西
app-shell.mdx的 Header Bar / Content Area 两处数值与AppShell.tsx不符(「64px / 4rem」实为h-14=56px;「4 on mobile」实为p-3,且 mobile 的pb-20未记) #3914 钉过的h-14、padding 数值;href(本来就对);size="icon"是 Button 的 prop,不是 NavItem 的icon,未误伤。顺带发现(未在本 PR 修,已按 #4949 纪律先查重后立单)
AppShellProps的文档块少了branding/rightRail两个真实 prop:检索命中已立的 finding: app-shell.mdx 的 AppShellProps 声明块漏了 2 个真实 props(branding、rightRail/ADR-0057 P3a),读者从文档看不到它们存在 #4808,不开孪生单。该块在本页 Component Props 段,与导航示例无关,本 PR 未动。headerprop,而AppShellProps没有它 —— 照抄示例头部区永不渲染 #4817(新立,未认领,未打标交 PM 分诊)—— packages/layout/README.md 的 AppShell 示例传了一个headerprop,而AppShellProps没有它、解构无 rest:与本页 SidebarNav 的header是同一类幻影 prop,但载体是另一个文件的另一个示例。PR docs(layout): SidebarNav README 示例改回 NavItem 真实形状,补 props 表并钉住 (#3999) #4792 给该 README 加的钉子只断言 SidebarNav 的 fence 与 props 表,够不到上方这个 AppShell 示例;本 PR 的钉子扫描面只覆盖 app-shell.mdx 一页,同样够不到。AppShellBranding.logo无任何读取方,注释「passed to sidebar/navbar via context」是假的(AppShell 不提供该 context) #4818(新立,finding标,不挂pm:queue)——AppShellBranding.logo全无读取方(useAppShellBranding只消费 primaryColor / accentColor / favicon / title,依赖数组里也没有它),而注释写着「passed to sidebar/navbar via context」,AppShell 根本没有那个 context;apps/console/src/hooks/useBranding.ts:27还在喂值。判 observation-class 的理由:侧栏 logo 今天照常显示,因为它走AppSidebar.tsx:194直接读 app schema 的另一条路,坏的只是这个声明面。Generated by Claude Code