Skip to content

DetailSection's click-to-copy writes [object Object] to the clipboard for every object-valued cell (address, geolocation, JSON, attachment) #8395

Description

@os-justin

Filed by the objectui#8376 dev (branch claude/issue-8376-detailsection-emptiness-authority) while converging that file's emptiness tests. ⛔ Not claimed. Out of scope there: #8376 is about which rows count as EMPTY; this is about what the copy affordance WRITES for a row that is filled, and fixing it does not move any emptiness predicate.

What

packages/plugin-detail/src/DetailSection.tsx:

const handleCopyField = React.useCallback((fieldName: string, value: any) => {
  const textValue = value !== null && value !== undefined ? String(value) : '';
  navigator.clipboard.writeText(textValue).then(...)

String(value) on an object is '[object Object]'. The affordance is offered for every non-empty value — objects included — so on a detail page a reader who clicks the copy button (or the row, or presses Enter on it) on an address, geolocation, JSON, attachment/file, multiselect or expanded lookup cell silently gets [object Object] on the clipboard.

Reachable in read mode on any non-editable object-valued row, which is the common case: the pencil affordance replaces copy only when the field is inline-editable AND the parent threaded onEnterInlineEdit.

Why it is worth fixing rather than removing

The cell next to the button is already rendering that value correctlyAddressCellRenderer prints a formatted postal address (objectui#4037), LocationCellRenderer prints 30.2741, 120.1551, SelectCellRenderer prints option badges. So the rendered text the reader is looking at is exactly what they expect to copy, and the clipboard gets a placeholder string instead. The failure is silent: nothing errors, and it is only noticed on paste.

Fix shape (a suggestion, not a ruling)

Two candidates, and a taker should decide rather than assume:

  • A — copy the rendered text. Read the row's rendered textContent. Matches what the reader sees, and needs no per-type table. Costs a DOM read at click time and depends on the renderer's formatting (a truncated value would have to be handled — TruncatedText is in this path).
  • B — a shared value→text formatter. Serialize per type (formatAddress for address, lat, lng for geolocation, JSON.stringify for json, the option labels for multiselect). Deterministic and testable, but it is a second formatting authority next to the cell renderers — the exact drift shape objectui#4037 closed for formatAddress, so it should reuse those functions rather than re-spell them.

⛔ Not "don't offer copy for objects": the value IS copyable and the reader has a legitimate reason to want it.

The pin should assert what reaches navigator.clipboard.writeText, per type, from a rendered DetailSection — with a control asserting an ordinary string row still copies its own value unchanged.

Measured

Read on branch claude/issue-8376-detailsection-emptiness-authority at b6ed5cdaf. canCopy is hasCellValue(value) as of #8376, and that function classifies every object as a value (deliberately — see its docblock), exactly as the raw test it replaced did. So #8376 neither introduces nor widens this; the String(value) line is untouched by it.

Dedup

search_issues once, self-validating (it returned a card that IS about this file's object-valued cells): the clipboard / [object Object] / detail copy wording returned exactly one issue, objectui#4037 — the address cell renderer, closed. #4037 is read-side only and says nothing about the clipboard; its own body scopes itself to the display registry. Nothing names the clipboard write.

Related

objectui#4037 (formatAddress, the shared address formatting authority a fix B would reuse) · objectui#8376 (hasCellValue, which decides whether the affordance is offered at all)

Activity

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpluginpm:dispatchedpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions