@superblocksteam/cli 2.0.0-next.11 → 2.0.0-next.13
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.
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ $ npm install -g @superblocksteam/cli
|
|
|
14
14
|
$ superblocks COMMAND
|
|
15
15
|
running command...
|
|
16
16
|
$ superblocks (--version)
|
|
17
|
-
@superblocksteam/cli/2.0.0-next.
|
|
17
|
+
@superblocksteam/cli/2.0.0-next.13 linux-x64 node-v20.19.0
|
|
18
18
|
$ superblocks --help [COMMAND]
|
|
19
19
|
USAGE
|
|
20
20
|
$ superblocks COMMAND
|
|
@@ -36,7 +36,7 @@ var content3 = '# Custom Components\n\n- ULTRA CRITICAL: NEVER use Superblocks c
|
|
|
36
36
|
|
|
37
37
|
// ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-event-flow.js
|
|
38
38
|
init_cjs_shims();
|
|
39
|
-
var content4 = '# 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\n<SbButton onClick={SbEventFlow.setStateVar(
|
|
39
|
+
var content4 = '# 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.role === "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';
|
|
40
40
|
|
|
41
41
|
// ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-layouts.js
|
|
42
42
|
init_cjs_shims();
|
|
@@ -52,7 +52,7 @@ var content7 = '- The `routes.json` file maps URLs to pages.\n Example routes.j
|
|
|
52
52
|
|
|
53
53
|
// ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-state.js
|
|
54
54
|
init_cjs_shims();
|
|
55
|
-
var content8 = '**Superblocks State System**\n\nThe Superblocks state system is built around scopes that contain entities (variables, APIs, components). Here\'s how it works:\n\n### 1. Scopes\n\nScopes are defined in separate `scope.ts` files for each page and contain all the page\'s entities.\n\n- **Page scopes** are visible only within the current page\n- **App scopes** can be shared across pages (though you should primarily use page scopes)\n- Entities are accessed by importing and destructuring from the scope\n\n> **Parent \u2192 child rule**: Child scopes can read & write parent entities, but parents cannot reach into children.\n\n### 2. Scope Structure\n\nEach page has its own scope file that defines all entities:\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n SbApi,\n sbComputed,\n} from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n}>(\n ({ entities: { counter } }) => ({\n // Static state variable with a simple default value\n counter: SbVariable({\n defaultValue: 0,\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n // State variable with computed default value from other entities\n doubledCounter: SbVariable({\n defaultValue: sbComputed(() => counter.value * 2),\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n myApi: SbApi({}),\n }),\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\nThen in your page component, you import and destructure the entities:\n\n```tsx\n// pages/Page1/index.tsx\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbText,\n SbButton,\n sbComputed,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nfunction Page() {\n // Destructure entities for easy access\n const { counter, doubledCounter, myApi, OrdersTable } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbText text={sbComputed(() => `Count: ${counter.value}`)} />\n <SbButton onClick={SbEventFlow.setStateVar("counter", 5)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n}\n\nexport default registerPage(Page, Page1Scope);\n```\n\n_You should NOT create any extra scopes other than page scopes in most cases._\n\n### 3. Computed Default Values\n\nState variables can have their `defaultValue` computed from other entities in the same scope at initialization time.\n\n**Static default value:**\n\n```ts\nstaticVar: SbVariable({\n defaultValue: "Hello World",\n});\n```\n\n**Computed default value:**\n\n```ts\n({ entities: { Input1, staticVar } }) => ({\n computedVar: SbVariable({\n defaultValue: sbComputed(() => `${staticVar.value} - ${Input1.value}`),\n }),\n});\n```\n\nWrap the entire scope object with the entities function and destructure needed entities from the `entities` parameter. This only sets the initial value - it doesn\'t create ongoing updates.\n\n### 4. Entity Types\n\n- **Component state**\n\n - Declared by defining the component type in the scope and using the `bind` prop\n - Accessed by destructuring the component entity and using `sbComputed(() => ComponentName.prop)`\n - Writable if the prop is marked writable in the schema\n\n- **State variable**\n\n - Declared with `SbVariable({ defaultValue })` or within `(({ entities }) => ({ ... }))` wrapper for computed defaults\n - `defaultValue` sets the initial value when the application loads\n - For static variables: Only JSON parsable data structures, no functions\n - For computed variables: Use `sbComputed` within defaultValue to reference other entities\n - Do not call `defaultValue` like a function. Set values with `SbEventFlow.setStateVar()` or read with `sbComputed(() => varName.value)`\n - Accessed with `sbComputed(() => varName.value)` \u2014 **always include `.value`**\n - Writable through SbEventFlow\n\n- **API**\n - Declared with `SbApi({})` in the scope file.\n - Accessed with `sbComputed(() => apiName.response)` or `sbComputed(() => apiName.error)`\n - Read\u2011only\n\n### 5. Reading State with sbComputed\n\n**CRITICAL**: There are two different patterns for accessing data in `sbComputed` depending on what you\'re accessing:\n\n#### 5.1. Scope Entities (Direct Access)\n\nFor entities defined in your scope file (variables, APIs, components), access them **directly** after destructuring:\n\n```tsx\nconst { UserSearchInput, myVariable, myApi } = Page1;\n\n// \u2705 CORRECT - Direct access for scope entities\n<SbText text={sbComputed(() => `Search: ${UserSearchInput.value}`)} />\n<SbText text={sbComputed(() => myVariable.value)} />\n<SbTable tableData={sbComputed(() => myApi.response)} />\n```\n\n#### 4.2. Global State (Import Access)\n\nFor global state like globals, theme, environment, and embedded data, import the globals directly from the library:\n\n```tsx\n// \u2705 CORRECT - Import globals directly\n<SbText\n text={sbComputed(() => `Welcome ${Global.user.name}!`)}\n textStyle={{\n textColor: {\n default: sbComputed(() => Theme.colors.neutral900)\n }\n }}\n/>\n<SbContainer backgroundColor={sbComputed(() => Theme.colors.primary)} />\n```\n\n#### 5.3. Mixed Access\n\nWhen you need both scope entities and global state in the same `sbComputed`:\n\n```tsx\nconst { orders } = Page1;\n\n// \u2705 CORRECT - Combine direct entity access with imported globals\n<SbText\n text={sbComputed(() => `${orders.length} orders for ${Global.user.name}`)}\n/>;\n```\n\n### 6. Writing State\n\nPreferred approach:\n\n```tsx\nSbEventFlow.setStateVar("pageSize", 50);\n```\n\nFallback for complex operations:\n\n```tsx\nSbEventFlow.runJS(() => {\n // Direct assignment works within SbEventFlow.runJS\n pageSize.value = 50;\n});\n```\n\n### 7. CRITICAL Rules\n\n1. **Use component state directly**; NEVER create a state variable for a value that is available directly from a component property.\n2. Use component bindings by defining component types in your scope and using the `bind` prop.\n3. Keep logic declarative \u2014 derive UI from state using `sbComputed` instead of mutating props at runtime.\n4. Always destructure entities from your scope for clean access patterns.\n5. **Use the correct sbComputedz pattern**: Direct access for scope entities, import globals (Global, Theme, Embed, Env) for global access.\n6. Always complete implement all features, don\'t stub out or skip anything.\n\n**\u2705 Example**\n\n```tsx\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n ApplicantSelector: any;\n}>(\n () => ({\n applicants: SbVariable({ defaultValue: [] }),\n }),\n {\n name: "Page1",\n },\n);\n```\n\n```tsx\n// In your page component after destructuring entities\nconst { ApplicantSelector, applicants } = Page1;\n\n<SbDropdown bind={ApplicantSelector} options={/* ... */} />\n<SbTable tableData={sbComputed(() => applicants[ApplicantSelector.selectedOptionValue])} />\n```\n\n```tsx\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n FirstName: any;\n LastName: any;\n}>(\n ({ entities: { FirstName, LastName } }) => ({\n applicants: SbVariable({ defaultValue: [] }),\n fullName: SbVariable({\n defaultValue: sbComputed(() =>\n `${FirstName.value} ${LastName.value}`.trim(),\n ),\n }),\n }),\n {\n name: "Page1",\n },\n);\n```\n\n```tsx\nconst { FirstName, LastName, fullName } = Page1;\n\n<SbInput bind={FirstName} placeholder="First name" />\n<SbInput bind={LastName} placeholder="Last name" />\n<SbText text={sbComputed(() => `Welcome ${fullName.value}!`)} />\n```\n\n```tsx\n{\n /* The user types in the search input, and the value is displayed */\n}\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n searchTerm: any;\n}>(() => ({}), {\n name: "Page1",\n});\n```\n\n```tsx\nconst { searchTerm } = Page1;\n\n<SbInput bind={searchTerm} />\n<SbText text={sbComputed(() => searchTerm.value)} />\n```\n\n```tsx\n{\n /* Switch to change into admin mode */\n}\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n isAdmin: any;\n}>(() => ({}), {\n name: "Page1",\n});\n```\n\n```tsx\nconst { isAdmin } = Page1;\n\n<SbSwitch bind={isAdmin} label="Use Admin Mode" defaultChecked={false} />;\n{\n /* Only enable the delete button when switched into Admin mode */\n}\n<SbButton\n disabled={sbComputed(() => !isAdmin.isChecked)}\n label="Delete profile"\n/>;\n```\n\n\u2705 ALWAYS USE DIRECT COMPONENT STATE ACCESS WITH sbComputed:\n\n```tsx\n// GOOD - DO THIS\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n UserNameInput: any;\n}>(() => ({}), {\n name: "Page1",\n});\n```\n\n```tsx\nconst { UserNameInput } = Page1;\n\n<SbTextInput bind={UserNameInput} />\n<SbText text={sbComputed(() => `Hello, ${UserNameInput.value}!`)} />\n```\n\n\u274C NEVER CREATE REDUNDANT STATE VARIABLES:\n\n```tsx\n// WRONG - DON\'T DO THIS\n<SbTextInput bind={UserNameInput} onChange={SbEventFlow.setStateVar(\'userNameVar\', \'myValue\')} />\n<SbText text={sbComputed(() => `Hello, ${userNameVar.value}!`)} />\n...\n// And then in scope.ts:\n{\n userNameVar: SbVariable({ defaultValue: "" }),\n}\n```\n\nTo reference a property of a component using `sbComputed`, the component must have a binding defined in your scope.\n\nThat\'s why you should ALWAYS define component bindings in your scope for the following component types when you need to access their state:\n\n- SbInput\n- SbDropdown\n- SbDatePicker\n- SbCheckbox\n- SbSwitch\n- SbForm\n- SbRadio\n- SbRichText\n- SbFilePicker\n- SbCodeEditor\n- SbChat\n\n\u274C DO NOT USE STATE VARIABLES AS FUNCTIONS:\n\nState variables are not functions. You cannot call them or store functions in defaultValue.\n\n```tsx\n// WRONG - DON\'T DO THIS\nfunction Page1() {\n const { customerNameFilter, filterOrders } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbInput\n bind={customerNameFilter}\n label="Customer Name"\n placeholder="Filter by customer name"\n width={Dim.fill()}\n onTextChanged={SbEventFlow.runJS(() => {\n // This is wrong - you cannot call filterOrders as a function\n filterOrders();\n })}\n />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n}\n\n// And in scope.ts (WRONG):\n{\n filterOrders: SbVariable({\n defaultValue: () => {\n // This doesn\'t work - state variables are not functions\n const customerNameFilter = customerNameFilter.value.toLowerCase();\n // ... more logic\n },\n });\n}\n```\n\nInstead do the following:\n\n\u2705 COMPUTE VALUES WITH sbComputed AND SET STATE WITH SbEventFlow:\n\n```tsx\n// CORRECT - DO THIS\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbInput,\n SbButton,\n SbTable,\n sbComputed,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\n\nfunction Page1() {\n const { customerNameFilter, filteredOrders, orders } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbInput\n bind={customerNameFilter}\n label="Customer Name"\n placeholder="Filter by customer name"\n width={Dim.fill()}\n onTextChanged={SbEventFlow.runJS(() => {\n // Repeat the filtering logic inline - do NOT create helper functions\n const filtered = orders.value.filter((order) => {\n return (\n !customerNameFilter.value ||\n order.customerName\n .toLowerCase()\n .includes(customerNameFilter.value.toLowerCase())\n );\n });\n\n // Set the state variable with the computed result\n filteredOrders.value = filtered;\n })}\n />\n {/* If you need the same filtering logic elsewhere, repeat it inline */}\n <SbButton\n label="Apply Filter"\n onClick={SbEventFlow.runJS(() => {\n // Repeat the same filtering logic here - code repetition is preferred\n const filtered = orders.value.filter((order) => {\n return (\n !customerNameFilter.value ||\n order.customerName\n .toLowerCase()\n .includes(customerNameFilter.value.toLowerCase())\n );\n });\n\n filteredOrders.value = filtered;\n })}\n />\n <SbTable tableData={sbComputed(() => filteredOrders.value)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n}\n\nexport default registerPage(Page1, Page1Scope);\n```\n\nAnd in your scope.ts file:\n\n```ts\nexport const Page1Scope = createSbScope<{\n customerNameFilter: any;\n}>(\n () => ({\n orders: SbVariable({\n defaultValue: [\n {\n id: "ORD-1001",\n customerName: "John Smith",\n orderType: "Grocery Delivery",\n },\n {\n id: "ORD-1002",\n customerName: "Emily Johnson",\n orderType: "Express Delivery",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n filteredOrders: SbVariable({\n defaultValue: [],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: "Page1",\n },\n);\n```\n';
|
|
55
|
+
var content8 = '**Superblocks State System**\n\nThe Superblocks state system is built around scopes that contain entities (variables, APIs, components). Here\'s how it works:\n\n### 1. Scopes\n\nScopes are defined in separate `scope.ts` files for each page and contain all the page\'s entities.\n\n- **Page scopes** are visible only within the current page\n- **App scopes** can be shared across pages (though you should primarily use page scopes)\n- Entities are accessed by importing and destructuring from the scope\n\n> **Parent \u2192 child rule**: Child scopes can read & write parent entities, but parents cannot reach into children.\n\n### 2. Scope Structure\n\nEach page has its own scope file that defines all entities:\n\n```ts\n// pages/Page1/scope.ts\nimport {\n createSbScope,\n SbVariable,\n SbVariablePersistence,\n SbApi,\n sbComputed,\n} from "@superblocksteam/library";\n\nexport const Page1Scope = createSbScope<{\n OrdersTable: any;\n}>(\n ({ entities: { counter } }) => ({\n // Static state variable with a simple default value\n counter: SbVariable({\n defaultValue: 0,\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n // State variable with computed default value from other entities\n doubledCounter: SbVariable({\n defaultValue: sbComputed(() => counter.value * 2),\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n myApi: SbApi({}),\n }),\n {\n name: "Page1",\n },\n);\n\nexport const Page1 = Page1Scope.entities;\n```\n\nThen in your page component, you import and destructure the entities:\n\n```tsx\n// pages/Page1/index.tsx\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbText,\n SbButton,\n sbComputed,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\nimport { Page1, Page1Scope } from "./scope";\n\nfunction Page() {\n // Destructure entities for easy access\n const { counter, doubledCounter, myApi, OrdersTable } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbText text={sbComputed(() => `Count: ${counter.value}`)} />\n <SbButton onClick={SbEventFlow.setStateVar(counter, 5)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n}\n\nexport default registerPage(Page, Page1Scope);\n```\n\n_You should NOT create any extra scopes other than page scopes in most cases._\n\n### 3. Computed Default Values\n\nState variables can have their `defaultValue` computed from other entities in the same scope at initialization time.\n\n**Static default value:**\n\n```ts\nstaticVar: SbVariable({\n defaultValue: "Hello World",\n});\n```\n\n**Computed default value:**\n\n```ts\n({ entities: { Input1, staticVar } }) => ({\n computedVar: SbVariable({\n defaultValue: sbComputed(() => `${staticVar.value} - ${Input1.value}`),\n }),\n});\n```\n\nWrap the entire scope object with the entities function and destructure needed entities from the `entities` parameter. This only sets the initial value - it doesn\'t create ongoing updates.\n\n### 4. Entity Types\n\n- **Component state**\n\n - Declared by defining the component type in the scope and using the `bind` prop\n - Accessed by destructuring the component entity and using `sbComputed(() => ComponentName.prop)`\n - Writable if the prop is marked writable in the schema\n\n- **State variable**\n\n - Declared with `SbVariable({ defaultValue })` or within `(({ entities }) => ({ ... }))` wrapper for computed defaults\n - `defaultValue` sets the initial value when the application loads\n - For static variables: Only JSON parsable data structures, no functions\n - For computed variables: Use `sbComputed` within defaultValue to reference other entities\n - Do not call `defaultValue` like a function. Set values with `SbEventFlow.setStateVar(importedStateVarEntity, value)` or read with `sbComputed(() => importedStateVarEntity.value)`\n - Accessed with `sbComputed(() => varName.value)` \u2014 **always include `.value`**\n - Writable through SbEventFlow\n\n- **API**\n - Declared with `SbApi({})` in the scope file.\n - Accessed with `sbComputed(() => apiName.response)` or `sbComputed(() => apiName.error)`\n - Read\u2011only\n\n### 5. Reading State with sbComputed\n\n**CRITICAL**: There are two different patterns for accessing data in `sbComputed` depending on what you\'re accessing:\n\n#### 5.1. Scope Entities (Direct Access)\n\nFor entities defined in your scope file (variables, APIs, components), access them **directly** after destructuring:\n\n```tsx\nconst { UserSearchInput, myVariable, myApi } = Page1;\n\n// \u2705 CORRECT - Direct access for scope entities\n<SbText text={sbComputed(() => `Search: ${UserSearchInput.value}`)} />\n<SbText text={sbComputed(() => myVariable.value)} />\n<SbTable tableData={sbComputed(() => myApi.response)} />\n```\n\n#### 4.2. Global State (Import Access)\n\nFor global state like globals, theme, environment, and embedded data, import the globals directly from the library:\n\n```tsx\n// \u2705 CORRECT - Import globals directly\n<SbText\n text={sbComputed(() => `Welcome ${Global.user.name}!`)}\n textStyle={{\n textColor: {\n default: sbComputed(() => Theme.colors.neutral900)\n }\n }}\n/>\n<SbContainer backgroundColor={sbComputed(() => Theme.colors.primary)} />\n```\n\n#### 5.3. Mixed Access\n\nWhen you need both scope entities and global state in the same `sbComputed`:\n\n```tsx\nconst { orders } = Page1;\n\n// \u2705 CORRECT - Combine direct entity access with imported globals\n<SbText\n text={sbComputed(() => `${orders.length} orders for ${Global.user.name}`)}\n/>;\n```\n\n### 6. Writing State\n\nPreferred approach:\n\n```tsx\nconst { pageSize } = Page1;\nSbEventFlow.setStateVar(pageSize, 50);\n```\n\nFallback for complex operations:\n\n```tsx\nSbEventFlow.runJS(() => {\n // Direct assignment works within SbEventFlow.runJS\n pageSize.value = 50;\n});\n```\n\n### 7. CRITICAL Rules\n\n1. **Use component state directly**; NEVER create a state variable for a value that is available directly from a component property.\n2. Use component bindings by defining component types in your scope and using the `bind` prop.\n3. Keep logic declarative \u2014 derive UI from state using `sbComputed` instead of mutating props at runtime.\n4. Always destructure entities from your scope for clean access patterns.\n5. **Use the correct sbComputedz pattern**: Direct access for scope entities, import globals (Global, Theme, Embed, Env) for global access.\n6. Always complete implement all features, don\'t stub out or skip anything.\n\n**\u2705 Example**\n\n```tsx\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n ApplicantSelector: any;\n}>(\n () => ({\n applicants: SbVariable({ defaultValue: [] }),\n }),\n {\n name: "Page1",\n },\n);\n```\n\n```tsx\n// In your page component after destructuring entities\nconst { ApplicantSelector, applicants } = Page1;\n\n<SbDropdown bind={ApplicantSelector} options={/* ... */} />\n<SbTable tableData={sbComputed(() => applicants[ApplicantSelector.selectedOptionValue])} />\n```\n\n```tsx\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n FirstName: any;\n LastName: any;\n}>(\n ({ entities: { FirstName, LastName } }) => ({\n applicants: SbVariable({ defaultValue: [] }),\n fullName: SbVariable({\n defaultValue: sbComputed(() =>\n `${FirstName.value} ${LastName.value}`.trim(),\n ),\n }),\n }),\n {\n name: "Page1",\n },\n);\n```\n\n```tsx\nconst { FirstName, LastName, fullName } = Page1;\n\n<SbInput bind={FirstName} placeholder="First name" />\n<SbInput bind={LastName} placeholder="Last name" />\n<SbText text={sbComputed(() => `Welcome ${fullName.value}!`)} />\n```\n\n```tsx\n{\n /* The user types in the search input, and the value is displayed */\n}\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n searchTerm: any;\n}>(() => ({}), {\n name: "Page1",\n});\n```\n\n```tsx\nconst { searchTerm } = Page1;\n\n<SbInput bind={searchTerm} />\n<SbText text={sbComputed(() => searchTerm.value)} />\n```\n\n```tsx\n{\n /* Switch to change into admin mode */\n}\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n isAdmin: any;\n}>(() => ({}), {\n name: "Page1",\n});\n```\n\n```tsx\nconst { isAdmin } = Page1;\n\n<SbSwitch bind={isAdmin} label="Use Admin Mode" defaultChecked={false} />;\n{\n /* Only enable the delete button when switched into Admin mode */\n}\n<SbButton\n disabled={sbComputed(() => !isAdmin.isChecked)}\n label="Delete profile"\n/>;\n```\n\n\u2705 ALWAYS USE DIRECT COMPONENT STATE ACCESS WITH sbComputed:\n\n```tsx\n// GOOD - DO THIS\n// In your scope.ts file\nexport const Page1Scope = createSbScope<{\n UserNameInput: any;\n}>(() => ({}), {\n name: "Page1",\n});\n```\n\n```tsx\nconst { UserNameInput } = Page1;\n\n<SbTextInput bind={UserNameInput} />\n<SbText text={sbComputed(() => `Hello, ${UserNameInput.value}!`)} />\n```\n\n\u274C NEVER CREATE REDUNDANT STATE VARIABLES:\n\n```tsx\n// WRONG - DON\'T DO THIS\n<SbTextInput bind={UserNameInput} onChange={SbEventFlow.setStateVar(userNameVar, \'myValue\')} />\n<SbText text={sbComputed(() => `Hello, ${userNameVar.value}!`)} />\n...\n// And then in scope.ts:\n{\n userNameVar: SbVariable({ defaultValue: "" }),\n}\n```\n\nTo reference a property of a component using `sbComputed`, the component must have a binding defined in your scope.\n\nThat\'s why you should ALWAYS define component bindings in your scope for the following component types when you need to access their state:\n\n- SbInput\n- SbDropdown\n- SbDatePicker\n- SbCheckbox\n- SbSwitch\n- SbForm\n- SbRadio\n- SbRichText\n- SbFilePicker\n- SbCodeEditor\n- SbChat\n\n\u274C DO NOT USE STATE VARIABLES AS FUNCTIONS:\n\nState variables are not functions. You cannot call them or store functions in defaultValue.\n\n```tsx\n// WRONG - DON\'T DO THIS\nfunction Page1() {\n const { customerNameFilter, filterOrders } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbInput\n bind={customerNameFilter}\n label="Customer Name"\n placeholder="Filter by customer name"\n width={Dim.fill()}\n onTextChanged={SbEventFlow.runJS(() => {\n // This is wrong - you cannot call filterOrders as a function\n filterOrders();\n })}\n />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n}\n\n// And in scope.ts (WRONG):\n{\n filterOrders: SbVariable({\n defaultValue: () => {\n // This doesn\'t work - state variables are not functions\n const customerNameFilter = customerNameFilter.value.toLowerCase();\n // ... more logic\n },\n });\n}\n```\n\nInstead do the following:\n\n\u2705 COMPUTE VALUES WITH sbComputed AND SET STATE WITH SbEventFlow:\n\n```tsx\n// CORRECT - DO THIS\nimport {\n SbPage,\n SbSection,\n SbColumn,\n SbInput,\n SbButton,\n SbTable,\n sbComputed,\n SbEventFlow,\n registerPage,\n} from "@superblocksteam/library";\n\nfunction Page1() {\n const { customerNameFilter, filteredOrders, orders } = Page1;\n\n return (\n <SbPage name="Page1" height={Dim.fill()} width={Dim.fill()}>\n <SbSection height={Dim.fill()}>\n <SbColumn width={Dim.fill()}>\n <SbInput\n bind={customerNameFilter}\n label="Customer Name"\n placeholder="Filter by customer name"\n width={Dim.fill()}\n onTextChanged={SbEventFlow.runJS(() => {\n // Repeat the filtering logic inline - do NOT create helper functions\n const filtered = orders.value.filter((order) => {\n return (\n !customerNameFilter.value ||\n order.customerName\n .toLowerCase()\n .includes(customerNameFilter.value.toLowerCase())\n );\n });\n\n // Set the state variable with the computed result\n filteredOrders.value = filtered;\n })}\n />\n {/* If you need the same filtering logic elsewhere, repeat it inline */}\n <SbButton\n label="Apply Filter"\n onClick={SbEventFlow.runJS(() => {\n // Repeat the same filtering logic here - code repetition is preferred\n const filtered = orders.value.filter((order) => {\n return (\n !customerNameFilter.value ||\n order.customerName\n .toLowerCase()\n .includes(customerNameFilter.value.toLowerCase())\n );\n });\n\n filteredOrders.value = filtered;\n })}\n />\n <SbTable tableData={sbComputed(() => filteredOrders.value)} />\n </SbColumn>\n </SbSection>\n </SbPage>\n );\n}\n\nexport default registerPage(Page1, Page1Scope);\n```\n\nAnd in your scope.ts file:\n\n```ts\nexport const Page1Scope = createSbScope<{\n customerNameFilter: any;\n}>(\n () => ({\n orders: SbVariable({\n defaultValue: [\n {\n id: "ORD-1001",\n customerName: "John Smith",\n orderType: "Grocery Delivery",\n },\n {\n id: "ORD-1002",\n customerName: "Emily Johnson",\n orderType: "Express Delivery",\n },\n ],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n filteredOrders: SbVariable({\n defaultValue: [],\n persistence: SbVariablePersistence.TEMPORARY,\n }),\n }),\n {\n name: "Page1",\n },\n);\n```\n';
|
|
56
56
|
|
|
57
57
|
// ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/subprompts/superblocks-theming.js
|
|
58
58
|
init_cjs_shims();
|
|
@@ -162,7 +162,7 @@ var content27 = '## Dim\n\nThe `Dim` class is used to define dimensions for size
|
|
|
162
162
|
|
|
163
163
|
// ../../../vite-plugin-file-sync/dist/ai-service/prompts/generated/library-typedefs/SbEventFlow.js
|
|
164
164
|
init_cjs_shims();
|
|
165
|
-
var content28 = '## SbEventFlow\n\nThe `SbEventFlow` class is used to define responses to events triggered on components (like onClick) in Superblocks. It has a number of methods that can be chained together.\n\n```typescript\nclass SbEventFlow {\n // Run custom JavaScript code\n static runJS(\n handler: (s: ScopedState, additionalProps?: Record<string, any>) => void,\n ): SbEventFlow;\n runJS(\n handler: (s: ScopedState, additionalProps?: Record<string, any>) => void,\n ): this;\n\n // Navigation methods\n static navigateTo(props: { url: string; newWindow?: boolean }): SbEventFlow;\n navigateTo(props: { url: string; newWindow?: boolean }): this;\n\n static navigateToApp(appId: string): SbEventFlow;\n navigateToApp(appId: string): this;\n\n static navigateToRoute(route: string): SbEventFlow;\n navigateToRoute(route: string): this;\n\n static setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): SbEventFlow;\n setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): this;\n\n // Control UI components\n static controlSlideout(\n slideoutId: string,\n action: "open" | "close",\n ): SbEventFlow;\n controlSlideout(slideoutId: string, action: "open" | "close"): this;\n\n static controlModal(modalId: string, action: "open" | "close"): SbEventFlow;\n controlModal(modalId: string, action: "open" | "close"): this;\n\n static controlTimer(\n timerId: string,\n action: "start" | "stop" | "toggle",\n ): SbEventFlow;\n controlTimer(timerId: string, action: "start" | "stop" | "toggle"): this;\n\n // API methods\n static runApis(\n apis: SbApi[],\n onSuccess?: SbEventFlow,\n onError?: SbEventFlow,\n ): SbEventFlow;\n runApis(apis: SbApi[], onSuccess?: SbEventFlow, onError?: SbEventFlow): this;\n\n static cancelApis(apiNames: string[], onCancel?: SbEventFlow): SbEventFlow;\n cancelApis(apiNames: string[], onCancel?: SbEventFlow): this;\n\n // Component and state manipulation\n static resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): SbEventFlow;\n resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): this;\n\n static resetStateVar(
|
|
165
|
+
var content28 = '## SbEventFlow\n\nThe `SbEventFlow` class is used to define responses to events triggered on components (like onClick) in Superblocks. It has a number of methods that can be chained together.\n\n```typescript\nclass SbEventFlow {\n // Run custom JavaScript code\n static runJS(\n handler: (s: ScopedState, additionalProps?: Record<string, any>) => void,\n ): SbEventFlow;\n runJS(\n handler: (s: ScopedState, additionalProps?: Record<string, any>) => void,\n ): this;\n\n // Navigation methods\n static navigateTo(props: { url: string; newWindow?: boolean }): SbEventFlow;\n navigateTo(props: { url: string; newWindow?: boolean }): this;\n\n static navigateToApp(appId: string): SbEventFlow;\n navigateToApp(appId: string): this;\n\n static navigateToRoute(route: string): SbEventFlow;\n navigateToRoute(route: string): this;\n\n static setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): SbEventFlow;\n setQueryParams(\n params: Record<string, string>,\n keepQueryParams?: boolean,\n ): this;\n\n // Control UI components\n static controlSlideout(\n slideoutId: string,\n action: "open" | "close",\n ): SbEventFlow;\n controlSlideout(slideoutId: string, action: "open" | "close"): this;\n\n static controlModal(modalId: string, action: "open" | "close"): SbEventFlow;\n controlModal(modalId: string, action: "open" | "close"): this;\n\n static controlTimer(\n timerId: string,\n action: "start" | "stop" | "toggle",\n ): SbEventFlow;\n controlTimer(timerId: string, action: "start" | "stop" | "toggle"): this;\n\n // API methods\n static runApis(\n apis: SbApi[],\n onSuccess?: SbEventFlow,\n onError?: SbEventFlow,\n ): SbEventFlow;\n runApis(apis: SbApi[], onSuccess?: SbEventFlow, onError?: SbEventFlow): this;\n\n static cancelApis(apiNames: string[], onCancel?: SbEventFlow): SbEventFlow;\n cancelApis(apiNames: string[], onCancel?: SbEventFlow): this;\n\n // Component and state manipulation\n static resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): SbEventFlow;\n resetComponent(\n widget: { id: string },\n propertyName: string,\n resetChildren: boolean,\n ): this;\n\n static resetStateVar(stateVar: SbVariable): SbEventFlow;\n resetStateVar(stateVar: SbVariable): this;\n\n static setStateVar(stateVar: SbVariable, value: any): SbEventFlow;\n setStateVar(stateVar: SbVariable, value: any): this;\n\n static setComponentProperty(\n widget: { id: string },\n propertyName: string,\n value: any,\n ): SbEventFlow;\n setComponentProperty(\n widget: { id: string },\n propertyName: string,\n value: any,\n ): this;\n\n // Utility methods\n static showAlert(\n message: string,\n alertType: "info" | "success" | "warning" | "error",\n ): SbEventFlow;\n showAlert(\n message: string,\n alertType: "info" | "success" | "warning" | "error",\n ): this;\n\n static setProfile(\n profileId: string,\n profileAction: "set" | "unset",\n ): SbEventFlow;\n setProfile(profileId: string, profileAction: "set" | "unset"): this;\n\n static triggerEvent(\n eventName: string,\n eventData: Record<string, string>,\n ): SbEventFlow;\n triggerEvent(eventName: string, eventData: Record<string, string>): this;\n}\n```\n';
|
|
166
166
|
export {
|
|
167
167
|
library_components_exports as library_components,
|
|
168
168
|
library_typedefs_exports as library_typedefs,
|
package/dist/index.js
CHANGED
|
@@ -263726,7 +263726,7 @@ init_esm();
|
|
|
263726
263726
|
// ../sdk/package.json
|
|
263727
263727
|
var package_default = {
|
|
263728
263728
|
name: "@superblocksteam/sdk",
|
|
263729
|
-
version: "2.0.0-next.
|
|
263729
|
+
version: "2.0.0-next.13",
|
|
263730
263730
|
type: "module",
|
|
263731
263731
|
description: "Superblocks JS SDK",
|
|
263732
263732
|
homepage: "https://www.superblocks.com",
|
|
@@ -263763,8 +263763,8 @@ var package_default = {
|
|
|
263763
263763
|
"@rollup/wasm-node": "^4.35.0",
|
|
263764
263764
|
"@superblocksteam/bucketeer-sdk": "0.4.1",
|
|
263765
263765
|
"@superblocksteam/shared": "0.9122.0",
|
|
263766
|
-
"@superblocksteam/util": "2.0.0-next.
|
|
263767
|
-
"@superblocksteam/vite-plugin-file-sync": "2.0.0-next.
|
|
263766
|
+
"@superblocksteam/util": "2.0.0-next.13",
|
|
263767
|
+
"@superblocksteam/vite-plugin-file-sync": "2.0.0-next.13",
|
|
263768
263768
|
"@vitejs/plugin-react": "^4.3.4",
|
|
263769
263769
|
axios: "^1.4.0",
|
|
263770
263770
|
chokidar: "^4.0.3",
|
|
@@ -308628,7 +308628,7 @@ async function startVite({ app, httpServer: httpServer2, root: root2, mode, port
|
|
|
308628
308628
|
};
|
|
308629
308629
|
const isCustomBuildEnabled2 = await isCustomComponentsEnabled();
|
|
308630
308630
|
const customFolder = path21.join(root2, "custom");
|
|
308631
|
-
const cdnUrl = "https://assets-cdn.superblocks.com/library/2.0.0-next.
|
|
308631
|
+
const cdnUrl = "https://assets-cdn.superblocks.com/library/2.0.0-next.13";
|
|
308632
308632
|
const env3 = loadEnv(mode, root2, "");
|
|
308633
308633
|
const hmrPort = await getFreePort();
|
|
308634
308634
|
const hmrOptions = {
|
|
@@ -315351,7 +315351,7 @@ init_cjs_shims();
|
|
|
315351
315351
|
init_cjs_shims();
|
|
315352
315352
|
var generated = {};
|
|
315353
315353
|
try {
|
|
315354
|
-
generated = await import("./generated-
|
|
315354
|
+
generated = await import("./generated-CWPUNU3S.js");
|
|
315355
315355
|
} catch (_error) {
|
|
315356
315356
|
getLogger().warn("[ai-service] Generated markdown modules not found. Run `pnpm generate:markdown` first.");
|
|
315357
315357
|
}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superblocksteam/cli",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Official Superblocks CLI",
|
|
6
6
|
"homepage": "https://www.superblocks.com",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@eslint/js": "^9.16.0",
|
|
44
44
|
"@oclif/test": "^4.1.11",
|
|
45
|
-
"@superblocksteam/sdk": "2.0.0-next.
|
|
45
|
+
"@superblocksteam/sdk": "2.0.0-next.13",
|
|
46
46
|
"@superblocksteam/shared": "0.9122.0",
|
|
47
|
-
"@superblocksteam/util": "2.0.0-next.
|
|
47
|
+
"@superblocksteam/util": "2.0.0-next.13",
|
|
48
48
|
"@types/babel__core": "^7.20.0",
|
|
49
49
|
"@types/chai": "^4",
|
|
50
50
|
"@types/fs-extra": "^11.0.1",
|