@jfdevelops/react-layout 0.20.0 → 0.22.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/dist/create-config/create-resource-links.cjs +20 -4
- package/dist/create-config/create-resource-links.cjs.map +1 -1
- package/dist/create-config/create-resource-links.d.cts +9 -0
- package/dist/create-config/create-resource-links.d.cts.map +1 -1
- package/dist/create-config/create-resource-links.d.mts +9 -0
- package/dist/create-config/create-resource-links.d.mts.map +1 -1
- package/dist/create-config/create-resource-links.mjs +20 -4
- package/dist/create-config/create-resource-links.mjs.map +1 -1
- package/dist/create-config/define-layout.cjs +173 -1
- package/dist/create-config/define-layout.cjs.map +1 -1
- package/dist/create-config/define-layout.d.cts +174 -18
- package/dist/create-config/define-layout.d.cts.map +1 -1
- package/dist/create-config/define-layout.d.mts +174 -18
- package/dist/create-config/define-layout.d.mts.map +1 -1
- package/dist/create-config/define-layout.mjs +174 -2
- package/dist/create-config/define-layout.mjs.map +1 -1
- package/dist/create-config/for-resources/create-component.d.mts +1 -1
- package/dist/create-config/for-resources/create-for-resources.cjs +1 -1
- package/dist/create-config/for-resources/create-for-resources.mjs +1 -1
- package/dist/create-config/index.d.cts +2 -1
- package/dist/create-config/index.d.mts +2 -1
- package/dist/create-config/shell-context.cjs +22 -0
- package/dist/create-config/shell-context.cjs.map +1 -0
- package/dist/create-config/shell-context.d.cts +18 -0
- package/dist/create-config/shell-context.d.cts.map +1 -0
- package/dist/create-config/shell-context.d.mts +18 -0
- package/dist/create-config/shell-context.d.mts.map +1 -0
- package/dist/create-config/shell-context.mjs +21 -0
- package/dist/create-config/shell-context.mjs.map +1 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.mts +3 -2
- package/dist/resource.d.mts +1 -1
- package/package.json +1 -1
- package/skills/build-react-layouts/SKILL.md +4 -0
- package/skills/build-react-layouts/references/architecture.md +92 -0
|
@@ -7,8 +7,8 @@ import { CreateResourceLinksFn } from "./create-resource-links.mjs";
|
|
|
7
7
|
import { CreateLayoutForResource, CreateResourceLayoutOptions, CreateResourceLayoutOptionsBase } from "./for-resource.mjs";
|
|
8
8
|
import { CreateResourceLayoutForResourcesFn } from "./for-resources/scoped-layout.mjs";
|
|
9
9
|
import { ComposableComponents, ComposableResourceLayout, CreateLayoutComposable, MakeComposable, RequiredPresetLayoutProps } from "@jfdevelops/react-layout-composables";
|
|
10
|
+
import { JSX, ReactNode } from "react";
|
|
10
11
|
import { ResolveLayoutProps, ResolveProps } from "@jfdevelops/react-layout-validator";
|
|
11
|
-
import { JSX } from "react";
|
|
12
12
|
|
|
13
13
|
//#region src/create-config/define-layout.d.ts
|
|
14
14
|
type LayoutIncludeProps<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, Composables extends ComposableComponents> = IncludedProps<MergedLayoutInProps<Resources, Options, Composables>>;
|
|
@@ -114,6 +114,29 @@ type LayoutRenderResourcesAccessor<Resources extends ReadonlyArray<ResourceDefin
|
|
|
114
114
|
/** The resource this layout instance is rendering for. */readonly current: LayoutResourceKey<Resources>;
|
|
115
115
|
};
|
|
116
116
|
type LayoutRenderComposables<Composables extends ComposableComponents> = [keyof Composables] extends [never] ? undefined : Composables;
|
|
117
|
+
/**
|
|
118
|
+
* The `layout` block of a {@link defineResourceLayout} call: the props, the
|
|
119
|
+
* composable map, and the render for a per-resource page component.
|
|
120
|
+
*
|
|
121
|
+
* Extracted so {@link defineResourceLayout.withLayout} can reuse the exact same
|
|
122
|
+
* shape while making `render` optional (see {@link ShellLayoutDefinition}).
|
|
123
|
+
*/
|
|
124
|
+
type LayoutDefinition<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, Composables extends ComposableComponents, IncludeProps extends LayoutIncludeProps<Resources, Options, Composables>, CustomProps extends InPropsObject> = {
|
|
125
|
+
/**
|
|
126
|
+
* The props to pass to the layout.
|
|
127
|
+
*/
|
|
128
|
+
props?: LayoutProps<Resources, Options, Composables, IncludeProps, CustomProps>;
|
|
129
|
+
/**
|
|
130
|
+
* Components used to compose the layout. Invoked per layout instance with
|
|
131
|
+
* a scoped `create` that resolves composable `name` callbacks using the
|
|
132
|
+
* layout's `resource` and `name`.
|
|
133
|
+
*/
|
|
134
|
+
composables?: (create: CreateLayoutComposable<LayoutResourceKey<Resources>>) => Composables;
|
|
135
|
+
/**
|
|
136
|
+
* The render function for the layout.
|
|
137
|
+
*/
|
|
138
|
+
render: (props: LayoutRenderProps<Resources, Options, Composables, IncludeProps, CustomProps>, context: LayoutRenderContext<Resources, Composables>) => JSX.Element;
|
|
139
|
+
};
|
|
117
140
|
type CreateViewMapOptions<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources> = {}, Composables extends ComposableComponents = {}, IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {}, CustomProps extends InPropsObject = {}> = {
|
|
118
141
|
/**
|
|
119
142
|
* An array of valid resource names to support. Nested sub-resource slugs that
|
|
@@ -124,22 +147,7 @@ type CreateViewMapOptions<Resources extends ReadonlyArray<ResourceDefinition>, O
|
|
|
124
147
|
* The options that are passed into the created resource layout.
|
|
125
148
|
*/
|
|
126
149
|
options?: Options;
|
|
127
|
-
layout:
|
|
128
|
-
/**
|
|
129
|
-
* The props to pass to the layout.
|
|
130
|
-
*/
|
|
131
|
-
props?: LayoutProps<Resources, Options, Composables, IncludeProps, CustomProps>;
|
|
132
|
-
/**
|
|
133
|
-
* Components used to compose the layout. Invoked per layout instance with
|
|
134
|
-
* a scoped `create` that resolves composable `name` callbacks using the
|
|
135
|
-
* layout's `resource` and `name`.
|
|
136
|
-
*/
|
|
137
|
-
composables?: (create: CreateLayoutComposable<LayoutResourceKey<Resources>>) => Composables;
|
|
138
|
-
/**
|
|
139
|
-
* The render function for the layout.
|
|
140
|
-
*/
|
|
141
|
-
render: (props: LayoutRenderProps<Resources, Options, Composables, IncludeProps, CustomProps>, context: LayoutRenderContext<Resources, Composables>) => JSX.Element;
|
|
142
|
-
};
|
|
150
|
+
layout: LayoutDefinition<Resources, Options, Composables, IncludeProps, CustomProps>;
|
|
143
151
|
};
|
|
144
152
|
type ResourceLayoutComposition<Name extends string, Composables extends ComposableComponents> = [keyof Composables] extends [never] ? {} : {
|
|
145
153
|
makeComposable: MakeComposable<Composables, Name>;
|
|
@@ -216,8 +224,156 @@ type DefineResourceLayout = DefineResourceLayoutFn & {
|
|
|
216
224
|
* (or `defineResourceLayout.forResources`) without an `as const` assertion.
|
|
217
225
|
*/
|
|
218
226
|
defineResources: DefineResourcesFn;
|
|
227
|
+
/**
|
|
228
|
+
* Like {@link defineResourceLayout}, but also returns a `Shell` component.
|
|
229
|
+
*
|
|
230
|
+
* With plain `defineResourceLayout`, every page is wrapped in its own
|
|
231
|
+
* `createResourceLayout` component, so navigating between resources unmounts
|
|
232
|
+
* one page component and mounts another — the shared chrome the `render`
|
|
233
|
+
* produces (a sidebar, a header, subscriptions, observers) is rebuilt every
|
|
234
|
+
* time. `withLayout` splits that chrome into a `shell` that mounts once,
|
|
235
|
+
* above the router outlet, and stays mounted across navigation; pages mount
|
|
236
|
+
* and unmount inside it and report their resource up automatically.
|
|
237
|
+
*/
|
|
238
|
+
withLayout: DefineResourceLayoutWithLayoutFn;
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* Render context passed as the second argument to
|
|
242
|
+
* {@link ShellLayoutDefinition.render}.
|
|
243
|
+
*
|
|
244
|
+
* The same shape as a per-resource `render` context (`composables`,
|
|
245
|
+
* `resources`, `name`, `inProps`), with two differences that follow from the
|
|
246
|
+
* shell being mounted once above the router outlet rather than per page:
|
|
247
|
+
*
|
|
248
|
+
* - `resource` / `resources.current` are `LayoutResourceKey | undefined`. The
|
|
249
|
+
* shell outlives any single page, so the current resource is whatever the
|
|
250
|
+
* mounted page last reported (or the `resource` prop, or nothing yet).
|
|
251
|
+
* - `children` is the shell's content region. Render it where page content
|
|
252
|
+
* belongs; it is already wrapped so mounted pages report their resource back.
|
|
253
|
+
*/
|
|
254
|
+
type ShellRenderContext<Resources extends ReadonlyArray<ResourceDefinition>, ShellComposables extends ComposableComponents> = {
|
|
255
|
+
composables: LayoutRenderComposables<ShellComposables>;
|
|
256
|
+
inProps: Record<string, unknown>;
|
|
257
|
+
/**
|
|
258
|
+
* The resource currently rendered in the outlet, or `undefined` when no
|
|
259
|
+
* per-resource page is mounted and no `resource` prop was passed.
|
|
260
|
+
*/
|
|
261
|
+
resource: LayoutResourceKey<Resources> | undefined;
|
|
262
|
+
/**
|
|
263
|
+
* Resources accessor for this definition. `current` follows `resource` above
|
|
264
|
+
* and may be `undefined`.
|
|
265
|
+
*/
|
|
266
|
+
resources: LayoutResourcesAccessor<Resources> & {
|
|
267
|
+
readonly current: LayoutResourceKey<Resources> | undefined;
|
|
268
|
+
};
|
|
269
|
+
name: string;
|
|
270
|
+
/**
|
|
271
|
+
* The shell's content region — typically a router `<Outlet />`. Render it
|
|
272
|
+
* where page content belongs.
|
|
273
|
+
*/
|
|
274
|
+
children: ReactNode;
|
|
275
|
+
};
|
|
276
|
+
/**
|
|
277
|
+
* The `shell` block of a {@link defineResourceLayout.withLayout} call: the
|
|
278
|
+
* chrome that mounts once and stays mounted while pages navigate inside it.
|
|
279
|
+
*
|
|
280
|
+
* Mirrors {@link LayoutDefinition} (`props`, `composables`, `render`) so the
|
|
281
|
+
* two blocks read the same, plus an optional `name`.
|
|
282
|
+
*/
|
|
283
|
+
type ShellLayoutDefinition<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, ShellComposables extends ComposableComponents, ShellIncludeProps extends LayoutIncludeProps<Resources, Options, ShellComposables>, ShellCustomProps extends InPropsObject> = {
|
|
284
|
+
/**
|
|
285
|
+
* Stable name for the shell component (React DevTools) and the base for any
|
|
286
|
+
* resource-scoped composable names. Defaults to `'ResourceLayoutShell'`.
|
|
287
|
+
*/
|
|
288
|
+
name?: string;
|
|
289
|
+
props?: LayoutProps<Resources, Options, ShellComposables, ShellIncludeProps, ShellCustomProps>;
|
|
290
|
+
composables?: (create: CreateLayoutComposable<LayoutResourceKey<Resources>>) => ShellComposables;
|
|
291
|
+
render: (props: LayoutRenderProps<Resources, Options, ShellComposables, ShellIncludeProps, ShellCustomProps>, context: ShellRenderContext<Resources, ShellComposables>) => JSX.Element;
|
|
219
292
|
};
|
|
293
|
+
/**
|
|
294
|
+
* Props accepted by the `Shell` component from
|
|
295
|
+
* {@link defineResourceLayout.withLayout}.
|
|
296
|
+
*/
|
|
297
|
+
type ResourceLayoutShellProps<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, ShellComposables extends ComposableComponents, ShellIncludeProps extends LayoutIncludeProps<Resources, Options, ShellComposables>, ShellCustomProps extends InPropsObject> = Show<ResolveProps<ShellCustomProps> & ResolvedIncludedComponentProps<MergedLayoutInProps<Resources, Options, ShellComposables>, ShellIncludeProps> & {
|
|
298
|
+
/**
|
|
299
|
+
* The resource the shell renders for. Overrides the value reported by the
|
|
300
|
+
* page mounted in `children`. Always available — pass it from tests,
|
|
301
|
+
* stories, or a route that renders non-library content but still wants
|
|
302
|
+
* the shell.
|
|
303
|
+
*/
|
|
304
|
+
resource?: LayoutResourceKey<Resources>; /** The shell's content region — typically a router `<Outlet />`. */
|
|
305
|
+
children: ReactNode;
|
|
306
|
+
}>;
|
|
307
|
+
/**
|
|
308
|
+
* The once-mounted application shell returned from
|
|
309
|
+
* {@link defineResourceLayout.withLayout}. Wrap the router outlet with it.
|
|
310
|
+
*/
|
|
311
|
+
type ResourceLayoutShellComponent<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, ShellComposables extends ComposableComponents = {}, ShellIncludeProps extends LayoutIncludeProps<Resources, Options, ShellComposables> = {}, ShellCustomProps extends InPropsObject = {}> = BaseComponent<string, ResourceLayoutShellProps<Resources, Options, ShellComposables, ShellIncludeProps, ShellCustomProps>> & {
|
|
312
|
+
(props: ResourceLayoutShellProps<Resources, Options, ShellComposables, ShellIncludeProps, ShellCustomProps>): JSX.Element;
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* Options for {@link defineResourceLayout.withLayout}: everything
|
|
316
|
+
* {@link defineResourceLayout} accepts, plus a required `shell`, and with the
|
|
317
|
+
* per-resource `layout.render` made optional.
|
|
318
|
+
*/
|
|
319
|
+
type CreateResourceLayoutWithLayoutOptions<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources> = {}, Composables extends ComposableComponents = {}, IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {}, CustomProps extends InPropsObject = {}, ShellComposables extends ComposableComponents = {}, ShellIncludeProps extends LayoutIncludeProps<Resources, Options, ShellComposables> = {}, ShellCustomProps extends InPropsObject = {}> = {
|
|
320
|
+
/**
|
|
321
|
+
* An array of valid resource names to support. Nested sub-resource slugs that
|
|
322
|
+
* collide with config keys (`component`, `detail`, `new`, …) are reserved.
|
|
323
|
+
*/
|
|
324
|
+
resources: AssertUnreservedResources<Resources>;
|
|
325
|
+
/**
|
|
326
|
+
* The options that are passed into the created resource layout. Shared by the
|
|
327
|
+
* shell and the per-resource layout, so an `include` on either side can draw
|
|
328
|
+
* from the same definitions.
|
|
329
|
+
*/
|
|
330
|
+
options?: Options;
|
|
331
|
+
/**
|
|
332
|
+
* The once-mounted shell. The returned `Shell` wraps the router outlet and
|
|
333
|
+
* stays mounted across resource navigation, so its composables (a persistent
|
|
334
|
+
* sidebar, header, breadcrumb container, …) keep their state and DOM while
|
|
335
|
+
* pages mount and unmount inside it.
|
|
336
|
+
*/
|
|
337
|
+
shell: ShellLayoutDefinition<Resources, Options, ShellComposables, ShellIncludeProps, ShellCustomProps>;
|
|
338
|
+
/**
|
|
339
|
+
* Per-resource content. Optional here: when the shell renders the whole
|
|
340
|
+
* chrome, a page is just a slot — omit `render` and the generated component
|
|
341
|
+
* renders its own `children` into the shell's outlet. Provide it to give a
|
|
342
|
+
* resource its own header, actions, or per-page structure.
|
|
343
|
+
*/
|
|
344
|
+
layout?: Omit<LayoutDefinition<Resources, Options, Composables, IncludeProps, CustomProps>, 'render'> & {
|
|
345
|
+
render?: LayoutDefinition<Resources, Options, Composables, IncludeProps, CustomProps>['render'];
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* {@link DefinedResourceLayout} plus the once-mounted `Shell`.
|
|
350
|
+
*/
|
|
351
|
+
type DefinedResourceLayoutWithShell<Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources>, Composables extends ComposableComponents = {}, IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {}, CustomProps extends InPropsObject = {}, ShellComposables extends ComposableComponents = {}, ShellIncludeProps extends LayoutIncludeProps<Resources, Options, ShellComposables> = {}, ShellCustomProps extends InPropsObject = {}> = DefinedResourceLayout<Resources, Options, Composables, IncludeProps, CustomProps> & {
|
|
352
|
+
/**
|
|
353
|
+
* The application shell. Mount it once, wrapping the router outlet:
|
|
354
|
+
*
|
|
355
|
+
* ```tsx
|
|
356
|
+
* function AdminRoute() {
|
|
357
|
+
* const resource = Route.useParams({ select: (p) => p.resource });
|
|
358
|
+
* return (
|
|
359
|
+
* <Shell resource={resource}>
|
|
360
|
+
* <Outlet />
|
|
361
|
+
* </Shell>
|
|
362
|
+
* );
|
|
363
|
+
* }
|
|
364
|
+
* ```
|
|
365
|
+
*
|
|
366
|
+
* Passing `resource` is optional: a page created by `createResourceLayout`
|
|
367
|
+
* reports its own resource to the shell automatically. Pass it for routes
|
|
368
|
+
* that render non-library content, or in tests and stories.
|
|
369
|
+
*/
|
|
370
|
+
Shell: ResourceLayoutShellComponent<Resources, Options, ShellComposables, ShellIncludeProps, ShellCustomProps>;
|
|
371
|
+
};
|
|
372
|
+
/**
|
|
373
|
+
* Signature of {@link defineResourceLayout.withLayout}.
|
|
374
|
+
*/
|
|
375
|
+
type DefineResourceLayoutWithLayoutFn = <const Resources extends ReadonlyArray<ResourceDefinition>, Options extends InPropsDefinition<Resources> = {}, Composables extends ComposableComponents = {}, const IncludeProps extends LayoutIncludeProps<Resources, Options, Composables> = {}, CustomProps extends InPropsObject = {}, ShellComposables extends ComposableComponents = {}, const ShellIncludeProps extends LayoutIncludeProps<Resources, Options, ShellComposables> = {}, ShellCustomProps extends InPropsObject = {}>(options: CreateResourceLayoutWithLayoutOptions<Resources, Options, Composables, IncludeProps, CustomProps, ShellComposables, ShellIncludeProps, ShellCustomProps>) => DefinedResourceLayoutWithShell<Resources, Options, Composables, IncludeProps, CustomProps, ShellComposables, ShellIncludeProps, ShellCustomProps>;
|
|
220
376
|
declare const defineResourceLayout: DefineResourceLayout;
|
|
221
377
|
//#endregion
|
|
222
|
-
export { CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourcesFn, LayoutIncludeProps, LayoutProps, LayoutPropsForResource, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutComponent, ResourceSelection, defineResourceLayout };
|
|
378
|
+
export { CreateResourceLayoutFn, CreateResourceLayoutMakeComposableOptions, CreateResourceLayoutWithLayoutOptions, DefineResourceLayout, DefineResourceLayoutFn, DefineResourceLayoutForResources, DefineResourceLayoutForResourcesFactory, DefineResourceLayoutWithLayoutFn, DefineResourcesFn, DefinedResourceLayoutWithShell, LayoutIncludeProps, LayoutProps, LayoutPropsForResource, LayoutRenderResourcesAccessor, LayoutResourcesAccessor, ResourceLayoutComponent, ResourceLayoutShellComponent, ResourceLayoutShellProps, ResourceSelection, ShellLayoutDefinition, ShellRenderContext, defineResourceLayout };
|
|
223
379
|
//# sourceMappingURL=define-layout.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-layout.d.mts","names":[],"sources":["../../src/create-config/define-layout.tsx"],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"define-layout.d.mts","names":[],"sources":["../../src/create-config/define-layout.tsx"],"mappings":"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"}
|
|
@@ -7,9 +7,11 @@ import { createResourceConfig } from "./get-component.mjs";
|
|
|
7
7
|
import { createResourceLinksFn } from "./create-resource-links.mjs";
|
|
8
8
|
import { createForResource } from "./for-resource.mjs";
|
|
9
9
|
import { createForResources } from "./for-resources/create-for-resources.mjs";
|
|
10
|
+
import { ResourceLayoutShellPublisherContext, useResourceLayoutShellPublisher } from "./shell-context.mjs";
|
|
10
11
|
import { LayoutComposablePresetProvider, collectComposablePresetEntries, makeComposable, resolveLayoutComposables } from "@jfdevelops/react-layout-composables";
|
|
12
|
+
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
11
13
|
import { createPrimitivePropBuilder, createProp, resolvePropDefinitionValues, validateProps } from "@jfdevelops/react-layout-validator";
|
|
12
|
-
import { jsx } from "react/jsx-runtime";
|
|
14
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
13
15
|
|
|
14
16
|
//#region src/create-config/define-layout.tsx
|
|
15
17
|
function createResourceSelection(definitions) {
|
|
@@ -96,6 +98,7 @@ function assertUnreservedResourceSlugs(resources, owner) {
|
|
|
96
98
|
}
|
|
97
99
|
function defineResourceLayoutImpl(options) {
|
|
98
100
|
const { options: inProps = {}, resources, layout } = options;
|
|
101
|
+
const shellId = options.shellId;
|
|
99
102
|
assertUnreservedResourceSlugs(resources);
|
|
100
103
|
const resourcesAccessor = createLayoutResourcesAccessor(resources);
|
|
101
104
|
const normalizedResources = normalizeResources(resources);
|
|
@@ -144,6 +147,11 @@ function defineResourceLayoutImpl(options) {
|
|
|
144
147
|
inProps: splitInProps
|
|
145
148
|
};
|
|
146
149
|
function Component(props) {
|
|
150
|
+
const publishResource = useResourceLayoutShellPublisher();
|
|
151
|
+
useLayoutEffect(() => {
|
|
152
|
+
publishResource?.(layoutContext.resource, shellId);
|
|
153
|
+
return () => publishResource?.(void 0, shellId);
|
|
154
|
+
}, [publishResource, layoutContext.resource]);
|
|
147
155
|
const validatedProps = validateProps(resolvedLayoutProps, props, { ...validationContext });
|
|
148
156
|
const includedPropKeys = Object.keys(includeLayoutProps ?? {});
|
|
149
157
|
const includedPropDefinitions = pick(mergedResolvedInProps, includedPropKeys);
|
|
@@ -247,9 +255,173 @@ function defineResourceLayoutForResources(...baseResources) {
|
|
|
247
255
|
});
|
|
248
256
|
});
|
|
249
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Builds the `Shell` component. Kept beside {@link defineResourceLayoutImpl} so
|
|
260
|
+
* it can reuse the same private prop-resolution helpers.
|
|
261
|
+
*
|
|
262
|
+
* Unlike a per-resource component, the shell re-reads the current resource on
|
|
263
|
+
* every render (reported by the mounted page) so resource-scoped composable
|
|
264
|
+
* *names* can update. Composable *component identities* are resolved once and
|
|
265
|
+
* kept stable: React reconciles by element type, so recreating
|
|
266
|
+
* `composables.Layout` each render would remount wrapWith targets, sidebar
|
|
267
|
+
* state, and the outlet. Display names are synced onto those stable functions
|
|
268
|
+
* when the resource changes.
|
|
269
|
+
*
|
|
270
|
+
* @param shellId - Identity of the owning `withLayout` definition. The shell
|
|
271
|
+
* only accepts resource reports tagged with this id, so a page or pane from a
|
|
272
|
+
* different definition rendered in the outlet cannot corrupt its state.
|
|
273
|
+
*/
|
|
274
|
+
function createResourceLayoutShellComponent(resources, inProps, shell, shellId) {
|
|
275
|
+
const shellName = shell.name ?? "ResourceLayoutShell";
|
|
276
|
+
const resourceKeys = Object.keys(normalizeResources(resources));
|
|
277
|
+
const resourcesEnum = createPrimitivePropBuilder("string").enum(resourceKeys);
|
|
278
|
+
const { resolvedInProps, splitInProps } = splitLayoutInProps(typeof inProps === "function" ? inProps({
|
|
279
|
+
resource: resourcesEnum,
|
|
280
|
+
name: createProp.string().literal(shellName)
|
|
281
|
+
}) : inProps);
|
|
282
|
+
const includeShellProps = shell.props?.include;
|
|
283
|
+
const includeShellPropKeys = Object.keys(includeShellProps ?? {});
|
|
284
|
+
const shellCustomDefinitions = { ...shell.props?.custom ?? {} };
|
|
285
|
+
function syncShellComposableDisplayNames(stable, resource) {
|
|
286
|
+
if (!shell.composables) return;
|
|
287
|
+
const named = resolveLayoutComposables(shell.composables, {
|
|
288
|
+
resource,
|
|
289
|
+
name: shellName,
|
|
290
|
+
capitalize
|
|
291
|
+
});
|
|
292
|
+
for (const [key, component] of Object.entries(named)) {
|
|
293
|
+
const stableComponent = stable[key];
|
|
294
|
+
if (typeof stableComponent === "function" && typeof component === "function" && "displayName" in component) stableComponent.displayName = component.displayName;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function Shell(props) {
|
|
298
|
+
const { children: outlet, resource: resourceProp } = props;
|
|
299
|
+
const [reportedResource, setReportedResource] = useState(void 0);
|
|
300
|
+
const publishResource = useCallback((resource, ownerId) => {
|
|
301
|
+
if (ownerId !== shellId) return;
|
|
302
|
+
setReportedResource(resource);
|
|
303
|
+
}, []);
|
|
304
|
+
const resource = resourceProp ?? reportedResource;
|
|
305
|
+
const shellChildren = useMemo(() => /* @__PURE__ */ jsx(ResourceLayoutShellPublisherContext.Provider, {
|
|
306
|
+
value: publishResource,
|
|
307
|
+
children: outlet
|
|
308
|
+
}), [outlet, publishResource]);
|
|
309
|
+
const composablesRef = useRef(void 0);
|
|
310
|
+
if (shell.composables) {
|
|
311
|
+
const nameContextResource = resource ?? "";
|
|
312
|
+
if (!composablesRef.current) composablesRef.current = resolveLayoutComposables(shell.composables, {
|
|
313
|
+
resource: nameContextResource,
|
|
314
|
+
name: shellName,
|
|
315
|
+
capitalize
|
|
316
|
+
});
|
|
317
|
+
else syncShellComposableDisplayNames(composablesRef.current, nameContextResource);
|
|
318
|
+
}
|
|
319
|
+
const resolvedComposables = composablesRef.current;
|
|
320
|
+
const validationContext = {
|
|
321
|
+
layoutName: shellName,
|
|
322
|
+
resource: resource ?? ""
|
|
323
|
+
};
|
|
324
|
+
const mergedResolvedInProps = { ...resolvedInProps };
|
|
325
|
+
for (const { props: presetPropDefinitions } of collectComposablePresetEntries(resolvedComposables)) Object.assign(mergedResolvedInProps, presetPropDefinitions);
|
|
326
|
+
const includedPropDefinitions = pick(mergedResolvedInProps, includeShellPropKeys);
|
|
327
|
+
const includedPropValues = { ...resolvePropDefinitionValues(includedPropDefinitions) };
|
|
328
|
+
for (const key of includeShellPropKeys) {
|
|
329
|
+
const definition = mergedResolvedInProps[key];
|
|
330
|
+
const behavior = includeShellProps?.[key];
|
|
331
|
+
const callSiteValue = allowsComponentPassthrough(behavior) ? readLayoutOptionValue(key, definition, props) : void 0;
|
|
332
|
+
const configValue = allowsConfigPassthrough(behavior) ? readLayoutOptionValue(key, definition, {
|
|
333
|
+
...includedPropValues,
|
|
334
|
+
...splitInProps
|
|
335
|
+
}) : void 0;
|
|
336
|
+
const splitValue = key in splitInProps ? splitInProps[key] : void 0;
|
|
337
|
+
const value = callSiteValue ?? configValue ?? splitValue;
|
|
338
|
+
if (value !== void 0) includedPropValues[key] = value;
|
|
339
|
+
}
|
|
340
|
+
const composablePresetProps = Object.fromEntries(collectComposablePresetEntries(resolvedComposables).map(({ key, props: presetPropDefinitions }) => {
|
|
341
|
+
const entries = Object.entries(presetPropDefinitions);
|
|
342
|
+
return [key, validateProps(Object.fromEntries(entries.filter(([propKey]) => {
|
|
343
|
+
const behavior = includeShellProps?.[propKey];
|
|
344
|
+
if (behavior === void 0) return true;
|
|
345
|
+
if (allowsComponentPassthrough(behavior)) return true;
|
|
346
|
+
if (allowsConfigPassthrough(behavior)) return includedPropValues[propKey] !== void 0;
|
|
347
|
+
return false;
|
|
348
|
+
})), Object.fromEntries(entries.flatMap(([propKey]) => {
|
|
349
|
+
if (propKey in props) return [[propKey, props[propKey]]];
|
|
350
|
+
if (includedPropValues[propKey] !== void 0) return [[propKey, includedPropValues[propKey]]];
|
|
351
|
+
return [];
|
|
352
|
+
})), validationContext)];
|
|
353
|
+
}));
|
|
354
|
+
const validatedCustomProps = validateProps(shellCustomDefinitions, props, validationContext);
|
|
355
|
+
const requiredIncludedDefinitions = Object.fromEntries(Object.entries(includedPropDefinitions).filter(([key]) => {
|
|
356
|
+
const behavior = includeShellProps?.[key];
|
|
357
|
+
if (!isIncludedPropRequired(behavior)) return false;
|
|
358
|
+
if (allowsComponentPassthrough(behavior)) return true;
|
|
359
|
+
return includedPropValues[key] !== void 0;
|
|
360
|
+
}));
|
|
361
|
+
const optionalIncludedDefinitions = Object.fromEntries(Object.entries(includedPropDefinitions).filter(([key]) => !isIncludedPropRequired(includeShellProps?.[key]) && includedPropValues[key] !== void 0));
|
|
362
|
+
const validatedIncludedProps = validateProps({
|
|
363
|
+
...requiredIncludedDefinitions,
|
|
364
|
+
...optionalIncludedDefinitions
|
|
365
|
+
}, includedPropValues, validationContext);
|
|
366
|
+
const renderIncludedProps = Object.fromEntries(includeShellPropKeys.flatMap((key) => key in validatedIncludedProps ? [[toLayoutRenderPropKey(key, mergedResolvedInProps[key]), validatedIncludedProps[key]]] : []));
|
|
367
|
+
const renderProps = {
|
|
368
|
+
...validatedCustomProps,
|
|
369
|
+
...renderIncludedProps
|
|
370
|
+
};
|
|
371
|
+
const renderContext = {
|
|
372
|
+
composables: resolvedComposables,
|
|
373
|
+
resource,
|
|
374
|
+
resources: createLayoutRenderResourcesAccessor(resources, resource),
|
|
375
|
+
name: shellName,
|
|
376
|
+
inProps: splitInProps,
|
|
377
|
+
children: shellChildren
|
|
378
|
+
};
|
|
379
|
+
const rendered = shell.render(renderProps, renderContext);
|
|
380
|
+
return resolvedComposables ? /* @__PURE__ */ jsx(LayoutComposablePresetProvider, {
|
|
381
|
+
value: composablePresetProps,
|
|
382
|
+
children: rendered
|
|
383
|
+
}) : rendered;
|
|
384
|
+
}
|
|
385
|
+
return Object.assign(Shell, {
|
|
386
|
+
displayName: shellName,
|
|
387
|
+
props: void 0
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Implementation of {@link defineResourceLayout.withLayout}. Delegates the
|
|
392
|
+
* config / links / `createResourceLayout` pieces to {@link defineResourceLayoutImpl}
|
|
393
|
+
* and adds the {@link createResourceLayoutShellComponent | Shell}.
|
|
394
|
+
*/
|
|
395
|
+
function defineResourceLayoutWithLayoutImpl(options) {
|
|
396
|
+
const { shell, layout, resources, options: inProps } = options;
|
|
397
|
+
const resolvedLayout = layout?.render ? layout : {
|
|
398
|
+
...layout,
|
|
399
|
+
props: {
|
|
400
|
+
...layout?.props,
|
|
401
|
+
custom: {
|
|
402
|
+
children: createProp.component({ type: "ReactNode" }).optional(),
|
|
403
|
+
...layout?.props?.custom ?? {}
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
render: (pageProps) => /* @__PURE__ */ jsx(Fragment, { children: pageProps.children ?? null })
|
|
407
|
+
};
|
|
408
|
+
const shellId = Symbol("resourceLayoutShell");
|
|
409
|
+
const base = defineResourceLayoutImpl({
|
|
410
|
+
resources,
|
|
411
|
+
options: inProps,
|
|
412
|
+
layout: resolvedLayout,
|
|
413
|
+
shellId
|
|
414
|
+
});
|
|
415
|
+
const Shell = createResourceLayoutShellComponent(resources, inProps ?? {}, shell, shellId);
|
|
416
|
+
return {
|
|
417
|
+
...base,
|
|
418
|
+
Shell
|
|
419
|
+
};
|
|
420
|
+
}
|
|
250
421
|
const defineResourceLayout = Object.assign(defineResourceLayoutImpl, {
|
|
251
422
|
forResources: defineResourceLayoutForResources,
|
|
252
|
-
defineResources
|
|
423
|
+
defineResources,
|
|
424
|
+
withLayout: defineResourceLayoutWithLayoutImpl
|
|
253
425
|
});
|
|
254
426
|
|
|
255
427
|
//#endregion
|