|
| 1 | +--- |
| 2 | +'@objectstack/spec': minor |
| 3 | +'@object-ui/types': minor |
| 4 | +'@object-ui/react': minor |
| 5 | +'@object-ui/components': minor |
| 6 | +'@object-ui/plugin-calendar': minor |
| 7 | +'@object-ui/plugin-gantt': minor |
| 8 | +'@object-ui/plugin-grid': minor |
| 9 | +'@object-ui/plugin-kanban': minor |
| 10 | +'@object-ui/plugin-list': minor |
| 11 | +'@object-ui/plugin-map': minor |
| 12 | +'@object-ui/plugin-timeline': minor |
| 13 | +'@object-ui/plugin-tree': minor |
| 14 | +'@object-ui/plugin-view': minor |
| 15 | +'@object-ui/plugin-detail': minor |
| 16 | +'@object-ui/app-shell': minor |
| 17 | +--- |
| 18 | + |
| 19 | +feat(spec,ui)!: a record opens one way per object — `navigation.mode` keeps `drawer` (now the default), `page`, `new_window` and `none`; `modal`, `split` and `popover` are retired, and a list page's `recordAction` drops `modal` |
| 20 | + |
| 21 | +Clause-②: no (narrowing) |
| 22 | + |
| 23 | +Metadata-protocol: narrowed (`navigation.mode` refuses `modal`, `split` and `popover`; `interfaceConfig.recordAction` refuses `modal`; an omitted `navigation.mode` defaults to `drawer` instead of `page`) |
| 24 | + |
| 25 | +<!-- adr-0087: registered navigation-mode-overlay-values-removed, ui-record-open-overlay-modes-retired --> |
| 26 | + |
| 27 | +**BREAKING** accept-set narrowing and default change on the record-open surface (`@objectstack/spec`), with the console following it in the same release. |
| 28 | + |
| 29 | +The model, ruled by the maintainer: an object has one default way to open a record — the drawer, which expands to the full page (the same record page at two widths) — and `page` only for an object that declares it. A centred dialog and a popover were extra surfaces for the same record, and the side-by-side pane is each reader's own choice, not something an author fixes for every reader. |
| 30 | + |
| 31 | +- **FROM → TO.** `navigation.mode: 'modal'`, `'split'` or `'popover'` (on a list view, an object's `listViews` entry, or a page list block: `list-view`, `object-grid`, `object-kanban`, `object-calendar`, `object-map`, `object-gantt`, `object-tree`, `object-timeline`) → delete the value; the block takes the `drawer` default. `interfaceConfig.recordAction: 'modal'` → delete the value; the default is `drawer`. Declare `page` only for an object whose record should open as a full page. |
| 32 | +- **The one-line fix.** Delete the retired value. `os migrate meta --from 17` lists the edit for existing sources, and `--write` applies it. A stored `sys_metadata` row is converted when it is read (the `navigation-mode-overlay-values-removed` conversion), so a view saved from Studio with one of the three values keeps loading and opens the drawer. |
| 33 | +- **What the parse says.** Each retired value is refused by name with its prescription, for example "`navigation.mode: 'modal'` was removed in @objectstack/spec 18.3.0 (ADR-0087 D2) — …", at `defineStack` as `STACK_SCHEMA_INVALID` / 422. TypeScript rejects each at a `NavigationMode` position. A misspelt mode keeps zod's own message. |
| 34 | +- **The default.** A navigation block written without `mode` parses to `drawer` (it parsed to `page`). The console never honoured that `page` for a list with no navigation block, because it guessed the surface from the object's field count; that guess is retired too. A list of an object with no authored navigation opens a clicked record in the drawer, whatever its field count, and a mobile viewport still pages. An artifact or stored row that a released toolchain parsed carries the old `page` written out and keeps opening as a full page; delete it to take the drawer. |
| 35 | +- **The split pane.** It is now a reader's preference, read by the console's object page from the browser (`os:record-open-mode`, `drawer` or `split`, default `drawer`). It applies only to a record that opens in the drawer; an object or view that declares `page` keeps its declaration. |
| 36 | + |
| 37 | +The console (`@object-ui/*`): `useNavigationOverlay` defaults a block without `mode` to `drawer` and treats `drawer` as the one overlay mode. `NavigationOverlay` keeps the drawer face and the split face the console's object page draws from the preference; its `modal` and `popover` faces, the `popoverTrigger` / `popoverAnchorRef` props and the `useOverlayAnchor` export are removed, because no caller can reach them. The grid, kanban, calendar, gantt and tree renderers drop their `split` and `popover` plumbing. The registered `object-view` renderer opens records in the drawer (a page on a mobile viewport) instead of paging a field-heavy object. The Studio list-view inspector offers the four live modes, and the list page's `recordAction` the three live values. |
| 38 | + |
| 39 | +Migration for code that imported the removed component API: drop `popoverAnchorRef` / `popoverTrigger` from a `NavigationOverlay` call and any `useOverlayAnchor()` call; pass `mode="split"` with `mainContent` for a side-by-side pane. |
0 commit comments