@dxos/plugin-kanban 0.8.4-main.dedc0f3 → 0.8.4-main.dfabb4ec29

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 (275) hide show
  1. package/dist/lib/neutral/KanbanContainer-QK6LNCYT.mjs +132 -0
  2. package/dist/lib/neutral/KanbanContainer-QK6LNCYT.mjs.map +7 -0
  3. package/dist/lib/neutral/KanbanPlugin.mjs +36 -0
  4. package/dist/lib/neutral/KanbanPlugin.mjs.map +7 -0
  5. package/dist/lib/neutral/KanbanPlugin.node.mjs +27 -0
  6. package/dist/lib/neutral/KanbanPlugin.node.mjs.map +7 -0
  7. package/dist/lib/neutral/KanbanSettings-G6M47NSK.mjs +83 -0
  8. package/dist/lib/neutral/KanbanSettings-G6M47NSK.mjs.map +7 -0
  9. package/dist/lib/neutral/blueprint-definition-FHVIEKTQ.mjs +15 -0
  10. package/dist/lib/neutral/blueprint-definition-FHVIEKTQ.mjs.map +7 -0
  11. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  12. package/dist/lib/neutral/capabilities/index.mjs +19 -0
  13. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  14. package/dist/lib/neutral/chunk-E65AME5F.mjs +255 -0
  15. package/dist/lib/neutral/chunk-E65AME5F.mjs.map +7 -0
  16. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  17. package/dist/lib/neutral/chunk-KDPM77BD.mjs +21 -0
  18. package/dist/lib/neutral/chunk-KDPM77BD.mjs.map +7 -0
  19. package/dist/lib/neutral/chunk-Z7O5CETK.mjs +8 -0
  20. package/dist/lib/neutral/chunk-Z7O5CETK.mjs.map +7 -0
  21. package/dist/lib/neutral/chunk-ZTQW5KQS.mjs +26 -0
  22. package/dist/lib/neutral/chunk-ZTQW5KQS.mjs.map +7 -0
  23. package/dist/lib/neutral/components/index.mjs +243 -0
  24. package/dist/lib/neutral/components/index.mjs.map +7 -0
  25. package/dist/lib/neutral/containers/index.mjs +11 -0
  26. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  27. package/dist/lib/neutral/create-object-DKBSI46K.mjs +40 -0
  28. package/dist/lib/neutral/create-object-DKBSI46K.mjs.map +7 -0
  29. package/dist/lib/neutral/delete-card-QKT6OXGP.mjs +24 -0
  30. package/dist/lib/neutral/delete-card-QKT6OXGP.mjs.map +7 -0
  31. package/dist/lib/neutral/delete-card-field-XQKM7ZXE.mjs +42 -0
  32. package/dist/lib/neutral/delete-card-field-XQKM7ZXE.mjs.map +7 -0
  33. package/dist/lib/neutral/hooks/index.mjs +432 -0
  34. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  35. package/dist/lib/neutral/index.mjs +34 -0
  36. package/dist/lib/neutral/index.mjs.map +7 -0
  37. package/dist/lib/neutral/meta.json +1 -0
  38. package/dist/lib/neutral/meta.mjs +8 -0
  39. package/dist/lib/neutral/meta.mjs.map +7 -0
  40. package/dist/lib/neutral/migrations-4NS6H7U2.mjs +31 -0
  41. package/dist/lib/neutral/migrations-4NS6H7U2.mjs.map +7 -0
  42. package/dist/lib/neutral/operation-handler-B7IW6MXU.mjs +13 -0
  43. package/dist/lib/neutral/operation-handler-B7IW6MXU.mjs.map +7 -0
  44. package/dist/lib/neutral/operations/index.mjs +8 -0
  45. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  46. package/dist/lib/neutral/plugin.mjs +16 -0
  47. package/dist/lib/neutral/plugin.mjs.map +7 -0
  48. package/dist/lib/neutral/react-surface-6RVSCHMJ.mjs +93 -0
  49. package/dist/lib/neutral/react-surface-6RVSCHMJ.mjs.map +7 -0
  50. package/dist/lib/neutral/restore-card-XW7AHMPO.mjs +21 -0
  51. package/dist/lib/neutral/restore-card-XW7AHMPO.mjs.map +7 -0
  52. package/dist/lib/neutral/restore-card-field-QOAUY3RJ.mjs +40 -0
  53. package/dist/lib/neutral/restore-card-field-QOAUY3RJ.mjs.map +7 -0
  54. package/dist/lib/neutral/testing/index.mjs +60 -0
  55. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  56. package/dist/lib/neutral/translations.mjs +44 -0
  57. package/dist/lib/neutral/translations.mjs.map +7 -0
  58. package/dist/lib/neutral/types/index.mjs +22 -0
  59. package/dist/lib/neutral/types/index.mjs.map +7 -0
  60. package/dist/lib/neutral/undo-mappings-6CHW6BOF.mjs +42 -0
  61. package/dist/lib/neutral/undo-mappings-6CHW6BOF.mjs.map +7 -0
  62. package/dist/types/src/KanbanPlugin.d.ts +3 -1
  63. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  64. package/dist/types/src/KanbanPlugin.node.d.ts +4 -0
  65. package/dist/types/src/KanbanPlugin.node.d.ts.map +1 -0
  66. package/dist/types/src/KanbanPlugin.test.d.ts +2 -0
  67. package/dist/types/src/KanbanPlugin.test.d.ts.map +1 -0
  68. package/dist/types/src/blueprints/index.d.ts +2 -0
  69. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  70. package/dist/types/src/blueprints/kanban-blueprint.d.ts +4 -0
  71. package/dist/types/src/blueprints/kanban-blueprint.d.ts.map +1 -0
  72. package/dist/types/src/capabilities/artifact-definition.d.ts +3 -2
  73. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  74. package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -4
  75. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  76. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  77. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  78. package/dist/types/src/capabilities/index.d.ts +13 -3
  79. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  80. package/dist/types/src/capabilities/migrations.d.ts +5 -0
  81. package/dist/types/src/capabilities/migrations.d.ts.map +1 -0
  82. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  83. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  84. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  85. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  86. package/dist/types/src/capabilities/undo-mappings.d.ts +5 -0
  87. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -0
  88. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts +37 -0
  89. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts.map +1 -0
  90. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts +72 -0
  91. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts.map +1 -0
  92. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts +9 -0
  93. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -0
  94. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts +8 -0
  95. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts.map +1 -0
  96. package/dist/types/src/components/KanbanBoard/context.d.ts +38 -0
  97. package/dist/types/src/components/KanbanBoard/context.d.ts.map +1 -0
  98. package/dist/types/src/components/KanbanBoard/index.d.ts +2 -0
  99. package/dist/types/src/components/KanbanBoard/index.d.ts.map +1 -0
  100. package/dist/types/src/components/index.d.ts +1 -2
  101. package/dist/types/src/components/index.d.ts.map +1 -1
  102. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts +6 -0
  103. package/dist/types/src/containers/KanbanContainer/KanbanContainer.d.ts.map +1 -0
  104. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts +79 -0
  105. package/dist/types/src/containers/KanbanContainer/KanbanContainer.stories.d.ts.map +1 -0
  106. package/dist/types/src/containers/KanbanContainer/index.d.ts +2 -0
  107. package/dist/types/src/containers/KanbanContainer/index.d.ts.map +1 -0
  108. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts +13 -0
  109. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts.map +1 -0
  110. package/dist/types/src/containers/KanbanSettings/index.d.ts +2 -0
  111. package/dist/types/src/containers/KanbanSettings/index.d.ts.map +1 -0
  112. package/dist/types/src/containers/index.d.ts +4 -0
  113. package/dist/types/src/containers/index.d.ts.map +1 -0
  114. package/dist/types/src/hooks/index.d.ts +7 -0
  115. package/dist/types/src/hooks/index.d.ts.map +1 -0
  116. package/dist/types/src/hooks/useEchoChangeCallback.d.ts +13 -0
  117. package/dist/types/src/hooks/useEchoChangeCallback.d.ts.map +1 -0
  118. package/dist/types/src/hooks/useItemsProjection.d.ts +10 -0
  119. package/dist/types/src/hooks/useItemsProjection.d.ts.map +1 -0
  120. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts +2 -0
  121. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts.map +1 -0
  122. package/dist/types/src/hooks/useKanbanBoardModel.d.ts +16 -0
  123. package/dist/types/src/hooks/useKanbanBoardModel.d.ts.map +1 -0
  124. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts +22 -0
  125. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts.map +1 -0
  126. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts +19 -0
  127. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts.map +1 -0
  128. package/dist/types/src/hooks/useProjectionModel.d.ts +15 -0
  129. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
  130. package/dist/types/src/index.d.ts +3 -1
  131. package/dist/types/src/index.d.ts.map +1 -1
  132. package/dist/types/src/meta.d.ts +2 -3
  133. package/dist/types/src/meta.d.ts.map +1 -1
  134. package/dist/types/src/operations/delete-card-field.d.ts +5 -0
  135. package/dist/types/src/operations/delete-card-field.d.ts.map +1 -0
  136. package/dist/types/src/operations/delete-card.d.ts +5 -0
  137. package/dist/types/src/operations/delete-card.d.ts.map +1 -0
  138. package/dist/types/src/operations/index.d.ts +3 -0
  139. package/dist/types/src/operations/index.d.ts.map +1 -0
  140. package/dist/types/src/operations/restore-card-field.d.ts +5 -0
  141. package/dist/types/src/operations/restore-card-field.d.ts.map +1 -0
  142. package/dist/types/src/operations/restore-card.d.ts +5 -0
  143. package/dist/types/src/operations/restore-card.d.ts.map +1 -0
  144. package/dist/types/src/playwright/board-manager.d.ts +5 -0
  145. package/dist/types/src/playwright/board-manager.d.ts.map +1 -0
  146. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  147. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  148. package/dist/types/src/playwright/smoke.spec.d.ts +2 -0
  149. package/dist/types/src/playwright/smoke.spec.d.ts.map +1 -0
  150. package/dist/types/src/plugin.d.ts +4 -0
  151. package/dist/types/src/plugin.d.ts.map +1 -0
  152. package/dist/types/src/testing/KanbanCardTileSimple.d.ts +7 -0
  153. package/dist/types/src/testing/KanbanCardTileSimple.d.ts.map +1 -0
  154. package/dist/types/src/testing/index.d.ts +2 -0
  155. package/dist/types/src/testing/index.d.ts.map +1 -0
  156. package/dist/types/src/translations.d.ts +50 -22
  157. package/dist/types/src/translations.d.ts.map +1 -1
  158. package/dist/types/src/types/Kanban.d.ts +109 -0
  159. package/dist/types/src/types/Kanban.d.ts.map +1 -0
  160. package/dist/types/src/types/KanbanOperation.d.ts +52 -0
  161. package/dist/types/src/types/KanbanOperation.d.ts.map +1 -0
  162. package/dist/types/src/types/constants.d.ts +6 -0
  163. package/dist/types/src/types/constants.d.ts.map +1 -0
  164. package/dist/types/src/types/index.d.ts +3 -0
  165. package/dist/types/src/types/index.d.ts.map +1 -1
  166. package/dist/types/src/types/migrations.test.d.ts +2 -0
  167. package/dist/types/src/types/migrations.test.d.ts.map +1 -0
  168. package/dist/types/src/types/schema.d.ts +18 -52
  169. package/dist/types/src/types/schema.d.ts.map +1 -1
  170. package/dist/types/src/types/types.d.ts +28 -0
  171. package/dist/types/src/types/types.d.ts.map +1 -1
  172. package/dist/types/src/util/arrangement.d.ts +72 -0
  173. package/dist/types/src/util/arrangement.d.ts.map +1 -0
  174. package/dist/types/src/util/arrangement.test.d.ts +2 -0
  175. package/dist/types/src/util/arrangement.test.d.ts.map +1 -0
  176. package/dist/types/src/util/index.d.ts +2 -0
  177. package/dist/types/src/util/index.d.ts.map +1 -0
  178. package/dist/types/tsconfig.tsbuildinfo +1 -1
  179. package/package.json +120 -57
  180. package/src/KanbanPlugin.node.ts +21 -0
  181. package/src/KanbanPlugin.test.ts +31 -0
  182. package/src/KanbanPlugin.tsx +29 -57
  183. package/src/blueprints/index.ts +5 -0
  184. package/src/blueprints/kanban-blueprint.ts +27 -0
  185. package/src/capabilities/artifact-definition.ts +117 -113
  186. package/src/capabilities/blueprint-definition.ts +13 -24
  187. package/src/capabilities/create-object.ts +40 -0
  188. package/src/capabilities/index.ts +12 -4
  189. package/src/capabilities/migrations.ts +35 -0
  190. package/src/capabilities/operation-handler.ts +14 -0
  191. package/src/capabilities/react-surface.tsx +79 -68
  192. package/src/capabilities/undo-mappings.ts +34 -0
  193. package/src/components/KanbanBoard/KanbanBoard.stories.tsx +146 -0
  194. package/src/components/KanbanBoard/KanbanBoard.tsx +164 -0
  195. package/src/components/KanbanBoard/KanbanCard.tsx +101 -0
  196. package/src/components/KanbanBoard/KanbanColumn.tsx +72 -0
  197. package/src/components/KanbanBoard/context.ts +54 -0
  198. package/src/components/KanbanBoard/index.ts +5 -0
  199. package/src/components/index.ts +1 -2
  200. package/src/containers/KanbanContainer/KanbanContainer.stories.tsx +277 -0
  201. package/src/containers/KanbanContainer/KanbanContainer.tsx +178 -0
  202. package/src/containers/KanbanContainer/index.ts +5 -0
  203. package/src/containers/KanbanSettings/KanbanSettings.tsx +94 -0
  204. package/src/containers/KanbanSettings/index.ts +5 -0
  205. package/src/containers/index.ts +8 -0
  206. package/src/hooks/index.ts +10 -0
  207. package/src/hooks/useEchoChangeCallback.ts +30 -0
  208. package/src/hooks/useItemsProjection.ts +44 -0
  209. package/src/hooks/useKanbanBoardModel.browser.test.ts +235 -0
  210. package/src/hooks/useKanbanBoardModel.ts +157 -0
  211. package/src/hooks/useKanbanColumnEventHandler.ts +106 -0
  212. package/src/hooks/useKanbanItemEventHandler.ts +133 -0
  213. package/src/hooks/useProjectionModel.ts +58 -0
  214. package/src/index.ts +3 -2
  215. package/src/meta.ts +9 -7
  216. package/src/operations/delete-card-field.ts +47 -0
  217. package/src/operations/delete-card.ts +23 -0
  218. package/src/operations/index.ts +10 -0
  219. package/src/operations/restore-card-field.ts +41 -0
  220. package/src/operations/restore-card.ts +21 -0
  221. package/src/playwright/board-manager.ts +13 -0
  222. package/src/playwright/playwright.config.ts +19 -0
  223. package/src/playwright/smoke.spec.ts +107 -0
  224. package/src/plugin.ts +11 -0
  225. package/src/testing/KanbanCardTileSimple.tsx +82 -0
  226. package/src/testing/index.ts +5 -0
  227. package/src/translations.ts +28 -20
  228. package/src/types/Kanban.ts +151 -0
  229. package/src/types/KanbanOperation.ts +67 -0
  230. package/src/types/constants.ts +9 -0
  231. package/src/types/index.ts +4 -0
  232. package/src/types/migrations.test.ts +83 -0
  233. package/src/types/schema.ts +33 -45
  234. package/src/types/types.ts +35 -0
  235. package/src/util/arrangement.test.ts +218 -0
  236. package/src/util/arrangement.ts +177 -0
  237. package/src/util/index.ts +5 -0
  238. package/dist/lib/browser/blueprint-definition-GFG7LX2C.mjs +0 -28
  239. package/dist/lib/browser/blueprint-definition-GFG7LX2C.mjs.map +0 -7
  240. package/dist/lib/browser/chunk-NCNNL74W.mjs +0 -82
  241. package/dist/lib/browser/chunk-NCNNL74W.mjs.map +0 -7
  242. package/dist/lib/browser/index.mjs +0 -106
  243. package/dist/lib/browser/index.mjs.map +0 -7
  244. package/dist/lib/browser/intent-resolver-KHOAFPNN.mjs +0 -111
  245. package/dist/lib/browser/intent-resolver-KHOAFPNN.mjs.map +0 -7
  246. package/dist/lib/browser/meta.json +0 -1
  247. package/dist/lib/browser/react-surface-UBRYXDKS.mjs +0 -253
  248. package/dist/lib/browser/react-surface-UBRYXDKS.mjs.map +0 -7
  249. package/dist/lib/browser/types/index.mjs +0 -11
  250. package/dist/lib/node-esm/blueprint-definition-MIMDXMUM.mjs +0 -30
  251. package/dist/lib/node-esm/blueprint-definition-MIMDXMUM.mjs.map +0 -7
  252. package/dist/lib/node-esm/chunk-5B3LKGA7.mjs +0 -84
  253. package/dist/lib/node-esm/chunk-5B3LKGA7.mjs.map +0 -7
  254. package/dist/lib/node-esm/index.mjs +0 -107
  255. package/dist/lib/node-esm/index.mjs.map +0 -7
  256. package/dist/lib/node-esm/intent-resolver-MKO5HVES.mjs +0 -112
  257. package/dist/lib/node-esm/intent-resolver-MKO5HVES.mjs.map +0 -7
  258. package/dist/lib/node-esm/meta.json +0 -1
  259. package/dist/lib/node-esm/react-surface-B2FPS52G.mjs +0 -254
  260. package/dist/lib/node-esm/react-surface-B2FPS52G.mjs.map +0 -7
  261. package/dist/lib/node-esm/types/index.mjs +0 -12
  262. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  263. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  264. package/dist/types/src/components/KanbanContainer.d.ts +0 -7
  265. package/dist/types/src/components/KanbanContainer.d.ts.map +0 -1
  266. package/dist/types/src/components/KanbanContainer.stories.d.ts +0 -41
  267. package/dist/types/src/components/KanbanContainer.stories.d.ts.map +0 -1
  268. package/dist/types/src/components/KanbanViewEditor.d.ts +0 -8
  269. package/dist/types/src/components/KanbanViewEditor.d.ts.map +0 -1
  270. package/src/capabilities/intent-resolver.ts +0 -71
  271. package/src/components/KanbanContainer.stories.tsx +0 -190
  272. package/src/components/KanbanContainer.tsx +0 -95
  273. package/src/components/KanbanViewEditor.tsx +0 -62
  274. /package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  275. /package/dist/lib/{node-esm/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
@@ -2,29 +2,18 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes } from '@dxos/app-framework';
6
- import { Blueprint, Template } from '@dxos/blueprints';
7
- import { type FunctionDefinition } from '@dxos/functions';
8
- import { trim } from '@dxos/util';
5
+ import * as Effect from 'effect/Effect';
9
6
 
