@cohesivesystems/presentation-react 0.1.0-alpha.1

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.
Files changed (252) hide show
  1. package/LICENSE +55 -0
  2. package/dist/collection-chrome-slot-renderer-registry.d.ts +12 -0
  3. package/dist/collection-chrome-slot-renderer-registry.d.ts.map +1 -0
  4. package/dist/collection-chrome-slot-renderer-registry.js +12 -0
  5. package/dist/collection-chrome-slot-renderer-registry.js.map +1 -0
  6. package/dist/collection-selection-state-context.d.ts +6 -0
  7. package/dist/collection-selection-state-context.d.ts.map +1 -0
  8. package/dist/collection-selection-state-context.js +25 -0
  9. package/dist/collection-selection-state-context.js.map +1 -0
  10. package/dist/collection-selection-state.d.ts +3 -0
  11. package/dist/collection-selection-state.d.ts.map +1 -0
  12. package/dist/collection-selection-state.js +52 -0
  13. package/dist/collection-selection-state.js.map +1 -0
  14. package/dist/document-workspace-runtime.d.ts +262 -0
  15. package/dist/document-workspace-runtime.d.ts.map +1 -0
  16. package/dist/document-workspace-runtime.js +699 -0
  17. package/dist/document-workspace-runtime.js.map +1 -0
  18. package/dist/index.d.ts +51 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +51 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/input-form-endpoint-runtime.d.ts +140 -0
  23. package/dist/input-form-endpoint-runtime.d.ts.map +1 -0
  24. package/dist/input-form-endpoint-runtime.js +280 -0
  25. package/dist/input-form-endpoint-runtime.js.map +1 -0
  26. package/dist/local-flow-state-data-source-projection.d.ts +21 -0
  27. package/dist/local-flow-state-data-source-projection.d.ts.map +1 -0
  28. package/dist/local-flow-state-data-source-projection.js +65 -0
  29. package/dist/local-flow-state-data-source-projection.js.map +1 -0
  30. package/dist/navigation-runtime-context.d.ts +22 -0
  31. package/dist/navigation-runtime-context.d.ts.map +1 -0
  32. package/dist/navigation-runtime-context.js +23 -0
  33. package/dist/navigation-runtime-context.js.map +1 -0
  34. package/dist/navigation-shell-frame-renderer-registry.d.ts +20 -0
  35. package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
  36. package/dist/navigation-shell-frame-renderer-registry.js +9 -0
  37. package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
  38. package/dist/navigation-shell-region-component-registry.d.ts +50 -0
  39. package/dist/navigation-shell-region-component-registry.d.ts.map +1 -0
  40. package/dist/navigation-shell-region-component-registry.js +44 -0
  41. package/dist/navigation-shell-region-component-registry.js.map +1 -0
  42. package/dist/navigation-shell-slot-renderer-registry.d.ts +22 -0
  43. package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
  44. package/dist/navigation-shell-slot-renderer-registry.js +9 -0
  45. package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
  46. package/dist/page-host-projection.d.ts +127 -0
  47. package/dist/page-host-projection.d.ts.map +1 -0
  48. package/dist/page-host-projection.js +59 -0
  49. package/dist/page-host-projection.js.map +1 -0
  50. package/dist/page-host-renderer-registry.d.ts +72 -0
  51. package/dist/page-host-renderer-registry.d.ts.map +1 -0
  52. package/dist/page-host-renderer-registry.js +63 -0
  53. package/dist/page-host-renderer-registry.js.map +1 -0
  54. package/dist/presentation-action-group-runtime-options.d.ts +36 -0
  55. package/dist/presentation-action-group-runtime-options.d.ts.map +1 -0
  56. package/dist/presentation-action-group-runtime-options.js +50 -0
  57. package/dist/presentation-action-group-runtime-options.js.map +1 -0
  58. package/dist/presentation-action-runtime.d.ts +52 -0
  59. package/dist/presentation-action-runtime.d.ts.map +1 -0
  60. package/dist/presentation-action-runtime.js +78 -0
  61. package/dist/presentation-action-runtime.js.map +1 -0
  62. package/dist/presentation-data-source-binding-runtime.d.ts +3 -0
  63. package/dist/presentation-data-source-binding-runtime.d.ts.map +1 -0
  64. package/dist/presentation-data-source-binding-runtime.js +65 -0
  65. package/dist/presentation-data-source-binding-runtime.js.map +1 -0
  66. package/dist/presentation-data-source-binding.d.ts +12 -0
  67. package/dist/presentation-data-source-binding.d.ts.map +1 -0
  68. package/dist/presentation-data-source-binding.js +13 -0
  69. package/dist/presentation-data-source-binding.js.map +1 -0
  70. package/dist/presentation-flow-runtime.d.ts +139 -0
  71. package/dist/presentation-flow-runtime.d.ts.map +1 -0
  72. package/dist/presentation-flow-runtime.js +514 -0
  73. package/dist/presentation-flow-runtime.js.map +1 -0
  74. package/dist/presentation-module-context.d.ts +4 -0
  75. package/dist/presentation-module-context.d.ts.map +1 -0
  76. package/dist/presentation-module-context.js +6 -0
  77. package/dist/presentation-module-context.js.map +1 -0
  78. package/dist/presentation-module-provider.d.ts +7 -0
  79. package/dist/presentation-module-provider.d.ts.map +1 -0
  80. package/dist/presentation-module-provider.js +7 -0
  81. package/dist/presentation-module-provider.js.map +1 -0
  82. package/dist/presentation-projection-diagnostics-context.d.ts +8 -0
  83. package/dist/presentation-projection-diagnostics-context.d.ts.map +1 -0
  84. package/dist/presentation-projection-diagnostics-context.js +3 -0
  85. package/dist/presentation-projection-diagnostics-context.js.map +1 -0
  86. package/dist/presentation-projection-diagnostics-hooks.d.ts +4 -0
  87. package/dist/presentation-projection-diagnostics-hooks.d.ts.map +1 -0
  88. package/dist/presentation-projection-diagnostics-hooks.js +17 -0
  89. package/dist/presentation-projection-diagnostics-hooks.js.map +1 -0
  90. package/dist/presentation-projection-diagnostics-runtime.d.ts +12 -0
  91. package/dist/presentation-projection-diagnostics-runtime.d.ts.map +1 -0
  92. package/dist/presentation-projection-diagnostics-runtime.js +54 -0
  93. package/dist/presentation-projection-diagnostics-runtime.js.map +1 -0
  94. package/dist/presentation-projection-trace.d.ts +27 -0
  95. package/dist/presentation-projection-trace.d.ts.map +1 -0
  96. package/dist/presentation-projection-trace.js +54 -0
  97. package/dist/presentation-projection-trace.js.map +1 -0
  98. package/dist/presentation-query-form-runtime.d.ts +30 -0
  99. package/dist/presentation-query-form-runtime.d.ts.map +1 -0
  100. package/dist/presentation-query-form-runtime.js +75 -0
  101. package/dist/presentation-query-form-runtime.js.map +1 -0
  102. package/dist/presentation-query-form-state-adapter-registry.d.ts +4 -0
  103. package/dist/presentation-query-form-state-adapter-registry.d.ts.map +1 -0
  104. package/dist/presentation-query-form-state-adapter-registry.js +13 -0
  105. package/dist/presentation-query-form-state-adapter-registry.js.map +1 -0
  106. package/dist/presentation-query-form-state-context.d.ts +20 -0
  107. package/dist/presentation-query-form-state-context.d.ts.map +1 -0
  108. package/dist/presentation-query-form-state-context.js +20 -0
  109. package/dist/presentation-query-form-state-context.js.map +1 -0
  110. package/dist/presentation-query-form-state.d.ts +29 -0
  111. package/dist/presentation-query-form-state.d.ts.map +1 -0
  112. package/dist/presentation-query-form-state.js +99 -0
  113. package/dist/presentation-query-form-state.js.map +1 -0
  114. package/dist/presentation-renderer-registry.d.ts +109 -0
  115. package/dist/presentation-renderer-registry.d.ts.map +1 -0
  116. package/dist/presentation-renderer-registry.js +25 -0
  117. package/dist/presentation-renderer-registry.js.map +1 -0
  118. package/dist/presentation-standards-context.d.ts +4 -0
  119. package/dist/presentation-standards-context.d.ts.map +1 -0
  120. package/dist/presentation-standards-context.js +12 -0
  121. package/dist/presentation-standards-context.js.map +1 -0
  122. package/dist/presentation-standards-provider.d.ts +14 -0
  123. package/dist/presentation-standards-provider.d.ts.map +1 -0
  124. package/dist/presentation-standards-provider.js +16 -0
  125. package/dist/presentation-standards-provider.js.map +1 -0
  126. package/dist/projected-document-action-runtime-bindings.d.ts +20 -0
  127. package/dist/projected-document-action-runtime-bindings.d.ts.map +1 -0
  128. package/dist/projected-document-action-runtime-bindings.js +88 -0
  129. package/dist/projected-document-action-runtime-bindings.js.map +1 -0
  130. package/dist/projected-document-action-runtime.d.ts +76 -0
  131. package/dist/projected-document-action-runtime.d.ts.map +1 -0
  132. package/dist/projected-document-action-runtime.js +224 -0
  133. package/dist/projected-document-action-runtime.js.map +1 -0
  134. package/dist/projected-document-process-preview-action-runtime-bindings.d.ts +26 -0
  135. package/dist/projected-document-process-preview-action-runtime-bindings.d.ts.map +1 -0
  136. package/dist/projected-document-process-preview-action-runtime-bindings.js +106 -0
  137. package/dist/projected-document-process-preview-action-runtime-bindings.js.map +1 -0
  138. package/dist/projected-document-process-preview-action-runtime.d.ts +321 -0
  139. package/dist/projected-document-process-preview-action-runtime.d.ts.map +1 -0
  140. package/dist/projected-document-process-preview-action-runtime.js +729 -0
  141. package/dist/projected-document-process-preview-action-runtime.js.map +1 -0
  142. package/dist/projected-document-process-preview-capability-runtime.d.ts +47 -0
  143. package/dist/projected-document-process-preview-capability-runtime.d.ts.map +1 -0
  144. package/dist/projected-document-process-preview-capability-runtime.js +49 -0
  145. package/dist/projected-document-process-preview-capability-runtime.js.map +1 -0
  146. package/dist/projected-document-workspace-action-runtime.d.ts +87 -0
  147. package/dist/projected-document-workspace-action-runtime.d.ts.map +1 -0
  148. package/dist/projected-document-workspace-action-runtime.js +150 -0
  149. package/dist/projected-document-workspace-action-runtime.js.map +1 -0
  150. package/dist/projected-document-workspace-projection-renderer-diagnostics.d.ts +18 -0
  151. package/dist/projected-document-workspace-projection-renderer-diagnostics.d.ts.map +1 -0
  152. package/dist/projected-document-workspace-projection-renderer-diagnostics.js +207 -0
  153. package/dist/projected-document-workspace-projection-renderer-diagnostics.js.map +1 -0
  154. package/dist/projected-document-workspace-runtime-binding-diagnostics.d.ts +19 -0
  155. package/dist/projected-document-workspace-runtime-binding-diagnostics.d.ts.map +1 -0
  156. package/dist/projected-document-workspace-runtime-binding-diagnostics.js +124 -0
  157. package/dist/projected-document-workspace-runtime-binding-diagnostics.js.map +1 -0
  158. package/dist/projected-navigation-provider.d.ts +16 -0
  159. package/dist/projected-navigation-provider.d.ts.map +1 -0
  160. package/dist/projected-navigation-provider.js +51 -0
  161. package/dist/projected-navigation-provider.js.map +1 -0
  162. package/dist/projected-presentation-flow-host.d.ts +16 -0
  163. package/dist/projected-presentation-flow-host.d.ts.map +1 -0
  164. package/dist/projected-presentation-flow-host.js +14 -0
  165. package/dist/projected-presentation-flow-host.js.map +1 -0
  166. package/dist/projected-query-form-state-adapter.d.ts +12 -0
  167. package/dist/projected-query-form-state-adapter.d.ts.map +1 -0
  168. package/dist/projected-query-form-state-adapter.js +361 -0
  169. package/dist/projected-query-form-state-adapter.js.map +1 -0
  170. package/dist/react-router-binding.d.ts +133 -0
  171. package/dist/react-router-binding.d.ts.map +1 -0
  172. package/dist/react-router-binding.js +76 -0
  173. package/dist/react-router-binding.js.map +1 -0
  174. package/dist/react-router-path.d.ts +4 -0
  175. package/dist/react-router-path.d.ts.map +1 -0
  176. package/dist/react-router-path.js +11 -0
  177. package/dist/react-router-path.js.map +1 -0
  178. package/dist/scope-selection-context.d.ts +28 -0
  179. package/dist/scope-selection-context.d.ts.map +1 -0
  180. package/dist/scope-selection-context.js +13 -0
  181. package/dist/scope-selection-context.js.map +1 -0
  182. package/dist/scope-selection-provider.d.ts +33 -0
  183. package/dist/scope-selection-provider.d.ts.map +1 -0
  184. package/dist/scope-selection-provider.js +162 -0
  185. package/dist/scope-selection-provider.js.map +1 -0
  186. package/dist/scope-selection-request.d.ts +6 -0
  187. package/dist/scope-selection-request.d.ts.map +1 -0
  188. package/dist/scope-selection-request.js +12 -0
  189. package/dist/scope-selection-request.js.map +1 -0
  190. package/dist/standard-navigation-shell-frame-renderers.d.ts +15 -0
  191. package/dist/standard-navigation-shell-frame-renderers.d.ts.map +1 -0
  192. package/dist/standard-navigation-shell-frame-renderers.js +22 -0
  193. package/dist/standard-navigation-shell-frame-renderers.js.map +1 -0
  194. package/dist/standard-navigation-shell-slot-renderers.d.ts +59 -0
  195. package/dist/standard-navigation-shell-slot-renderers.d.ts.map +1 -0
  196. package/dist/standard-navigation-shell-slot-renderers.js +67 -0
  197. package/dist/standard-navigation-shell-slot-renderers.js.map +1 -0
  198. package/dist/view-chrome-slot-renderer-registry.d.ts +12 -0
  199. package/dist/view-chrome-slot-renderer-registry.d.ts.map +1 -0
  200. package/dist/view-chrome-slot-renderer-registry.js +12 -0
  201. package/dist/view-chrome-slot-renderer-registry.js.map +1 -0
  202. package/package.json +60 -0
  203. package/src/collection-chrome-slot-renderer-registry.ts +66 -0
  204. package/src/collection-selection-state-context.ts +51 -0
  205. package/src/collection-selection-state.tsx +101 -0
  206. package/src/document-workspace-runtime.tsx +1505 -0
  207. package/src/index.ts +50 -0
  208. package/src/input-form-endpoint-runtime.ts +632 -0
  209. package/src/local-flow-state-data-source-projection.ts +133 -0
  210. package/src/navigation-runtime-context.ts +40 -0
  211. package/src/navigation-shell-frame-renderer-registry.ts +54 -0
  212. package/src/navigation-shell-region-component-registry.tsx +127 -0
  213. package/src/navigation-shell-slot-renderer-registry.ts +88 -0
  214. package/src/page-host-projection.ts +356 -0
  215. package/src/page-host-renderer-registry.tsx +353 -0
  216. package/src/presentation-action-group-runtime-options.ts +121 -0
  217. package/src/presentation-action-runtime.ts +190 -0
  218. package/src/presentation-data-source-binding-runtime.ts +109 -0
  219. package/src/presentation-data-source-binding.tsx +24 -0
  220. package/src/presentation-flow-runtime.tsx +835 -0
  221. package/src/presentation-module-context.ts +10 -0
  222. package/src/presentation-module-provider.tsx +19 -0
  223. package/src/presentation-projection-diagnostics-context.ts +17 -0
  224. package/src/presentation-projection-diagnostics-hooks.ts +29 -0
  225. package/src/presentation-projection-diagnostics-runtime.tsx +95 -0
  226. package/src/presentation-projection-trace.ts +117 -0
  227. package/src/presentation-query-form-runtime.ts +148 -0
  228. package/src/presentation-query-form-state-adapter-registry.ts +25 -0
  229. package/src/presentation-query-form-state-context.ts +56 -0
  230. package/src/presentation-query-form-state.tsx +250 -0
  231. package/src/presentation-renderer-registry.ts +214 -0
  232. package/src/presentation-standards-context.ts +21 -0
  233. package/src/presentation-standards-provider.tsx +44 -0
  234. package/src/projected-document-action-runtime-bindings.ts +132 -0
  235. package/src/projected-document-action-runtime.ts +414 -0
  236. package/src/projected-document-process-preview-action-runtime-bindings.ts +231 -0
  237. package/src/projected-document-process-preview-action-runtime.ts +1725 -0
  238. package/src/projected-document-process-preview-capability-runtime.ts +216 -0
  239. package/src/projected-document-workspace-action-runtime.ts +402 -0
  240. package/src/projected-document-workspace-projection-renderer-diagnostics.ts +342 -0
  241. package/src/projected-document-workspace-runtime-binding-diagnostics.ts +208 -0
  242. package/src/projected-navigation-provider.tsx +104 -0
  243. package/src/projected-presentation-flow-host.tsx +46 -0
  244. package/src/projected-query-form-state-adapter.ts +578 -0
  245. package/src/react-router-binding.tsx +417 -0
  246. package/src/react-router-path.ts +16 -0
  247. package/src/scope-selection-context.ts +58 -0
  248. package/src/scope-selection-provider.tsx +324 -0
  249. package/src/scope-selection-request.ts +21 -0
  250. package/src/standard-navigation-shell-frame-renderers.tsx +106 -0
  251. package/src/standard-navigation-shell-slot-renderers.tsx +289 -0
  252. package/src/view-chrome-slot-renderer-registry.ts +66 -0
