Skip to content

Commit bec4767

Browse files
committed
docs(spec): navigation.view stops promising a view selection nothing performs
`NavigationConfigSchema.view` described itself as "Name of the form view to use for details". Measured against spec source and the `objectui` tree this repo pins in `.objectui-sha`, no reader resolves an authored view name: - Its only read is `useNavigationOverlay`, which binds `navigation?.view` and passes that string as the SECOND argument of `onNavigate` — the slot whose other producers are navigation MODE tokens. - The hook also re-exports it on `NavigationOverlayState.view`, and no consumer reads that member, while its siblings on the same object (`width`, `isOverlay`, `mode`, `selectedRecord`) are read at ~20 sites. - Every `formViews` read in that tree is `formViews?.default`; none is keyed by an authored view name. - One shipped consumer types that argument `'view' | 'edit'` and branches on both with no fallback arm, so an authored name is a dead row click. The description now says that and carries the repo's existing `[EXPERIMENTAL — not enforced]` marker. No accept set moves: `view` is still `z.string().optional()` and every document that parsed before parses now. The enforce-or-remove decision (ADR-0049) is deliberately NOT taken here. Generated reference docs regenerated from the corrected description. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
1 parent 6548118 commit bec4767

3 files changed

Lines changed: 66 additions & 5 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
`ListViewSchema.navigation.view`'s description stops promising view selection the stack never performs
6+
7+
`NavigationConfigSchema.view` described itself as *"Name of the form view to use
8+
for details (e.g. `summary_view`, `edit_form`)"*. Measured against
9+
`@objectstack/spec` source and the `objectui` checkout this repo pins in
10+
`.objectui-sha`, no reader resolves an authored view name:
11+
12+
- The key's **only** read is `useNavigationOverlay`
13+
(`packages/react/src/hooks/useNavigationOverlay.ts`). It binds
14+
`const view = navigation?.view` and then passes that string as the **second
15+
argument of `onNavigate`** — the slot whose other producers are navigation
16+
**mode** tokens (`'new_window'`, and the `'view'` literal the `??` supplies).
17+
- The hook also re-exports it on `NavigationOverlayState.view`, and **no
18+
consumer reads that member** — while its siblings on the same returned object
19+
(`width`, `isOverlay`, `mode`, `selectedRecord`) are read at roughly twenty
20+
sites, which is the lit control that makes the zero a reading.
21+
- Every `formViews` read in that tree is `formViews?.default`. None is keyed by
22+
an authored view name, so no resolution path exists for this key to reach.
23+
- One shipped consumer types that second argument `'view' | 'edit'` and
24+
branches on both with **no fallback arm**, so an authored name there matches
25+
neither branch and the row click does nothing.
26+
27+
The key is therefore worse than ignored: the value travels, and it lands in a
28+
slot that means something else. The description now says that, carries the
29+
repo's existing `[EXPERIMENTAL — not enforced]` marker, and tells authors to
30+
leave the key unset.
31+
32+
**No accept set moves.** `view` is still `z.string().optional()`; every
33+
document that parsed before parses now, with identical issues and identical
34+
output. Nothing is retired, renamed, constrained, or newly resolved — the
35+
enforce-or-remove decision (ADR-0049) is still open on #16885, and this change
36+
deliberately does not take it.
37+
38+
**This is shipped, which is why it carries a changeset rather than
39+
`skip-changeset`.** `@objectstack/spec`'s published `files[]` ships both `dist`
40+
and `src/**/*.zod.ts`. Measured on the rebuilt artifact: the corrected sentence
41+
is present in 22 built bundles and in the published source file, the old
42+
sentence is absent from all of them, a sibling `describe()` that ships
43+
(`Disable standard navigation entirely`) lit the same probe at 22 as the
44+
positive control, and a test-only `it()` title lit `src` but not `dist` as the
45+
negative control.

