Skip to content

finding(plugin-grid): the list link: true column renders a span role="link" with no href — no middle-click, no copy-link, and now inconsistent with the detail page's real anchors #4490

Description

@yinlianghui

Measured during #4336 (PR #4489). Observation-class; no fix proposed here.

What

ObjectGrid's link: true column renders LinkCell as a span role="link" (no href), navigating only via navigation.handleClick(row) → the host's onNavigate. Consequences:

Remedy shape (when someone takes it)

LinkCell consumes the same host-published recordHref (the provider needs mounting on the list surface, or the href callback threading through the grid's navigation context) and renders a real anchor with the same left-click-SPA / modifier-click-native split #4489 established. One mechanism, both surfaces.

Refs #4336 (PR #4489), #4472 (no hand-built URLs — the href must come from the host).

Filed unassigned for triage.


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 13, 2026
  2. yinlianghui commented on Aug 13, 2026

    @yinlianghui
    CollaboratorAuthor

    CLAIM — session session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4490-linkcell-real-anchor.

    Ruling (delegated authority; open veto window): give the list link: true column the SAME real-anchor mechanism PR #4489 established for detail/related surfaces — LinkCell consumes the host-published recordHref (RelatedRecordActionsContext) and renders a real <a href> with the #4489 split: plain left click SPA-handled via the existing navigation.handleClick, modifier clicks left to the browser. One mechanism, all three surfaces.

    1. Provider reach is the measured question: RelatedRecordActionsProvider mounts today only on the record detail body. Measure where the LIST surface's host (app-shell ObjectView) can publish recordHref — mounting the provider there, or threading the href callback through the grid's existing navigation context — pick the seam that does NOT create a new cross-package dependency and does NOT hand-build URLs (the console: copied invitation link is unusable — buildAcceptUrl rebuilds the trailing-dot host that resolveHomeUrl already retired #4472/finding(app-shell): AiChatPage's publicShareBase is a third hand-rolled console-mount resolution — correct today, drift risk under the one-resolver rule #4482 rule; the host owns the route shape). If BOTH seams require more than provider-mounting + context consumption, STOP and report the measurement.
    2. Graceful degradation: no host recordHref ⇒ LinkCell renders exactly today's span role="link" behavior — byte-identical, pinned. The anchor is an upgrade where the host provides the URL, never a break where it doesn't.
    3. a11y: the anchor carries the display text as its accessible name; role="link" span path unchanged for the fallback.

    Red-first: list with a host-published recordHref → pre-fix querySelector('a') null in the link cell (today's span — capture); post-fix a real anchor whose href is the host-built record URL; modifier-click not preventDefault'ed (assert the handler split); plain click still calls navigation.handleClick. Must-not-change (green both sides): provider-less hosts byte-identical; non-link columns untouched; row-click navigation unchanged; #4503/#4510's landed BulkActionBar/fan-out behavior untouched (their pins stay green).

    Grading: patch @object-ui/plugin-grid (+ patch app-shell if the provider mounting lands there — .d.ts measured; additive-export rules per precedent). Never major.

    Surface (mutual exclusion): packages/plugin-grid/src/ObjectGrid.tsx (LinkCell) + the measured provider/threading seam + tests + changesets. ⛔ NOT: packages/react's context FILE unless a new optional member is genuinely required (measure — #4489 already added recordHref/openRecord), RecordDetailView (in-flight #4213), AppContent (in-flight #4252), metadata-admin (in-flight #4518), plugin-timeline (in-flight #4513), content/docs/releases/.


    Generated by Claude Code


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions