@btst/stack 2.5.3 → 2.5.5

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 (59) hide show
  1. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +1 -1
  2. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +1 -1
  3. package/dist/packages/stack/src/plugins/ui-builder/client/components/page-renderer.cjs +7 -1
  4. package/dist/packages/stack/src/plugins/ui-builder/client/components/page-renderer.mjs +7 -1
  5. package/dist/packages/stack/src/plugins/ui-builder/client/registry.cjs +309 -37
  6. package/dist/packages/stack/src/plugins/ui-builder/client/registry.mjs +310 -38
  7. package/dist/packages/ui/src/lib/ui-builder/registry/form-field-overrides.cjs +207 -0
  8. package/dist/packages/ui/src/lib/ui-builder/registry/form-field-overrides.mjs +206 -1
  9. package/dist/plugins/blog/api/index.d.cts +2 -2
  10. package/dist/plugins/blog/api/index.d.mts +2 -2
  11. package/dist/plugins/blog/api/index.d.ts +2 -2
  12. package/dist/plugins/blog/client/hooks/index.d.cts +3 -3
  13. package/dist/plugins/blog/client/hooks/index.d.mts +3 -3
  14. package/dist/plugins/blog/client/hooks/index.d.ts +3 -3
  15. package/dist/plugins/blog/client/index.d.cts +1 -1
  16. package/dist/plugins/blog/client/index.d.mts +1 -1
  17. package/dist/plugins/blog/client/index.d.ts +1 -1
  18. package/dist/plugins/blog/query-keys.d.cts +2 -2
  19. package/dist/plugins/blog/query-keys.d.mts +2 -2
  20. package/dist/plugins/blog/query-keys.d.ts +2 -2
  21. package/dist/plugins/kanban/api/index.d.cts +1 -1
  22. package/dist/plugins/kanban/api/index.d.mts +1 -1
  23. package/dist/plugins/kanban/api/index.d.ts +1 -1
  24. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  25. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  26. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  27. package/dist/plugins/ui-builder/client/components/index.d.cts +5 -3
  28. package/dist/plugins/ui-builder/client/components/index.d.mts +5 -3
  29. package/dist/plugins/ui-builder/client/components/index.d.ts +5 -3
  30. package/dist/plugins/ui-builder/client/hooks/index.d.cts +2 -2
  31. package/dist/plugins/ui-builder/client/hooks/index.d.mts +2 -2
  32. package/dist/plugins/ui-builder/client/hooks/index.d.ts +2 -2
  33. package/dist/plugins/ui-builder/client/index.d.cts +2 -2
  34. package/dist/plugins/ui-builder/client/index.d.mts +2 -2
  35. package/dist/plugins/ui-builder/client/index.d.ts +2 -2
  36. package/dist/plugins/ui-builder/index.d.cts +2 -2
  37. package/dist/plugins/ui-builder/index.d.mts +2 -2
  38. package/dist/plugins/ui-builder/index.d.ts +2 -2
  39. package/dist/shared/{stack.Cj_zKww4.d.ts → stack.B2DwzF3r.d.ts} +1 -1
  40. package/dist/shared/{stack.DXnclTG7.d.ts → stack.B8_74ror.d.ts} +4 -4
  41. package/dist/shared/{stack.DaZM10cp.d.cts → stack.C21-LFX8.d.cts} +4 -4
  42. package/dist/shared/{stack.B-YHz18S.d.cts → stack.C5ZSOJGJ.d.cts} +29 -2
  43. package/dist/shared/{stack.cfCkioTe.d.mts → stack.CL4mKxe7.d.mts} +4 -4
  44. package/dist/shared/{stack.B2xZTSiO.d.cts → stack.Cl7ok_cY.d.cts} +1 -1
  45. package/dist/shared/{stack.GygI_T3X.d.ts → stack.D0QupDcQ.d.ts} +29 -2
  46. package/dist/shared/{stack.D1DMlJp-.d.mts → stack.Dq4qVr1F.d.mts} +29 -2
  47. package/dist/shared/{stack.dH7u-TJH.d.mts → stack.VMmQdbsJ.d.mts} +1 -1
  48. package/package.json +1 -1
  49. package/src/plugins/ai-chat/api/plugin.ts +2 -1
  50. package/src/plugins/ui-builder/client/components/page-renderer.tsx +9 -0
  51. package/src/plugins/ui-builder/client/registry.ts +295 -19
  52. package/src/plugins/ui-builder/index.ts +1 -0
  53. package/src/plugins/ui-builder/types.ts +1 -0
  54. package/dist/shared/{stack.DMobugrZ.d.ts → stack.BFcg0tDz.d.ts} +9 -9
  55. package/dist/shared/{stack.BQmuNl5p.d.ts → stack.BWp0hcm9.d.cts} +3 -3
  56. package/dist/shared/{stack.BQmuNl5p.d.cts → stack.BWp0hcm9.d.mts} +3 -3
  57. package/dist/shared/{stack.BQmuNl5p.d.mts → stack.BWp0hcm9.d.ts} +3 -3
  58. package/dist/shared/{stack.Ba_Ks8qi.d.mts → stack.CxNeGV2z.d.mts} +9 -9
  59. package/dist/shared/{stack.CFqqZUes.d.cts → stack.DSxTDZBQ.d.cts} +9 -9