10
- const functions: FunctionDefinition[] = [];
11
- const tools: string[] = [];
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
9
+ // eslint-disable-next-line unused-imports/no-unused-imports
10
+ import type { Blueprint } from '@dxos/compute';
12
11
 
13
- export default () => {
14
- return [
15
- contributes(Capabilities.Functions, functions),
16
- contributes(
17
- Capabilities.BlueprintDefinition,
18
- Blueprint.make({
19
- key: 'dxos.org/blueprint/kanban',
20
- name: 'Kanban',
21
- tools: Blueprint.toolDefinitions({ functions, tools }),
22
- instructions: Template.make({
23
- source: trim`
24
- You can create and update kanban boards to show data in sorted columns defined by schema.
25
- `,
26
- }),
27
- }),
28
- ),
29
- ];
30
- };
12
+ import { KanbanBlueprint } from '#blueprints';
13
+
14
+ const blueprintDefinition = Capability.makeModule<
15
+ [],
16
+ Capability.Capability<typeof AppCapabilities.BlueprintDefinition>[]
17
+ >(() => Effect.succeed([Capability.contributes(AppCapabilities.BlueprintDefinition, KanbanBlueprint)]));
18
+
19
+ export default blueprintDefinition;
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { Operation } from '@dxos/compute';
9
+ import { Type } from '@dxos/echo';
10
+ import { SpaceOperation } from '@dxos/plugin-space';
11
+ import { SpaceCapabilities } from '@dxos/plugin-space';
12
+ import { ViewModel } from '@dxos/schema';
13
+
14
+ import { CreateKanbanSchema, Kanban } from '#types';
15
+
16
+ export default Capability.makeModule(
17
+ Effect.fnUntraced(function* () {
18
+ return Capability.contributes(SpaceCapabilities.CreateObjectEntry, {
19
+ id: Type.getTypename(Kanban.Kanban),
20
+ inputSchema: CreateKanbanSchema,
21
+ createObject: (props, options) =>
22
+ Effect.gen(function* () {
23
+ const object = yield* Effect.promise(async () => {
24
+ const { view } = await ViewModel.makeFromDatabase({
25
+ db: options.db,
26
+ typename: props.typename,
27
+ pivotFieldName: props.initialPivotColumn,
28
+ });
29
+ return Kanban.make({ name: props.name, view });
30
+ });
31
+ return yield* Operation.invoke(SpaceOperation.AddObject, {
32
+ object,
33
+ target: options.target,
34
+ hidden: true,
35
+ targetNodeId: options.targetNodeId,
36
+ });
37
+ }),
38
+ });
39
+ }),
40
+ );
@@ -2,8 +2,16 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { lazy } from '@dxos/app-framework';
5
+ import { Capability } from '@dxos/app-framework';
6
+ // eslint-disable-next-line unused-imports/no-unused-imports
7
+ import type { Blueprint, OperationHandlerSet } from '@dxos/compute';
6
8
 
