Skip to content

fix(plugin-detail): reveal the read-only field copy button on keyboard focus - #26487

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-26329-copy-focus-reveal
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-26329-copy-focus-reveal

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #26329
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:记录详情页(桌面阅读模式)只读字段旁的「复制」按钮,除了鼠标悬停,现在键盘 Tab 聚焦到它或它所在的字段时也会显示。只改了一个 className,另加一个测试和一个 patch changeset。
  • 为什么改:这个按钮是真实可聚焦的按钮,但之前只在悬停时显示,键盘用户按 Tab 会停在一个看不见的控件上。旁边的编辑铅笔已在 fix(plugin-detail): reveal the inline-edit pencil on keyboard focus #26325 用同样写法处理,这次是它的复制按钮同类项。
  • 风险与回滚:只加了两个 Tailwind 显示类,悬停、点击复制、按钮名称都不变。回滚就是 revert 这一行。
  • 先看:ui/packages/plugin-detail/src/DetailSection.tsx 复制按钮的 className(与上方铅笔按钮写法一致)。
  • 两分钟验证:打开任意记录详情页,用 Tab 键在只读字段间移动,复制图标应随焦点出现;鼠标悬停行为与之前相同。
  • 需要你做的:无。不涉及受管面,CI 绿后由席位按常规合并队列落地。

What changed

  • ui/packages/plugin-detail/src/DetailSection.tsx: the copy-to-clipboard button drawn beside a read-only, copyable field in desktop read mode was opacity-0 group-hover:opacity-100. It is a real button, so a keyboard Tab stop landed on a control the user could not see, and the shared Button focus ring was painted at opacity 0. It now also carries group-focus-within:opacity-100 focus-visible:opacity-100, the spelling the inline-edit pencil a few lines above already uses (PR fix(plugin-detail): reveal the inline-edit pencil on keyboard focus #26325), as do RowActionMenu (plugin-grid) and data-table (components).
  • focus-visible reveals the button while it has keyboard focus. group-focus-within reveals it while anything in its own field has focus, which includes the field's own click-to-copy row (itself a Tab stop with role="button").
  • Unchanged: the hover reveal, click-to-copy on the row and on the button, the button's accessible name (detail.copyToClipboard), the copied-state icon, the mobile grouped-inset row, and every locale pack.
  • .changeset/26329-copy-button-focus-reveal.md: @object-ui/plugin-detail patch.
  • No sdui record is written; node scripts/check-sdui-manifest.mjs exits 0 and no registry component contract changed.

Tests

New: ui/packages/plugin-detail/src/__tests__/copyButton.focusReveal-26329.test.tsx, 4 tests, modelled on the pencil's pin inlineEditPencil.focusReveal-25883.test.tsx.

jsdom has no layout and no CSS engine, so it cannot measure "visible on focus". The tests pin the contract a browser turns into visibility:

  • the copy button is an enabled, focusable button and takes focus;
  • it carries focus-visible:opacity-100 and group-focus-within:opacity-100 next to the unchanged opacity-0 group-hover:opacity-100;
  • the shared Button's focus-visible:ring-2 survives the className merge;
  • the nearest .group ancestor is the button's own field, so focus in one field reveals only that field's button;
  • the field's click-to-copy row is a Tab stop inside that same group.

Activating the focused button copies its own field's value (navigator.clipboard.writeText receives Paris), an empty field offers no copy button, and an editable field draws the pencil instead. The button is found by its icon, not by its localized label.

  • Red first, at df130cf0 (the pin committed, the fix absent): Tests 1 failed | 3 passed (4). The failure is at the focus-visible:opacity-100 assertion; focusability and the hover reveal were already green there, which is the defect: a focusable but invisible control.
  • Green, at head 2f49b3e0, from cwd ui/ under scripts/pm/os-verify-lock.sh:
    • pnpm exec vitest run packages/plugin-detail --maxWorkers=2: Test Files 307 passed | 1 skipped (308), Tests 2857 passed | 18 skipped (2875). The new file alone: Tests 4 passed (4).
    • pnpm --filter @object-ui/plugin-detail run type-check (both tsc --noEmit and tsc -p tsconfig.test.json, so the new test is compiled): exit 0.
  • The plugin-detail dependency closure was built first, under the lock: pnpm --filter '@object-ui/plugin-detail^...' build, VERDICT command-exit 0.

Gates

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at head 2f49b3e0: 34 commands, each run locally, each exit 0. They include node scripts/check-sdui-manifest.mjs (and its --self-test), pnpm check:nul-bytes, pnpm check:cross-package-test-inputs, pnpm check:test-source-alias, pnpm check:type-check-coverage, pnpm check:type-check-debt (re-measure under the lock: 0 raw tsc errors), pnpm --dir ui exec vitest run scripts/ (Tests 5097 passed | 2 skipped) and the changeset gates.

--ran reconciliation with exit codes recorded: 34 derived famil(ies) accounted for — 34 run, 0 NOT-MEASURED (a DERIVED zero), exit 0.

CI runs every other family (lint, the type-check lanes, Build and E2E UI); this PR cites CI rather than re-running them locally.

Acceptance notes


Generated by Claude Code

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:记录详情页(桌面阅读模式)只读字段旁的「复制」按钮,除了鼠标悬停,现在键盘 Tab 聚焦到它或它所在的字段时也会显示。
为什么改:这个按钮是真实可聚焦的按钮,但之前只在悬停时显示,键盘用户按 Tab 会停在一个看不见的控件上;旁边的编辑铅笔已在 #26325 用同样写法处理(#26329)。
风险与回滚:只加了两个显示类,悬停、点击复制、按钮名称都不变。回滚 = revert 本 PR。
先看:ui/packages/plugin-detail/src/DetailSection.tsx 复制按钮的 className(与上方铅笔按钮写法一致)→ copyButton.focusReveal-26329.test.tsx。
两分钟验证:打开任意记录详情页,用 Tab 键在只读字段间移动,复制图标应随焦点出现;或在 ui/ 下运行 pnpm exec vitest run packages/plugin-detail/src/__tests__/copyButton.focusReveal-26329.test.tsx,预期 4 个测试全过。
需要你做的:无,席位落地。
席位意见:ACCEPT。一行 className,与 #26325 的铅笔同一写法。触屏上两个按钮都不显示(缺 pointer-coarse)不在本卡范围,留给移动端阅读行的编辑路径。

席位核对

seat 2 · 2026-10-27T05:23Z · head 2f49b3e0 (#26329)

item reading
form 3 files, +164/−1: the copy button's className in DetailSection.tsx gains group-focus-within:opacity-100 focus-visible:opacity-100; new 4-case pin; root .changeset/ patch on plugin-detail
premise measured at base 6746140361 the copy button had hover reveal only; the pencil beside it already had the focus reveal (#26325)
gates (check-runs on 2f49b3e0) 54 runs: 45 success, 9 skipped, 0 failed. Local: red 1/4 at the test-only commit (the focus-visible assertion), green 4/4; plugin-detail 307 files / 2857 tests; type-check exit 0; check-sdui-manifest exit 0; 34 of 34 derived gates exit 0
accepted deviations none
out of scope the pencil's "Double-click to edit" label vs keyboard activation stays with #25883; the touch reveal is not filed (no carrier yet)
landing NOT governed (check-governed-merges --pr 26487: 165 lines, no hit path); git merge-tree against origin/main clean; next on DetailSection.tsx: #25883 item 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

record page: the read-only field copy button is a Tab stop that stays invisible (hover-only reveal), like the inline-edit pencil before #25883

2 participants