@object-ui/layout 17.3.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 +691 -0
- package/README.md +148 -32
- package/dist/AppSchemaRenderer.d.ts +23 -5
- package/dist/AppShell.d.ts +0 -2
- package/dist/NavigationRenderer.d.ts +32 -25
- package/dist/PageHeader.d.ts +12 -5
- package/dist/ResponsiveGrid.d.ts +19 -22
- package/dist/index.d.ts +7 -7
- package/dist/index.js +369 -350
- package/dist/index.umd.cjs +1 -1
- package/package.json +16 -10
package/README.md
CHANGED
|
@@ -17,38 +17,87 @@ pnpm add @object-ui/layout
|
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
**Peer Dependencies:**
|
|
20
|
-
- `react`
|
|
21
|
-
- `react-dom`
|
|
22
|
-
- `react-router-dom`
|
|
20
|
+
- `react` ^18.0.0 || ^19.0.0
|
|
21
|
+
- `react-dom` ^18.0.0 || ^19.0.0
|
|
22
|
+
- `react-router-dom` ^6.0.0 || ^7.0.0
|
|
23
|
+
|
|
24
|
+
## Registration
|
|
25
|
+
|
|
26
|
+
Importing this package registers its component keys (`page-header`, `page:card`,
|
|
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
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import '@object-ui/layout';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
That is a supported entry point, not an accident of the build: `package.json`
|
|
36
|
+
declares the registering modules in `sideEffects`, which is what stops a bundler
|
|
37
|
+
from tree-shaking a side-effect-only import away (objectui#3899 — the manifest
|
|
38
|
+
used to say `"sideEffects": false`, and a bundler honouring it dropped the
|
|
39
|
+
registration silently). `registerLayout()` is also exported for hosts that
|
|
40
|
+
prefer to register explicitly.
|
|
23
41
|
|
|
24
42
|
## Components
|
|
25
43
|
|
|
26
44
|
### AppShell
|
|
27
45
|
|
|
28
|
-
Complete application shell with
|
|
46
|
+
Complete application shell with a top navbar, a sidebar, and a main content area.
|
|
29
47
|
|
|
30
48
|
```typescript
|
|
31
49
|
import { AppShell } from '@object-ui/layout';
|
|
32
50
|
|
|
33
51
|
<AppShell
|
|
34
|
-
|
|
52
|
+
navbar={<div>Navbar Content</div>}
|
|
35
53
|
sidebar={<div>Sidebar Content</div>}
|
|
36
54
|
>
|
|
37
55
|
<div>Main Content</div>
|
|
38
56
|
</AppShell>
|
|
39
57
|
```
|
|
40
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
|
+
|
|
41
84
|
### PageHeader
|
|
42
85
|
|
|
43
|
-
Page title block with an optional
|
|
86
|
+
Page title block with an optional subtitle, used at the top of a page's
|
|
44
87
|
content area.
|
|
45
88
|
|
|
46
89
|
```typescript
|
|
47
90
|
import { PageHeader } from '@object-ui/layout';
|
|
48
91
|
|
|
49
|
-
<PageHeader title="Dashboard"
|
|
92
|
+
<PageHeader title="Dashboard" subtitle="View your metrics" />
|
|
50
93
|
```
|
|
51
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
|
+
|
|
52
101
|
> **Rendering a whole `page` node?** That belongs to `PageRenderer` in
|
|
53
102
|
> `@object-ui/components`, which is what the `page` component key resolves to —
|
|
54
103
|
> it handles page types (record/home/app/utility), named regions and page
|
|
@@ -60,17 +109,91 @@ import { PageHeader } from '@object-ui/layout';
|
|
|
60
109
|
Navigation sidebar component with React Router integration.
|
|
61
110
|
|
|
62
111
|
```typescript
|
|
63
|
-
import { SidebarNav } from '@object-ui/layout';
|
|
112
|
+
import { SidebarNav, type NavItem } from '@object-ui/layout';
|
|
113
|
+
import { Home, Settings, Users } from 'lucide-react';
|
|
64
114
|
|
|
65
|
-
const navItems = [
|
|
66
|
-
{
|
|
67
|
-
{
|
|
68
|
-
{
|
|
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 },
|
|
69
119
|
];
|
|
70
120
|
|
|
71
121
|
<SidebarNav items={navItems} />
|
|
72
122
|
```
|
|
73
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
|
+
|
|
74
197
|
## Usage with React Router
|
|
75
198
|
|
|
76
199
|
The layout components are designed to work seamlessly with React Router:
|
|
@@ -78,17 +201,18 @@ The layout components are designed to work seamlessly with React Router:
|
|
|
78
201
|
```typescript
|
|
79
202
|
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
80
203
|
import { AppShell, SidebarNav } from '@object-ui/layout';
|
|
204
|
+
import { Home, Users } from 'lucide-react';
|
|
81
205
|
|
|
82
206
|
function App() {
|
|
83
207
|
return (
|
|
84
208
|
<BrowserRouter>
|
|
85
209
|
<AppShell
|
|
86
|
-
|
|
210
|
+
navbar={<div className="p-4">My App</div>}
|
|
87
211
|
sidebar={
|
|
88
212
|
<SidebarNav
|
|
89
213
|
items={[
|
|
90
|
-
{
|
|
91
|
-
{
|
|
214
|
+
{ title: 'Dashboard', href: '/', icon: Home },
|
|
215
|
+
{ title: 'Users', href: '/users', icon: Users },
|
|
92
216
|
]}
|
|
93
217
|
/>
|
|
94
218
|
}
|
|
@@ -105,36 +229,28 @@ function App() {
|
|
|
105
229
|
|
|
106
230
|
## Customization
|
|
107
231
|
|
|
108
|
-
|
|
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:
|
|
109
236
|
|
|
110
237
|
```typescript
|
|
111
238
|
<AppShell
|
|
112
239
|
className="bg-gray-50"
|
|
113
|
-
|
|
114
|
-
|
|
240
|
+
navbar={<div className="border-b px-4">My App</div>}
|
|
241
|
+
sidebar={<div className="bg-white shadow-lg">Sidebar Content</div>}
|
|
115
242
|
>
|
|
116
|
-
|
|
243
|
+
<div>Main Content</div>
|
|
117
244
|
</AppShell>
|
|
118
245
|
```
|
|
119
246
|
|
|
120
247
|
## API Reference
|
|
121
248
|
|
|
122
|
-
For detailed API documentation, visit the [Object UI Documentation](https://www.objectui.org/docs/layout).
|
|
123
|
-
|
|
124
|
-
<!-- release-metadata:v3.3.0 -->
|
|
125
|
-
|
|
126
|
-
## Compatibility
|
|
127
|
-
|
|
128
|
-
- **React:** 18.x or 19.x
|
|
129
|
-
- **Node.js:** ≥ 18
|
|
130
|
-
- **TypeScript:** ≥ 5.0 (strict mode)
|
|
131
|
-
- **`@objectstack/spec`:** ^3.3.0
|
|
132
|
-
- **`@objectstack/client`:** ^3.3.0
|
|
133
|
-
- **Tailwind CSS:** ≥ 3.4 (for packages with UI)
|
|
249
|
+
For detailed API documentation, visit the [Object UI Documentation](https://www.objectui.org/docs/layout/app-shell).
|
|
134
250
|
|
|
135
251
|
## Links
|
|
136
252
|
|
|
137
|
-
- 📚 [Documentation](https://www.objectui.org/docs/layout)
|
|
253
|
+
- 📚 [Documentation](https://www.objectui.org/docs/guide/layout)
|
|
138
254
|
- 📦 [npm package](https://www.npmjs.com/package/@object-ui/layout)
|
|
139
255
|
- 📝 [Changelog](./CHANGELOG.md)
|
|
140
256
|
- 🐛 [Report an issue](https://github.com/objectstack-ai/objectui/issues)
|
|
@@ -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
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { NavigationItem } from '@object-ui/types';
|
|
2
|
+
import { NavigationItem, KeyedI18nLabel } from '@object-ui/types';
|
|
3
3
|
/**
|
|
4
4
|
* Callback to evaluate a visibility expression.
|
|
5
5
|
* Return `true` if the item should be visible.
|
|
@@ -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
|
|
@@ -141,14 +125,18 @@ export interface NavigationRendererProps {
|
|
|
141
125
|
export declare function resolveIcon(name?: string): React.ComponentType<any>;
|
|
142
126
|
/**
|
|
143
127
|
* Resolve a NavigationItem label to a plain string.
|
|
144
|
-
*
|
|
145
|
-
*
|
|
128
|
+
*
|
|
129
|
+
* Handles both plain strings and the KEYED i18n form
|
|
130
|
+
* `{ key, defaultValue?, params? }` — named `KeyedI18nLabel` in
|
|
131
|
+
* `@object-ui/types` since #4581, which is what this signature now states
|
|
132
|
+
* instead of a third inline copy of the same object literal. When a `t`
|
|
133
|
+
* function is provided the key is translated via i18next.
|
|
134
|
+
*
|
|
135
|
+
* "Keyed", not the spec's `I18nLabel`: that one is the INLINE LOCALE MAP
|
|
136
|
+
* (`{ en: 'Owner' }`) resolved against a BCP-47 locale, and the two answer
|
|
137
|
+
* wrongly for each other's input, silently (objectui#4167).
|
|
146
138
|
*/
|
|
147
|
-
export declare function resolveLabel(label: string |
|
|
148
|
-
key: string;
|
|
149
|
-
defaultValue?: string;
|
|
150
|
-
params?: Record<string, any>;
|
|
151
|
-
}, t?: (key: string, options?: any) => string): string;
|
|
139
|
+
export declare function resolveLabel(label: string | KeyedI18nLabel, t?: (key: string, options?: any) => string): string;
|
|
152
140
|
/** Guard callbacks for {@link hasVisibleNavigationItems}. */
|
|
153
141
|
export interface NavigationVisibilityOptions {
|
|
154
142
|
/** Evaluator for item `visible` expressions. Defaults to always-visible. */
|
|
@@ -209,6 +197,25 @@ export interface NavTemplateContext {
|
|
|
209
197
|
*/
|
|
210
198
|
contextValues?: Record<string, string | null | undefined>;
|
|
211
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";
|
|
212
219
|
/**
|
|
213
220
|
* Resolve a NavigationItem to an absolute href (relative to `basePath`).
|
|
214
221
|
*
|
|
@@ -264,4 +271,4 @@ export declare function filterNavigationItems(items: NavigationItem[], query: st
|
|
|
264
271
|
* />
|
|
265
272
|
* ```
|
|
266
273
|
*/
|
|
267
|
-
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/ResponsiveGrid.d.ts
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
import { BreakpointColumnMap, BreakpointOrderMap } from '@objectstack/spec/ui';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
*
|
|
4
|
+
* Breakpoint column map (`BreakpointColumnMapSchema`) and breakpoint order map
|
|
5
|
+
* (`BreakpointOrderMapSchema`), both re-exported from `@objectstack/spec/ui`.
|
|
6
|
+
*
|
|
7
|
+
* These were hand copies until objectui#4167, each carrying the word "mirrors"
|
|
8
|
+
* — the doc-comment shape objectstack#4115 catalogues, where the claim is what
|
|
9
|
+
* the next agent reads as canonical and the code is what actually decides. rc.6
|
|
10
|
+
* publishes both names, and both copies happened to still be exact: six
|
|
11
|
+
* optional numbers keyed `xs`…`2xl`, on a `$strict` schema. "Still exact" is
|
|
12
|
+
* the argument FOR binding them, not against — the copies had nothing to
|
|
13
|
+
* protect, so the only thing they could do from here was drift, and a
|
|
14
|
+
* breakpoint the spec adds now arrives instead of silently not existing.
|
|
15
|
+
*
|
|
16
|
+
* `BreakpointOrderMap` has no read point in this package (`ResponsiveGrid`
|
|
17
|
+
* resolves columns only); it is published because `ResponsiveConfigSchema`
|
|
18
|
+
* pairs the two and an author configuring order needs the type. Bound rather
|
|
19
|
+
* than deleted for that reason — deleting a published type is a separate
|
|
20
|
+
* decision from stopping it being a fork.
|
|
17
21
|
*/
|
|
18
|
-
export
|
|
19
|
-
xs?: number;
|
|
20
|
-
sm?: number;
|
|
21
|
-
md?: number;
|
|
22
|
-
lg?: number;
|
|
23
|
-
xl?: number;
|
|
24
|
-
'2xl'?: number;
|
|
25
|
-
}
|
|
22
|
+
export type { BreakpointColumnMap, BreakpointOrderMap };
|
|
26
23
|
export interface ResponsiveGridProps {
|
|
27
24
|
/** Grid column map per breakpoint */
|
|
28
25
|
columns?: BreakpointColumnMap;
|
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;
|