@cohesivesystems/presentation-react-shadcn 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 (262) hide show
  1. package/LICENSE +55 -0
  2. package/dist/document-workspace-surface-slot-renderers.d.ts +58 -0
  3. package/dist/document-workspace-surface-slot-renderers.d.ts.map +1 -0
  4. package/dist/document-workspace-surface-slot-renderers.js +206 -0
  5. package/dist/document-workspace-surface-slot-renderers.js.map +1 -0
  6. package/dist/index.d.ts +53 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +53 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/navigation-shell-frame-renderer-registry.d.ts +8 -0
  11. package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
  12. package/dist/navigation-shell-frame-renderer-registry.js +2 -0
  13. package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
  14. package/dist/navigation-shell-slot-renderer-registry.d.ts +9 -0
  15. package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
  16. package/dist/navigation-shell-slot-renderer-registry.js +2 -0
  17. package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
  18. package/dist/page-host-unavailable-renderer.d.ts +10 -0
  19. package/dist/page-host-unavailable-renderer.d.ts.map +1 -0
  20. package/dist/page-host-unavailable-renderer.js +27 -0
  21. package/dist/page-host-unavailable-renderer.js.map +1 -0
  22. package/dist/presentation-action-group.d.ts +99 -0
  23. package/dist/presentation-action-group.d.ts.map +1 -0
  24. package/dist/presentation-action-group.js +214 -0
  25. package/dist/presentation-action-group.js.map +1 -0
  26. package/dist/presentation-badge-target-interpreter.d.ts +26 -0
  27. package/dist/presentation-badge-target-interpreter.d.ts.map +1 -0
  28. package/dist/presentation-badge-target-interpreter.js +17 -0
  29. package/dist/presentation-badge-target-interpreter.js.map +1 -0
  30. package/dist/presentation-component-groups.d.ts +968 -0
  31. package/dist/presentation-component-groups.d.ts.map +1 -0
  32. package/dist/presentation-component-groups.js +505 -0
  33. package/dist/presentation-component-groups.js.map +1 -0
  34. package/dist/presentation-component-system-diagnostics.d.ts +27 -0
  35. package/dist/presentation-component-system-diagnostics.d.ts.map +1 -0
  36. package/dist/presentation-component-system-diagnostics.js +399 -0
  37. package/dist/presentation-component-system-diagnostics.js.map +1 -0
  38. package/dist/presentation-component-system.d.ts +31 -0
  39. package/dist/presentation-component-system.d.ts.map +1 -0
  40. package/dist/presentation-component-system.js +61 -0
  41. package/dist/presentation-component-system.js.map +1 -0
  42. package/dist/presentation-icon-diagnostics.d.ts +12 -0
  43. package/dist/presentation-icon-diagnostics.d.ts.map +1 -0
  44. package/dist/presentation-icon-diagnostics.js +17 -0
  45. package/dist/presentation-icon-diagnostics.js.map +1 -0
  46. package/dist/presentation-icon-registry.d.ts +28 -0
  47. package/dist/presentation-icon-registry.d.ts.map +1 -0
  48. package/dist/presentation-icon-registry.js +80 -0
  49. package/dist/presentation-icon-registry.js.map +1 -0
  50. package/dist/presentation-projection-trace-panel.d.ts +10 -0
  51. package/dist/presentation-projection-trace-panel.d.ts.map +1 -0
  52. package/dist/presentation-projection-trace-panel.js +48 -0
  53. package/dist/presentation-projection-trace-panel.js.map +1 -0
  54. package/dist/presentation-routed-surface-host.d.ts +19 -0
  55. package/dist/presentation-routed-surface-host.d.ts.map +1 -0
  56. package/dist/presentation-routed-surface-host.js +12 -0
  57. package/dist/presentation-routed-surface-host.js.map +1 -0
  58. package/dist/presentation-shadcn-component-system.d.ts +22 -0
  59. package/dist/presentation-shadcn-component-system.d.ts.map +1 -0
  60. package/dist/presentation-shadcn-component-system.js +2 -0
  61. package/dist/presentation-shadcn-component-system.js.map +1 -0
  62. package/dist/presentation-standard-renderers.d.ts +168 -0
  63. package/dist/presentation-standard-renderers.d.ts.map +1 -0
  64. package/dist/presentation-standard-renderers.js +440 -0
  65. package/dist/presentation-standard-renderers.js.map +1 -0
  66. package/dist/presentation-surface-renderer.d.ts +23 -0
  67. package/dist/presentation-surface-renderer.d.ts.map +1 -0
  68. package/dist/presentation-surface-renderer.js +119 -0
  69. package/dist/presentation-surface-renderer.js.map +1 -0
  70. package/dist/presentation-value-renderers.d.ts +10 -0
  71. package/dist/presentation-value-renderers.d.ts.map +1 -0
  72. package/dist/presentation-value-renderers.js +14 -0
  73. package/dist/presentation-value-renderers.js.map +1 -0
  74. package/dist/process-task-icons.d.ts +49 -0
  75. package/dist/process-task-icons.d.ts.map +1 -0
  76. package/dist/process-task-icons.js +154 -0
  77. package/dist/process-task-icons.js.map +1 -0
  78. package/dist/projected-activity-state.d.ts +17 -0
  79. package/dist/projected-activity-state.d.ts.map +1 -0
  80. package/dist/projected-activity-state.js +22 -0
  81. package/dist/projected-activity-state.js.map +1 -0
  82. package/dist/projected-collection-action-runtime-diagnostics.d.ts +4 -0
  83. package/dist/projected-collection-action-runtime-diagnostics.d.ts.map +1 -0
  84. package/dist/projected-collection-action-runtime-diagnostics.js +9 -0
  85. package/dist/projected-collection-action-runtime-diagnostics.js.map +1 -0
  86. package/dist/projected-collection-view.d.ts +90 -0
  87. package/dist/projected-collection-view.d.ts.map +1 -0
  88. package/dist/projected-collection-view.js +532 -0
  89. package/dist/projected-collection-view.js.map +1 -0
  90. package/dist/projected-document-action-status-notices.d.ts +15 -0
  91. package/dist/projected-document-action-status-notices.d.ts.map +1 -0
  92. package/dist/projected-document-action-status-notices.js +33 -0
  93. package/dist/projected-document-action-status-notices.js.map +1 -0
  94. package/dist/projected-document-badges.d.ts +24 -0
  95. package/dist/projected-document-badges.d.ts.map +1 -0
  96. package/dist/projected-document-badges.js +53 -0
  97. package/dist/projected-document-badges.js.map +1 -0
  98. package/dist/projected-document-editor-surface.d.ts +46 -0
  99. package/dist/projected-document-editor-surface.d.ts.map +1 -0
  100. package/dist/projected-document-editor-surface.js +399 -0
  101. package/dist/projected-document-editor-surface.js.map +1 -0
  102. package/dist/projected-document-workspace-notices.d.ts +24 -0
  103. package/dist/projected-document-workspace-notices.d.ts.map +1 -0
  104. package/dist/projected-document-workspace-notices.js +14 -0
  105. package/dist/projected-document-workspace-notices.js.map +1 -0
  106. package/dist/projected-document-workspace-prompt-child-view-registry.d.ts +25 -0
  107. package/dist/projected-document-workspace-prompt-child-view-registry.d.ts.map +1 -0
  108. package/dist/projected-document-workspace-prompt-child-view-registry.js +41 -0
  109. package/dist/projected-document-workspace-prompt-child-view-registry.js.map +1 -0
  110. package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts +32 -0
  111. package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts.map +1 -0
  112. package/dist/projected-document-workspace-prompt-child-view-renderers.js +77 -0
  113. package/dist/projected-document-workspace-prompt-child-view-renderers.js.map +1 -0
  114. package/dist/projected-document-workspace-shell.d.ts +100 -0
  115. package/dist/projected-document-workspace-shell.d.ts.map +1 -0
  116. package/dist/projected-document-workspace-shell.js +153 -0
  117. package/dist/projected-document-workspace-shell.js.map +1 -0
  118. package/dist/projected-document-workspace.d.ts +39 -0
  119. package/dist/projected-document-workspace.d.ts.map +1 -0
  120. package/dist/projected-document-workspace.js +63 -0
  121. package/dist/projected-document-workspace.js.map +1 -0
  122. package/dist/projected-field-value-rendering.d.ts +94 -0
  123. package/dist/projected-field-value-rendering.d.ts.map +1 -0
  124. package/dist/projected-field-value-rendering.js +377 -0
  125. package/dist/projected-field-value-rendering.js.map +1 -0
  126. package/dist/projected-inline-list.d.ts +20 -0
  127. package/dist/projected-inline-list.d.ts.map +1 -0
  128. package/dist/projected-inline-list.js +149 -0
  129. package/dist/projected-inline-list.js.map +1 -0
  130. package/dist/projected-input-form.d.ts +143 -0
  131. package/dist/projected-input-form.d.ts.map +1 -0
  132. package/dist/projected-input-form.js +612 -0
  133. package/dist/projected-input-form.js.map +1 -0
  134. package/dist/projected-metric-dashboard.d.ts +26 -0
  135. package/dist/projected-metric-dashboard.d.ts.map +1 -0
  136. package/dist/projected-metric-dashboard.js +20 -0
  137. package/dist/projected-metric-dashboard.js.map +1 -0
  138. package/dist/projected-metric-strip.d.ts +20 -0
  139. package/dist/projected-metric-strip.d.ts.map +1 -0
  140. package/dist/projected-metric-strip.js +131 -0
  141. package/dist/projected-metric-strip.js.map +1 -0
  142. package/dist/projected-navigation-shell-view-host.d.ts +34 -0
  143. package/dist/projected-navigation-shell-view-host.d.ts.map +1 -0
  144. package/dist/projected-navigation-shell-view-host.js +75 -0
  145. package/dist/projected-navigation-shell-view-host.js.map +1 -0
  146. package/dist/projected-navigation-shell.d.ts +33 -0
  147. package/dist/projected-navigation-shell.d.ts.map +1 -0
  148. package/dist/projected-navigation-shell.js +112 -0
  149. package/dist/projected-navigation-shell.js.map +1 -0
  150. package/dist/projected-presentation-badges.d.ts +34 -0
  151. package/dist/projected-presentation-badges.d.ts.map +1 -0
  152. package/dist/projected-presentation-badges.js +22 -0
  153. package/dist/projected-presentation-badges.js.map +1 -0
  154. package/dist/projected-presentation-diagnostics.d.ts +10 -0
  155. package/dist/projected-presentation-diagnostics.d.ts.map +1 -0
  156. package/dist/projected-presentation-diagnostics.js +40 -0
  157. package/dist/projected-presentation-diagnostics.js.map +1 -0
  158. package/dist/projected-presentation-flow-layer.d.ts +33 -0
  159. package/dist/projected-presentation-flow-layer.d.ts.map +1 -0
  160. package/dist/projected-presentation-flow-layer.js +71 -0
  161. package/dist/projected-presentation-flow-layer.js.map +1 -0
  162. package/dist/projected-process-task-notices.d.ts +37 -0
  163. package/dist/projected-process-task-notices.d.ts.map +1 -0
  164. package/dist/projected-process-task-notices.js +225 -0
  165. package/dist/projected-process-task-notices.js.map +1 -0
  166. package/dist/projected-prompt-child-view-renderer.d.ts +101 -0
  167. package/dist/projected-prompt-child-view-renderer.d.ts.map +1 -0
  168. package/dist/projected-prompt-child-view-renderer.js +442 -0
  169. package/dist/projected-prompt-child-view-renderer.js.map +1 -0
  170. package/dist/projected-prompt-document-preview.d.ts +39 -0
  171. package/dist/projected-prompt-document-preview.d.ts.map +1 -0
  172. package/dist/projected-prompt-document-preview.js +50 -0
  173. package/dist/projected-prompt-document-preview.js.map +1 -0
  174. package/dist/projected-prompt-view.d.ts +35 -0
  175. package/dist/projected-prompt-view.d.ts.map +1 -0
  176. package/dist/projected-prompt-view.js +292 -0
  177. package/dist/projected-prompt-view.js.map +1 -0
  178. package/dist/projected-query-form.d.ts +56 -0
  179. package/dist/projected-query-form.d.ts.map +1 -0
  180. package/dist/projected-query-form.js +100 -0
  181. package/dist/projected-query-form.js.map +1 -0
  182. package/dist/projected-record-details.d.ts +20 -0
  183. package/dist/projected-record-details.d.ts.map +1 -0
  184. package/dist/projected-record-details.js +60 -0
  185. package/dist/projected-record-details.js.map +1 -0
  186. package/dist/projected-routed-surface-runtime.d.ts +86 -0
  187. package/dist/projected-routed-surface-runtime.d.ts.map +1 -0
  188. package/dist/projected-routed-surface-runtime.js +332 -0
  189. package/dist/projected-routed-surface-runtime.js.map +1 -0
  190. package/dist/projected-tabs-view.d.ts +21 -0
  191. package/dist/projected-tabs-view.d.ts.map +1 -0
  192. package/dist/projected-tabs-view.js +140 -0
  193. package/dist/projected-tabs-view.js.map +1 -0
  194. package/dist/projected-view-chrome.d.ts +15 -0
  195. package/dist/projected-view-chrome.d.ts.map +1 -0
  196. package/dist/projected-view-chrome.js +67 -0
  197. package/dist/projected-view-chrome.js.map +1 -0
  198. package/dist/projected-view-surface.d.ts +34 -0
  199. package/dist/projected-view-surface.d.ts.map +1 -0
  200. package/dist/projected-view-surface.js +40 -0
  201. package/dist/projected-view-surface.js.map +1 -0
  202. package/dist/standard-collection-chrome-slot-renderers.d.ts +26 -0
  203. package/dist/standard-collection-chrome-slot-renderers.d.ts.map +1 -0
  204. package/dist/standard-collection-chrome-slot-renderers.js +250 -0
  205. package/dist/standard-collection-chrome-slot-renderers.js.map +1 -0
  206. package/dist/standard-view-chrome-slot-renderers.d.ts +57 -0
  207. package/dist/standard-view-chrome-slot-renderers.d.ts.map +1 -0
  208. package/dist/standard-view-chrome-slot-renderers.js +614 -0
  209. package/dist/standard-view-chrome-slot-renderers.js.map +1 -0
  210. package/package.json +68 -0
  211. package/src/document-workspace-surface-slot-renderers.tsx +395 -0
  212. package/src/index.ts +53 -0
  213. package/src/navigation-shell-frame-renderer-registry.ts +29 -0
  214. package/src/navigation-shell-slot-renderer-registry.ts +46 -0
  215. package/src/page-host-unavailable-renderer.tsx +79 -0
  216. package/src/presentation-action-group.tsx +475 -0
  217. package/src/presentation-badge-target-interpreter.ts +54 -0
  218. package/src/presentation-component-groups.ts +2505 -0
  219. package/src/presentation-component-system-diagnostics.ts +848 -0
  220. package/src/presentation-component-system.ts +365 -0
  221. package/src/presentation-icon-diagnostics.ts +53 -0
  222. package/src/presentation-icon-registry.tsx +181 -0
  223. package/src/presentation-projection-trace-panel.tsx +140 -0
  224. package/src/presentation-routed-surface-host.tsx +48 -0
  225. package/src/presentation-shadcn-component-system.ts +102 -0
  226. package/src/presentation-standard-renderers.tsx +1290 -0
  227. package/src/presentation-surface-renderer.tsx +263 -0
  228. package/src/presentation-value-renderers.tsx +40 -0
  229. package/src/process-task-icons.tsx +258 -0
  230. package/src/projected-activity-state.tsx +63 -0
  231. package/src/projected-collection-action-runtime-diagnostics.ts +22 -0
  232. package/src/projected-collection-view.tsx +1273 -0
  233. package/src/projected-document-action-status-notices.tsx +66 -0
  234. package/src/projected-document-badges.tsx +134 -0
  235. package/src/projected-document-editor-surface.tsx +808 -0
  236. package/src/projected-document-workspace-notices.tsx +77 -0
  237. package/src/projected-document-workspace-prompt-child-view-registry.ts +99 -0
  238. package/src/projected-document-workspace-prompt-child-view-renderers.tsx +205 -0
  239. package/src/projected-document-workspace-shell.tsx +427 -0
  240. package/src/projected-document-workspace.tsx +216 -0
  241. package/src/projected-field-value-rendering.tsx +704 -0
  242. package/src/projected-inline-list.tsx +434 -0
  243. package/src/projected-input-form.tsx +1218 -0
  244. package/src/projected-metric-dashboard.tsx +106 -0
  245. package/src/projected-metric-strip.tsx +244 -0
  246. package/src/projected-navigation-shell-view-host.tsx +177 -0
  247. package/src/projected-navigation-shell.tsx +219 -0
  248. package/src/projected-presentation-badges.tsx +95 -0
  249. package/src/projected-presentation-diagnostics.tsx +120 -0
  250. package/src/projected-presentation-flow-layer.tsx +186 -0
  251. package/src/projected-process-task-notices.tsx +501 -0
  252. package/src/projected-prompt-child-view-renderer.tsx +698 -0
  253. package/src/projected-prompt-document-preview.tsx +197 -0
  254. package/src/projected-prompt-view.tsx +592 -0
  255. package/src/projected-query-form.tsx +286 -0
  256. package/src/projected-record-details.tsx +133 -0
  257. package/src/projected-routed-surface-runtime.tsx +713 -0
  258. package/src/projected-tabs-view.tsx +308 -0
  259. package/src/projected-view-chrome.tsx +148 -0
  260. package/src/projected-view-surface.tsx +131 -0
  261. package/src/standard-collection-chrome-slot-renderers.tsx +391 -0
  262. package/src/standard-view-chrome-slot-renderers.tsx +1064 -0
