@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,434 @@
1
+ import { useCallback, useMemo, type ReactNode } from 'react'
2
+
3
+ import {
4
+ defaultPresentationComponentSet,
5
+ createProjectedCollectionRuntime,
6
+ findPresentationView,
7
+ isCollectionSelectionEnabled,
8
+ projectPresentationActionRuntimeRegistry,
9
+ projectProjectedCollectionActionRuntimeBindings,
10
+ resolveProjectedCollectionSelectionMode,
11
+ resolveProjectedCollectionSelectionStateId,
12
+ type CollectionChromeSlotDefinition,
13
+ type FieldPresentationDefinition,
14
+ type NavigationRouteParameters,
15
+ type PresentationActionRuntimeBinding,
16
+ type ProjectedCollectionActionExecutionContext,
17
+ type ProjectedCollectionActionRuntimeRegistry,
18
+ type ProjectedCollectionRuntime,
19
+ type ViewDefinition,
20
+ } from '@cohesivesystems/presentation-core'
21
+ import {
22
+ projectProjectedCollectionActionRuntimeDiagnostics,
23
+ } from './projected-collection-action-runtime-diagnostics'
24
+ import type {
25
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
26
+ } from './presentation-shadcn-component-system'
27
+ import {
28
+ useCollectionSelectionState,
29
+ usePresentationModule,
30
+ usePresentationNavigationRuntime,
31
+ useRegisterPresentationProjectionDiagnostics,
32
+ } from '@cohesivesystems/presentation-react'
33
+ import {
34
+ ProjectedCollectionRowActions,
35
+ type ProjectedActionPlacementLike,
36
+ type ProjectedFieldRenderContext,
37
+ } from './projected-collection-view'
38
+ import {
39
+ renderProjectedFieldValue,
40
+ } from './projected-field-value-rendering'
41
+ import {
42
+ collectionChromeSlotKinds,
43
+ collectionChromeSlotPlacements,
44
+ } from '@cohesivesystems/presentation-contracts'
45
+
46
+ type ProjectedInlineListModule = NonNullable<ReturnType<typeof usePresentationModule>>
47
+
48
+ export interface ProjectedInlineListProps<TData extends object> {
49
+ readonly actionRuntimeBindings?: readonly PresentationActionRuntimeBinding<
50
+ ProjectedCollectionActionExecutionContext<TData>,
51
+ ReactNode
52
+ >[]
53
+ readonly createHref?: (
54
+ routeId: string,
55
+ parameters?: NavigationRouteParameters,
56
+ ) => string | null
57
+ readonly componentSet?: string
58
+ readonly data: readonly TData[]
59
+ readonly emptyMessage?: string | null
60
+ readonly componentSystem: PresentationComponentSystem
61
+ readonly fieldRenderers?: Record<
62
+ string,
63
+ (context: ProjectedFieldRenderContext<TData>) => ReactNode
64
+ >
65
+ readonly getRowLabel?: (row: TData) => string
66
+ readonly navigateHref?: (href: string) => void
67
+ readonly renderActionIcon?: (placement: ProjectedActionPlacementLike) => ReactNode
68
+ readonly title?: string | null
69
+ readonly viewId: string
70
+ }
71
+
72
+ export function ProjectedInlineList<TData extends object>({
73
+ actionRuntimeBindings,
74
+ componentSet = defaultPresentationComponentSet,
75
+ componentSystem,
76
+ createHref: createHrefOverride,
77
+ data,
78
+ emptyMessage,
79
+ fieldRenderers,
80
+ getRowLabel,
81
+ navigateHref: navigateHrefOverride,
82
+ renderActionIcon,
83
+ title,
84
+ viewId,
85
+ }: ProjectedInlineListProps<TData>) {
86
+ const Badge = componentSystem.badges.Badge
87
+ const module = usePresentationModule()
88
+ const navigation = usePresentationNavigationRuntime()
89
+ const view = findPresentationView<ViewDefinition>(module, viewId)
90
+ const createHref = createHrefOverride ?? navigation.createHref
91
+ const navigateHref = navigateHrefOverride ?? navigation.navigateHref
92
+ const selectionMode = resolveProjectedCollectionSelectionMode(view?.Collection)
93
+ const selectionStateId = resolveProjectedCollectionSelectionStateId(view?.Collection)
94
+ const selectionState = useCollectionSelectionState(
95
+ isCollectionSelectionEnabled(selectionMode)
96
+ ? selectionStateId
97
+ : null,
98
+ )
99
+ const collectionRuntime = useMemo(
100
+ () => createProjectedCollectionRuntime({
101
+ createHref,
102
+ data,
103
+ module,
104
+ selectionState,
105
+ view,
106
+ }),
107
+ [createHref, data, module, selectionState, view],
108
+ )
109
+ const actionIds = useMemo(
110
+ () => [
111
+ ...collectionRuntime.actions.rowActions.map(({ action }) => action.Id),
112
+ ...collectionRuntime.actions.selectionActions.map(({ action }) => action.Id),
113
+ ],
114
+ [
115
+ collectionRuntime.actions.rowActions,
116
+ collectionRuntime.actions.selectionActions,
117
+ ],
118
+ )
119
+ const actionRuntimes = useMemo(
120
+ () =>
121
+ projectPresentationActionRuntimeRegistry<
122
+ ProjectedCollectionActionExecutionContext<TData>,
123
+ ReactNode
124
+ >({
125
+ actionIds,
126
+ module,
127
+ projections: [
128
+ ...(actionRuntimeBindings ?? []),
129
+ ...projectProjectedCollectionActionRuntimeBindings<TData, ReactNode>({
130
+ navigateHref,
131
+ }),
132
+ ],
133
+ }) as ProjectedCollectionActionRuntimeRegistry<TData>,
134
+ [
135
+ actionIds,
136
+ actionRuntimeBindings,
137
+ module,
138
+ navigateHref,
139
+ ],
140
+ )
141
+ const actionRuntimeDiagnostics = useMemo(
142
+ () =>
143
+ projectProjectedCollectionActionRuntimeDiagnostics({
144
+ actionRuntimes,
145
+ collectionRuntime,
146
+ module,
147
+ view,
148
+ }),
149
+ [
150
+ actionRuntimes,
151
+ collectionRuntime,
152
+ module,
153
+ view,
154
+ ],
155
+ )
156
+ useRegisterPresentationProjectionDiagnostics(
157
+ `projected-inline-list-action-runtime.${viewId}`,
158
+ actionRuntimeDiagnostics,
159
+ )
160
+ const rowActionSlot = collectionRuntime.chrome.findSlots(
161
+ collectionChromeSlotKinds.rowActions,
162
+ collectionChromeSlotPlacements.inline,
163
+ )[0] ?? null
164
+ const bodySlot = collectionRuntime.chrome.bodySlot
165
+ const activatedRowAction = collectionRuntime.actions.activatedRowAction
166
+ const canExecuteAction = useCallback(
167
+ (context: ProjectedCollectionActionExecutionContext<TData>) =>
168
+ collectionRuntime.actions.canInvokeAction(context, actionRuntimes),
169
+ [actionRuntimes, collectionRuntime],
170
+ )
171
+ const executeAction = useCallback(
172
+ (context: ProjectedCollectionActionExecutionContext<TData>) =>
173
+ collectionRuntime.actions.invokeAction(context, actionRuntimes),
174
+ [actionRuntimes, collectionRuntime],
175
+ )
176
+ const shouldSelectOnRowClick = Boolean(
177
+ bodySlot?.SelectOnRowClick && collectionRuntime.selection.state,
178
+ )
179
+ const shouldActivateOnRowClick = Boolean(bodySlot?.ActivateOnRowClick && activatedRowAction)
180
+ const handleRowClick = useCallback(
181
+ (row: TData, index: number) => {
182
+ if (shouldSelectOnRowClick) {
183
+ collectionRuntime.selection.activateRow(row, index)
184
+ }
185
+
186
+ if (!shouldActivateOnRowClick || !activatedRowAction) {
187
+ return
188
+ }
189
+
190
+ const actionContext = collectionRuntime.actions.createRowActionContext(
191
+ activatedRowAction,
192
+ row,
193
+ )
194
+ if (canExecuteAction(actionContext)) {
195
+ void executeAction(actionContext)
196
+ }
197
+ },
198
+ [
199
+ activatedRowAction,
200
+ canExecuteAction,
201
+ collectionRuntime,
202
+ executeAction,
203
+ shouldActivateOnRowClick,
204
+ shouldSelectOnRowClick,
205
+ ],
206
+ )
207
+
208
+ if (!module) {
209
+ return <ProjectedInlineListStatus label="Presentation module is not available." />
210
+ }
211
+
212
+ if (!view) {
213
+ return <ProjectedInlineListStatus label={`Presentation view '${viewId}' is not available.`} />
214
+ }
215
+
216
+ if (collectionRuntime.columns.length === 0) {
217
+ return <ProjectedInlineListStatus label={`Presentation view '${view.Name}' has no projected fields.`} />
218
+ }
219
+
220
+ if (data.length === 0) {
221
+ const emptyMessageLabel = collectionRuntime.chrome.bodySlot?.EmptyMessage ?? emptyMessage
222
+ return emptyMessageLabel ? (
223
+ <ProjectedInlineListStatus label={emptyMessageLabel} />
224
+ ) : null
225
+ }
226
+
227
+ return (
228
+ <div className="grid gap-2 rounded-lg border border-slate-950/8 bg-white/70 p-3">
229
+ <div className="flex flex-wrap items-center justify-between gap-2">
230
+ <p className="text-sm font-semibold text-slate-950">{title ?? view.Name}</p>
231
+ <Badge className="border-slate-950/10 bg-white text-slate-600" variant="outline">
232
+ {data.length.toLocaleString()}
233
+ </Badge>
234
+ </div>
235
+ <div className="grid gap-2">
236
+ {data.map((row, index) => (
237
+ <ProjectedInlineListRow
238
+ canExecuteAction={canExecuteAction}
239
+ collectionRuntime={collectionRuntime}
240
+ componentSet={componentSet}
241
+ componentSystem={componentSystem}
242
+ createHref={createHref}
243
+ executeAction={executeAction}
244
+ fieldRenderers={fieldRenderers}
245
+ getRowLabel={getRowLabel}
246
+ index={index}
247
+ key={collectionRuntime.getRowId?.(row, index) ?? index}
248
+ module={module}
249
+ navigateHref={navigateHref}
250
+ onRowClick={
251
+ shouldSelectOnRowClick || shouldActivateOnRowClick
252
+ ? handleRowClick
253
+ : undefined
254
+ }
255
+ renderActionIcon={renderActionIcon}
256
+ row={row}
257
+ rowActionSlot={rowActionSlot}
258
+ viewId={viewId}
259
+ />
260
+ ))}
261
+ </div>
262
+ </div>
263
+ )
264
+ }
265
+
266
+ function ProjectedInlineListRow<TData extends object>({
267
+ canExecuteAction,
268
+ collectionRuntime,
269
+ componentSet,
270
+ componentSystem,
271
+ createHref,
272
+ executeAction,
273
+ fieldRenderers,
274
+ getRowLabel,
275
+ index,
276
+ module,
277
+ navigateHref,
278
+ onRowClick,
279
+ renderActionIcon,
280
+ row,
281
+ rowActionSlot,
282
+ viewId,
283
+ }: {
284
+ readonly canExecuteAction: (
285
+ context: ProjectedCollectionActionExecutionContext<TData>,
286
+ ) => boolean
287
+ readonly collectionRuntime: ProjectedCollectionRuntime<TData>
288
+ readonly componentSet: string
289
+ readonly componentSystem: PresentationComponentSystem
290
+ readonly createHref?: (
291
+ routeId: string,
292
+ parameters?: NavigationRouteParameters,
293
+ ) => string | null
294
+ readonly executeAction: (
295
+ context: ProjectedCollectionActionExecutionContext<TData>,
296
+ ) => Promise<void> | void
297
+ readonly fieldRenderers?: Record<
298
+ string,
299
+ (context: ProjectedFieldRenderContext<TData>) => ReactNode
300
+ >
301
+ readonly getRowLabel?: (row: TData) => string
302
+ readonly index: number
303
+ readonly module: ProjectedInlineListModule
304
+ readonly navigateHref?: (href: string) => void
305
+ readonly onRowClick?: (row: TData, index: number) => void
306
+ readonly renderActionIcon?: (placement: ProjectedActionPlacementLike) => ReactNode
307
+ readonly row: TData
308
+ readonly rowActionSlot: CollectionChromeSlotDefinition | null
309
+ readonly viewId: string
310
+ }) {
311
+ const [primaryColumn, ...supportingColumns] = collectionRuntime.columns
312
+ const rowLabel = getRowLabel?.(row) ?? collectionRuntime.readRowLabel(row)
313
+
314
+ return (
315
+ <div
316
+ className={cn(
317
+ 'grid gap-2 rounded-md border border-slate-950/8 bg-white/78 px-3 py-2',
318
+ onRowClick ? 'cursor-pointer hover:border-slate-950/15 hover:bg-white' : null,
319
+ )}
320
+ onClick={onRowClick ? () => onRowClick(row, index) : undefined}
321
+ >
322
+ <div className="flex items-start justify-between gap-3">
323
+ <div className="min-w-0">
324
+ {primaryColumn ? (
325
+ <div className="text-sm font-medium text-slate-950">
326
+ {renderInlineListField({
327
+ column: primaryColumn,
328
+ componentSystem,
329
+ createHref,
330
+ fieldRenderers,
331
+ module,
332
+ navigateHref,
333
+ row,
334
+ })}
335
+ </div>
336
+ ) : (
337
+ <p className="text-sm font-medium text-slate-950">{rowLabel ?? `Item ${index + 1}`}</p>
338
+ )}
339
+ </div>
340
+ {rowActionSlot ? (
341
+ <ProjectedCollectionRowActions
342
+ canExecuteAction={canExecuteAction}
343
+ collectionRuntime={collectionRuntime}
344
+ componentSet={componentSet}
345
+ componentSystem={componentSystem}
346
+ executeAction={executeAction}
347
+ module={module}
348
+ renderActionIcon={renderActionIcon}
349
+ row={row}
350
+ rowLabel={rowLabel}
351
+ slot={rowActionSlot}
352
+ viewId={viewId}
353
+ />
354
+ ) : null}
355
+ </div>
356
+
357
+ {supportingColumns.length > 0 ? (
358
+ <div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-slate-500">
359
+ {supportingColumns.map((column) => (
360
+ <span className="inline-flex min-w-0 items-center gap-1.5" key={column.id}>
361
+ <span className="shrink-0 font-medium text-slate-400">{column.header}</span>
362
+ <span className="min-w-0 break-all text-slate-600">
363
+ {renderInlineListField({
364
+ column,
365
+ componentSystem,
366
+ createHref,
367
+ fieldRenderers,
368
+ module,
369
+ navigateHref,
370
+ row,
371
+ })}
372
+ </span>
373
+ </span>
374
+ ))}
375
+ </div>
376
+ ) : null}
377
+ </div>
378
+ )
379
+ }
380
+
381
+ function renderInlineListField<TData extends object>({
382
+ column,
383
+ componentSystem,
384
+ createHref,
385
+ fieldRenderers,
386
+ module,
387
+ navigateHref,
388
+ row,
389
+ }: {
390
+ readonly column: {
391
+ readonly field: FieldPresentationDefinition
392
+ readonly readValue: (row: TData) => unknown
393
+ }
394
+ readonly componentSystem: PresentationComponentSystem
395
+ readonly createHref?: (
396
+ routeId: string,
397
+ parameters?: NavigationRouteParameters,
398
+ ) => string | null
399
+ readonly fieldRenderers?: Record<
400
+ string,
401
+ (context: ProjectedFieldRenderContext<TData>) => ReactNode
402
+ >
403
+ readonly module: ProjectedInlineListModule
404
+ readonly navigateHref?: (href: string) => void
405
+ readonly row: TData
406
+ }) {
407
+ const field = column.field
408
+ const value = column.readValue(row)
409
+ const renderer = fieldRenderers?.[field.Id] ?? fieldRenderers?.[field.Field]
410
+ return renderer
411
+ ? renderer({ field, row, value })
412
+ : renderProjectedFieldValue({
413
+ componentSystem,
414
+ createHref,
415
+ emptyValueFallback: <span className="text-slate-400">none</span>,
416
+ field,
417
+ module,
418
+ navigateHref,
419
+ resource: row,
420
+ value,
421
+ })
422
+ }
423
+
424
+ function ProjectedInlineListStatus({ label }: { readonly label: ReactNode }) {
425
+ return (
426
+ <div className="rounded-md border border-slate-950/8 bg-white/65 px-4 py-3 text-sm text-slate-500">
427
+ {label}
428
+ </div>
429
+ )
430
+ }
431
+
432
+ function cn(...values: readonly (string | null | undefined | false)[]) {
433
+ return values.filter(Boolean).join(' ')
434
+ }