@@ -20,6 +20,7 @@ const card = require('../../../components/card.cjs');
20
20
  const breakpointClassnameControl = require('../../../components/ui-builder/internal/form-fields/classname-control/breakpoint-classname-control.cjs');
21
21
  const label = require('../../../components/label.cjs');
22
22
  const badge = require('../../../components/badge.cjs');
23
+ const select = require('../../../components/select.cjs');
23
24
 
24
25
  const classNameFieldOverrides = (layer) => {
25
26
  return {
@@ -167,6 +168,210 @@ const commonFieldOverrides = (allowBinding = true) => {
167
168
  memoizedCommonFieldOverrides.set(allowBinding, overrides);
168
169
  return overrides;
169
170
  };
171
+ function FunctionPropField({
172
+ propName,
173
+ label,
174
+ isRequired,
175
+ fieldConfigItem
176
+ }) {
177
+ const selectedLayerId = layerStore.useLayerStore((state) => state.selectedLayerId);
178
+ const findLayerById = layerStore.useLayerStore((state) => state.findLayerById);
179
+ const updateLayer = layerStore.useLayerStore((state) => state.updateLayer);
180
+ const incrementRevision = editorStore.useEditorStore((state) => state.incrementRevision);
181
+ const functionRegistry = editorStore.useEditorStore((state) => state.functionRegistry);
182
+ const unbindPropFromVariable = layerStore.useLayerStore(
183
+ (state) => state.unbindPropFromVariable
184
+ );
185
+ const selectedLayer = findLayerById(selectedLayerId);
186
+ if (!selectedLayer || !functionRegistry) {
187
+ return /* @__PURE__ */ jsxRuntime.jsx(
188
+ FormFieldWrapper,
189
+ {
190
+ label,
191
+ isRequired,
192
+ fieldConfigItem,
193
+ children: /* @__PURE__ */ jsxRuntime.jsx(select.Select, { disabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: "No function registry available" }) }) })
194
+ }
195
+ );
196
+ }
197
+ const functionEntries = Object.entries(functionRegistry);
198
+ const getCurrentFunctionId = () => {
199
+ const directFuncId = selectedLayer.props[`__function_${propName}`];
200
+ if (typeof directFuncId === "string") {
201
+ return directFuncId;
202
+ }
203
+ return "";
204
+ };
205
+ const handleValueChange = (value) => {
206
+ if (value === "__none__") {
207
+ unbindPropFromVariable(selectedLayer.id, propName);
208
+ updateLayer(selectedLayer.id, {
209
+ [`__function_${propName}`]: void 0,
210
+ [propName]: void 0
211
+ });
212
+ incrementRevision();
213
+ return;
214
+ }
215
+ const funcDef = functionRegistry[value];
216
+ if (funcDef) {
217
+ unbindPropFromVariable(selectedLayer.id, propName);
218
+ updateLayer(selectedLayer.id, {
219
+ [propName]: funcDef.fn,
220
+ [`__function_${propName}`]: value
221
+ });
222
+ incrementRevision();
223
+ }
224
+ };
225
+ const currentFunctionId = getCurrentFunctionId();
226
+ const getDisplayText = () => {
227
+ if (currentFunctionId) {
228
+ const funcDef = functionRegistry[currentFunctionId];
229
+ return funcDef?.name || currentFunctionId;
230
+ }
231
+ return "Select a function...";
232
+ };
233
+ return /* @__PURE__ */ jsxRuntime.jsx(
234
+ FormFieldWrapper,
235
+ {
236
+ label,
237
+ isRequired,
238
+ fieldConfigItem,
239
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
240
+ select.Select,
241
+ {
242
+ value: currentFunctionId,
243
+ onValueChange: handleValueChange,
244
+ children: [
245
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectTrigger, { className: "w-full mb-0", children: /* @__PURE__ */ jsxRuntime.jsx(select.SelectValue, { placeholder: "Select a function...", children: getDisplayText() }) }),
246
+ /* @__PURE__ */ jsxRuntime.jsxs(select.SelectContent, { children: [
247
+ /* @__PURE__ */ jsxRuntime.jsx(select.SelectItem, { value: "__none__", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "None (clear)" }) }),
248
+ functionEntries.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: functionEntries.map(([id, funcDef]) => /* @__PURE__ */ jsxRuntime.jsx(select.SelectItem, { value: id, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
249
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: funcDef.name }),
250
+ funcDef.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: funcDef.description })
251
+ ] }) }, id)) })
252
+ ] })
253
+ ]
254
+ }
255
+ )
256
+ }
257
+ );
258
+ }
259
+ const functionPropFieldOverrides = (propName) => {
260
+ return {
261
+ renderParent: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx(VariableBindingWrapper, { propName, isFunctionProp: true, children }),
262
+ fieldType: (props) => /* @__PURE__ */ jsxRuntime.jsx(FunctionPropField, { propName, ...props })
263
+ };
264
+ };
265
+ function VariableBindingWrapper({
266
+ propName,
267
+ children,
268
+ isFunctionProp = false
269
+ }) {
270
+ const variables = layerStore.useLayerStore((state) => state.variables);
271
+ const selectedLayerId = layerStore.useLayerStore((state) => state.selectedLayerId);
272
+ const findLayerById = layerStore.useLayerStore((state) => state.findLayerById);
273
+ const isBindingImmutable = layerStore.useLayerStore((state) => state.isBindingImmutable);
274
+ const incrementRevision = editorStore.useEditorStore((state) => state.incrementRevision);
275
+ const functionRegistry = editorStore.useEditorStore((state) => state.functionRegistry);
276
+ const unbindPropFromVariable = layerStore.useLayerStore(
277
+ (state) => state.unbindPropFromVariable
278
+ );
279
+ const bindPropToVariable = layerStore.useLayerStore((state) => state.bindPropToVariable);
280
+ const selectedLayer = findLayerById(selectedLayerId);
281
+ if (!selectedLayer) {
282
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
283
+ }
284
+ const filteredVariables = variables.filter(
285
+ (v) => isFunctionProp ? v.type === "function" : v.type !== "function"
286
+ );
287
+ const currentValue = selectedLayer.props[propName];
288
+ const isCurrentlyBound = types.isVariableReference(currentValue);
289
+ const boundVariable = isCurrentlyBound ? variables.find((v) => v.id === currentValue.__variableRef) : null;
290
+ const isImmutable = isBindingImmutable(selectedLayer.id, propName);
291
+ const getFunctionDisplayValue = (variable) => {
292
+ if (variable.type === "function" && functionRegistry) {
293
+ const funcId = String(variable.defaultValue);
294
+ const funcDef = functionRegistry[funcId];
295
+ return funcDef ? funcDef.name : funcId;
296
+ }
297
+ return String(variable.defaultValue);
298
+ };
299
+ const handleBindToVariable = (variableId) => {
300
+ bindPropToVariable(selectedLayer.id, propName, variableId);
301
+ incrementRevision();
302
+ };
303
+ const handleUnbind = () => {
304
+ unbindPropFromVariable(selectedLayer.id, propName);
305
+ incrementRevision();
306
+ };
307
+ const emptyMessage = isFunctionProp ? "No function variables defined" : "No variables defined";
308
+ const bindLabel = isFunctionProp ? "Bind to Function Variable" : "Bind to Variable";
309
+ const tooltipLabel = isFunctionProp ? "Bind Function" : "Bind Variable";
310
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full gap-2 items-end", children: isCurrentlyBound && boundVariable ? (
311
+ // Bound state - show variable info and unbind button
312
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
313
+ /* @__PURE__ */ jsxRuntime.jsx(label.Label, { children: propName.charAt(0).toUpperCase() + propName.slice(1) }),
314
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end gap-2 w-full", children: [
315
+ /* @__PURE__ */ jsxRuntime.jsx(card.Card, { className: "w-full overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(card.CardContent, { className: "py-1 px-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 w-full", children: [
316
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Link, { className: "h-4 w-4 flex-shrink-0" }),
317
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
318
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 w-full", children: [
319
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: boundVariable.name }),
320
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: boundVariable.type }),
321
+ isImmutable && /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { "data-testid": "immutable-badge", className: "rounded", children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.LockKeyhole, { strokeWidth: 3, className: "w-3 h-3" }) })
322
+ ] }),
323
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground truncate", children: getFunctionDisplayValue(boundVariable) })
324
+ ] })
325
+ ] }) }) }),
326
+ !isImmutable && /* @__PURE__ */ jsxRuntime.jsxs(tooltip.Tooltip, { children: [
327
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
328
+ button.Button,
329
+ {
330
+ variant: "outline",
331
+ onClick: handleUnbind,
332
+ className: "px-3 h-10",
333
+ "data-testid": "unbind-variable-button",
334
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Unlink, { className: "h-4 w-4" })
335
+ }
336
+ ) }),
337
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipContent, { children: "Unbind Variable" })
338
+ ] })
339
+ ] })
340
+ ] })
341
+ ) : (
342
+ // Unbound state - show normal field with bind button
343
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
344
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children }),
345
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenu, { children: [
346
+ /* @__PURE__ */ jsxRuntime.jsxs(tooltip.Tooltip, { children: [
347
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "outline", size: "sm", className: "px-3 h-10", "data-testid": "bind-variable-button", children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Link, { className: "h-4 w-4 my-1" }) }) }) }),
348
+ /* @__PURE__ */ jsxRuntime.jsx(tooltip.TooltipContent, { children: tooltipLabel })
349
+ ] }),
350
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuContent, { align: "end", className: "w-56", children: [
351
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-xs font-medium text-muted-foreground border-b", children: bindLabel }),
352
+ filteredVariables.length > 0 ? filteredVariables.map((variable) => /* @__PURE__ */ jsxRuntime.jsx(
353
+ dropdownMenu.DropdownMenuItem,
354
+ {
355
+ onClick: () => handleBindToVariable(variable.id),
356
+ className: "flex flex-col items-start p-3",
357
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 w-full", children: [
358
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Link, { className: "h-4 w-4 flex-shrink-0" }),
359
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
360
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 ", children: [
361
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: variable.name }),
362
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: variable.type })
363
+ ] }),
364
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground truncate", children: getFunctionDisplayValue(variable) })
365
+ ] })
366
+ ] })
367
+ },
368
+ variable.id
369
+ )) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground", children: emptyMessage })
370
+ ] })
371
+ ] }) })
372
+ ] })
373
+ ) });
374
+ }
170
375
  function FormFieldWrapper({
171
376
  label,
172
377
  isRequired,
@@ -278,9 +483,11 @@ function ChildrenVariableBindingWrapper({
278
483
 
279
484
  exports.ChildrenVariableBindingWrapper = ChildrenVariableBindingWrapper;
280
485
  exports.FormFieldWrapper = FormFieldWrapper;
486
+ exports.VariableBindingWrapper = VariableBindingWrapper;
281
487
  exports.childrenAsTextareaFieldOverrides = childrenAsTextareaFieldOverrides;
282
488
  exports.childrenAsTipTapFieldOverrides = childrenAsTipTapFieldOverrides;
283
489
  exports.childrenFieldOverrides = childrenFieldOverrides;
284
490
  exports.classNameFieldOverrides = classNameFieldOverrides;
285
491
  exports.commonFieldOverrides = commonFieldOverrides;
492
+ exports.functionPropFieldOverrides = functionPropFieldOverrides;
286
493
  exports.iconNameFieldOverrides = iconNameFieldOverrides;
@@ -18,6 +18,7 @@ import { Card, CardContent } from '../../../components/card.mjs';
18
18
  import { BreakpointClassNameControl } from '../../../components/ui-builder/internal/form-fields/classname-control/breakpoint-classname-control.mjs';
19
19
  import { Label } from '../../../components/label.mjs';
20
20
  import { Badge } from '../../../components/badge.mjs';
21
+ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '../../../components/select.mjs';
21
22
 
22
23
  const classNameFieldOverrides = (layer) => {
23
24
  return {
@@ -165,6 +166,210 @@ const commonFieldOverrides = (allowBinding = true) => {
165
166
  memoizedCommonFieldOverrides.set(allowBinding, overrides);
166
167
  return overrides;
167
168
  };
169
+ function FunctionPropField({
170
+ propName,
171
+ label,
172
+ isRequired,
173
+ fieldConfigItem
174
+ }) {
175
+ const selectedLayerId = useLayerStore((state) => state.selectedLayerId);
176
+ const findLayerById = useLayerStore((state) => state.findLayerById);
177
+ const updateLayer = useLayerStore((state) => state.updateLayer);
178
+ const incrementRevision = useEditorStore((state) => state.incrementRevision);
179
+ const functionRegistry = useEditorStore((state) => state.functionRegistry);
180
+ const unbindPropFromVariable = useLayerStore(
181
+ (state) => state.unbindPropFromVariable
182
+ );
183
+ const selectedLayer = findLayerById(selectedLayerId);
184
+ if (!selectedLayer || !functionRegistry) {
185
+ return /* @__PURE__ */ jsx(
186
+ FormFieldWrapper,
187
+ {
188
+ label,
189
+ isRequired,
190
+ fieldConfigItem,
191
+ children: /* @__PURE__ */ jsx(Select, { disabled: true, children: /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "No function registry available" }) }) })
192
+ }
193
+ );
194
+ }
195
+ const functionEntries = Object.entries(functionRegistry);
196
+ const getCurrentFunctionId = () => {
197
+ const directFuncId = selectedLayer.props[`__function_${propName}`];
198
+ if (typeof directFuncId === "string") {
199
+ return directFuncId;
200
+ }
201
+ return "";
202
+ };
203
+ const handleValueChange = (value) => {
204
+ if (value === "__none__") {
205
+ unbindPropFromVariable(selectedLayer.id, propName);
206
+ updateLayer(selectedLayer.id, {
207
+ [`__function_${propName}`]: void 0,
208
+ [propName]: void 0
209
+ });
210
+ incrementRevision();
211
+ return;
212
+ }
213
+ const funcDef = functionRegistry[value];
214
+ if (funcDef) {
215
+ unbindPropFromVariable(selectedLayer.id, propName);
216
+ updateLayer(selectedLayer.id, {
217
+ [propName]: funcDef.fn,
218
+ [`__function_${propName}`]: value
219
+ });
220
+ incrementRevision();
221
+ }
222
+ };
223
+ const currentFunctionId = getCurrentFunctionId();
224
+ const getDisplayText = () => {
225
+ if (currentFunctionId) {
226
+ const funcDef = functionRegistry[currentFunctionId];
227
+ return funcDef?.name || currentFunctionId;
228
+ }
229
+ return "Select a function...";
230
+ };
231
+ return /* @__PURE__ */ jsx(
232
+ FormFieldWrapper,
233
+ {
234
+ label,
235
+ isRequired,
236
+ fieldConfigItem,
237
+ children: /* @__PURE__ */ jsxs(
238
+ Select,
239
+ {
240
+ value: currentFunctionId,
241
+ onValueChange: handleValueChange,
242
+ children: [
243
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full mb-0", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a function...", children: getDisplayText() }) }),
244
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
245
+ /* @__PURE__ */ jsx(SelectItem, { value: "__none__", children: /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "None (clear)" }) }),
246
+ functionEntries.length > 0 && /* @__PURE__ */ jsx(Fragment, { children: functionEntries.map(([id, funcDef]) => /* @__PURE__ */ jsx(SelectItem, { value: id, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
247
+ /* @__PURE__ */ jsx("span", { children: funcDef.name }),
248
+ funcDef.description && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: funcDef.description })
249
+ ] }) }, id)) })
250
+ ] })
251
+ ]
252
+ }
253
+ )
254
+ }
255
+ );
256
+ }
257
+ const functionPropFieldOverrides = (propName) => {
258
+ return {
259
+ renderParent: ({ children }) => /* @__PURE__ */ jsx(VariableBindingWrapper, { propName, isFunctionProp: true, children }),
260
+ fieldType: (props) => /* @__PURE__ */ jsx(FunctionPropField, { propName, ...props })
261
+ };
262
+ };
263
+ function VariableBindingWrapper({
264
+ propName,
265
+ children,
266
+ isFunctionProp = false
267
+ }) {
268
+ const variables = useLayerStore((state) => state.variables);
269
+ const selectedLayerId = useLayerStore((state) => state.selectedLayerId);
270
+ const findLayerById = useLayerStore((state) => state.findLayerById);
271
+ const isBindingImmutable = useLayerStore((state) => state.isBindingImmutable);
272
+ const incrementRevision = useEditorStore((state) => state.incrementRevision);
273
+ const functionRegistry = useEditorStore((state) => state.functionRegistry);
274
+ const unbindPropFromVariable = useLayerStore(
275
+ (state) => state.unbindPropFromVariable
276
+ );
277
+ const bindPropToVariable = useLayerStore((state) => state.bindPropToVariable);
278
+ const selectedLayer = findLayerById(selectedLayerId);
279
+ if (!selectedLayer) {
280
+ return /* @__PURE__ */ jsx(Fragment, { children });
281
+ }
282
+ const filteredVariables = variables.filter(
283
+ (v) => isFunctionProp ? v.type === "function" : v.type !== "function"
284
+ );
285
+ const currentValue = selectedLayer.props[propName];
286
+ const isCurrentlyBound = isVariableReference(currentValue);
287
+ const boundVariable = isCurrentlyBound ? variables.find((v) => v.id === currentValue.__variableRef) : null;
288
+ const isImmutable = isBindingImmutable(selectedLayer.id, propName);
289
+ const getFunctionDisplayValue = (variable) => {
290
+ if (variable.type === "function" && functionRegistry) {
291
+ const funcId = String(variable.defaultValue);
292
+ const funcDef = functionRegistry[funcId];
293
+ return funcDef ? funcDef.name : funcId;
294
+ }
295
+ return String(variable.defaultValue);
296
+ };
297
+ const handleBindToVariable = (variableId) => {
298
+ bindPropToVariable(selectedLayer.id, propName, variableId);
299
+ incrementRevision();
300
+ };
301
+ const handleUnbind = () => {
302
+ unbindPropFromVariable(selectedLayer.id, propName);
303
+ incrementRevision();
304
+ };
305
+ const emptyMessage = isFunctionProp ? "No function variables defined" : "No variables defined";
306
+ const bindLabel = isFunctionProp ? "Bind to Function Variable" : "Bind to Variable";
307
+ const tooltipLabel = isFunctionProp ? "Bind Function" : "Bind Variable";
308
+ return /* @__PURE__ */ jsx("div", { className: "flex w-full gap-2 items-end", children: isCurrentlyBound && boundVariable ? (
309
+ // Bound state - show variable info and unbind button
310
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 w-full", children: [
311
+ /* @__PURE__ */ jsx(Label, { children: propName.charAt(0).toUpperCase() + propName.slice(1) }),
312
+ /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2 w-full", children: [
313
+ /* @__PURE__ */ jsx(Card, { className: "w-full overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(CardContent, { className: "py-1 px-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
314
+ /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 flex-shrink-0" }),
315
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
316
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
317
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: boundVariable.name }),
318
+ /* @__PURE__ */ jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: boundVariable.type }),
319
+ isImmutable && /* @__PURE__ */ jsx(Badge, { "data-testid": "immutable-badge", className: "rounded", children: /* @__PURE__ */ jsx(LockKeyhole, { strokeWidth: 3, className: "w-3 h-3" }) })
320
+ ] }),
321
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate", children: getFunctionDisplayValue(boundVariable) })
322
+ ] })
323
+ ] }) }) }),
324
+ !isImmutable && /* @__PURE__ */ jsxs(Tooltip, { children: [
325
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
326
+ Button,
327
+ {
328
+ variant: "outline",
329
+ onClick: handleUnbind,
330
+ className: "px-3 h-10",
331
+ "data-testid": "unbind-variable-button",
332
+ children: /* @__PURE__ */ jsx(Unlink, { className: "h-4 w-4" })
333
+ }
334
+ ) }),
335
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Unbind Variable" })
336
+ ] })
337
+ ] })
338
+ ] })
339
+ ) : (
340
+ // Unbound state - show normal field with bind button
341
+ /* @__PURE__ */ jsxs(Fragment, { children: [
342
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children }),
343
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
344
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
345
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: "px-3 h-10", "data-testid": "bind-variable-button", children: /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 my-1" }) }) }) }),
346
+ /* @__PURE__ */ jsx(TooltipContent, { children: tooltipLabel })
347
+ ] }),
348
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
349
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs font-medium text-muted-foreground border-b", children: bindLabel }),
350
+ filteredVariables.length > 0 ? filteredVariables.map((variable) => /* @__PURE__ */ jsx(
351
+ DropdownMenuItem,
352
+ {
353
+ onClick: () => handleBindToVariable(variable.id),
354
+ className: "flex flex-col items-start p-3",
355
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full", children: [
356
+ /* @__PURE__ */ jsx(Link, { className: "h-4 w-4 flex-shrink-0" }),
357
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
358
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 ", children: [
359
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: variable.name }),
360
+ /* @__PURE__ */ jsx("span", { className: "px-1.5 py-0.5 bg-muted rounded text-xs font-mono", children: variable.type })
361
+ ] }),
362
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate", children: getFunctionDisplayValue(variable) })
363
+ ] })
364
+ ] })
365
+ },
366
+ variable.id
367
+ )) : /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground", children: emptyMessage })
368
+ ] })
369
+ ] }) })
370
+ ] })
371
+ ) });
372
+ }
168
373
  function FormFieldWrapper({
169
374
  label,
170
375
  isRequired,
@@ -274,4 +479,4 @@ function ChildrenVariableBindingWrapper({
274
479
  ) });
275
480
  }
276
481
 
277
- export { ChildrenVariableBindingWrapper, FormFieldWrapper, childrenAsTextareaFieldOverrides, childrenAsTipTapFieldOverrides, childrenFieldOverrides, classNameFieldOverrides, commonFieldOverrides, iconNameFieldOverrides };
482
+ export { ChildrenVariableBindingWrapper, FormFieldWrapper, VariableBindingWrapper, childrenAsTextareaFieldOverrides, childrenAsTipTapFieldOverrides, childrenFieldOverrides, classNameFieldOverrides, commonFieldOverrides, functionPropFieldOverrides, iconNameFieldOverrides };
@@ -1,5 +1,5 @@
1
- export { B as BLOG_QUERY_KEYS, h as BlogApiContext, k as BlogApiRouter, i as BlogBackendHooks, e as BlogRouteKey, N as NextPreviousPostsQuerySchema, P as PostListParams, f as PostListQuerySchema, c as PostListResult, j as blogBackendPlugin, d as createBlogQueryKeys, g as getAllPosts, b as getAllTags, a as getPostBySlug } from '../../../shared/stack.DaZM10cp.cjs';
2
- import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.BQmuNl5p.cjs';
1
+ export { B as BLOG_QUERY_KEYS, h as BlogApiContext, k as BlogApiRouter, i as BlogBackendHooks, e as BlogRouteKey, N as NextPreviousPostsQuerySchema, P as PostListParams, f as PostListQuerySchema, c as PostListResult, j as blogBackendPlugin, d as createBlogQueryKeys, g as getAllPosts, b as getAllTags, a as getPostBySlug } from '../../../shared/stack.C21-LFX8.cjs';
2
+ import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.BWp0hcm9.cjs';
3
3
  import '@tanstack/react-query';
4
4
  import '@btst/stack/plugins/client';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
- export { B as BLOG_QUERY_KEYS, h as BlogApiContext, k as BlogApiRouter, i as BlogBackendHooks, e as BlogRouteKey, N as NextPreviousPostsQuerySchema, P as PostListParams, f as PostListQuerySchema, c as PostListResult, j as blogBackendPlugin, d as createBlogQueryKeys, g as getAllPosts, b as getAllTags, a as getPostBySlug } from '../../../shared/stack.cfCkioTe.mjs';
2
- import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.BQmuNl5p.mjs';
1
+ export { B as BLOG_QUERY_KEYS, h as BlogApiContext, k as BlogApiRouter, i as BlogBackendHooks, e as BlogRouteKey, N as NextPreviousPostsQuerySchema, P as PostListParams, f as PostListQuerySchema, c as PostListResult, j as blogBackendPlugin, d as createBlogQueryKeys, g as getAllPosts, b as getAllTags, a as getPostBySlug } from '../../../shared/stack.CL4mKxe7.mjs';
2
+ import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.BWp0hcm9.mjs';
3
3
  import '@tanstack/react-query';
4
4
  import '@btst/stack/plugins/client';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
- export { B as BLOG_QUERY_KEYS, h as BlogApiContext, k as BlogApiRouter, i as BlogBackendHooks, e as BlogRouteKey, N as NextPreviousPostsQuerySchema, P as PostListParams, f as PostListQuerySchema, c as PostListResult, j as blogBackendPlugin, d as createBlogQueryKeys, g as getAllPosts, b as getAllTags, a as getPostBySlug } from '../../../shared/stack.DXnclTG7.js';
2
- import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.BQmuNl5p.js';
1
+ export { B as BLOG_QUERY_KEYS, h as BlogApiContext, k as BlogApiRouter, i as BlogBackendHooks, e as BlogRouteKey, N as NextPreviousPostsQuerySchema, P as PostListParams, f as PostListQuerySchema, c as PostListResult, j as blogBackendPlugin, d as createBlogQueryKeys, g as getAllPosts, b as getAllTags, a as getPostBySlug } from '../../../shared/stack.B8_74ror.js';
2
+ import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.BWp0hcm9.js';
3
3
  import '@tanstack/react-query';
4
4
  import '@btst/stack/plugins/client';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.BQmuNl5p.cjs';
2
+ import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.BWp0hcm9.cjs';
3
3
  import { z } from 'zod';
4
4
 
5
5
  /**
@@ -135,14 +135,14 @@ declare function useCreatePost(): _tanstack_react_query.UseMutationResult<Serial
135
135
  name: string;
136
136
  slug: string;
137
137
  })[];
138
+ published: boolean;
138
139
  title: string;
139
140
  content: string;
140
141
  excerpt: string;
141
- published: boolean;
142
142
  slug?: string | undefined;
143
+ publishedAt?: Date | undefined;
143
144
  createdAt?: Date | undefined;
144
145
  updatedAt?: Date | undefined;
145
- publishedAt?: Date | undefined;
146
146
  image?: string | undefined;
147
147
  }, unknown>;
148
148
  /** Update an existing post by id */
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.BQmuNl5p.mjs';
2
+ import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.BWp0hcm9.mjs';
3
3
  import { z } from 'zod';
4
4
 
5
5
  /**
@@ -135,14 +135,14 @@ declare function useCreatePost(): _tanstack_react_query.UseMutationResult<Serial
135
135
  name: string;
136
136
  slug: string;
137
137
  })[];
138
+ published: boolean;
138
139
  title: string;
139
140
  content: string;
140
141
  excerpt: string;
141
- published: boolean;
142
142
  slug?: string | undefined;
143
+ publishedAt?: Date | undefined;
143
144
  createdAt?: Date | undefined;
144
145
  updatedAt?: Date | undefined;
145
- publishedAt?: Date | undefined;
146
146
  image?: string | undefined;
147
147
  }, unknown>;
148
148
  /** Update an existing post by id */
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.BQmuNl5p.js';
2
+ import { S as SerializedPost, c as createPostSchema, u as updatePostSchema, a as SerializedTag } from '../../../../shared/stack.BWp0hcm9.js';
3
3
  import { z } from 'zod';
4
4
 
5
5
  /**
@@ -135,14 +135,14 @@ declare function useCreatePost(): _tanstack_react_query.UseMutationResult<Serial
135
135
  name: string;
136
136
  slug: string;
137
137
  })[];
138
+ published: boolean;
138
139
  title: string;
139
140
  content: string;
140
141
  excerpt: string;
141
- published: boolean;
142
142
  slug?: string | undefined;
143
+ publishedAt?: Date | undefined;
143
144
  createdAt?: Date | undefined;
144
145
  updatedAt?: Date | undefined;
145
- publishedAt?: Date | undefined;
146
146
  image?: string | undefined;
147
147
  }, unknown>;
148
148
  /** Update an existing post by id */
@@ -3,7 +3,7 @@ import * as react from 'react';
3
3
  import { ComponentType } from 'react';
4
4
  import * as _btst_yar from '@btst/yar';
5
5
  import { QueryClient } from '@tanstack/react-query';
6
- import { P as Post, S as SerializedPost } from '../../../shared/stack.BQmuNl5p.cjs';
6
+ import { P as Post, S as SerializedPost } from '../../../shared/stack.BWp0hcm9.cjs';
7
7
  export { UsePostsOptions, UsePostsResult } from './hooks/index.cjs';
8
8
  import 'zod';
9
9
 
@@ -3,7 +3,7 @@ import * as react from 'react';
3
3
  import { ComponentType } from 'react';
4
4
  import * as _btst_yar from '@btst/yar';
5
5
  import { QueryClient } from '@tanstack/react-query';
6
- import { P as Post, S as SerializedPost } from '../../../shared/stack.BQmuNl5p.mjs';
6
+ import { P as Post, S as SerializedPost } from '../../../shared/stack.BWp0hcm9.mjs';
7
7
  export { UsePostsOptions, UsePostsResult } from './hooks/index.mjs';
8
8
  import 'zod';
9
9
 
@@ -3,7 +3,7 @@ import * as react from 'react';
3
3
  import { ComponentType } from 'react';
4
4
  import * as _btst_yar from '@btst/yar';
5
5
  import { QueryClient } from '@tanstack/react-query';
6
- import { P as Post, S as SerializedPost } from '../../../shared/stack.BQmuNl5p.js';
6
+ import { P as Post, S as SerializedPost } from '../../../shared/stack.BWp0hcm9.js';
7
7
  export { UsePostsOptions, UsePostsResult } from './hooks/index.js';
8
8
  import 'zod';
9
9
 
@@ -1,7 +1,7 @@
1
1
  import '@tanstack/react-query';