7
- export const BlueprintDefinition = lazy(() => import('./blueprint-definition'));
8
- export const IntentResolver = lazy(() => import('./intent-resolver'));
9
- export const ReactSurface = lazy(() => import('./react-surface'));
9
+ export const BlueprintDefinition = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
10
+ export const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));
11
+ export const Migrations = Capability.lazy('Migrations', () => import('./migrations'));
12
+ export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
13
+ 'OperationHandler',
14
+ () => import('./operation-handler'),
15
+ );
16
+ export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
17
+ export const UndoMappings = Capability.lazy('UndoMappings', () => import('./undo-mappings'));
@@ -0,0 +1,35 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { defineObjectMigration } from '@dxos/client/echo';
9
+ import { ClientCapabilities } from '@dxos/plugin-client';
10
+
11
+ import { Kanban } from '#types';
12
+
13
+ /**
14
+ * v0.1.0 → v0.2.0: nests the existing `view` ref under a `spec: { kind: 'view', view }`
15
+ * discriminated union. v0.2.0 introduced an items-variant for externally-synced kanbans;
16
+ * pre-migration objects were all view-based by construction.
17
+ */
18
+ const migrations = [
19
+ defineObjectMigration({
20
+ from: Kanban.KanbanV1,
21
+ to: Kanban.Kanban,
22
+ transform: async (from) => ({
23
+ name: from.name,
24
+ arrangement: from.arrangement,
25
+ spec: { kind: 'view' as const, view: from.view },
26
+ }),
27
+ onMigration: async () => {},
28
+ }),
29
+ ];
30
+
31
+ export default Capability.makeModule(
32
+ Effect.fnUntraced(function* () {
33
+ return Capability.contributes(ClientCapabilities.Migration, migrations);
34
+ }),
35
+ );
@@ -0,0 +1,14 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Capabilities, Capability } from '@dxos/app-framework';
6
+ import type { OperationHandlerSet } from '@dxos/compute';
7
+
8
+ import { KanbanOperationHandlerSet } from '#operations';
9
+
10
+ export default Capability.makeModule<OperationHandlerSet.OperationHandlerSet>(
11
+ Effect.fnUntraced(function* () {
12
+ return Capability.contributes(Capabilities.OperationHandler, KanbanOperationHandlerSet);
13
+ }),
14
+ );
@@ -2,83 +2,94 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Schema } from 'effect';
5
+ import * as Effect from 'effect/Effect';
6
+ import type * as Schema from 'effect/Schema';
7
+ import * as SchemaAST from 'effect/SchemaAST';
6
8
  import React, { useMemo } from 'react';
7
9
 
8
- import { Capabilities, contributes, createSurface, useCapabilities } from '@dxos/app-framework';
9
- import { Obj, Type } from '@dxos/echo';
10
+ import { Capabilities, Capability } from '@dxos/app-framework';
11
+ import { Surface } from '@dxos/app-framework/ui';
12
+ import { AppSurface } from '@dxos/app-toolkit/ui';
13
+ import { Database, JsonSchema, Obj } from '@dxos/echo';
14
+ import { type Collection } from '@dxos/echo';
10
15
  import { findAnnotation } from '@dxos/effect';
11
- import { ClientCapabilities } from '@dxos/plugin-client';
12
- import { type Space, getSpace, isSpace } from '@dxos/react-client/echo';
13
- import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
14
- import { Kanban } from '@dxos/react-ui-kanban/types';
15
- import { DataType } from '@dxos/schema';
16
+ import { type FormFieldComponentProps, SelectField, useFormValues } from '@dxos/react-ui-form';
16
17
 
17
- import { KanbanContainer, KanbanViewEditor } from '../components';
18
- import { meta } from '../meta';
19
- import { PivotColumnAnnotationId } from '../types';
18
+ import { KanbanContainer, KanbanSettings } from '#containers';
19
+ import { Kanban, PivotColumnAnnotationId } from '#types';
20
20
 
