@object-ui/layout 17.2.0 → 17.5.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/README.md CHANGED
@@ -17,9 +17,27 @@ pnpm add @object-ui/layout
17
17
  ```
18
18
 
19
19
  **Peer Dependencies:**
20
- - `react` >= 18.0.0
21
- - `react-dom` >= 18.0.0
22
- - `react-router-dom` >= 6.0.0
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
+ `app-shell`, `responsive-grid`, `navigation-renderer`, `app-schema-renderer`) on
28
+ the `ComponentRegistry` as a module load side effect, so the side-effect-only
29
+ import 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
 
@@ -119,22 +137,11 @@ All components accept `className` prop for Tailwind customization:
119
137
 
120
138
  ## API Reference
121
139
 
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)
140
+ For detailed API documentation, visit the [Object UI Documentation](https://www.objectui.org/docs/layout/app-shell).
134
141
 
135
142
  ## Links
136
143
 
137
- - 📚 [Documentation](https://www.objectui.org/docs/layout)
144
+ - 📚 [Documentation](https://www.objectui.org/docs/guide/layout)
138
145
  - 📦 [npm package](https://www.npmjs.com/package/@object-ui/layout)
139
146
  - 📝 [Changelog](./CHANGELOG.md)
140
147
  - 🐛 [Report an issue](https://github.com/objectstack-ai/objectui/issues)
@@ -49,7 +49,9 @@ export interface AppSchemaRendererProps {
49
49
  * Responsibilities:
50
50
  * - Reads `name`, `title`, `description`, `logo`, `favicon` for branding
51
51
  * - Renders sidebar navigation from `navigation` or `areas[].navigation`
52
- * - Area switcher when multiple `areas` are defined
52
+ * - Area switcher when multiple areas are VISIBLE — area visibility is
53
+ * derived from the items inside, not authored (objectui#3311): an area
54
+ * whose items are all gated away is hidden and never auto-activated
53
55
  * - Mobile modes: `drawer` (sheet overlay, default), `bottom_nav` (fixed
54
56
  * bottom bar), `hamburger` (collapsed sidebar)
55
57
  * - Evaluates `visible` expressions and `requiredPermissions` on every item
@@ -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.
@@ -141,14 +141,58 @@ export interface NavigationRendererProps {
141
141
  export declare function resolveIcon(name?: string): React.ComponentType<any>;
142
142
  /**
143
143
  * Resolve a NavigationItem label to a plain string.
144
- * Handles both plain strings and I18nLabel objects { key, defaultValue }.
145
- * When a `t` function is provided, I18nLabel objects are translated via i18next.
144
+ *
145
+ * Handles both plain strings and the KEYED i18n form
146
+ * `{ key, defaultValue?, params? }` — named `KeyedI18nLabel` in
147
+ * `@object-ui/types` since #4581, which is what this signature now states
148
+ * instead of a third inline copy of the same object literal. When a `t`
149
+ * function is provided the key is translated via i18next.
150
+ *
151
+ * "Keyed", not the spec's `I18nLabel`: that one is the INLINE LOCALE MAP
152
+ * (`{ en: 'Owner' }`) resolved against a BCP-47 locale, and the two answer
153
+ * wrongly for each other's input, silently (objectui#4167).
154
+ */
155
+ export declare function resolveLabel(label: string | KeyedI18nLabel, t?: (key: string, options?: any) => string): string;
156
+ /** Guard callbacks for {@link hasVisibleNavigationItems}. */
157
+ export interface NavigationVisibilityOptions {
158
+ /** Evaluator for item `visible` expressions. Defaults to always-visible. */
159
+ evaluateVisibility?: VisibilityEvaluator;
160
+ /** Checker for item `requiredPermissions`. Defaults to always-permitted. */
161
+ checkPermission?: PermissionChecker;
162
+ /** Checker for `requiresObject` / `requiresService`. Defaults to pass. */
163
+ checkCapability?: CapabilityChecker;
164
+ /**
165
+ * Whether the host wires an `onAction` dispatcher. Without one, `action`
166
+ * items are not rendered at all (framework#4509 — a nav entry that looks
167
+ * clickable and silently does nothing is worse than an absent one), so
168
+ * they cannot carry an area's visibility either. Defaults to `false`,
169
+ * matching a renderer with no `onAction` prop.
170
+ */
171
+ hasActionHandler?: boolean;
172
+ }
173
+ /**
174
+ * Whether a navigation tree contains at least one item that would actually
175
+ * render under the given guards — the exact guards `NavigationItemRenderer`
176
+ * applies per item: the `visible` expression, `requiredPermissions`, the
177
+ * `requiresObject` / `requiresService` runtime-capability gates, and (for
178
+ * `action` items) the presence of an action dispatcher.
179
+ *
180
+ * Non-content nodes never count: a `separator` is a visual divider, and a
181
+ * `group` counts only through its children — a group whose children are all
182
+ * gated away contributes nothing a user can navigate to.
183
+ *
184
+ * This is the predicate behind DERIVED area visibility (objectui#3311).
185
+ * `@objectstack/spec` 17.0.0 retired the authorable area-level `visible` /
186
+ * `requiredPermissions` (`AREA_VISIBLE_RETIRED` /
187
+ * `AREA_REQUIRED_PERMISSIONS_RETIRED`): an area is a layout grouping, not an
188
+ * access boundary. What replaces those keys is not a new key but this
189
+ * derivation: an area is visible iff something inside it is. Because it is
190
+ * computed from the same guards that decide what renders, it can never
191
+ * disagree with the rendered navigation — and there is nothing for a
192
+ * metadata author to get wrong. An area with no items at all derives the
193
+ * same way (no visible item → hidden).
146
194
  */
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;
195
+ export declare function hasVisibleNavigationItems(items: NavigationItem[], options?: NavigationVisibilityOptions): boolean;
152
196
  /**
153
197
  * Lightweight template-variable context for nav items that target a
154
198
  * specific record / org. The shell injects the signed-in user id and
@@ -1,28 +1,25 @@
1
1
  import { default as React } from 'react';
2
+ import { BreakpointColumnMap, BreakpointOrderMap } from '@objectstack/spec/ui';
2
3
  /**
3
- * Spec-aligned breakpoint column map (mirrors @objectstack/spec BreakpointColumnMapSchema).
4
- * Maps breakpoint names to grid column counts (1-12).
5
- */
6
- export interface BreakpointColumnMap {
7
- xs?: number;
8
- sm?: number;
9
- md?: number;
10
- lg?: number;
11
- xl?: number;
12
- '2xl'?: number;
13
- }
14
- /**
15
- * Spec-aligned breakpoint order map (mirrors @objectstack/spec BreakpointOrderMapSchema).
16
- * Maps breakpoint names to display order numbers.
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 interface BreakpointOrderMap {
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;