@@ -0,0 +1,417 @@
1
+ import type { ReactNode } from 'react'
2
+ import { Route, Routes, useLocation, useParams } from 'react-router'
3
+
4
+ import {
5
+ createNavigationRouteInstanceKey,
6
+ resolveNavigationTarget,
7
+ type NavigationDefinitionProjection,
8
+ type NavigationTarget,
9
+ } from '@cohesivesystems/presentation-core'
10
+ import type {
11
+ NavigationRouteDefinition,
12
+ PageHostDefinition,
13
+ } from '@cohesivesystems/presentation-contracts'
14
+ import {
15
+ renderPageHost,
16
+ type PageHostComponentRegistry,
17
+ type RouteParameterValues,
18
+ type UnknownPageHostRenderer,
19
+ } from './page-host-projection'
20
+ import { toReactRouterPath } from './react-router-path'
21
+
22
+ /**
23
+ * Props for rendering one semantic navigation route through React Router.
24
+ *
25
+ * The route definition remains presentation IR; this component only adapts it
26
+ * to React Router matching, resolves the target page host, and then delegates
27
+ * rendering to either an app-specific navigation target renderer or the
28
+ * page-host projection runtime.
29
+ */
30
+ export interface ProjectedNavigationRouteProps<
31
+ TComponentKey extends string,
32
+ TModule,
33
+ TNavigation extends NavigationDefinitionProjection<TRoute, TPageHost>,
34
+ TRoute extends NavigationRouteDefinition,
35
+ TPageHost extends PageHostDefinition,
36
+ TProjectionContext,
37
+ > {
38
+ /** Optional concrete component registry used when rendering a bound page host directly. */
39
+ readonly componentRegistry?: PageHostComponentRegistry<
40
+ TComponentKey,
41
+ TModule,
42
+ TNavigation,
43
+ TRoute,
44
+ TPageHost,
45
+ TProjectionContext
46
+ >
47
+ /** App-defined runtime context carried through route and page-host renderers. */
48
+ readonly context: TProjectionContext
49
+ /** Presentation module or module projection that owns the route target bindings. */
50
+ readonly module: TModule
51
+ /** Navigation graph containing the route and its page-host definitions. */
52
+ readonly navigation: TNavigation
53
+ /** Fallback renderer for unmatched routes, missing page hosts, or unknown bindings. */
54
+ readonly renderUnknownPageHost: UnknownPageHostRenderer<
55
+ TModule,
56
+ TNavigation,
57
+ TRoute,
58
+ TPageHost,
59
+ TProjectionContext
60
+ >
61
+ /**
62
+ * Optional higher-level renderer for the resolved navigation target.
63
+ *
64
+ * Use this when an app needs to attach route-level services, auth, data-source
65
+ * bindings, or layout before rendering the page host.
66
+ */
67
+ readonly renderNavigationTarget?: ProjectedNavigationTargetRenderer<
68
+ TComponentKey,
69
+ TModule,
70
+ TNavigation,
71
+ TRoute,
72
+ TPageHost,
73
+ TProjectionContext
74
+ >
75
+ /**
76
+ * Optional component-key resolver used by direct page-host rendering.
77
+ *
78
+ * Most projected apps prefer target bindings or a `renderNavigationTarget`
79
+ * implementation; this hook remains useful for simple router integrations.
80
+ */
81
+ readonly resolveComponentKey?: (
82
+ context: ProjectedNavigationRouteResolutionContext<
83
+ TModule,
84
+ TNavigation,
85
+ TRoute,
86
+ TPageHost,
87
+ TProjectionContext
88
+ >,
89
+ ) => string | null
90
+ /** The semantic route definition being adapted to a React Router route. */
91
+ readonly route: TRoute
92
+ }
93
+
94
+ /**
95
+ * Context available while resolving a route-level component key.
96
+ *
97
+ * This is deliberately pre-render context: route parameters are not included
98
+ * here because component-key resolution should depend on the semantic route,
99
+ * page host, and module bindings rather than current URL values.
100
+ */
101
+ export interface ProjectedNavigationRouteResolutionContext<
102
+ TModule,
103
+ TNavigation extends NavigationDefinitionProjection<TRoute, TPageHost>,
104
+ TRoute extends NavigationRouteDefinition,
105
+ TPageHost extends PageHostDefinition,
106
+ TProjectionContext,
107
+ > {
108
+ /** App-defined runtime context passed into the navigation projection. */
109
+ readonly context: TProjectionContext
110
+ /** Presentation module or module projection used by the resolver. */
111
+ readonly module: TModule
112
+ /** Navigation graph that contains the current route and page host. */
113
+ readonly navigation: TNavigation
114
+ /** Fully resolved semantic navigation target for the matched route. */
115
+ readonly navigationTarget: NavigationTarget<TRoute, TPageHost>
116
+ /** Page host addressed by the route, or `null` when the graph is incomplete. */
117
+ readonly pageHost: TPageHost | null
118
+ /** Matched semantic route definition. */
119
+ readonly route: TRoute
120
+ }
121
+
122
+ /**
123
+ * Convenience route-resolution context for integrations that use the generated
124
+ * default navigation and page-host shapes.
125
+ */
126
+ export type SimpleProjectedNavigationRouteResolutionContext<
127
+ TModule,
128
+ TProjectionContext,
129
+ > = ProjectedNavigationRouteResolutionContext<
130
+ TModule,
131
+ NavigationDefinitionProjection,
132
+ NavigationRouteDefinition,
133
+ PageHostDefinition,
134
+ TProjectionContext
135
+ >
136
+
137
+ /**
138
+ * Render context for apps that take over the route target after React Router
139
+ * has matched a URL.
140
+ *
141
+ * This is the main extension point for product shells: callers receive route
142
+ * params, semantic route/page-host data, and a helper for falling back to the
143
+ * standard page-host renderer.
144
+ */
145
+ export interface ProjectedNavigationTargetRenderContext<
146
+ TComponentKey extends string,
147
+ TModule,
148
+ TNavigation extends NavigationDefinitionProjection<TRoute, TPageHost>,
149
+ TRoute extends NavigationRouteDefinition,
150
+ TPageHost extends PageHostDefinition,
151
+ TProjectionContext,
152
+ > extends ProjectedNavigationRouteResolutionContext<
153
+ TModule,
154
+ TNavigation,
155
+ TRoute,
156
+ TPageHost,
157
+ TProjectionContext
158
+ > {
159
+ /** Route parameter values returned by React Router for the matched URL. */
160
+ readonly parameters: RouteParameterValues
161
+ /**
162
+ * Renders the resolved page host through the standard page-host projection.
163
+ *
164
+ * Pass a component key to force a binding for simple adapters; omit it to let
165
+ * the page-host projection resolve from the registry and target metadata.
166
+ */
167
+ readonly renderBoundPageHost: (
168
+ componentKey?: TComponentKey | string | null,
169
+ ) => ReactNode
170
+ }
171
+
172
+ /**
173
+ * Convenience target-render context for integrations that use the generated
174
+ * default navigation and page-host shapes.
175
+ */
176
+ export type SimpleProjectedNavigationTargetRenderContext<
177
+ TModule,
178
+ TProjectionContext,
179
+ > = ProjectedNavigationTargetRenderContext<
180
+ string,
181
+ TModule,
182
+ NavigationDefinitionProjection,
183
+ NavigationRouteDefinition,
184
+ PageHostDefinition,
185
+ TProjectionContext
186
+ >
187
+
188
+ /**
189
+ * App-level route target renderer.
190
+ *
191
+ * Implement this when route dispatch needs to be explicit and inspectable while
192
+ * the actual page body remains projected from presentation IR.
193
+ */
194
+ export type ProjectedNavigationTargetRenderer<
195
+ TComponentKey extends string,
196
+ TModule,
197
+ TNavigation extends NavigationDefinitionProjection<TRoute, TPageHost>,
198
+ TRoute extends NavigationRouteDefinition,
199
+ TPageHost extends PageHostDefinition,
200
+ TProjectionContext,
201
+ > = (
202
+ context: ProjectedNavigationTargetRenderContext<
203
+ TComponentKey,
204
+ TModule,
205
+ TNavigation,
206
+ TRoute,
207
+ TPageHost,
208
+ TProjectionContext
209
+ >,
210
+ ) => ReactNode
211
+
212
+ /**
213
+ * React Router element for one generated presentation route.
214
+ *
215
+ * It resolves the semantic navigation target, captures URL parameters, and then
216
+ * either invokes `renderNavigationTarget` or renders the target page host
217
+ * directly through `renderPageHost`.
218
+ */
219
+ export function ProjectedNavigationRoute<
220
+ TComponentKey extends string,
221
+ TModule,
222
+ TNavigation extends NavigationDefinitionProjection<TRoute, TPageHost>,
223
+ TRoute extends NavigationRouteDefinition,
224
+ TPageHost extends PageHostDefinition,
225
+ TProjectionContext,
226
+ >({
227
+ componentRegistry,
228
+ context,
229
+ module,
230
+ navigation,
231
+ renderUnknownPageHost,
232
+ renderNavigationTarget,
233
+ resolveComponentKey,
234
+ route,
235
+ }: ProjectedNavigationRouteProps<
236
+ TComponentKey,
237
+ TModule,
238
+ TNavigation,
239
+ TRoute,
240
+ TPageHost,
241
+ TProjectionContext
242
+ >) {
243
+ const parameters = useParams()
244
+ const navigationTarget = resolveNavigationTarget<TNavigation, TRoute, TPageHost>(navigation, route)
245
+ const pageHost = navigationTarget.pageHost
246
+ const resolvedComponentRegistry = (componentRegistry ?? {}) as PageHostComponentRegistry<
247
+ TComponentKey,
248
+ TModule,
249
+ TNavigation,
250
+ TRoute,
251
+ TPageHost,
252
+ TProjectionContext
253
+ >
254
+ const renderBoundPageHost = (componentKey?: TComponentKey | string | null) =>
255
+ renderPageHost({
256
+ componentKey,
257
+ componentRegistry: resolvedComponentRegistry,
258
+ context,
259
+ module,
260
+ navigation,
261
+ navigationTarget,
262
+ pageHost,
263
+ parameters,
264
+ renderUnknownPageHost,
265
+ route,
266
+ })
267
+
268
+ if (renderNavigationTarget) {
269
+ return renderNavigationTarget({
270
+ context,
271
+ module,
272
+ navigation,
273
+ navigationTarget,
274
+ pageHost,
275
+ parameters,
276
+ renderBoundPageHost,
277
+ route,
278
+ })
279
+ }
280
+
281
+ const componentKey = resolveComponentKey?.({
282
+ context,
283
+ module,
284
+ navigation,
285
+ navigationTarget,
286
+ pageHost,
287
+ route,
288
+ }) ?? null
289
+
290
+ return renderBoundPageHost(componentKey)
291
+ }
292
+
293
+ /**
294
+ * Props for projecting an entire navigation graph into React Router routes.
295
+ */
296
+ export interface ProjectedNavigationRoutesProps<
297
+ TComponentKey extends string,
298
+ TModule,
299
+ TNavigation extends NavigationDefinitionProjection<TRoute, TPageHost>,
300
+ TRoute extends NavigationRouteDefinition,
301
+ TPageHost extends PageHostDefinition,
302
+ TProjectionContext,
303
+ > {
304
+ /** Optional registry used when route elements render page hosts directly. */
305
+ readonly componentRegistry?: PageHostComponentRegistry<
306
+ TComponentKey,
307
+ TModule,
308
+ TNavigation,
309
+ TRoute,
310
+ TPageHost,
311
+ TProjectionContext
312
+ >
313
+ /** App-defined runtime context passed to every generated route element. */
314
+ readonly context: TProjectionContext
315
+ /** Presentation module or module projection used by generated routes. */
316
+ readonly module: TModule
317
+ /** Semantic navigation graph whose routes are projected into React Router. */
318
+ readonly navigation: TNavigation
319
+ /** Fallback renderer used for missing bindings and the catch-all route. */
320
+ readonly renderUnknownPageHost: UnknownPageHostRenderer<
321
+ TModule,
322
+ TNavigation,
323
+ TRoute,
324
+ TPageHost,
325
+ TProjectionContext
326
+ >
327
+ /** Optional route-level renderer invoked after a URL has matched. */
328
+ readonly renderNavigationTarget?: ProjectedNavigationTargetRenderer<
329
+ TComponentKey,
330
+ TModule,
331
+ TNavigation,
332
+ TRoute,
333
+ TPageHost,
334
+ TProjectionContext
335
+ >
336
+ /** Optional direct page-host component-key resolver. */
337
+ readonly resolveComponentKey?: ProjectedNavigationRouteProps<
338
+ TComponentKey,
339
+ TModule,
340
+ TNavigation,
341
+ TRoute,
342
+ TPageHost,
343
+ TProjectionContext
344
+ >['resolveComponentKey']
345
+ }
346
+
347
+ /**
348
+ * Projects a semantic navigation graph into a React Router `<Routes>` tree.
349
+ *
350
+ * Each `NavigationRouteDefinition.PathTemplate` is translated to a React Router
351
+ * path, while unmatched URLs are routed to the supplied unknown page-host
352
+ * renderer.
353
+ */
354
+ export function ProjectedNavigationRoutes<
355
+ TComponentKey extends string,
356
+ TModule,
357
+ TNavigation extends NavigationDefinitionProjection<TRoute, TPageHost>,
358
+ TRoute extends NavigationRouteDefinition,
359
+ TPageHost extends PageHostDefinition,
360
+ TProjectionContext,
361
+ >({
362
+ componentRegistry,
363
+ context,
364
+ module,
365
+ navigation,
366
+ renderUnknownPageHost,
367
+ renderNavigationTarget,
368
+ resolveComponentKey,
369
+ }: ProjectedNavigationRoutesProps<
370
+ TComponentKey,
371
+ TModule,
372
+ TNavigation,
373
+ TRoute,
374
+ TPageHost,
375
+ TProjectionContext
376
+ >) {
377
+ const location = useLocation()
378
+ const routeInstanceKey = createNavigationRouteInstanceKey(navigation, location)
379
+
380
+ return (
381
+ // A semantic route instance owns route-scoped bindings and workspace state.
382
+ // The navigation history policy declares which URL parts identify that instance.
383
+ <Routes key={routeInstanceKey}>
384
+ {navigation.Routes.map((route) => (
385
+ <Route
386
+ element={
387
+ <ProjectedNavigationRoute
388
+ componentRegistry={componentRegistry}
389
+ context={context}
390
+ module={module}
391
+ navigation={navigation}
392
+ renderUnknownPageHost={renderUnknownPageHost}
393
+ renderNavigationTarget={renderNavigationTarget}
394
+ resolveComponentKey={resolveComponentKey}
395
+ route={route}
396
+ />
397
+ }
398
+ key={route.Id}
399
+ path={toReactRouterPath(route.PathTemplate)}
400
+ />
401
+ ))}
402
+ <Route
403
+ element={renderUnknownPageHost({
404
+ context,
405
+ module,
406
+ navigation,
407
+ navigationTarget: null,
408
+ pageHost: null,
409
+ parameters: {},
410
+ reason: 'unmatched-route',
411
+ route: null,
412
+ })}
413
+ path="*"
414
+ />
415
+ </Routes>
416
+ )
417
+ }
@@ -0,0 +1,16 @@
1
+ import type { RouteParameterValues } from './page-host-projection'
2
+
3
+ export function readRequiredRouteParameter(
4
+ parameters: RouteParameterValues,
5
+ name: string,
6
+ ) {
7
+ return parameters[name] ?? ''
8
+ }
9
+
10
+ export function toReactRouterPath(pathTemplate: string) {
11
+ const pathname = pathTemplate.split(/[?#]/)[0] ?? '/'
12
+ const routePath = pathname.length === 0 ? '/' : pathname
13
+ return routePath.replace(/\{([^}]+)\}/g, (_token, parameterName: string) => {
14
+ return `:${parameterName}`
15
+ })
16
+ }
@@ -0,0 +1,58 @@
1
+ import { createContext, useContext } from 'react'
2
+
3
+ import type {
4
+ PresentationScopeAccess,
5
+ } from '@cohesivesystems/presentation-core'
6
+
7
+ /**
8
+ * React scope-selection state shared by a presentation host.
9
+ */
10
+ export interface PresentationScopeSelectionContextValue<
11
+ TScopeContext = unknown,
12
+ TScopeMetadata = unknown,
13
+ > {
14
+ /** Source context that produced the accessible scopes. */
15
+ readonly scopeContext: TScopeContext | null
16
+
17
+ /** Whether scope context is currently loading. */
18
+ readonly isLoading: boolean
19
+
20
+ /** Scopes accessible to the current principal. */
21
+ readonly scopes: readonly PresentationScopeAccess<TScopeMetadata>[]
22
+
23
+ /** Primary single selected scope id. */
24
+ readonly selectedScopeId: string | null
25
+
26
+ /** Selects the primary single scope. */
27
+ readonly setSelectedScopeId: (scopeId: string) => void
28
+
29
+ /** Reads selected scope ids for a named multi-scope purpose. */
30
+ readonly getSelectedScopeIds: (
31
+ purpose: string,
32
+ fallbackScopeIds?: readonly string[]
33
+ ) => readonly string[]
34
+
35
+ /** Stores selected scope ids for a named multi-scope purpose. */
36
+ readonly setSelectedScopeIds: (purpose: string, scopeIds: readonly string[]) => void
37
+
38
+ /** Stable query/cache suffix for the primary single selected scope. */
39
+ readonly singleScopeQuerySuffix: string
40
+ }
41
+
42
+ export const PresentationScopeSelectionContext =
43
+ createContext<PresentationScopeSelectionContextValue | null>(null)
44
+
45
+ /**
46
+ * Reads the nearest presentation scope-selection context.
47
+ */
48
+ export function usePresentationScopeSelection<
49
+ TScopeContext = unknown,
50
+ TScopeMetadata = unknown,
51
+ >() {
52
+ const value = useContext(PresentationScopeSelectionContext)
53
+ if (!value) {
54
+ throw new Error('usePresentationScopeSelection must be used inside PresentationScopeSelectionProvider.')
55
+ }
56
+
57
+ return value as PresentationScopeSelectionContextValue<TScopeContext, TScopeMetadata>
58
+ }