2
- export { d as createBlogQueryKeys } from '../../shared/stack.DaZM10cp.cjs';
2
+ export { d as createBlogQueryKeys } from '../../shared/stack.C21-LFX8.cjs';
3
3
  import '@btst/stack/plugins/client';
4
- import '../../shared/stack.BQmuNl5p.cjs';
4
+ import '../../shared/stack.BWp0hcm9.cjs';
5
5
  import '@btst/stack/plugins/api';
6
6
  import 'better-call';
7
7
  import '@btst/db';
@@ -1,7 +1,7 @@
1
1
  import '@tanstack/react-query';
2
- export { d as createBlogQueryKeys } from '../../shared/stack.cfCkioTe.mjs';
2
+ export { d as createBlogQueryKeys } from '../../shared/stack.CL4mKxe7.mjs';
3
3
  import '@btst/stack/plugins/client';
4
- import '../../shared/stack.BQmuNl5p.mjs';
4
+ import '../../shared/stack.BWp0hcm9.mjs';
5
5
  import '@btst/stack/plugins/api';
6
6
  import 'better-call';
7
7
  import '@btst/db';
@@ -1,7 +1,7 @@
1
1
  import '@tanstack/react-query';
2
- export { d as createBlogQueryKeys } from '../../shared/stack.DXnclTG7.js';
2
+ export { d as createBlogQueryKeys } from '../../shared/stack.B8_74ror.js';
3
3
  import '@btst/stack/plugins/client';
4
- import '../../shared/stack.BQmuNl5p.js';
4
+ import '../../shared/stack.BWp0hcm9.js';
5
5
  import '@btst/stack/plugins/api';
6
6
  import 'better-call';
7
7
  import '@btst/db';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.CFqqZUes.cjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.DSxTDZBQ.cjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.cjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import 'better-call';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.Ba_Ks8qi.mjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.CxNeGV2z.mjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.mjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import 'better-call';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.DMobugrZ.js';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.BFcg0tDz.js';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.js';
3
3
  import '@btst/stack/plugins/api';
4
4
  import 'better-call';