Skip to content

spec(ui): ComponentPropsMap refuses navigation by name on the object-kanban and object-calendar element faces while objectui's renderers read and honour it — and object-timeline has no entry at all (spec half of objectui#8652) #17987

Description

@os-sam

Filed by the domain:spec @ objectui execution seat (session_01L5xpA5q533BgTTNADibEFt), 2026-09-13T09:4xZ, executing a maintainer ruling on objectui#8652.

⛔ Filed unassigned. ⛔ No domain:*, priority or type applied — routing and grading are this repo's triage's. ⛔ Not a claim.

The ruling this card executes

objectui#8652 asked where record-click navigation gets declared for a standalone object-kanban / object-timeline / object-calendar element. Four options were put to the maintainer; the reply, verbatim, was:

B

B — declare navigation on the platform element schemas first, then mirror it in objectui's packages/types. Options A (retire the read), C (keep it as an undeclared host-composition surface) and D (do nothing, hold) were not taken. objectui's three cards go pm:blocked on this one; ⛔ nothing lands there first.

The measurement — runtime safeParse against the INSTALLED validator, with both controls

@objectstack/spec 17.4.0, ComponentPropsMap from its /ui entry, run in an objectui worktree at objectui main 85243729:

document verdict
object-kanban carrying navigation REFUSED — issue code unrecognized_keys, message names the key: Unrecognized key(s) on this `object-kanban`: `navigation`
object-calendar carrying navigation REFUSED, identically, naming navigation
CONTROL A — the same two documents without navigation both parse GREEN (success: true)
CONTROL B — a known-bogus key zzzDefinitelyNotAKey refused through the same unrecognized_keys channel ⇒ this is the generic unknown-key rule, ⛔ not a navigation-specific refusal
object-timeline no entry in ComponentPropsMap at all. Firing control, same call: object-kanban true, object-calendar true, object-grid true

Why this is a producer-side divergence rather than an objectui defect

In objectui the key is read and honoured on the standalone element, measured on a two-leg runtime probe through the real renderer and the real registry, with no view ancestor and no onRowClick anywhere in the tree:

  • navigation: { mode: 'new_window' } on a standalone object-kanban root node ⇒ window.open called once, with /contacts/record/c1
  • the identical document with one key changed to mode: 'none'window.open never called

(Same two-leg result on a standalone object-timeline node.) Two objectui pins already assert this independently — ObjectKanban.navWidthDefault.test.tsx and ObjectCalendar.navWidthDefault.test.tsx each render standalone and assert an authored node-level navigation.width reaches the drawer.

the same document runs correctly and fails os check. An author writing navigation on a standalone board gets the behaviour they asked for from the renderer and a by-name refusal from the platform. Neither face teaches them the truth.

⚠️ And this is not reachable by pushing the key up to the view level, which was the shape objectui's triage originally preferred. A standalone element has no enclosing view to resolve from; that was measured (authored root-level documents exist in objectui's own catalog and its published plugin guide teaches the shape), and it is what falsified the premise the original ruling hung on.

What this card asks for

  1. Declare navigation on the object-kanban and object-calendar element schemas in ComponentPropsMap (packages/spec/src/ui/), carrying the same NavigationConfigSchema the view face already uses, so the vocabulary cannot fork.
  2. Add the missing object-timeline entry to ComponentPropsMap. Today that element is unjudged by the strict props map in either direction.
  3. ⚠️ The view-level navigation on ListViewSchema is not being retired or changed by this card. The element-level key is an additional carrier for the standalone placement, not a replacement — ⛔ do not fold the two into one question.

One executable acceptance criterion: with the change built, ComponentPropsMap['object-kanban'].safeParse({ …, navigation: { mode: 'drawer' } }) returns success: true, ComponentPropsMap['object-timeline'] is defined, and the bogus-key control still returns success: false through unrecognized_keys.

⭐ Precedent — the same shape, already resolved this way

objectstack#16503, "spec half of objectui#8172": ComponentPropsMap['object-kanban'] refused limit by name while four objectui faces implemented and taught it. It was resolved by declaring the key here. This card is that shape again, on a different key, and with the added wrinkle that one of the three elements has no entry at all.

Downstream, and the unlock criterion

objectui#8652 (carrier), objectui#8654 (timeline) and objectui#8651's CalendarSchema arm all wait on this. ⚠️ Their unlock criterion is consumer-installable, ⛔ not "this merged": objectui unblocks when a released @objectstack/spec carrying the declaration is installable there and its pin has moved.

Refs

objectui#8652 (the carrier and the ruling) · objectui#8654 · objectui#8651 · objectui#8327 (the census this family belongs to) · objectui#7334 (why forwarding the view-level key to these three renderers was ruled against) · objectstack#16503 (precedent).

Dedup

Searched this repo before filing. Four hits on the same corpus, all closed and none this subject: objectstack#17054 (object-calendar's calendar: block vs CalendarConfigSchema), objectstack#16553 (sort value shape on object-calendar / object-grid), objectstack#16503 (the limit precedent above), objectstack#7121 (dataSource on object-bound blocks). ⭐ Those four are the firing control: an empty result here would have been a reading rather than a silent zero.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions