@btst/stack 1.11.0 → 1.12.0

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 (163) hide show
  1. 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
  2. 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
  3. 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.cjs +77 -0
  4. 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 +79 -3
  5. package/dist/node_modules/.pnpm/@radix-ui_react-avatar@1.1.11_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react_850cfbef1935a6e49a6ad6c93c7ca70d/node_modules/@radix-ui/react-avatar/dist/index.cjs +140 -0
  6. package/dist/node_modules/.pnpm/@radix-ui_react-avatar@1.1.11_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react_850cfbef1935a6e49a6ad6c93c7ca70d/node_modules/@radix-ui/react-avatar/dist/index.mjs +119 -0
  7. package/dist/node_modules/.pnpm/@radix-ui_react-context@1.1.3_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-context/dist/index.cjs +80 -0
  8. package/dist/node_modules/.pnpm/@radix-ui_react-context@1.1.3_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-context/dist/index.mjs +64 -0
  9. package/dist/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.cjs +18 -0
  10. package/dist/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.2.6_react@19.2.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.mjs +16 -0
  11. package/dist/packages/better-stack/src/plugins/kanban/api/plugin.cjs +846 -0
  12. package/dist/packages/better-stack/src/plugins/kanban/api/plugin.mjs +844 -0
  13. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/board-form.cjs +85 -0
  14. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/board-form.mjs +83 -0
  15. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/column-form.cjs +72 -0
  16. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/column-form.mjs +70 -0
  17. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/task-form.cjs +200 -0
  18. package/dist/packages/better-stack/src/plugins/kanban/client/components/forms/task-form.mjs +198 -0
  19. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/board-skeleton.cjs +47 -0
  20. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/board-skeleton.mjs +45 -0
  21. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/boards-list-skeleton.cjs +30 -0
  22. package/dist/packages/better-stack/src/plugins/kanban/client/components/loading/boards-list-skeleton.mjs +28 -0
  23. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/404-page.cjs +27 -0
  24. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/404-page.mjs +25 -0
  25. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.cjs +31 -0
  26. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.internal.cjs +458 -0
  27. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.internal.mjs +456 -0
  28. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/board-page.mjs +29 -0
  29. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.cjs +30 -0
  30. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.internal.cjs +72 -0
  31. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.internal.mjs +70 -0
  32. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/boards-list-page.mjs +28 -0
  33. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.cjs +30 -0
  34. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.internal.cjs +51 -0
  35. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.internal.mjs +49 -0
  36. package/dist/packages/better-stack/src/plugins/kanban/client/components/pages/new-board-page.mjs +28 -0
  37. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/column-content.cjs +76 -0
  38. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/column-content.mjs +74 -0
  39. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/default-error.cjs +27 -0
  40. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/default-error.mjs +25 -0
  41. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/empty-state.cjs +32 -0
  42. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/empty-state.mjs +30 -0
  43. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/kanban-board.cjs +78 -0
  44. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/kanban-board.mjs +76 -0
  45. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/page-wrapper.cjs +15 -0
  46. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/page-wrapper.mjs +13 -0
  47. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/task-card.cjs +68 -0
  48. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/task-card.mjs +66 -0
  49. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/user-avatar.cjs +32 -0
  50. package/dist/packages/better-stack/src/plugins/kanban/client/components/shared/user-avatar.mjs +30 -0
  51. package/dist/packages/better-stack/src/plugins/kanban/client/hooks/kanban-hooks.cjs +391 -0
  52. package/dist/packages/better-stack/src/plugins/kanban/client/hooks/kanban-hooks.mjs +381 -0
  53. package/dist/packages/better-stack/src/plugins/kanban/client/plugin.cjs +290 -0
  54. package/dist/packages/better-stack/src/plugins/kanban/client/plugin.mjs +288 -0
  55. package/dist/packages/better-stack/src/plugins/kanban/db.cjs +125 -0
  56. package/dist/packages/better-stack/src/plugins/kanban/db.mjs +123 -0
  57. package/dist/packages/better-stack/src/plugins/kanban/schemas.cjs +117 -0
  58. package/dist/packages/better-stack/src/plugins/kanban/schemas.mjs +102 -0
  59. package/dist/packages/better-stack/src/plugins/kanban/utils.cjs +49 -0
  60. package/dist/packages/better-stack/src/plugins/kanban/utils.mjs +45 -0
  61. package/dist/packages/ui/src/components/avatar.cjs +58 -0
  62. package/dist/packages/ui/src/components/avatar.mjs +54 -0
  63. package/dist/packages/ui/src/components/command.cjs +3 -3
  64. package/dist/packages/ui/src/components/command.mjs +3 -3
  65. package/dist/packages/ui/src/components/form-builder/index.mjs +2 -2
  66. package/dist/packages/ui/src/components/kanban.cjs +835 -0
  67. package/dist/packages/ui/src/components/kanban.mjs +805 -0
  68. package/dist/packages/ui/src/components/popover.cjs +8 -3
  69. package/dist/packages/ui/src/components/popover.mjs +9 -4
  70. package/dist/packages/ui/src/components/search-select.cjs +75 -0
  71. package/dist/packages/ui/src/components/search-select.mjs +73 -0
  72. package/dist/packages/ui/src/lib/compose-refs.cjs +56 -0
  73. package/dist/packages/ui/src/lib/compose-refs.mjs +39 -0
  74. package/dist/plugins/blog/api/index.d.cts +1 -1
  75. package/dist/plugins/blog/api/index.d.mts +1 -1
  76. package/dist/plugins/blog/api/index.d.ts +1 -1
  77. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  78. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  79. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  80. package/dist/plugins/blog/client/index.d.cts +1 -1
  81. package/dist/plugins/blog/client/index.d.mts +1 -1
  82. package/dist/plugins/blog/client/index.d.ts +1 -1
  83. package/dist/plugins/blog/query-keys.d.cts +2 -2
  84. package/dist/plugins/blog/query-keys.d.mts +2 -2
  85. package/dist/plugins/blog/query-keys.d.ts +2 -2
  86. package/dist/plugins/kanban/api/index.cjs +7 -0
  87. package/dist/plugins/kanban/api/index.d.cts +403 -0
  88. package/dist/plugins/kanban/api/index.d.mts +403 -0
  89. package/dist/plugins/kanban/api/index.d.ts +403 -0
  90. package/dist/plugins/kanban/api/index.mjs +1 -0
  91. package/dist/plugins/kanban/client/components/index.cjs +35 -0
  92. package/dist/plugins/kanban/client/components/index.d.cts +102 -0
  93. package/dist/plugins/kanban/client/components/index.d.mts +102 -0
  94. package/dist/plugins/kanban/client/components/index.d.ts +102 -0
  95. package/dist/plugins/kanban/client/components/index.mjs +15 -0
  96. package/dist/plugins/kanban/client/hooks/index.cjs +15 -0
  97. package/dist/plugins/kanban/client/hooks/index.d.cts +143 -0
  98. package/dist/plugins/kanban/client/hooks/index.d.mts +143 -0
  99. package/dist/plugins/kanban/client/hooks/index.d.ts +143 -0
  100. package/dist/plugins/kanban/client/hooks/index.mjs +1 -0
  101. package/dist/plugins/kanban/client/index.cjs +7 -0
  102. package/dist/plugins/kanban/client/index.d.cts +196 -0
  103. package/dist/plugins/kanban/client/index.d.mts +196 -0
  104. package/dist/plugins/kanban/client/index.d.ts +196 -0
  105. package/dist/plugins/kanban/client/index.mjs +1 -0
  106. package/dist/plugins/kanban/client.css +68 -0
  107. package/dist/plugins/kanban/query-keys.cjs +105 -0
  108. package/dist/plugins/kanban/query-keys.d.cts +59 -0
  109. package/dist/plugins/kanban/query-keys.d.mts +59 -0
  110. package/dist/plugins/kanban/query-keys.d.ts +59 -0
  111. package/dist/plugins/kanban/query-keys.mjs +103 -0
  112. package/dist/plugins/kanban/style.css +7 -0
  113. package/dist/plugins/ui-builder/style.css +6 -0
  114. package/dist/shared/stack.DKDMI-QO.d.cts +70 -0
  115. package/dist/shared/stack.DKDMI-QO.d.mts +70 -0
  116. package/dist/shared/stack.DKDMI-QO.d.ts +70 -0
  117. package/dist/shared/stack.FeaWkglm.d.cts +190 -0
  118. package/dist/shared/stack.FeaWkglm.d.mts +190 -0
  119. package/dist/shared/stack.FeaWkglm.d.ts +190 -0
  120. package/package.json +56 -2
  121. package/src/plugins/kanban/api/index.ts +6 -0
  122. package/src/plugins/kanban/api/plugin.ts +1245 -0
  123. package/src/plugins/kanban/client/components/forms/board-form.tsx +108 -0
  124. package/src/plugins/kanban/client/components/forms/column-form.tsx +97 -0
  125. package/src/plugins/kanban/client/components/forms/task-form.tsx +274 -0
  126. package/src/plugins/kanban/client/components/index.tsx +21 -0
  127. package/src/plugins/kanban/client/components/loading/board-skeleton.tsx +49 -0
  128. package/src/plugins/kanban/client/components/loading/boards-list-skeleton.tsx +34 -0
  129. package/src/plugins/kanban/client/components/loading/index.tsx +2 -0
  130. package/src/plugins/kanban/client/components/pages/404-page.tsx +28 -0
  131. package/src/plugins/kanban/client/components/pages/board-page.internal.tsx +575 -0
  132. package/src/plugins/kanban/client/components/pages/board-page.tsx +31 -0
  133. package/src/plugins/kanban/client/components/pages/boards-list-page.internal.tsx +101 -0
  134. package/src/plugins/kanban/client/components/pages/boards-list-page.tsx +26 -0
  135. package/src/plugins/kanban/client/components/pages/new-board-page.internal.tsx +65 -0
  136. package/src/plugins/kanban/client/components/pages/new-board-page.tsx +26 -0
  137. package/src/plugins/kanban/client/components/shared/column-content.tsx +108 -0
  138. package/src/plugins/kanban/client/components/shared/default-error.tsx +32 -0
  139. package/src/plugins/kanban/client/components/shared/empty-state.tsx +37 -0
  140. package/src/plugins/kanban/client/components/shared/kanban-board.tsx +87 -0
  141. package/src/plugins/kanban/client/components/shared/page-wrapper.tsx +20 -0
  142. package/src/plugins/kanban/client/components/shared/task-card.tsx +79 -0
  143. package/src/plugins/kanban/client/components/shared/user-avatar.tsx +63 -0
  144. package/src/plugins/kanban/client/hooks/index.tsx +11 -0
  145. package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +560 -0
  146. package/src/plugins/kanban/client/index.ts +8 -0
  147. package/src/plugins/kanban/client/localization/index.ts +28 -0
  148. package/src/plugins/kanban/client/localization/kanban-common.ts +69 -0
  149. package/src/plugins/kanban/client/localization/kanban-forms.ts +70 -0
  150. package/src/plugins/kanban/client/localization/kanban-list.ts +36 -0
  151. package/src/plugins/kanban/client/overrides.ts +145 -0
  152. package/src/plugins/kanban/client/plugin.tsx +463 -0
  153. package/src/plugins/kanban/client.css +68 -0
  154. package/src/plugins/kanban/db.ts +125 -0
  155. package/src/plugins/kanban/query-keys.ts +154 -0
  156. package/src/plugins/kanban/schemas.ts +143 -0
  157. package/src/plugins/kanban/style.css +7 -0
  158. package/src/plugins/kanban/types.ts +106 -0
  159. package/src/plugins/kanban/utils.ts +107 -0
  160. package/src/plugins/ui-builder/style.css +6 -0
  161. package/dist/shared/{stack.DLhzx1-D.d.cts → stack.CcI4sYJP.d.cts} +1 -1
  162. package/dist/shared/{stack.DLhzx1-D.d.mts → stack.CcI4sYJP.d.mts} +1 -1
  163. package/dist/shared/{stack.DLhzx1-D.d.ts → stack.CcI4sYJP.d.ts} +1 -1
@@ -0,0 +1,190 @@
1
+ import { ComponentType } from 'react';
2
+
3
+ interface KanbanCommonLocalization {
4
+ backToBoards: string;
5
+ actions: string;
6
+ create: string;
7
+ edit: string;
8
+ delete: string;
9
+ cancel: string;
10
+ save: string;
11
+ loading: string;
12
+ saving: string;
13
+ deleting: string;
14
+ board: string;
15
+ boards: string;
16
+ column: string;
17
+ columns: string;
18
+ task: string;
19
+ tasks: string;
20
+ priorityLow: string;
21
+ priorityMedium: string;
22
+ priorityHigh: string;
23
+ priorityUrgent: string;
24
+ noBoards: string;
25
+ noColumns: string;
26
+ noTasks: string;
27
+ errorGeneric: string;
28
+ errorNotFound: string;
29
+ }
30
+
31
+ interface KanbanFormsLocalization {
32
+ boardName: string;
33
+ boardNamePlaceholder: string;
34
+ boardDescription: string;
35
+ boardDescriptionPlaceholder: string;
36
+ createBoard: string;
37
+ updateBoard: string;
38
+ deleteBoard: string;
39
+ deleteBoardConfirm: string;
40
+ columnTitle: string;
41
+ columnTitlePlaceholder: string;
42
+ createColumn: string;
43
+ updateColumn: string;
44
+ deleteColumn: string;
45
+ deleteColumnConfirm: string;
46
+ taskTitle: string;
47
+ taskTitlePlaceholder: string;
48
+ taskDescription: string;
49
+ taskDescriptionPlaceholder: string;
50
+ taskPriority: string;
51
+ taskColumn: string;
52
+ taskAssignee: string;
53
+ createTask: string;
54
+ updateTask: string;
55
+ deleteTask: string;
56
+ deleteTaskConfirm: string;
57
+ nameRequired: string;
58
+ titleRequired: string;
59
+ }
60
+
61
+ interface KanbanListLocalization {
62
+ kanbanBoards: string;
63
+ manageProjects: string;
64
+ createNewBoard: string;
65
+ boardDetails: string;
66
+ newBoard: string;
67
+ addColumn: string;
68
+ addTask: string;
69
+ columnsCount: string;
70
+ noBoardsDescription: string;
71
+ noColumnsDescription: string;
72
+ noTasksDescription: string;
73
+ }
74
+
75
+ type KanbanLocalization = Partial<KanbanCommonLocalization & KanbanFormsLocalization & KanbanListLocalization>;
76
+
77
+ /**
78
+ * User information for assignee display/selection
79
+ * Framework-agnostic - consumers map their auth system to this shape
80
+ */
81
+ interface KanbanUser {
82
+ id: string;
83
+ name: string;
84
+ avatarUrl?: string;
85
+ email?: string;
86
+ }
87
+ /**
88
+ * Context passed to lifecycle hooks
89
+ */
90
+ interface RouteContext {
91
+ /** Current route path */
92
+ path: string;
93
+ /** Route parameters (e.g., { boardId: "abc123" }) */
94
+ params?: Record<string, string>;
95
+ /** Whether rendering on server (true) or client (false) */
96
+ isSSR: boolean;
97
+ /** Additional context properties */
98
+ [key: string]: unknown;
99
+ }
100
+ /**
101
+ * Overridable components and functions for the Kanban plugin
102
+ *
103
+ * External consumers can provide their own implementations of these
104
+ * to customize the behavior for their framework (Next.js, React Router, etc.)
105
+ */
106
+ interface KanbanPluginOverrides {
107
+ /**
108
+ * Link component for navigation
109
+ */
110
+ Link?: ComponentType<React.ComponentProps<"a"> & Record<string, unknown>>;
111
+ /**
112
+ * Navigation function for programmatic navigation
113
+ */
114
+ navigate: (path: string) => void | Promise<void>;
115
+ /**
116
+ * Refresh function to invalidate server-side cache (e.g., Next.js router.refresh())
117
+ */
118
+ refresh?: () => void | Promise<void>;
119
+ /**
120
+ * Image component for displaying images
121
+ */
122
+ Image?: ComponentType<React.ImgHTMLAttributes<HTMLImageElement> & Record<string, unknown>>;
123
+ /**
124
+ * Localization object for the kanban plugin
125
+ */
126
+ localization?: KanbanLocalization;
127
+ /**
128
+ * API base URL
129
+ */
130
+ apiBaseURL: string;
131
+ /**
132
+ * API base path
133
+ */
134
+ apiBasePath: string;
135
+ /**
136
+ * Whether to show the attribution
137
+ */
138
+ showAttribution?: boolean;
139
+ /**
140
+ * Optional headers to pass with API requests (e.g., for SSR auth)
141
+ */
142
+ headers?: HeadersInit;
143
+ /**
144
+ * Resolve user info from an assigneeId
145
+ * Called when rendering task cards/forms that have an assignee
146
+ * Return null for unknown users (will show fallback UI)
147
+ */
148
+ resolveUser: (userId: string) => Promise<KanbanUser | null> | KanbanUser | null;
149
+ /**
150
+ * Search/list users available for assignment
151
+ * Called when user opens the assignee picker
152
+ * @param query - Search query (empty string for initial load)
153
+ * @param boardId - Optional board context for scoped user lists
154
+ */
155
+ searchUsers: (query: string, boardId?: string) => Promise<KanbanUser[]> | KanbanUser[];
156
+ /**
157
+ * Called when a route is rendered
158
+ * @param routeName - Name of the route (e.g., 'boards', 'board', 'newBoard')
159
+ * @param context - Route context with path, params, etc.
160
+ */
161
+ onRouteRender?: (routeName: string, context: RouteContext) => void | Promise<void>;
162
+ /**
163
+ * Called when a route encounters an error
164
+ * @param routeName - Name of the route
165
+ * @param error - The error that occurred
166
+ * @param context - Route context
167
+ */
168
+ onRouteError?: (routeName: string, error: Error, context: RouteContext) => void | Promise<void>;
169
+ /**
170
+ * Called before the boards list page is rendered
171
+ * Return false to prevent rendering (e.g., for authorization)
172
+ * @param context - Route context
173
+ */
174
+ onBeforeBoardsPageRendered?: (context: RouteContext) => boolean;
175
+ /**
176
+ * Called before a single board page is rendered
177
+ * Return false to prevent rendering (e.g., for authorization)
178
+ * @param boardId - The board ID
179
+ * @param context - Route context
180
+ */
181
+ onBeforeBoardPageRendered?: (boardId: string, context: RouteContext) => boolean;
182
+ /**
183
+ * Called before the new board page is rendered
184
+ * Return false to prevent rendering (e.g., for authorization)
185
+ * @param context - Route context
186
+ */
187
+ onBeforeNewBoardPageRendered?: (context: RouteContext) => boolean;
188
+ }
189
+
190
+ export type { KanbanPluginOverrides as K, KanbanUser as a };
@@ -0,0 +1,190 @@
1
+ import { ComponentType } from 'react';
2
+
3
+ interface KanbanCommonLocalization {
4
+ backToBoards: string;
5
+ actions: string;
6
+ create: string;
7
+ edit: string;
8
+ delete: string;
9
+ cancel: string;
10
+ save: string;
11
+ loading: string;
12
+ saving: string;
13
+ deleting: string;
14
+ board: string;
15
+ boards: string;
16
+ column: string;
17
+ columns: string;
18
+ task: string;
19
+ tasks: string;
20
+ priorityLow: string;
21
+ priorityMedium: string;
22
+ priorityHigh: string;
23
+ priorityUrgent: string;
24
+ noBoards: string;
25
+ noColumns: string;
26
+ noTasks: string;
27
+ errorGeneric: string;
28
+ errorNotFound: string;
29
+ }
30
+
31
+ interface KanbanFormsLocalization {
32
+ boardName: string;
33
+ boardNamePlaceholder: string;
34
+ boardDescription: string;
35
+ boardDescriptionPlaceholder: string;
36
+ createBoard: string;
37
+ updateBoard: string;
38
+ deleteBoard: string;
39
+ deleteBoardConfirm: string;
40
+ columnTitle: string;
41
+ columnTitlePlaceholder: string;
42
+ createColumn: string;
43
+ updateColumn: string;
44
+ deleteColumn: string;
45
+ deleteColumnConfirm: string;
46
+ taskTitle: string;
47
+ taskTitlePlaceholder: string;
48
+ taskDescription: string;
49
+ taskDescriptionPlaceholder: string;
50
+ taskPriority: string;
51
+ taskColumn: string;
52
+ taskAssignee: string;
53
+ createTask: string;
54
+ updateTask: string;
55
+ deleteTask: string;
56
+ deleteTaskConfirm: string;
57
+ nameRequired: string;
58
+ titleRequired: string;
59
+ }
60
+
61
+ interface KanbanListLocalization {
62
+ kanbanBoards: string;
63
+ manageProjects: string;
64
+ createNewBoard: string;
65
+ boardDetails: string;
66
+ newBoard: string;
67
+ addColumn: string;
68
+ addTask: string;
69
+ columnsCount: string;
70
+ noBoardsDescription: string;
71
+ noColumnsDescription: string;
72
+ noTasksDescription: string;
73
+ }
74
+
75
+ type KanbanLocalization = Partial<KanbanCommonLocalization & KanbanFormsLocalization & KanbanListLocalization>;
76
+
77
+ /**
78
+ * User information for assignee display/selection
79
+ * Framework-agnostic - consumers map their auth system to this shape
80
+ */
81
+ interface KanbanUser {
82
+ id: string;
83
+ name: string;
84
+ avatarUrl?: string;
85
+ email?: string;
86
+ }
87
+ /**
88
+ * Context passed to lifecycle hooks
89
+ */
90
+ interface RouteContext {
91
+ /** Current route path */
92
+ path: string;
93
+ /** Route parameters (e.g., { boardId: "abc123" }) */
94
+ params?: Record<string, string>;
95
+ /** Whether rendering on server (true) or client (false) */
96
+ isSSR: boolean;
97
+ /** Additional context properties */
98
+ [key: string]: unknown;
99
+ }
100
+ /**
101
+ * Overridable components and functions for the Kanban plugin
102
+ *
103
+ * External consumers can provide their own implementations of these
104
+ * to customize the behavior for their framework (Next.js, React Router, etc.)
105
+ */
106
+ interface KanbanPluginOverrides {
107
+ /**
108
+ * Link component for navigation
109
+ */
110
+ Link?: ComponentType<React.ComponentProps<"a"> & Record<string, unknown>>;
111
+ /**
112
+ * Navigation function for programmatic navigation
113
+ */
114
+ navigate: (path: string) => void | Promise<void>;
115
+ /**
116
+ * Refresh function to invalidate server-side cache (e.g., Next.js router.refresh())
117
+ */
118
+ refresh?: () => void | Promise<void>;
119
+ /**
120
+ * Image component for displaying images
121
+ */
122
+ Image?: ComponentType<React.ImgHTMLAttributes<HTMLImageElement> & Record<string, unknown>>;
123
+ /**
124
+ * Localization object for the kanban plugin
125
+ */
126
+ localization?: KanbanLocalization;
127
+ /**
128
+ * API base URL
129
+ */
130
+ apiBaseURL: string;
131
+ /**
132
+ * API base path
133
+ */
134
+ apiBasePath: string;
135
+ /**
136
+ * Whether to show the attribution
137
+ */
138
+ showAttribution?: boolean;
139
+ /**
140
+ * Optional headers to pass with API requests (e.g., for SSR auth)
141
+ */
142
+ headers?: HeadersInit;
143
+ /**
144
+ * Resolve user info from an assigneeId
145
+ * Called when rendering task cards/forms that have an assignee
146
+ * Return null for unknown users (will show fallback UI)
147
+ */
148
+ resolveUser: (userId: string) => Promise<KanbanUser | null> | KanbanUser | null;
149
+ /**
150
+ * Search/list users available for assignment
151
+ * Called when user opens the assignee picker
152
+ * @param query - Search query (empty string for initial load)
153
+ * @param boardId - Optional board context for scoped user lists
154
+ */
155
+ searchUsers: (query: string, boardId?: string) => Promise<KanbanUser[]> | KanbanUser[];
156
+ /**
157
+ * Called when a route is rendered
158
+ * @param routeName - Name of the route (e.g., 'boards', 'board', 'newBoard')
159
+ * @param context - Route context with path, params, etc.
160
+ */
161
+ onRouteRender?: (routeName: string, context: RouteContext) => void | Promise<void>;
162
+ /**
163
+ * Called when a route encounters an error
164
+ * @param routeName - Name of the route
165
+ * @param error - The error that occurred
166
+ * @param context - Route context
167
+ */
168
+ onRouteError?: (routeName: string, error: Error, context: RouteContext) => void | Promise<void>;
169
+ /**
170
+ * Called before the boards list page is rendered
171
+ * Return false to prevent rendering (e.g., for authorization)
172
+ * @param context - Route context
173
+ */
174
+ onBeforeBoardsPageRendered?: (context: RouteContext) => boolean;
175
+ /**
176
+ * Called before a single board page is rendered
177
+ * Return false to prevent rendering (e.g., for authorization)
178
+ * @param boardId - The board ID
179
+ * @param context - Route context
180
+ */
181
+ onBeforeBoardPageRendered?: (boardId: string, context: RouteContext) => boolean;
182
+ /**
183
+ * Called before the new board page is rendered
184
+ * Return false to prevent rendering (e.g., for authorization)
185
+ * @param context - Route context
186
+ */
187
+ onBeforeNewBoardPageRendered?: (context: RouteContext) => boolean;
188
+ }
189
+
190
+ export type { KanbanPluginOverrides as K, KanbanUser as a };
@@ -0,0 +1,190 @@
1
+ import { ComponentType } from 'react';
2
+
3
+ interface KanbanCommonLocalization {
4
+ backToBoards: string;
5
+ actions: string;
6
+ create: string;
7
+ edit: string;
8
+ delete: string;
9
+ cancel: string;
10
+ save: string;
11
+ loading: string;
12
+ saving: string;
13
+ deleting: string;
14
+ board: string;
15
+ boards: string;
16
+ column: string;
17
+ columns: string;
18
+ task: string;
19
+ tasks: string;
20
+ priorityLow: string;
21
+ priorityMedium: string;
22
+ priorityHigh: string;
23
+ priorityUrgent: string;
24
+ noBoards: string;
25
+ noColumns: string;
26
+ noTasks: string;
27
+ errorGeneric: string;
28
+ errorNotFound: string;
29
+ }
30
+
31
+ interface KanbanFormsLocalization {
32
+ boardName: string;
33
+ boardNamePlaceholder: string;
34
+ boardDescription: string;
35
+ boardDescriptionPlaceholder: string;
36
+ createBoard: string;
37
+ updateBoard: string;
38
+ deleteBoard: string;
39
+ deleteBoardConfirm: string;
40
+ columnTitle: string;
41
+ columnTitlePlaceholder: string;
42
+ createColumn: string;
43
+ updateColumn: string;
44
+ deleteColumn: string;
45
+ deleteColumnConfirm: string;
46
+ taskTitle: string;
47
+ taskTitlePlaceholder: string;
48
+ taskDescription: string;
49
+ taskDescriptionPlaceholder: string;
50
+ taskPriority: string;
51
+ taskColumn: string;
52
+ taskAssignee: string;
53
+ createTask: string;
54
+ updateTask: string;
55
+ deleteTask: string;
56
+ deleteTaskConfirm: string;
57
+ nameRequired: string;
58
+ titleRequired: string;
59
+ }
60
+
61
+ interface KanbanListLocalization {
62
+ kanbanBoards: string;
63
+ manageProjects: string;
64
+ createNewBoard: string;
65
+ boardDetails: string;
66
+ newBoard: string;
67
+ addColumn: string;
68
+ addTask: string;
69
+ columnsCount: string;
70
+ noBoardsDescription: string;
71
+ noColumnsDescription: string;
72
+ noTasksDescription: string;
73
+ }
74
+
75
+ type KanbanLocalization = Partial<KanbanCommonLocalization & KanbanFormsLocalization & KanbanListLocalization>;
76
+
77
+ /**
78
+ * User information for assignee display/selection
79
+ * Framework-agnostic - consumers map their auth system to this shape
80
+ */
81
+ interface KanbanUser {
82
+ id: string;
83
+ name: string;
84
+ avatarUrl?: string;
85
+ email?: string;
86
+ }
87
+ /**
88
+ * Context passed to lifecycle hooks
89
+ */
90
+ interface RouteContext {
91
+ /** Current route path */
92
+ path: string;
93
+ /** Route parameters (e.g., { boardId: "abc123" }) */
94
+ params?: Record<string, string>;
95
+ /** Whether rendering on server (true) or client (false) */
96
+ isSSR: boolean;
97
+ /** Additional context properties */
98
+ [key: string]: unknown;
99
+ }
100
+ /**
101
+ * Overridable components and functions for the Kanban plugin
102
+ *
103
+ * External consumers can provide their own implementations of these
104
+ * to customize the behavior for their framework (Next.js, React Router, etc.)
105
+ */
106
+ interface KanbanPluginOverrides {
107
+ /**
108
+ * Link component for navigation
109
+ */
110
+ Link?: ComponentType<React.ComponentProps<"a"> & Record<string, unknown>>;
111
+ /**
112
+ * Navigation function for programmatic navigation
113
+ */
114
+ navigate: (path: string) => void | Promise<void>;
115
+ /**
116
+ * Refresh function to invalidate server-side cache (e.g., Next.js router.refresh())
117
+ */
118
+ refresh?: () => void | Promise<void>;
119
+ /**
120
+ * Image component for displaying images
121
+ */
122
+ Image?: ComponentType<React.ImgHTMLAttributes<HTMLImageElement> & Record<string, unknown>>;
123
+ /**
124
+ * Localization object for the kanban plugin
125
+ */
126
+ localization?: KanbanLocalization;
127
+ /**
128
+ * API base URL
129
+ */
130
+ apiBaseURL: string;
131
+ /**
132
+ * API base path
133
+ */
134
+ apiBasePath: string;
135
+ /**
136
+ * Whether to show the attribution
137
+ */
138
+ showAttribution?: boolean;
139
+ /**
140
+ * Optional headers to pass with API requests (e.g., for SSR auth)
141
+ */
142
+ headers?: HeadersInit;
143
+ /**
144
+ * Resolve user info from an assigneeId
145
+ * Called when rendering task cards/forms that have an assignee
146
+ * Return null for unknown users (will show fallback UI)
147
+ */
148
+ resolveUser: (userId: string) => Promise<KanbanUser | null> | KanbanUser | null;
149
+ /**
150
+ * Search/list users available for assignment
151
+ * Called when user opens the assignee picker
152
+ * @param query - Search query (empty string for initial load)
153
+ * @param boardId - Optional board context for scoped user lists
154
+ */
155
+ searchUsers: (query: string, boardId?: string) => Promise<KanbanUser[]> | KanbanUser[];
156
+ /**
157
+ * Called when a route is rendered
158
+ * @param routeName - Name of the route (e.g., 'boards', 'board', 'newBoard')
159
+ * @param context - Route context with path, params, etc.
160
+ */
161
+ onRouteRender?: (routeName: string, context: RouteContext) => void | Promise<void>;
162
+ /**
163
+ * Called when a route encounters an error
164
+ * @param routeName - Name of the route
165
+ * @param error - The error that occurred
166
+ * @param context - Route context
167
+ */
168
+ onRouteError?: (routeName: string, error: Error, context: RouteContext) => void | Promise<void>;
169
+ /**
170
+ * Called before the boards list page is rendered
171
+ * Return false to prevent rendering (e.g., for authorization)
172
+ * @param context - Route context
173
+ */
174
+ onBeforeBoardsPageRendered?: (context: RouteContext) => boolean;
175
+ /**
176
+ * Called before a single board page is rendered
177
+ * Return false to prevent rendering (e.g., for authorization)
178
+ * @param boardId - The board ID
179
+ * @param context - Route context
180
+ */
181
+ onBeforeBoardPageRendered?: (boardId: string, context: RouteContext) => boolean;
182
+ /**
183
+ * Called before the new board page is rendered
184
+ * Return false to prevent rendering (e.g., for authorization)
185
+ * @param context - Route context
186
+ */
187
+ onBeforeNewBoardPageRendered?: (context: RouteContext) => boolean;
188
+ }
189
+
190
+ export type { KanbanPluginOverrides as K, KanbanUser as a };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btst/stack",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "A composable, plugin-based library for building full-stack applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -298,6 +298,47 @@
298
298
  "default": "./dist/plugins/open-api/api/index.cjs"
299
299
  }
300
300
  },
301
+ "./plugins/kanban/api": {
302
+ "import": {
303
+ "types": "./dist/plugins/kanban/api/index.d.ts",
304
+ "default": "./dist/plugins/kanban/api/index.mjs"
305
+ },
306
+ "require": {
307
+ "types": "./dist/plugins/kanban/api/index.d.cts",
308
+ "default": "./dist/plugins/kanban/api/index.cjs"
309
+ }
310
+ },
311
+ "./plugins/kanban/client": {
312
+ "import": {
313
+ "types": "./dist/plugins/kanban/client/index.d.ts",
314
+ "default": "./dist/plugins/kanban/client/index.mjs"
315
+ },
316
+ "require": {
317
+ "types": "./dist/plugins/kanban/client/index.d.cts",
318
+ "default": "./dist/plugins/kanban/client/index.cjs"
319
+ }
320
+ },
321
+ "./plugins/kanban/client/components": {
322
+ "import": {
323
+ "types": "./dist/plugins/kanban/client/components/index.d.ts",
324
+ "default": "./dist/plugins/kanban/client/components/index.mjs"
325
+ },
326
+ "require": {
327
+ "types": "./dist/plugins/kanban/client/components/index.d.cts",
328
+ "default": "./dist/plugins/kanban/client/components/index.cjs"
329
+ }
330
+ },
331
+ "./plugins/kanban/client/hooks": {
332
+ "import": {
333
+ "types": "./dist/plugins/kanban/client/hooks/index.d.ts",
334
+ "default": "./dist/plugins/kanban/client/hooks/index.mjs"
335
+ },
336
+ "require": {
337
+ "types": "./dist/plugins/kanban/client/hooks/index.d.cts",
338
+ "default": "./dist/plugins/kanban/client/hooks/index.cjs"
339
+ }
340
+ },
341
+ "./plugins/kanban/css": "./dist/plugins/kanban/style.css",
301
342
  "./plugins/route-docs/client": {
302
343
  "import": {
303
344
  "types": "./dist/plugins/route-docs/client/index.d.ts",
@@ -390,6 +431,18 @@
390
431
  "plugins/open-api/api": [
391
432
  "./dist/plugins/open-api/api/index.d.ts"
392
433
  ],
434
+ "plugins/kanban/api": [
435
+ "./dist/plugins/kanban/api/index.d.ts"
436
+ ],
437
+ "plugins/kanban/client": [
438
+ "./dist/plugins/kanban/client/index.d.ts"
439
+ ],
440
+ "plugins/kanban/client/components": [
441
+ "./dist/plugins/kanban/client/components/index.d.ts"
442
+ ],
443
+ "plugins/kanban/client/hooks": [
444
+ "./dist/plugins/kanban/client/hooks/index.d.ts"
445
+ ],
393
446
  "plugins/route-docs/client": [
394
447
  "./dist/plugins/route-docs/client/index.d.ts"
395
448
  ]
@@ -426,7 +479,7 @@
426
479
  "react-error-boundary": ">=4.0.0",
427
480
  "react-hook-form": ">=7.55.0",
428
481
  "react-intersection-observer": ">=9.0.0",
429
- "react-markdown": ">=10.1.0",
482
+ "react-markdown": ">=9.1.0",
430
483
  "rehype-highlight": ">=7.0.0",
431
484
  "rehype-katex": ">=7.0.0",
432
485
  "rehype-raw": ">=7.0.0",
@@ -435,6 +488,7 @@
435
488
  "sonner": ">=2.0.0",
436
489
  "tailwind-merge": ">=2.6.0",
437
490
  "tailwindcss": ">=3.0.0",
491
+ "@tailwindcss/typography": ">=0.5.0",
438
492
  "zod": ">=4.2.0"
439
493
  },
440
494
  "devDependencies": {
@@ -0,0 +1,6 @@
1
+ export {
2
+ kanbanBackendPlugin,
3
+ type KanbanApiRouter,
4
+ type KanbanApiContext,
5
+ type KanbanBackendHooks,
6
+ } from "./plugin";