Skip to content

finding(types): @object-ui/types publishes two spellings of the spec's navigation config, and the hand-written ViewNavigationConfig still requires mode #4588

Description

@yinlianghui

Observation-class finding, surfaced by the repo-wide census done for #4550 (PR #4586). No fix proposed here, and nothing is being changed in that PR — packages/types was explicitly outside its surface.

What the census found

@object-ui/types publishes two types for the same spec object, and they disagree about whether mode may be omitted:

  1. packages/types/src/index.ts:1087 re-exports NavigationConfig from @objectstack/spec/ui, unchanged. The spec declares mode: NavigationModeSchema.default('page') (packages/spec/src/ui/view.zod.ts:1210), and a .default() lands on the authoring side as | undefined — so mode is optional there.

  2. packages/types/src/objectql.ts:1725 declares a hand-written ViewNavigationConfig covering the same six keys, with mode required:

export interface ViewNavigationConfig {
  /** ... @default 'page' */
  mode: 'page' | 'drawer' | 'modal' | 'split' | 'popover' | 'new_window' | 'none';
  view?: string;
  preventNavigation?: boolean;
  openNewTab?: boolean;
  size?: 'auto' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
  width?: string | number;
}

Its own doc comment says @default 'page' on a key it then makes required — the same self-contradiction #4550 reported one package over, and the reason that one was fixed at the producer.

Why it may matter

ViewNavigationConfig is what the schema types actually use: objectql.ts:801, :1402 and :1623 all spell navigation?: ViewNavigationConfig. So a spec-valid authored value such as

{ "navigation": { "view": "summary_view" } }

does not type-check against those schema interfaces, even though the spec permits it and every renderer defaults the mode. plugin-view/src/ObjectView.tsx:390 consumes it as ViewNavigationConfig | undefined and reads .mode only through === 'x' comparisons behind an if (navigationConfig) guard, so no runtime behaviour depends on the requirement — it is a typing constraint only, which is why this is filed as an observation rather than a defect.

Two further things a fix would want to weigh, neither established here:

  • Whether ViewNavigationConfig should exist at all, or whether these declarations should point at the spec re-export the same package already publishes. A hand copy of a spec object is the shape objectstack#4115 / objectui#3169 keep finding expired.
  • The @default 'page' annotation is duplicated prose about a default that lives in the spec and is applied in useNavigationOverlay; if the type is derived instead, that comment stops being a third place to keep in sync.

What was already fixed, for context

#4550 / PR #4586 collapsed @object-ui/react's NavigationConfig to the spec's authored config, so that name and the spec now agree. This finding is the remaining half in a different package, and was deliberately left alone: packages/types was in flight under #4535 at the time.

Refs #4550, #4586, #4528.


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions