@btst/stack 2.5.6 → 2.6.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 (216) hide show
  1. package/README.md +23 -0
  2. package/dist/client/components/index.d.cts +9 -9
  3. package/dist/client/components/index.d.mts +9 -9
  4. package/dist/client/components/index.d.ts +9 -9
  5. package/dist/components/auto-form/index.cjs +8 -0
  6. package/dist/components/auto-form/index.d.cts +26 -0
  7. package/dist/components/auto-form/index.d.mts +26 -0
  8. package/dist/components/auto-form/index.d.ts +26 -0
  9. package/dist/components/auto-form/index.mjs +1 -0
  10. package/dist/components/empty/index.cjs +12 -0
  11. package/dist/components/empty/index.d.cts +15 -0
  12. package/dist/components/empty/index.d.mts +15 -0
  13. package/dist/components/empty/index.d.ts +15 -0
  14. package/dist/components/empty/index.mjs +1 -0
  15. package/dist/components/form-builder/index.cjs +16 -0
  16. package/dist/components/form-builder/index.d.cts +385 -0
  17. package/dist/components/form-builder/index.d.mts +385 -0
  18. package/dist/components/form-builder/index.d.ts +385 -0
  19. package/dist/components/form-builder/index.mjs +4 -0
  20. package/dist/components/markdown/index.cjs +9 -0
  21. package/dist/components/markdown/index.d.cts +30 -0
  22. package/dist/components/markdown/index.d.mts +30 -0
  23. package/dist/components/markdown/index.d.ts +30 -0
  24. package/dist/components/markdown/index.mjs +2 -0
  25. package/dist/components/markdown/style.css +394 -0
  26. package/dist/components/minimal-tiptap/style.css +548 -0
  27. package/dist/components/multi-select/index.cjs +7 -0
  28. package/dist/components/multi-select/index.d.cts +78 -0
  29. package/dist/components/multi-select/index.d.mts +78 -0
  30. package/dist/components/multi-select/index.d.ts +78 -0
  31. package/dist/components/multi-select/index.mjs +1 -0
  32. package/dist/components/search-select/index.cjs +7 -0
  33. package/dist/components/search-select/index.d.cts +15 -0
  34. package/dist/components/search-select/index.d.mts +15 -0
  35. package/dist/components/search-select/index.d.ts +15 -0
  36. package/dist/components/search-select/index.mjs +1 -0
  37. package/dist/components/stepped-auto-form/index.cjs +7 -0
  38. package/dist/components/stepped-auto-form/index.d.cts +37 -0
  39. package/dist/components/stepped-auto-form/index.d.mts +37 -0
  40. package/dist/components/stepped-auto-form/index.d.ts +37 -0
  41. package/dist/components/stepped-auto-form/index.mjs +1 -0
  42. package/dist/components/ui-builder/style.css +552 -0
  43. package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.cjs +1 -1
  44. package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.mjs +1 -1
  45. package/dist/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.mjs +2 -2
  46. package/dist/node_modules/.pnpm/@floating-ui_core@1.7.3/node_modules/@floating-ui/core/dist/floating-ui.core.mjs +1 -1
  47. package/dist/node_modules/.pnpm/@floating-ui_dom@1.7.4/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs +3 -3
  48. package/dist/node_modules/.pnpm/@floating-ui_react-dom@2.1.6_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.mjs +1 -1
  49. package/dist/packages/stack/src/plugins/ai-chat/client/components/shared/default-error.cjs +1 -1
  50. package/dist/packages/stack/src/plugins/ai-chat/client/components/shared/default-error.mjs +1 -1
  51. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.cjs +44 -35
  52. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.mjs +44 -35
  53. package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.cjs +23 -0
  54. package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.mjs +21 -0
  55. package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor.cjs +11 -12
  56. package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor.mjs +11 -12
  57. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.cjs +2 -2
  58. package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.mjs +2 -2
  59. package/dist/packages/stack/src/plugins/blog/client/components/shared/default-error.cjs +1 -1
  60. package/dist/packages/stack/src/plugins/blog/client/components/shared/default-error.mjs +1 -1
  61. package/dist/packages/stack/src/plugins/blog/client/components/shared/search-input.cjs +0 -3
  62. package/dist/packages/stack/src/plugins/blog/client/components/shared/search-input.mjs +1 -1
  63. package/dist/packages/stack/src/plugins/blog/client/components/shared/search-modal.cjs +0 -3
  64. package/dist/packages/stack/src/plugins/blog/client/components/shared/search-modal.mjs +1 -1
  65. package/dist/packages/stack/src/plugins/blog/client/hooks/use-debounce.cjs +22 -0
  66. package/dist/packages/stack/src/plugins/blog/client/hooks/use-debounce.mjs +23 -2
  67. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +12 -6
  68. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +12 -6
  69. package/dist/packages/stack/src/plugins/cms/client/components/shared/default-error.cjs +1 -1
  70. package/dist/packages/stack/src/plugins/cms/client/components/shared/default-error.mjs +1 -1
  71. package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +38 -26
  72. package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +38 -26
  73. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/default-error.cjs +1 -1
  74. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/default-error.mjs +1 -1
  75. package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +32 -20
  76. package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +32 -20
  77. package/dist/packages/stack/src/plugins/kanban/client/components/shared/default-error.cjs +1 -1
  78. package/dist/packages/stack/src/plugins/kanban/client/components/shared/default-error.mjs +1 -1
  79. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +6 -3
  80. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +6 -3
  81. package/dist/packages/stack/src/plugins/ui-builder/client/components/page-renderer.cjs +1 -1
  82. package/dist/packages/stack/src/plugins/ui-builder/client/components/page-renderer.mjs +1 -1
  83. package/dist/packages/stack/src/plugins/ui-builder/client/components/shared/default-error.cjs +1 -1
  84. package/dist/packages/stack/src/plugins/ui-builder/client/components/shared/default-error.mjs +1 -1
  85. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.cjs +24 -15
  86. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.mjs +24 -15
  87. package/dist/packages/ui/src/components/auto-form/index.cjs +12 -2
  88. package/dist/packages/ui/src/components/auto-form/index.mjs +9 -2
  89. package/dist/packages/ui/src/components/auto-form/stepped-auto-form.cjs +2 -2
  90. package/dist/packages/ui/src/components/empty.cjs +28 -0
  91. package/dist/packages/ui/src/components/empty.mjs +27 -1
  92. package/dist/packages/ui/src/components/form-builder/components/index.mjs +2 -2
  93. package/dist/packages/ui/src/components/form-builder/edit-field-dialog.cjs +1 -1
  94. package/dist/packages/ui/src/components/form-builder/index.mjs +2 -2
  95. package/dist/packages/ui/src/components/form.mjs +1 -1
  96. package/dist/packages/ui/src/components/kanban.mjs +1 -1
  97. package/dist/packages/ui/src/components/multi-select.mjs +2 -2
  98. package/dist/packages/ui/src/components/search-select.cjs +13 -3
  99. package/dist/packages/ui/src/components/search-select.mjs +14 -4
  100. package/dist/packages/ui/src/components/ui-builder/internal/config-panel.cjs +1 -1
  101. package/dist/packages/ui/src/components/ui-builder/internal/props-panel.cjs +1 -1
  102. package/dist/plugins/ai-chat/client/index.d.cts +17 -4
  103. package/dist/plugins/ai-chat/client/index.d.mts +17 -4
  104. package/dist/plugins/ai-chat/client/index.d.ts +17 -4
  105. package/dist/plugins/blog/api/index.d.cts +2 -2
  106. package/dist/plugins/blog/api/index.d.mts +2 -2
  107. package/dist/plugins/blog/api/index.d.ts +2 -2
  108. package/dist/plugins/blog/client/hooks/index.cjs +3 -0
  109. package/dist/plugins/blog/client/hooks/index.d.cts +7 -226
  110. package/dist/plugins/blog/client/hooks/index.d.mts +7 -226
  111. package/dist/plugins/blog/client/hooks/index.d.ts +7 -226
  112. package/dist/plugins/blog/client/hooks/index.mjs +1 -0
  113. package/dist/plugins/blog/client/index.d.cts +46 -22
  114. package/dist/plugins/blog/client/index.d.mts +46 -22
  115. package/dist/plugins/blog/client/index.d.ts +46 -22
  116. package/dist/plugins/blog/query-keys.d.cts +2 -2
  117. package/dist/plugins/blog/query-keys.d.mts +2 -2
  118. package/dist/plugins/blog/query-keys.d.ts +2 -2
  119. package/dist/plugins/cms/client/index.d.cts +36 -15
  120. package/dist/plugins/cms/client/index.d.mts +36 -15
  121. package/dist/plugins/cms/client/index.d.ts +36 -15
  122. package/dist/plugins/form-builder/client/components/index.d.cts +2 -2
  123. package/dist/plugins/form-builder/client/components/index.d.mts +2 -2
  124. package/dist/plugins/form-builder/client/components/index.d.ts +2 -2
  125. package/dist/plugins/form-builder/client/index.d.cts +33 -15
  126. package/dist/plugins/form-builder/client/index.d.mts +33 -15
  127. package/dist/plugins/form-builder/client/index.d.ts +33 -15
  128. package/dist/plugins/kanban/api/index.d.cts +1 -1
  129. package/dist/plugins/kanban/api/index.d.mts +1 -1
  130. package/dist/plugins/kanban/api/index.d.ts +1 -1
  131. package/dist/plugins/kanban/client/components/index.d.cts +5 -5
  132. package/dist/plugins/kanban/client/components/index.d.mts +5 -5
  133. package/dist/plugins/kanban/client/components/index.d.ts +5 -5
  134. package/dist/plugins/kanban/client/index.d.cts +25 -10
  135. package/dist/plugins/kanban/client/index.d.mts +25 -10
  136. package/dist/plugins/kanban/client/index.d.ts +25 -10
  137. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  138. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  139. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  140. package/dist/plugins/route-docs/client/index.d.cts +4 -4
  141. package/dist/plugins/route-docs/client/index.d.mts +4 -4
  142. package/dist/plugins/route-docs/client/index.d.ts +4 -4
  143. package/dist/plugins/ui-builder/client/components/index.d.cts +3 -3
  144. package/dist/plugins/ui-builder/client/components/index.d.mts +3 -3
  145. package/dist/plugins/ui-builder/client/components/index.d.ts +3 -3
  146. package/dist/plugins/ui-builder/client/hooks/index.d.cts +3 -3
  147. package/dist/plugins/ui-builder/client/hooks/index.d.mts +3 -3
  148. package/dist/plugins/ui-builder/client/hooks/index.d.ts +3 -3
  149. package/dist/plugins/ui-builder/client/index.d.cts +32 -18
  150. package/dist/plugins/ui-builder/client/index.d.mts +32 -18
  151. package/dist/plugins/ui-builder/client/index.d.ts +32 -18
  152. package/dist/plugins/ui-builder/index.d.cts +3 -3
  153. package/dist/plugins/ui-builder/index.d.mts +3 -3
  154. package/dist/plugins/ui-builder/index.d.ts +3 -3
  155. package/dist/shared/{stack.B2DwzF3r.d.ts → stack.ASwEoINr.d.ts} +1 -1
  156. package/dist/shared/{stack.C5ZSOJGJ.d.cts → stack.B1srlBud.d.mts} +1 -1
  157. package/dist/shared/stack.B8vT-Yt4.d.mts +228 -0
  158. package/dist/shared/stack.BAT540yW.d.ts +228 -0
  159. package/dist/shared/{stack.D0QupDcQ.d.ts → stack.BK9Z2dcL.d.ts} +1 -1
  160. package/dist/shared/stack.BwA7trxA.d.cts +228 -0
  161. package/dist/shared/{stack.Cl7ok_cY.d.cts → stack.CFECM0ew.d.cts} +1 -1
  162. package/dist/shared/stack.CZMWR72v.d.cts +10 -0
  163. package/dist/shared/stack.CZMWR72v.d.mts +10 -0
  164. package/dist/shared/stack.CZMWR72v.d.ts +10 -0
  165. package/dist/shared/{stack.VMmQdbsJ.d.mts → stack.DVtk5CNw.d.mts} +1 -1
  166. package/dist/shared/{stack.B8_74ror.d.ts → stack.DXnclTG7.d.ts} +4 -4
  167. package/dist/shared/{stack.C21-LFX8.d.cts → stack.DaZM10cp.d.cts} +4 -4
  168. package/dist/shared/{stack.Dq4qVr1F.d.mts → stack.DmpPDPxA.d.cts} +1 -1
  169. package/dist/shared/{stack.CL4mKxe7.d.mts → stack.cfCkioTe.d.mts} +4 -4
  170. package/dist/shared/stack.fdi94T4S.d.cts +291 -0
  171. package/dist/shared/stack.fdi94T4S.d.mts +291 -0
  172. package/dist/shared/stack.fdi94T4S.d.ts +291 -0
  173. package/package.json +115 -4
  174. package/src/__tests__/page-component-overrides.test.tsx +147 -0
  175. package/src/components/auto-form/index.ts +12 -0
  176. package/src/components/empty/index.ts +8 -0
  177. package/src/components/form-builder/index.ts +23 -0
  178. package/src/components/kanban/index.ts +9 -0
  179. package/src/components/markdown/index.ts +5 -0
  180. package/src/components/markdown/style.css +3 -0
  181. package/src/components/minimal-tiptap/index.ts +5 -0
  182. package/src/components/minimal-tiptap/style.css +1 -0
  183. package/src/components/multi-select/index.ts +5 -0
  184. package/src/components/search-select/index.ts +1 -0
  185. package/src/components/stepped-auto-form/index.ts +5 -0
  186. package/src/components/ui-builder/index.ts +50 -0
  187. package/src/components/ui-builder/style.css +5 -0
  188. package/src/plugins/ai-chat/client/components/shared/default-error.tsx +1 -1
  189. package/src/plugins/ai-chat/client/plugin.tsx +60 -32
  190. package/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.tsx +29 -0
  191. package/src/plugins/blog/client/components/forms/markdown-editor.tsx +24 -21
  192. package/src/plugins/blog/client/components/forms/post-forms.tsx +2 -2
  193. package/src/plugins/blog/client/components/shared/default-error.tsx +2 -1
  194. package/src/plugins/blog/client/components/shared/posts-list.tsx +1 -1
  195. package/src/plugins/blog/client/components/shared/search-input.tsx +0 -2
  196. package/src/plugins/blog/client/components/shared/search-modal.tsx +0 -2
  197. package/src/plugins/blog/client/hooks/index.tsx +1 -0
  198. package/src/plugins/blog/client/plugin.tsx +41 -6
  199. package/src/plugins/cms/client/components/shared/default-error.tsx +3 -2
  200. package/src/plugins/cms/client/plugin.tsx +65 -32
  201. package/src/plugins/form-builder/client/components/shared/default-error.tsx +3 -2
  202. package/src/plugins/form-builder/client/plugin.tsx +56 -23
  203. package/src/plugins/kanban/client/components/shared/default-error.tsx +3 -2
  204. package/src/plugins/kanban/client/plugin.tsx +23 -3
  205. package/src/plugins/ui-builder/client/components/page-renderer.tsx +5 -3
  206. package/src/plugins/ui-builder/client/components/shared/default-error.tsx +3 -2
  207. package/src/plugins/ui-builder/client/plugin.tsx +41 -15
  208. package/dist/shared/stack.8nldKomx.d.cts +0 -114
  209. package/dist/shared/stack.8nldKomx.d.mts +0 -114
  210. package/dist/shared/stack.8nldKomx.d.ts +0 -114
  211. package/dist/shared/{stack.CxNeGV2z.d.mts → stack.B8D4r97Z.d.mts} +6 -6
  212. package/dist/shared/{stack.BWp0hcm9.d.cts → stack.BQmuNl5p.d.cts} +3 -3
  213. package/dist/shared/{stack.BWp0hcm9.d.mts → stack.BQmuNl5p.d.mts} +3 -3
  214. package/dist/shared/{stack.BWp0hcm9.d.ts → stack.BQmuNl5p.d.ts} +3 -3
  215. package/dist/shared/{stack.BFcg0tDz.d.ts → stack.DgKOwl20.d.ts} +6 -6
  216. package/dist/shared/{stack.DSxTDZBQ.d.cts → stack.uWSqCWAb.d.cts} +6 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btst/stack",
3
- "version": "2.5.6",
3
+ "version": "2.6.1",
4
4
  "description": "A composable, plugin-based library for building full-stack applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,11 +21,15 @@
21
21
  "access": "public"
22
22
  },
23
23
  "scripts": {
24
- "build": "unbuild --clean && node ./scripts/postbuild.cjs",
25
- "build:analyze": "ANALYZE=1 unbuild --clean && node ./scripts/postbuild.cjs",
24
+ "build": "NODE_OPTIONS='--max-old-space-size=8192' unbuild --clean && node ./scripts/postbuild.cjs",
25
+ "build:analyze": "NODE_OPTIONS='--max-old-space-size=8192' ANALYZE=1 unbuild --clean && node ./scripts/postbuild.cjs",
26
26
  "stub": "unbuild --stub",
27
27
  "test": "vitest",
28
- "typecheck": "tsc --project tsconfig.json"
28
+ "typecheck": "tsc --project tsconfig.json",
29
+ "knip": "knip --strict",
30
+ "build-registry": "tsx scripts/build-registry.ts",
31
+ "test-registry": "bash scripts/test-registry.sh",
32
+ "host-registry": "npx http-server registry -p 8766 -c-1"
29
33
  },
30
34
  "main": "./dist/index.cjs",
31
35
  "module": "./dist/index.mjs",
