@nextsparkjs/ai-workflow 0.1.0-beta.100
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/LICENSE +21 -0
- package/README.md +115 -0
- package/claude/_docs/workflows-optimizations.md +359 -0
- package/claude/agents/api-tester.md +634 -0
- package/claude/agents/architecture-supervisor.md +1351 -0
- package/claude/agents/backend-developer.md +997 -0
- package/claude/agents/backend-validator.md +417 -0
- package/claude/agents/bdd-docs-writer.md +737 -0
- package/claude/agents/block-developer.md +677 -0
- package/claude/agents/code-reviewer.md +1432 -0
- package/claude/agents/db-developer.md +721 -0
- package/claude/agents/db-validator.md +407 -0
- package/claude/agents/demo-video-generator.md +493 -0
- package/claude/agents/documentation-writer.md +1268 -0
- package/claude/agents/frontend-developer.md +1234 -0
- package/claude/agents/frontend-validator.md +777 -0
- package/claude/agents/functional-validator.md +630 -0
- package/claude/agents/mock-analyst.md +387 -0
- package/claude/agents/product-manager.md +963 -0
- package/claude/agents/qa-automation.md +1762 -0
- package/claude/agents/release-manager.md +634 -0
- package/claude/agents/selectors-translator.md +262 -0
- package/claude/agents/unit-test-writer.md +785 -0
- package/claude/agents/visual-comparator.md +329 -0
- package/claude/agents/workflow-maintainer.md +352 -0
- package/claude/commands/do/README.md +88 -0
- package/claude/commands/do/create-api.md +64 -0
- package/claude/commands/do/create-entity.md +66 -0
- package/claude/commands/do/create-migration.md +64 -0
- package/claude/commands/do/create-plugin.md +56 -0
- package/claude/commands/do/create-theme.md +70 -0
- package/claude/commands/do/mock-data.md +67 -0
- package/claude/commands/do/reset-db.md +71 -0
- package/claude/commands/do/setup-scheduled-action.md +75 -0
- package/claude/commands/do/sync-code-review.md +117 -0
- package/claude/commands/do/update-selectors.md +112 -0
- package/claude/commands/do/use-skills.md +90 -0
- package/claude/commands/do/validate-blocks.md +69 -0
- package/claude/commands/how-to/README.md +261 -0
- package/claude/commands/how-to/add-metadata.md +692 -0
- package/claude/commands/how-to/add-taxonomies.md +806 -0
- package/claude/commands/how-to/add-translations.md +571 -0
- package/claude/commands/how-to/create-api.md +577 -0
- package/claude/commands/how-to/create-block.md +575 -0
- package/claude/commands/how-to/create-child-entities.md +771 -0
- package/claude/commands/how-to/create-entity.md +597 -0
- package/claude/commands/how-to/create-migrations.md +605 -0
- package/claude/commands/how-to/create-plugin.md +654 -0
- package/claude/commands/how-to/customize-app.md +481 -0
- package/claude/commands/how-to/customize-dashboard.md +553 -0
- package/claude/commands/how-to/customize-theme.md +438 -0
- package/claude/commands/how-to/define-features-flows.md +632 -0
- package/claude/commands/how-to/deploy.md +507 -0
- package/claude/commands/how-to/handle-file-uploads.md +746 -0
- package/claude/commands/how-to/implement-search.md +1001 -0
- package/claude/commands/how-to/install-plugins.md +352 -0
- package/claude/commands/how-to/manage-test-coverage.md +984 -0
- package/claude/commands/how-to/run-tests.md +400 -0
- package/claude/commands/how-to/set-app-languages.md +601 -0
- package/claude/commands/how-to/set-plans-and-permissions.md +575 -0
- package/claude/commands/how-to/set-scheduled-actions.md +527 -0
- package/claude/commands/how-to/set-user-roles-and-permissions.md +550 -0
- package/claude/commands/how-to/setup-authentication.md +388 -0
- package/claude/commands/how-to/setup-claude-code.md +440 -0
- package/claude/commands/how-to/setup-database.md +274 -0
- package/claude/commands/how-to/setup-email-providers.md +598 -0
- package/claude/commands/how-to/setup-mobile-dev.md +627 -0
- package/claude/commands/how-to/start.md +500 -0
- package/claude/commands/how-to/use-devtools.md +639 -0
- package/claude/commands/how-to/use-superadmin.md +622 -0
- package/claude/commands/session/README.md +193 -0
- package/claude/commands/session/block-create.md +190 -0
- package/claude/commands/session/block-list.md +203 -0
- package/claude/commands/session/block-update.md +192 -0
- package/claude/commands/session/block-validate.md +218 -0
- package/claude/commands/session/changelog.md +115 -0
- package/claude/commands/session/close.md +225 -0
- package/claude/commands/session/commit.md +174 -0
- package/claude/commands/session/db-entity.md +206 -0
- package/claude/commands/session/db-fix.md +212 -0
- package/claude/commands/session/db-sample.md +206 -0
- package/claude/commands/session/demo.md +178 -0
- package/claude/commands/session/doc-bdd.md +207 -0
- package/claude/commands/session/doc-feature.md +218 -0
- package/claude/commands/session/doc-read.md +225 -0
- package/claude/commands/session/execute.md +204 -0
- package/claude/commands/session/explain.md +202 -0
- package/claude/commands/session/fix-bug.md +210 -0
- package/claude/commands/session/fix-build.md +182 -0
- package/claude/commands/session/fix-test.md +189 -0
- package/claude/commands/session/pending.md +232 -0
- package/claude/commands/session/refine.md +188 -0
- package/claude/commands/session/resume.md +192 -0
- package/claude/commands/session/review.md +192 -0
- package/claude/commands/session/scope-change.md +181 -0
- package/claude/commands/session/start-blocks.md +347 -0
- package/claude/commands/session/start.md +604 -0
- package/claude/commands/session/status.md +169 -0
- package/claude/commands/session/test-fix.md +221 -0
- package/claude/commands/session/test-run.md +203 -0
- package/claude/commands/session/test-write.md +242 -0
- package/claude/commands/session/validate.md +162 -0
- package/claude/config/context.json +40 -0
- package/claude/config/github.json +69 -0
- package/claude/config/github.schema.json +106 -0
- package/claude/config/team.json +46 -0
- package/claude/config/team.schema.json +106 -0
- package/claude/config/workspace.json +43 -0
- package/claude/config/workspace.schema.json +75 -0
- package/claude/skills/README.md +228 -0
- package/claude/skills/accessibility/SKILL.md +573 -0
- package/claude/skills/api-bypass-layers/SKILL.md +550 -0
- package/claude/skills/asana-integration/SKILL.md +499 -0
- package/claude/skills/better-auth/SKILL.md +666 -0
- package/claude/skills/billing-subscriptions/SKILL.md +660 -0
- package/claude/skills/block-decision-matrix/SKILL.md +359 -0
- package/claude/skills/clickup-integration/SKILL.md +434 -0
- package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
- package/claude/skills/create-plugin/SKILL.md +425 -0
- package/claude/skills/create-theme/SKILL.md +331 -0
- package/claude/skills/cypress-api/SKILL.md +511 -0
- package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
- package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
- package/claude/skills/cypress-e2e/SKILL.md +526 -0
- package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
- package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
- package/claude/skills/cypress-selectors/SKILL.md +309 -0
- package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
- package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
- package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
- package/claude/skills/database-migrations/SKILL.md +335 -0
- package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
- package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
- package/claude/skills/design-system/SKILL.md +682 -0
- package/claude/skills/documentation/SKILL.md +540 -0
- package/claude/skills/entity-api/SKILL.md +482 -0
- package/claude/skills/entity-system/SKILL.md +635 -0
- package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
- package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
- package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
- package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
- package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
- package/claude/skills/github/SKILL.md +467 -0
- package/claude/skills/i18n-nextintl/SKILL.md +302 -0
- package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
- package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
- package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
- package/claude/skills/impact-analysis/SKILL.md +203 -0
- package/claude/skills/jest-unit/SKILL.md +306 -0
- package/claude/skills/jest-unit/references/component-testing.md +371 -0
- package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
- package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
- package/claude/skills/jira-integration/SKILL.md +539 -0
- package/claude/skills/media-library/SKILL.md +743 -0
- package/claude/skills/mock-analysis/SKILL.md +276 -0
- package/claude/skills/monorepo-architecture/SKILL.md +162 -0
- package/claude/skills/nextjs-api-development/SKILL.md +364 -0
- package/claude/skills/nextjs-api-development/scripts/generate-crud-tests.py +456 -0
- package/claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py +481 -0
- package/claude/skills/nextjs-api-development/scripts/validate-api.py +283 -0
- package/claude/skills/notion-integration/SKILL.md +641 -0
- package/claude/skills/npm-development-workflow/SKILL.md +480 -0
- package/claude/skills/page-builder-blocks/SKILL.md +530 -0
- package/claude/skills/page-builder-blocks/scripts/scaffold-block.py +444 -0
- package/claude/skills/permissions-system/SKILL.md +619 -0
- package/claude/skills/plugins/SKILL.md +340 -0
- package/claude/skills/plugins/references/plugin-templates.md +414 -0
- package/claude/skills/plugins/references/plugin-testing.md +353 -0
- package/claude/skills/plugins/references/plugin-types.md +198 -0
- package/claude/skills/plugins/scripts/scaffold-plugin.py +443 -0
- package/claude/skills/pom-patterns/SKILL.md +452 -0
- package/claude/skills/pom-patterns/scripts/generate-pom.py +392 -0
- package/claude/skills/rate-limiting/SKILL.md +342 -0
- package/claude/skills/react-best-practices/AGENTS.md +2410 -0
- package/claude/skills/react-best-practices/README.md +123 -0
- package/claude/skills/react-best-practices/SKILL.md +125 -0
- package/claude/skills/react-best-practices/metadata.json +15 -0
- package/claude/skills/react-best-practices/rules/_sections.md +46 -0
- package/claude/skills/react-best-practices/rules/_template.md +28 -0
- package/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/claude/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/claude/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/claude/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/claude/skills/react-patterns/SKILL.md +688 -0
- package/claude/skills/registry-system/SKILL.md +331 -0
- package/claude/skills/scheduled-actions/SKILL.md +671 -0
- package/claude/skills/scope-enforcement/SKILL.md +542 -0
- package/claude/skills/scope-enforcement/scripts/validate-scope.py +357 -0
- package/claude/skills/server-actions/SKILL.md +493 -0
- package/claude/skills/service-layer/SKILL.md +587 -0
- package/claude/skills/session-management/SKILL.md +266 -0
- package/claude/skills/session-management/scripts/create-session.py +166 -0
- package/claude/skills/session-management/scripts/iteration-close.sh +105 -0
- package/claude/skills/session-management/scripts/iteration-init.sh +180 -0
- package/claude/skills/session-management/scripts/session-archive.sh +87 -0
- package/claude/skills/session-management/scripts/session-close.sh +133 -0
- package/claude/skills/session-management/scripts/session-init.sh +225 -0
- package/claude/skills/session-management/scripts/session-list.sh +163 -0
- package/claude/skills/session-management/scripts/split-plan.sh +116 -0
- package/claude/skills/shadcn-components/SKILL.md +586 -0
- package/claude/skills/shadcn-theming/SKILL.md +446 -0
- package/claude/skills/suspense-loading/SKILL.md +280 -0
- package/claude/skills/tailwind-theming/SKILL.md +507 -0
- package/claude/skills/tanstack-query/SKILL.md +608 -0
- package/claude/skills/test-coverage/SKILL.md +239 -0
- package/claude/skills/web-design-guidelines/SKILL.md +39 -0
- package/claude/skills/zod-validation/SKILL.md +537 -0
- package/claude/templates/blocks/progress.md +86 -0
- package/claude/templates/iteration/changes.md +61 -0
- package/claude/templates/iteration/progress.md +55 -0
- package/claude/templates/log.md +31 -0
- package/claude/templates/story/context.md +77 -0
- package/claude/templates/story/pendings.md +37 -0
- package/claude/templates/story/plan.md +299 -0
- package/claude/templates/story/requirements.md +109 -0
- package/claude/templates/story/scope.json +10 -0
- package/claude/templates/story/tests.md +91 -0
- package/claude/templates/task/progress.md +58 -0
- package/claude/templates/task/requirements.md +54 -0
- package/claude/workflows/README.md +154 -0
- package/claude/workflows/blocks.md +614 -0
- package/claude/workflows/story.md +1207 -0
- package/claude/workflows/task.md +927 -0
- package/claude/workflows/tweak.md +527 -0
- package/cursor/.gitkeep +0 -0
- package/package.json +35 -0
- package/scripts/postinstall.mjs +198 -0
- package/scripts/setup.mjs +282 -0
- package/scripts/sync.mjs +209 -0
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
# /how-to:create-block
|
|
2
|
+
|
|
3
|
+
Interactive guide to create page builder blocks in NextSpark.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Required Skills
|
|
8
|
+
|
|
9
|
+
Before executing, these skills provide deeper context:
|
|
10
|
+
- `.claude/skills/page-builder-blocks/SKILL.md` - Block structure and patterns
|
|
11
|
+
- `.claude/skills/block-decision-matrix/SKILL.md` - When to create new vs use existing
|
|
12
|
+
- `.claude/skills/tailwind-theming/SKILL.md` - Styling with Tailwind CSS
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Syntax
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
/how-to:create-block
|
|
20
|
+
/how-to:create-block [block-name]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Behavior
|
|
26
|
+
|
|
27
|
+
Guides the user through creating a page builder block with all 5 required files, following NextSpark conventions.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Tutorial Structure
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
STEPS OVERVIEW (5 steps)
|
|
35
|
+
|
|
36
|
+
Step 1: Understanding Block Structure
|
|
37
|
+
└── The 5 required files explained
|
|
38
|
+
|
|
39
|
+
Step 2: Create Block Configuration (config.ts)
|
|
40
|
+
└── Define block metadata and category
|
|
41
|
+
|
|
42
|
+
Step 3: Create Schema (schema.ts)
|
|
43
|
+
└── Define Zod schema extending baseBlockSchema
|
|
44
|
+
|
|
45
|
+
Step 4: Create Fields Definition (fields.ts)
|
|
46
|
+
└── Define form fields for the editor
|
|
47
|
+
|
|
48
|
+
Step 5: Create React Component (component.tsx)
|
|
49
|
+
└── Build the visual component
|
|
50
|
+
|
|
51
|
+
Bonus: Register and Test
|
|
52
|
+
└── Rebuild registry and preview
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Step 1: Understanding Block Structure
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
61
|
+
📚 HOW TO: CREATE A BLOCK
|
|
62
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
63
|
+
|
|
64
|
+
STEP 1 OF 5: Understanding Block Structure
|
|
65
|
+
|
|
66
|
+
Every page builder block in NextSpark consists of 5 files:
|
|
67
|
+
|
|
68
|
+
contents/themes/{theme}/blocks/{block-name}/
|
|
69
|
+
├── config.ts # Block metadata (name, category, icon)
|
|
70
|
+
├── schema.ts # Zod schema for data validation
|
|
71
|
+
├── fields.ts # Form fields for the editor UI
|
|
72
|
+
├── component.tsx # React component that renders
|
|
73
|
+
└── index.ts # Barrel export file
|
|
74
|
+
|
|
75
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
76
|
+
|
|
77
|
+
📋 Why 5 files?
|
|
78
|
+
|
|
79
|
+
• config.ts - Registry needs to know block metadata
|
|
80
|
+
• schema.ts - Ensures data integrity with Zod
|
|
81
|
+
• fields.ts - Powers the visual editor form
|
|
82
|
+
• component.tsx - What users see on the page
|
|
83
|
+
• index.ts - Clean imports for the registry
|
|
84
|
+
|
|
85
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
86
|
+
|
|
87
|
+
What would you like to do?
|
|
88
|
+
|
|
89
|
+
[1] Continue to Step 2
|
|
90
|
+
[2] I have a question about block structure
|
|
91
|
+
[3] Show me an example of each file
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Step 2: Create Block Configuration
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
100
|
+
STEP 2 OF 5: Create Block Configuration
|
|
101
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
102
|
+
|
|
103
|
+
The config.ts file defines your block's identity:
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**📋 config.ts Example:**
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// contents/themes/default/blocks/hero-banner/config.ts
|
|
110
|
+
import type { BlockConfig } from '@/core/types/block'
|
|
111
|
+
import { LayoutTemplate } from 'lucide-react'
|
|
112
|
+
|
|
113
|
+
export const config: BlockConfig = {
|
|
114
|
+
// Unique identifier (kebab-case)
|
|
115
|
+
name: 'hero-banner',
|
|
116
|
+
|
|
117
|
+
// Display name in editor (i18n key)
|
|
118
|
+
displayName: 'blocks.heroBanner.name',
|
|
119
|
+
|
|
120
|
+
// Short description (i18n key)
|
|
121
|
+
description: 'blocks.heroBanner.description',
|
|
122
|
+
|
|
123
|
+
// Category for grouping in editor
|
|
124
|
+
category: 'hero', // hero | content | features | cta | footer
|
|
125
|
+
|
|
126
|
+
// Lucide icon component
|
|
127
|
+
icon: LayoutTemplate,
|
|
128
|
+
|
|
129
|
+
// Available style variants
|
|
130
|
+
variants: ['default', 'centered', 'split'],
|
|
131
|
+
|
|
132
|
+
// Default variant
|
|
133
|
+
defaultVariant: 'default',
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export default config
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**📋 Key Points:**
|
|
140
|
+
|
|
141
|
+
- `name`: Must match folder name (kebab-case)
|
|
142
|
+
- `displayName`: Use i18n key, add translation later
|
|
143
|
+
- `category`: Groups blocks in the editor sidebar
|
|
144
|
+
- `variants`: Optional different visual styles
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
148
|
+
|
|
149
|
+
What would you like to do?
|
|
150
|
+
|
|
151
|
+
[1] Continue to Step 3
|
|
152
|
+
[2] I have a question about config
|
|
153
|
+
[3] What categories are available?
|
|
154
|
+
[4] Let me create this file for my block now
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Step 3: Create Schema
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
163
|
+
STEP 3 OF 5: Create Schema
|
|
164
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
165
|
+
|
|
166
|
+
The schema.ts file validates block data with Zod:
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**📋 schema.ts Example:**
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// contents/themes/default/blocks/hero-banner/schema.ts
|
|
173
|
+
import { z } from 'zod'
|
|
174
|
+
import { baseBlockSchema } from '@/core/lib/blocks/base-schema'
|
|
175
|
+
|
|
176
|
+
// CRITICAL: Always extend baseBlockSchema
|
|
177
|
+
export const heroBannerSchema = baseBlockSchema.extend({
|
|
178
|
+
// Required fields
|
|
179
|
+
title: z.string().min(1).max(100),
|
|
180
|
+
|
|
181
|
+
// Optional fields with defaults
|
|
182
|
+
subtitle: z.string().max(200).optional(),
|
|
183
|
+
|
|
184
|
+
// CTA button (optional object)
|
|
185
|
+
cta: z.object({
|
|
186
|
+
text: z.string().min(1).max(50),
|
|
187
|
+
url: z.string().url(),
|
|
188
|
+
variant: z.enum(['primary', 'secondary', 'outline']).default('primary'),
|
|
189
|
+
}).optional(),
|
|
190
|
+
|
|
191
|
+
// Background settings
|
|
192
|
+
background: z.object({
|
|
193
|
+
type: z.enum(['color', 'image', 'gradient']).default('color'),
|
|
194
|
+
value: z.string().optional(),
|
|
195
|
+
}).default({ type: 'color' }),
|
|
196
|
+
|
|
197
|
+
// Alignment
|
|
198
|
+
alignment: z.enum(['left', 'center', 'right']).default('center'),
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
// Export the type for TypeScript
|
|
202
|
+
export type HeroBannerData = z.infer<typeof heroBannerSchema>
|
|
203
|
+
|
|
204
|
+
export default heroBannerSchema
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**⚠️ CRITICAL: Always extend baseBlockSchema!**
|
|
208
|
+
|
|
209
|
+
The baseBlockSchema includes:
|
|
210
|
+
- `id`: string (unique block ID)
|
|
211
|
+
- `type`: string (block type name)
|
|
212
|
+
- `variant`: string (selected variant)
|
|
213
|
+
- `order`: number (position on page)
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
217
|
+
|
|
218
|
+
What would you like to do?
|
|
219
|
+
|
|
220
|
+
[1] Continue to Step 4
|
|
221
|
+
[2] What types of fields can I use?
|
|
222
|
+
[3] Show me validation examples
|
|
223
|
+
[4] Let me create my schema now
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Step 4: Create Fields Definition
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
232
|
+
STEP 4 OF 5: Create Fields Definition
|
|
233
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
234
|
+
|
|
235
|
+
The fields.ts file defines the editor form UI:
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**📋 fields.ts Example:**
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// contents/themes/default/blocks/hero-banner/fields.ts
|
|
242
|
+
import type { BlockFieldDefinition } from '@/core/types/block'
|
|
243
|
+
|
|
244
|
+
export const fields: BlockFieldDefinition[] = [
|
|
245
|
+
// Text input field
|
|
246
|
+
{
|
|
247
|
+
name: 'title',
|
|
248
|
+
type: 'text',
|
|
249
|
+
label: 'blocks.heroBanner.fields.title',
|
|
250
|
+
placeholder: 'blocks.heroBanner.placeholders.title',
|
|
251
|
+
required: true,
|
|
252
|
+
group: 'content',
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
// Textarea field
|
|
256
|
+
{
|
|
257
|
+
name: 'subtitle',
|
|
258
|
+
type: 'textarea',
|
|
259
|
+
label: 'blocks.heroBanner.fields.subtitle',
|
|
260
|
+
rows: 2,
|
|
261
|
+
group: 'content',
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
// Nested object fields (CTA)
|
|
265
|
+
{
|
|
266
|
+
name: 'cta.text',
|
|
267
|
+
type: 'text',
|
|
268
|
+
label: 'blocks.heroBanner.fields.ctaText',
|
|
269
|
+
group: 'cta',
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: 'cta.url',
|
|
273
|
+
type: 'url',
|
|
274
|
+
label: 'blocks.heroBanner.fields.ctaUrl',
|
|
275
|
+
group: 'cta',
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: 'cta.variant',
|
|
279
|
+
type: 'select',
|
|
280
|
+
label: 'blocks.heroBanner.fields.ctaVariant',
|
|
281
|
+
options: [
|
|
282
|
+
{ value: 'primary', label: 'Primary' },
|
|
283
|
+
{ value: 'secondary', label: 'Secondary' },
|
|
284
|
+
{ value: 'outline', label: 'Outline' },
|
|
285
|
+
],
|
|
286
|
+
group: 'cta',
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
// Alignment select
|
|
290
|
+
{
|
|
291
|
+
name: 'alignment',
|
|
292
|
+
type: 'select',
|
|
293
|
+
label: 'blocks.heroBanner.fields.alignment',
|
|
294
|
+
options: [
|
|
295
|
+
{ value: 'left', label: 'Left' },
|
|
296
|
+
{ value: 'center', label: 'Center' },
|
|
297
|
+
{ value: 'right', label: 'Right' },
|
|
298
|
+
],
|
|
299
|
+
group: 'style',
|
|
300
|
+
},
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
// Field groups for editor tabs
|
|
304
|
+
export const fieldGroups = [
|
|
305
|
+
{ id: 'content', label: 'Content' },
|
|
306
|
+
{ id: 'cta', label: 'Call to Action' },
|
|
307
|
+
{ id: 'style', label: 'Style' },
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
export default fields
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**📋 Available Field Types:**
|
|
314
|
+
|
|
315
|
+
- `text` - Single line text input
|
|
316
|
+
- `textarea` - Multi-line text
|
|
317
|
+
- `number` - Numeric input
|
|
318
|
+
- `select` - Dropdown selection
|
|
319
|
+
- `checkbox` - Boolean toggle
|
|
320
|
+
- `url` - URL with validation
|
|
321
|
+
- `image` - Image upload/selection
|
|
322
|
+
- `color` - Color picker
|
|
323
|
+
- `richtext` - Rich text editor
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
327
|
+
|
|
328
|
+
What would you like to do?
|
|
329
|
+
|
|
330
|
+
[1] Continue to Step 5
|
|
331
|
+
[2] Show me more field type examples
|
|
332
|
+
[3] How do I handle nested fields?
|
|
333
|
+
[4] Let me create my fields now
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Step 5: Create Component
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
342
|
+
STEP 5 OF 5: Create React Component
|
|
343
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
344
|
+
|
|
345
|
+
The component.tsx file renders your block:
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**📋 component.tsx Example:**
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
// contents/themes/default/blocks/hero-banner/component.tsx
|
|
352
|
+
import type { HeroBannerData } from './schema'
|
|
353
|
+
import { cn } from '@/core/lib/utils'
|
|
354
|
+
import { Button } from '@/core/components/ui/button'
|
|
355
|
+
|
|
356
|
+
interface HeroBannerProps {
|
|
357
|
+
data: HeroBannerData
|
|
358
|
+
isPreview?: boolean
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export function HeroBanner({ data, isPreview }: HeroBannerProps) {
|
|
362
|
+
const { title, subtitle, cta, alignment, variant } = data
|
|
363
|
+
|
|
364
|
+
// Alignment classes
|
|
365
|
+
const alignmentClasses = {
|
|
366
|
+
left: 'text-left items-start',
|
|
367
|
+
center: 'text-center items-center',
|
|
368
|
+
right: 'text-right items-end',
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
<section
|
|
373
|
+
data-cy="block-hero-banner"
|
|
374
|
+
data-block-type="hero-banner"
|
|
375
|
+
data-variant={variant}
|
|
376
|
+
className={cn(
|
|
377
|
+
'py-20 px-4 flex flex-col gap-6',
|
|
378
|
+
alignmentClasses[alignment || 'center']
|
|
379
|
+
)}
|
|
380
|
+
>
|
|
381
|
+
{/* Title */}
|
|
382
|
+
<h1
|
|
383
|
+
data-cy="hero-banner-title"
|
|
384
|
+
className="text-4xl md:text-6xl font-bold"
|
|
385
|
+
>
|
|
386
|
+
{title}
|
|
387
|
+
</h1>
|
|
388
|
+
|
|
389
|
+
{/* Subtitle */}
|
|
390
|
+
{subtitle && (
|
|
391
|
+
<p
|
|
392
|
+
data-cy="hero-banner-subtitle"
|
|
393
|
+
className="text-xl text-muted-foreground max-w-2xl"
|
|
394
|
+
>
|
|
395
|
+
{subtitle}
|
|
396
|
+
</p>
|
|
397
|
+
)}
|
|
398
|
+
|
|
399
|
+
{/* CTA Button */}
|
|
400
|
+
{cta && (
|
|
401
|
+
<Button
|
|
402
|
+
data-cy="hero-banner-cta"
|
|
403
|
+
variant={cta.variant}
|
|
404
|
+
asChild
|
|
405
|
+
>
|
|
406
|
+
<a href={cta.url}>{cta.text}</a>
|
|
407
|
+
</Button>
|
|
408
|
+
)}
|
|
409
|
+
</section>
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export default HeroBanner
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**⚠️ CRITICAL: Always add data-cy attributes!**
|
|
417
|
+
|
|
418
|
+
Required selectors for testing:
|
|
419
|
+
- `data-cy="block-{block-name}"` - Main container
|
|
420
|
+
- `data-cy="{block-name}-{element}"` - Key elements
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
424
|
+
|
|
425
|
+
What would you like to do?
|
|
426
|
+
|
|
427
|
+
[1] Continue to Bonus: Register and Test
|
|
428
|
+
[2] How do I handle variants?
|
|
429
|
+
[3] Best practices for styling?
|
|
430
|
+
[4] Let me create my component now
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Bonus: Register and Test
|
|
436
|
+
|
|
437
|
+
```
|
|
438
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
439
|
+
BONUS: Register and Test Your Block
|
|
440
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**1️⃣ Create the index.ts barrel file:**
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
// contents/themes/default/blocks/hero-banner/index.ts
|
|
447
|
+
export { config } from './config'
|
|
448
|
+
export { heroBannerSchema as schema } from './schema'
|
|
449
|
+
export { fields, fieldGroups } from './fields'
|
|
450
|
+
export { HeroBanner as Component } from './component'
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**2️⃣ Add translations (messages/en.json):**
|
|
454
|
+
|
|
455
|
+
```json
|
|
456
|
+
{
|
|
457
|
+
"blocks": {
|
|
458
|
+
"heroBanner": {
|
|
459
|
+
"name": "Hero Banner",
|
|
460
|
+
"description": "Large hero section with title and CTA",
|
|
461
|
+
"fields": {
|
|
462
|
+
"title": "Title",
|
|
463
|
+
"subtitle": "Subtitle",
|
|
464
|
+
"ctaText": "Button Text",
|
|
465
|
+
"ctaUrl": "Button URL",
|
|
466
|
+
"ctaVariant": "Button Style",
|
|
467
|
+
"alignment": "Alignment"
|
|
468
|
+
},
|
|
469
|
+
"placeholders": {
|
|
470
|
+
"title": "Enter your headline..."
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**3️⃣ Rebuild the registry:**
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
node core/scripts/build/registry.mjs
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
**4️⃣ Test your block:**
|
|
484
|
+
|
|
485
|
+
- Start dev server: `pnpm dev`
|
|
486
|
+
- Go to Page Builder in dashboard
|
|
487
|
+
- Find your block in the sidebar
|
|
488
|
+
- Add it to a page and configure
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
492
|
+
|
|
493
|
+
✅ TUTORIAL STORY!
|
|
494
|
+
|
|
495
|
+
You've learned how to create a page builder block.
|
|
496
|
+
|
|
497
|
+
📚 Related tutorials:
|
|
498
|
+
• /how-to:customize-theme - Customize your theme's design
|
|
499
|
+
• /how-to:add-translations - Add more translations
|
|
500
|
+
|
|
501
|
+
🔙 Back to menu: /how-to:start
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## Interactive Options
|
|
507
|
+
|
|
508
|
+
At each step, Claude should:
|
|
509
|
+
|
|
510
|
+
1. **Validate understanding** - Ask if the user has questions
|
|
511
|
+
2. **Offer to implement** - Let user create files immediately
|
|
512
|
+
3. **Show examples** - Provide real code samples
|
|
513
|
+
4. **Answer questions** - Pause for clarification
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## Common Questions
|
|
518
|
+
|
|
519
|
+
### "What categories are available?"
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
📋 Block Categories:
|
|
523
|
+
|
|
524
|
+
• hero - Large header sections
|
|
525
|
+
• content - General content blocks
|
|
526
|
+
• features - Feature showcases
|
|
527
|
+
• cta - Call to action sections
|
|
528
|
+
• footer - Footer components
|
|
529
|
+
• gallery - Image galleries
|
|
530
|
+
• testimonials - Reviews and testimonials
|
|
531
|
+
• pricing - Pricing tables
|
|
532
|
+
• faq - FAQ/Accordion sections
|
|
533
|
+
• custom - Theme-specific blocks
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### "How do I handle variants?"
|
|
537
|
+
|
|
538
|
+
**📋 Handling Variants:**
|
|
539
|
+
|
|
540
|
+
Variants allow different visual styles for the same block.
|
|
541
|
+
|
|
542
|
+
In your component, use the variant prop:
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
export function HeroBanner({ data }: Props) {
|
|
546
|
+
const { variant } = data
|
|
547
|
+
|
|
548
|
+
// Variant-specific classes
|
|
549
|
+
const variantClasses = {
|
|
550
|
+
default: 'bg-background',
|
|
551
|
+
centered: 'bg-muted text-center',
|
|
552
|
+
split: 'grid grid-cols-2 gap-8',
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return (
|
|
556
|
+
<section className={cn('py-20', variantClasses[variant])}>
|
|
557
|
+
{variant === 'split' ? (
|
|
558
|
+
<SplitLayout {...data} />
|
|
559
|
+
) : (
|
|
560
|
+
<DefaultLayout {...data} />
|
|
561
|
+
)}
|
|
562
|
+
</section>
|
|
563
|
+
)
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## Related Commands
|
|
570
|
+
|
|
571
|
+
| Command | Action |
|
|
572
|
+
|---------|--------|
|
|
573
|
+
| `/session:block:create` | Create block via session workflow |
|
|
574
|
+
| `/session:block:validate` | Validate block structure |
|
|
575
|
+
| `/how-to:customize-theme` | Theme customization |
|