content/docs/references/ui/view.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ View filter rule
914914
| Property | Type | Required | Description |
915915
| :--- | :--- | :--- | :--- |
916916
| **mode** | `Enum<'page' \| 'drawer' \| 'modal' \| 'split' \| 'popover' \| 'new_window' \| 'none'>` | optional (default: `"page"`) | |
917-
| **view** | `string` | optional | Name of the form view to use for details (e.g. "summary_view", "edit_form") |
917+
| **view** | `string` | optional | [EXPERIMENTAL — not enforced] Intended as the name of a form view to open for details (e.g. "summary_view", "edit_form"), but no reader resolves an authored view name: the one read forwards this string into the renderer's navigation-ACTION argument (the slot that otherwise carries the mode token), where a consumer with a closed action vocabulary matches no branch and the row click does nothing. Authoring it selects no view — leave it unset until enforce-or-remove (ADR-0049) is decided for this key. |
918918
| **preventNavigation** | `boolean` | optional (default: `false`) | Disable standard navigation entirely |
919919
| **openNewTab** | `boolean` | optional (default: `false`) | Force open in new tab (applies to page mode) |
920920
| **size** | `Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>` | optional (default: `"auto"`) | Overlay size bucket for drawer/modal detail: 'auto' (default — renderer derives from field count + viewport; AI writes nothing) or a coarse override sm/md/lg/xl/full. Prefer this over the pixel `width`; page mode ignores it. |
@@ -1159,7 +1159,7 @@ Tab configuration for multi-tab view interface
11591159
| Property | Type | Required | Description |
11601160
| :--- | :--- | :--- | :--- |
11611161
| **mode** | `Enum<'page' \| 'drawer' \| 'modal' \| 'split' \| 'popover' \| 'new_window' \| 'none'>` | optional (default: `"page"`) | |
1162-
| **view** | `string` | optional | Name of the form view to use for details (e.g. "summary_view", "edit_form") |
1162+
| **view** | `string` | optional | [EXPERIMENTAL — not enforced] Intended as the name of a form view to open for details (e.g. "summary_view", "edit_form"), but no reader resolves an authored view name: the one read forwards this string into the renderer's navigation-ACTION argument (the slot that otherwise carries the mode token), where a consumer with a closed action vocabulary matches no branch and the row click does nothing. Authoring it selects no view — leave it unset until enforce-or-remove (ADR-0049) is decided for this key. |
11631163
| **preventNavigation** | `boolean` | optional (default: `false`) | Disable standard navigation entirely |
11641164
| **openNewTab** | `boolean` | optional (default: `false`) | Force open in new tab (applies to page mode) |
11651165
| **size** | `Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>` | optional (default: `"auto"`) | Overlay size bucket for drawer/modal detail: 'auto' (default — renderer derives from field count + viewport; AI writes nothing) or a coarse override sm/md/lg/xl/full. Prefer this over the pixel `width`; page mode ignores it. |
@@ -1310,7 +1310,7 @@ View filter rule
13101310
| Property | Type | Required | Description |
13111311
| :--- | :--- | :--- | :--- |
13121312
| **mode** | `Enum<'page' \| 'drawer' \| 'modal' \| 'split' \| 'popover' \| 'new_window' \| 'none'>` | optional (default: `"page"`) | |
1313-
| **view** | `string` | optional | Name of the form view to use for details (e.g. "summary_view", "edit_form") |
1313+
| **view** | `string` | optional | [EXPERIMENTAL — not enforced] Intended as the name of a form view to open for details (e.g. "summary_view", "edit_form"), but no reader resolves an authored view name: the one read forwards this string into the renderer's navigation-ACTION argument (the slot that otherwise carries the mode token), where a consumer with a closed action vocabulary matches no branch and the row click does nothing. Authoring it selects no view — leave it unset until enforce-or-remove (ADR-0049) is decided for this key. |
13141314
| **preventNavigation** | `boolean` | optional (default: `false`) | Disable standard navigation entirely |
13151315
| **openNewTab** | `boolean` | optional (default: `false`) | Force open in new tab (applies to page mode) |
13161316
| **size** | `Enum<'auto' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'>` | optional (default: `"auto"`) | Overlay size bucket for drawer/modal detail: 'auto' (default — renderer derives from field count + viewport; AI writes nothing) or a coarse override sm/md/lg/xl/full. Prefer this over the pixel `width`; page mode ignores it. |

packages/spec/src/ui/view.zod.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,8 +1595,24 @@ export const NavigationConfigSchema = lazySchema(() => strictObject({
15951595
}, {
15961596
mode: NavigationModeSchema.default('page'),
15971597

1598-
/** Target View Config */
1599-
view: z.string().optional().describe('Name of the form view to use for details (e.g. "summary_view", "edit_form")'),
1598+
/**
1599+
* [#16885] Target view config — DECLARED, NOT RESOLVED. The name promises
1600+
* view selection; nothing in the stack performs it. Measured at
1601+
* `.objectui-sha`: the single read is `useNavigationOverlay`
1602+
* (`packages/react/src/hooks/useNavigationOverlay.ts`), which passes the
1603+
* string as the SECOND argument of `onNavigate` — the slot whose other
1604+
* producers are mode tokens (`'new_window'`, `'view'`) — and re-exports it
1605+
* on `NavigationOverlayState.view`, which no consumer reads. Every
1606+
* `formViews` read in that tree is `formViews?.default`; none is keyed by
1607+
* an authored view name, so there is no path by which this could resolve.
1608+
* One shipped consumer types that argument `'view' | 'edit'` with no
1609+
* fallback branch, so an authored name there is a dead row click.
1610+
*
1611+
* Enforce-or-remove (ADR-0049) is undecided — #16885 carries the
1612+
* measurement. This description is corrected, not the accept set: the key
1613+
* still parses exactly as before.
1614+
*/
1615+
view: z.string().optional().describe('[EXPERIMENTAL — not enforced] Intended as the name of a form view to open for details (e.g. "summary_view", "edit_form"), but no reader resolves an authored view name: the one read forwards this string into the renderer\'s navigation-ACTION argument (the slot that otherwise carries the mode token), where a consumer with a closed action vocabulary matches no branch and the row click does nothing. Authoring it selects no view — leave it unset until enforce-or-remove (ADR-0049) is decided for this key.'),
16001616

16011617
/** Interaction Triggers */
16021618
preventNavigation: z.boolean().default(false).describe('Disable standard navigation entirely'),

0 commit comments

Comments
 (0)