@@ -123,6 +127,16 @@
123
127
  "default": "./dist/plugins/blog/client/index.cjs"
124
128
  }
125
129
  },
130
+ "./plugins/blog/client/hooks": {
131
+ "import": {
132
+ "types": "./dist/plugins/blog/client/hooks/index.d.ts",
133
+ "default": "./dist/plugins/blog/client/hooks/index.mjs"
134
+ },
135
+ "require": {
136
+ "types": "./dist/plugins/blog/client/hooks/index.d.cts",
137
+ "default": "./dist/plugins/blog/client/hooks/index.cjs"
138
+ }
139
+ },
126
140
  "./plugins/ai-chat/api": {
127
141
  "import": {
128
142
  "types": "./dist/plugins/ai-chat/api/index.d.ts",
@@ -360,6 +374,77 @@
360
374
  }
361
375
  },
362
376
  "./plugins/route-docs/css": "./dist/plugins/route-docs/style.css",
377
+ "./components/markdown": {
378
+ "import": {
379
+ "types": "./dist/components/markdown/index.d.ts",
380
+ "default": "./dist/components/markdown/index.mjs"
381
+ },
382
+ "require": {
383
+ "types": "./dist/components/markdown/index.d.cts",
384
+ "default": "./dist/components/markdown/index.cjs"
385
+ }
386
+ },
387
+ "./components/markdown/css": "./dist/components/markdown/style.css",
388
+ "./components/auto-form": {
389
+ "import": {
390
+ "types": "./dist/components/auto-form/index.d.ts",
391
+ "default": "./dist/components/auto-form/index.mjs"
392
+ },
393
+ "require": {
394
+ "types": "./dist/components/auto-form/index.d.cts",
395
+ "default": "./dist/components/auto-form/index.cjs"
396
+ }
397
+ },
398
+ "./components/stepped-auto-form": {
399
+ "import": {
400
+ "types": "./dist/components/stepped-auto-form/index.d.ts",
401
+ "default": "./dist/components/stepped-auto-form/index.mjs"
402
+ },
403
+ "require": {
404
+ "types": "./dist/components/stepped-auto-form/index.d.cts",
405
+ "default": "./dist/components/stepped-auto-form/index.cjs"
406
+ }
407
+ },
408
+ "./components/form-builder": {
409
+ "import": {
410
+ "types": "./dist/components/form-builder/index.d.ts",
411
+ "default": "./dist/components/form-builder/index.mjs"
412
+ },
413
+ "require": {
414
+ "types": "./dist/components/form-builder/index.d.cts",
415
+ "default": "./dist/components/form-builder/index.cjs"
416
+ }
417
+ },
418
+ "./components/multi-select": {
419
+ "import": {
420
+ "types": "./dist/components/multi-select/index.d.ts",
421
+ "default": "./dist/components/multi-select/index.mjs"
422
+ },
423
+ "require": {
424
+ "types": "./dist/components/multi-select/index.d.cts",
425
+ "default": "./dist/components/multi-select/index.cjs"
426
+ }
427
+ },
428
+ "./components/search-select": {
429
+ "import": {
430
+ "types": "./dist/components/search-select/index.d.ts",
431
+ "default": "./dist/components/search-select/index.mjs"
432
+ },
433
+ "require": {
434
+ "types": "./dist/components/search-select/index.d.cts",
435
+ "default": "./dist/components/search-select/index.cjs"
436
+ }
437
+ },
438
+ "./components/empty": {
439
+ "import": {
440
+ "types": "./dist/components/empty/index.d.ts",
441
+ "default": "./dist/components/empty/index.mjs"
442
+ },
443
+ "require": {
444
+ "types": "./dist/components/empty/index.d.cts",
445
+ "default": "./dist/components/empty/index.cjs"
446
+ }
447
+ },
363
448
  "./dist/*": "./dist/*",
