@superblocksteam/vite-plugin-file-sync 2.0.4 → 2.0.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 (152) hide show
  1. package/dist/ai-service/app-interface/linter.d.ts +3 -0
  2. package/dist/ai-service/app-interface/linter.d.ts.map +1 -0
  3. package/dist/ai-service/app-interface/linter.js +64 -0
  4. package/dist/ai-service/app-interface/linter.js.map +1 -0
  5. package/dist/ai-service/app-interface/shell.d.ts +2 -0
  6. package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
  7. package/dist/ai-service/app-interface/shell.js +16 -0
  8. package/dist/ai-service/app-interface/shell.js.map +1 -1
  9. package/dist/ai-service/index.d.ts +2 -4
  10. package/dist/ai-service/index.d.ts.map +1 -1
  11. package/dist/ai-service/index.js +17 -8
  12. package/dist/ai-service/index.js.map +1 -1
  13. package/dist/ai-service/integrations/const.d.ts +2 -0
  14. package/dist/ai-service/integrations/const.d.ts.map +1 -1
  15. package/dist/ai-service/integrations/const.js +2 -0
  16. package/dist/ai-service/integrations/const.js.map +1 -1
  17. package/dist/ai-service/integrations/to-sdk-prompt.d.ts.map +1 -1
  18. package/dist/ai-service/integrations/to-sdk-prompt.js +3648 -158
  19. package/dist/ai-service/integrations/to-sdk-prompt.js.map +1 -1
  20. package/dist/ai-service/prompts/generated/library-components/SbButtonPropsDocs.js +1 -1
  21. package/dist/ai-service/prompts/generated/library-components/SbCheckboxPropsDocs.js +1 -1
  22. package/dist/ai-service/prompts/generated/library-components/SbColumnPropsDocs.js +1 -1
  23. package/dist/ai-service/prompts/generated/library-components/SbContainerPropsDocs.js +1 -1
  24. package/dist/ai-service/prompts/generated/library-components/SbDatePickerPropsDocs.js +1 -1
  25. package/dist/ai-service/prompts/generated/library-components/SbDropdownPropsDocs.js +1 -1
  26. package/dist/ai-service/prompts/generated/library-components/SbIconPropsDocs.js +1 -1
  27. package/dist/ai-service/prompts/generated/library-components/SbImagePropsDocs.js +1 -1
  28. package/dist/ai-service/prompts/generated/library-components/SbInputPropsDocs.js +1 -1
  29. package/dist/ai-service/prompts/generated/library-components/SbModalPropsDocs.js +1 -1
  30. package/dist/ai-service/prompts/generated/library-components/SbPagePropsDocs.js +1 -1
  31. package/dist/ai-service/prompts/generated/library-components/SbSectionPropsDocs.js +1 -1
  32. package/dist/ai-service/prompts/generated/library-components/SbSlideoutPropsDocs.js +1 -1
  33. package/dist/ai-service/prompts/generated/library-components/SbSwitchPropsDocs.js +1 -1
  34. package/dist/ai-service/prompts/generated/library-components/SbTablePropsDocs.js +1 -1
  35. package/dist/ai-service/prompts/generated/library-components/SbTextPropsDocs.js +1 -1
  36. package/dist/ai-service/prompts/generated/library-typedefs/Dim.js +1 -1
  37. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.d.ts +1 -1
  38. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.d.ts.map +1 -1
  39. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.js +2 -2
  40. package/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.js.map +1 -1
  41. package/dist/ai-service/prompts/generated/subprompts/full-examples.d.ts +2 -0
  42. package/dist/ai-service/prompts/generated/subprompts/full-examples.d.ts.map +1 -0
  43. package/dist/ai-service/prompts/generated/subprompts/full-examples.js +6 -0
  44. package/dist/ai-service/prompts/generated/subprompts/full-examples.js.map +1 -0
  45. package/dist/ai-service/prompts/generated/subprompts/index.d.ts +1 -0
  46. package/dist/ai-service/prompts/generated/subprompts/index.d.ts.map +1 -1
  47. package/dist/ai-service/prompts/generated/subprompts/index.js +1 -0
  48. package/dist/ai-service/prompts/generated/subprompts/index.js.map +1 -1
  49. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.d.ts +1 -1
  50. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.d.ts.map +1 -1
  51. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.js +2 -2
  52. package/dist/ai-service/prompts/generated/subprompts/superblocks-api.js.map +1 -1
  53. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.d.ts +1 -1
  54. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.d.ts.map +1 -1
  55. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.js +2 -2
  56. package/dist/ai-service/prompts/generated/subprompts/superblocks-components-rules.js.map +1 -1
  57. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.d.ts +1 -1
  58. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.d.ts.map +1 -1
  59. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.js +2 -2
  60. package/dist/ai-service/prompts/generated/subprompts/superblocks-custom-components.js.map +1 -1
  61. package/dist/ai-service/prompts/generated/subprompts/superblocks-data-filtering.d.ts +1 -1
  62. package/dist/ai-service/prompts/generated/subprompts/superblocks-data-filtering.d.ts.map +1 -1
  63. package/dist/ai-service/prompts/generated/subprompts/superblocks-data-filtering.js +2 -2
  64. package/dist/ai-service/prompts/generated/subprompts/superblocks-data-filtering.js.map +1 -1
  65. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.d.ts +1 -1
  66. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.d.ts.map +1 -1
  67. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.js +2 -2
  68. package/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.js.map +1 -1
  69. package/dist/ai-service/prompts/generated/subprompts/superblocks-forms.d.ts +1 -1
  70. package/dist/ai-service/prompts/generated/subprompts/superblocks-forms.d.ts.map +1 -1
  71. package/dist/ai-service/prompts/generated/subprompts/superblocks-forms.js +2 -2
  72. package/dist/ai-service/prompts/generated/subprompts/superblocks-forms.js.map +1 -1
  73. package/dist/ai-service/prompts/generated/subprompts/superblocks-layouts.js +1 -1
  74. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.d.ts +1 -1
  75. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.d.ts.map +1 -1
  76. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.js +2 -2
  77. package/dist/ai-service/prompts/generated/subprompts/superblocks-page.js.map +1 -1
  78. package/dist/ai-service/prompts/generated/subprompts/superblocks-rbac.js +1 -1
  79. package/dist/ai-service/prompts/generated/subprompts/superblocks-routes.js +1 -1
  80. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.d.ts +1 -1
  81. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.d.ts.map +1 -1
  82. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.js +2 -2
  83. package/dist/ai-service/prompts/generated/subprompts/superblocks-state.js.map +1 -1
  84. package/dist/ai-service/prompts/generated/subprompts/superblocks-theming.js +1 -1
  85. package/dist/ai-service/prompts/generated/subprompts/system.d.ts +1 -1
  86. package/dist/ai-service/prompts/generated/subprompts/system.d.ts.map +1 -1
  87. package/dist/ai-service/prompts/generated/subprompts/system.js +2 -2
  88. package/dist/ai-service/prompts/generated/subprompts/system.js.map +1 -1
  89. package/dist/ai-service/prompts/system.d.ts.map +1 -1
  90. package/dist/ai-service/prompts/system.js +4 -0
  91. package/dist/ai-service/prompts/system.js.map +1 -1
  92. package/dist/ai-service/state-machine/clark-fsm.d.ts +3 -3
  93. package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
  94. package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
  95. package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -1
  96. package/dist/ai-service/state-machine/handlers/agent-planning.js +23 -9
  97. package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
  98. package/dist/ai-service/state-machine/handlers/post-processing.d.ts.map +1 -1
  99. package/dist/ai-service/state-machine/handlers/post-processing.js +6 -7
  100. package/dist/ai-service/state-machine/handlers/post-processing.js.map +1 -1
  101. package/dist/ai-service/state-machine/handlers/runtime-reviewing.d.ts.map +1 -1
  102. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js +17 -7
  103. package/dist/ai-service/state-machine/handlers/runtime-reviewing.js.map +1 -1
  104. package/dist/ai-service/state-machine/mocks.d.ts.map +1 -1
  105. package/dist/ai-service/state-machine/mocks.js +2 -0
  106. package/dist/ai-service/state-machine/mocks.js.map +1 -1
  107. package/dist/components-manager.d.ts +4 -2
  108. package/dist/components-manager.d.ts.map +1 -1
  109. package/dist/components-manager.js +9 -5
  110. package/dist/components-manager.js.map +1 -1
  111. package/dist/errors/make-server-error.d.ts +0 -1
  112. package/dist/errors/make-server-error.d.ts.map +1 -1
  113. package/dist/errors/make-server-error.js +0 -9
  114. package/dist/errors/make-server-error.js.map +1 -1
  115. package/dist/file-sync-vite-plugin.d.ts.map +1 -1
  116. package/dist/file-sync-vite-plugin.js +9 -5
  117. package/dist/file-sync-vite-plugin.js.map +1 -1
  118. package/dist/file-system-manager.d.ts +3 -2
  119. package/dist/file-system-manager.d.ts.map +1 -1
  120. package/dist/file-system-manager.js +6 -9
  121. package/dist/file-system-manager.js.map +1 -1
  122. package/dist/lock-service/index.d.ts +2 -2
  123. package/dist/lock-service/index.d.ts.map +1 -1
  124. package/dist/lock-service/index.js +4 -4
  125. package/dist/lock-service/index.js.map +1 -1
  126. package/dist/parsing/events/to-code-events.js +1 -1
  127. package/dist/parsing/events/to-code-events.js.map +1 -1
  128. package/dist/refactor/javascript.d.ts +4 -0
  129. package/dist/refactor/javascript.d.ts.map +1 -1
  130. package/dist/refactor/javascript.js +8 -0
  131. package/dist/refactor/javascript.js.map +1 -1
  132. package/dist/rename-manager.d.ts +5 -0
  133. package/dist/rename-manager.d.ts.map +1 -1
  134. package/dist/rename-manager.js +27 -1
  135. package/dist/rename-manager.js.map +1 -1
  136. package/dist/sb-scope-manager.d.ts +4 -3
  137. package/dist/sb-scope-manager.d.ts.map +1 -1
  138. package/dist/sb-scope-manager.js +4 -4
  139. package/dist/sb-scope-manager.js.map +1 -1
  140. package/dist/socket-manager.d.ts +2 -4
  141. package/dist/socket-manager.d.ts.map +1 -1
  142. package/dist/socket-manager.js +3 -13
  143. package/dist/socket-manager.js.map +1 -1
  144. package/dist/source-tracker.d.ts +2 -1
  145. package/dist/source-tracker.d.ts.map +1 -1
  146. package/dist/source-tracker.js +15 -2
  147. package/dist/source-tracker.js.map +1 -1
  148. package/dist/sync-service/index.d.ts +4 -2
  149. package/dist/sync-service/index.d.ts.map +1 -1
  150. package/dist/sync-service/index.js +5 -6
  151. package/dist/sync-service/index.js.map +1 -1
  152. package/package.json +6 -5
@@ -1,2 +1,2 @@
1
- export declare const content = "### Rules for using Superblocks components:\n\n- ENSURE THAT ALL PROPERTY VALUES COMPLY WITH THE SUPPLIED TYPES FOR EACH PROPERTY\n- NEVER use a component in this section in a custom component\n- SbModal components DO NOT need to have their own close button. The modal component comes with a close button by default.\n- NEVER store property values in variables and then pass those variables to components. ALWAYS define the values inline so the visual editor can show them correctly.\n\nNOTES:\n\n- When you see _Border_, it's {width: Dim, style: string, color: string}\n- When you see _TextStyle_, it's a plain JS object with the following properties:\n - variant: \"heading1\" | \"heading2\" | \"heading3\" | \"heading4\" | \"heading5\" | \"body1\" | \"body2\" | \"body3\" | \"label\" | \"inputLabel\" | \"code\"\n - textColor: an object with only the following properties:\n - default: string // the text color to use. A color value from the theme, or a hex code if necessary. ALWAYS wrap this property in sbComputed. Example: sbComputed(() => Theme.colors.neutral900), and remember to import sbComputed and globals from the library: import { sbComputed,Theme } from '@superblocksteam/library';\n- When you see _SbEventFlow_, use the SbEventFlow builder\n- Import all components you use from '@superblocksteam/library'; Example: `import { SbContainer, SbButton, sbComputed, ... } from '@superblocksteam/library';` If you don't import all components you use, the app will crash!\n- Don't add props to the Page component other than onLoad\n- SbContainer has a default style of \"card\" if you want to remove the style, set the style to \"none\"\n- When using dynamic values in component props, use `sbComputed` with the correct pattern:\n - For scope entities (variables, APIs): `sbComputed(() => entityName.value)` (direct access)\n - For bound components: `sbComputed(() => ComponentName.property)` (direct access after binding)\n - For global access: `sbComputed(() => Global.user.name)` or `sbComputed(() => Theme.colors.primary)` (import globals from the library first: `import { Global, Theme, Embed, Env } from '@superblocksteam/library';`)\n- Use sbComputed ONLY when the value references dynamic data (state variables, API responses, component values, or theme)\n- Do NOT use sbComputed for static configuration like table columns, static dropdown options, or style objects that don't reference theme\n";
1
+ export declare const content = "### Rules for using Superblocks components:\n\n- ENSURE THAT ALL PROPERTY VALUES COMPLY WITH THE SUPPLIED TYPES FOR EACH PROPERTY\n- NEVER use a component in this section in a custom component\n- **\uD83D\uDEA8 CRITICAL: NEVER use sbComputed as React children.** sbComputed returns an object that React cannot render. Examples:\n - \u274C WRONG: `<SbContainer>{sbComputed(() => dynamicText)}</SbContainer>`\n - \u274C WRONG: `<SbSection>{sbComputed(() => conditionalContent)}</SbSection>`\n - \u2705 CORRECT: `<SbText text={sbComputed(() => dynamicText)} />`\n - \u2705 CORRECT: `<SbContainer isVisible={sbComputed(() => showContainer)} />`\n- SbModal components DO NOT need to have their own close button. The modal component comes with a close button by default.\n- NEVER store property values in variables and then pass those variables to components. ALWAYS define the values inline so the visual editor can show them correctly.\n\nNOTES:\n\n- When you see _Border_, it's {width: Dim, style: string, color: string}\n- When you see _TextStyle_, it's a plain JS object with the following properties:\n - variant: \"heading1\" | \"heading2\" | \"heading3\" | \"heading4\" | \"heading5\" | \"body1\" | \"body2\" | \"body3\" | \"label\" | \"inputLabel\" | \"code\"\n - textColor: an object with only the following properties:\n - default: string // the text color to use. A color value from the theme, or a hex code if necessary. ALWAYS wrap this property in sbComputed. Example: sbComputed(() => Theme.colors.neutral900), and remember to import sbComputed and globals from the library: import { sbComputed,Theme } from '@superblocksteam/library';\n- When you see _SbEventFlow_, use the SbEventFlow builder\n- Import all components you use from '@superblocksteam/library'; Example: `import { SbContainer, SbButton, sbComputed, ... } from '@superblocksteam/library';` If you don't import all components you use, the app will crash!\n- Don't add props to the Page component other than onLoad\n- SbContainer has a default style of \"card\" if you want to remove the style, set the style to \"none\"\n- When using dynamic values in component props, use `sbComputed` with the correct pattern:\n - For scope entities (variables, APIs): `sbComputed(() => entityName.value)` (direct access)\n - For bound components: `sbComputed(() => ComponentName.property)` (direct access after binding)\n - For global access: `sbComputed(() => Global.user.name)` or `sbComputed(() => Theme.colors.primary)` (import globals from the library first: `import { Global, Theme, Embed, Env } from '@superblocksteam/library';`)\n- Use sbComputed ONLY when the value references dynamic data (state variables, API responses, component values, or theme)\n- Do NOT use sbComputed for static configuration like table columns, static dropdown options, or style objects that don't reference theme\n";
2
2
  //# sourceMappingURL=superblocks-components-rules.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-components-rules.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-components-rules.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,y3EAAy3E,CAAC"}
1
+ {"version":3,"file":"superblocks-components-rules.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-components-rules.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,6zFAA+xF,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  // Auto-generated from superblocks-components-rules.md
3
3
  // Do not edit this file directly
4
- // Generated at: 2025-06-15T06:08:09.960Z
5
- export const content = "### Rules for using Superblocks components:\n\n- ENSURE THAT ALL PROPERTY VALUES COMPLY WITH THE SUPPLIED TYPES FOR EACH PROPERTY\n- NEVER use a component in this section in a custom component\n- SbModal components DO NOT need to have their own close button. The modal component comes with a close button by default.\n- NEVER store property values in variables and then pass those variables to components. ALWAYS define the values inline so the visual editor can show them correctly.\n\nNOTES:\n\n- When you see _Border_, it's {width: Dim, style: string, color: string}\n- When you see _TextStyle_, it's a plain JS object with the following properties:\n - variant: \"heading1\" | \"heading2\" | \"heading3\" | \"heading4\" | \"heading5\" | \"body1\" | \"body2\" | \"body3\" | \"label\" | \"inputLabel\" | \"code\"\n - textColor: an object with only the following properties:\n - default: string // the text color to use. A color value from the theme, or a hex code if necessary. ALWAYS wrap this property in sbComputed. Example: sbComputed(() => Theme.colors.neutral900), and remember to import sbComputed and globals from the library: import { sbComputed,Theme } from '@superblocksteam/library';\n- When you see _SbEventFlow_, use the SbEventFlow builder\n- Import all components you use from '@superblocksteam/library'; Example: `import { SbContainer, SbButton, sbComputed, ... } from '@superblocksteam/library';` If you don't import all components you use, the app will crash!\n- Don't add props to the Page component other than onLoad\n- SbContainer has a default style of \"card\" if you want to remove the style, set the style to \"none\"\n- When using dynamic values in component props, use `sbComputed` with the correct pattern:\n - For scope entities (variables, APIs): `sbComputed(() => entityName.value)` (direct access)\n - For bound components: `sbComputed(() => ComponentName.property)` (direct access after binding)\n - For global access: `sbComputed(() => Global.user.name)` or `sbComputed(() => Theme.colors.primary)` (import globals from the library first: `import { Global, Theme, Embed, Env } from '@superblocksteam/library';`)\n- Use sbComputed ONLY when the value references dynamic data (state variables, API responses, component values, or theme)\n- Do NOT use sbComputed for static configuration like table columns, static dropdown options, or style objects that don't reference theme\n";
4
+ // Generated at: 2025-06-23T03:26:44.022Z
5
+ export const content = "### Rules for using Superblocks components:\n\n- ENSURE THAT ALL PROPERTY VALUES COMPLY WITH THE SUPPLIED TYPES FOR EACH PROPERTY\n- NEVER use a component in this section in a custom component\n- **🚨 CRITICAL: NEVER use sbComputed as React children.** sbComputed returns an object that React cannot render. Examples:\n - ❌ WRONG: `<SbContainer>{sbComputed(() => dynamicText)}</SbContainer>`\n - ❌ WRONG: `<SbSection>{sbComputed(() => conditionalContent)}</SbSection>`\n - ✅ CORRECT: `<SbText text={sbComputed(() => dynamicText)} />`\n - ✅ CORRECT: `<SbContainer isVisible={sbComputed(() => showContainer)} />`\n- SbModal components DO NOT need to have their own close button. The modal component comes with a close button by default.\n- NEVER store property values in variables and then pass those variables to components. ALWAYS define the values inline so the visual editor can show them correctly.\n\nNOTES:\n\n- When you see _Border_, it's {width: Dim, style: string, color: string}\n- When you see _TextStyle_, it's a plain JS object with the following properties:\n - variant: \"heading1\" | \"heading2\" | \"heading3\" | \"heading4\" | \"heading5\" | \"body1\" | \"body2\" | \"body3\" | \"label\" | \"inputLabel\" | \"code\"\n - textColor: an object with only the following properties:\n - default: string // the text color to use. A color value from the theme, or a hex code if necessary. ALWAYS wrap this property in sbComputed. Example: sbComputed(() => Theme.colors.neutral900), and remember to import sbComputed and globals from the library: import { sbComputed,Theme } from '@superblocksteam/library';\n- When you see _SbEventFlow_, use the SbEventFlow builder\n- Import all components you use from '@superblocksteam/library'; Example: `import { SbContainer, SbButton, sbComputed, ... } from '@superblocksteam/library';` If you don't import all components you use, the app will crash!\n- Don't add props to the Page component other than onLoad\n- SbContainer has a default style of \"card\" if you want to remove the style, set the style to \"none\"\n- When using dynamic values in component props, use `sbComputed` with the correct pattern:\n - For scope entities (variables, APIs): `sbComputed(() => entityName.value)` (direct access)\n - For bound components: `sbComputed(() => ComponentName.property)` (direct access after binding)\n - For global access: `sbComputed(() => Global.user.name)` or `sbComputed(() => Theme.colors.primary)` (import globals from the library first: `import { Global, Theme, Embed, Env } from '@superblocksteam/library';`)\n- Use sbComputed ONLY when the value references dynamic data (state variables, API responses, component values, or theme)\n- Do NOT use sbComputed for static configuration like table columns, static dropdown options, or style objects that don't reference theme\n";
6
6
  //# sourceMappingURL=superblocks-components-rules.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-components-rules.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-components-rules.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,sDAAsD;AACtD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,s3EAAs3E,CAAC"}
1
+ {"version":3,"file":"superblocks-components-rules.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-components-rules.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,sDAAsD;AACtD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,4xFAA4xF,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const content = "# Custom Components\n\n- ULTRA CRITICAL: NEVER use Superblocks components in a custom component.\n\n- CRITICAL: Use custom components sparingly.\n\n- CRITICAL: ONLY when all else fails and a component is not available in the Superblocks library, you may construct it out of external component libraries by installing them.\n\n- CRITICAL: ALWAYS import React using a namespace import: `import * as React from 'react'`.\n\nIn order to hook it up correctly, the platform needs to know what props the component exposes, their types, default values, and how they should be displayed to users.\n\nTo do this, you use the **`Prop` API** and **`registerComponent`** function.\n\n## Key Concepts\n\n- All custom components should live within the `components/` folder.\n- **`Prop`**: Defines a single editable property for your component.\n - Can specify the data type (`string`, `number`, `boolean`, `event`, etc.).\n - Can define a **default value**, **label** for the properties panel, and other validations.\n- **`registerComponent`**: Connects your React component with its editable schema (`properties`) so it appears correctly in the visual editor.\n- **`useUpdateProperties`**: A hook that lets your component programmatically update its properties during runtime (e.g., when a user interacts with it).\n\n---\n\n## Basic Example\n\n```tsx\nimport { Rate } from \"antd\";\nimport {\n CustomComponentProps,\n Prop,\n registerComponent,\n useUpdateProperties,\n} from \"@superblocksteam/library\";\n\n// 1. Define editable properties\nconst properties = {\n value: Prop.number()\n .default(3) // Default to 3 stars\n .propertiesPanel({ label: \"Default value\" }), // Editor label\n onChange: Prop.event().propertiesPanel({ label: \"On change\" }), // Editor label for event\n};\n\n// 2. Create typed props for your component\ntype ComponentProps = CustomComponentProps<typeof properties>;\n\n// 3. Build your React component\nconst Rating = ({ value, onChange }: ComponentProps) => {\n const updateProperties = useUpdateProperties(); // Hook to update properties dynamically\n\n return (\n <div style={{ display: \"flex\" }}>\n <Rate\n value={value}\n defaultValue={value}\n onChange={(newValue) => {\n updateProperties({ value: newValue }); // Update visual editor\n onChange?.(); // Trigger custom event\n }}\n />\n </div>\n );\n};\n\n// 4. Register your component to make it available in the visual editor\nexport default registerComponent(\"Rating\", properties, Rating);\n```\n\n---\n\n## How `Prop` Works\n\nYou can define different types of props:\n\n- **`string`**: `Prop.string()`\n- **`number`**: `Prop.number()`\n- **`boolean`**: `Prop.boolean()`\n- **`event`**: `Prop.event()` (for user interactions like clicks)\n- **`any`**: `Prop.any()` (for any type)\n- **`composite`**: `Prop.composite({ x: Prop.number(), y: Prop.number() })` (for nested objects)\n- **`record`**: `Prop.record({...})` (for key-value maps)\n- **`union`**: `Prop.union({...})` (for multiple variants)\n\nYou can chain additional methods:\n\n- `.default(value)` \u2014 Sets a default value.\n- `.propertiesPanel({ label: \"Your Label\" })` \u2014 Controls how the prop appears in the editor.\n- `.validate(fn)` \u2014 Adds custom validation logic.\n- `.readable()`, `.writable()` \u2014 Control read/write capabilities.\n\n---\n\n## Typical Flow\n\n1. **Define** the **editable schema** (`properties`) with `Prop`.\n2. **Type** your component's props using `CustomComponentProps`.\n3. **Use** `useUpdateProperties` to sync UI interactions back to the editor.\n4. **Register** the component using `registerComponent`.\n\n---# Tips\n\n- All `registeredComponent`s automatically support width and height using the `Dim` object.\n ```\n <CustomSlider\n width={Dim.fill(2)} // Fill available space with a weight of 2\n height={Dim.px(100)} // Fixed height of 100 pixels\n />\n ```\n\n## When not to use custom components\n\n- If a user asks for something by name, like showing \"metrics\", and you do not find a \"metrics\" component in the Superblocks library, do not immediately assume you need to use a custom component. Instead consider using one of the pre-designed templates built from existing Superblocks components.\n\n## Pre-designed templates to use instead of custom components\n\n### Rules for using pre-designed templates\n\n- Use the pre-designed templates as a base to work from. You can make changes to the content, but generally you do not need to change the layout or styling. Example: below there are width and height properties set on the icons and you should NOT change these or you will break the layout.\n\n### Metrics template\n\nThis template is a row of three large numerical metrics with icons and annotation text.\n\nTemplate code below and a few notes to help explain usage:\n\n- We use the SbContainer component to layout the metrics in a row\n- We use the SbText component to show the numerical values and how we use the textStyle prop variant to make the text a big heading\n- We use the SbIcon component to show nice icons that make sense for the metric\n- We create a little \"badge\" using the SbContainer component to show small annotation text. Prefer this over using brackets in the main heading text. Example: Rather than \"32 (2m)\" we use \"32\" in the main heading text and then a badge with the \"2m\" text\n- Keep the icon sizing you see in this template unless you are explicitly asked to change it\n\n```tsx\nimport {\n SbIcon,\n SbText,\n SbContainer,\n sbComputed,\n Dim,\n Global,\n Theme,\n Embed,\n Env,\n} from \"@superblocksteam/library\";\n\n<SbContainer\n layout=\"horizontal\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"none\"\n spacing={Dim.px(12)}\n>\n {/* First card */}\n <SbContainer\n layout=\"vertical\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"card\"\n spacing={Dim.px(6)}\n >\n <SbContainer\n layout=\"horizontal\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"none\"\n horizontalAlign=\"space-between\"\n spacing={Dim.px(6)}\n >\n <SbText\n text=\"Avg delivery time (min)\"\n textStyle={{\n variant: \"body2\",\n textColor: {\n default: sbComputed(() => Theme.colors.neutral500),\n },\n }}\n />\n <SbIcon icon=\"route\" height={Dim.px(24)} width={Dim.fit()} />\n </SbContainer>\n <SbContainer\n layout=\"horizontal\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"none\"\n horizontalAlign=\"left\"\n spacing={Dim.px(6)}\n >\n <SbText\n text=\"32\"\n textStyle={{\n variant: \"heading1\",\n }}\n />\n {/* Smaller annotation badge, showing change. Container background color is green because the value change is considered \"good\" (lower delivery time is better) */}\n <SbContainer\n layout=\"horizontal\"\n width={Dim.fit()}\n height={Dim.fit()}\n variant=\"none\"\n spacing={Dim.px(2)}\n horizontalAlign=\"center\"\n verticalAlign=\"center\"\n backgroundColor=\"#c4e1af\"\n padding={{\n top: Dim.px(3),\n right: Dim.px(6),\n bottom: Dim.px(3),\n left: Dim.px(6),\n }}\n borderRadius={{\n topLeft: Dim.px(20),\n topRight: Dim.px(20),\n bottomRight: Dim.px(20),\n bottomLeft: Dim.px(20),\n }}\n >\n <SbIcon\n icon=\"arrow_downward_alt\"\n height={Dim.px(24)}\n width={Dim.fit()}\n />\n <SbText\n text=\"2m\"\n width={Dim.fit()}\n textStyle={{\n variant: \"body2\",\n }}\n />\n </SbContainer>\n </SbContainer>\n </SbContainer>\n</SbContainer>;\n```\n";
1
+ export declare const content = "# Custom Components\n\n- ULTRA CRITICAL: NEVER use Superblocks components in a custom component.\n\n- CRITICAL: Use custom components sparingly.\n\n- CRITICAL: ONLY when all else fails and a component is not available in the Superblocks library, you may construct it out of external component libraries by installing them.\n\n- CRITICAL: ALWAYS import React using a namespace import: `import * as React from 'react'`.\n\n## Default Custom Components\n\n- **IMPORTANT**: New Superblocks apps come with default custom components in the `components/` directory that provide common functionality not available in the core Superblocks library.\n\n- **USE THESE FIRST**: Before creating new custom components, check if existing default custom components in the `components/` directory can fulfill the user's requirements. These are likely to handle common use cases that users frequently request.\n\n- **PRESERVE INTERNALS**: Do NOT modify the internal implementation of default custom components (including their TypeScript/JavaScript code, CSS files, or other supporting files) unless the user explicitly asks you to change their internals. Instead, use them as-is with their existing API.\n\n- **COMMON PATTERN**: Many user requests that seem to require custom components can actually be fulfilled by using the existing default custom components that ship with new apps.\n\nIn order to hook it up correctly, the platform needs to know what props the component exposes, their types, default values, and how they should be displayed to users.\n\nTo do this, you use the **`Prop` API** and **`registerComponent`** function.\n\n## Key Concepts\n\n- All custom components should live within the `components/` folder.\n- **`Prop`**: Defines a single editable property for your component.\n - Can specify the data type (`string`, `number`, `boolean`, `event`, etc.).\n - Can define a **default value**, **label** for the properties panel, and other validations.\n- **`registerComponent`**: Connects your React component with its editable schema (`properties`) so it appears correctly in the visual editor.\n- **`useUpdateProperties`**: A hook that lets your component programmatically update its properties during runtime (e.g., when a user interacts with it).\n\n---\n\n## Basic Example\n\n```tsx\nimport { Rate } from \"antd\";\nimport {\n CustomComponentProps,\n Prop,\n registerComponent,\n useUpdateProperties,\n} from \"@superblocksteam/library\";\n\n// 1. Define editable properties\nconst properties = {\n value: Prop.number()\n .default(3) // Default to 3 stars\n .propertiesPanel({ label: \"Default value\" }), // Editor label\n onChange: Prop.event().propertiesPanel({ label: \"On change\" }), // Editor label for event\n};\n\n// 2. Create typed props for your component\ntype ComponentProps = CustomComponentProps<typeof properties>;\n\n// 3. Build your React component\nconst Rating = ({ value, onChange }: ComponentProps) => {\n const updateProperties = useUpdateProperties(); // Hook to update properties dynamically\n\n return (\n <div style={{ display: \"flex\" }}>\n <Rate\n value={value}\n defaultValue={value}\n onChange={(newValue) => {\n updateProperties({ value: newValue }); // Update visual editor\n onChange?.(); // Trigger custom event\n }}\n />\n </div>\n );\n};\n\n// 4. Register your component to make it available in the visual editor\nexport default registerComponent(\"Rating\", properties, Rating);\n```\n\n---\n\n## How `Prop` Works\n\nYou can define different types of props:\n\n- **`string`**: `Prop.string()`\n- **`number`**: `Prop.number()`\n- **`boolean`**: `Prop.boolean()`\n- **`event`**: `Prop.event()` (for user interactions like clicks)\n- **`any`**: `Prop.any()` (for any type)\n- **`composite`**: `Prop.composite({ x: Prop.number(), y: Prop.number() })` (for nested objects)\n- **`record`**: `Prop.record({...})` (for key-value maps)\n- **`union`**: `Prop.union({...})` (for multiple variants)\n\nYou can chain additional methods:\n\n- `.default(value)` \u2014 Sets a default value.\n- `.propertiesPanel({ label: \"Your Label\" })` \u2014 Controls how the prop appears in the editor.\n- `.validate(fn)` \u2014 Adds custom validation logic.\n- `.readable()`, `.writable()` \u2014 Control read/write capabilities.\n\n---\n\n## Typical Flow\n\n1. **Define** the **editable schema** (`properties`) with `Prop`.\n2. **Type** your component's props using `CustomComponentProps`.\n3. **Use** `useUpdateProperties` to sync UI interactions back to the editor.\n4. **Register** the component using `registerComponent`.\n\n---# Tips\n\n- All `registeredComponent`s automatically support width and height using the `Dim` object.\n ```\n <CustomSlider\n width={Dim.fill(2)} // Fill available space with a weight of 2\n height={Dim.px(100)} // Fixed height of 100 pixels\n />\n ```\n\n## When not to create a net new custom component\n\n- If a user asks for something by name, like showing \"metrics card\", and you do not find a \"metrics card\" component in the Superblocks library, be sure to check if an existing custom component exists that you can use inside the `/components` directory of the project.\n";
2
2
  //# sourceMappingURL=superblocks-custom-components.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-custom-components.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-custom-components.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,qvPAAiuP,CAAC"}
1
+ {"version":3,"file":"superblocks-custom-components.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-custom-components.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,2mKAAulK,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  // Auto-generated from superblocks-custom-components.md
3
3
  // Do not edit this file directly
4
- // Generated at: 2025-06-15T06:08:09.959Z
5
- export const content = "# Custom Components\n\n- ULTRA CRITICAL: NEVER use Superblocks components in a custom component.\n\n- CRITICAL: Use custom components sparingly.\n\n- CRITICAL: ONLY when all else fails and a component is not available in the Superblocks library, you may construct it out of external component libraries by installing them.\n\n- CRITICAL: ALWAYS import React using a namespace import: `import * as React from 'react'`.\n\nIn order to hook it up correctly, the platform needs to know what props the component exposes, their types, default values, and how they should be displayed to users.\n\nTo do this, you use the **`Prop` API** and **`registerComponent`** function.\n\n## Key Concepts\n\n- All custom components should live within the `components/` folder.\n- **`Prop`**: Defines a single editable property for your component.\n - Can specify the data type (`string`, `number`, `boolean`, `event`, etc.).\n - Can define a **default value**, **label** for the properties panel, and other validations.\n- **`registerComponent`**: Connects your React component with its editable schema (`properties`) so it appears correctly in the visual editor.\n- **`useUpdateProperties`**: A hook that lets your component programmatically update its properties during runtime (e.g., when a user interacts with it).\n\n---\n\n## Basic Example\n\n```tsx\nimport { Rate } from \"antd\";\nimport {\n CustomComponentProps,\n Prop,\n registerComponent,\n useUpdateProperties,\n} from \"@superblocksteam/library\";\n\n// 1. Define editable properties\nconst properties = {\n value: Prop.number()\n .default(3) // Default to 3 stars\n .propertiesPanel({ label: \"Default value\" }), // Editor label\n onChange: Prop.event().propertiesPanel({ label: \"On change\" }), // Editor label for event\n};\n\n// 2. Create typed props for your component\ntype ComponentProps = CustomComponentProps<typeof properties>;\n\n// 3. Build your React component\nconst Rating = ({ value, onChange }: ComponentProps) => {\n const updateProperties = useUpdateProperties(); // Hook to update properties dynamically\n\n return (\n <div style={{ display: \"flex\" }}>\n <Rate\n value={value}\n defaultValue={value}\n onChange={(newValue) => {\n updateProperties({ value: newValue }); // Update visual editor\n onChange?.(); // Trigger custom event\n }}\n />\n </div>\n );\n};\n\n// 4. Register your component to make it available in the visual editor\nexport default registerComponent(\"Rating\", properties, Rating);\n```\n\n---\n\n## How `Prop` Works\n\nYou can define different types of props:\n\n- **`string`**: `Prop.string()`\n- **`number`**: `Prop.number()`\n- **`boolean`**: `Prop.boolean()`\n- **`event`**: `Prop.event()` (for user interactions like clicks)\n- **`any`**: `Prop.any()` (for any type)\n- **`composite`**: `Prop.composite({ x: Prop.number(), y: Prop.number() })` (for nested objects)\n- **`record`**: `Prop.record({...})` (for key-value maps)\n- **`union`**: `Prop.union({...})` (for multiple variants)\n\nYou can chain additional methods:\n\n- `.default(value)` — Sets a default value.\n- `.propertiesPanel({ label: \"Your Label\" })` — Controls how the prop appears in the editor.\n- `.validate(fn)` — Adds custom validation logic.\n- `.readable()`, `.writable()` — Control read/write capabilities.\n\n---\n\n## Typical Flow\n\n1. **Define** the **editable schema** (`properties`) with `Prop`.\n2. **Type** your component's props using `CustomComponentProps`.\n3. **Use** `useUpdateProperties` to sync UI interactions back to the editor.\n4. **Register** the component using `registerComponent`.\n\n---# Tips\n\n- All `registeredComponent`s automatically support width and height using the `Dim` object.\n ```\n <CustomSlider\n width={Dim.fill(2)} // Fill available space with a weight of 2\n height={Dim.px(100)} // Fixed height of 100 pixels\n />\n ```\n\n## When not to use custom components\n\n- If a user asks for something by name, like showing \"metrics\", and you do not find a \"metrics\" component in the Superblocks library, do not immediately assume you need to use a custom component. Instead consider using one of the pre-designed templates built from existing Superblocks components.\n\n## Pre-designed templates to use instead of custom components\n\n### Rules for using pre-designed templates\n\n- Use the pre-designed templates as a base to work from. You can make changes to the content, but generally you do not need to change the layout or styling. Example: below there are width and height properties set on the icons and you should NOT change these or you will break the layout.\n\n### Metrics template\n\nThis template is a row of three large numerical metrics with icons and annotation text.\n\nTemplate code below and a few notes to help explain usage:\n\n- We use the SbContainer component to layout the metrics in a row\n- We use the SbText component to show the numerical values and how we use the textStyle prop variant to make the text a big heading\n- We use the SbIcon component to show nice icons that make sense for the metric\n- We create a little \"badge\" using the SbContainer component to show small annotation text. Prefer this over using brackets in the main heading text. Example: Rather than \"32 (2m)\" we use \"32\" in the main heading text and then a badge with the \"2m\" text\n- Keep the icon sizing you see in this template unless you are explicitly asked to change it\n\n```tsx\nimport {\n SbIcon,\n SbText,\n SbContainer,\n sbComputed,\n Dim,\n Global,\n Theme,\n Embed,\n Env,\n} from \"@superblocksteam/library\";\n\n<SbContainer\n layout=\"horizontal\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"none\"\n spacing={Dim.px(12)}\n>\n {/* First card */}\n <SbContainer\n layout=\"vertical\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"card\"\n spacing={Dim.px(6)}\n >\n <SbContainer\n layout=\"horizontal\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"none\"\n horizontalAlign=\"space-between\"\n spacing={Dim.px(6)}\n >\n <SbText\n text=\"Avg delivery time (min)\"\n textStyle={{\n variant: \"body2\",\n textColor: {\n default: sbComputed(() => Theme.colors.neutral500),\n },\n }}\n />\n <SbIcon icon=\"route\" height={Dim.px(24)} width={Dim.fit()} />\n </SbContainer>\n <SbContainer\n layout=\"horizontal\"\n width={Dim.fill()}\n height={Dim.fit()}\n variant=\"none\"\n horizontalAlign=\"left\"\n spacing={Dim.px(6)}\n >\n <SbText\n text=\"32\"\n textStyle={{\n variant: \"heading1\",\n }}\n />\n {/* Smaller annotation badge, showing change. Container background color is green because the value change is considered \"good\" (lower delivery time is better) */}\n <SbContainer\n layout=\"horizontal\"\n width={Dim.fit()}\n height={Dim.fit()}\n variant=\"none\"\n spacing={Dim.px(2)}\n horizontalAlign=\"center\"\n verticalAlign=\"center\"\n backgroundColor=\"#c4e1af\"\n padding={{\n top: Dim.px(3),\n right: Dim.px(6),\n bottom: Dim.px(3),\n left: Dim.px(6),\n }}\n borderRadius={{\n topLeft: Dim.px(20),\n topRight: Dim.px(20),\n bottomRight: Dim.px(20),\n bottomLeft: Dim.px(20),\n }}\n >\n <SbIcon\n icon=\"arrow_downward_alt\"\n height={Dim.px(24)}\n width={Dim.fit()}\n />\n <SbText\n text=\"2m\"\n width={Dim.fit()}\n textStyle={{\n variant: \"body2\",\n }}\n />\n </SbContainer>\n </SbContainer>\n </SbContainer>\n</SbContainer>;\n```\n";
4
+ // Generated at: 2025-06-23T03:26:44.022Z
5
+ export const content = "# Custom Components\n\n- ULTRA CRITICAL: NEVER use Superblocks components in a custom component.\n\n- CRITICAL: Use custom components sparingly.\n\n- CRITICAL: ONLY when all else fails and a component is not available in the Superblocks library, you may construct it out of external component libraries by installing them.\n\n- CRITICAL: ALWAYS import React using a namespace import: `import * as React from 'react'`.\n\n## Default Custom Components\n\n- **IMPORTANT**: New Superblocks apps come with default custom components in the `components/` directory that provide common functionality not available in the core Superblocks library.\n\n- **USE THESE FIRST**: Before creating new custom components, check if existing default custom components in the `components/` directory can fulfill the user's requirements. These are likely to handle common use cases that users frequently request.\n\n- **PRESERVE INTERNALS**: Do NOT modify the internal implementation of default custom components (including their TypeScript/JavaScript code, CSS files, or other supporting files) unless the user explicitly asks you to change their internals. Instead, use them as-is with their existing API.\n\n- **COMMON PATTERN**: Many user requests that seem to require custom components can actually be fulfilled by using the existing default custom components that ship with new apps.\n\nIn order to hook it up correctly, the platform needs to know what props the component exposes, their types, default values, and how they should be displayed to users.\n\nTo do this, you use the **`Prop` API** and **`registerComponent`** function.\n\n## Key Concepts\n\n- All custom components should live within the `components/` folder.\n- **`Prop`**: Defines a single editable property for your component.\n - Can specify the data type (`string`, `number`, `boolean`, `event`, etc.).\n - Can define a **default value**, **label** for the properties panel, and other validations.\n- **`registerComponent`**: Connects your React component with its editable schema (`properties`) so it appears correctly in the visual editor.\n- **`useUpdateProperties`**: A hook that lets your component programmatically update its properties during runtime (e.g., when a user interacts with it).\n\n---\n\n## Basic Example\n\n```tsx\nimport { Rate } from \"antd\";\nimport {\n CustomComponentProps,\n Prop,\n registerComponent,\n useUpdateProperties,\n} from \"@superblocksteam/library\";\n\n// 1. Define editable properties\nconst properties = {\n value: Prop.number()\n .default(3) // Default to 3 stars\n .propertiesPanel({ label: \"Default value\" }), // Editor label\n onChange: Prop.event().propertiesPanel({ label: \"On change\" }), // Editor label for event\n};\n\n// 2. Create typed props for your component\ntype ComponentProps = CustomComponentProps<typeof properties>;\n\n// 3. Build your React component\nconst Rating = ({ value, onChange }: ComponentProps) => {\n const updateProperties = useUpdateProperties(); // Hook to update properties dynamically\n\n return (\n <div style={{ display: \"flex\" }}>\n <Rate\n value={value}\n defaultValue={value}\n onChange={(newValue) => {\n updateProperties({ value: newValue }); // Update visual editor\n onChange?.(); // Trigger custom event\n }}\n />\n </div>\n );\n};\n\n// 4. Register your component to make it available in the visual editor\nexport default registerComponent(\"Rating\", properties, Rating);\n```\n\n---\n\n## How `Prop` Works\n\nYou can define different types of props:\n\n- **`string`**: `Prop.string()`\n- **`number`**: `Prop.number()`\n- **`boolean`**: `Prop.boolean()`\n- **`event`**: `Prop.event()` (for user interactions like clicks)\n- **`any`**: `Prop.any()` (for any type)\n- **`composite`**: `Prop.composite({ x: Prop.number(), y: Prop.number() })` (for nested objects)\n- **`record`**: `Prop.record({...})` (for key-value maps)\n- **`union`**: `Prop.union({...})` (for multiple variants)\n\nYou can chain additional methods:\n\n- `.default(value)` — Sets a default value.\n- `.propertiesPanel({ label: \"Your Label\" })` — Controls how the prop appears in the editor.\n- `.validate(fn)` — Adds custom validation logic.\n- `.readable()`, `.writable()` — Control read/write capabilities.\n\n---\n\n## Typical Flow\n\n1. **Define** the **editable schema** (`properties`) with `Prop`.\n2. **Type** your component's props using `CustomComponentProps`.\n3. **Use** `useUpdateProperties` to sync UI interactions back to the editor.\n4. **Register** the component using `registerComponent`.\n\n---# Tips\n\n- All `registeredComponent`s automatically support width and height using the `Dim` object.\n ```\n <CustomSlider\n width={Dim.fill(2)} // Fill available space with a weight of 2\n height={Dim.px(100)} // Fixed height of 100 pixels\n />\n ```\n\n## When not to create a net new custom component\n\n- If a user asks for something by name, like showing \"metrics card\", and you do not find a \"metrics card\" component in the Superblocks library, be sure to check if an existing custom component exists that you can use inside the `/components` directory of the project.\n";
6
6
  //# sourceMappingURL=superblocks-custom-components.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-custom-components.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-custom-components.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,uDAAuD;AACvD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,8tPAA8tP,CAAC"}
1
+ {"version":3,"file":"superblocks-custom-components.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-custom-components.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,uDAAuD;AACvD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,olKAAolK,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const content = "# Data Filtering Best Practices\n\nWhen filtering data from APIs or state variables, follow these patterns to keep component properties clean and maintainable:\n\n## When to Use Reactive State Variables for Filtering\n\n**Use reactive state variables with `defaultValue` for complex filtering when:**\n\n- The filtering logic is more than 1-2 lines of code\n- Multiple conditions need to be evaluated\n- Multiple form controls affect the same filtered dataset\n- The logic would make component properties hard to read in the visual editor\n\n**Keep simple filtering in component properties when:**\n\n- The filtering is 1-2 lines of basic logic\n- It's a straightforward filter operation\n- Only one control affects the filtering\n\n## Good Pattern: Reactive State Variables with defaultValue\n\n```tsx\n// First, define component bindings in scope.ts\nexport const Page1Scope = createSbScope<{\n OrderSearchInput: any;\n StatusFilterDropdown: any;\n DateFromPicker: any;\n DateToPicker: any;\n}>(\n ({ entities: { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, getOrders } }) => ({\n getOrders: SbApi({}),\n // Define reactive state variable with complex filtering logic in defaultValue\n filteredOrders: SbVariable({\n defaultValue: sbComputed(() => {\n return getOrders.response?.filter(order => {\n const matchesSearch = OrderSearchInput.value === '' ||\n order.customerName.toLowerCase().includes(OrderSearchInput.value.toLowerCase()) ||\n order.id.toLowerCase().includes(OrderSearchInput.value.toLowerCase());\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n order.status === StatusFilterDropdown.selectedOptionValue;\n const matchesDateRange = !DateFromPicker.value || !DateToPicker.value ||\n (new Date(order.orderDate) >= new Date(DateFromPicker.value) &&\n new Date(order.orderDate) <= new Date(DateToPicker.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use bind properties\nconst { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, filteredOrders } = Page1;\n\n// Clean component properties - just reference the reactive state variable\n<SbTable tableData={sbComputed(() => filteredOrders.value)} />\n\n// Form controls use bind properties - no onChange logic needed\n<SbInput\n bind={OrderSearchInput}\n placeholder=\"Search orders...\"\n/>\n\n<SbDropdown\n bind={StatusFilterDropdown}\n options={[\n { value: 'All', label: 'All Statuses' },\n { value: 'Processing', label: 'Processing' },\n { value: 'Shipped', label: 'Shipped' },\n { value: 'Delivered', label: 'Delivered' }\n ]}\n/>\n\n<SbDatePicker bind={DateFromPicker} />\n<SbDatePicker bind={DateToPicker} />\n```\n\n## Bad Pattern: Duplicated Filtering Logic in Event Handlers\n\n```tsx\n// Avoid this - duplicates filtering logic in every event handler\n<SbInput\n placeholder=\"Search orders...\"\n onChange={SbEventFlow([\n (value) => {\n const filtered = getOrders.response?.filter(order => {\n const matchesSearch = value === '' ||\n order.customerName.toLowerCase().includes(value.toLowerCase()) ||\n order.id.toLowerCase().includes(value.toLowerCase());\n const matchesStatus = statusFilter.value === 'All' || order.status === statusFilter.value;\n const matchesDateRange = !dateFrom.value || !dateTo.value ||\n (new Date(order.orderDate) >= new Date(dateFrom.value) &&\n new Date(order.orderDate) <= new Date(dateTo.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n filteredOrders.setValue(filtered);\n }\n ])}\n/>\n\n<SbDropdown\n onChange={SbEventFlow([\n (value) => {\n // Same filtering logic repeated here - this is what we want to avoid\n const filtered = getOrders.response?.filter(order => {\n const matchesSearch = searchTerm.value === '' ||\n order.customerName.toLowerCase().includes(searchTerm.value.toLowerCase());\n const matchesStatus = value === 'All' || order.status === value;\n return matchesSearch && matchesStatus;\n }) || [];\n filteredOrders.setValue(filtered);\n }\n ])}\n/>\n```\n\n## Bad Pattern: Complex Filtering in Component Properties\n\n```tsx\n// Avoid this - complex logic in component property makes visual editor cluttered\n<SbTable\n tableData={sbComputed(\n () =>\n getOrders.response?.filter((order) => {\n const matchesSearch =\n searchTerm.value === \"\" ||\n order.customerName\n .toLowerCase()\n .includes(searchTerm.value.toLowerCase()) ||\n order.id.toLowerCase().includes(searchTerm.value.toLowerCase());\n const matchesStatus =\n statusFilter.value === \"All\" || order.status === statusFilter.value;\n const matchesDateRange =\n !dateFrom.value ||\n !dateTo.value ||\n (new Date(order.orderDate) >= new Date(dateFrom.value) &&\n new Date(order.orderDate) <= new Date(dateTo.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [],\n )}\n/>\n```\n\n## Acceptable: Simple Filtering in Component Properties\n\n```tsx\n// This is fine - simple, straightforward filtering\n<SbTable tableData={sbComputed(() => getOrders.response?.filter(order => order.status === 'Active') || [])} />\n<SbText text={sbComputed(() => `Total: ${getOrders.response?.length || 0}`)} />\n```\n\n## Pattern for Non-Table Components\n\nThis pattern applies to all components, not just tables:\n\n```tsx\n// In scope.ts - define component binding and reactive state variable\nexport const Page1Scope = createSbScope<{\n CategoryDropdown: any;\n}>(\n ({ entities: { CategoryDropdown } }) => ({\n rawData: SbVariable({ defaultValue: [] }),\n // Good: Complex calculation in reactive state variable\n summaryText: SbVariable({\n defaultValue: sbComputed(() => {\n const filteredData = rawData.value?.filter(item => item.category === CategoryDropdown.selectedOptionValue) || [];\n const total = filteredData.reduce((sum, item) => sum + item.amount, 0);\n const average = filteredData.length > 0 ? total / filteredData.length : 0;\n return `${CategoryDropdown.selectedOptionValue} category: ${filteredData.length} items, Total: $${total.toFixed(2)}, Average: $${average.toFixed(2)}`;\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In component - destructure and use bind\nconst { CategoryDropdown, summaryText } = Page1;\n\n// Clean component property - just references reactive state variable\n<SbText text={sbComputed(() => summaryText.value)} />\n\n// Form control uses bind property - no onChange needed\n<SbDropdown\n bind={CategoryDropdown}\n options={[\n { value: 'Electronics', label: 'Electronics' },\n { value: 'Clothing', label: 'Clothing' },\n { value: 'Books', label: 'Books' }\n ]}\n/>\n```\n\n## Dynamic Dropdown Options from API Data\n\nWhen you need to create dropdown filters based on actual values from your API response (like filtering by status, category, type, etc.), extract the unique values from the API data to populate dropdown options dynamically.\n\n**Use this pattern when:**\n\n- You want to filter on a property that exists in your API data\n- The possible values for that property are not known in advance\n- You want the dropdown to show only values that actually exist in the data\n\n```tsx\n// In scope.ts - define component bindings and reactive state variables\nexport const Page1Scope = createSbScope<{\n StatusFilterDropdown: any;\n CategoryFilterDropdown: any;\n}>(\n ({ entities: { StatusFilterDropdown, CategoryFilterDropdown, getProducts } }) => ({\n getProducts: SbApi({}),\n\n // Generate unique status options from API data\n statusOptions: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProducts.response) return [{ value: 'All', label: 'All Statuses' }];\n\n const uniqueStatuses = [...new Set(getProducts.response.map(product => product.status))]\n .filter(status => status) // Remove any null/undefined values\n .sort()\n .map(status => ({ value: status, label: status }));\n\n return [{ value: 'All', label: 'All Statuses' }, ...uniqueStatuses];\n })\n }),\n\n // Generate unique category options from API data\n categoryOptions: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProducts.response) return [{ value: 'All', label: 'All Categories' }];\n\n const uniqueCategories = [...new Set(getProducts.response.map(product => product.category))]\n .filter(category => category) // Remove any null/undefined values\n .sort()\n .map(category => ({ value: category, label: category }));\n\n return [{ value: 'All', label: 'All Categories' }, ...uniqueCategories];\n })\n }),\n\n // Filtered data based on both dropdowns\n filteredProducts: SbVariable({\n defaultValue: sbComputed(() => {\n return getProducts.response?.filter(product => {\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n product.status === StatusFilterDropdown.selectedOptionValue;\n const matchesCategory = CategoryFilterDropdown.selectedOptionValue === 'All' ||\n product.category === CategoryFilterDropdown.selectedOptionValue;\n return matchesStatus && matchesCategory;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use\nconst { StatusFilterDropdown, CategoryFilterDropdown, statusOptions, categoryOptions, filteredProducts } = Page1;\n\n// Dropdowns with dynamic options from API data\n<SbDropdown\n bind={StatusFilterDropdown}\n options={sbComputed(() => statusOptions.value)}\n defaultValue=\"All\"\n/>\n\n<SbDropdown\n bind={CategoryFilterDropdown}\n options={sbComputed(() => categoryOptions.value)}\n defaultValue=\"All\"\n/>\n\n// Table showing filtered results\n<SbTable tableData={sbComputed(() => filteredProducts.value)} />\n```\n\n**Key points:**\n\n- Always include an \"All\" option as the first option\n- Use `new Set()` to get unique values from the API response\n- Filter out null/undefined values to avoid empty options\n- Sort the options alphabetically for better UX\n- The dropdown options are reactive - they update when the API data changes\n- Use `bind` properties on dropdowns so that the bind entities you set up in the scope file update automatically when the dropdown values change\n- Default to \"All\" to show all data initially\n";
1
+ export declare const content = "# Data Filtering Best Practices\n\n**\uD83D\uDEA8 CRITICAL: When implementing data filtering, remember that sbComputed cannot be used as React children.** All dynamic filtered content must be passed to component properties like `tableData={}`, `text={}`, etc. Never use `{sbComputed(...)}` as children.\n\nWhen filtering data from APIs or state variables, follow these patterns to keep component properties clean and maintainable:\n\n## When to Use Reactive State Variables for Filtering\n\n**Use reactive state variables with `defaultValue` for complex filtering when:**\n\n- The filtering logic is more than 1-2 lines of code\n- Multiple conditions need to be evaluated\n- Multiple form controls affect the same filtered dataset\n- The logic would make component properties hard to read in the visual editor\n\n**Keep simple filtering in component properties when:**\n\n- The filtering is 1-2 lines of basic logic\n- It's a straightforward filter operation\n- Only one control affects the filtering\n\n## Good Pattern: Reactive State Variables with defaultValue\n\n```tsx\n// First, define component bindings in scope.ts\nexport const Page1Scope = createSbScope<{\n OrderSearchInput: any;\n StatusFilterDropdown: any;\n DateFromPicker: any;\n DateToPicker: any;\n}>(\n ({ entities: { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, getOrdersApi } }) => ({\n getOrdersApi: SbApi({}),\n // Define reactive state variable with complex filtering logic in defaultValue\n filteredOrdersVar: SbVariable({\n defaultValue: sbComputed(() => {\n return getOrdersApi.response?.filter(order => {\n const matchesSearch = OrderSearchInput.value === '' ||\n order.customerName.toLowerCase().includes(OrderSearchInput.value.toLowerCase()) ||\n order.id.toLowerCase().includes(OrderSearchInput.value.toLowerCase());\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n order.status === StatusFilterDropdown.selectedOptionValue;\n const matchesDateRange = !DateFromPicker.value || !DateToPicker.value ||\n (new Date(order.orderDate) >= new Date(DateFromPicker.value) &&\n new Date(order.orderDate) <= new Date(DateToPicker.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use bind properties\nconst { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, filteredOrdersVar } = Page1;\n\n// Clean component properties - just reference the reactive state variable\n<SbTable tableData={sbComputed(() => filteredOrdersVar.value)} />\n\n// Form controls use bind properties - no onChange logic needed\n<SbInput\n bind={OrderSearchInput}\n placeholder=\"Search orders...\"\n/>\n\n<SbDropdown\n bind={StatusFilterDropdown}\n options={[\n { value: 'All', label: 'All Statuses' },\n { value: 'Processing', label: 'Processing' },\n { value: 'Shipped', label: 'Shipped' },\n { value: 'Delivered', label: 'Delivered' }\n ]}\n/>\n\n<SbDatePicker bind={DateFromPicker} />\n<SbDatePicker bind={DateToPicker} />\n```\n\n## Bad Pattern: Duplicated Filtering Logic in Event Handlers\n\n```tsx\n// Avoid this - duplicates filtering logic in every event handler\n<SbInput\n placeholder=\"Search orders...\"\n onChange={SbEventFlow([\n (value) => {\n const filtered = getOrdersApi.response?.filter(order => {\n const matchesSearch = value === '' ||\n order.customerName.toLowerCase().includes(value.toLowerCase()) ||\n order.id.toLowerCase().includes(value.toLowerCase());\n const matchesStatus = statusFilterVar.value === 'All' || order.status === statusFilterVar.value;\n const matchesDateRange = !dateFromVar.value || !dateToVar.value ||\n (new Date(order.orderDate) >= new Date(dateFromVar.value) &&\n new Date(order.orderDate) <= new Date(dateToVar.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n filteredOrdersVar.setValue(filtered);\n }\n ])}\n/>\n\n<SbDropdown\n onChange={SbEventFlow([\n (value) => {\n // Same filtering logic repeated here - this is what we want to avoid\n const filtered = getOrdersApi.response?.filter(order => {\n const matchesSearch = searchTermVar.value === '' ||\n order.customerName.toLowerCase().includes(searchTermVar.value.toLowerCase());\n const matchesStatus = value === 'All' || order.status === value;\n return matchesSearch && matchesStatus;\n }) || [];\n filteredOrdersVar.setValue(filtered);\n }\n ])}\n/>\n```\n\n## Bad Pattern: Complex Filtering in Component Properties\n\n```tsx\n// Avoid this - complex logic in component property makes visual editor cluttered\n<SbTable\n tableData={sbComputed(\n () =>\n getOrdersApi.response?.filter((order) => {\n const matchesSearch =\n searchTermVar.value === \"\" ||\n order.customerName\n .toLowerCase()\n .includes(searchTermVar.value.toLowerCase()) ||\n order.id.toLowerCase().includes(searchTermVar.value.toLowerCase());\n const matchesStatus =\n statusFilterVar.value === \"All\" ||\n order.status === statusFilterVar.value;\n const matchesDateRange =\n !dateFromVar.value ||\n !dateToVar.value ||\n (new Date(order.orderDate) >= new Date(dateFromVar.value) &&\n new Date(order.orderDate) <= new Date(dateToVar.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [],\n )}\n/>\n```\n\n## Acceptable: Simple Filtering in Component Properties\n\n```tsx\n// This is fine - simple, straightforward filtering\n<SbTable tableData={sbComputed(() => getOrdersApi.response?.filter(order => order.status === 'Active') || [])} />\n<SbText text={sbComputed(() => `Total: ${getOrdersApi.response?.length || 0}`)} />\n```\n\n## Pattern for Non-Table Components\n\nThis pattern applies to all components, not just tables:\n\n```tsx\n// In scope.ts - define component binding and reactive state variable\nexport const Page1Scope = createSbScope<{\n CategoryDropdown: any;\n}>(\n ({ entities: { CategoryDropdown } }) => ({\n rawDataVar: SbVariable({ defaultValue: [] }),\n // Good: Complex calculation in reactive state variable\n summaryTextVar: SbVariable({\n defaultValue: sbComputed(() => {\n const filteredData = rawDataVar.value?.filter(item => item.category === CategoryDropdown.selectedOptionValue) || [];\n const total = filteredData.reduce((sum, item) => sum + item.amount, 0);\n const average = filteredData.length > 0 ? total / filteredData.length : 0;\n return `${CategoryDropdown.selectedOptionValue} category: ${filteredData.length} items, Total: $${total.toFixed(2)}, Average: $${average.toFixed(2)}`;\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In component - destructure and use bind\nconst { CategoryDropdown, summaryTextVar } = Page1;\n\n// Clean component property - just references reactive state variable\n<SbText text={sbComputed(() => summaryTextVar.value)} />\n\n// Form control uses bind property - no onChange needed\n<SbDropdown\n bind={CategoryDropdown}\n options={[\n { value: 'Electronics', label: 'Electronics' },\n { value: 'Clothing', label: 'Clothing' },\n { value: 'Books', label: 'Books' }\n ]}\n/>\n```\n\n## Dynamic Dropdown Options from API Data\n\nWhen you need to create dropdown filters based on actual values from your API response (like filtering by status, category, type, etc.), extract the unique values from the API data to populate dropdown options dynamically.\n\n**Use this pattern when:**\n\n- You want to filter on a property that exists in your API data\n- The possible values for that property are not known in advance\n- You want the dropdown to show only values that actually exist in the data\n\n```tsx\n// In scope.ts - define component bindings and reactive state variables\nexport const Page1Scope = createSbScope<{\n StatusFilterDropdown: any;\n CategoryFilterDropdown: any;\n}>(\n ({ entities: { StatusFilterDropdown, CategoryFilterDropdown, getProductsApi } }) => ({\n getProductsApi: SbApi({}),\n\n // Generate unique status options from API data\n statusOptionsVar: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProductsApi.response) return [{ value: 'All', label: 'All Statuses' }];\n\n const uniqueStatuses = [...new Set(getProductsApi.response.map(product => product.status))]\n .filter(status => status) // Remove any null/undefined values\n .sort()\n .map(status => ({ value: status, label: status }));\n\n return [{ value: 'All', label: 'All Statuses' }, ...uniqueStatuses];\n })\n }),\n\n // Generate unique category options from API data\n categoryOptionsVar: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProductsApi.response) return [{ value: 'All', label: 'All Categories' }];\n\n const uniqueCategories = [...new Set(getProductsApi.response.map(product => product.category))]\n .filter(category => category) // Remove any null/undefined values\n .sort()\n .map(category => ({ value: category, label: category }));\n\n return [{ value: 'All', label: 'All Categories' }, ...uniqueCategories];\n })\n }),\n\n // Filtered data based on both dropdowns\n filteredProductsVar: SbVariable({\n defaultValue: sbComputed(() => {\n return getProductsApi.response?.filter(product => {\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n product.status === StatusFilterDropdown.selectedOptionValue;\n const matchesCategory = CategoryFilterDropdown.selectedOptionValue === 'All' ||\n product.category === CategoryFilterDropdown.selectedOptionValue;\n return matchesStatus && matchesCategory;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use\nconst { StatusFilterDropdown, CategoryFilterDropdown, statusOptionsVar, categoryOptionsVar, filteredProductsVar } = Page1;\n\n// Dropdowns with dynamic options from API data\n<SbDropdown\n bind={StatusFilterDropdown}\n options={sbComputed(() => statusOptionsVar.value)}\n defaultValue=\"All\"\n/>\n\n<SbDropdown\n bind={CategoryFilterDropdown}\n options={sbComputed(() => categoryOptionsVar.value)}\n defaultValue=\"All\"\n/>\n\n// Table showing filtered results\n<SbTable tableData={sbComputed(() => filteredProductsVar.value)} />\n```\n\n**Key points:**\n\n- Always include an \"All\" option as the first option\n- Use `new Set()` to get unique values from the API response\n- Filter out null/undefined values to avoid empty options\n- Sort the options alphabetically for better UX\n- The dropdown options are reactive - they update when the API data changes\n- Use `bind` properties on dropdowns so that the bind entities you set up in the scope file update automatically when the dropdown values change\n- Default to \"All\" to show all data initially\n";
2
2
  //# sourceMappingURL=superblocks-data-filtering.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-data-filtering.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-data-filtering.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,gnVAAgnV,CAAC"}
1
+ {"version":3,"file":"superblocks-data-filtering.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-data-filtering.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,miWAAyhW,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  // Auto-generated from superblocks-data-filtering.md
3
3
  // Do not edit this file directly
4
- // Generated at: 2025-06-15T06:08:09.959Z
5
- export const content = "# Data Filtering Best Practices\n\nWhen filtering data from APIs or state variables, follow these patterns to keep component properties clean and maintainable:\n\n## When to Use Reactive State Variables for Filtering\n\n**Use reactive state variables with `defaultValue` for complex filtering when:**\n\n- The filtering logic is more than 1-2 lines of code\n- Multiple conditions need to be evaluated\n- Multiple form controls affect the same filtered dataset\n- The logic would make component properties hard to read in the visual editor\n\n**Keep simple filtering in component properties when:**\n\n- The filtering is 1-2 lines of basic logic\n- It's a straightforward filter operation\n- Only one control affects the filtering\n\n## Good Pattern: Reactive State Variables with defaultValue\n\n```tsx\n// First, define component bindings in scope.ts\nexport const Page1Scope = createSbScope<{\n OrderSearchInput: any;\n StatusFilterDropdown: any;\n DateFromPicker: any;\n DateToPicker: any;\n}>(\n ({ entities: { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, getOrders } }) => ({\n getOrders: SbApi({}),\n // Define reactive state variable with complex filtering logic in defaultValue\n filteredOrders: SbVariable({\n defaultValue: sbComputed(() => {\n return getOrders.response?.filter(order => {\n const matchesSearch = OrderSearchInput.value === '' ||\n order.customerName.toLowerCase().includes(OrderSearchInput.value.toLowerCase()) ||\n order.id.toLowerCase().includes(OrderSearchInput.value.toLowerCase());\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n order.status === StatusFilterDropdown.selectedOptionValue;\n const matchesDateRange = !DateFromPicker.value || !DateToPicker.value ||\n (new Date(order.orderDate) >= new Date(DateFromPicker.value) &&\n new Date(order.orderDate) <= new Date(DateToPicker.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use bind properties\nconst { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, filteredOrders } = Page1;\n\n// Clean component properties - just reference the reactive state variable\n<SbTable tableData={sbComputed(() => filteredOrders.value)} />\n\n// Form controls use bind properties - no onChange logic needed\n<SbInput\n bind={OrderSearchInput}\n placeholder=\"Search orders...\"\n/>\n\n<SbDropdown\n bind={StatusFilterDropdown}\n options={[\n { value: 'All', label: 'All Statuses' },\n { value: 'Processing', label: 'Processing' },\n { value: 'Shipped', label: 'Shipped' },\n { value: 'Delivered', label: 'Delivered' }\n ]}\n/>\n\n<SbDatePicker bind={DateFromPicker} />\n<SbDatePicker bind={DateToPicker} />\n```\n\n## Bad Pattern: Duplicated Filtering Logic in Event Handlers\n\n```tsx\n// Avoid this - duplicates filtering logic in every event handler\n<SbInput\n placeholder=\"Search orders...\"\n onChange={SbEventFlow([\n (value) => {\n const filtered = getOrders.response?.filter(order => {\n const matchesSearch = value === '' ||\n order.customerName.toLowerCase().includes(value.toLowerCase()) ||\n order.id.toLowerCase().includes(value.toLowerCase());\n const matchesStatus = statusFilter.value === 'All' || order.status === statusFilter.value;\n const matchesDateRange = !dateFrom.value || !dateTo.value ||\n (new Date(order.orderDate) >= new Date(dateFrom.value) &&\n new Date(order.orderDate) <= new Date(dateTo.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n filteredOrders.setValue(filtered);\n }\n ])}\n/>\n\n<SbDropdown\n onChange={SbEventFlow([\n (value) => {\n // Same filtering logic repeated here - this is what we want to avoid\n const filtered = getOrders.response?.filter(order => {\n const matchesSearch = searchTerm.value === '' ||\n order.customerName.toLowerCase().includes(searchTerm.value.toLowerCase());\n const matchesStatus = value === 'All' || order.status === value;\n return matchesSearch && matchesStatus;\n }) || [];\n filteredOrders.setValue(filtered);\n }\n ])}\n/>\n```\n\n## Bad Pattern: Complex Filtering in Component Properties\n\n```tsx\n// Avoid this - complex logic in component property makes visual editor cluttered\n<SbTable\n tableData={sbComputed(\n () =>\n getOrders.response?.filter((order) => {\n const matchesSearch =\n searchTerm.value === \"\" ||\n order.customerName\n .toLowerCase()\n .includes(searchTerm.value.toLowerCase()) ||\n order.id.toLowerCase().includes(searchTerm.value.toLowerCase());\n const matchesStatus =\n statusFilter.value === \"All\" || order.status === statusFilter.value;\n const matchesDateRange =\n !dateFrom.value ||\n !dateTo.value ||\n (new Date(order.orderDate) >= new Date(dateFrom.value) &&\n new Date(order.orderDate) <= new Date(dateTo.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [],\n )}\n/>\n```\n\n## Acceptable: Simple Filtering in Component Properties\n\n```tsx\n// This is fine - simple, straightforward filtering\n<SbTable tableData={sbComputed(() => getOrders.response?.filter(order => order.status === 'Active') || [])} />\n<SbText text={sbComputed(() => `Total: ${getOrders.response?.length || 0}`)} />\n```\n\n## Pattern for Non-Table Components\n\nThis pattern applies to all components, not just tables:\n\n```tsx\n// In scope.ts - define component binding and reactive state variable\nexport const Page1Scope = createSbScope<{\n CategoryDropdown: any;\n}>(\n ({ entities: { CategoryDropdown } }) => ({\n rawData: SbVariable({ defaultValue: [] }),\n // Good: Complex calculation in reactive state variable\n summaryText: SbVariable({\n defaultValue: sbComputed(() => {\n const filteredData = rawData.value?.filter(item => item.category === CategoryDropdown.selectedOptionValue) || [];\n const total = filteredData.reduce((sum, item) => sum + item.amount, 0);\n const average = filteredData.length > 0 ? total / filteredData.length : 0;\n return `${CategoryDropdown.selectedOptionValue} category: ${filteredData.length} items, Total: $${total.toFixed(2)}, Average: $${average.toFixed(2)}`;\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In component - destructure and use bind\nconst { CategoryDropdown, summaryText } = Page1;\n\n// Clean component property - just references reactive state variable\n<SbText text={sbComputed(() => summaryText.value)} />\n\n// Form control uses bind property - no onChange needed\n<SbDropdown\n bind={CategoryDropdown}\n options={[\n { value: 'Electronics', label: 'Electronics' },\n { value: 'Clothing', label: 'Clothing' },\n { value: 'Books', label: 'Books' }\n ]}\n/>\n```\n\n## Dynamic Dropdown Options from API Data\n\nWhen you need to create dropdown filters based on actual values from your API response (like filtering by status, category, type, etc.), extract the unique values from the API data to populate dropdown options dynamically.\n\n**Use this pattern when:**\n\n- You want to filter on a property that exists in your API data\n- The possible values for that property are not known in advance\n- You want the dropdown to show only values that actually exist in the data\n\n```tsx\n// In scope.ts - define component bindings and reactive state variables\nexport const Page1Scope = createSbScope<{\n StatusFilterDropdown: any;\n CategoryFilterDropdown: any;\n}>(\n ({ entities: { StatusFilterDropdown, CategoryFilterDropdown, getProducts } }) => ({\n getProducts: SbApi({}),\n\n // Generate unique status options from API data\n statusOptions: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProducts.response) return [{ value: 'All', label: 'All Statuses' }];\n\n const uniqueStatuses = [...new Set(getProducts.response.map(product => product.status))]\n .filter(status => status) // Remove any null/undefined values\n .sort()\n .map(status => ({ value: status, label: status }));\n\n return [{ value: 'All', label: 'All Statuses' }, ...uniqueStatuses];\n })\n }),\n\n // Generate unique category options from API data\n categoryOptions: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProducts.response) return [{ value: 'All', label: 'All Categories' }];\n\n const uniqueCategories = [...new Set(getProducts.response.map(product => product.category))]\n .filter(category => category) // Remove any null/undefined values\n .sort()\n .map(category => ({ value: category, label: category }));\n\n return [{ value: 'All', label: 'All Categories' }, ...uniqueCategories];\n })\n }),\n\n // Filtered data based on both dropdowns\n filteredProducts: SbVariable({\n defaultValue: sbComputed(() => {\n return getProducts.response?.filter(product => {\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n product.status === StatusFilterDropdown.selectedOptionValue;\n const matchesCategory = CategoryFilterDropdown.selectedOptionValue === 'All' ||\n product.category === CategoryFilterDropdown.selectedOptionValue;\n return matchesStatus && matchesCategory;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use\nconst { StatusFilterDropdown, CategoryFilterDropdown, statusOptions, categoryOptions, filteredProducts } = Page1;\n\n// Dropdowns with dynamic options from API data\n<SbDropdown\n bind={StatusFilterDropdown}\n options={sbComputed(() => statusOptions.value)}\n defaultValue=\"All\"\n/>\n\n<SbDropdown\n bind={CategoryFilterDropdown}\n options={sbComputed(() => categoryOptions.value)}\n defaultValue=\"All\"\n/>\n\n// Table showing filtered results\n<SbTable tableData={sbComputed(() => filteredProducts.value)} />\n```\n\n**Key points:**\n\n- Always include an \"All\" option as the first option\n- Use `new Set()` to get unique values from the API response\n- Filter out null/undefined values to avoid empty options\n- Sort the options alphabetically for better UX\n- The dropdown options are reactive - they update when the API data changes\n- Use `bind` properties on dropdowns so that the bind entities you set up in the scope file update automatically when the dropdown values change\n- Default to \"All\" to show all data initially\n";
4
+ // Generated at: 2025-06-23T03:26:44.022Z
5
+ export const content = "# Data Filtering Best Practices\n\n**🚨 CRITICAL: When implementing data filtering, remember that sbComputed cannot be used as React children.** All dynamic filtered content must be passed to component properties like `tableData={}`, `text={}`, etc. Never use `{sbComputed(...)}` as children.\n\nWhen filtering data from APIs or state variables, follow these patterns to keep component properties clean and maintainable:\n\n## When to Use Reactive State Variables for Filtering\n\n**Use reactive state variables with `defaultValue` for complex filtering when:**\n\n- The filtering logic is more than 1-2 lines of code\n- Multiple conditions need to be evaluated\n- Multiple form controls affect the same filtered dataset\n- The logic would make component properties hard to read in the visual editor\n\n**Keep simple filtering in component properties when:**\n\n- The filtering is 1-2 lines of basic logic\n- It's a straightforward filter operation\n- Only one control affects the filtering\n\n## Good Pattern: Reactive State Variables with defaultValue\n\n```tsx\n// First, define component bindings in scope.ts\nexport const Page1Scope = createSbScope<{\n OrderSearchInput: any;\n StatusFilterDropdown: any;\n DateFromPicker: any;\n DateToPicker: any;\n}>(\n ({ entities: { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, getOrdersApi } }) => ({\n getOrdersApi: SbApi({}),\n // Define reactive state variable with complex filtering logic in defaultValue\n filteredOrdersVar: SbVariable({\n defaultValue: sbComputed(() => {\n return getOrdersApi.response?.filter(order => {\n const matchesSearch = OrderSearchInput.value === '' ||\n order.customerName.toLowerCase().includes(OrderSearchInput.value.toLowerCase()) ||\n order.id.toLowerCase().includes(OrderSearchInput.value.toLowerCase());\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n order.status === StatusFilterDropdown.selectedOptionValue;\n const matchesDateRange = !DateFromPicker.value || !DateToPicker.value ||\n (new Date(order.orderDate) >= new Date(DateFromPicker.value) &&\n new Date(order.orderDate) <= new Date(DateToPicker.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use bind properties\nconst { OrderSearchInput, StatusFilterDropdown, DateFromPicker, DateToPicker, filteredOrdersVar } = Page1;\n\n// Clean component properties - just reference the reactive state variable\n<SbTable tableData={sbComputed(() => filteredOrdersVar.value)} />\n\n// Form controls use bind properties - no onChange logic needed\n<SbInput\n bind={OrderSearchInput}\n placeholder=\"Search orders...\"\n/>\n\n<SbDropdown\n bind={StatusFilterDropdown}\n options={[\n { value: 'All', label: 'All Statuses' },\n { value: 'Processing', label: 'Processing' },\n { value: 'Shipped', label: 'Shipped' },\n { value: 'Delivered', label: 'Delivered' }\n ]}\n/>\n\n<SbDatePicker bind={DateFromPicker} />\n<SbDatePicker bind={DateToPicker} />\n```\n\n## Bad Pattern: Duplicated Filtering Logic in Event Handlers\n\n```tsx\n// Avoid this - duplicates filtering logic in every event handler\n<SbInput\n placeholder=\"Search orders...\"\n onChange={SbEventFlow([\n (value) => {\n const filtered = getOrdersApi.response?.filter(order => {\n const matchesSearch = value === '' ||\n order.customerName.toLowerCase().includes(value.toLowerCase()) ||\n order.id.toLowerCase().includes(value.toLowerCase());\n const matchesStatus = statusFilterVar.value === 'All' || order.status === statusFilterVar.value;\n const matchesDateRange = !dateFromVar.value || !dateToVar.value ||\n (new Date(order.orderDate) >= new Date(dateFromVar.value) &&\n new Date(order.orderDate) <= new Date(dateToVar.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [];\n filteredOrdersVar.setValue(filtered);\n }\n ])}\n/>\n\n<SbDropdown\n onChange={SbEventFlow([\n (value) => {\n // Same filtering logic repeated here - this is what we want to avoid\n const filtered = getOrdersApi.response?.filter(order => {\n const matchesSearch = searchTermVar.value === '' ||\n order.customerName.toLowerCase().includes(searchTermVar.value.toLowerCase());\n const matchesStatus = value === 'All' || order.status === value;\n return matchesSearch && matchesStatus;\n }) || [];\n filteredOrdersVar.setValue(filtered);\n }\n ])}\n/>\n```\n\n## Bad Pattern: Complex Filtering in Component Properties\n\n```tsx\n// Avoid this - complex logic in component property makes visual editor cluttered\n<SbTable\n tableData={sbComputed(\n () =>\n getOrdersApi.response?.filter((order) => {\n const matchesSearch =\n searchTermVar.value === \"\" ||\n order.customerName\n .toLowerCase()\n .includes(searchTermVar.value.toLowerCase()) ||\n order.id.toLowerCase().includes(searchTermVar.value.toLowerCase());\n const matchesStatus =\n statusFilterVar.value === \"All\" ||\n order.status === statusFilterVar.value;\n const matchesDateRange =\n !dateFromVar.value ||\n !dateToVar.value ||\n (new Date(order.orderDate) >= new Date(dateFromVar.value) &&\n new Date(order.orderDate) <= new Date(dateToVar.value));\n return matchesSearch && matchesStatus && matchesDateRange;\n }) || [],\n )}\n/>\n```\n\n## Acceptable: Simple Filtering in Component Properties\n\n```tsx\n// This is fine - simple, straightforward filtering\n<SbTable tableData={sbComputed(() => getOrdersApi.response?.filter(order => order.status === 'Active') || [])} />\n<SbText text={sbComputed(() => `Total: ${getOrdersApi.response?.length || 0}`)} />\n```\n\n## Pattern for Non-Table Components\n\nThis pattern applies to all components, not just tables:\n\n```tsx\n// In scope.ts - define component binding and reactive state variable\nexport const Page1Scope = createSbScope<{\n CategoryDropdown: any;\n}>(\n ({ entities: { CategoryDropdown } }) => ({\n rawDataVar: SbVariable({ defaultValue: [] }),\n // Good: Complex calculation in reactive state variable\n summaryTextVar: SbVariable({\n defaultValue: sbComputed(() => {\n const filteredData = rawDataVar.value?.filter(item => item.category === CategoryDropdown.selectedOptionValue) || [];\n const total = filteredData.reduce((sum, item) => sum + item.amount, 0);\n const average = filteredData.length > 0 ? total / filteredData.length : 0;\n return `${CategoryDropdown.selectedOptionValue} category: ${filteredData.length} items, Total: $${total.toFixed(2)}, Average: $${average.toFixed(2)}`;\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In component - destructure and use bind\nconst { CategoryDropdown, summaryTextVar } = Page1;\n\n// Clean component property - just references reactive state variable\n<SbText text={sbComputed(() => summaryTextVar.value)} />\n\n// Form control uses bind property - no onChange needed\n<SbDropdown\n bind={CategoryDropdown}\n options={[\n { value: 'Electronics', label: 'Electronics' },\n { value: 'Clothing', label: 'Clothing' },\n { value: 'Books', label: 'Books' }\n ]}\n/>\n```\n\n## Dynamic Dropdown Options from API Data\n\nWhen you need to create dropdown filters based on actual values from your API response (like filtering by status, category, type, etc.), extract the unique values from the API data to populate dropdown options dynamically.\n\n**Use this pattern when:**\n\n- You want to filter on a property that exists in your API data\n- The possible values for that property are not known in advance\n- You want the dropdown to show only values that actually exist in the data\n\n```tsx\n// In scope.ts - define component bindings and reactive state variables\nexport const Page1Scope = createSbScope<{\n StatusFilterDropdown: any;\n CategoryFilterDropdown: any;\n}>(\n ({ entities: { StatusFilterDropdown, CategoryFilterDropdown, getProductsApi } }) => ({\n getProductsApi: SbApi({}),\n\n // Generate unique status options from API data\n statusOptionsVar: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProductsApi.response) return [{ value: 'All', label: 'All Statuses' }];\n\n const uniqueStatuses = [...new Set(getProductsApi.response.map(product => product.status))]\n .filter(status => status) // Remove any null/undefined values\n .sort()\n .map(status => ({ value: status, label: status }));\n\n return [{ value: 'All', label: 'All Statuses' }, ...uniqueStatuses];\n })\n }),\n\n // Generate unique category options from API data\n categoryOptionsVar: SbVariable({\n defaultValue: sbComputed(() => {\n if (!getProductsApi.response) return [{ value: 'All', label: 'All Categories' }];\n\n const uniqueCategories = [...new Set(getProductsApi.response.map(product => product.category))]\n .filter(category => category) // Remove any null/undefined values\n .sort()\n .map(category => ({ value: category, label: category }));\n\n return [{ value: 'All', label: 'All Categories' }, ...uniqueCategories];\n })\n }),\n\n // Filtered data based on both dropdowns\n filteredProductsVar: SbVariable({\n defaultValue: sbComputed(() => {\n return getProductsApi.response?.filter(product => {\n const matchesStatus = StatusFilterDropdown.selectedOptionValue === 'All' ||\n product.status === StatusFilterDropdown.selectedOptionValue;\n const matchesCategory = CategoryFilterDropdown.selectedOptionValue === 'All' ||\n product.category === CategoryFilterDropdown.selectedOptionValue;\n return matchesStatus && matchesCategory;\n }) || [];\n })\n }),\n }),\n { name: \"Page1\" }\n);\n\n// In the component, destructure and use\nconst { StatusFilterDropdown, CategoryFilterDropdown, statusOptionsVar, categoryOptionsVar, filteredProductsVar } = Page1;\n\n// Dropdowns with dynamic options from API data\n<SbDropdown\n bind={StatusFilterDropdown}\n options={sbComputed(() => statusOptionsVar.value)}\n defaultValue=\"All\"\n/>\n\n<SbDropdown\n bind={CategoryFilterDropdown}\n options={sbComputed(() => categoryOptionsVar.value)}\n defaultValue=\"All\"\n/>\n\n// Table showing filtered results\n<SbTable tableData={sbComputed(() => filteredProductsVar.value)} />\n```\n\n**Key points:**\n\n- Always include an \"All\" option as the first option\n- Use `new Set()` to get unique values from the API response\n- Filter out null/undefined values to avoid empty options\n- Sort the options alphabetically for better UX\n- The dropdown options are reactive - they update when the API data changes\n- Use `bind` properties on dropdowns so that the bind entities you set up in the scope file update automatically when the dropdown values change\n- Default to \"All\" to show all data initially\n";
6
6
  //# sourceMappingURL=superblocks-data-filtering.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-data-filtering.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-data-filtering.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,oDAAoD;AACpD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,6mVAA6mV,CAAC"}
1
+ {"version":3,"file":"superblocks-data-filtering.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-data-filtering.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,oDAAoD;AACpD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,shWAAshW,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const content = "# Event handlers with SbEventFlow\n\nRather than using standard browser event handlers, Superblocks provides a structured event handler action flow that allows you to run a series of events within the Superblocks system.\n\nImporting SbEventFlow:\n\n```jsx\nimport { SbEventFlow } from \"@superblocksteam/library\";\n```\n\nAll event handlers MUST be written using the `SbEventFlow` object.\n\nFor example, here we set the `isReady` state variable to `true` when the button is clicked:\n\n```jsx\nconst { isReady } = Page1;\n<SbButton onClick={SbEventFlow.setStateVar(isReady, true)} />;\n```\n\n## SbEventFlow builder pattern\n\n`SbEventFlow` provides a number of functions that can be chained together using `SbEventFlow` which correspond to actions in the Superblocks system.\n\nYou should always use these dedicated functions for individual and sequential actions.\n\nImportant: DO NOT use .run() at the end of a chain of SbEventFlow functions, it is not needed and it will throw an error.\n\n```jsx\nconst { isReady, getUserData, getPermissions } = Page1;\n<SbButton\n onClick={SbEventFlow.setQueryParams({ filter: \"active\" }, true)\n .setStateVar(isReady, true)\n .controlModal(\"loginModal\", \"close\")\n\n // run APIs allows you to run Superblocks APIs by name using string arrays\n // Each runAPIs call executes the list of API names supplied in parallel\n .runApis([getUserData, getPermissions])\n\n // set a state variable's value\n .showAlert(\"Workflow complete\", \"success\")\n .navigateTo({ url: \"/dashboard\", newWindow: false })}\n/>;\n```\n\n#### Using RunJS (only when needed)\n\n`SbEventFlow` also has a special `runJS` event type that allows you to run any JavaScript in the browser.\n\nThis allows you to write more complex logic such as control flow.\n\nImportant:\n\n- The only things you can do in runJS is set state variables or set the public state of components, like modal.isOpen.\n- You CANNOT use SbEventFlow inside of a SbEventFlow.runJS function. If you do this, it won't work!\n- **State access in runJS**: Scope entities are accessible directly by their names, global state is accessible via imported globals (Global, Theme, Embed, Env).\n\nExample accessing scope entities:\n\n```jsx\n<SbButton\n label=\"Enable\"\n buttonStyle={\"SECONDARY_BUTTON\"}\n onClick={SbEventFlow.runJS(() => {\n // Scope entities (variables, bound components) are accessible directly in runJS\n if (isUserAdmin.value) {\n // isUserAdmin is a bound component from scope\n myStateVar.value = true; // myStateVar is a state variable from scope\n myModal.isOpen = false; // myModal is a bound component from scope\n } else {\n console.log(\"This user was not an admin\");\n }\n })}\n/>\n```\n\nExample accessing global state when needed:\n\n```jsx\n<SbButton\n label=\"Personalized Action\"\n onClick={SbEventFlow.runJS(() => {\n // Import globals and access directly\n if (Global.user.groups.some((g) => g.name === \"admin\")) {\n // Also access scope entities (bound components) directly\n adminPanel.isVisible = true; // adminPanel is a bound component from scope\n }\n console.log(`Welcome ${Global.user.name}!`);\n })}\n/>\n```\n\nAs mentioned above, you should only use `runJS` when the flow is too complex to represent using only chained event flow actions.\n\n### SbEvent Flow Usage Examples\n\n```typescript\nimport { SbEventFlow, sbComputed } from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst { fetchUserData, saveUserData, userDataVariable } = Page1;\n\n// Navigation example\nSbEventFlow.navigateTo({ url: \"https://example.com\", newWindow: true });\n\n// Control UI components example\nSbEventFlow.controlModal(\"myModal\", \"open\");\n\n// State management example\nconst { userProfile } = Page1;\nSbEventFlow.setStateVar(userProfile, { name: \"John\", role: \"Admin\" });\n\n// Chaining multiple actions\nSbEventFlow.runApis([fetchUserData])\n .setStateVar(\n userDataVariable,\n sbComputed(() => {\n fetchUserData.response;\n }),\n )\n .showAlert(\"Data loaded successfully\", \"success\");\n\n// Conditional flow with success/error handlers\nconst successFlow = SbEventFlow.showAlert(\"Success!\", \"success\");\nconst errorFlow = SbEventFlow.showAlert(\"An error occurred\", \"error\");\nSbEventFlow.runApis([saveUserData], successFlow, errorFlow);\n```\n\n**SbEventFlow: Managing Events and Side Effects in Superblocks**\n\n## Important Syntax Rules\n\n- Always use function braces with SbEventFlow.runJS. Example: `SbEventFlow.runJS(() => { someFunction(); })` not `SbEventFlow.runJS(() => someFunction())`\n- SbEventFlow.runApis() accepts an array of direct API entity references. Example: `SbEventFlow.runApis([fetchUserData, saveUserData])`\n";
1
+ export declare const content = "# Event handlers with SbEventFlow\n\nRather than using standard browser event handlers, Superblocks provides a structured event handler action flow that allows you to run a series of events within the Superblocks system.\n\nImporting SbEventFlow:\n\n```jsx\nimport { SbEventFlow } from \"@superblocksteam/library\";\n```\n\nAll event handlers MUST be written using the `SbEventFlow` object.\n\nFor example, here we set the `isReady` state variable to `true` when the button is clicked:\n\n```jsx\nconst { isReady } = Page1;\n<SbButton onClick={SbEventFlow.setStateVar(isReady, true)} />;\n```\n\n## SbEventFlow builder pattern\n\n`SbEventFlow` provides a number of functions that can be chained together using `SbEventFlow` which correspond to actions in the Superblocks system.\n\nYou should always use these dedicated functions for individual and sequential actions.\n\nImportant: DO NOT use .run() at the end of a chain of SbEventFlow functions, it is not needed and it will throw an error.\n\n```jsx\nconst { isReady, getUserData, getPermissions, LoginModal } = Page1;\n<SbButton\n onClick={SbEventFlow.setQueryParams({ filter: \"active\" }, true)\n .setStateVar(isReady, true)\n .controlModal(LoginModal, \"close\")\n\n // run APIs allows you to run Superblocks APIs by name using string arrays\n // Each runAPIs call executes the list of API names supplied in parallel\n .runApis([getUserData, getPermissions])\n\n // set a state variable's value\n .showAlert(\"Workflow complete\", \"success\")\n .navigateTo({ url: \"/dashboard\", newWindow: false })}\n/>;\n```\n\n#### Using RunJS (only when needed)\n\n`SbEventFlow` also has a special `runJS` event type that allows you to run any JavaScript in the browser.\n\nThis allows you to write more complex logic such as control flow.\n\nImportant:\n\n- The only things you can do in runJS is set state variables or set the public state of components, like modal.isOpen.\n- You CANNOT use SbEventFlow inside of a SbEventFlow.runJS function. If you do this, it won't work!\n- **State access in runJS**: Scope entities are accessible directly by their names, global state is accessible via imported globals (Global, Theme, Embed, Env).\n\nExample accessing scope entities:\n\n```jsx\n<SbButton\n label=\"Enable\"\n buttonStyle={\"SECONDARY_BUTTON\"}\n onClick={SbEventFlow.runJS(() => {\n // Scope entities (variables, bound components) are accessible directly in runJS\n if (isUserAdmin.value) {\n // isUserAdmin is a bound component from scope\n myStateVar.value = true; // myStateVar is a state variable from scope\n myModal.isOpen = false; // myModal is a bound component from scope\n } else {\n console.log(\"This user was not an admin\");\n }\n })}\n/>\n```\n\nExample accessing global state when needed:\n\n```jsx\n<SbButton\n label=\"Personalized Action\"\n onClick={SbEventFlow.runJS(() => {\n // Import globals and access directly\n if (Global.user.groups.some((g) => g.name === \"admin\")) {\n // Also access scope entities (bound components) directly\n adminPanel.isVisible = true; // adminPanel is a bound component from scope\n }\n console.log(`Welcome ${Global.user.name}!`);\n })}\n/>\n```\n\nAs mentioned above, you should only use `runJS` when the flow is too complex to represent using only chained event flow actions.\n\n### SbEvent Flow Usage Examples\n\n```typescript\nimport { SbEventFlow, sbComputed } from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst { fetchUserData, saveUserData, userDataVariable, MyModal } = Page1;\n\n// Navigation example\nSbEventFlow.navigateTo({ url: \"https://example.com\", newWindow: true });\n\n// Control UI components example\nSbEventFlow.controlModal(MyModal, \"open\");\n\n// State management example\nconst { userProfile } = Page1;\nSbEventFlow.setStateVar(userProfile, { name: \"John\", role: \"Admin\" });\n\n// Chaining multiple actions\nSbEventFlow.runApis([fetchUserData])\n .setStateVar(\n userDataVariable,\n sbComputed(() => {\n fetchUserData.response;\n }),\n )\n .showAlert(\"Data loaded successfully\", \"success\");\n\n// Conditional flow with success/error handlers\nconst successFlow = SbEventFlow.showAlert(\"Success!\", \"success\");\nconst errorFlow = SbEventFlow.showAlert(\"An error occurred\", \"error\");\nSbEventFlow.runApis([saveUserData], successFlow, errorFlow);\n```\n\n**SbEventFlow: Managing Events and Side Effects in Superblocks**\n\n## Important Syntax Rules\n\n- Always use function braces with SbEventFlow.runJS. Example: `SbEventFlow.runJS(() => { someFunction(); })` not `SbEventFlow.runJS(() => someFunction())`\n- SbEventFlow.runApis() accepts an array of direct API entity references. Example: `SbEventFlow.runApis([fetchUserData, saveUserData])`\n";
2
2
  //# sourceMappingURL=superblocks-event-flow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-event-flow.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-event-flow.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,mtJAAmtJ,CAAC"}
1
+ {"version":3,"file":"superblocks-event-flow.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-event-flow.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,guJAAguJ,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  // Auto-generated from superblocks-event-flow.md
3
3
  // Do not edit this file directly
4
- // Generated at: 2025-06-15T06:08:09.959Z
5
- export const content = "# Event handlers with SbEventFlow\n\nRather than using standard browser event handlers, Superblocks provides a structured event handler action flow that allows you to run a series of events within the Superblocks system.\n\nImporting SbEventFlow:\n\n```jsx\nimport { SbEventFlow } from \"@superblocksteam/library\";\n```\n\nAll event handlers MUST be written using the `SbEventFlow` object.\n\nFor example, here we set the `isReady` state variable to `true` when the button is clicked:\n\n```jsx\nconst { isReady } = Page1;\n<SbButton onClick={SbEventFlow.setStateVar(isReady, true)} />;\n```\n\n## SbEventFlow builder pattern\n\n`SbEventFlow` provides a number of functions that can be chained together using `SbEventFlow` which correspond to actions in the Superblocks system.\n\nYou should always use these dedicated functions for individual and sequential actions.\n\nImportant: DO NOT use .run() at the end of a chain of SbEventFlow functions, it is not needed and it will throw an error.\n\n```jsx\nconst { isReady, getUserData, getPermissions } = Page1;\n<SbButton\n onClick={SbEventFlow.setQueryParams({ filter: \"active\" }, true)\n .setStateVar(isReady, true)\n .controlModal(\"loginModal\", \"close\")\n\n // run APIs allows you to run Superblocks APIs by name using string arrays\n // Each runAPIs call executes the list of API names supplied in parallel\n .runApis([getUserData, getPermissions])\n\n // set a state variable's value\n .showAlert(\"Workflow complete\", \"success\")\n .navigateTo({ url: \"/dashboard\", newWindow: false })}\n/>;\n```\n\n#### Using RunJS (only when needed)\n\n`SbEventFlow` also has a special `runJS` event type that allows you to run any JavaScript in the browser.\n\nThis allows you to write more complex logic such as control flow.\n\nImportant:\n\n- The only things you can do in runJS is set state variables or set the public state of components, like modal.isOpen.\n- You CANNOT use SbEventFlow inside of a SbEventFlow.runJS function. If you do this, it won't work!\n- **State access in runJS**: Scope entities are accessible directly by their names, global state is accessible via imported globals (Global, Theme, Embed, Env).\n\nExample accessing scope entities:\n\n```jsx\n<SbButton\n label=\"Enable\"\n buttonStyle={\"SECONDARY_BUTTON\"}\n onClick={SbEventFlow.runJS(() => {\n // Scope entities (variables, bound components) are accessible directly in runJS\n if (isUserAdmin.value) {\n // isUserAdmin is a bound component from scope\n myStateVar.value = true; // myStateVar is a state variable from scope\n myModal.isOpen = false; // myModal is a bound component from scope\n } else {\n console.log(\"This user was not an admin\");\n }\n })}\n/>\n```\n\nExample accessing global state when needed:\n\n```jsx\n<SbButton\n label=\"Personalized Action\"\n onClick={SbEventFlow.runJS(() => {\n // Import globals and access directly\n if (Global.user.groups.some((g) => g.name === \"admin\")) {\n // Also access scope entities (bound components) directly\n adminPanel.isVisible = true; // adminPanel is a bound component from scope\n }\n console.log(`Welcome ${Global.user.name}!`);\n })}\n/>\n```\n\nAs mentioned above, you should only use `runJS` when the flow is too complex to represent using only chained event flow actions.\n\n### SbEvent Flow Usage Examples\n\n```typescript\nimport { SbEventFlow, sbComputed } from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst { fetchUserData, saveUserData, userDataVariable } = Page1;\n\n// Navigation example\nSbEventFlow.navigateTo({ url: \"https://example.com\", newWindow: true });\n\n// Control UI components example\nSbEventFlow.controlModal(\"myModal\", \"open\");\n\n// State management example\nconst { userProfile } = Page1;\nSbEventFlow.setStateVar(userProfile, { name: \"John\", role: \"Admin\" });\n\n// Chaining multiple actions\nSbEventFlow.runApis([fetchUserData])\n .setStateVar(\n userDataVariable,\n sbComputed(() => {\n fetchUserData.response;\n }),\n )\n .showAlert(\"Data loaded successfully\", \"success\");\n\n// Conditional flow with success/error handlers\nconst successFlow = SbEventFlow.showAlert(\"Success!\", \"success\");\nconst errorFlow = SbEventFlow.showAlert(\"An error occurred\", \"error\");\nSbEventFlow.runApis([saveUserData], successFlow, errorFlow);\n```\n\n**SbEventFlow: Managing Events and Side Effects in Superblocks**\n\n## Important Syntax Rules\n\n- Always use function braces with SbEventFlow.runJS. Example: `SbEventFlow.runJS(() => { someFunction(); })` not `SbEventFlow.runJS(() => someFunction())`\n- SbEventFlow.runApis() accepts an array of direct API entity references. Example: `SbEventFlow.runApis([fetchUserData, saveUserData])`\n";
4
+ // Generated at: 2025-06-23T03:26:44.022Z
5
+ export const content = "# Event handlers with SbEventFlow\n\nRather than using standard browser event handlers, Superblocks provides a structured event handler action flow that allows you to run a series of events within the Superblocks system.\n\nImporting SbEventFlow:\n\n```jsx\nimport { SbEventFlow } from \"@superblocksteam/library\";\n```\n\nAll event handlers MUST be written using the `SbEventFlow` object.\n\nFor example, here we set the `isReady` state variable to `true` when the button is clicked:\n\n```jsx\nconst { isReady } = Page1;\n<SbButton onClick={SbEventFlow.setStateVar(isReady, true)} />;\n```\n\n## SbEventFlow builder pattern\n\n`SbEventFlow` provides a number of functions that can be chained together using `SbEventFlow` which correspond to actions in the Superblocks system.\n\nYou should always use these dedicated functions for individual and sequential actions.\n\nImportant: DO NOT use .run() at the end of a chain of SbEventFlow functions, it is not needed and it will throw an error.\n\n```jsx\nconst { isReady, getUserData, getPermissions, LoginModal } = Page1;\n<SbButton\n onClick={SbEventFlow.setQueryParams({ filter: \"active\" }, true)\n .setStateVar(isReady, true)\n .controlModal(LoginModal, \"close\")\n\n // run APIs allows you to run Superblocks APIs by name using string arrays\n // Each runAPIs call executes the list of API names supplied in parallel\n .runApis([getUserData, getPermissions])\n\n // set a state variable's value\n .showAlert(\"Workflow complete\", \"success\")\n .navigateTo({ url: \"/dashboard\", newWindow: false })}\n/>;\n```\n\n#### Using RunJS (only when needed)\n\n`SbEventFlow` also has a special `runJS` event type that allows you to run any JavaScript in the browser.\n\nThis allows you to write more complex logic such as control flow.\n\nImportant:\n\n- The only things you can do in runJS is set state variables or set the public state of components, like modal.isOpen.\n- You CANNOT use SbEventFlow inside of a SbEventFlow.runJS function. If you do this, it won't work!\n- **State access in runJS**: Scope entities are accessible directly by their names, global state is accessible via imported globals (Global, Theme, Embed, Env).\n\nExample accessing scope entities:\n\n```jsx\n<SbButton\n label=\"Enable\"\n buttonStyle={\"SECONDARY_BUTTON\"}\n onClick={SbEventFlow.runJS(() => {\n // Scope entities (variables, bound components) are accessible directly in runJS\n if (isUserAdmin.value) {\n // isUserAdmin is a bound component from scope\n myStateVar.value = true; // myStateVar is a state variable from scope\n myModal.isOpen = false; // myModal is a bound component from scope\n } else {\n console.log(\"This user was not an admin\");\n }\n })}\n/>\n```\n\nExample accessing global state when needed:\n\n```jsx\n<SbButton\n label=\"Personalized Action\"\n onClick={SbEventFlow.runJS(() => {\n // Import globals and access directly\n if (Global.user.groups.some((g) => g.name === \"admin\")) {\n // Also access scope entities (bound components) directly\n adminPanel.isVisible = true; // adminPanel is a bound component from scope\n }\n console.log(`Welcome ${Global.user.name}!`);\n })}\n/>\n```\n\nAs mentioned above, you should only use `runJS` when the flow is too complex to represent using only chained event flow actions.\n\n### SbEvent Flow Usage Examples\n\n```typescript\nimport { SbEventFlow, sbComputed } from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst { fetchUserData, saveUserData, userDataVariable, MyModal } = Page1;\n\n// Navigation example\nSbEventFlow.navigateTo({ url: \"https://example.com\", newWindow: true });\n\n// Control UI components example\nSbEventFlow.controlModal(MyModal, \"open\");\n\n// State management example\nconst { userProfile } = Page1;\nSbEventFlow.setStateVar(userProfile, { name: \"John\", role: \"Admin\" });\n\n// Chaining multiple actions\nSbEventFlow.runApis([fetchUserData])\n .setStateVar(\n userDataVariable,\n sbComputed(() => {\n fetchUserData.response;\n }),\n )\n .showAlert(\"Data loaded successfully\", \"success\");\n\n// Conditional flow with success/error handlers\nconst successFlow = SbEventFlow.showAlert(\"Success!\", \"success\");\nconst errorFlow = SbEventFlow.showAlert(\"An error occurred\", \"error\");\nSbEventFlow.runApis([saveUserData], successFlow, errorFlow);\n```\n\n**SbEventFlow: Managing Events and Side Effects in Superblocks**\n\n## Important Syntax Rules\n\n- Always use function braces with SbEventFlow.runJS. Example: `SbEventFlow.runJS(() => { someFunction(); })` not `SbEventFlow.runJS(() => someFunction())`\n- SbEventFlow.runApis() accepts an array of direct API entity references. Example: `SbEventFlow.runApis([fetchUserData, saveUserData])`\n";
6
6
  //# sourceMappingURL=superblocks-event-flow.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-event-flow.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-event-flow.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,gDAAgD;AAChD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,gtJAAgtJ,CAAC"}
1
+ {"version":3,"file":"superblocks-event-flow.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-event-flow.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,gDAAgD;AAChD,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,6tJAA6tJ,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const content = "### Form Layouts in Superblocks\n\nWhen creating forms using form field components, follow these rules:\n\n1. Always put form components together inside an `SbContainer` with `layout=\"vertical\"`, `width={Dim.fill()}`, and appropriate `spacing`\n2. Use `spacing={Dim.px(12)}` or similar for consistent form field spacing\n3. Do not change the label position on form components (like `SbInput`). The default is the label is above the input and we want to keep that\n4. Make all form field components and any container parents be `width={Dim.fill()}` so they are all aligned horizontally and easy to use\n\n**Example:**\n\n```jsx\n<SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput label=\"First Name\" bind={FirstName} width={Dim.fill()} />\n <SbInput label=\"Last Name\" bind={LastName} width={Dim.fill()} />\n <SbInput label=\"Email\" bind={Email} inputType=\"EMAIL\" width={Dim.fill()} />\n</SbContainer>\n```\n\n### Forms inside Modals\n\nIt's common to put a form inside a Modal, like for creating or editing an entity. Here are comprehensive examples showing different patterns:\n\n#### Basic Create Form Modal\n\n```tsx\n// Import required components and utilities\nimport {\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\n// ...\n\nconst {\n NewOrderCustomerName,\n NewOrderCustomerEmail,\n NewOrderAmount,\n NewOrderStatus,\n NewOrderNotes,\n OrdersStateVar,\n CreateOrderModal,\n} = Page1;\n\n<SbModal bind={CreateOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Create New Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Fill out the form below to create a new order\" />\n </SbContainer>\n\n {/* Form Content */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={NewOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={NewOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={NewOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.runJS(() => {\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(\"CreateOrderModal\", \"close\")}\n />\n <SbButton\n label=\"Create Order\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Create new order using the form values\n const newOrder = {\n id: `ORD_${Math.floor(Math.random() * 10000)\n .toString()\n .padStart(4, \"0\")}`,\n customerName: NewOrderCustomerName.value,\n customerEmail: NewOrderCustomerEmail.value,\n amount: NewOrderAmount.value,\n status: NewOrderStatus.selectedOptionValue,\n notes: NewOrderNotes.value,\n createdAt: new Date().toISOString(),\n };\n\n // Add to orders list or call API\n OrdersStateVar.setValue([...OrdersStateVar.value, newOrder]);\n\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(\"CreateOrderModal\", \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>;\n```\n\n#### Table with Edit Form Modal\n\nThis example shows a more complete pattern where a table displays data and clicking a row opens an edit modal with the form fields pre-populated:\n\n```tsx\n// Import required components and utilities\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n sbComputed,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst {\n OrdersTable,\n EditOrderModal,\n EditOrderCustomerName,\n EditOrderCustomerEmail,\n EditOrderAmount,\n EditOrderStatus,\n EditOrderNotes,\n OrdersStateVar,\n} = Page1;\n\n// Main page with table\n<SbPage name=\"Page1\" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()} spacing={Dim.px(24)}>\n <SbText\n text=\"Orders Management\"\n textStyle={{ variant: \"heading2\" }}\n />\n\n <SbTable\n bind={OrdersTable}\n tableData={sbComputed(() => OrdersStateVar.value)}\n onRowClick={SbEventFlow.runJS((event) => {\n // Populate form fields with the selected row data\n EditOrderCustomerName.text = event.row.customerName;\n EditOrderCustomerEmail.text = event.row.customerEmail;\n EditOrderAmount.text = event.row.amount;\n EditOrderStatus.metaSelectedOptionValue = event.row.status;\n EditOrderNotes.text = event.row.notes || \"\";\n })\n // Open the edit modal\n .controlModal(\"EditOrderModal\", \"open\")}\n width={Dim.fill()}\n height={Dim.fill()}\n />\n </SbColumn>\n </SbSection>\n</SbPage>\n\n// Edit modal with form pre-populated from table row\n<SbModal bind={EditOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Edit Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Update the order details below\" />\n </SbContainer>\n\n {/* Form Content - Fields are pre-populated by onRowClick */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={EditOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={EditOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={EditOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.controlModal(\"EditOrderModal\", \"close\")}\n />\n <SbButton\n label=\"Save Changes\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Find and update the order in the orders array\n const updatedOrders = OrdersStateVar.value.map(order => {\n if (order.id === OrdersTable.selectedRow.id) {\n return {\n ...order,\n customerName: EditOrderCustomerName.value,\n customerEmail: EditOrderCustomerEmail.value,\n amount: EditOrderAmount.value,\n status: EditOrderStatus.selectedOptionValue,\n notes: EditOrderNotes.value,\n updatedAt: new Date().toISOString(),\n };\n }\n return order;\n });\n\n // Update the orders state\n OrdersStateVar.setValue(updatedOrders);\n })\n .controlModal(\"EditOrderModal\", \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>\n```\n\n**Corresponding scope.ts file for the table + edit modal example:**\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n} from \"@superblocksteam/library\";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n EditOrderModal: any;\n EditOrderCustomerName: any;\n EditOrderCustomerEmail: any;\n EditOrderAmount: any;\n EditOrderStatus: any;\n EditOrderNotes: any;\n OrdersStateVar: any;\n}>(\n () => ({\n OrdersStateVar: SbVariable({\n defaultValue: [\n {\n id: 1,\n customerName: \"John Doe\",\n customerEmail: \"john@example.com\",\n amount: 150.0,\n status: \"pending\",\n notes: \"Rush order\",\n createdAt: \"2024-01-15T10:30:00Z\",\n },\n {\n id: 2,\n customerName: \"Jane Smith\",\n customerEmail: \"jane@example.com\",\n amount: 89.99,\n status: \"delivered\",\n notes: \"\",\n createdAt: \"2024-01-14T14:20:00Z\",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: \"Page1\",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\n#### Alternative Population Method - Button with State Variable\n\nHere's another common pattern where a button populates form fields from a state variable:\n\n```tsx\n// Button that loads selected user data into edit form\n<SbButton\n label=\"Edit Selected User\"\n onClick={SbEventFlow.runJS(() => {\n const selectedUser = SelectedUserStateVar.value;\n\n // Populate form fields from state variable\n EditUserName.text = selectedUser.name;\n EditUserEmail.text = selectedUser.email;\n EditUserRole.metaSelectedOptionValue = selectedUser.role;\n EditUserDepartment.text = selectedUser.department;\n }).controlModal(\"EditUserModal\", \"open\")}\n/>\n```\n\n### Key Form Patterns\n\n1. **Create Forms**: Start with empty fields, populate from user input\n2. **Edit Forms**: Pre-populate fields with existing data from various sources\n3. **Field Population Methods**:\n - **Table Row Selection**: Use `onRowClick` to set form field values to `s.row.{columnName}` (most common)\n - **Button Actions**: Use button clicks to populate from state variables or API responses\n - **API Loading**: Fetch data and populate fields when modal opens\n - **State Variables**: Populate from existing application state\n4. **Form Validation**: Use `required={true}` on form components and validate in submit handlers\n5. **Form Reset**: Always reset form fields when canceling or after successful submission\n6. **Modal Control**: Prefer `SbEventFlow.controlModal()` over directly setting modal open property\n\n### Form Layout Best Practices\n\n- **Container Structure**: Always wrap forms in `SbContainer` with `layout=\"vertical\"`\n- **Consistent Spacing**: Use `spacing={Dim.px(12)}` for form field spacing\n- **Full Width**: Make form fields and containers `width={Dim.fill()}` for proper alignment\n- **Modal Structure**: Use header, content, and footer containers with appropriate spacing\n- **Button Alignment**: Use `horizontalAlign=\"right\"` for the footer containers in modals that contain buttons\n";
1
+ export declare const content = "### Form Layouts in Superblocks\n\n**\uD83D\uDEA8 CRITICAL: Remember that sbComputed cannot be used as React children.** When building forms, all dynamic content must be in component properties (like `text={}`, `label={}`) not as children.\n\nWhen creating forms using form field components, follow these rules:\n\n1. Always put form components together inside an `SbContainer` with `layout=\"vertical\"`, `width={Dim.fill()}`, and appropriate `spacing`\n2. Use `spacing={Dim.px(12)}` or similar for consistent form field spacing\n3. Do not change the label position on form components (like `SbInput`). The default is the label is above the input and we want to keep that\n4. Make all form field components and any container parents be `width={Dim.fill()}` so they are all aligned horizontally and easy to use\n\n**Example:**\n\n```jsx\n<SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput label=\"First Name\" bind={FirstName} width={Dim.fill()} />\n <SbInput label=\"Last Name\" bind={LastName} width={Dim.fill()} />\n <SbInput label=\"Email\" bind={Email} inputType=\"EMAIL\" width={Dim.fill()} />\n</SbContainer>\n```\n\n### Forms inside Modals\n\nIt's common to put a form inside a Modal, like for creating or editing an entity. Here are comprehensive examples showing different patterns:\n\n#### Basic Create Form Modal\n\n```tsx\n// Import required components and utilities\nimport {\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\n// ...\n\nconst {\n NewOrderCustomerName,\n NewOrderCustomerEmail,\n NewOrderAmount,\n NewOrderStatus,\n NewOrderNotes,\n OrdersStateVar,\n CreateOrderModal,\n} = Page1;\n\n<SbModal bind={CreateOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Create New Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Fill out the form below to create a new order\" />\n </SbContainer>\n\n {/* Form Content */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={NewOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={NewOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={NewOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.runJS(() => {\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(CreateOrderModal, \"close\")}\n />\n <SbButton\n label=\"Create Order\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Create new order using the form values\n const newOrder = {\n id: `ORD_${Math.floor(Math.random() * 10000)\n .toString()\n .padStart(4, \"0\")}`,\n customerName: NewOrderCustomerName.value,\n customerEmail: NewOrderCustomerEmail.value,\n amount: NewOrderAmount.value,\n status: NewOrderStatus.selectedOptionValue,\n notes: NewOrderNotes.value,\n createdAt: new Date().toISOString(),\n };\n\n // Add to orders list or call API\n OrdersStateVar.setValue([...OrdersStateVar.value, newOrder]);\n\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(CreateOrderModal, \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>;\n```\n\n#### Table with Edit Form Modal\n\nThis example shows a more complete pattern where a table displays data and clicking a row opens an edit modal with the form fields pre-populated:\n\n```tsx\n// Import required components and utilities\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n sbComputed,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst {\n OrdersTable,\n EditOrderModal,\n EditOrderCustomerName,\n EditOrderCustomerEmail,\n EditOrderAmount,\n EditOrderStatus,\n EditOrderNotes,\n OrdersStateVar,\n} = Page1;\n\n// Main page with table\n<SbPage name=\"Page1\" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()} spacing={Dim.px(24)}>\n <SbText\n text=\"Orders Management\"\n textStyle={{ variant: \"heading2\" }}\n />\n\n <SbTable\n bind={OrdersTable}\n tableData={sbComputed(() => OrdersStateVar.value)}\n onRowClick={SbEventFlow.runJS(() => {\n // Populate form fields with the selected row data\n EditOrderCustomerName.text = OrdersTable.selectedRow.customerName;\n EditOrderCustomerEmail.text = OrdersTable.selectedRow.customerEmail;\n EditOrderAmount.text = OrdersTable.selectedRow.amount;\n EditOrderStatus.metaSelectedOptionValue = OrdersTable.selectedRow.status;\n EditOrderNotes.text = OrdersTable.selectedRow.notes || \"\";\n })\n // Open the edit modal\n .controlModal(EditOrderModal, \"open\")}\n width={Dim.fill()}\n height={Dim.fill()}\n />\n </SbColumn>\n </SbSection>\n</SbPage>\n\n// Edit modal with form pre-populated from table row\n<SbModal bind={EditOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Edit Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Update the order details below\" />\n </SbContainer>\n\n {/* Form Content - Fields are pre-populated by onRowClick */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={EditOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={EditOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={EditOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.controlModal(EditOrderModal, \"close\")}\n />\n <SbButton\n label=\"Save Changes\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Find and update the order in the orders array\n const updatedOrders = OrdersStateVar.value.map(order => {\n if (order.id === OrdersTable.selectedRow.id) {\n return {\n ...order,\n customerName: EditOrderCustomerName.value,\n customerEmail: EditOrderCustomerEmail.value,\n amount: EditOrderAmount.value,\n status: EditOrderStatus.selectedOptionValue,\n notes: EditOrderNotes.value,\n updatedAt: new Date().toISOString(),\n };\n }\n return order;\n });\n\n // Update the orders state\n OrdersStateVar.setValue(updatedOrders);\n })\n .controlModal(EditOrderModal, \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>\n```\n\n**Corresponding scope.ts file for the table + edit modal example:**\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n} from \"@superblocksteam/library\";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n EditOrderModal: any;\n EditOrderCustomerName: any;\n EditOrderCustomerEmail: any;\n EditOrderAmount: any;\n EditOrderStatus: any;\n EditOrderNotes: any;\n OrdersStateVar: any;\n}>(\n () => ({\n OrdersStateVar: SbVariable({\n defaultValue: [\n {\n id: 1,\n customerName: \"John Doe\",\n customerEmail: \"john@example.com\",\n amount: 150.0,\n status: \"pending\",\n notes: \"Rush order\",\n createdAt: \"2024-01-15T10:30:00Z\",\n },\n {\n id: 2,\n customerName: \"Jane Smith\",\n customerEmail: \"jane@example.com\",\n amount: 89.99,\n status: \"delivered\",\n notes: \"\",\n createdAt: \"2024-01-14T14:20:00Z\",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: \"Page1\",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\n#### Alternative Population Method - Button with State Variable\n\nHere's another common pattern where a button populates form fields from a state variable:\n\n```tsx\n// Button that loads selected user data into edit form\n<SbButton\n label=\"Edit Selected User\"\n onClick={SbEventFlow.runJS(() => {\n const selectedUser = SelectedUserStateVar.value;\n\n // Populate form fields from state variable\n EditUserName.text = selectedUser.name;\n EditUserEmail.text = selectedUser.email;\n EditUserRole.metaSelectedOptionValue = selectedUser.role;\n EditUserDepartment.text = selectedUser.department;\n }).controlModal(EditUserModal, \"open\")}\n/>\n```\n\n### Key Form Patterns\n\n1. **Create Forms**: Start with empty fields, populate from user input\n2. **Edit Forms**: Pre-populate fields with existing data from various sources\n3. **Field Population Methods**:\n - **Table Row Selection**: Use `onRowClick` to set form field values to `{TableName}.selectedRow.{columnName}` (most common)\n - **Button Actions**: Use button clicks to populate from state variables or API responses\n - **API Loading**: Fetch data and populate fields when modal opens\n - **State Variables**: Populate from existing application state\n4. **Form Validation**: Use `required={true}` on form components and validate in submit handlers\n5. **Form Reset**: Always reset form fields when canceling or after successful submission\n6. **Modal Control**: Prefer `SbEventFlow.controlModal()` over directly setting modal open property\n\n### Form Layout Best Practices\n\n- **Container Structure**: Always wrap forms in `SbContainer` with `layout=\"vertical\"`\n- **Consistent Spacing**: Use `spacing={Dim.px(12)}` for form field spacing\n- **Full Width**: Make form fields and containers `width={Dim.fill()}` for proper alignment\n- **Modal Structure**: Use header, content, and footer containers with appropriate spacing\n- **Button Alignment**: Use `horizontalAlign=\"right\"` for the footer containers in modals that contain buttons\n";
2
2
  //# sourceMappingURL=superblocks-forms.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-forms.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-forms.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,o5bAAo5b,CAAC"}
1
+ {"version":3,"file":"superblocks-forms.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-forms.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,+pcAAqpc,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  // Auto-generated from superblocks-forms.md
3
3
  // Do not edit this file directly
4
- // Generated at: 2025-06-15T06:08:09.959Z
5
- export const content = "### Form Layouts in Superblocks\n\nWhen creating forms using form field components, follow these rules:\n\n1. Always put form components together inside an `SbContainer` with `layout=\"vertical\"`, `width={Dim.fill()}`, and appropriate `spacing`\n2. Use `spacing={Dim.px(12)}` or similar for consistent form field spacing\n3. Do not change the label position on form components (like `SbInput`). The default is the label is above the input and we want to keep that\n4. Make all form field components and any container parents be `width={Dim.fill()}` so they are all aligned horizontally and easy to use\n\n**Example:**\n\n```jsx\n<SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput label=\"First Name\" bind={FirstName} width={Dim.fill()} />\n <SbInput label=\"Last Name\" bind={LastName} width={Dim.fill()} />\n <SbInput label=\"Email\" bind={Email} inputType=\"EMAIL\" width={Dim.fill()} />\n</SbContainer>\n```\n\n### Forms inside Modals\n\nIt's common to put a form inside a Modal, like for creating or editing an entity. Here are comprehensive examples showing different patterns:\n\n#### Basic Create Form Modal\n\n```tsx\n// Import required components and utilities\nimport {\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\n// ...\n\nconst {\n NewOrderCustomerName,\n NewOrderCustomerEmail,\n NewOrderAmount,\n NewOrderStatus,\n NewOrderNotes,\n OrdersStateVar,\n CreateOrderModal,\n} = Page1;\n\n<SbModal bind={CreateOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Create New Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Fill out the form below to create a new order\" />\n </SbContainer>\n\n {/* Form Content */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={NewOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={NewOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={NewOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.runJS(() => {\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(\"CreateOrderModal\", \"close\")}\n />\n <SbButton\n label=\"Create Order\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Create new order using the form values\n const newOrder = {\n id: `ORD_${Math.floor(Math.random() * 10000)\n .toString()\n .padStart(4, \"0\")}`,\n customerName: NewOrderCustomerName.value,\n customerEmail: NewOrderCustomerEmail.value,\n amount: NewOrderAmount.value,\n status: NewOrderStatus.selectedOptionValue,\n notes: NewOrderNotes.value,\n createdAt: new Date().toISOString(),\n };\n\n // Add to orders list or call API\n OrdersStateVar.setValue([...OrdersStateVar.value, newOrder]);\n\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(\"CreateOrderModal\", \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>;\n```\n\n#### Table with Edit Form Modal\n\nThis example shows a more complete pattern where a table displays data and clicking a row opens an edit modal with the form fields pre-populated:\n\n```tsx\n// Import required components and utilities\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n sbComputed,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst {\n OrdersTable,\n EditOrderModal,\n EditOrderCustomerName,\n EditOrderCustomerEmail,\n EditOrderAmount,\n EditOrderStatus,\n EditOrderNotes,\n OrdersStateVar,\n} = Page1;\n\n// Main page with table\n<SbPage name=\"Page1\" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()} spacing={Dim.px(24)}>\n <SbText\n text=\"Orders Management\"\n textStyle={{ variant: \"heading2\" }}\n />\n\n <SbTable\n bind={OrdersTable}\n tableData={sbComputed(() => OrdersStateVar.value)}\n onRowClick={SbEventFlow.runJS((event) => {\n // Populate form fields with the selected row data\n EditOrderCustomerName.text = event.row.customerName;\n EditOrderCustomerEmail.text = event.row.customerEmail;\n EditOrderAmount.text = event.row.amount;\n EditOrderStatus.metaSelectedOptionValue = event.row.status;\n EditOrderNotes.text = event.row.notes || \"\";\n })\n // Open the edit modal\n .controlModal(\"EditOrderModal\", \"open\")}\n width={Dim.fill()}\n height={Dim.fill()}\n />\n </SbColumn>\n </SbSection>\n</SbPage>\n\n// Edit modal with form pre-populated from table row\n<SbModal bind={EditOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Edit Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Update the order details below\" />\n </SbContainer>\n\n {/* Form Content - Fields are pre-populated by onRowClick */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={EditOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={EditOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={EditOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.controlModal(\"EditOrderModal\", \"close\")}\n />\n <SbButton\n label=\"Save Changes\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Find and update the order in the orders array\n const updatedOrders = OrdersStateVar.value.map(order => {\n if (order.id === OrdersTable.selectedRow.id) {\n return {\n ...order,\n customerName: EditOrderCustomerName.value,\n customerEmail: EditOrderCustomerEmail.value,\n amount: EditOrderAmount.value,\n status: EditOrderStatus.selectedOptionValue,\n notes: EditOrderNotes.value,\n updatedAt: new Date().toISOString(),\n };\n }\n return order;\n });\n\n // Update the orders state\n OrdersStateVar.setValue(updatedOrders);\n })\n .controlModal(\"EditOrderModal\", \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>\n```\n\n**Corresponding scope.ts file for the table + edit modal example:**\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n} from \"@superblocksteam/library\";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n EditOrderModal: any;\n EditOrderCustomerName: any;\n EditOrderCustomerEmail: any;\n EditOrderAmount: any;\n EditOrderStatus: any;\n EditOrderNotes: any;\n OrdersStateVar: any;\n}>(\n () => ({\n OrdersStateVar: SbVariable({\n defaultValue: [\n {\n id: 1,\n customerName: \"John Doe\",\n customerEmail: \"john@example.com\",\n amount: 150.0,\n status: \"pending\",\n notes: \"Rush order\",\n createdAt: \"2024-01-15T10:30:00Z\",\n },\n {\n id: 2,\n customerName: \"Jane Smith\",\n customerEmail: \"jane@example.com\",\n amount: 89.99,\n status: \"delivered\",\n notes: \"\",\n createdAt: \"2024-01-14T14:20:00Z\",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: \"Page1\",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\n#### Alternative Population Method - Button with State Variable\n\nHere's another common pattern where a button populates form fields from a state variable:\n\n```tsx\n// Button that loads selected user data into edit form\n<SbButton\n label=\"Edit Selected User\"\n onClick={SbEventFlow.runJS(() => {\n const selectedUser = SelectedUserStateVar.value;\n\n // Populate form fields from state variable\n EditUserName.text = selectedUser.name;\n EditUserEmail.text = selectedUser.email;\n EditUserRole.metaSelectedOptionValue = selectedUser.role;\n EditUserDepartment.text = selectedUser.department;\n }).controlModal(\"EditUserModal\", \"open\")}\n/>\n```\n\n### Key Form Patterns\n\n1. **Create Forms**: Start with empty fields, populate from user input\n2. **Edit Forms**: Pre-populate fields with existing data from various sources\n3. **Field Population Methods**:\n - **Table Row Selection**: Use `onRowClick` to set form field values to `s.row.{columnName}` (most common)\n - **Button Actions**: Use button clicks to populate from state variables or API responses\n - **API Loading**: Fetch data and populate fields when modal opens\n - **State Variables**: Populate from existing application state\n4. **Form Validation**: Use `required={true}` on form components and validate in submit handlers\n5. **Form Reset**: Always reset form fields when canceling or after successful submission\n6. **Modal Control**: Prefer `SbEventFlow.controlModal()` over directly setting modal open property\n\n### Form Layout Best Practices\n\n- **Container Structure**: Always wrap forms in `SbContainer` with `layout=\"vertical\"`\n- **Consistent Spacing**: Use `spacing={Dim.px(12)}` for form field spacing\n- **Full Width**: Make form fields and containers `width={Dim.fill()}` for proper alignment\n- **Modal Structure**: Use header, content, and footer containers with appropriate spacing\n- **Button Alignment**: Use `horizontalAlign=\"right\"` for the footer containers in modals that contain buttons\n";
4
+ // Generated at: 2025-06-23T03:26:44.020Z
5
+ export const content = "### Form Layouts in Superblocks\n\n**🚨 CRITICAL: Remember that sbComputed cannot be used as React children.** When building forms, all dynamic content must be in component properties (like `text={}`, `label={}`) not as children.\n\nWhen creating forms using form field components, follow these rules:\n\n1. Always put form components together inside an `SbContainer` with `layout=\"vertical\"`, `width={Dim.fill()}`, and appropriate `spacing`\n2. Use `spacing={Dim.px(12)}` or similar for consistent form field spacing\n3. Do not change the label position on form components (like `SbInput`). The default is the label is above the input and we want to keep that\n4. Make all form field components and any container parents be `width={Dim.fill()}` so they are all aligned horizontally and easy to use\n\n**Example:**\n\n```jsx\n<SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput label=\"First Name\" bind={FirstName} width={Dim.fill()} />\n <SbInput label=\"Last Name\" bind={LastName} width={Dim.fill()} />\n <SbInput label=\"Email\" bind={Email} inputType=\"EMAIL\" width={Dim.fill()} />\n</SbContainer>\n```\n\n### Forms inside Modals\n\nIt's common to put a form inside a Modal, like for creating or editing an entity. Here are comprehensive examples showing different patterns:\n\n#### Basic Create Form Modal\n\n```tsx\n// Import required components and utilities\nimport {\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\n// ...\n\nconst {\n NewOrderCustomerName,\n NewOrderCustomerEmail,\n NewOrderAmount,\n NewOrderStatus,\n NewOrderNotes,\n OrdersStateVar,\n CreateOrderModal,\n} = Page1;\n\n<SbModal bind={CreateOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Create New Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Fill out the form below to create a new order\" />\n </SbContainer>\n\n {/* Form Content */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={NewOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={NewOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={NewOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={NewOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.runJS(() => {\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(CreateOrderModal, \"close\")}\n />\n <SbButton\n label=\"Create Order\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Create new order using the form values\n const newOrder = {\n id: `ORD_${Math.floor(Math.random() * 10000)\n .toString()\n .padStart(4, \"0\")}`,\n customerName: NewOrderCustomerName.value,\n customerEmail: NewOrderCustomerEmail.value,\n amount: NewOrderAmount.value,\n status: NewOrderStatus.selectedOptionValue,\n notes: NewOrderNotes.value,\n createdAt: new Date().toISOString(),\n };\n\n // Add to orders list or call API\n OrdersStateVar.setValue([...OrdersStateVar.value, newOrder]);\n\n // Reset form components\n NewOrderCustomerName.text = \"\";\n NewOrderCustomerEmail.text = \"\";\n NewOrderAmount.text = \"\";\n NewOrderStatus.metaSelectedOptionValue = \"\";\n NewOrderNotes.text = \"\";\n })\n // Note how we prefer use controlModal for handling opening/closing\n // the modal rather than setting the modal's open property directly\n .controlModal(CreateOrderModal, \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>;\n```\n\n#### Table with Edit Form Modal\n\nThis example shows a more complete pattern where a table displays data and clicking a row opens an edit modal with the form fields pre-populated:\n\n```tsx\n// Import required components and utilities\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbTable,\n SbModal,\n SbContainer,\n SbText,\n SbInput,\n SbDropdown,\n SbButton,\n Dim,\n SbEventFlow,\n sbComputed,\n} from \"@superblocksteam/library\";\nimport { Page1 } from \"./scope\";\n\nconst {\n OrdersTable,\n EditOrderModal,\n EditOrderCustomerName,\n EditOrderCustomerEmail,\n EditOrderAmount,\n EditOrderStatus,\n EditOrderNotes,\n OrdersStateVar,\n} = Page1;\n\n// Main page with table\n<SbPage name=\"Page1\" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()} spacing={Dim.px(24)}>\n <SbText\n text=\"Orders Management\"\n textStyle={{ variant: \"heading2\" }}\n />\n\n <SbTable\n bind={OrdersTable}\n tableData={sbComputed(() => OrdersStateVar.value)}\n onRowClick={SbEventFlow.runJS(() => {\n // Populate form fields with the selected row data\n EditOrderCustomerName.text = OrdersTable.selectedRow.customerName;\n EditOrderCustomerEmail.text = OrdersTable.selectedRow.customerEmail;\n EditOrderAmount.text = OrdersTable.selectedRow.amount;\n EditOrderStatus.metaSelectedOptionValue = OrdersTable.selectedRow.status;\n EditOrderNotes.text = OrdersTable.selectedRow.notes || \"\";\n })\n // Open the edit modal\n .controlModal(EditOrderModal, \"open\")}\n width={Dim.fill()}\n height={Dim.fill()}\n />\n </SbColumn>\n </SbSection>\n</SbPage>\n\n// Edit modal with form pre-populated from table row\n<SbModal bind={EditOrderModal}>\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(24)}>\n {/* Modal Header */}\n <SbContainer layout=\"vertical\" spacing={Dim.px(8)}>\n <SbText\n text=\"Edit Order\"\n textStyle={{\n variant: \"heading4\",\n }}\n />\n <SbText text=\"Update the order details below\" />\n </SbContainer>\n\n {/* Form Content - Fields are pre-populated by onRowClick */}\n <SbContainer layout=\"vertical\" width={Dim.fill()} spacing={Dim.px(12)}>\n <SbInput\n bind={EditOrderCustomerName}\n width={Dim.fill()}\n label=\"Customer Name\"\n placeholderText=\"Enter customer name\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderCustomerEmail}\n width={Dim.fill()}\n label=\"Customer Email\"\n inputType=\"EMAIL\"\n placeholderText=\"Enter customer email\"\n required={true}\n />\n\n <SbInput\n bind={EditOrderAmount}\n width={Dim.fill()}\n label=\"Order Amount\"\n placeholderText=\"Enter order amount\"\n inputType=\"NUMBER\"\n required={true}\n />\n\n <SbDropdown\n bind={EditOrderStatus}\n width={Dim.fill()}\n label=\"Order Status\"\n options={[\n {\n label: \"Pending\",\n value: \"pending\",\n },\n {\n label: \"Processing\",\n value: \"processing\",\n },\n {\n label: \"En route\",\n value: \"en_route\",\n },\n {\n label: \"Delivered\",\n value: \"delivered\",\n },\n {\n label: \"Refunded\",\n value: \"refunded\",\n },\n ]}\n required={true}\n />\n\n <SbInput\n bind={EditOrderNotes}\n width={Dim.fill()}\n label=\"Order Notes\"\n placeholderText=\"Optional notes about the order\"\n multiline={true}\n />\n </SbContainer>\n\n {/* Modal Footer */}\n <SbContainer\n layout=\"horizontal\"\n horizontalAlign=\"right\"\n spacing={Dim.px(12)}\n width={Dim.fill()}\n >\n <SbButton\n label=\"Cancel\"\n variant=\"secondary\"\n onClick={SbEventFlow.controlModal(EditOrderModal, \"close\")}\n />\n <SbButton\n label=\"Save Changes\"\n variant=\"primary\"\n onClick={SbEventFlow.runJS(() => {\n // Find and update the order in the orders array\n const updatedOrders = OrdersStateVar.value.map(order => {\n if (order.id === OrdersTable.selectedRow.id) {\n return {\n ...order,\n customerName: EditOrderCustomerName.value,\n customerEmail: EditOrderCustomerEmail.value,\n amount: EditOrderAmount.value,\n status: EditOrderStatus.selectedOptionValue,\n notes: EditOrderNotes.value,\n updatedAt: new Date().toISOString(),\n };\n }\n return order;\n });\n\n // Update the orders state\n OrdersStateVar.setValue(updatedOrders);\n })\n .controlModal(EditOrderModal, \"close\")}\n />\n </SbContainer>\n </SbContainer>\n</SbModal>\n```\n\n**Corresponding scope.ts file for the table + edit modal example:**\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n} from \"@superblocksteam/library\";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n EditOrderModal: any;\n EditOrderCustomerName: any;\n EditOrderCustomerEmail: any;\n EditOrderAmount: any;\n EditOrderStatus: any;\n EditOrderNotes: any;\n OrdersStateVar: any;\n}>(\n () => ({\n OrdersStateVar: SbVariable({\n defaultValue: [\n {\n id: 1,\n customerName: \"John Doe\",\n customerEmail: \"john@example.com\",\n amount: 150.0,\n status: \"pending\",\n notes: \"Rush order\",\n createdAt: \"2024-01-15T10:30:00Z\",\n },\n {\n id: 2,\n customerName: \"Jane Smith\",\n customerEmail: \"jane@example.com\",\n amount: 89.99,\n status: \"delivered\",\n notes: \"\",\n createdAt: \"2024-01-14T14:20:00Z\",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: \"Page1\",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\n#### Alternative Population Method - Button with State Variable\n\nHere's another common pattern where a button populates form fields from a state variable:\n\n```tsx\n// Button that loads selected user data into edit form\n<SbButton\n label=\"Edit Selected User\"\n onClick={SbEventFlow.runJS(() => {\n const selectedUser = SelectedUserStateVar.value;\n\n // Populate form fields from state variable\n EditUserName.text = selectedUser.name;\n EditUserEmail.text = selectedUser.email;\n EditUserRole.metaSelectedOptionValue = selectedUser.role;\n EditUserDepartment.text = selectedUser.department;\n }).controlModal(EditUserModal, \"open\")}\n/>\n```\n\n### Key Form Patterns\n\n1. **Create Forms**: Start with empty fields, populate from user input\n2. **Edit Forms**: Pre-populate fields with existing data from various sources\n3. **Field Population Methods**:\n - **Table Row Selection**: Use `onRowClick` to set form field values to `{TableName}.selectedRow.{columnName}` (most common)\n - **Button Actions**: Use button clicks to populate from state variables or API responses\n - **API Loading**: Fetch data and populate fields when modal opens\n - **State Variables**: Populate from existing application state\n4. **Form Validation**: Use `required={true}` on form components and validate in submit handlers\n5. **Form Reset**: Always reset form fields when canceling or after successful submission\n6. **Modal Control**: Prefer `SbEventFlow.controlModal()` over directly setting modal open property\n\n### Form Layout Best Practices\n\n- **Container Structure**: Always wrap forms in `SbContainer` with `layout=\"vertical\"`\n- **Consistent Spacing**: Use `spacing={Dim.px(12)}` for form field spacing\n- **Full Width**: Make form fields and containers `width={Dim.fill()}` for proper alignment\n- **Modal Structure**: Use header, content, and footer containers with appropriate spacing\n- **Button Alignment**: Use `horizontalAlign=\"right\"` for the footer containers in modals that contain buttons\n";
6
6
  //# sourceMappingURL=superblocks-forms.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"superblocks-forms.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-forms.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,2CAA2C;AAC3C,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,i5bAAi5b,CAAC"}
1
+ {"version":3,"file":"superblocks-forms.js","sourceRoot":"","sources":["../../../../../src/ai-service/prompts/generated/subprompts/superblocks-forms.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,2CAA2C;AAC3C,iCAAiC;AACjC,yCAAyC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,kpcAAkpc,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  // Auto-generated from superblocks-layouts.md
3
3
  // Do not edit this file directly
4
- // Generated at: 2025-06-15T06:08:09.959Z
4
+ // Generated at: 2025-06-23T03:26:44.020Z
5
5
  export const content = "### Layout and Sizing in Superblocks\n\n- `SbSection` should only be used as a child of `SbPage` and `SbColumn` only used as a child of `SbSection`\n- All other layouts in Superblocks are configured using the `SbContainer` component\n- `SbContainer` provides both layout and optional visual styling.\n\n```jsx\n<SbContainer\n variant=\"card\" | \"none\" // default is \"none\"\n layout=\"vertical\" | \"horizontal\" | \"freeform\" // default is \"vertical\"\n>\n {/* Children here */}\n</SbContainer>\n```\n\nWe have three main layout options in Superblocks for `SbContainer` and `SbColumn`:\n\n- Vertical Stack (`vertical`)\n- Horizontal Stack (`horizontal`)\n- Freeform (`freeform`)\n\nFor new designs, we recommend using Horizontal or Vertical Stacks for almost all use cases, especially Vertical Stacks.\n\nThe `variant` prop is optional and can be set to `\"card\"` or `\"none\"`. Default is `\"none\"`.\n`\"card\"` applies a card-like visual style to the container, such as rounded corners, white background, and padding.\n\n**When to use each variant:**\n\n- `variant=\"none\"` - For pure layout containers (by far most common)\n- `variant=\"card\"` - When you need visual separation with padding, borders, and background\n\n---\n\n### Height and Width Options\n\nAll Superblocks components support width and height. They take in a `Dim` object, which has 3 main options:\n\n- `Dim.fit()`: Fit to content size, this is the default behavior and can be omitted.\n- `Dim.px(100)`: Fixed pixel size.\n- `Dim.fill()` or `Dim.fill(2)`: Fill available space with an optional weight.\n\n> IMPORTANT: Prefer using `Dim.fit()` over `Dim.px()` for height and width unless you have a specific reason to use fixed pixel sizes. This is extra true for containers\n> IMPORTANT: Prefer using `Dim.fill()` or `Dim.fit()` over `Dim.px()` for width unless you have a specific reason to use fixed pixel sizes.\n\n**Examples**:\n\n```jsx\n<SbText width={Dim.px(2)}>Hello</SbText> // 2 pixels\n<SbText width={Dim.fit()}>Hello</SbText> // Fit to content (default)\n<SbText width={Dim.fill()}>Hello</SbText> // Fill available space, no weight (aka 1)\n<SbText width={Dim.fill(2)}>Hello</SbText> // Fill available space, with weight of 2\n```\n\n---\n\n### Spacing Between Components\n\n`SbContainer` has a **default spacing of `Dim.px(6)`** between child components when using `layout=\"vertical\"` or `layout=\"horizontal\"`. You can override this default when you need different spacing.\n\n```jsx\n{\n /* Uses default 6px spacing */\n}\n<SbContainer layout=\"vertical\">\n <SbText text=\"First item\" />\n <SbText text=\"Second item\" />\n <SbText text=\"Third item\" />\n</SbContainer>;\n\n{\n /* Override with custom spacing */\n}\n<SbContainer layout=\"vertical\" spacing={Dim.px(12)}>\n <SbText text=\"First item\" />\n <SbText text=\"Second item\" />\n</SbContainer>;\n\n{\n /* No spacing (components touch) - often useful for nested containers */\n}\n<SbContainer layout=\"horizontal\" spacing={Dim.px(0)}>\n <SbContainer />\n <SbContainer />\n</SbContainer>;\n```\n\n**Common spacing values:**\n\n- `spacing={Dim.px(0)}` - No spacing (components touch)\n- Default `Dim.px(6)` - Minimal spacing (used if spacing prop omitted)\n- `spacing={Dim.px(12)}` - Comfortable spacing for buttons/controls/form fields\n- `spacing={Dim.px(24)}` - Loose spacing for distinct sections\n\n**Best practices:**\n\n- The default 6px spacing works well for most layouts\n- Override spacing when you need tighter control or larger gaps\n- DO NOT add margins to components - use container spacing instead\n- Try to use consistent spacing values throughout your app\n\n---\n\n### Standard Page Structure\n\n**CRITICAL**: All new Superblocks apps must follow this standard page structure:\n\n```tsx\n<SbPage name=\"Page1\" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>{/* Your page content goes here */}</SbColumn>\n </SbSection>\n</SbPage>\n```\n\nNote that `SbSection` and `SbColumn` can only be used inside `SbPage`. For anything inside an `SbModal` or nested deeper inside an `SbColumn`, use an `SbContainer`.\n\n#### App headers\n\n- If you want to have a header section for your app, that's best done in its own `SbSection` above the main content's `SbSection`.\n- Put any background color on the section itself, as the columns are padded in from the edge by default\n\nExample:\n\n```tsx\n<SbPage name=\"Page1\" height={Dim.fill()} width={Dim.fill()}>\n {/* App header Section */}\n <SbSection height={Dim.fit()} backgroundColor=\"#90EE90\">\n <SbColumn\n width={Dim.fill()}\n layout=\"horizontal\"\n horizontalAlign=\"space-between\"\n >\n <SbText text=\"My App\" textStyle={{ variant: \"heading2\" }} />\n <SbButton label=\"New Item\" />\n </SbColumn>\n </SbSection>\n\n {/* Main Content Section */}\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbTable tableData={sbComputed(() => myData.response)} />\n </SbColumn>\n </SbSection>\n</SbPage>\n```\n\n#### Column and Container Width Guidelines\n\n**Default Rule**: All columns under a section, and almost all Containers (especially if they are the root of a Column or Modal) should use `width={Dim.fill()}` unless you have a really good reason not to.\n\n**Good Reason Example** - Fixed Sidebar Layout:\nWhen you need a fixed-width sidebar alongside a flexible content area:\n\n```tsx\n<SbPage name=\"Page1\" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n {/* Fixed sidebar column */}\n <SbColumn width={Dim.px(250)}>\n <SbText text=\"Sidebar content\" />\n <SbButton label=\"Menu Item 1\" />\n <SbButton label=\"Menu Item 2\" />\n </SbColumn>\n\n {/* Flexible content column */}\n <SbColumn width={Dim.fill()}>\n <SbText text=\"Main content area that fills remaining space\" />\n <SbTable tableData={sbComputed(() => myApi.response)} />\n </SbColumn>\n </SbSection>\n</SbPage>\n```\n\nIn this example:\n\n- Left column uses `width={Dim.px(250)}` for a fixed 250px sidebar\n- Right column uses `width={Dim.fill()}` to take up all remaining space\n- This creates a responsive layout where the sidebar stays fixed while the content area adapts\n\n### Layouts for modals\n\n- SbModal components should always use an SbContainer with layout=vertical as the root of their content\n- SbModal components DO NOT need to have their own close button. The modal component comes with a close button by default\n- Put the header of the modal into its own `SbContainer` and the footer in its own `SbContainer`. If the footer has buttons for actions, ensure you add `horizontalAlign=\"right\"` to the container\n\n**Modal Content Width Guidelines:**\n\nMost components inside modals should use `width={Dim.fill()}` to prevent left-aligned, inconsistent layouts:\n\n- Root container: `<SbContainer layout=\"vertical\" width={Dim.fill()}>`\n- Form fields: `<SbInput bind={...} width={Dim.fill()} />`\n- Form containers: `<SbContainer layout=\"vertical\" width={Dim.fill()}>`\n\n**Exceptions:** Some components work better with default `Dim.fit()` width:\n\n- Footer buttons (SbButton) - wide buttons look awkward\n- Icons, small text labels, or decorative elements\n\n**Good Example:** See the modal examples in `superblocks-forms.md` where the footer container uses `width={Dim.fill()}` but the Cancel/Submit buttons inside use default fit width for proper proportions.\n";
6
6
  //# sourceMappingURL=superblocks-layouts.js.map