@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,219 @@
1
+ import { type ReactNode, useCallback, useMemo } from 'react'
2
+
3
+ import {
4
+ defaultNavigationShellSlotPlacements,
5
+ findPresentationView,
6
+ projectNavigationShellDiagnostics,
7
+ resolveProjectedNavigationShellSlots,
8
+ } from '@cohesivesystems/presentation-core'
9
+ import {
10
+ getNavigationShellFrameRendererRegistryKeys,
11
+ resolveNavigationShellFrameRenderer,
12
+ type NavigationShellFrameRendererRegistry,
13
+ } from './navigation-shell-frame-renderer-registry'
14
+ import {
15
+ projectNavigationShellLayoutDiagnostics,
16
+ resolveProjectedNavigationShellLayout,
17
+ resolveProjectedNavigationShellSlotLayout,
18
+ } from '@cohesivesystems/presentation-tailwind'
19
+ import type {
20
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
21
+ } from './presentation-shadcn-component-system'
22
+ import {
23
+ projectPresentationDesignSystemBindingDiagnostics,
24
+ projectPresentationComponentSystemDiagnostics,
25
+ } from './presentation-component-system-diagnostics'
26
+ import type { PresentationDesignSystem } from '@cohesivesystems/presentation-tailwind'
27
+ import {
28
+ getNavigationShellSlotRendererRegistryKeys,
29
+ resolveNavigationShellSlotRenderer,
30
+ type NavigationShellSlotRendererRegistry,
31
+ } from './navigation-shell-slot-renderer-registry'
32
+ import {
33
+ usePresentationModule,
34
+ useRegisterPresentationProjectionDiagnostics,
35
+ } from '@cohesivesystems/presentation-react'
36
+ import {
37
+ standardNavigationShellSlotRenderers,
38
+ } from '@cohesivesystems/presentation-react'
39
+ import {
40
+ standardNavigationShellFrameRenderers,
41
+ } from '@cohesivesystems/presentation-react'
42
+ import type {
43
+ NavigationDefinition,
44
+ NavigationNodeDefinition,
45
+ NavigationShellRegionDefinition,
46
+ NavigationShellSlotDefinition,
47
+ } from '@cohesivesystems/presentation-contracts'
48
+
49
+ export interface ProjectedNavigationShellProps {
50
+ readonly activePath: string
51
+ readonly children: ReactNode
52
+ readonly componentSystem: PresentationComponentSystem
53
+ readonly defaultComponentSystem: PresentationComponentSystem
54
+ readonly designSystem: PresentationDesignSystem
55
+ readonly frameRendererRegistry?: NavigationShellFrameRendererRegistry
56
+ readonly isNodeIconSupported?: (icon: string) => boolean
57
+ readonly isShellRegionComponentBound?: (
58
+ componentKey: string,
59
+ region: NavigationShellRegionDefinition,
60
+ ) => boolean
61
+ readonly isShellRegionComponentTargetBound?: (
62
+ region: NavigationShellRegionDefinition,
63
+ ) => boolean
64
+ readonly isShellRegionSupported?: (region: NavigationShellRegionDefinition) => boolean
65
+ readonly navigation: NavigationDefinition
66
+ readonly renderNodeIcon?: (node: NavigationNodeDefinition) => ReactNode
67
+ readonly renderShellIcon?: (icon: string) => ReactNode
68
+ readonly renderShellRegion?: (region: NavigationShellRegionDefinition) => ReactNode
69
+ readonly slotRendererRegistry?: NavigationShellSlotRendererRegistry
70
+ readonly supportedSlotPlacements?: readonly string[]
71
+ }
72
+
73
+ /**
74
+ * Interprets a navigation shell from the presentation/navigation IR.
75
+ *
76
+ * The shell frame owns generic concerns such as brand chrome, primary
77
+ * navigation, placement slots, and the routed content slot. App-specific
78
+ * integrations remain attached through icon and shell-region renderers.
79
+ */
80
+ export function ProjectedNavigationShell({
81
+ activePath,
82
+ children,
83
+ componentSystem,
84
+ defaultComponentSystem,
85
+ designSystem,
86
+ isNodeIconSupported,
87
+ isShellRegionComponentBound,
88
+ isShellRegionComponentTargetBound,
89
+ isShellRegionSupported,
90
+ navigation,
91
+ renderNodeIcon,
92
+ renderShellIcon,
93
+ renderShellRegion,
94
+ frameRendererRegistry = standardNavigationShellFrameRenderers,
95
+ slotRendererRegistry = standardNavigationShellSlotRenderers,
96
+ supportedSlotPlacements = defaultNavigationShellSlotPlacements,
97
+ }: ProjectedNavigationShellProps) {
98
+ const module = usePresentationModule()
99
+ const shellSlots = useMemo(
100
+ () => resolveProjectedNavigationShellSlots(navigation),
101
+ [navigation],
102
+ )
103
+ const shellLayout = useMemo(
104
+ () => resolveProjectedNavigationShellLayout(navigation, shellSlots, designSystem),
105
+ [designSystem, navigation, shellSlots],
106
+ )
107
+ const shellFrameRendererKeys = useMemo(
108
+ () => getNavigationShellFrameRendererRegistryKeys(frameRendererRegistry),
109
+ [frameRendererRegistry],
110
+ )
111
+ const shellSlotRendererKeys = useMemo(
112
+ () => getNavigationShellSlotRendererRegistryKeys(slotRendererRegistry),
113
+ [slotRendererRegistry],
114
+ )
115
+ const renderSlot = useCallback(
116
+ (slot: NavigationShellSlotDefinition | null) => {
117
+ if (!slot) {
118
+ return null
119
+ }
120
+
121
+ const renderer = resolveNavigationShellSlotRenderer(slotRendererRegistry, slot)
122
+
123
+ return renderer?.({
124
+ activePath,
125
+ children,
126
+ componentSystem,
127
+ navigation,
128
+ renderNodeIcon,
129
+ renderShellIcon,
130
+ renderShellRegion,
131
+ slot,
132
+ slotLayout:
133
+ shellLayout.slotLayouts[slot.Id] ??
134
+ resolveProjectedNavigationShellSlotLayout(slot, designSystem),
135
+ }) ?? null
136
+ },
137
+ [
138
+ activePath,
139
+ children,
140
+ componentSystem,
141
+ designSystem,
142
+ navigation,
143
+ renderNodeIcon,
144
+ renderShellIcon,
145
+ renderShellRegion,
146
+ shellLayout,
147
+ slotRendererRegistry,
148
+ ],
149
+ )
150
+ const shellFrameRenderer = useMemo(
151
+ () => resolveNavigationShellFrameRenderer(frameRendererRegistry, navigation.Shell.Kind),
152
+ [frameRendererRegistry, navigation.Shell.Kind],
153
+ )
154
+ const diagnostics = useMemo(
155
+ () => [
156
+ ...projectPresentationComponentSystemDiagnostics({
157
+ componentSystem,
158
+ defaultComponentSystem,
159
+ sourceId: `navigation-shell:${navigation.Shell.Id}`,
160
+ }),
161
+ ...projectPresentationDesignSystemBindingDiagnostics({
162
+ componentSystem,
163
+ module,
164
+ sourceId: `navigation-shell:${navigation.Shell.Id}`,
165
+ }),
166
+ ...projectNavigationShellLayoutDiagnostics({
167
+ designSystem,
168
+ navigation,
169
+ shellFrameRendererKeys,
170
+ shellSlots,
171
+ }),
172
+ ...projectNavigationShellDiagnostics({
173
+ isNodeIconSupported,
174
+ isShellRegionComponentBound,
175
+ isShellRegionComponentTargetBound,
176
+ isShellRegionSupported,
177
+ isShellRegionViewBound: module
178
+ ? (viewId) => Boolean(findPresentationView(module, viewId))
179
+ : undefined,
180
+ navigation,
181
+ renderShellIconBound: Boolean(renderShellIcon),
182
+ shellSlotRendererKeys,
183
+ shellSlots,
184
+ supportedSlotPlacements,
185
+ }),
186
+ ],
187
+ [
188
+ componentSystem,
189
+ defaultComponentSystem,
190
+ designSystem,
191
+ isNodeIconSupported,
192
+ isShellRegionComponentBound,
193
+ isShellRegionComponentTargetBound,
194
+ isShellRegionSupported,
195
+ module,
196
+ navigation,
197
+ renderShellIcon,
198
+ shellFrameRendererKeys,
199
+ shellSlotRendererKeys,
200
+ shellSlots,
201
+ supportedSlotPlacements,
202
+ ],
203
+ )
204
+ useRegisterPresentationProjectionDiagnostics(
205
+ `navigation-shell:${navigation.Shell.Id}`,
206
+ diagnostics,
207
+ )
208
+
209
+ return shellFrameRenderer?.({
210
+ activePath,
211
+ children,
212
+ layout: shellLayout,
213
+ navigation,
214
+ renderNodeIcon,
215
+ renderShellIcon,
216
+ renderShellRegion,
217
+ renderSlot,
218
+ }) ?? children
219
+ }
@@ -0,0 +1,95 @@
1
+ import type { ReactNode } from 'react'
2
+ import type { PresentationBadgeVariant } from './presentation-component-groups'
3
+
4
+ import type {
5
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
6
+ } from './presentation-shadcn-component-system'
7
+ import type { PresentationDesignSystem } from '@cohesivesystems/presentation-tailwind'
8
+ import type {
9
+ ResolvedPresentationBadge,
10
+ } from '@cohesivesystems/presentation-core'
11
+
12
+ export interface ProjectedPresentationBadgeItem
13
+ extends Omit<ResolvedPresentationBadge, 'label'> {
14
+ readonly className?: string
15
+ readonly label: ReactNode
16
+ }
17
+
18
+ export interface ProjectedPresentationBadgeProps {
19
+ readonly badge: ProjectedPresentationBadgeItem
20
+ readonly className?: string
21
+ readonly componentSystem: PresentationComponentSystem
22
+ readonly designSystem: PresentationDesignSystem
23
+ readonly variant?: PresentationBadgeVariant
24
+ }
25
+
26
+ export interface ProjectedPresentationBadgesProps {
27
+ readonly badgeClassName?: string
28
+ readonly badges: readonly ProjectedPresentationBadgeItem[]
29
+ readonly className?: string
30
+ readonly componentSystem: PresentationComponentSystem
31
+ readonly designSystem: PresentationDesignSystem
32
+ readonly variant?: PresentationBadgeVariant
33
+ }
34
+
35
+ /**
36
+ * Standard badge interpreter for resolved presentation badge semantics.
37
+ *
38
+ * The badge model carries semantic tone and content only; this component is
39
+ * where the target component system and design system decide how that becomes
40
+ * concrete UI.
41
+ */
42
+ export function ProjectedPresentationBadge({
43
+ badge,
44
+ className,
45
+ componentSystem,
46
+ designSystem,
47
+ variant = 'outline',
48
+ }: ProjectedPresentationBadgeProps) {
49
+ const BadgeComponent = componentSystem.badges.Badge
50
+
51
+ return (
52
+ <BadgeComponent
53
+ className={cn(
54
+ designSystem.classNames.badge.tone({ tone: badge.tone }),
55
+ className,
56
+ badge.className,
57
+ )}
58
+ variant={variant}
59
+ >
60
+ {badge.label}
61
+ </BadgeComponent>
62
+ )
63
+ }
64
+
65
+ export function ProjectedPresentationBadges({
66
+ badgeClassName,
67
+ badges,
68
+ className,
69
+ componentSystem,
70
+ designSystem,
71
+ variant = 'outline',
72
+ }: ProjectedPresentationBadgesProps) {
73
+ if (badges.length === 0) {
74
+ return null
75
+ }
76
+
77
+ return (
78
+ <div className={cn('flex flex-wrap items-center gap-2', className)}>
79
+ {badges.map((badge, index) => (
80
+ <ProjectedPresentationBadge
81
+ badge={badge}
82
+ className={badgeClassName}
83
+ componentSystem={componentSystem}
84
+ designSystem={designSystem}
85
+ key={badge.id ?? index}
86
+ variant={variant}
87
+ />
88
+ ))}
89
+ </div>
90
+ )
91
+ }
92
+
93
+ function cn(...values: readonly (false | null | string | undefined)[]) {
94
+ return values.filter(Boolean).join(' ')
95
+ }
@@ -0,0 +1,120 @@
1
+ import type {
2
+ PresentationProjectionDiagnostic,
3
+ PresentationProjectionDiagnosticSeverity,
4
+ } from '@cohesivesystems/presentation-core'
5
+
6
+ export interface ProjectedPresentationDiagnosticsProps {
7
+ readonly diagnostics: readonly PresentationProjectionDiagnostic[]
8
+ readonly emptyLabel?: string
9
+ readonly minSeverity?: PresentationProjectionDiagnosticSeverity
10
+ readonly title?: string | null
11
+ }
12
+
13
+ const severityRank: Record<PresentationProjectionDiagnosticSeverity, number> = {
14
+ info: 0,
15
+ warning: 1,
16
+ error: 2,
17
+ }
18
+
19
+ /** Renders projection TODOs emitted by frontend interpreters. */
20
+ export function ProjectedPresentationDiagnostics({
21
+ diagnostics,
22
+ emptyLabel,
23
+ minSeverity = 'warning',
24
+ title = 'Projection diagnostics',
25
+ }: ProjectedPresentationDiagnosticsProps) {
26
+ const visibleDiagnostics = diagnostics.filter(
27
+ (diagnostic) => severityRank[diagnostic.severity] >= severityRank[minSeverity],
28
+ )
29
+
30
+ if (visibleDiagnostics.length === 0) {
31
+ return emptyLabel ? (
32
+ <p className="rounded-md border border-slate-950/10 bg-slate-50 px-3 py-2 text-sm text-slate-500">
33
+ {emptyLabel}
34
+ </p>
35
+ ) : null
36
+ }
37
+
38
+ const hasError = visibleDiagnostics.some((diagnostic) => diagnostic.severity === 'error')
39
+ const hasWarning = visibleDiagnostics.some((diagnostic) => diagnostic.severity === 'warning')
40
+
41
+ return (
42
+ <section
43
+ className={getDiagnosticsPanelClassName({ hasError, hasWarning })}
44
+ >
45
+ {title ? <div className="font-medium">{title}</div> : null}
46
+ <ul className="mt-1 grid gap-1">
47
+ {visibleDiagnostics.map((diagnostic) => (
48
+ <li className="grid gap-0.5" key={`${diagnostic.source}:${diagnostic.id}`}>
49
+ <div className="flex flex-wrap items-center gap-1">
50
+ <span className={getDiagnosticSeverityClassName(diagnostic.severity)}>
51
+ {formatDiagnosticSeverity(diagnostic.severity)}
52
+ </span>
53
+ {diagnostic.category ? (
54
+ <span className="rounded bg-white/70 px-1.5 py-0.5 text-[0.65rem] font-medium uppercase tracking-wide opacity-80">
55
+ {diagnostic.category}
56
+ </span>
57
+ ) : null}
58
+ {diagnostic.interpretation ? (
59
+ <span className="rounded bg-white/70 px-1.5 py-0.5 text-[0.65rem] font-medium uppercase tracking-wide opacity-80">
60
+ {diagnostic.interpretation.status}
61
+ </span>
62
+ ) : null}
63
+ <span>{diagnostic.message}</span>
64
+ </div>
65
+ <span className="break-all font-mono text-[0.7rem] opacity-75">
66
+ {diagnostic.source}
67
+ {diagnostic.interpretation
68
+ ? ` - target:${diagnostic.interpretation.target}`
69
+ : ''}
70
+ {diagnostic.subject ? ` - ${diagnostic.subject.kind}:${diagnostic.subject.id}` : ''}
71
+ </span>
72
+ {diagnostic.suggestedNextStep ? (
73
+ <span className="text-[0.72rem] opacity-85">
74
+ {diagnostic.suggestedNextStep}
75
+ </span>
76
+ ) : null}
77
+ </li>
78
+ ))}
79
+ </ul>
80
+ </section>
81
+ )
82
+ }
83
+
84
+ function getDiagnosticsPanelClassName({
85
+ hasError,
86
+ hasWarning,
87
+ }: {
88
+ readonly hasError: boolean
89
+ readonly hasWarning: boolean
90
+ }) {
91
+ if (hasError) {
92
+ return 'rounded-md border border-red-300/70 bg-red-50 px-3 py-2 text-sm text-red-900'
93
+ }
94
+
95
+ if (hasWarning) {
96
+ return 'rounded-md border border-amber-300/70 bg-amber-50 px-3 py-2 text-sm text-amber-950'
97
+ }
98
+
99
+ return 'rounded-md border border-sky-200/80 bg-sky-50 px-3 py-2 text-sm text-sky-950'
100
+ }
101
+
102
+ function getDiagnosticSeverityClassName(
103
+ severity: PresentationProjectionDiagnosticSeverity,
104
+ ) {
105
+ if (severity === 'error') {
106
+ return 'rounded bg-red-100 px-1.5 py-0.5 text-[0.65rem] font-medium uppercase tracking-wide text-red-700'
107
+ }
108
+
109
+ if (severity === 'warning') {
110
+ return 'rounded bg-amber-100 px-1.5 py-0.5 text-[0.65rem] font-medium uppercase tracking-wide text-amber-800'
111
+ }
112
+
113
+ return 'rounded bg-sky-100 px-1.5 py-0.5 text-[0.65rem] font-medium uppercase tracking-wide text-sky-700'
114
+ }
115
+
116
+ function formatDiagnosticSeverity(
117
+ severity: PresentationProjectionDiagnosticSeverity,
118
+ ) {
119
+ return severity === 'warning' ? 'warn' : severity
120
+ }
@@ -0,0 +1,186 @@
1
+ import { useMemo, type ReactNode } from 'react'
2
+
3
+ import type {
4
+ PresentationDataSourceResolver,
5
+ PresentationModuleDefinition,
6
+ ViewChromeSlotDefinition,
7
+ ViewDefinition,
8
+ } from '@cohesivesystems/presentation-core'
9
+ import {
10
+ createPresentationTestAttributes,
11
+ } from '@cohesivesystems/presentation-core'
12
+ import type {
13
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
14
+ } from './presentation-shadcn-component-system'
15
+ import type { PresentationDesignSystem } from '@cohesivesystems/presentation-tailwind'
16
+ import type {
17
+ PresentationActionGroupOptions,
18
+ } from './presentation-action-group'
19
+ import type {
20
+ ProjectedDocumentActionStatusMap,
21
+ } from '@cohesivesystems/presentation-core'
22
+ import type {
23
+ ProjectedViewSurfaceChromeSlotRenderer,
24
+ } from './projected-view-surface'
25
+ import {
26
+ renderStandardViewChromeSlot,
27
+ } from './standard-view-chrome-slot-renderers'
28
+ import type {
29
+ PresentationFlowRuntimeEntry,
30
+ PresentationFlowRuntimeRegistrySnapshot,
31
+ } from '@cohesivesystems/presentation-react'
32
+ import {
33
+ createProjectedPromptChildViewRenderer,
34
+ projectPromptChildViewRendererDiagnostics,
35
+ type ProjectedPromptChildViewRendererRegistry,
36
+ } from './projected-prompt-child-view-renderer'
37
+ import { ProjectedPromptView } from './projected-prompt-view'
38
+ import {
39
+ useRegisterPresentationProjectionDiagnostics,
40
+ } from '@cohesivesystems/presentation-react'
41
+
42
+ export interface ProjectedPresentationFlowLayerProps<TContext> {
43
+ readonly actionGroupOptions?: PresentationActionGroupOptions<TContext>
44
+ readonly actionStatuses?: ProjectedDocumentActionStatusMap
45
+ readonly actionRegionId?: string
46
+ readonly childViewRegistry: ProjectedPromptChildViewRendererRegistry<TContext>
47
+ readonly componentSet?: string
48
+ readonly componentSystem: PresentationComponentSystem
49
+ readonly context: TContext
50
+ readonly dataSourceResolver: PresentationDataSourceResolver
51
+ readonly designSystem: PresentationDesignSystem
52
+ readonly flowRegistry: PresentationFlowRuntimeRegistrySnapshot
53
+ readonly module: PresentationModuleDefinition | null
54
+ readonly renderChromeSlot?: (
55
+ context: ProjectedPresentationFlowLayerChromeSlotRenderContext<TContext>,
56
+ ) => ReactNode
57
+ readonly shouldRenderEntry?: (
58
+ context: ProjectedPresentationFlowLayerRenderContext,
59
+ ) => boolean
60
+ }
61
+
62
+ export interface ProjectedPresentationFlowLayerRenderContext
63
+ extends Omit<PresentationFlowRuntimeEntry, 'view'> {
64
+ readonly view: ViewDefinition
65
+ }
66
+
67
+ export interface ProjectedPresentationFlowLayerChromeSlotRenderContext<TContext>
68
+ extends ProjectedPresentationFlowLayerRenderContext {
69
+ readonly context: TContext
70
+ readonly dataSourceResolver: PresentationDataSourceResolver
71
+ readonly slot: ViewChromeSlotDefinition
72
+ }
73
+
74
+ export function ProjectedPresentationFlowLayer<TContext>({
75
+ actionGroupOptions,
76
+ actionStatuses,
77
+ actionRegionId,
78
+ childViewRegistry,
79
+ componentSet,
80
+ componentSystem,
81
+ context,
82
+ dataSourceResolver,
83
+ designSystem,
84
+ flowRegistry,
85
+ module,
86
+ renderChromeSlot,
87
+ shouldRenderEntry,
88
+ }: ProjectedPresentationFlowLayerProps<TContext>) {
89
+ const promptChildViewRendererDiagnostics = useMemo(
90
+ () =>
91
+ module
92
+ ? flowRegistry.activeEntries.flatMap((entry) =>
93
+ entry.view
94
+ ? projectPromptChildViewRendererDiagnostics({
95
+ componentSet,
96
+ module,
97
+ promptView: entry.view,
98
+ registry: childViewRegistry,
99
+ sourceId: 'presentation-flow.prompt-child-view-renderers',
100
+ })
101
+ : [])
102
+ : [],
103
+ [childViewRegistry, componentSet, flowRegistry.activeEntries, module],
104
+ )
105
+ useRegisterPresentationProjectionDiagnostics(
106
+ 'presentation-flow.prompt-child-view-renderers',
107
+ promptChildViewRendererDiagnostics,
108
+ )
109
+
110
+ if (!module) {
111
+ return null
112
+ }
113
+
114
+ return (
115
+ <>
116
+ {flowRegistry.activeEntries.map((entry) => {
117
+ if (!entry.view) {
118
+ return null
119
+ }
120
+
121
+ const promptView = entry.view
122
+ const renderContext = {
123
+ ...entry,
124
+ view: promptView,
125
+ } satisfies ProjectedPresentationFlowLayerRenderContext
126
+ if (shouldRenderEntry?.(renderContext) === false) {
127
+ return null
128
+ }
129
+
130
+ const renderPromptChildView = createProjectedPromptChildViewRenderer({
131
+ componentSet,
132
+ componentSystem,
133
+ context,
134
+ dataSourceResolver,
135
+ designSystem,
136
+ module,
137
+ promptView,
138
+ registry: childViewRegistry,
139
+ })
140
+ const renderPromptChromeSlot: ProjectedViewSurfaceChromeSlotRenderer = (slot, view) =>
141
+ renderChromeSlot?.({
142
+ ...renderContext,
143
+ context,
144
+ dataSourceResolver,
145
+ slot,
146
+ }) ?? renderStandardViewChromeSlot({
147
+ actionContext: context,
148
+ actionGroupOptions,
149
+ actionStatuses,
150
+ componentSystem,
151
+ dataSourceResolver,
152
+ designSystem,
153
+ module,
154
+ resource: dataSourceResolver.resolveViewPrimary(view ?? promptView)?.data,
155
+ slot,
156
+ view: view ?? promptView,
157
+ workspaceView: view ?? promptView,
158
+ })
159
+
160
+ return (
161
+ <div
162
+ key={entry.flow.Id}
163
+ {...createPresentationTestAttributes({
164
+ flowId: entry.flow.Id,
165
+ flowStateId: entry.state.Id,
166
+ viewId: promptView.Id,
167
+ })}
168
+ >
169
+ <ProjectedPromptView
170
+ actionGroupOptions={actionGroupOptions}
171
+ actionRegionId={actionRegionId}
172
+ componentSystem={componentSystem}
173
+ context={context}
174
+ dataSourceResolver={dataSourceResolver}
175
+ designSystem={designSystem}
176
+ module={module}
177
+ renderChromeSlot={renderPromptChromeSlot}
178
+ renderView={renderPromptChildView}
179
+ view={promptView}
180
+ />
181
+ </div>
182
+ )
183
+ })}
184
+ </>
185
+ )
186
+ }