364
449
  "./ui/css": "./dist/ui/components.css",
365
450
  "./package.json": "./package.json"
@@ -390,6 +475,9 @@
390
475
  "plugins/blog/client": [
391
476
  "./dist/plugins/blog/client/index.d.ts"
392
477
  ],
478
+ "plugins/blog/client/hooks": [
479
+ "./dist/plugins/blog/client/hooks/index.d.ts"
480
+ ],
393
481
  "plugins/ai-chat/api": [
394
482
  "./dist/plugins/ai-chat/api/index.d.ts"
395
483
  ],
@@ -458,6 +546,27 @@
458
546
  ],
459
547
  "plugins/route-docs/client": [
460
548
  "./dist/plugins/route-docs/client/index.d.ts"
549
+ ],
550
+ "components/markdown": [
551
+ "./dist/components/markdown/index.d.ts"
552
+ ],
553
+ "components/auto-form": [
554
+ "./dist/components/auto-form/index.d.ts"
555
+ ],
556
+ "components/stepped-auto-form": [
557
+ "./dist/components/stepped-auto-form/index.d.ts"
558
+ ],
559
+ "components/form-builder": [
560
+ "./dist/components/form-builder/index.d.ts"
561
+ ],
562
+ "components/multi-select": [
563
+ "./dist/components/multi-select/index.d.ts"
564
+ ],
565
+ "components/search-select": [
566
+ "./dist/components/search-select/index.d.ts"
567
+ ],
568
+ "components/empty": [
569
+ "./dist/components/empty/index.d.ts"
461
570
  ]
