Repository navigation
Commit 7a2818c
fix(app-shell): name Studio's group-title, Description, Help text and nav-item inputs (#26926)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbXRpscK3dszbSuQtCmGe4R8)_
Fixes #26732
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:Studio
里五个输入框以前读屏软件读不出名字:表单设计器里分组标题的行内输入框、字段属性面板的「描述」和「帮助文本」、界面导航项属性面板的「链接到对象」下拉和「标签」输入框。现在每个都有可读的名字,点击标签也会聚焦到对应输入框。外观和保存内容都不变。
- **为什么改**:QA 读无障碍树时发现这几处是无名编辑框(studio-qa-2026-10-27,U7),自动化无障碍检查也会报错。
- **风险与回滚**:很低。只加了 `id`/`htmlFor` 关联和一个 `aria-label`,没有新文案键,不动元数据和
spec。一个旧测试钉住了「对象下拉没有名字」,本 PR 把它改为钉住新名字。回滚即 revert。
- **先看**:`StudioDesignSurface.tsx` 里 `StudioNavItemInspector` 的两处
`htmlFor`;`ObjectFieldInspector.tsx` 的
`TextareaField`;`StudioDesignSurface.sharedSelect-11865.test.tsx`
改掉的那条断言。
- **两分钟验证**:在 Studio 打开一个应用的导航项,点「链接到对象」这几个字,预期下拉获得焦点;或在浏览器无障碍面板里看到该下拉名为
"Link to object"。
- **需要你做的**:无,席位落地。
## What changes
- **Form designer group title** (`ObjectFormDesigner.tsx`): a declared
group's inline title input element had no label, `aria-label` or `id`.
No visible label sits beside it, so it takes `aria-label` from the label
the group inspector already gives the same value,
`engine.studio.designer.group.nameLabel` ("Group name" / 「分组名称」). No new
key.
- **Field inspector Description and Help text**
(`ObjectFieldInspector.tsx`): the file-local `TextareaField` drew its
`Label` beside the textarea element without closing the pair. It now
mints a per-instance `React.useId()` and sets `htmlFor` ⇄ `id`, the way
`_shared.tsx`'s form atoms (`InspectorTextField`,
`InspectorNumberField`) close theirs. Every `TextareaField` in the
inspector gets its name from this one change.
- **Interfaces nav-item inspector** (`StudioDesignSurface.tsx`,
`StudioNavItemInspector` only): the *Link to object* label and the
*Label* label were drawn above their controls without `htmlFor`. Both
now close the pair with a `useId()`, as the same inspector's target,
URL, *Open in* and icon fields already did. The object picker is the
shared `StudioPicker`, which already forwards `id` to its Radix trigger,
so no component changed; its header comment now says the object picker
is named like the others.
## Tests
- `ObjectFieldInspector.textareaNames-26732.test.tsx`: Description and
Help text found by `getByRole('textbox', { name })` and `getByLabelText`
in en; a zh case awaits `loadStudioCatalogue('zh')` at module scope (the
#26800 pattern) and finds both by 「描述」 / 「帮助文本」.
- `ObjectFormDesigner.groupTitleName-26732.test.tsx`: the group-title
input found by `getByRole('textbox', { name: 'Group name' })`, holding
the group's label.
- `StudioDesignSurface.navItemInspectorNames-26732.test.tsx`: the object
picker found by `getByRole('combobox', { name: 'Link to object' })` (and
it is the `nav-link-object` trigger), the Label input by
`getByRole('textbox', { name: 'Label' })`.
- `StudioDesignSurface.sharedSelect-11865.test.tsx`: its pin "the object
picker had none" now reads the object picker's name as `Link to object`.
- Ablation (one-off, not kept), each with the fix committed, through
`node scripts/ablation-replace.mjs` (anchor 1 → 0, restored blob equal
to HEAD each time): dropping the group input's `aria-label` reds its
test (1 failed of 1); dropping `htmlFor={id}` from `TextareaField` reds
both textarea cases (2 failed of 2); dropping the object picker's `id`
reds the nav test, and so does dropping the Label input's `id` (1 failed
of 1 each). `git diff HEAD` empty after all four.
## Acceptance notes
- **Sweep of the three files for the same hole.**
`ObjectFormDesigner.tsx` has no other unnamed input (its icon buttons
all carry `aria-label`). In `ObjectFieldInspector.tsx`, every control
other than `TextareaField` is a `_shared.tsx` atom that already closes
its pair, an `InspectorComboField` with a label or `ariaLabel`, or a
checkbox inside its label element; the picklist option rows' value and
label inputs are named by their placeholders ("Value", "Label") and the
color swatch by its `title`, so they are not unnamed and are left as
they are. In the nav-item inspector, the type radios sit inside their
labels and the remaining fields were already tied.
- **A pinned behaviour is reversed on purpose.**
`StudioDesignSurface.sharedSelect-11865` pinned that the object picker
kept the native control's lack of a name; this card asks for that name,
so the pin now reads it.
## Verification
All readings at head `67406db6` (base `2720874a`), under
`scripts/pm/os-verify-lock.sh` with `--maxWorkers=1`.
<details><summary>Touched package: @object-ui/app-shell</summary>
- Dependency closure: `pnpm exec turbo run build --concurrency=2
--filter='@object-ui/app-shell^...'`, 63 tasks, VERDICT command-exit 0.
Then `pnpm --filter @object-ui/app-shell type-check` (`tsc --noEmit` and
`tsc -p tsconfig.test.json`, so the tests too): VERDICT command-exit 0.
- The four new or edited test files: Test Files 3 passed (3), Tests 4
passed (4); `StudioDesignSurface.sharedSelect-11865`: Tests 79 passed
(79).
- Narrowed app-shell run: every test file naming `ObjectFormDesigner`,
`ObjectFieldInspector`, `StudioNavItemInspector`, `nav-link-object` or
`InterfacesPillar` (89 files). First run at `a3764046`: 1 failed, 892
passed, the `sharedSelect-11865` pin of the unnamed object picker,
updated in `67406db6` and green after. The rest of app-shell is left to
CI's Test UI shards.
- ESLint with `ui/eslint.config.js` on the seven touched files: 0
errors, and no warning on a changed line.
</details>
<details><summary>Derived gates</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 34 commands for the 8 changed paths
(same list at both heads); all 34 exit 0, each code captured before any
pipe, among them `check:nul-bytes`, `check:test-source-alias`,
`check:cross-package-test-inputs`, `check:type-check-coverage`,
`check:type-check-debt`, `check-sdui-manifest`, `check-empty-changeset`
and `check-changeset-no-major`. `pnpm --dir ui exec vitest run
scripts/`: Test Files 178 passed, 2 skipped (180), Tests 5065 passed, 2
skipped.
- `--ran` reconciled: "34 derived famil(ies) accounted for — 34 run, 0
NOT-MEASURED".
- PR-body gates on this body: `check-changeset-no-major`,
`check-adr-0087-registration`, `check-closing-keyword-parity`,
`check-partof-closing-keyword`, all exit 0. `pnpm --dir ui run
check:new-line-citations`: 0 new citations.
- Families CI runs over the whole tree (type-check lanes, lint, artifact
rosters) are CI's; the PR's check-runs are the reading.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (lint is CI's)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (not touched)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QsR2jT6kwaZ4RiKsDR3s5f
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jT6kwaZ4RiKsDR3s5f)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 8bbdb0b commit 7a2818c
8 files changed
Lines changed: 219 additions & 11 deletions
File tree
- .changeset
- ui/packages/app-shell/src/views
- metadata-admin/inspectors
- studio-design
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1516 | 1516 | | |
1517 | 1517 | | |
1518 | 1518 | | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
1519 | 1522 | | |
1520 | 1523 | | |
1521 | | - | |
| 1524 | + | |
1522 | 1525 | | |
| 1526 | + | |
1523 | 1527 | | |
1524 | 1528 | | |
1525 | 1529 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
481 | 481 | | |
482 | 482 | | |
483 | 483 | | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
484 | 487 | | |
485 | 488 | | |
486 | 489 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
18 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
158 | 159 | | |
159 | 160 | | |
160 | 161 | | |
161 | | - | |
| 162 | + | |
162 | 163 | | |
163 | 164 | | |
164 | 165 | | |
| |||
337 | 338 | | |
338 | 339 | | |
339 | 340 | | |
340 | | - | |
| 341 | + | |
| 342 | + | |
341 | 343 | | |
342 | 344 | | |
343 | 345 | | |
344 | 346 | | |
345 | 347 | | |
346 | | - | |
| 348 | + | |
347 | 349 | | |
348 | 350 | | |
349 | 351 | | |
350 | 352 | | |
351 | 353 | | |
352 | 354 | | |
353 | 355 | | |
354 | | - | |
| 356 | + | |
355 | 357 | | |
356 | 358 | | |
357 | 359 | | |
| |||
361 | 363 | | |
362 | 364 | | |
363 | 365 | | |
364 | | - | |
| 366 | + | |
365 | 367 | | |
366 | 368 | | |
367 | 369 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2631 | 2631 | | |
2632 | 2632 | | |
2633 | 2633 | | |
| 2634 | + | |
| 2635 | + | |
2634 | 2636 | | |
2635 | 2637 | | |
2636 | 2638 | | |
| |||
2749 | 2751 | | |
2750 | 2752 | | |
2751 | 2753 | | |
2752 | | - | |
| 2754 | + | |
| 2755 | + | |
| 2756 | + | |
2753 | 2757 | | |
| 2758 | + | |
2754 | 2759 | | |
2755 | 2760 | | |
2756 | 2761 | | |
| |||
2789 | 2794 | | |
2790 | 2795 | | |
2791 | 2796 | | |
2792 | | - | |
| 2797 | + | |
| 2798 | + | |
| 2799 | + | |
2793 | 2800 | | |
| 2801 | + | |
2794 | 2802 | | |
2795 | 2803 | | |
2796 | 2804 | | |
| |||
3061 | 3069 | | |
3062 | 3070 | | |
3063 | 3071 | | |
3064 | | - | |
| 3072 | + | |
| 3073 | + | |
3065 | 3074 | | |
3066 | 3075 | | |
3067 | 3076 | | |
| |||
0 commit comments