@@ -0,0 +1,713 @@
1
+ import { useCallback, useMemo, useState, type Dispatch, type SetStateAction } from 'react'
2
+ import { useLocation, useNavigate } from 'react-router'
3
+
4
+ import {
5
+ applyPresentationPaginationToRequest,
6
+ applyPresentationActionResultPolicyStateWrites,
7
+ applyPresentationActionResultStateWrites,
8
+ createInitialPresentationPaginationState,
9
+ createNextPresentationPaginationState,
10
+ projectPresentationDataSourceBindings,
11
+ createPresentationCollectionPaginationBindings,
12
+ createPresentationPaginationSearch,
13
+ createPreviousPresentationPaginationState,
14
+ defaultPresentationComponentSet,
15
+ getPresentationPaginationPageIndex,
16
+ getPresentationSurfaceDataSourceIds,
17
+ getPresentationSurfaceViewTree,
18
+ normalizePresentationPaginationState,
19
+ projectPresentationCollectionPaginationDiagnostics,
20
+ projectPresentationDataSourceCoverageDiagnostics,
21
+ readPresentationPaginationStateFromSearch,
22
+ resolvePresentationSurface,
23
+ type NavigationTarget,
24
+ type ActionDefinition,
25
+ type ActionResultStateWriteDefinition,
26
+ type PresentationDataSourceBindingProjectionRegistry,
27
+ type PresentationActionResultStateValues,
28
+ type PresentationDataSourceTargetInterpretation,
29
+ type PresentationCollectionPaginationRequestMap,
30
+ type PresentationModuleDefinition,
31
+ type PresentationNavigationRuntime,
32
+ type PresentationPaginationBinding,
33
+ type PresentationPaginationRuntime,
34
+ type PresentationPaginationState,
35
+ type PresentationProjectionDiagnostic,
36
+ type PresentationQueryFormStateMap,
37
+ type PresentationSurface,
38
+ type QueryFormDefinition,
39
+ type ViewDefinition,
40
+ } from '@cohesivesystems/presentation-core'
41
+ import type {
42
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
43
+ } from './presentation-shadcn-component-system'
44
+ import {
45
+ createPresentationQueryFormRuntime,
46
+ resolvePresentationQueryFormStateAdapters,
47
+ usePresentationModule,
48
+ usePresentationNavigationRuntime,
49
+ usePresentationQueryFormStateEntries,
50
+ usePresentationQueryFormStateMap,
51
+ useRegisterPresentationProjectionDiagnostics,
52
+ type PresentationQueryFormStateAdapter,
53
+ type PresentationQueryFormStateAdapterRegistry,
54
+ type PresentationQueryFormStateEntry,
55
+ type PresentationRendererRegistry,
56
+ type RouteParameterValues,
57
+ } from '@cohesivesystems/presentation-react'
58
+ import type { PresentationDesignSystem } from '@cohesivesystems/presentation-tailwind'
59
+ import {
60
+ projectPresentationRoutedSurfaceLayoutDiagnostics,
61
+ resolvePresentationRoutedSurfaceLayout,
62
+ } from '@cohesivesystems/presentation-tailwind'
63
+ import {
64
+ PresentationRoutedSurfaceHost,
65
+ } from './presentation-routed-surface-host'
66
+
67
+ export interface ProjectedRoutedSurfaceRouteContext {
68
+ readonly collectionPagination?: Readonly<Record<string, PresentationPaginationRuntime>>
69
+ readonly queryFormRuntimes?: Readonly<Record<string, unknown>>
70
+ readonly routeParameters?: RouteParameterValues
71
+ }
72
+
73
+ export type ProjectedRoutedSurfacePaginationRequestMap =
74
+ PresentationCollectionPaginationRequestMap
75
+
76
+ export interface ProjectedRoutedSurfaceRuntimeProps<TContext = ProjectedRoutedSurfaceRouteContext> {
77
+ readonly className?: string
78
+ readonly componentSet?: string
79
+ readonly componentSystem: PresentationComponentSystem
80
+ readonly createCollectionPaginationBindings?: (
81
+ context: ProjectedRoutedSurfaceCollectionPaginationBindingContext,
82
+ ) => readonly PresentationPaginationBinding[]
83
+ readonly createDataSourceBindingRegistry: (
84
+ context: ProjectedRoutedSurfaceRuntimeContext<TContext>,
85
+ ) => PresentationDataSourceBindingProjectionRegistry
86
+ readonly createPaginationRequests?: (
87
+ bindings: readonly PresentationPaginationBinding[],
88
+ states: Readonly<Record<string, PresentationPaginationState>>,
89
+ ) => ProjectedRoutedSurfacePaginationRequestMap
90
+ readonly createRendererRegistry: (
91
+ context: ProjectedRoutedSurfaceRendererRegistryContext<TContext>,
92
+ ) => PresentationRendererRegistry<TContext>
93
+ readonly createRouteContext?: (
94
+ context: ProjectedRoutedSurfaceRuntimeContext<TContext>,
95
+ ) => TContext
96
+ readonly dataSourceTargetInterpretation: PresentationDataSourceTargetInterpretation
97
+ /** Fallback collection page size used when the presentation IR has no default. */
98
+ readonly defaultCollectionPageSize?: number
99
+ readonly designSystem: PresentationDesignSystem
100
+ readonly navigationTarget: NavigationTarget
101
+ readonly projectCollectionPaginationDiagnostics?: (
102
+ context: ProjectedRoutedSurfaceCollectionPaginationDiagnosticsContext,
103
+ ) => readonly PresentationProjectionDiagnostic[]
104
+ readonly queryFormStateAdapterRegistry: PresentationQueryFormStateAdapterRegistry
105
+ readonly resolveContentClassName?: (
106
+ context: ProjectedRoutedSurfaceRuntimeContext<TContext>,
107
+ ) => string | undefined
108
+ readonly routeParameters: RouteParameterValues
109
+ }
110
+
111
+ export interface ProjectedRoutedSurfaceCollectionPaginationBindingContext {
112
+ readonly componentSystem: PresentationComponentSystem
113
+ readonly dataSourceIds: readonly string[]
114
+ /** Fallback collection page size used when the presentation IR has no default. */
115
+ readonly defaultPageSize?: number
116
+ readonly designSystem: PresentationDesignSystem
117
+ readonly module: PresentationModuleDefinition | null
118
+ readonly views: readonly ViewDefinition[]
119
+ }
120
+
121
+ export interface ProjectedRoutedSurfaceCollectionPaginationDiagnosticsContext {
122
+ readonly bindings: readonly PresentationPaginationBinding[]
123
+ readonly componentSystem: PresentationComponentSystem
124
+ readonly designSystem: PresentationDesignSystem
125
+ readonly module: PresentationModuleDefinition | null
126
+ readonly sourceId: string
127
+ readonly views: readonly ViewDefinition[]
128
+ }
129
+
130
+ export interface ProjectedRoutedSurfaceRuntimeContext<TContext = ProjectedRoutedSurfaceRouteContext> {
131
+ readonly actionResultState: ProjectedRoutedSurfaceActionResultStateRuntime
132
+ readonly collectionPagination: Readonly<Record<string, PresentationPaginationRuntime>>
133
+ readonly collectionPaginationBindings: readonly PresentationPaginationBinding[]
134
+ readonly collectionPaginationStates: Readonly<Record<string, PresentationPaginationState>>
135
+ readonly componentSystem: PresentationComponentSystem
136
+ readonly dataSourceIds: readonly string[]
137
+ readonly designSystem: PresentationDesignSystem
138
+ readonly module: PresentationModuleDefinition | null
139
+ readonly navigationRuntime: PresentationNavigationRuntime
140
+ readonly navigationTarget: NavigationTarget
141
+ readonly paginationRequestsByDataSourceId: ProjectedRoutedSurfacePaginationRequestMap
142
+ readonly queryFormRuntimes: Readonly<Record<string, unknown>>
143
+ readonly queryFormStates: PresentationQueryFormStateMap
144
+ readonly routeContext?: TContext
145
+ readonly routeParameters: RouteParameterValues
146
+ readonly surface: PresentationSurface | null
147
+ readonly surfaceViews: readonly ViewDefinition[]
148
+ }
149
+
150
+ export interface ProjectedRoutedSurfaceActionResultStateRuntime {
151
+ readonly applyActionResult: (
152
+ action: Pick<ActionDefinition, 'Result'> | null | undefined,
153
+ result: unknown,
154
+ ) => void
155
+ readonly applyStateWrites: (
156
+ writes: readonly ActionResultStateWriteDefinition[] | null | undefined,
157
+ result: unknown,
158
+ ) => void
159
+ readonly values: PresentationActionResultStateValues
160
+ }
161
+
162
+ export interface ProjectedRoutedSurfaceRendererRegistryContext<TContext = ProjectedRoutedSurfaceRouteContext>
163
+ extends ProjectedRoutedSurfaceRuntimeContext<TContext> {
164
+ readonly routeContext: TContext
165
+ }
166
+
167
+ /**
168
+ * Standard React runtime for a routed semantic presentation surface.
169
+ *
170
+ * The backend presentation module declares the route target, surface tree,
171
+ * query forms, and data sources. This runtime handles the target-independent
172
+ * mechanics of projecting those constructs into React state, URL state,
173
+ * pagination windows, data-source bindings, and diagnostics. Product code
174
+ * supplies target interpretations for auth, concrete data execution, and
175
+ * renderer registries.
176
+ */
177
+ export function ProjectedRoutedSurfaceRuntime<TContext = ProjectedRoutedSurfaceRouteContext>({
178
+ className,
179
+ componentSet = defaultPresentationComponentSet,
180
+ componentSystem,
181
+ createCollectionPaginationBindings = createPresentationCollectionPaginationBindings,
182
+ createDataSourceBindingRegistry,
183
+ createPaginationRequests = createProjectedRoutedSurfacePaginationRequests,
184
+ createRendererRegistry,
185
+ createRouteContext,
186
+ dataSourceTargetInterpretation,
187
+ defaultCollectionPageSize,
188
+ designSystem,
189
+ navigationTarget,
190
+ projectCollectionPaginationDiagnostics = projectPresentationCollectionPaginationDiagnostics,
191
+ queryFormStateAdapterRegistry,
192
+ resolveContentClassName,
193
+ routeParameters,
194
+ }: ProjectedRoutedSurfaceRuntimeProps<TContext>) {
195
+ const navigationRuntime = usePresentationNavigationRuntime()
196
+ const module = usePresentationModule()
197
+ const location = useLocation()
198
+ const navigate = useNavigate()
199
+ const queryFormStates = usePresentationQueryFormStateMap()
200
+ const queryFormStateEntries = usePresentationQueryFormStateEntries()
201
+ const [actionResultStateValues, setActionResultStateValues] = useState<PresentationActionResultStateValues>({})
202
+ const applyActionResult = useCallback(
203
+ (
204
+ action: Pick<ActionDefinition, 'Result'> | null | undefined,
205
+ result: unknown,
206
+ ) => {
207
+ setActionResultStateValues((current) =>
208
+ applyPresentationActionResultPolicyStateWrites({
209
+ policy: action?.Result,
210
+ result,
211
+ state: current,
212
+ }),
213
+ )
214
+ },
215
+ [],
216
+ )
217
+ const applyStateWrites = useCallback(
218
+ (
219
+ writes: readonly ActionResultStateWriteDefinition[] | null | undefined,
220
+ result: unknown,
221
+ ) => {
222
+ setActionResultStateValues((current) =>
223
+ applyPresentationActionResultStateWrites({
224
+ result,
225
+ state: current,
226
+ writes,
227
+ }),
228
+ )
229
+ },
230
+ [],
231
+ )
232
+ const actionResultState = useMemo(
233
+ () => ({
234
+ applyActionResult,
235
+ applyStateWrites,
236
+ values: actionResultStateValues,
237
+ }) satisfies ProjectedRoutedSurfaceActionResultStateRuntime,
238
+ [
239
+ actionResultStateValues,
240
+ applyActionResult,
241
+ applyStateWrites,
242
+ ],
243
+ )
244
+ const queryFormStateAdapters = useMemo(
245
+ () => resolvePresentationQueryFormStateAdapters(module, queryFormStateAdapterRegistry),
246
+ [module, queryFormStateAdapterRegistry],
247
+ )
248
+ const surface = useMemo(
249
+ () => module ? resolvePresentationSurface(module, navigationTarget) : null,
250
+ [module, navigationTarget],
251
+ )
252
+ const dataSourceIds = useMemo(
253
+ () => getPresentationSurfaceDataSourceIds(module, surface),
254
+ [module, surface],
255
+ )
256
+ const surfaceViews = useMemo(
257
+ () => getPresentationSurfaceViewTree(module, surface),
258
+ [module, surface],
259
+ )
260
+ const collectionPaginationBindings = useMemo(
261
+ () => createCollectionPaginationBindings({
262
+ componentSystem,
263
+ dataSourceIds,
264
+ defaultPageSize: defaultCollectionPageSize,
265
+ designSystem,
266
+ module,
267
+ views: surfaceViews,
268
+ }),
269
+ [
270
+ createCollectionPaginationBindings,
271
+ componentSystem,
272
+ dataSourceIds,
273
+ defaultCollectionPageSize,
274
+ designSystem,
275
+ module,
276
+ surfaceViews,
277
+ ],
278
+ )
279
+ const collectionPaginationStates = useMemo(
280
+ () =>
281
+ Object.fromEntries(
282
+ collectionPaginationBindings.map((binding) => [
283
+ binding.dataSourceId,
284
+ readPresentationPaginationStateFromSearch(location.search, binding),
285
+ ]),
286
+ ) as Readonly<Record<string, PresentationPaginationState>>,
287
+ [collectionPaginationBindings, location.search],
288
+ )
289
+ const paginationRequestsByDataSourceId = useMemo(
290
+ () => createPaginationRequests(
291
+ collectionPaginationBindings,
292
+ collectionPaginationStates,
293
+ ),
294
+ [
295
+ collectionPaginationBindings,
296
+ collectionPaginationStates,
297
+ createPaginationRequests,
298
+ ],
299
+ )
300
+ const commitRoutedSurfaceSearch = useCallback(
301
+ (
302
+ search: string,
303
+ options: { readonly replace?: boolean } = {},
304
+ ) => {
305
+ const normalizedSearch = search
306
+ ? search.startsWith('?')
307
+ ? search
308
+ : `?${search}`
309
+ : ''
310
+ const nextHref = `${location.pathname}${normalizedSearch}${location.hash}`
311
+ const currentHref = `${location.pathname}${location.search}${location.hash}`
312
+ if (nextHref !== currentHref) {
313
+ void navigate(nextHref, {
314
+ flushSync: true,
315
+ replace: options.replace ?? false,
316
+ })
317
+ }
318
+ },
319
+ [
320
+ location.hash,
321
+ location.pathname,
322
+ location.search,
323
+ navigate,
324
+ ],
325
+ )
326
+ const commitCollectionPagination = useCallback(
327
+ (
328
+ binding: PresentationPaginationBinding,
329
+ nextState: PresentationPaginationState,
330
+ options: { readonly replace?: boolean } = {},
331
+ ) => {
332
+ const search = createPresentationPaginationSearch(
333
+ location.search,
334
+ binding,
335
+ normalizePresentationPaginationState(nextState),
336
+ )
337
+ commitRoutedSurfaceSearch(search, options)
338
+ },
339
+ [
340
+ commitRoutedSurfaceSearch,
341
+ location.search,
342
+ ],
343
+ )
344
+ const queryFormRuntimes = useMemo(
345
+ () =>
346
+ createQueryFormRuntimes({
347
+ adapters: queryFormStateAdapters,
348
+ collectionPaginationBindings,
349
+ commitRoutedSurfaceSearch,
350
+ entries: queryFormStateEntries,
351
+ locationSearch: location.search,
352
+ module,
353
+ }),
354
+ [
355
+ collectionPaginationBindings,
356
+ commitRoutedSurfaceSearch,
357
+ location.search,
358
+ module,
359
+ queryFormStateAdapters,
360
+ queryFormStateEntries,
361
+ ],
362
+ )
363
+ const collectionPagination = useMemo(
364
+ () =>
365
+ Object.fromEntries(
366
+ collectionPaginationBindings.map((binding) => {
367
+ const state = collectionPaginationStates[binding.dataSourceId] ??
368
+ createInitialPresentationPaginationState(binding)
369
+ const pageIndex = getPresentationPaginationPageIndex(state)
370
+ return [
371
+ binding.dataSourceId,
372
+ {
373
+ binding,
374
+ canGoPreviousPage: pageIndex > 0,
375
+ dataSourceId: binding.dataSourceId,
376
+ goToFirstPage: () =>
377
+ commitCollectionPagination(
378
+ binding,
379
+ createInitialPresentationPaginationState(binding),
380
+ ),
381
+ goToNextPage: (response?: unknown) =>
382
+ commitCollectionPagination(
383
+ binding,
384
+ createNextPresentationPaginationState(binding, state, response),
385
+ ),
386
+ goToPreviousPage: () =>
387
+ commitCollectionPagination(
388
+ binding,
389
+ createPreviousPresentationPaginationState(state),
390
+ ),
391
+ pageIndex,
392
+ pageSize: state.pageSize,
393
+ state,
394
+ } satisfies PresentationPaginationRuntime,
395
+ ]
396
+ }),
397
+ ) as Readonly<Record<string, PresentationPaginationRuntime>>,
398
+ [
399
+ collectionPaginationBindings,
400
+ collectionPaginationStates,
401
+ commitCollectionPagination,
402
+ ],
403
+ )
404
+ const runtimeContext = useMemo(
405
+ () => ({
406
+ actionResultState,
407
+ collectionPagination,
408
+ collectionPaginationBindings,
409
+ collectionPaginationStates,
410
+ componentSystem,
411
+ dataSourceIds,
412
+ designSystem,
413
+ module,
414
+ navigationRuntime,
415
+ navigationTarget,
416
+ paginationRequestsByDataSourceId,
417
+ queryFormRuntimes,
418
+ queryFormStates,
419
+ routeParameters,
420
+ surface,
421
+ surfaceViews,
422
+ }) satisfies ProjectedRoutedSurfaceRuntimeContext<TContext>,
423
+ [
424
+ actionResultState,
425
+ collectionPagination,
426
+ collectionPaginationBindings,
427
+ collectionPaginationStates,
428
+ componentSystem,
429
+ dataSourceIds,
430
+ designSystem,
431
+ module,
432
+ navigationRuntime,
433
+ navigationTarget,
434
+ paginationRequestsByDataSourceId,
435
+ queryFormRuntimes,
436
+ queryFormStates,
437
+ routeParameters,
438
+ surface,
439
+ surfaceViews,
440
+ ],
441
+ )
442
+ const routeContext = useMemo(
443
+ () =>
444
+ createRouteContext?.(runtimeContext) ??
445
+ ({
446
+ collectionPagination,
447
+ queryFormRuntimes,
448
+ routeParameters,
449
+ } satisfies ProjectedRoutedSurfaceRouteContext) as TContext,
450
+ [
451
+ collectionPagination,
452
+ createRouteContext,
453
+ queryFormRuntimes,
454
+ routeParameters,
455
+ runtimeContext,
456
+ ],
457
+ )
458
+ const runtimeContextWithRouteContext = useMemo(
459
+ () => ({
460
+ ...runtimeContext,
461
+ routeContext,
462
+ }),
463
+ [routeContext, runtimeContext],
464
+ )
465
+ const dataSourceBindingRegistry = useMemo(
466
+ () => createDataSourceBindingRegistry(runtimeContextWithRouteContext),
467
+ [createDataSourceBindingRegistry, runtimeContextWithRouteContext],
468
+ )
469
+ const bindings = useMemo(
470
+ () =>
471
+ projectPresentationDataSourceBindings({
472
+ context: {
473
+ queryFormStates,
474
+ routeParameters,
475
+ workspaceId: surface?.workspaceRef?.WorkspaceId ?? null,
476
+ },
477
+ dataSourceIds,
478
+ module,
479
+ registry: dataSourceBindingRegistry,
480
+ }),
481
+ [
482
+ dataSourceBindingRegistry,
483
+ dataSourceIds,
484
+ module,
485
+ queryFormStates,
486
+ routeParameters,
487
+ surface,
488
+ ],
489
+ )
490
+ const dataSourceDiagnosticsSourceId = `routed-surface-data-sources:${navigationTarget.route.Id}`
491
+ const dataSourceCoverageDiagnostics = useMemo(
492
+ () =>
493
+ projectPresentationDataSourceCoverageDiagnostics({
494
+ bindings,
495
+ dataSourceIds,
496
+ module,
497
+ routeParameters,
498
+ sourceId: dataSourceDiagnosticsSourceId,
499
+ targetInterpretation: dataSourceTargetInterpretation,
500
+ }),
501
+ [
502
+ bindings,
503
+ dataSourceDiagnosticsSourceId,
504
+ dataSourceIds,
505
+ dataSourceTargetInterpretation,
506
+ module,
507
+ routeParameters,
508
+ ],
509
+ )
510
+ useRegisterPresentationProjectionDiagnostics(
511
+ dataSourceDiagnosticsSourceId,
512
+ dataSourceCoverageDiagnostics,
513
+ )
514
+
515
+ const paginationDiagnosticsSourceId =
516
+ `routed-surface-collection-pagination:${navigationTarget.route.Id}`
517
+ const collectionPaginationDiagnostics = useMemo(
518
+ () =>
519
+ projectCollectionPaginationDiagnostics?.({
520
+ bindings: collectionPaginationBindings,
521
+ componentSystem,
522
+ designSystem,
523
+ module,
524
+ sourceId: paginationDiagnosticsSourceId,
525
+ views: surfaceViews,
526
+ }) ?? [],
527
+ [
528
+ collectionPaginationBindings,
529
+ componentSystem,
530
+ designSystem,
531
+ module,
532
+ paginationDiagnosticsSourceId,
533
+ projectCollectionPaginationDiagnostics,
534
+ surfaceViews,
535
+ ],
536
+ )
537
+ useRegisterPresentationProjectionDiagnostics(
538
+ paginationDiagnosticsSourceId,
539
+ collectionPaginationDiagnostics,
540
+ )
541
+
542
+ const layoutDiagnosticsSourceId =
543
+ `routed-surface-layout:${navigationTarget.route.Id}`
544
+ const routedSurfaceLayoutDiagnostics = useMemo(
545
+ () =>
546
+ projectPresentationRoutedSurfaceLayoutDiagnostics({
547
+ designSystem,
548
+ sourceId: layoutDiagnosticsSourceId,
549
+ surface,
550
+ }),
551
+ [
552
+ designSystem,
553
+ layoutDiagnosticsSourceId,
554
+ surface,
555
+ ],
556
+ )
557
+ useRegisterPresentationProjectionDiagnostics(
558
+ layoutDiagnosticsSourceId,
559
+ routedSurfaceLayoutDiagnostics,
560
+ )
561
+
562
+ const rendererRegistry = useMemo(
563
+ () => createRendererRegistry(runtimeContextWithRouteContext),
564
+ [createRendererRegistry, runtimeContextWithRouteContext],
565
+ )
566
+ const routedSurfaceLayout = useMemo(
567
+ () => resolvePresentationRoutedSurfaceLayout({ designSystem, surface }),
568
+ [designSystem, surface],
569
+ )
570
+ const contentClassName = useMemo(
571
+ () =>
572
+ resolveContentClassName?.(runtimeContextWithRouteContext) ??
573
+ routedSurfaceLayout.contentClassName,
574
+ [resolveContentClassName, routedSurfaceLayout, runtimeContextWithRouteContext],
575
+ )
576
+
577
+ return (
578
+ <PresentationRoutedSurfaceHost
579
+ bindings={bindings}
580
+ className={className ?? routedSurfaceLayout.className}
581
+ componentSet={componentSet}
582
+ contentClassName={contentClassName}
583
+ context={routeContext}
584
+ rendererRegistry={rendererRegistry}
585
+ surface={surface}
586
+ />
587
+ )
588
+ }
589
+
590
+ export function createProjectedRoutedSurfacePaginationRequests(
591
+ bindings: readonly PresentationPaginationBinding[],
592
+ states: Readonly<Record<string, PresentationPaginationState>>,
593
+ ): ProjectedRoutedSurfacePaginationRequestMap {
594
+ return Object.fromEntries(
595
+ bindings.map((binding) => [
596
+ binding.dataSourceId,
597
+ applyPresentationPaginationToRequest(
598
+ {},
599
+ binding,
600
+ states[binding.dataSourceId],
601
+ ),
602
+ ]),
603
+ )
604
+ }
605
+
606
+ interface CreateQueryFormRuntimesOptions {
607
+ readonly adapters: readonly PresentationQueryFormStateAdapter[]
608
+ readonly collectionPaginationBindings: readonly PresentationPaginationBinding[]
609
+ readonly commitRoutedSurfaceSearch: (
610
+ search: string,
611
+ options?: { readonly replace?: boolean },
612
+ ) => void
613
+ readonly entries: Readonly<Record<string, PresentationQueryFormStateEntry>>
614
+ readonly locationSearch: string
615
+ readonly module: PresentationModuleDefinition | null
616
+ }
617
+
618
+ function createQueryFormRuntimes({
619
+ adapters,
620
+ collectionPaginationBindings,
621
+ commitRoutedSurfaceSearch,
622
+ entries,
623
+ locationSearch,
624
+ module,
625
+ }: CreateQueryFormRuntimesOptions) {
626
+ return Object.fromEntries(
627
+ adapters.flatMap((adapter) => {
628
+ const entry = entries[adapter.queryFormId]
629
+ if (!entry?.queryForm) {
630
+ return []
631
+ }
632
+
633
+ const queryForm = entry.queryForm
634
+ const runtime = createPresentationQueryFormRuntime({
635
+ applyValue: ({ choiceValuesByFieldId, value }) => {
636
+ entry.setAppliedValue(value)
637
+ const resetSearch = createQueryFormPaginationResetSearch(
638
+ locationSearch,
639
+ queryForm,
640
+ collectionPaginationBindings,
641
+ )
642
+ const nextSearch = adapter.createAppliedSearch?.({
643
+ choiceValuesByFieldId,
644
+ inputForm: entry.inputForm,
645
+ module,
646
+ queryForm,
647
+ search: resetSearch,
648
+ value,
649
+ }) ?? resetSearch
650
+ commitRoutedSurfaceSearch(nextSearch)
651
+ },
652
+ createDefaultValue: ({ choiceValuesByFieldId }) =>
653
+ adapter.createDefaultValue({
654
+ choiceValuesByFieldId,
655
+ inputForm: entry.inputForm,
656
+ module,
657
+ queryForm,
658
+ search: locationSearch,
659
+ }),
660
+ normalizeValue: adapter.normalizeValue
661
+ ? ({ choiceValuesByFieldId, value }) =>
662
+ adapter.normalizeValue?.({
663
+ choiceValuesByFieldId,
664
+ inputForm: entry.inputForm,
665
+ module,
666
+ queryForm,
667
+ search: locationSearch,
668
+ value,
669
+ }) ?? value
670
+ : undefined,
671
+ queryForm,
672
+ setDraftValue: entry.setDraftValue as Dispatch<SetStateAction<object>>,
673
+ value: coerceObjectValue(entry.draftValue),
674
+ })
675
+
676
+ return runtime ? [[queryForm.Id, runtime] as const] : []
677
+ }),
678
+ )
679
+ }
680
+
681
+ function createQueryFormPaginationResetSearch(
682
+ search: string,
683
+ queryForm: QueryFormDefinition,
684
+ paginationBindings: readonly PresentationPaginationBinding[],
685
+ ) {
686
+ const targetDataSourceIds = getQueryFormTargetDataSourceIds(queryForm)
687
+ return paginationBindings.reduce(
688
+ (nextSearch, binding) =>
689
+ targetDataSourceIds.has(binding.dataSourceId)
690
+ ? createPresentationPaginationSearch(
691
+ nextSearch,
692
+ binding,
693
+ createInitialPresentationPaginationState(binding),
694
+ )
695
+ : nextSearch,
696
+ search,
697
+ )
698
+ }
699
+
700
+ function getQueryFormTargetDataSourceIds(queryForm: QueryFormDefinition) {
701
+ const state = queryForm.Target.State
702
+ return new Set(
703
+ [
704
+ state.AppliedDataSourceId,
705
+ state.ResultDataSourceId,
706
+ ...state.SynchronizedDataSourceIds,
707
+ ].filter((dataSourceId): dataSourceId is string => Boolean(dataSourceId)),
708
+ )
709
+ }
710
+
711
+ function coerceObjectValue(value: unknown) {
712
+ return value && typeof value === 'object' ? value as object : {}
713
+ }