@object-ui/layout 17.5.0 → 17.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +259 -0
- package/README.md +128 -19
- package/dist/AppSchemaRenderer.d.ts +23 -5
- package/dist/AppShell.d.ts +0 -2
- package/dist/NavigationRenderer.d.ts +20 -17
- package/dist/PageHeader.d.ts +12 -5
- package/dist/index.d.ts +7 -7
- package/dist/index.js +400 -406
- package/dist/index.umd.cjs +1 -1
- package/package.json +10 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,264 @@
|
|
|
1
1
|
# @object-ui/layout
|
|
2
2
|
|
|
3
|
+
## 17.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 88085e3: Consume the declared nav `runAction` slot; retire the private `?runAction=` string convention
|
|
8
|
+
|
|
9
|
+
An `object` navigation item can now declare `runAction: '<actionName>'` and the shell will run that action once on arrival at the object's list surface, through the ordinary execute path — so param dialogs, confirms and entitlement gates all still apply. The slot is `@objectstack/spec`'s `ObjectNavItemSchema.runAction`; objectui now reads it instead of a private convention.
|
|
10
|
+
|
|
11
|
+
- `NavigationItem` declares `runAction` (derived from the spec's object-nav variant), and objectui's own nav schema stops stripping it — `objectui validate` previously discarded the key, so an entry carrying a deep link validated clean with the deep link thrown away.
|
|
12
|
+
- `resolveHref` encodes it onto the list href as the reserved `?runAction=` param, on the list landings only. A `recordId` entry resolves to a record page, which has no list toolbar to answer it, so the slot is not encoded there.
|
|
13
|
+
- The deep link is honoured on **every** object list, not just the environments list. The action is armed only when it is actually present at `list_toolbar`; a name no action answers to runs nothing and deliberately leaves the URL untouched, so a later mount with fresher metadata can still honour it. Undefined references are rejected upstream at authoring time by `defineStack`.
|
|
14
|
+
- The param name now has exactly one definition (`NAV_RUN_ACTION_PARAM`, exported from `@object-ui/layout`) and is registered in the console's reserved-param collision check. It was previously a bare literal hand-written at both the producing and consuming ends, declared by no schema and listed in no registry.
|
|
15
|
+
- `CloudOnboardingNext` takes an optional `properties.createAction` (defaulting to `create_environment`) instead of hand-concatenating its deep link.
|
|
16
|
+
- 86f633f: Remove the published optional key `logo` from `AppShellBranding` (`@object-ui/layout`).
|
|
17
|
+
|
|
18
|
+
The key was declared but never read. `useAppShellBranding` applies only
|
|
19
|
+
`primaryColor`, `accentColor`, `favicon` and `title`, and `AppShell` installs no
|
|
20
|
+
context provider at all — so its doc comment, "Logo URL — passed to sidebar/navbar
|
|
21
|
+
via context", described a mechanism that did not exist. Three call sites were
|
|
22
|
+
feeding the key a real value that was silently discarded, and all three are removed
|
|
23
|
+
with it: `AppSchemaRenderer`, `ConsoleLayout` and the console's `useBranding` hook.
|
|
24
|
+
|
|
25
|
+
The real logo entry point is unchanged and is where it always was: the app schema's
|
|
26
|
+
own `branding.logo`, read directly by `AppSidebar` in `@object-ui/app-shell`, plus
|
|
27
|
+
the app schema's top-level `logo`, rendered directly by `AppSchemaRenderer`'s
|
|
28
|
+
default sidebar header. Neither path went through `AppShellBranding`, so nothing
|
|
29
|
+
rendering-visible changes.
|
|
30
|
+
|
|
31
|
+
Migration: a consumer that passes `logo` inside an `AppShellBranding` object literal
|
|
32
|
+
now gets a compile error. Delete the key — it never reached a renderer. To show a
|
|
33
|
+
logo, set it on the app schema's `branding.logo` instead.
|
|
34
|
+
- 29167d5: **Breaking (shipped as `minor`, following the `page-header` `description` retirement):**
|
|
35
|
+
`app-shell` is no longer a component key. `registerLayout()` registered `AppShell` under
|
|
36
|
+
that key with no `inputs`; the registration is gone (objectui#4841, ADR-0049
|
|
37
|
+
enforce-or-remove, remove side, maintainer ruling 2026-08-16).
|
|
38
|
+
|
|
39
|
+
**What it could never do.** Four of `AppShellProps`' seven keys are `React.ReactNode`
|
|
40
|
+
slots — `sidebar`, `navbar`, `children`, `rightRail` — and a JSON document can fill none
|
|
41
|
+
of them, so `{ "type": "app-shell" }` resolved to a component that had exactly two
|
|
42
|
+
outcomes, neither of them a shell. `children` was dropped in silence: `SchemaRenderer`
|
|
43
|
+
strips `children` (and `body`) before spreading a node's keys as props, and `AppShell`
|
|
44
|
+
reads its `children` prop, never `schema.children`, so the `<main>` element rendered
|
|
45
|
+
empty with nothing logged. A schema written into `sidebar` / `navbar` / `rightRail`
|
|
46
|
+
arrived as a plain object React refuses to render, replacing the node with an error box.
|
|
47
|
+
Only `className`, `defaultOpen` and `branding` ever survived the JSON path, i.e. the best
|
|
48
|
+
result JSON could reach was a shell with no navigation, no top bar and an empty content
|
|
49
|
+
area. With no `inputs` declared, `sdui-parser` had no declaration face to compare a node
|
|
50
|
+
against either, so neither outcome was diagnosed.
|
|
51
|
+
|
|
52
|
+
**What changes for an author.** The middle state — parses, resolves, renders nothing — is
|
|
53
|
+
replaced by a named refusal. `SchemaRenderer` now shows its `Unknown component type:
|
|
54
|
+
app-shell` panel (`OBJUI-001`) and `sdui-parser` reports an `error`-severity
|
|
55
|
+
`unknown-component` diagnostic before render.
|
|
56
|
+
|
|
57
|
+
**FROM → TO.** There is no in-place rewrite, because the node never produced a shell.
|
|
58
|
+
Schema authors who want the whole shell from metadata use `app-schema-renderer`
|
|
59
|
+
(`AppSchemaRenderer`), which declares its `inputs` and builds branding and sidebar
|
|
60
|
+
navigation from an `AppSchema` document: `{ "type": "app-shell", … }` →
|
|
61
|
+
`{ "type": "app-schema-renderer", "schema": { … } }`. Everyone else composes in React —
|
|
62
|
+
`AppShell` is **unchanged and still exported** from `@object-ui/layout`, and remains the
|
|
63
|
+
way to build a shell and render JSON pages inside it.
|
|
64
|
+
|
|
65
|
+
Repo-wide scan before removal found no `"type": "app-shell"` node anywhere in
|
|
66
|
+
`objectstack-ai/objectui` or `objectstack-ai/objectstack` at `origin/main` — no example,
|
|
67
|
+
catalog schema, fixture or template authored one. `content/docs/guide/layout.md` is
|
|
68
|
+
updated to state the new fact, and
|
|
69
|
+
`packages/layout/src/__tests__/app-shell-not-a-component-key.test.tsx` pins it on both
|
|
70
|
+
faces (source and live registry) plus the rendered diagnostic.
|
|
71
|
+
- 45f7dcc: **Breaking (shipped as `minor`, following the `app-shell` component-key deregistration):**
|
|
72
|
+
`app-schema-renderer`'s `mobileNavMode` is now declared as the vocabulary the renderer
|
|
73
|
+
implements — `enum: ['drawer', 'bottom_nav']` — instead of free-text `string`, and the
|
|
74
|
+
third member of `MobileNavMode` is retired (objectui#3985, ADR-0049 enforce-or-remove,
|
|
75
|
+
maintainer ruling 2026-08-10).
|
|
76
|
+
|
|
77
|
+
**What used to happen.** The registration declared `{ name: 'mobileNavMode', type:
|
|
78
|
+
'string' }`, so `sdui-parser`'s `checkType` asked only whether the value was a string.
|
|
79
|
+
`mobileNavMode="bottom-nav"` — the hyphenated spelling of the underscored value, and the
|
|
80
|
+
likeliest typo on this key — passed the manifest gate, passed the parser, reached the
|
|
81
|
+
renderer, missed its one equality test, and rendered the drawer. Nothing reported
|
|
82
|
+
anything, at any layer. The declaration was WIDER than the implementation, which is why
|
|
83
|
+
the `invalid-enum` that should have fired never could.
|
|
84
|
+
|
|
85
|
+
**What happens now.** A value outside the vocabulary is an **error**-level `invalid-enum`
|
|
86
|
+
from `validateTree` / `compile`, so a schema-driven author — very often an AI author — is
|
|
87
|
+
stopped at the typo instead of debugging a mode that silently did nothing. The generated
|
|
88
|
+
`sdui-intrinsics.d.ts` narrows from `mobileNavMode?: string` to the two-value union for
|
|
89
|
+
the same reason.
|
|
90
|
+
|
|
91
|
+
**Retirement.** `MobileNavMode` had a third member documented as "collapsed sidebar" with
|
|
92
|
+
**zero read points** in `AppSchemaRenderer`: the only two reads are the `drawer` default
|
|
93
|
+
and the `=== 'bottom_nav'` comparison that gates the bottom bar, so the value was
|
|
94
|
+
behaviourally identical to the default while the union, the JSDoc and `ROADMAP.md`
|
|
95
|
+
presented it as a capability. It is gone from the union and from the published
|
|
96
|
+
vocabulary. Making it real behaviour is an implementation card first — the value comes
|
|
97
|
+
back together with a renderer read point, never as a declaration on its own.
|
|
98
|
+
|
|
99
|
+
**Migration.** Both implemented modes are unchanged; no runtime behaviour moves. A
|
|
100
|
+
TypeScript caller passing the retired literal now fails to compile (it previously
|
|
101
|
+
compiled and rendered the drawer), and a JSON/JSX author writing it — or any other
|
|
102
|
+
out-of-vocabulary value — now gets a validation error where they previously got silence.
|
|
103
|
+
In both cases the value that reproduces the old behaviour exactly is `drawer`.
|
|
104
|
+
- f923b7c: **Breaking (shipped as `minor`, see below):** `@object-ui/layout`'s `<PageHeader>` retires the legacy `description` prop. `subtitle` is now the only spelling for the secondary line.
|
|
105
|
+
|
|
106
|
+
`PageHeader` read `subtitle ?? description`. The alias was not tolerance for a sloppy author — it was the only thing standing between an externally authored `description` and a page that renders its title and silently drops its second line, which is why objectui#3226 refused to delete it: "no in-repo author writes `description`" (true, verified) says nothing about the stored metadata of out-of-repo consumers.
|
|
107
|
+
|
|
108
|
+
**FROM → TO.** JSX call sites: `<PageHeader title="X" description="Y" />` → `<PageHeader title="X" subtitle="Y" />`. Schema authors: `{ "type": "page-header", "description": "Y" }` → `{ "type": "page-header", "subtitle": "Y" }`. Stored stack metadata needs no hand edit — `os migrate meta` rewrites it, and a protocol 17 loader rewrites it on the way in.
|
|
109
|
+
|
|
110
|
+
**Why the read could go now.** The normalization moved upstream, where a contract belongs: protocol 17's ADR-0087 D2 conversion `page-header-subtitle-alias` rewrites a header node's `properties.description` to `properties.subtitle` as the stack loads. The gate on this side was a measurement, not a date — every position a `page-header` node can occupy had to be shown to pass through that rewrite. It did not, at first: measured 2026-08-08 against `@objectstack/spec@17.0.0-rc.5`, the conversion walk reached `pages[].regions[].components[]` and stopped, leaving seven spec-valid header positions unconverted — including `slots.header` on a `kind: 'slotted'` record page, the shape this repo's own slotted-pages guide prescribes (objectstack#6775). With the walk widened by objectstack#6776 (slots) and objectstack PR #7034 (containers nested to any depth: `properties.children`, `items[].children`, `body`, `footer`), all seven convert. Re-measured against `@objectstack/spec@17.0.0-rc.6`, which this package depends on, before the read was deleted.
|
|
111
|
+
|
|
112
|
+
The measurement is now a standing pin rather than a one-off: `packages/layout/src/__tests__/page-header-subtitle-conversion-coverage.test.ts` re-runs all seven positions against the resolved spec build on every test run. If a future spec narrows that reach — or a dependency is pinned back below `17.0.0-rc.6` — it fails there, at the seam, instead of turning into a second line that quietly stops rendering in a consumer's app. The two tests in `page-header-authorable-keys.test.tsx` that pinned the fallback's continued existence were deleted in this same change, as their own SEQUENCING note instructed, and replaced with the opposite assertion: a lone `description` now renders no secondary line.
|
|
113
|
+
|
|
114
|
+
**Not affected, despite the shared word:** the `page` renderer's own `description` prop (the page's prose under the page title) is a live declared key of a different node, untouched here. `@object-ui/app-shell`'s separate `<PageHeader>` uses `description` as its only secondary-line prop and is likewise unchanged.
|
|
115
|
+
|
|
116
|
+
`minor` rather than `major` is deliberate and follows the repo's retirement precedent (PR #3793): all 39 publishable packages sit in one `fixed` group, so a `major` here would carry the whole family to 18.0.0 against an `@objectstack` still on 17 and break the "same major ⇒ compatible" pin between the two repos (AGENTS.md §版本号策略, enforced by `scripts/check-changeset-no-major.mjs`). objectui's own breaking changes ship as `minor` with the break spelled out in the body — which is what the FROM → TO above is.
|
|
117
|
+
- 9c60144: **Breaking (published API):** `NavigationRenderer` no longer accepts `resolveGroupLabel` or `resolveItemLabel`. If your build just broke on one of these props, delete the prop — it never did anything.
|
|
118
|
+
|
|
119
|
+
Both were id-keyed label resolvers on `NavigationRendererProps` (`@object-ui/layout`), typically wired to `useObjectLabel().navGroupLabel` from `@object-ui/i18n` to translate sidebar group and leaf labels from a client translation pack keyed `{ns}.apps.{appName}.navigation.{nodeId}.label`.
|
|
120
|
+
|
|
121
|
+
**They could never fire.** The renderer guards convention-based resolution with `isCustomized` — a case-insensitive "the authored label differs from this branch's comparison target" test. On the `object` / `dashboard` branches the target is the object or dashboard name, and the test is meaningful: it protects an author's custom label (`Projects`) from being overwritten by an `objects.project.label` translation. On the two id-keyed branches the target was the nav node's own **`id`** — `grp_workspace`, `group_sales` — while the label was its text — `Workspace`, `Sales`. Those never compare equal, so the guard was true for every real navigation entry and the resolver beneath it was unreachable. The only node that could have reached it is one whose label is literally its own id.
|
|
122
|
+
|
|
123
|
+
Nothing regresses when they go, because nothing was using them to begin with: **app-navigation localization is owned solely by the server-side `/meta` boundary.** `translateApp` (`@objectstack/spec`, `src/system/i18n-resolver.ts`) rewrites every navigation node's `label` by id, and `@objectstack/rest` applies it before the metadata reaches the client — so nav labels arrive already localized and the client-side path was never the one answering. One owner, not two.
|
|
124
|
+
|
|
125
|
+
**If you wired these hooks to localize navigation, your labels were never being localized by them.** Move the translation to the server side: add it to the app's i18n bundle that `translateApp` reads, keyed by navigation node id. A client-side pack keyed `apps.*.navigation.*.label` changes nothing in the sidebar.
|
|
126
|
+
|
|
127
|
+
Also in this change:
|
|
128
|
+
|
|
129
|
+
- `useObjectLabel().navGroupLabel` (`@object-ui/i18n`) is **kept**, but its docstring no longer promises `"Sales" → "销售"` for sidebar groups — that promise was false, and a live docstring describing an unreachable path is how an agent or a developer ends up wiring a translation pack and receiving silent non-localization. It is now documented for what it is: a plain reader for `{ns}.apps.{appName}.navigation.{groupId}.label` with no first-party caller, pointing at the server boundary for anything nav-related.
|
|
130
|
+
- `UnifiedSidebar` (`@object-ui/app-shell`) drops the two prop wirings, including a `studio` carve-out that existed only to stop `resolveItemLabel` from re-translating an already-translated "Package management" label.
|
|
131
|
+
- The `object` / `dashboard` / `viewName` branches — `resolveObjectLabel`, `resolveDashboardLabel`, `resolveViewLabel` — are untouched and keep both their resolvers and the `isCustomized` guard.
|
|
132
|
+
|
|
133
|
+
### Patch Changes
|
|
134
|
+
|
|
135
|
+
- d442795: AppShell: drop the unused `Sidebar` import. `AppShell` renders the node the caller passes
|
|
136
|
+
in the `sidebar` prop and never constructs a `Sidebar` itself, so the import was dead
|
|
137
|
+
(tree-shaken out of every bundle) and only suggested otherwise to readers. No runtime
|
|
138
|
+
behaviour changes.
|
|
139
|
+
- 8a9dece: `SidebarNav`'s README example teaches the shape the component actually reads.
|
|
140
|
+
|
|
141
|
+
`packages/layout/README.md` — the package's npm landing page, shipped in `files` —
|
|
142
|
+
spelled every nav item `{ label, path, icon: 'home' }`. `NavItem` declares none of
|
|
143
|
+
those three keys: the label is `title`, the target is `href`, and `icon` is a
|
|
144
|
+
`React.ComponentType` rendered as `<item.icon />`, not an icon name. Copied
|
|
145
|
+
verbatim the example produced a sidebar whose every row was unlabelled
|
|
146
|
+
(`<span>{item.title}</span>` reading `undefined`), a `NavLink` with
|
|
147
|
+
`to={undefined}`, and the string `'home'` handed to React as an unknown lowercase
|
|
148
|
+
tag. Both README examples now use `title` / `href` / imported Lucide components,
|
|
149
|
+
and annotate the array as `NavItem[]` so the same class of typo becomes a compile
|
|
150
|
+
error where it is written instead of a blank sidebar at runtime.
|
|
151
|
+
|
|
152
|
+
Adds the props tables the README never carried — `SidebarNavProps`, `NavItem`
|
|
153
|
+
(`badge`, `badgeVariant` and `children` included) and `NavGroup`, plus a grouped
|
|
154
|
+
and nested example — and pins all of it rather than leaving a second surface free
|
|
155
|
+
to rot the same way: the examples are real, type-checked code in
|
|
156
|
+
`readme-sidebar-nav-example.test.ts` asserted to appear verbatim in the README, and
|
|
157
|
+
the tables are compared against the interface keys read out of `SidebarNav.tsx` on
|
|
158
|
+
every run. Also corrects a comment in `side-effects-manifest.test.ts` that named
|
|
159
|
+
`SidebarNav` as the component behind the `navigation-renderer` registration; that
|
|
160
|
+
key belongs to a different component, and `SidebarNav` is registered under no key
|
|
161
|
+
at all.
|
|
162
|
+
|
|
163
|
+
No runtime change — `SidebarNav.tsx` is untouched. This is `patch` rather than a
|
|
164
|
+
no-release declaration because the corrected landing page only reaches npm through
|
|
165
|
+
a publish.
|
|
166
|
+
- 183d09b: Studio 页面设计器不再为 canonical `page:header` 提供 `icon` 编辑框(objectui#3829)
|
|
167
|
+
|
|
168
|
+
`PageHeaderProps.icon` 已在 `@objectstack/spec` 17.0.0 随 ADR-0087 D2 退役
|
|
169
|
+
(objectstack#6946 / PR objectstack#7115):canonical `page:header` 渲染器从未读过它,
|
|
170
|
+
表头的身份由 record chrome(`recordChrome`)与每个 action 自带的 `icon` 承担。退役前
|
|
171
|
+
作者填入的值被静默丢弃,退役后平台按名拒绝整个节点 —— 而设计器仍在提供那个输入框,
|
|
172
|
+
等于教作者写出解析失败的元数据。本次移除该字段与它此时已成孤儿的两条 i18n 键
|
|
173
|
+
(en / zh 同一次改动,两张表的键集保持一致),并把「不得回潮」钉在
|
|
174
|
+
`previews/__tests__/block-config.test.ts`。
|
|
175
|
+
|
|
176
|
+
`@object-ui/layout` 的 `page-header` / `layout:page-header` 别名**保留** `icon` 输入,
|
|
177
|
+
行为不变:那是另一个渲染器,它真读真画(`PageHeader.tsx`),文档与本仓唯一的活 demo
|
|
178
|
+
都写它。变的只是这条声明的**依据** —— 从 spec parity 改述为 renderer-read 事实,并让
|
|
179
|
+
`page-header-authorable-keys` 守卫在派生 spec 键集时跳过墓碑成员,不再因为
|
|
180
|
+
`Object.keys(shape)` 仍列着已退役的 `icon` 而假绿。
|
|
181
|
+
- Updated dependencies [88085e3]
|
|
182
|
+
- Updated dependencies [516663d]
|
|
183
|
+
- Updated dependencies [460c4d0]
|
|
184
|
+
- Updated dependencies [0ae27f7]
|
|
185
|
+
- Updated dependencies [2533ec5]
|
|
186
|
+
- Updated dependencies [78c0f9a]
|
|
187
|
+
- Updated dependencies [bbe8b86]
|
|
188
|
+
- Updated dependencies [8477be5]
|
|
189
|
+
- Updated dependencies [279fb13]
|
|
190
|
+
- Updated dependencies [2e82ab2]
|
|
191
|
+
- Updated dependencies [ad07b65]
|
|
192
|
+
- Updated dependencies [41f498b]
|
|
193
|
+
- Updated dependencies [e1d4251]
|
|
194
|
+
- Updated dependencies [40d3a33]
|
|
195
|
+
- Updated dependencies [8b9dc62]
|
|
196
|
+
- Updated dependencies [1184192]
|
|
197
|
+
- Updated dependencies [a2a9747]
|
|
198
|
+
- Updated dependencies [a1609a6]
|
|
199
|
+
- Updated dependencies [53f23bc]
|
|
200
|
+
- Updated dependencies [c4533dc]
|
|
201
|
+
- Updated dependencies [be60815]
|
|
202
|
+
- Updated dependencies [37f6844]
|
|
203
|
+
- Updated dependencies [93de4f6]
|
|
204
|
+
- Updated dependencies [2b50261]
|
|
205
|
+
- Updated dependencies [384f30d]
|
|
206
|
+
- Updated dependencies [ac600e5]
|
|
207
|
+
- Updated dependencies [97fba31]
|
|
208
|
+
- Updated dependencies [232f61a]
|
|
209
|
+
- Updated dependencies [d374caf]
|
|
210
|
+
- Updated dependencies [5673576]
|
|
211
|
+
- Updated dependencies [c1ef923]
|
|
212
|
+
- Updated dependencies [911ceaa]
|
|
213
|
+
- Updated dependencies [98eab36]
|
|
214
|
+
- Updated dependencies [af5e292]
|
|
215
|
+
- Updated dependencies [3fbbea1]
|
|
216
|
+
- Updated dependencies [7f96b10]
|
|
217
|
+
- Updated dependencies [167ec42]
|
|
218
|
+
- Updated dependencies [616a2a5]
|
|
219
|
+
- Updated dependencies [0046d8f]
|
|
220
|
+
- Updated dependencies [f1d4748]
|
|
221
|
+
- Updated dependencies [b1119ec]
|
|
222
|
+
- Updated dependencies [9f23d2b]
|
|
223
|
+
- Updated dependencies [578e025]
|
|
224
|
+
- Updated dependencies [af025ee]
|
|
225
|
+
- Updated dependencies [598c89a]
|
|
226
|
+
- Updated dependencies [4a0bd17]
|
|
227
|
+
- Updated dependencies [b8b9af4]
|
|
228
|
+
- Updated dependencies [31676be]
|
|
229
|
+
- Updated dependencies [8c0d52e]
|
|
230
|
+
- Updated dependencies [aff10e2]
|
|
231
|
+
- Updated dependencies [70a774b]
|
|
232
|
+
- Updated dependencies [9ce096f]
|
|
233
|
+
- Updated dependencies [e05db88]
|
|
234
|
+
- Updated dependencies [7458a41]
|
|
235
|
+
- Updated dependencies [5ffcc14]
|
|
236
|
+
- Updated dependencies [d971e51]
|
|
237
|
+
- Updated dependencies [97abb24]
|
|
238
|
+
- Updated dependencies [deb157a]
|
|
239
|
+
- Updated dependencies [d2ce342]
|
|
240
|
+
- Updated dependencies [9695da7]
|
|
241
|
+
- Updated dependencies [75444e3]
|
|
242
|
+
- Updated dependencies [58b8346]
|
|
243
|
+
- Updated dependencies [2d0bd16]
|
|
244
|
+
- Updated dependencies [dad51e5]
|
|
245
|
+
- Updated dependencies [1c9c342]
|
|
246
|
+
- Updated dependencies [787c738]
|
|
247
|
+
- Updated dependencies [8396656]
|
|
248
|
+
- Updated dependencies [dbbd38a]
|
|
249
|
+
- Updated dependencies [93fe362]
|
|
250
|
+
- Updated dependencies [dfc6975]
|
|
251
|
+
- Updated dependencies [3cf4de0]
|
|
252
|
+
- Updated dependencies [c9dc811]
|
|
253
|
+
- Updated dependencies [144ef9b]
|
|
254
|
+
- Updated dependencies [138ab04]
|
|
255
|
+
- Updated dependencies [a0b9e91]
|
|
256
|
+
- Updated dependencies [99bd015]
|
|
257
|
+
- @object-ui/types@17.6.0
|
|
258
|
+
- @object-ui/react@17.6.0
|
|
259
|
+
- @object-ui/components@17.6.0
|
|
260
|
+
- @object-ui/core@17.6.0
|
|
261
|
+
|
|
3
262
|
## 17.5.0
|
|
4
263
|
|
|
5
264
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -24,9 +24,9 @@ pnpm add @object-ui/layout
|
|
|
24
24
|
## Registration
|
|
25
25
|
|
|
26
26
|
Importing this package registers its component keys (`page-header`, `page:card`,
|
|
27
|
-
`
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
`responsive-grid`, `navigation-renderer`, `app-schema-renderer`) on the
|
|
28
|
+
`ComponentRegistry` as a module load side effect, so the side-effect-only import
|
|
29
|
+
is enough:
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
32
|
import '@object-ui/layout';
|
|
@@ -43,30 +43,61 @@ prefer to register explicitly.
|
|
|
43
43
|
|
|
44
44
|
### AppShell
|
|
45
45
|
|
|
46
|
-
Complete application shell with
|
|
46
|
+
Complete application shell with a top navbar, a sidebar, and a main content area.
|
|
47
47
|
|
|
48
48
|
```typescript
|
|
49
49
|
import { AppShell } from '@object-ui/layout';
|
|
50
50
|
|
|
51
51
|
<AppShell
|
|
52
|
-
|
|
52
|
+
navbar={<div>Navbar Content</div>}
|
|
53
53
|
sidebar={<div>Sidebar Content</div>}
|
|
54
54
|
>
|
|
55
55
|
<div>Main Content</div>
|
|
56
56
|
</AppShell>
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
The top bar's content goes in `navbar`. `AppShell` renders the `<header>`
|
|
60
|
+
element itself (`src/AppShell.tsx:248`) and `{navbar}` is the only thing that
|
|
61
|
+
fills it (`:249`) — there is no `header` prop. This example used to pass one
|
|
62
|
+
(objectui#4817), and because the component destructures a fixed key list with
|
|
63
|
+
**no rest element** (`:233-241`), the node was built and then dropped on the
|
|
64
|
+
floor: copied verbatim, the snippet rendered an empty top bar and said nothing.
|
|
65
|
+
|
|
66
|
+
Like `SidebarNav` below, `AppShell` is composed in JSX and is **not** on the
|
|
67
|
+
`ComponentRegistry`: four of its seven props are `React.ReactNode` slots that no
|
|
68
|
+
JSON document can fill, so the `app-shell` key was retired in objectui#4841 and
|
|
69
|
+
`{ "type": "app-shell" }` now reports `Unknown component type`. When the whole
|
|
70
|
+
shell has to come from metadata, the key for that is `app-schema-renderer`.
|
|
71
|
+
|
|
72
|
+
#### `AppShellProps`
|
|
73
|
+
|
|
74
|
+
| Prop | Type | Default | Description |
|
|
75
|
+
| --- | --- | --- | --- |
|
|
76
|
+
| `children` | `React.ReactNode` | — (required) | Main content, rendered inside the `<main>` element. |
|
|
77
|
+
| `navbar` | `React.ReactNode` | — | Top bar content. `AppShell` supplies the sticky `<header>` around it, so pass only what goes inside. |
|
|
78
|
+
| `sidebar` | `React.ReactNode` | — | Left sidebar node, rendered as a flex sibling of the content. Pass `SidebarNav`, or your own node. |
|
|
79
|
+
| `rightRail` | `React.ReactNode` | — | Optional right-side rail. It reflows the content beside it rather than overlaying it (ADR-0057 P3a); absent → unchanged single-pane layout. |
|
|
80
|
+
| `className` | `string` | — | Tailwind overrides for the `<main>` content element — **not** for the outer container. |
|
|
81
|
+
| `defaultOpen` | `boolean` | `true` | Initial open state of the underlying Shadcn `SidebarProvider`. |
|
|
82
|
+
| `branding` | `AppShellBranding` | — | App branding, applied by `useAppShellBranding`: `primaryColor` / `accentColor` become CSS custom properties on the document root (re-derived for dark mode), `favicon` sets the icon link's `href`, and `title` sets `document.title`. |
|
|
83
|
+
|
|
59
84
|
### PageHeader
|
|
60
85
|
|
|
61
|
-
Page title block with an optional
|
|
86
|
+
Page title block with an optional subtitle, used at the top of a page's
|
|
62
87
|
content area.
|
|
63
88
|
|
|
64
89
|
```typescript
|
|
65
90
|
import { PageHeader } from '@object-ui/layout';
|
|
66
91
|
|
|
67
|
-
<PageHeader title="Dashboard"
|
|
92
|
+
<PageHeader title="Dashboard" subtitle="View your metrics" />
|
|
68
93
|
```
|
|
69
94
|
|
|
95
|
+
`subtitle` is the only spelling for the secondary line — it is the key
|
|
96
|
+
`@objectstack/spec/ui`'s `PageHeaderProps` declares. The legacy `description`
|
|
97
|
+
alias this component used to read as well was retired in objectui#3789; stored
|
|
98
|
+
metadata still carrying it is rewritten to `subtitle` at load time by the
|
|
99
|
+
ADR-0087 D2 conversion `page-header-subtitle-alias`.
|
|
100
|
+
|
|
70
101
|
> **Rendering a whole `page` node?** That belongs to `PageRenderer` in
|
|
71
102
|
> `@object-ui/components`, which is what the `page` component key resolves to —
|
|
72
103
|
> it handles page types (record/home/app/utility), named regions and page
|
|
@@ -78,17 +109,91 @@ import { PageHeader } from '@object-ui/layout';
|
|
|
78
109
|
Navigation sidebar component with React Router integration.
|
|
79
110
|
|
|
80
111
|
```typescript
|
|
81
|
-
import { SidebarNav } from '@object-ui/layout';
|
|
112
|
+
import { SidebarNav, type NavItem } from '@object-ui/layout';
|
|
113
|
+
import { Home, Settings, Users } from 'lucide-react';
|
|
82
114
|
|
|
83
|
-
const navItems = [
|
|
84
|
-
{
|
|
85
|
-
{
|
|
86
|
-
{
|
|
115
|
+
const navItems: NavItem[] = [
|
|
116
|
+
{ title: 'Dashboard', href: '/dashboard', icon: Home },
|
|
117
|
+
{ title: 'Users', href: '/users', icon: Users },
|
|
118
|
+
{ title: 'Settings', href: '/settings', icon: Settings },
|
|
87
119
|
];
|
|
88
120
|
|
|
89
121
|
<SidebarNav items={navItems} />
|
|
90
122
|
```
|
|
91
123
|
|
|
124
|
+
An item's label is `title` and its target is `href` — and `icon` is a **component**,
|
|
125
|
+
not an icon name: it is rendered as `<item.icon />` (`src/SidebarNav.tsx:60`, `:109`),
|
|
126
|
+
so pass the imported Lucide component itself. This example used to be written with
|
|
127
|
+
`label` / `path` / `icon: 'home'`, none of which `NavItem` declares (objectui#3999);
|
|
128
|
+
copied as-is it produced rows with no label at all, a `NavLink` whose `to` was
|
|
129
|
+
`undefined`, and the string `'home'` handed to React as an unknown lowercase tag.
|
|
130
|
+
Annotating the array as `NavItem[]` is what turns that whole class of typo back into
|
|
131
|
+
a compile error where it is written, instead of a blank sidebar at runtime.
|
|
132
|
+
|
|
133
|
+
#### `SidebarNavProps`
|
|
134
|
+
|
|
135
|
+
| Prop | Type | Default | Description |
|
|
136
|
+
| --- | --- | --- | --- |
|
|
137
|
+
| `items` | `NavItem[] \| NavGroup[]` | — (required) | Flat item list, or grouped sections. The array must be homogeneous: only the **first** element is probed to decide which of the two it is. |
|
|
138
|
+
| `title` | `string` | `'Application'` | Section label shown above a flat `NavItem[]`. Ignored when `items` is a `NavGroup[]` — each group prints its own `label`. |
|
|
139
|
+
| `className` | `string` | — | Tailwind overrides, forwarded to the root `Sidebar`. |
|
|
140
|
+
| `collapsible` | `'offcanvas' \| 'icon' \| 'none'` | `'icon'` | Collapse behaviour of the underlying Shadcn `Sidebar`. |
|
|
141
|
+
| `searchEnabled` | `boolean` | `false` | Renders a search box that filters items by `title` (an item also survives when one of its `children` matches). |
|
|
142
|
+
| `searchPlaceholder` | `string` | `'Search…'` | Placeholder for that search box. |
|
|
143
|
+
|
|
144
|
+
#### `NavItem`
|
|
145
|
+
|
|
146
|
+
| Key | Type | Default | Description |
|
|
147
|
+
| --- | --- | --- | --- |
|
|
148
|
+
| `title` | `string` | — (required) | The visible label, and what search matches against. |
|
|
149
|
+
| `href` | `string` | — (required) | `NavLink` target; also the React key, so keep it unique within its list. Active state is `pathname === href`. |
|
|
150
|
+
| `icon` | `React.ComponentType<{ className?: string }>` | — | The icon **component** (e.g. `Home` from `lucide-react`), not its name. |
|
|
151
|
+
| `badge` | `string \| number` | — | Trailing badge content. Rendered whenever it is not `null`/`undefined`, so `0` shows. |
|
|
152
|
+
| `badgeVariant` | `'default' \| 'destructive' \| 'outline'` | `'default'` | Badge styling. |
|
|
153
|
+
| `children` | `NavItem[]` | — | Nested sub-items. A non-empty list turns the row into a collapsible group: the parent's own `href` is then no longer a link, only the children are. |
|
|
154
|
+
|
|
155
|
+
#### `NavGroup`
|
|
156
|
+
|
|
157
|
+
| Key | Type | Description |
|
|
158
|
+
| --- | --- | --- |
|
|
159
|
+
| `label` | `string` | Section heading printed above the group. |
|
|
160
|
+
| `items` | `NavItem[]` | The group's items — same `NavItem` shape as above, nesting included. |
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { SidebarNav, type NavGroup } from '@object-ui/layout';
|
|
164
|
+
import { FolderOpen, Home, Settings } from 'lucide-react';
|
|
165
|
+
|
|
166
|
+
const navGroups: NavGroup[] = [
|
|
167
|
+
{
|
|
168
|
+
label: 'Workspace',
|
|
169
|
+
items: [
|
|
170
|
+
{ title: 'Dashboard', href: '/dashboard', icon: Home },
|
|
171
|
+
{
|
|
172
|
+
title: 'Projects',
|
|
173
|
+
href: '/projects',
|
|
174
|
+
icon: FolderOpen,
|
|
175
|
+
badge: 3,
|
|
176
|
+
children: [
|
|
177
|
+
{ title: 'Active', href: '/projects/active' },
|
|
178
|
+
{ title: 'Archived', href: '/projects/archived', badge: 'WIP', badgeVariant: 'outline' },
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
label: 'System',
|
|
185
|
+
items: [{ title: 'Settings', href: '/settings', icon: Settings }],
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
<SidebarNav items={navGroups} searchEnabled />
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Note that `SidebarNav` is a plain React component: unlike the keys listed under
|
|
193
|
+
[Registration](#registration) it is **not** on the `ComponentRegistry`, so it is
|
|
194
|
+
composed in JSX rather than authored as a JSON node. Full guide:
|
|
195
|
+
[SidebarNav docs](https://www.objectui.org/docs/layout/sidebar-nav).
|
|
196
|
+
|
|
92
197
|
## Usage with React Router
|
|
93
198
|
|
|
94
199
|
The layout components are designed to work seamlessly with React Router:
|
|
@@ -96,17 +201,18 @@ The layout components are designed to work seamlessly with React Router:
|
|
|
96
201
|
```typescript
|
|
97
202
|
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
98
203
|
import { AppShell, SidebarNav } from '@object-ui/layout';
|
|
204
|
+
import { Home, Users } from 'lucide-react';
|
|
99
205
|
|
|
100
206
|
function App() {
|
|
101
207
|
return (
|
|
102
208
|
<BrowserRouter>
|
|
103
209
|
<AppShell
|
|
104
|
-
|
|
210
|
+
navbar={<div className="p-4">My App</div>}
|
|
105
211
|
sidebar={
|
|
106
212
|
<SidebarNav
|
|
107
213
|
items={[
|
|
108
|
-
{
|
|
109
|
-
{
|
|
214
|
+
{ title: 'Dashboard', href: '/', icon: Home },
|
|
215
|
+
{ title: 'Users', href: '/users', icon: Users },
|
|
110
216
|
]}
|
|
111
217
|
/>
|
|
112
218
|
}
|
|
@@ -123,15 +229,18 @@ function App() {
|
|
|
123
229
|
|
|
124
230
|
## Customization
|
|
125
231
|
|
|
126
|
-
|
|
232
|
+
`AppShell` takes a single `className`, and it lands on the `<main>` content
|
|
233
|
+
element (`src/AppShell.tsx:256`) rather than on the outer container. There is no
|
|
234
|
+
per-slot `headerClassName` / `sidebarClassName` — the navbar and the sidebar are
|
|
235
|
+
nodes **you** build, so style them where you build them:
|
|
127
236
|
|
|
128
237
|
```typescript
|
|
129
238
|
<AppShell
|
|
130
239
|
className="bg-gray-50"
|
|
131
|
-
|
|
132
|
-
|
|
240
|
+
navbar={<div className="border-b px-4">My App</div>}
|
|
241
|
+
sidebar={<div className="bg-white shadow-lg">Sidebar Content</div>}
|
|
133
242
|
>
|
|
134
|
-
|
|
243
|
+
<div>Main Content</div>
|
|
135
244
|
</AppShell>
|
|
136
245
|
```
|
|
137
246
|
|
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { AppComponentSchema, NavigationItem } from '@object-ui/types';
|
|
3
|
-
import { VisibilityEvaluator, PermissionChecker, CapabilityChecker } from './NavigationRenderer';
|
|
4
|
-
/**
|
|
5
|
-
|
|
3
|
+
import { VisibilityEvaluator, PermissionChecker, CapabilityChecker } from './NavigationRenderer.js';
|
|
4
|
+
/**
|
|
5
|
+
* Mobile navigation display mode — the two modes this renderer implements.
|
|
6
|
+
*
|
|
7
|
+
* `drawer` is the default (the sidebar rides in the AppShell's mobile sheet
|
|
8
|
+
* overlay); `bottom_nav` additionally renders the fixed bottom bar. Those are
|
|
9
|
+
* the renderer's only two read points for the prop — the default below and the
|
|
10
|
+
* `=== 'bottom_nav'` comparison that gates the bottom bar — so every value that
|
|
11
|
+
* is not `bottom_nav` produces drawer behaviour.
|
|
12
|
+
*
|
|
13
|
+
* A third member (spelled after the collapsed-sidebar menu button) rode in this
|
|
14
|
+
* union with a JSDoc line promising "collapsed sidebar" and NO read point
|
|
15
|
+
* anywhere, which made it behaviourally identical to `drawer` while reading as
|
|
16
|
+
* a capability. Retired in objectui#3985 under ADR-0049 enforce-or-remove
|
|
17
|
+
* (maintainer ruling 2026-08-10): it never was behaviour, so it is gone from
|
|
18
|
+
* this union and from the published vocabulary rather than being documented as
|
|
19
|
+
* a synonym for the default. Wanting a collapsed-sidebar mode is an
|
|
20
|
+
* implementation card first, and the value comes back with a read point — never
|
|
21
|
+
* as a declaration on its own.
|
|
22
|
+
*/
|
|
23
|
+
export type MobileNavMode = 'drawer' | 'bottom_nav';
|
|
6
24
|
export interface AppSchemaRendererProps {
|
|
7
25
|
/** The AppSchema JSON to render */
|
|
8
26
|
schema: AppComponentSchema;
|
|
@@ -52,8 +70,8 @@ export interface AppSchemaRendererProps {
|
|
|
52
70
|
* - Area switcher when multiple areas are VISIBLE — area visibility is
|
|
53
71
|
* derived from the items inside, not authored (objectui#3311): an area
|
|
54
72
|
* whose items are all gated away is hidden and never auto-activated
|
|
55
|
-
* - Mobile modes: `drawer` (sheet overlay, default)
|
|
56
|
-
* bottom bar)
|
|
73
|
+
* - Mobile modes: `drawer` (sheet overlay, default) and `bottom_nav` (fixed
|
|
74
|
+
* bottom bar) — see `MobileNavMode` for why that list is two long
|
|
57
75
|
* - Evaluates `visible` expressions and `requiredPermissions` on every item
|
|
58
76
|
*
|
|
59
77
|
* @example
|
package/dist/AppShell.d.ts
CHANGED
|
@@ -10,8 +10,6 @@ export interface AppShellBranding {
|
|
|
10
10
|
accentColor?: string;
|
|
11
11
|
/** Favicon URL — replaces the <link rel="icon"> href */
|
|
12
12
|
favicon?: string;
|
|
13
|
-
/** Logo URL — passed to sidebar/navbar via context */
|
|
14
|
-
logo?: string;
|
|
15
13
|
/** Page title suffix (sets document.title) */
|
|
16
14
|
title?: string;
|
|
17
15
|
}
|
|
@@ -100,22 +100,6 @@ export interface NavigationRendererProps {
|
|
|
100
100
|
* as two `商机` rows where one is the list and the other is a Kanban view).
|
|
101
101
|
*/
|
|
102
102
|
resolveViewLabel?: (objectName: string, viewName: string, fallbackLabel: string) => string;
|
|
103
|
-
/**
|
|
104
|
-
* Optional label resolver for navigation group items.
|
|
105
|
-
* Called with `(groupId, fallbackLabel)` for items where
|
|
106
|
-
* `item.type === 'group'` and `item.label` is a plain string.
|
|
107
|
-
* Enables convention-based i18n via
|
|
108
|
-
* `{ns}.apps.{appName}.navigation.{groupId}.label`.
|
|
109
|
-
*/
|
|
110
|
-
resolveGroupLabel?: (groupId: string, fallbackLabel: string) => string;
|
|
111
|
-
/**
|
|
112
|
-
* Optional label resolver for non-object/non-dashboard/non-group nav
|
|
113
|
-
* items (url, page, report, custom). Called with `(itemId, fallbackLabel)`
|
|
114
|
-
* for items that have a plain-string label and a stable `id`.
|
|
115
|
-
* Convention: `{ns}.apps.{appName}.navigation.{itemId}.label` — same
|
|
116
|
-
* key shape as `resolveGroupLabel` so a single i18n helper covers both.
|
|
117
|
-
*/
|
|
118
|
-
resolveItemLabel?: (itemId: string, fallbackLabel: string) => string;
|
|
119
103
|
/**
|
|
120
104
|
* Optional i18n translation function for resolving I18nLabel objects
|
|
121
105
|
* (`{ key, defaultValue }`). When provided, labels are translated
|
|
@@ -213,6 +197,25 @@ export interface NavTemplateContext {
|
|
|
213
197
|
*/
|
|
214
198
|
contextValues?: Record<string, string | null | undefined>;
|
|
215
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* The wire encoding of the declared `runAction` nav slot — ONE definition,
|
|
202
|
+
* sited with `resolveHref` because that is the only thing that writes it.
|
|
203
|
+
*
|
|
204
|
+
* `ObjectNavItemSchema.runAction` (objectstack#7253) declares WHICH action an
|
|
205
|
+
* object nav entry auto-runs on arrival; the URL is how that declaration
|
|
206
|
+
* survives the navigation, because the list surface mounts in a fresh render
|
|
207
|
+
* tree with nothing but the location to read. Naming the param after the slot
|
|
208
|
+
* is deliberate: the slot owns the name, so producer and consumer cannot drift.
|
|
209
|
+
*
|
|
210
|
+
* Before this constant existed, the name was a bare `'runAction'` literal
|
|
211
|
+
* hand-written at both ends — a private convention no schema declared, so
|
|
212
|
+
* `objectui validate` could not see it, `RESERVED_URL_PARAMS` did not list it,
|
|
213
|
+
* and a page could have repurposed the name with nothing to catch the
|
|
214
|
+
* collision. Import this; never re-spell it. `@object-ui/app-shell`'s
|
|
215
|
+
* `urlParams` re-exports it into the reserved registry rather than restating
|
|
216
|
+
* it, so there is still exactly one definition.
|
|
217
|
+
*/
|
|
218
|
+
export declare const NAV_RUN_ACTION_PARAM = "runAction";
|
|
216
219
|
/**
|
|
217
220
|
* Resolve a NavigationItem to an absolute href (relative to `basePath`).
|
|
218
221
|
*
|
|
@@ -268,4 +271,4 @@ export declare function filterNavigationItems(items: NavigationItem[], query: st
|
|
|
268
271
|
* />
|
|
269
272
|
* ```
|
|
270
273
|
*/
|
|
271
|
-
export declare function NavigationRenderer({ items, basePath, evaluateVisibility: evalVis, checkPermission: checkPerm, checkCapability: checkCap, onAction, searchQuery, enablePinning, onPinToggle, enableReorder, onReorder, resolveObjectLabel, resolveDashboardLabel,
|
|
274
|
+
export declare function NavigationRenderer({ items, basePath, evaluateVisibility: evalVis, checkPermission: checkPerm, checkCapability: checkCap, onAction, searchQuery, enablePinning, onPinToggle, enableReorder, onReorder, resolveObjectLabel, resolveDashboardLabel, resolveViewLabel, t: tProp, templateContext, }: NavigationRendererProps): React.JSX.Element;
|
package/dist/PageHeader.d.ts
CHANGED
|
@@ -24,12 +24,19 @@ import { default as React } from 'react';
|
|
|
24
24
|
export interface PageHeaderComponentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
25
25
|
title: string;
|
|
26
26
|
/**
|
|
27
|
-
* Optional secondary line under the title.
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* Optional secondary line under the title. `subtitle` is the only spelling:
|
|
28
|
+
* it is the key `@objectstack/spec/ui`'s `PageHeaderProps` declares, and it
|
|
29
|
+
* resolves {field.path} tokens against the current record context.
|
|
30
|
+
*
|
|
31
|
+
* The legacy `description` alias this component used to read alongside it
|
|
32
|
+
* was retired in objectui#3789, once the ADR-0087 D2 conversion
|
|
33
|
+
* `page-header-subtitle-alias` was measured to reach EVERY spec-valid header
|
|
34
|
+
* position on the load path (regions, slots, and containers nested to any
|
|
35
|
+
* depth — objectstack#6775 / #6776 / PR #7034). Stored metadata authored with
|
|
36
|
+
* `description` is rewritten to `subtitle` before it ever reaches a renderer,
|
|
37
|
+
* so the second line survives without this side holding a second dialect open.
|
|
30
38
|
*/
|
|
31
39
|
subtitle?: string;
|
|
32
|
-
description?: string;
|
|
33
40
|
/**
|
|
34
41
|
* Optional icon for the header chip. Accepts either a string Lucide icon
|
|
35
42
|
* name (resolved via `LazyIcon`, the standard ObjectUI helper) or a
|
|
@@ -66,4 +73,4 @@ export interface PageHeaderComponentProps extends React.HTMLAttributes<HTMLDivEl
|
|
|
66
73
|
};
|
|
67
74
|
};
|
|
68
75
|
}
|
|
69
|
-
export declare function PageHeader({ title, subtitle,
|
|
76
|
+
export declare function PageHeader({ title, subtitle, icon, action, actions, showBack, schema, className, children, ...props }: PageHeaderComponentProps): React.JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* ObjectUI Layout
|
|
3
3
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
4
|
*/
|
|
5
|
-
export * from './PageHeader';
|
|
6
|
-
export * from './AppShell';
|
|
7
|
-
export * from './PageCard';
|
|
8
|
-
export * from './SidebarNav';
|
|
9
|
-
export * from './ResponsiveGrid';
|
|
10
|
-
export * from './NavigationRenderer';
|
|
11
|
-
export * from './AppSchemaRenderer';
|
|
5
|
+
export * from './PageHeader.js';
|
|
6
|
+
export * from './AppShell.js';
|
|
7
|
+
export * from './PageCard.js';
|
|
8
|
+
export * from './SidebarNav.js';
|
|
9
|
+
export * from './ResponsiveGrid.js';
|
|
10
|
+
export * from './NavigationRenderer.js';
|
|
11
|
+
export * from './AppSchemaRenderer.js';
|
|
12
12
|
export declare function registerLayout(): void;
|