@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,848 @@
1
+ import type {
2
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
3
+ PresentationShadcnComponentSystemRoleGroups as PresentationComponentSystemRoleGroups,
4
+ } from './presentation-shadcn-component-system'
5
+ import {
6
+ componentSystemComponentRoles,
7
+ presentationViewComponentRoles,
8
+ promptChildViewComponentRoles,
9
+ } from '@cohesivesystems/presentation-contracts'
10
+ import {
11
+ createPresentationProjectionDiagnostic,
12
+ type PresentationProjectionDiagnostic,
13
+ } from '@cohesivesystems/presentation-core'
14
+ import type {
15
+ DesignSystemBindingDefinition,
16
+ PresentationBindingDefinition,
17
+ PresentationModuleDefinition,
18
+ } from '@cohesivesystems/presentation-contracts'
19
+
20
+ export interface ProjectPresentationComponentSystemDiagnosticsOptions {
21
+ readonly componentSystem: PresentationComponentSystem
22
+ readonly defaultComponentSystem: PresentationComponentSystem
23
+ readonly sourceId: string
24
+ }
25
+
26
+ export interface ProjectPresentationDesignSystemBindingDiagnosticsOptions {
27
+ readonly componentSystem: PresentationComponentSystem
28
+ readonly module: Pick<PresentationModuleDefinition, 'DesignSystems'> | null
29
+ readonly sourceId?: string
30
+ }
31
+
32
+ interface PresentationComponentRoleDescriptor {
33
+ readonly group: keyof PresentationComponentSystemRoleGroups
34
+ readonly name: string
35
+ readonly read: (componentSystem: PresentationComponentSystem) => unknown
36
+ }
37
+
38
+ interface PresentationDesignSystemComponentRoleDescriptor
39
+ extends PresentationComponentRoleDescriptor {
40
+ readonly bindingIds: readonly string[]
41
+ readonly componentRole: string
42
+ }
43
+
44
+ const presentationComponentRoleDescriptors = [
45
+ createRoleDescriptor('actions', 'ActionButton'),
46
+ createRoleDescriptor('badges', 'Badge'),
47
+ createRoleDescriptor('collectionChrome', 'CollectionBodySlot'),
48
+ createRoleDescriptor('collectionChrome', 'CollectionDetailSlot'),
49
+ createRoleDescriptor('collectionChrome', 'CollectionPaginationBar'),
50
+ createRoleDescriptor('collectionChrome', 'CollectionQueryFormSlot'),
51
+ createRoleDescriptor('collectionChrome', 'CollectionRowActions'),
52
+ createRoleDescriptor('collectionChrome', 'CollectionSelectionActionToolbar'),
53
+ createRoleDescriptor('collectionChrome', 'CollectionSummarySlot'),
54
+ createRoleDescriptor('collections', 'CollectionDetailLayout'),
55
+ createRoleDescriptor('collections', 'DataTable'),
56
+ createRoleDescriptor('collections', 'RowActionMenu'),
57
+ createRoleDescriptor('collections', 'RowActionMenuItem'),
58
+ createRoleDescriptor('collections', 'RowActionMenuTrigger'),
59
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceDetailPanel'),
60
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceLayoutGroup'),
61
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceLayoutPane'),
62
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceNodeLabel'),
63
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceShell'),
64
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceSurfaceSlot'),
65
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceStatus'),
66
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceTable'),
67
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceTreeControls'),
68
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceTreeItem'),
69
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceTreeLayout'),
70
+ createRoleDescriptor('documentWorkspaces', 'DocumentWorkspaceTreeView'),
71
+ createRoleDescriptor('documentWorkspaces', 'JsonDocumentDiff'),
72
+ createRoleDescriptor('documentWorkspaces', 'JsonDocumentEditor'),
73
+ createRoleDescriptor('fieldValues', 'FieldValueCode'),
74
+ createRoleDescriptor('fieldValues', 'FieldValueComposite'),
75
+ createRoleDescriptor('fieldValues', 'FieldValueEmpty'),
76
+ createRoleDescriptor('fieldValues', 'FieldValueJson'),
77
+ createRoleDescriptor('fieldValues', 'FieldValueScalar'),
78
+ createRoleDescriptor('fieldValues', 'FieldValueSupportingValue'),
79
+ createRoleDescriptor('feedback', 'StatusBlock'),
80
+ createRoleDescriptor('forms', 'CheckboxControl'),
81
+ createRoleDescriptor('forms', 'ChoiceToggleGroup'),
82
+ createRoleDescriptor('forms', 'ChoiceToggleItem'),
83
+ createRoleDescriptor('forms', 'DateTimeFilterControl'),
84
+ createRoleDescriptor('forms', 'FormActionButton'),
85
+ createRoleDescriptor('forms', 'FormFieldLabel'),
86
+ createRoleDescriptor('forms', 'InputForm'),
87
+ createRoleDescriptor('forms', 'InputFormActionRow'),
88
+ createRoleDescriptor('forms', 'InputFormControlGroup'),
89
+ createRoleDescriptor('forms', 'InputFormControlSlot'),
90
+ createRoleDescriptor('forms', 'InputFormField'),
91
+ createRoleDescriptor('forms', 'InputFormFieldMessage'),
92
+ createRoleDescriptor('forms', 'InputFormGroup'),
93
+ createRoleDescriptor('forms', 'InputFormGroups'),
94
+ createRoleDescriptor('forms', 'SelectControl'),
95
+ createRoleDescriptor('forms', 'TextInputControl'),
96
+ createRoleDescriptor('metrics', 'MetricItem'),
97
+ createRoleDescriptor('metrics', 'MetricStrip'),
98
+ createRoleDescriptor('navigation', 'NavigationLink'),
99
+ createRoleDescriptor('processes', 'ProcessTaskNotice'),
100
+ createRoleDescriptor('prompts', 'PromptContent'),
101
+ createRoleDescriptor('prompts', 'PromptFooter'),
102
+ createRoleDescriptor('prompts', 'PromptHeaderActions'),
103
+ createRoleDescriptor('prompts', 'PromptModal'),
104
+ createRoleDescriptor('prompts', 'PromptRegion'),
105
+ createRoleDescriptor('records', 'RecordDetailEmptyState'),
106
+ createRoleDescriptor('records', 'RecordDetailField'),
107
+ createRoleDescriptor('records', 'RecordDetails'),
108
+ createRoleDescriptor('surfaces', 'ViewSurface'),
109
+ createRoleDescriptor('surfaces', 'ViewSurfaceChromePlacement'),
110
+ createRoleDescriptor('surfaces', 'ViewSurfaceContent'),
111
+ createRoleDescriptor('surfaces', 'ViewSurfaceHeaderActions'),
112
+ createRoleDescriptor('tabs', 'TabsLayout'),
113
+ createRoleDescriptor('tabs', 'TabsList'),
114
+ createRoleDescriptor('tabs', 'TabsPanel'),
115
+ createRoleDescriptor('tabs', 'TabsTrigger'),
116
+ createRoleDescriptor('viewChrome', 'ActionSlot'),
117
+ createRoleDescriptor('viewChrome', 'BadgeStrip'),
118
+ createRoleDescriptor('viewChrome', 'LayoutSwitch'),
119
+ createRoleDescriptor('viewChrome', 'MetricStripSlot'),
120
+ createRoleDescriptor('viewChrome', 'ViewChromeSlot'),
121
+ createRoleDescriptor('viewChrome', 'ViewSwitch'),
122
+ ] as const
123
+
124
+ const presentationDesignSystemComponentRoleDescriptors = [
125
+ createDesignSystemComponentRoleDescriptor(
126
+ 'actions',
127
+ 'ActionButton',
128
+ componentSystemComponentRoles.actionButton,
129
+ ['button', 'action-button'],
130
+ ),
131
+ createDesignSystemComponentRoleDescriptor(
132
+ 'badges',
133
+ 'Badge',
134
+ componentSystemComponentRoles.badge,
135
+ ['badge'],
136
+ ),
137
+ createDesignSystemComponentRoleDescriptor(
138
+ 'collectionChrome',
139
+ 'CollectionBodySlot',
140
+ componentSystemComponentRoles.collectionBodySlot,
141
+ ['collection-body-slot'],
142
+ ),
143
+ createDesignSystemComponentRoleDescriptor(
144
+ 'collectionChrome',
145
+ 'CollectionDetailSlot',
146
+ componentSystemComponentRoles.collectionDetailSlot,
147
+ ['collection-detail-slot'],
148
+ ),
149
+ createDesignSystemComponentRoleDescriptor(
150
+ 'collectionChrome',
151
+ 'CollectionPaginationBar',
152
+ componentSystemComponentRoles.collectionPaginationBar,
153
+ ['collection-pagination-bar'],
154
+ ),
155
+ createDesignSystemComponentRoleDescriptor(
156
+ 'collectionChrome',
157
+ 'CollectionQueryFormSlot',
158
+ componentSystemComponentRoles.collectionQueryFormSlot,
159
+ ['collection-query-form-slot'],
160
+ ),
161
+ createDesignSystemComponentRoleDescriptor(
162
+ 'collectionChrome',
163
+ 'CollectionRowActions',
164
+ componentSystemComponentRoles.collectionRowActions,
165
+ ['collection-row-actions'],
166
+ ),
167
+ createDesignSystemComponentRoleDescriptor(
168
+ 'collectionChrome',
169
+ 'CollectionSelectionActionToolbar',
170
+ componentSystemComponentRoles.collectionSelectionActionToolbar,
171
+ ['collection-selection-action-toolbar'],
172
+ ),
173
+ createDesignSystemComponentRoleDescriptor(
174
+ 'collectionChrome',
175
+ 'CollectionSummarySlot',
176
+ componentSystemComponentRoles.collectionSummarySlot,
177
+ ['collection-summary-slot'],
178
+ ),
179
+ createDesignSystemComponentRoleDescriptor(
180
+ 'collections',
181
+ 'DataTable',
182
+ componentSystemComponentRoles.dataTable,
183
+ ['table', 'data-table'],
184
+ ),
185
+ createDesignSystemComponentRoleDescriptor(
186
+ 'fieldValues',
187
+ 'FieldValueCode',
188
+ componentSystemComponentRoles.fieldValueCode,
189
+ ['field-value-code'],
190
+ ),
191
+ createDesignSystemComponentRoleDescriptor(
192
+ 'fieldValues',
193
+ 'FieldValueComposite',
194
+ componentSystemComponentRoles.fieldValueComposite,
195
+ ['field-value-composite'],
196
+ ),
197
+ createDesignSystemComponentRoleDescriptor(
198
+ 'fieldValues',
199
+ 'FieldValueEmpty',
200
+ componentSystemComponentRoles.fieldValueEmpty,
201
+ ['field-value-empty'],
202
+ ),
203
+ createDesignSystemComponentRoleDescriptor(
204
+ 'fieldValues',
205
+ 'FieldValueJson',
206
+ componentSystemComponentRoles.fieldValueJson,
207
+ ['field-value-json'],
208
+ ),
209
+ createDesignSystemComponentRoleDescriptor(
210
+ 'fieldValues',
211
+ 'FieldValueScalar',
212
+ componentSystemComponentRoles.fieldValueScalar,
213
+ ['field-value-scalar'],
214
+ ),
215
+ createDesignSystemComponentRoleDescriptor(
216
+ 'fieldValues',
217
+ 'FieldValueSupportingValue',
218
+ componentSystemComponentRoles.fieldValueSupportingValue,
219
+ ['field-value-supporting-value'],
220
+ ),
221
+ createDesignSystemComponentRoleDescriptor(
222
+ 'forms',
223
+ 'InputForm',
224
+ componentSystemComponentRoles.inputForm,
225
+ ['input-form'],
226
+ ),
227
+ createDesignSystemComponentRoleDescriptor(
228
+ 'forms',
229
+ 'InputFormActionRow',
230
+ componentSystemComponentRoles.inputFormActionRow,
231
+ ['input-form-action-row'],
232
+ ),
233
+ createDesignSystemComponentRoleDescriptor(
234
+ 'forms',
235
+ 'InputFormControlGroup',
236
+ componentSystemComponentRoles.inputFormControlGroup,
237
+ ['input-form-control-group'],
238
+ ),
239
+ createDesignSystemComponentRoleDescriptor(
240
+ 'forms',
241
+ 'InputFormControlSlot',
242
+ componentSystemComponentRoles.inputFormControlSlot,
243
+ ['input-form-control-slot'],
244
+ ),
245
+ createDesignSystemComponentRoleDescriptor(
246
+ 'forms',
247
+ 'InputFormField',
248
+ componentSystemComponentRoles.inputFormField,
249
+ ['input-form-field'],
250
+ ),
251
+ createDesignSystemComponentRoleDescriptor(
252
+ 'forms',
253
+ 'InputFormFieldMessage',
254
+ componentSystemComponentRoles.inputFormFieldMessage,
255
+ ['input-form-field-message'],
256
+ ),
257
+ createDesignSystemComponentRoleDescriptor(
258
+ 'forms',
259
+ 'InputFormGroup',
260
+ componentSystemComponentRoles.inputFormGroup,
261
+ ['input-form-group'],
262
+ ),
263
+ createDesignSystemComponentRoleDescriptor(
264
+ 'forms',
265
+ 'InputFormGroups',
266
+ componentSystemComponentRoles.inputFormGroups,
267
+ ['input-form-groups'],
268
+ ),
269
+ createDesignSystemComponentRoleDescriptor(
270
+ 'documentWorkspaces',
271
+ 'DocumentWorkspaceShell',
272
+ componentSystemComponentRoles.documentWorkspaceShell,
273
+ ['document-workspace-shell'],
274
+ ),
275
+ createDesignSystemComponentRoleDescriptor(
276
+ 'documentWorkspaces',
277
+ 'DocumentWorkspaceLayoutGroup',
278
+ componentSystemComponentRoles.documentWorkspaceLayoutGroup,
279
+ ['document-workspace-layout-group'],
280
+ ),
281
+ createDesignSystemComponentRoleDescriptor(
282
+ 'documentWorkspaces',
283
+ 'DocumentWorkspaceLayoutPane',
284
+ componentSystemComponentRoles.documentWorkspaceLayoutPane,
285
+ ['document-workspace-layout-pane'],
286
+ ),
287
+ createDesignSystemComponentRoleDescriptor(
288
+ 'documentWorkspaces',
289
+ 'DocumentWorkspaceSurfaceSlot',
290
+ componentSystemComponentRoles.documentWorkspaceSurfaceSlot,
291
+ ['document-workspace-surface-slot'],
292
+ ),
293
+ createDesignSystemComponentRoleDescriptor(
294
+ 'documentWorkspaces',
295
+ 'DocumentWorkspaceTreeView',
296
+ componentSystemComponentRoles.documentWorkspaceTreeView,
297
+ ['tree', 'tree-view', 'document-workspace-tree-view'],
298
+ ),
299
+ createDesignSystemComponentRoleDescriptor(
300
+ 'documentWorkspaces',
301
+ 'JsonDocumentDiff',
302
+ componentSystemComponentRoles.jsonDocumentDiff,
303
+ ['diff', 'json-diff', 'json-document-diff'],
304
+ ),
305
+ createDesignSystemComponentRoleDescriptor(
306
+ 'documentWorkspaces',
307
+ 'JsonDocumentEditor',
308
+ componentSystemComponentRoles.jsonDocumentEditor,
309
+ ['json-editor', 'json-document-editor'],
310
+ ),
311
+ createDesignSystemComponentRoleDescriptor(
312
+ 'documentWorkspaces',
313
+ 'JsonDocumentDiff',
314
+ promptChildViewComponentRoles.jsonDocumentDiff,
315
+ ['projected-json-document-diff'],
316
+ ),
317
+ createDesignSystemComponentRoleDescriptor(
318
+ 'documentWorkspaces',
319
+ 'DocumentWorkspaceShell',
320
+ promptChildViewComponentRoles.promptDocumentPreview,
321
+ ['projected-prompt-document-preview'],
322
+ ),
323
+ createDesignSystemComponentRoleDescriptor(
324
+ 'feedback',
325
+ 'StatusBlock',
326
+ componentSystemComponentRoles.statusBlock,
327
+ ['status-block'],
328
+ ),
329
+ createDesignSystemComponentRoleDescriptor(
330
+ 'metrics',
331
+ 'MetricItem',
332
+ componentSystemComponentRoles.metricItem,
333
+ ['metric-item'],
334
+ ),
335
+ createDesignSystemComponentRoleDescriptor(
336
+ 'metrics',
337
+ 'MetricStrip',
338
+ componentSystemComponentRoles.metricStrip,
339
+ ['metric-strip'],
340
+ ),
341
+ createDesignSystemComponentRoleDescriptor(
342
+ 'metrics',
343
+ 'MetricStrip',
344
+ presentationViewComponentRoles.metricDashboard,
345
+ ['projected-metric-dashboard'],
346
+ ),
347
+ createDesignSystemComponentRoleDescriptor(
348
+ 'processes',
349
+ 'ProcessTaskNotice',
350
+ componentSystemComponentRoles.processTaskNotice,
351
+ ['process-task-notice'],
352
+ ),
353
+ createDesignSystemComponentRoleDescriptor(
354
+ 'prompts',
355
+ 'PromptModal',
356
+ componentSystemComponentRoles.promptModal,
357
+ ['prompt-modal'],
358
+ ),
359
+ createDesignSystemComponentRoleDescriptor(
360
+ 'prompts',
361
+ 'PromptHeaderActions',
362
+ componentSystemComponentRoles.promptHeaderActions,
363
+ ['prompt-header-actions'],
364
+ ),
365
+ createDesignSystemComponentRoleDescriptor(
366
+ 'prompts',
367
+ 'PromptContent',
368
+ componentSystemComponentRoles.promptContent,
369
+ ['prompt-content'],
370
+ ),
371
+ createDesignSystemComponentRoleDescriptor(
372
+ 'prompts',
373
+ 'PromptFooter',
374
+ componentSystemComponentRoles.promptFooter,
375
+ ['prompt-footer'],
376
+ ),
377
+ createDesignSystemComponentRoleDescriptor(
378
+ 'prompts',
379
+ 'PromptRegion',
380
+ componentSystemComponentRoles.promptRegion,
381
+ ['prompt-region'],
382
+ ),
383
+ createDesignSystemComponentRoleDescriptor(
384
+ 'records',
385
+ 'RecordDetailEmptyState',
386
+ componentSystemComponentRoles.recordDetailEmptyState,
387
+ ['record-detail-empty-state'],
388
+ ),
389
+ createDesignSystemComponentRoleDescriptor(
390
+ 'records',
391
+ 'RecordDetailField',
392
+ componentSystemComponentRoles.recordDetailField,
393
+ ['record-detail-field'],
394
+ ),
395
+ createDesignSystemComponentRoleDescriptor(
396
+ 'records',
397
+ 'RecordDetails',
398
+ componentSystemComponentRoles.recordDetails,
399
+ ['record-details'],
400
+ ),
401
+ createDesignSystemComponentRoleDescriptor(
402
+ 'tabs',
403
+ 'TabsLayout',
404
+ componentSystemComponentRoles.tabsLayout,
405
+ ['tabs-layout'],
406
+ ),
407
+ createDesignSystemComponentRoleDescriptor(
408
+ 'tabs',
409
+ 'TabsLayout',
410
+ presentationViewComponentRoles.tabsView,
411
+ ['projected-tabs-view'],
412
+ ),
413
+ createDesignSystemComponentRoleDescriptor(
414
+ 'tabs',
415
+ 'TabsList',
416
+ componentSystemComponentRoles.tabsList,
417
+ ['tabs-list'],
418
+ ),
419
+ createDesignSystemComponentRoleDescriptor(
420
+ 'tabs',
421
+ 'TabsPanel',
422
+ componentSystemComponentRoles.tabsPanel,
423
+ ['tabs-panel'],
424
+ ),
425
+ createDesignSystemComponentRoleDescriptor(
426
+ 'tabs',
427
+ 'TabsTrigger',
428
+ componentSystemComponentRoles.tabsTrigger,
429
+ ['tabs-trigger'],
430
+ ),
431
+ createDesignSystemComponentRoleDescriptor(
432
+ 'surfaces',
433
+ 'ViewSurface',
434
+ componentSystemComponentRoles.viewSurface,
435
+ ['surface', 'view-surface'],
436
+ ),
437
+ createDesignSystemComponentRoleDescriptor(
438
+ 'surfaces',
439
+ 'ViewSurface',
440
+ presentationViewComponentRoles.viewSurface,
441
+ ['projected-view-surface'],
442
+ ),
443
+ createDesignSystemComponentRoleDescriptor(
444
+ 'surfaces',
445
+ 'ViewSurfaceChromePlacement',
446
+ componentSystemComponentRoles.viewSurfaceChromePlacement,
447
+ ['view-surface-chrome-placement'],
448
+ ),
449
+ createDesignSystemComponentRoleDescriptor(
450
+ 'surfaces',
451
+ 'ViewSurfaceContent',
452
+ componentSystemComponentRoles.viewSurfaceContent,
453
+ ['view-surface-content'],
454
+ ),
455
+ createDesignSystemComponentRoleDescriptor(
456
+ 'surfaces',
457
+ 'ViewSurfaceHeaderActions',
458
+ componentSystemComponentRoles.viewSurfaceHeaderActions,
459
+ ['view-surface-header-actions'],
460
+ ),
461
+ createDesignSystemComponentRoleDescriptor(
462
+ 'viewChrome',
463
+ 'ActionSlot',
464
+ componentSystemComponentRoles.viewChromeActionSlot,
465
+ ['action-slot', 'view-chrome-action-slot'],
466
+ ),
467
+ createDesignSystemComponentRoleDescriptor(
468
+ 'viewChrome',
469
+ 'BadgeStrip',
470
+ componentSystemComponentRoles.viewChromeBadgeStrip,
471
+ ['badge-strip', 'view-chrome-badge-strip'],
472
+ ),
473
+ createDesignSystemComponentRoleDescriptor(
474
+ 'viewChrome',
475
+ 'LayoutSwitch',
476
+ componentSystemComponentRoles.viewChromeLayoutSwitch,
477
+ ['layout-switch', 'view-chrome-layout-switch'],
478
+ ),
479
+ createDesignSystemComponentRoleDescriptor(
480
+ 'viewChrome',
481
+ 'MetricStripSlot',
482
+ componentSystemComponentRoles.viewChromeMetricStrip,
483
+ ['view-chrome-metric-strip'],
484
+ ),
485
+ createDesignSystemComponentRoleDescriptor(
486
+ 'viewChrome',
487
+ 'ViewChromeSlot',
488
+ componentSystemComponentRoles.viewChromeSlot,
489
+ ['view-chrome-slot'],
490
+ ),
491
+ createDesignSystemComponentRoleDescriptor(
492
+ 'viewChrome',
493
+ 'ViewSwitch',
494
+ componentSystemComponentRoles.viewChromeViewSwitch,
495
+ ['view-switch', 'view-chrome-view-switch'],
496
+ ),
497
+ createDesignSystemComponentRoleDescriptor(
498
+ 'collections',
499
+ 'DataTable',
500
+ presentationViewComponentRoles.collectionView,
501
+ ['projected-collection-view'],
502
+ ),
503
+ createDesignSystemComponentRoleDescriptor(
504
+ 'forms',
505
+ 'InputForm',
506
+ presentationViewComponentRoles.inputForm,
507
+ ['projected-input-form'],
508
+ ),
509
+ createDesignSystemComponentRoleDescriptor(
510
+ 'forms',
511
+ 'InputForm',
512
+ presentationViewComponentRoles.queryForm,
513
+ ['projected-query-form'],
514
+ ),
515
+ ] as const
516
+
517
+ /**
518
+ * Reports which projected component roles are still interpreted by the default
519
+ * target component system. This gives the developer toolbar a compact TODO list
520
+ * when an app starts replacing shadcn/app defaults with its own component set.
521
+ */
522
+ export function projectPresentationComponentSystemDiagnostics({
523
+ componentSystem,
524
+ defaultComponentSystem,
525
+ sourceId,
526
+ }: ProjectPresentationComponentSystemDiagnosticsOptions): readonly PresentationProjectionDiagnostic[] {
527
+ const roleStatuses = presentationComponentRoleDescriptors.map((descriptor) => {
528
+ const roleId = `${descriptor.group}.${descriptor.name}`
529
+ const isDefault = descriptor.read(componentSystem) === descriptor.read(defaultComponentSystem)
530
+ return {
531
+ roleId,
532
+ status: isDefault ? 'default' : 'overridden',
533
+ }
534
+ })
535
+ const defaultedRoles = roleStatuses
536
+ .filter((role) => role.status === 'default')
537
+ .map((role) => role.roleId)
538
+ const overriddenRoles = roleStatuses
539
+ .filter((role) => role.status === 'overridden')
540
+ .map((role) => role.roleId)
541
+
542
+ if (defaultedRoles.length === 0) {
543
+ return []
544
+ }
545
+
546
+ return [
547
+ createPresentationProjectionDiagnostic({
548
+ category: 'local-interpretation',
549
+ details: {
550
+ defaultComponentSystemId: defaultComponentSystem.id,
551
+ defaultedRoles,
552
+ overriddenRoles,
553
+ roleStatuses: Object.fromEntries(
554
+ roleStatuses.map((role) => [role.roleId, role.status]),
555
+ ),
556
+ },
557
+ id: `component-system.${componentSystem.id}.defaulted-roles`,
558
+ interpretation: {
559
+ status: 'locally-interpreted',
560
+ target: componentSystem.target,
561
+ },
562
+ message:
563
+ `Component system '${componentSystem.id}' uses default implementations ` +
564
+ `for ${defaultedRoles.length} projected component role(s).`,
565
+ severity: 'info',
566
+ source: sourceId,
567
+ subject: {
568
+ id: componentSystem.id,
569
+ kind: 'PresentationComponentSystem',
570
+ name: componentSystem.target,
571
+ },
572
+ suggestedNextStep:
573
+ 'Override these component-system roles when this app needs a target-specific component interpretation.',
574
+ }),
575
+ ]
576
+ }
577
+
578
+ /**
579
+ * Reports how backend-declared design-system component bindings map onto the
580
+ * local frontend component-system interpreter. Design-system bindings describe
581
+ * low-level target widgets, so concrete component keys are allowed as explicit
582
+ * escape hatches, but they should be visible in the projection diagnostics.
583
+ */
584
+ export function projectPresentationDesignSystemBindingDiagnostics({
585
+ componentSystem,
586
+ module,
587
+ sourceId = 'presentation-design-system-bindings',
588
+ }: ProjectPresentationDesignSystemBindingDiagnosticsOptions): readonly PresentationProjectionDiagnostic[] {
589
+ if (!module) {
590
+ return []
591
+ }
592
+
593
+ return module.DesignSystems.flatMap((designSystem) =>
594
+ designSystem.ComponentBindings.flatMap((binding) =>
595
+ projectDesignSystemComponentBindingDiagnostics({
596
+ binding,
597
+ componentSystem,
598
+ designSystem,
599
+ sourceId,
600
+ }),
601
+ ),
602
+ )
603
+ }
604
+
605
+ function projectDesignSystemComponentBindingDiagnostics({
606
+ binding,
607
+ componentSystem,
608
+ designSystem,
609
+ sourceId,
610
+ }: {
611
+ readonly binding: PresentationBindingDefinition
612
+ readonly componentSystem: PresentationComponentSystem
613
+ readonly designSystem: DesignSystemBindingDefinition
614
+ readonly sourceId: string
615
+ }): readonly PresentationProjectionDiagnostic[] {
616
+ const bindingId = binding.Id ?? 'unknown'
617
+ const componentKey = binding.ComponentKey ?? null
618
+ const componentRole = binding.ComponentRole ?? null
619
+ const expectedRoleDescriptor = resolveExpectedDesignSystemComponentRole(binding)
620
+ const declaredRoleDescriptor = componentRole
621
+ ? findDesignSystemComponentRoleDescriptorByRole(componentRole)
622
+ : null
623
+ const diagnostics: PresentationProjectionDiagnostic[] = []
624
+
625
+ if (componentRole) {
626
+ const roleBound = declaredRoleDescriptor
627
+ ? Boolean(declaredRoleDescriptor.read(componentSystem))
628
+ : false
629
+ diagnostics.push(
630
+ createPresentationProjectionDiagnostic({
631
+ category: roleBound ? 'local-interpretation' : 'missing-binding',
632
+ details: createDesignSystemComponentBindingDiagnosticDetails({
633
+ binding,
634
+ componentSystem,
635
+ declaredRoleDescriptor,
636
+ designSystem,
637
+ expectedRoleDescriptor,
638
+ roleBound,
639
+ }),
640
+ id: `design-system.${designSystem.Id}.${bindingId}.component-role-coverage`,
641
+ interpretation: {
642
+ status: roleBound ? 'locally-interpreted' : 'unbound',
643
+ target: 'design-system-component-role',
644
+ },
645
+ message: roleBound
646
+ ? `Design-system component '${bindingId}' role '${componentRole}' is interpreted by local component-system role '${declaredRoleDescriptor?.group}.${declaredRoleDescriptor?.name}'.`
647
+ : `Design-system component '${bindingId}' role '${componentRole}' is not mapped to a local component-system role.`,
648
+ severity: roleBound ? 'info' : 'warning',
649
+ source: sourceId,
650
+ subject: {
651
+ id: `${designSystem.Id}:${bindingId}`,
652
+ kind: 'design-system-component-binding',
653
+ name: designSystem.Name,
654
+ },
655
+ suggestedNextStep: roleBound
656
+ ? undefined
657
+ : 'Add a frontend component-system role descriptor for this design-system component role or replace it with a modeled standard role.',
658
+ }),
659
+ )
660
+ } else if (expectedRoleDescriptor) {
661
+ diagnostics.push(
662
+ createPresentationProjectionDiagnostic({
663
+ category: 'missing-binding',
664
+ details: createDesignSystemComponentBindingDiagnosticDetails({
665
+ binding,
666
+ componentSystem,
667
+ declaredRoleDescriptor,
668
+ designSystem,
669
+ expectedRoleDescriptor,
670
+ roleBound: false,
671
+ }),
672
+ id: `design-system.${designSystem.Id}.${bindingId}.missing-component-role`,
673
+ interpretation: {
674
+ status: 'unbound',
675
+ target: 'design-system-component-role',
676
+ },
677
+ message:
678
+ `Design-system component '${bindingId}' has a standard component-system ` +
679
+ `role '${expectedRoleDescriptor.componentRole}' but does not declare it.`,
680
+ severity: 'warning',
681
+ source: sourceId,
682
+ subject: {
683
+ id: `${designSystem.Id}:${bindingId}`,
684
+ kind: 'design-system-component-binding',
685
+ name: designSystem.Name,
686
+ },
687
+ suggestedNextStep:
688
+ `Set ComponentRole to '${expectedRoleDescriptor.componentRole}' for this design-system binding.`,
689
+ }),
690
+ )
691
+ } else if (!componentKey) {
692
+ diagnostics.push(
693
+ createPresentationProjectionDiagnostic({
694
+ category: 'missing-binding',
695
+ details: createDesignSystemComponentBindingDiagnosticDetails({
696
+ binding,
697
+ componentSystem,
698
+ declaredRoleDescriptor,
699
+ designSystem,
700
+ expectedRoleDescriptor,
701
+ roleBound: false,
702
+ }),
703
+ id: `design-system.${designSystem.Id}.${bindingId}.missing-component-binding`,
704
+ interpretation: {
705
+ status: 'unbound',
706
+ target: 'design-system-component-role',
707
+ },
708
+ message:
709
+ `Design-system component '${bindingId}' declares neither ComponentRole nor ComponentKey.`,
710
+ severity: 'warning',
711
+ source: sourceId,
712
+ subject: {
713
+ id: `${designSystem.Id}:${bindingId}`,
714
+ kind: 'design-system-component-binding',
715
+ name: designSystem.Name,
716
+ },
717
+ suggestedNextStep:
718
+ 'Declare a standard component-system role, or use ComponentKey for a deliberate target-specific primitive.',
719
+ }),
720
+ )
721
+ }
722
+
723
+ if (componentKey) {
724
+ diagnostics.push(
725
+ createPresentationProjectionDiagnostic({
726
+ category: 'escape-hatch',
727
+ details: createDesignSystemComponentBindingDiagnosticDetails({
728
+ binding,
729
+ componentSystem,
730
+ declaredRoleDescriptor,
731
+ designSystem,
732
+ expectedRoleDescriptor,
733
+ roleBound: Boolean(
734
+ componentRole &&
735
+ declaredRoleDescriptor &&
736
+ declaredRoleDescriptor.read(componentSystem),
737
+ ),
738
+ }),
739
+ id: `design-system.${designSystem.Id}.${bindingId}.component-key-escape-hatch`,
740
+ interpretation: {
741
+ status: 'escape-hatch',
742
+ target: 'design-system-component-key',
743
+ },
744
+ message:
745
+ `Design-system component '${bindingId}' uses concrete component key ` +
746
+ `'${componentKey}'.`,
747
+ severity: 'warning',
748
+ source: sourceId,
749
+ subject: {
750
+ id: `${designSystem.Id}:${bindingId}`,
751
+ kind: 'design-system-component-binding',
752
+ name: designSystem.Name,
753
+ },
754
+ suggestedNextStep: expectedRoleDescriptor
755
+ ? `Prefer ComponentRole '${expectedRoleDescriptor.componentRole}' and keep ComponentKey only for adapter-specific overrides.`
756
+ : 'Model a standard component-system role when this widget becomes reusable across targets; otherwise keep this as an explicit primitive escape hatch.',
757
+ }),
758
+ )
759
+ }
760
+
761
+ return diagnostics
762
+ }
763
+
764
+ function createDesignSystemComponentBindingDiagnosticDetails({
765
+ binding,
766
+ componentSystem,
767
+ declaredRoleDescriptor,
768
+ designSystem,
769
+ expectedRoleDescriptor,
770
+ roleBound,
771
+ }: {
772
+ readonly binding: PresentationBindingDefinition
773
+ readonly componentSystem: PresentationComponentSystem
774
+ readonly declaredRoleDescriptor: PresentationDesignSystemComponentRoleDescriptor | null
775
+ readonly designSystem: DesignSystemBindingDefinition
776
+ readonly expectedRoleDescriptor: PresentationDesignSystemComponentRoleDescriptor | null
777
+ readonly roleBound: boolean
778
+ }) {
779
+ return {
780
+ bindingId: binding.Id ?? null,
781
+ componentKey: binding.ComponentKey ?? null,
782
+ componentRole: binding.ComponentRole ?? null,
783
+ componentSystemId: componentSystem.id,
784
+ declaredComponentSystemRole: declaredRoleDescriptor
785
+ ? `${declaredRoleDescriptor.group}.${declaredRoleDescriptor.name}`
786
+ : null,
787
+ designSystemId: designSystem.Id,
788
+ designSystemKind: designSystem.Kind,
789
+ expectedComponentRole: expectedRoleDescriptor?.componentRole ?? null,
790
+ expectedComponentSystemRole: expectedRoleDescriptor
791
+ ? `${expectedRoleDescriptor.group}.${expectedRoleDescriptor.name}`
792
+ : null,
793
+ roleBound,
794
+ }
795
+ }
796
+
797
+ function resolveExpectedDesignSystemComponentRole(
798
+ binding: PresentationBindingDefinition,
799
+ ) {
800
+ const componentRole = binding.ComponentRole ?? null
801
+ if (componentRole) {
802
+ return findDesignSystemComponentRoleDescriptorByRole(componentRole)
803
+ }
804
+
805
+ const bindingId = binding.Id?.toLocaleLowerCase()
806
+ if (!bindingId) {
807
+ return null
808
+ }
809
+
810
+ return presentationDesignSystemComponentRoleDescriptors.find((descriptor) =>
811
+ descriptor.bindingIds.some((candidate) => candidate.toLocaleLowerCase() === bindingId),
812
+ ) ?? null
813
+ }
814
+
815
+ function findDesignSystemComponentRoleDescriptorByRole(componentRole: string) {
816
+ return presentationDesignSystemComponentRoleDescriptors.find(
817
+ (descriptor) => descriptor.componentRole === componentRole,
818
+ ) ?? null
819
+ }
820
+
821
+ function createRoleDescriptor(
822
+ group: keyof PresentationComponentSystemRoleGroups,
823
+ name: string,
824
+ ): PresentationComponentRoleDescriptor {
825
+ return {
826
+ group,
827
+ name,
828
+ read: (componentSystem) => {
829
+ const roleGroup = componentSystem[group]
830
+ return roleGroup && typeof roleGroup === 'object'
831
+ ? (roleGroup as unknown as Record<string, unknown>)[name]
832
+ : undefined
833
+ },
834
+ }
835
+ }
836
+
837
+ function createDesignSystemComponentRoleDescriptor(
838
+ group: keyof PresentationComponentSystemRoleGroups,
839
+ name: string,
840
+ componentRole: string,
841
+ bindingIds: readonly string[],
842
+ ): PresentationDesignSystemComponentRoleDescriptor {
843
+ return {
844
+ ...createRoleDescriptor(group, name),
845
+ bindingIds,
846
+ componentRole,
847
+ }
848
+ }