21
- export default () =>
22
- contributes(Capabilities.ReactSurface, [
23
- createSurface({
24
- id: meta.id,
25
- role: ['article', 'section'],
26
- filter: (data): data is { subject: DataType.View } =>
27
- Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
28
- component: ({ data, role }) => <KanbanContainer view={data.subject} role={role} />,
29
- }),
30
- createSurface({
31
- id: `${meta.id}/object-settings`,
32
- role: 'object-settings',
33
- position: 'hoist',
34
- filter: (data): data is { subject: DataType.View } =>
35
- Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
36
- component: ({ data }) => <KanbanViewEditor view={data.subject} />,
37
- }),
38
- createSurface({
39
- id: `${meta.id}/create-initial-schema-form-[pivot-column]`,
40
- role: 'form-input',
41
- filter: (
42
- data,
43
- ): data is { prop: string; schema: Schema.Schema<any>; target: Space | DataType.Collection | undefined } => {
44
- const annotation = findAnnotation<boolean>((data.schema as Schema.Schema.All).ast, PivotColumnAnnotationId);
45
- return !!annotation;
46
- },
47
- component: ({ data: { target }, ...inputProps }) => {
48
- const props = inputProps as any as InputProps;
49
- const space = isSpace(target) ? target : getSpace(target);
50
- if (!space) {
51
- return null;
52
- }
53
- const { typename } = useFormValues();
54
- // TODO(wittjosiah): Unify this schema lookup.
55
- const schemaWhitelists = useCapabilities(ClientCapabilities.SchemaWhiteList);
56
- const staticSchema = schemaWhitelists.flat().find((schema) => Type.getTypename(schema) === typename);
57
- const [selectedSchema] = space?.db.schemaRegistry.query({ typename }).runSync();
21
+ export default Capability.makeModule(() =>
22
+ Effect.succeed(
23
+ Capability.contributes(Capabilities.ReactSurface, [
24
+ Surface.create({
25
+ id: 'root',
26
+ // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.
27
+ filter: AppSurface.oneOf(
28
+ AppSurface.object(AppSurface.Article, Kanban.Kanban),
29
+ AppSurface.object(AppSurface.Section, Kanban.Kanban),
30
+ ),
31
+ component: ({ data, role }) => <KanbanContainer role={role} subject={data.subject} />,
32
+ }),
33
+ Surface.create({
34
+ id: 'object-properties',
35
+ position: 'hoist',
36
+ filter: AppSurface.object(AppSurface.ObjectProperties, Kanban.Kanban),
37
+ component: ({ data }) => <KanbanSettings subject={data.subject} />,
38
+ }),
39
+ Surface.create({
40
+ id: 'create-initial-schema-form-[pivot-column]',
41
+ role: 'form-input',
42
+ filter: (
43
+ data,
44
+ ): data is {
45
+ prop: string;
46
+ schema: Schema.Schema<any>;
47
+ target: Database.Database | Collection.Collection | undefined;
48
+ fieldPropertyAst?: SchemaAST.AST;
49
+ } => {
50
+ const annotation = findAnnotation<boolean>((data.schema as Schema.Schema.All).ast, PivotColumnAnnotationId);
51
+ return !!annotation;
52
+ },
53
+ component: ({ data: { target, fieldPropertyAst }, ...inputProps }) => {
54
+ const ast = fieldPropertyAst;
55
+ if (!ast) {
56
+ return null;
57
+ }
58
58
 
59
- const singleSelectColumns = useMemo(() => {
60
- const properties = staticSchema
61
- ? Type.toJsonSchema(staticSchema).properties
62
- : selectedSchema?.jsonSchema?.properties;
63
- if (!properties) {
64
- return [];
59
+ const props = { ...inputProps, type: ast } as any as FormFieldComponentProps;
60
+ const db = Database.isDatabase(target) ? target : target && Obj.getDatabase(target);
61
+ if (!db) {
62
+ return null;
65
63
  }
66
64
 
67
- const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {
68
- if (typeof value === 'object' && value?.format === 'single-select') {
69
- acc.push(key);
65
+ const { typename } = useFormValues('KanbanForm');
66
+ const [selectedSchema] = useMemo(
67
+ () => db.schemaRegistry.query({ location: ['database', 'runtime'], typename }).runSync(),
68
+ [db, typename],
69
+ );
70
+ const singleSelectColumns = useMemo(() => {
71
+ const properties = JsonSchema.toJsonSchema(selectedSchema).properties;
72
+ if (!properties) {
73
+ return [];
70
74
  }
71
- return acc;
72
- }, []);
73
75
 
74
- return columns;
75
- }, [selectedSchema?.jsonSchema, staticSchema]);
76
+ const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {
77
+ if (typeof value === 'object' && value?.format === 'single-select') {
78
+ acc.push(key);
79
+ }
80
+ return acc;
81
+ }, []);
82
+
83
+ return columns;
84
+ }, [selectedSchema]);
76
85
 
77
- if (!typename) {
78
- return null;
79
- }
86
+ if (!typename) {
87
+ return null;
88
+ }
80
89
 
81
- return <SelectInput {...props} options={singleSelectColumns.map((column) => ({ value: column }))} />;
82
- },
83
- }),
84
- ]);
90
+ return <SelectField {...props} options={singleSelectColumns.map((column) => ({ value: column }))} />;
91
+ },
92
+ }),
93
+ ]),
94
+ ),
95
+ );
@@ -0,0 +1,34 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Capabilities, Capability, UndoMapping } from '@dxos/app-framework';
6
+
7
+ import { meta } from '#meta';
8
+ import { KanbanOperation } from '#types';
9
+
10
+ export default Capability.makeModule(() =>
11
+ Effect.succeed(
12
+ Capability.contributes(Capabilities.UndoMapping, [
13
+ UndoMapping.make({
14
+ operation: KanbanOperation.DeleteCardField,
15
+ inverse: KanbanOperation.RestoreCardField,
16
+ deriveContext: (input, output) => ({
17
+ view: input.view,
18
+ field: output.field,
19
+ props: output.props,
20
+ index: output.index,
21
+ }),
22
+ message: ['card-field-deleted.label', { ns: meta.id }],
23
+ }),
24
+ UndoMapping.make({
25
+ operation: KanbanOperation.DeleteCard,
26
+ inverse: KanbanOperation.RestoreCard,
27
+ deriveContext: (_input, output) => ({
28
+ card: output.card,
29
+ }),
30
+ message: ['card-deleted.label', { ns: meta.id }],
31
+ }),
32
+ ]),
33
+ ),
34
+ );
@@ -0,0 +1,146 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Atom, RegistryContext } from '@effect-atom/atom-react';
6
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
+ import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
8
+
9
+ import { Filter, JsonSchema, Obj, Query } from '@dxos/echo';
10
+ import { type View } from '@dxos/echo';
11
+ import { random } from '@dxos/random';
12
+ import { withMosaic } from '@dxos/react-ui-mosaic/testing';
13
+ import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
14
+ import { ProjectionModel, ViewModel, createEchoChangeCallback } from '@dxos/schema';
15
+ import { withRegistry } from '@dxos/storybook-utils';
16
+ import { Organization } from '@dxos/types';
17
+
18
+ import { createEchoChangeCallback as createKanbanChangeCallback } from '#hooks';
19
+ import { KanbanCardTileSimple } from '#testing';
20
+ import { translations } from '#translations';
21
+ import { Kanban } from '#types';
22
+
23
+ import { KanbanBoard } from './KanbanBoard';
24
+
25
+ random.seed(1);
26
+
27
+ const createOrg = () => ({
28
+ name: random.commerce.productName(),
29
+ description: random.lorem.sentence(),
30
+ image: random.image.url(),
31
+ website: random.internet.url(),
32
+ status: random.helpers.arrayElement(Organization.StatusOptions).id as Organization.Organization['status'],
33
+ });
34
+
35
+ /**
36
+ * In-memory Kanban board: View + ProjectionModel + Kanban + items, no plugin manager or Space.
37
+ * Similar to react-ui-kanban Kanban.stories.tsx.
38
+ */
39
+ const DefaultStory = () => {
40
+ const registry = useContext(RegistryContext);
41
+ const items = useMemo(() => Atom.make<Obj.Unknown[]>([]), []);
42
+ const [state, setState] = useState<{
43
+ view: View.View;
44
+ kanban: Kanban.Kanban;
45
+ projection: ProjectionModel;
46
+ change: ReturnType<typeof createKanbanChangeCallback>;
47
+ }>();
48
+
49
+ useEffect(() => {
50
+ const view = ViewModel.make({
51
+ query: Query.select(Filter.typename(Organization.Organization.typename)),
52
+ jsonSchema: JsonSchema.toJsonSchema(Organization.Organization),
53
+ pivotFieldName: 'status',
54
+ });
55
+ const kanban = Kanban.make({ view });
56
+ const change = createKanbanChangeCallback(kanban);
57
+ const projection = new ProjectionModel({
58
+ registry,
59
+ view,
60
+ baseSchema: JsonSchema.toJsonSchema(Organization.Organization),
61
+ change: createEchoChangeCallback(view),
62
+ });
63
+ projection.normalizeView();
64
+
65
+ const statuses = Organization.StatusOptions.map((o) => o.id);
66
+ const initialItems = Array.from({ length: 12 }, () =>
67
+ Obj.make(Organization.Organization, {
68
+ ...createOrg(),
69
+ status: random.helpers.arrayElement(statuses) as Organization.Organization['status'],
70
+ }),
71
+ );
72
+
73
+ setState({ view, kanban, projection, change });
74
+ registry.set(items, initialItems);
75
+ }, [registry, items]);
76
+
77
+ const columnFieldPath =
78
+ state?.projection.tryGetFieldProjection(state.projection.getFieldId('status') ?? '')?.props.property ?? 'status';
79
+
80
+ const handleCardAdd = useCallback(
81
+ (columnValue: string | undefined) => {
82
+ if (!state || !columnFieldPath || !registry) {
83
+ return undefined;
84
+ }
85
+ const card = Obj.make(Organization.Organization, {
86
+ ...createOrg(),
87
+ ...(columnFieldPath ? { [columnFieldPath]: columnValue } : {}),
88
+ });
89
+ const current = registry.get(items) ?? [];
90
+ registry.set(items, [...current, card]);
91
+ return card.id;
92
+ },
93
+ [state, columnFieldPath, registry, items],
94
+ );
95
+
96
+ const handleCardRemove = useCallback(
97
+ (card: Obj.Unknown) => {
98
+ if (!registry) {
99
+ return;
100
+ }
101
+ const current = registry.get(items) ?? [];
102
+ registry.set(
103
+ items,
104
+ current.filter((i) => i.id !== card.id),
105
+ );
106
+ },
107
+ [registry, items],
108
+ );
109
+
110
+ if (!state) {
111
+ return <Loading />;
112
+ }
113
+
114
+ return (
115
+ <KanbanBoard.Root
116
+ kanban={state.kanban}
117
+ projection={state.projection}
118
+ items={items}
119
+ itemTile={KanbanCardTileSimple}
120
+ change={state.change}
121
+ onCardAdd={handleCardAdd}
122
+ onCardRemove={handleCardRemove}
123
+ >
124
+ <KanbanBoard.Content />
125
+ </KanbanBoard.Root>
126
+ );
127
+ };
128
+
129
+ const meta = {
130
+ title: 'plugins/plugin-kanban/components/KanbanBoard',
131
+ component: DefaultStory,
132
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' }), withMosaic(), withRegistry],
133
+ parameters: {
134
+ layout: 'fullscreen',
135
+ translations,
136
+ },
137
+ } satisfies Meta<typeof DefaultStory>;
138
+
139
+ export default meta;
140
+
141
+ type Story = StoryObj<typeof meta>;
142
+
143
+ /**
144
+ * In-memory board with Echo-shaped objects. No plugin manager, client, or Space.
145
+ */
146
+ export const Default: Story = {};
@@ -0,0 +1,164 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Atom, RegistryContext } from '@effect-atom/atom-react';
6
+ import React, { type ComponentPropsWithoutRef, type PropsWithChildren, useCallback, useContext, useMemo } from 'react';
7
+
8
+ import { Obj } from '@dxos/echo';
9
+ import { useTranslation } from '@dxos/react-ui';
10
+ import { Board, useBoard } from '@dxos/react-ui-mosaic';
11
+ import type { ProjectionModel } from '@dxos/schema';
12
+ import { composable, composableProps } from '@dxos/ui-theme';
13
+
14
+ import { useKanbanBoardModel, useKanbanColumnEventHandler } from '#hooks';
15
+ import { meta } from '#meta';
16
+ import { type Kanban, UNCATEGORIZED_ATTRIBUTES, UNCATEGORIZED_VALUE } from '#types';
17
+
18
+ import {
19
+ KanbanBoardContext,
20
+ type KanbanBoardContextValue,
21
+ type KanbanCardProps,
22
+ type KanbanColumnProps,
23
+ useKanbanBoard,
24
+ } from './context';
25
+ import { KanbanCard } from './KanbanCard';
26
+ import { KanbanColumn } from './KanbanColumn';
27
+
28
+ // TODO(burdon): Rename Kanban.
29
+
30
+ //
31
+ // Root
32
+ //
33
+
34
+ const KANBAN_BOARD_ROOT = 'KanbanBoard.Root';
35
+
36
+ type KanbanBoardRootProps = PropsWithChildren<
37
+ {
38
+ kanban: Kanban.Kanban;
39
+ /** Required when providing context; Root derives columnFieldPath, pivotFieldId, getPivotAttributes from kanban + projection. */
40
+ projection: ProjectionModel;
41
+ /** Atom of items (e.g. from AtomQuery for DB, or Atom.make([]) for in-memory). */
42
+ items: Atom.Atom<Obj.Unknown[]>;
43
+ onCardAdd?: (columnValue: string | undefined) => string | undefined;
44
+ onCardRemove?: (card: Obj.Unknown) => void;
45
+ } & Pick<KanbanBoardContextValue, 'change' | 'itemTile'> &
46
+ ComponentPropsWithoutRef<'div'>
47
+ >;
48
+
49
+ export const KanbanBoardRoot = ({
50
+ children,
51
+ kanban,
52
+ projection,
53
+ items,
54
+ change,
55
+ itemTile = KanbanCard,
56
+ onCardAdd,
57
+ onCardRemove,
58
+ }: KanbanBoardRootProps) => {
59
+ const registry = useContext(RegistryContext);
60
+ const { t } = useTranslation(meta.id);
61
+ const model = useKanbanBoardModel(kanban, projection, items, registry);
62
+ const columns = model?.getColumns?.() ?? [];
63
+ const view = kanban?.spec.kind === 'view' ? kanban.spec.view.target : undefined;
64
+ const pivotFieldId = view?.projection?.pivotFieldId;
65
+ const columnFieldPath = useMemo(() => {
66
+ // Items-variant kanbans use the property name itself as the pivot field
67
+ // (no view/projection translation layer).
68
+ if (kanban?.spec.kind === 'items') {
69
+ return kanban.spec.pivotField;
70
+ }
71
+ if (pivotFieldId === undefined || !projection) {
72
+ return undefined;
73
+ }
74
+
75
+ return projection.tryGetFieldProjection(pivotFieldId)?.props.property;
76
+ }, [kanban?.spec, projection, pivotFieldId]);
77
+
78
+ const getPivotAttributes = useCallback<KanbanBoardContextValue['getPivotAttributes']>(
79
+ (columnValue) => {
80
+ if (columnValue === UNCATEGORIZED_VALUE) {
81
+ return UNCATEGORIZED_ATTRIBUTES;
82
+ }
83
+
84
+ const options = projection?.tryGetFieldProjection(pivotFieldId ?? '')?.props.options ?? [];
85
+ const option = options.find((option) => option.id === columnValue);
86
+ return option ?? ({ title: columnValue, color: 'neutral' } as const);
87
+ },
88
+ [projection, pivotFieldId],
89
+ );
90
+
91
+ if (columns.length === 0) {
92
+ return (
93
+ <div className='flex flex-1 items-center justify-center p-8 text-center text-description'>
94
+ {t('select-pivot.placeholder')}
95
+ </div>
96
+ );
97
+ }
98
+
99
+ return (
100
+ <KanbanBoardContext
101
+ kanbanId={Obj.getDXN(kanban).toString()}
102
+ projection={projection}
103
+ columnFieldPath={columnFieldPath}
104
+ pivotFieldId={pivotFieldId}
105
+ getPivotAttributes={getPivotAttributes}
106
+ itemTile={itemTile}
107
+ change={change}
108
+ onCardAdd={onCardAdd}
109
+ onCardRemove={onCardRemove}
110
+ >
111
+ <Board.Root model={model}>{children}</Board.Root>
112
+ </KanbanBoardContext>
113
+ );
114
+ };
115
+
116
+ KanbanBoardRoot.displayName = KANBAN_BOARD_ROOT;
117
+
118
+ //
119
+ // KanbanBoardContent
120
+ //
121
+
122
+ const KANBAN_BOARD_CONTENT = 'KanbanBoard.Content';
123
+
124
+ type KanbanBoardContentProps = {};
125
+
126
+ export const KanbanBoardContent = composable<HTMLDivElement, KanbanBoardContentProps>((props, forwardedRef) => {
127
+ const { model } = useBoard(KANBAN_BOARD_CONTENT);
128
+ const { kanbanId, projection, pivotFieldId, change } = useKanbanBoard(KANBAN_BOARD_CONTENT);
129
+
130
+ const columnEventHandler = useKanbanColumnEventHandler({
131
+ id: `${kanbanId}-columns`,
132
+ model,
133
+ projection: projection ?? undefined,
134
+ pivotFieldId: pivotFieldId ?? undefined,
135
+ change,
136
+ });
137
+
138
+ return (
139
+ <Board.Content
140
+ {...composableProps(props)}
141
+ ref={forwardedRef}
142
+ id={kanbanId}
143
+ eventHandler={columnEventHandler}
144
+ Tile={KanbanColumn}
145
+ />
146
+ );
147
+ });
148
+
149
+ KanbanBoardContent.displayName = KANBAN_BOARD_CONTENT;
150
+
151
+ //
152
+ // KanbanBoard
153
+ //
154
+
155
+ export const KanbanBoard = {
156
+ Root: KanbanBoardRoot,
157
+ Content: KanbanBoardContent,
158
+ Column: KanbanColumn,
159
+ Card: KanbanCard,
160
+ };
161
+
162
+ export { useKanbanBoard };
163
+
164
+ export type { KanbanBoardRootProps as KanbanBoardProps, KanbanCardProps, KanbanColumnProps };