462
571
  }
463
572
  },
@@ -505,6 +614,7 @@
505
614
  "zod": ">=4.2.0"
506
615
  },
507
616
  "devDependencies": {
617
+ "tsx": "catalog:",
508
618
  "@ai-sdk/react": "^2.0.94",
509
619
  "@btst/adapter-memory": "2.0.3",
510
620
  "@btst/yar": "1.2.0",
@@ -516,6 +626,7 @@
516
626
  "react": "^19.1.1",
517
627
  "react-dom": "^19.1.1",
518
628
  "react-error-boundary": "^4.1.2",
629
+ "knip": "^5.61.2",
519
630
  "rollup-plugin-preserve-directives": "0.4.0",
520
631
  "rollup-plugin-visualizer": "^5.12.0",
521
632
  "typescript": "catalog:",
@@ -0,0 +1,147 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { defineClientPlugin } from "../plugins/client";
3
+ import type { ComponentType } from "react";
4
+ import { createRoute } from "@btst/yar";
5
+
6
+ /**
7
+ * Default page components used by the mock plugin factory.
8
+ * These stand in for the real plugin page components (e.g. HomePageComponent).
9
+ */
10
+ const DefaultListComponent: ComponentType = () => <div>Default List</div>;
11
+ const DefaultDetailComponent: ComponentType<{ id: string }> = ({ id }) => (
12
+ <div>Default Detail {id}</div>
13
+ );
14
+
15
+ /**
16
+ * Lightweight mock plugin factory that mirrors the real plugin pattern:
17
+ * - Accepts a config with an optional `pageComponents` field
18
+ * - Falls back to built-in components when no override is provided
19
+ * - For param routes, extracts the override before the handler closure
20
+ */
21
+ function createTestPlugin(config: {
22
+ pageComponents?: {
23
+ list?: ComponentType;
24
+ detail?: ComponentType<{ id: string }>;
25
+ };
26
+ }) {
27
+ return defineClientPlugin({
28
+ name: "test",
29
+ routes: () => ({
30
+ list: createRoute("/items", () => {
31
+ const CustomList = config.pageComponents?.list;
32
+ return {
33
+ PageComponent: CustomList ?? DefaultListComponent,
34
+ };
35
+ }),
36
+ detail: createRoute("/items/:id", ({ params }) => {
37
+ const CustomDetail = config.pageComponents?.detail;
38
+ return {
39
+ PageComponent: CustomDetail
40
+ ? () => <CustomDetail id={params.id} />
41
+ : () => <DefaultDetailComponent id={params.id} />,
42
+ };
43
+ }),
44
+ }),
45
+ });
46
+ }
47
+
48
+ describe("pageComponents overrides", () => {
49
+ describe("default components used when no override provided", () => {
50
+ it("uses the default component for a no-param route", () => {
51
+ const plugin = createTestPlugin({});
52
+ const routes = plugin.routes();
53
+ const routeData = routes.list();
54
+
55
+ expect(routeData.PageComponent).toBe(DefaultListComponent);
56
+ });
57
+
58
+ it("uses the default component wrapper for a param route", () => {
59
+ const plugin = createTestPlugin({});
60
+ const routes = plugin.routes();
61
+ const routeData = routes.detail({ params: { id: "42" } });
62
+
63
+ // Should be an inline wrapper, not the custom component
64
+ expect(routeData.PageComponent).toBeDefined();
65
+ expect(typeof routeData.PageComponent).toBe("function");
66
+ // Verify it is NOT the custom component (no override was given)
67
+ const CustomDetail: ComponentType<{ id: string }> = () => (
68
+ <div>Custom</div>
69
+ );
70
+ expect(routeData.PageComponent).not.toBe(CustomDetail);
71
+ });
72
+ });
73
+
74
+ describe("custom component replaces default (no-param route)", () => {
75
+ it("uses the provided override instead of the default", () => {
76
+ const CustomList: ComponentType = () => <div>Custom List</div>;
77
+
78
+ const plugin = createTestPlugin({
79
+ pageComponents: { list: CustomList },
80
+ });
81
+ const routes = plugin.routes();
82
+ const routeData = routes.list();
83
+
84
+ expect(routeData.PageComponent).toBe(CustomList);
85
+ expect(routeData.PageComponent).not.toBe(DefaultListComponent);
86
+ });
87
+
88
+ it("leaves other routes using their defaults when only one is overridden", () => {
89
+ const CustomList: ComponentType = () => <div>Custom List</div>;
90
+
91
+ const plugin = createTestPlugin({
92
+ pageComponents: { list: CustomList },
93
+ });
94
+ const routes = plugin.routes();
95
+
96
+ // list uses custom
97
+ expect(routes.list().PageComponent).toBe(CustomList);
98
+
99
+ // detail still uses a wrapper (no override)
100
+ const detailData = routes.detail({ params: { id: "1" } });
101
+ expect(detailData.PageComponent).not.toBe(CustomList);
102
+ });
103
+ });
104
+
105
+ describe("custom component replaces default (param route)", () => {
106
+ it("uses the override wrapper for a param route", () => {
107
+ const CustomDetail: ComponentType<{ id: string }> = ({ id }) => (
108
+ <div>Custom Detail {id}</div>
109
+ );
110
+
111
+ const plugin = createTestPlugin({
112
+ pageComponents: { detail: CustomDetail },
113
+ });
114
+ const routes = plugin.routes();
115
+ const routeData = routes.detail({ params: { id: "42" } });
116
+
117
+ // Should be an inline wrapper (not the raw CustomDetail directly)
118
+ expect(routeData.PageComponent).toBeDefined();
119
+ expect(typeof routeData.PageComponent).toBe("function");
120
+ // Should NOT be the default
121
+ expect(routeData.PageComponent).not.toBe(DefaultDetailComponent);
122
+ });
123
+
124
+ it("produces a different PageComponent than when no override is given", () => {
125
+ const CustomDetail: ComponentType<{ id: string }> = ({ id }) => (
126
+ <div>Custom Detail {id}</div>
127
+ );
128
+
129
+ const defaultPlugin = createTestPlugin({});
130
+ const overridePlugin = createTestPlugin({
131
+ pageComponents: { detail: CustomDetail },
132
+ });
133
+
134
+ const defaultRouteData = defaultPlugin
135
+ .routes()
136
+ .detail({ params: { id: "1" } });
137
+ const overrideRouteData = overridePlugin
138
+ .routes()
139
+ .detail({ params: { id: "1" } });
140
+
141
+ // The wrapped component should be a different function reference
142
+ expect(overrideRouteData.PageComponent).not.toBe(
143
+ defaultRouteData.PageComponent,
144
+ );
145
+ });
146
+ });
147
+ });
@@ -0,0 +1,12 @@
1
+ export {
2
+ default as AutoForm,
3
+ AutoFormSubmit,
4
+ } from "@workspace/ui/components/auto-form";
5
+ export type {
6
+ FieldConfig,
7
+ FieldConfigItem,
8
+ Dependency,
9
+ DependencyType,
10
+ AutoFormInputComponentProps,
11
+ } from "@workspace/ui/components/auto-form/types";
12
+ export type { ZodObjectOrWrapped } from "@workspace/ui/components/auto-form/helpers";
@@ -0,0 +1,8 @@
1
+ export {
2
+ Empty,
3
+ EmptyHeader,
4
+ EmptyTitle,
5
+ EmptyDescription,
6
+ EmptyContent,
7
+ EmptyMedia,
8
+ } from "@workspace/ui/components/empty";
@@ -0,0 +1,23 @@
1
+ export {
2
+ FormBuilder,
3
+ defaultComponents,
4
+ objectFieldDefinition,
5
+ arrayFieldDefinition,
6
+ defineComponent,
7
+ baseMetaSchema,
8
+ baseMetaSchemaWithPlaceholder,
9
+ } from "@workspace/ui/components/form-builder";
10
+ export type {
11
+ FormBuilderComponentDefinition,
12
+ FormBuilderField,
13
+ FormBuilderFieldProps,
14
+ JSONSchema,
15
+ JSONSchemaProperty,
16
+ StringFieldProps,
17
+ } from "@workspace/ui/components/form-builder";
18
+ export type {
19
+ FormStep,
20
+ BackingType,
21
+ ComponentType,
22
+ TypedFieldProps,
23
+ } from "@workspace/ui/components/form-builder/types";
@@ -0,0 +1,9 @@
1
+ export {
2
+ Kanban,
3
+ KanbanBoard,
4
+ KanbanColumn,
5
+ KanbanColumnHandle,
6
+ KanbanItem,
7
+ KanbanItemHandle,
8
+ KanbanOverlay,
9
+ } from "@workspace/ui/components/kanban";
@@ -0,0 +1,5 @@
1
+ export { MarkdownContent } from "@workspace/ui/components/markdown-content";
2
+ export type { MarkdownContentProps } from "@workspace/ui/components/markdown-content";
3
+
4
+ export { MarkdownEditor } from "../../plugins/blog/client/components/forms/markdown-editor";
5
+ export type { MarkdownEditorProps } from "../../plugins/blog/client/components/forms/markdown-editor";
@@ -0,0 +1,3 @@
1
+ @import "@workspace/ui/markdown-content.css";
2
+ @import "@milkdown/crepe/theme/common/style.css";
3
+ @import "../../plugins/blog/client/components/forms/markdown-editor-styles.css";
@@ -0,0 +1,5 @@
1
+ export {
2
+ MinimalTiptapEditor,
3
+ MainMinimalTiptapEditor,
4
+ } from "@workspace/ui/components/minimal-tiptap";
5
+ export type { MinimalTiptapProps } from "@workspace/ui/components/minimal-tiptap";
@@ -0,0 +1 @@
1
+ @import "@workspace/ui/components/minimal-tiptap/styles.css";
@@ -0,0 +1,5 @@
1
+ export { default as MultipleSelector } from "@workspace/ui/components/multi-select";
2
+ export type {
3
+ Option,
4
+ MultipleSelectorRef,
5
+ } from "@workspace/ui/components/multi-select";
@@ -0,0 +1 @@
1
+ export { default as SearchSelect } from "@workspace/ui/components/search-select";
@@ -0,0 +1,5 @@
1
+ export { SteppedAutoForm } from "@workspace/ui/components/auto-form/stepped-auto-form";
2
+ export type {
3
+ SteppedAutoFormProps,
4
+ StepperComponentProps,
5
+ } from "@workspace/ui/components/auto-form/stepped-auto-form";
@@ -0,0 +1,50 @@
1
+ // Editor component
2
+ export {
3
+ default as UIBuilder,
4
+ PageConfigPanel,
5
+ defaultConfigTabsContent,
6
+ LoadingSkeleton,
7
+ getDefaultPanelConfigValues,
8
+ } from "@workspace/ui/components/ui-builder";
9
+ export type { TabsContentConfig } from "@workspace/ui/components/ui-builder";
10
+
11
+ // Page renderers
12
+ export { default as LayerRenderer } from "@workspace/ui/components/ui-builder/layer-renderer";
13
+ export { ServerLayerRenderer } from "@workspace/ui/components/ui-builder/server-layer-renderer";
14
+ export type { ServerLayerRendererProps } from "@workspace/ui/components/ui-builder/server-layer-renderer";
15
+
16
+ // Types
17
+ export type {
18
+ ComponentLayer,
19
+ ComponentRegistry,
20
+ Variable,
21
+ VariableReference,
22
+ FunctionRegistry,
23
+ BlockRegistry,
24
+ LayerChangeHandler,
25
+ VariableChangeHandler,
26
+ RegistryEntry,
27
+ PropValue,
28
+ BlockDefinition,
29
+ FunctionDefinition,
30
+ } from "@workspace/ui/components/ui-builder/types";
31
+ export {
32
+ isVariableReference,
33
+ createVariable,
34
+ } from "@workspace/ui/components/ui-builder/types";
35
+
36
+ // Registry utilities and field override helpers
37
+ export {
38
+ createComponentRegistry,
39
+ defaultComponentRegistry,
40
+ primitiveComponentDefinitions,
41
+ complexComponentDefinitions,
42
+ } from "../../plugins/ui-builder/client/registry";
43
+ export {
44
+ classNameFieldOverrides,
45
+ childrenFieldOverrides,
46
+ iconNameFieldOverrides,
47
+ commonFieldOverrides,
48
+ childrenAsTipTapFieldOverrides,
49
+ childrenAsTextareaFieldOverrides,
50
+ } from "@workspace/ui/lib/ui-builder/registry/form-field-overrides";
@@ -0,0 +1,5 @@
1
+ /* Import minimal-tiptap styles for rich text editor in form field overrides */
2
+ @import "@workspace/ui/components/minimal-tiptap/styles.css";
3
+
4
+ /* Load Tailwind Typography plugin for prose classes used by Markdown component */
5
+ @plugin "@tailwindcss/typography";
@@ -21,7 +21,7 @@ export function DefaultError({ error }: FallbackProps) {
21
21
  process.env.NODE_ENV === "production"
22
22
  ? (localization?.CHAT_GENERIC_ERROR_MESSAGE ??
23
23
  AI_CHAT_LOCALIZATION.CHAT_GENERIC_ERROR_MESSAGE)
24
- : (error?.message ??
24
+ : ((error instanceof Error ? error.message : undefined) ??
25
25
  localization?.CHAT_GENERIC_ERROR_MESSAGE ??
26
26
  AI_CHAT_LOCALIZATION.CHAT_GENERIC_ERROR_MESSAGE);
27
27
  return <ErrorPlaceholder title={title} message={message} />;
@@ -4,6 +4,7 @@ import {
4
4
  runClientHookWithShim,
5
5
  } from "@btst/stack/plugins/client";
6
6
  import { createRoute } from "@btst/yar";
7
+ import type { ComponentType } from "react";
7
8
  import type { QueryClient } from "@tanstack/react-query";
8
9
  import type { AiChatApiRouter } from "../api";
9
10
  import { createAiChatQueryKeys } from "../query-keys";
@@ -85,6 +86,18 @@ export interface AiChatClientConfig {
85
86
 
86
87
  /** Optional headers for SSR (e.g., forwarding cookies) */
87
88
  headers?: Headers;
89
+
90
+ /**
91
+ * Optional page component overrides.
92
+ * Replace any plugin page with a custom React component.
93
+ * The built-in component is used as the fallback when not provided.
94
+ */
95
+ pageComponents?: {
96
+ /** Replaces the chat home page */
97
+ chat?: ComponentType;
98
+ /** Replaces the conversation page (authenticated mode only) */
99
+ chatConversation?: ComponentType<{ conversationId: string }>;
100
+ };
88
101
  }
89
102
 
90
103
  /**
@@ -381,17 +394,22 @@ export const aiChatClientPlugin = (config: AiChatClientConfig) => {
381
394
 
382
395
  routes: () => ({
383
396
  // Chat home - simple chat interface without history
384
- chat: createRoute("/chat", () => ({
385
- PageComponent: () => (
386
- <ChatLayout
387
- apiBaseURL={config.apiBaseURL}
388
- apiBasePath={config.apiBasePath}
389
- showSidebar={false}
390
- />
391
- ),
392
- loader: createConversationsLoader(config),
393
- meta: createChatHomeMeta(config),
394
- })),
397
+ chat: createRoute("/chat", () => {
398
+ const CustomChat = config.pageComponents?.chat;
399
+ return {
400
+ PageComponent:
401
+ CustomChat ??
402
+ (() => (
403
+ <ChatLayout
404
+ apiBaseURL={config.apiBaseURL}
405
+ apiBasePath={config.apiBasePath}
406
+ showSidebar={false}
407
+ />
408
+ )),
409
+ loader: createConversationsLoader(config),
410
+ meta: createChatHomeMeta(config),
411
+ };
412
+ }),
395
413
  }),
396
414
 
397
415
  sitemap: async () => [],
@@ -404,29 +422,39 @@ export const aiChatClientPlugin = (config: AiChatClientConfig) => {
404
422
 
405
423
  routes: () => ({
406
424
  // Chat home - new conversation or list
407
- chat: createRoute("/chat", () => ({
408
- PageComponent: () => (
409
- <ChatLayout
410
- apiBaseURL={config.apiBaseURL}
411
- apiBasePath={config.apiBasePath}
412
- />
413
- ),
414
- loader: createConversationsLoader(config),
415
- meta: createChatHomeMeta(config),
416
- })),
425
+ chat: createRoute("/chat", () => {
426
+ const CustomChat = config.pageComponents?.chat;
427
+ return {
428
+ PageComponent:
429
+ CustomChat ??
430
+ (() => (
431
+ <ChatLayout
432
+ apiBaseURL={config.apiBaseURL}
433
+ apiBasePath={config.apiBasePath}
434
+ />
435
+ )),
436
+ loader: createConversationsLoader(config),
437
+ meta: createChatHomeMeta(config),
438
+ };
439
+ }),
417
440
 
418
441
  // Existing conversation
419
- chatConversation: createRoute("/chat/:id", ({ params }) => ({
420
- PageComponent: () => (
421
- <ChatLayout
422
- apiBaseURL={config.apiBaseURL}
423
- apiBasePath={config.apiBasePath}
424
- conversationId={params.id}
425
- />
426
- ),
427
- loader: createConversationLoader(params.id, config),
428
- meta: createConversationMeta(params.id, config),
429
- })),
442
+ chatConversation: createRoute("/chat/:id", ({ params }) => {
443
+ const CustomConversation = config.pageComponents?.chatConversation;
444
+ return {
445
+ PageComponent: CustomConversation
446
+ ? () => <CustomConversation conversationId={params.id} />
447
+ : () => (
448
+ <ChatLayout
449
+ apiBaseURL={config.apiBaseURL}
450
+ apiBasePath={config.apiBasePath}
451
+ conversationId={params.id}
452
+ />
453
+ ),
454
+ loader: createConversationLoader(params.id, config),
455
+ meta: createConversationMeta(params.id, config),
456
+ };
457
+ }),
430
458
  }),
431
459
 
432
460
  // Chat pages typically shouldn't be in sitemap, but we provide the option
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { usePluginOverrides } from "@btst/stack/context";
3
+ import type { BlogPluginOverrides } from "../../overrides";
4
+ import { BLOG_LOCALIZATION } from "../../localization";
5
+ import { MarkdownEditor, type MarkdownEditorProps } from "./markdown-editor";
6
+
7
+ type MarkdownEditorWithOverridesProps = Omit<
8
+ MarkdownEditorProps,
9
+ "uploadImage" | "placeholder"
10
+ >;
11
+
12
+ export function MarkdownEditorWithOverrides(
13
+ props: MarkdownEditorWithOverridesProps,
14
+ ) {
15
+ const { uploadImage, localization } = usePluginOverrides<
16
+ BlogPluginOverrides,
17
+ Partial<BlogPluginOverrides>
18
+ >("blog", {
19
+ localization: BLOG_LOCALIZATION,
20
+ });
21
+
22
+ return (
23
+ <MarkdownEditor
24
+ {...props}
25
+ uploadImage={uploadImage}
26
+ placeholder={localization?.BLOG_FORMS_EDITOR_PLACEHOLDER}
27
+ />
28
+ );
29
+ }