@salesforce/b2c-cli 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/dev.js +8 -8
- package/bin/run.js +5 -7
- package/content/guidance/b2c/b2c-business-manager-extensions/SKILL.md +361 -0
- package/content/guidance/b2c/b2c-business-manager-extensions/references/EXTENSIONS-XML.md +458 -0
- package/content/guidance/b2c/b2c-controllers/SKILL.md +301 -0
- package/content/guidance/b2c/b2c-controllers/references/CLASSIC-PATTERNS.md +335 -0
- package/content/guidance/b2c/b2c-controllers/references/SFRA-PATTERNS.md +400 -0
- package/content/guidance/b2c/b2c-custom-api-development/SKILL.md +281 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/CONTRACT.md +142 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/IMPLEMENTATION.md +153 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/TESTING.md +118 -0
- package/content/guidance/b2c/b2c-custom-caches/SKILL.md +279 -0
- package/content/guidance/b2c/b2c-custom-job-steps/SKILL.md +520 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/CHUNK-ORIENTED.md +377 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/JOBS-XML.md +212 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/STEPTYPES-JSON.md +373 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/TASK-ORIENTED.md +344 -0
- package/content/guidance/b2c/b2c-custom-objects/SKILL.md +327 -0
- package/content/guidance/b2c/b2c-custom-objects/references/OCAPI-SEARCH.md +298 -0
- package/content/guidance/b2c/b2c-forms/SKILL.md +242 -0
- package/content/guidance/b2c/b2c-forms/references/FORM-XML.md +409 -0
- package/content/guidance/b2c/b2c-hooks/SKILL.md +500 -0
- package/content/guidance/b2c/b2c-hooks/references/OCAPI-SCAPI-HOOKS.md +403 -0
- package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +169 -0
- package/content/guidance/b2c/b2c-hooks/references/SYSTEM-HOOKS.md +433 -0
- package/content/guidance/b2c/b2c-isml/SKILL.md +320 -0
- package/content/guidance/b2c/b2c-isml/references/EXPRESSIONS.md +366 -0
- package/content/guidance/b2c/b2c-isml/references/TAGS.md +443 -0
- package/content/guidance/b2c/b2c-localization/SKILL.md +344 -0
- package/content/guidance/b2c/b2c-localization/references/PATTERNS.md +407 -0
- package/content/guidance/b2c/b2c-logging/SKILL.md +352 -0
- package/content/guidance/b2c/b2c-logging/references/LOG-FILES.md +282 -0
- package/content/guidance/b2c/b2c-metadata/SKILL.md +406 -0
- package/content/guidance/b2c/b2c-metadata/references/SYSTEM-OBJECTS.md +320 -0
- package/content/guidance/b2c/b2c-metadata/references/XML-EXAMPLES.md +366 -0
- package/content/guidance/b2c/b2c-onboarding/SKILL.md +154 -0
- package/content/guidance/b2c/b2c-ordering/SKILL.md +391 -0
- package/content/guidance/b2c/b2c-page-designer/SKILL.md +410 -0
- package/content/guidance/b2c/b2c-page-designer/references/ATTRIBUTE-TYPES.md +436 -0
- package/content/guidance/b2c/b2c-page-designer/references/META-DEFINITIONS.md +340 -0
- package/content/guidance/b2c/b2c-querying-data/SKILL.md +289 -0
- package/content/guidance/b2c/b2c-querying-data/references/PERFORMANCE-APIS.md +74 -0
- package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +53 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +440 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/INTEGRATION-PATTERNS.md +518 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/OAUTH-SCOPES.md +337 -0
- package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +56 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/CHECKOUT-FLOW.md +466 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +351 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/COMMON-PATTERNS.md +390 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/SCOPES.md +290 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/SKILL.md +420 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/PASSKEYS.md +126 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/SESSION-BRIDGE.md +267 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/TOKEN-LIFECYCLE.md +367 -0
- package/content/guidance/b2c/b2c-webservices/SKILL.md +318 -0
- package/content/guidance/b2c/b2c-webservices/references/FTP-SERVICES.md +524 -0
- package/content/guidance/b2c/b2c-webservices/references/HTTP-SERVICES.md +578 -0
- package/content/guidance/b2c/b2c-webservices/references/SERVICES-XML.md +351 -0
- package/content/guidance/b2c/b2c-webservices/references/SOAP-SERVICES.md +587 -0
- package/content/guidance/b2c-cli/b2c-am/SKILL.md +277 -0
- package/content/guidance/b2c-cli/b2c-bm-users-roles/SKILL.md +210 -0
- package/content/guidance/b2c-cli/b2c-cap/SKILL.md +131 -0
- package/content/guidance/b2c-cli/b2c-cip/SKILL.md +116 -0
- package/content/guidance/b2c-cli/b2c-cip/references/KNOWN_TABLES.md +105 -0
- package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +50 -0
- package/content/guidance/b2c-cli/b2c-cip/references/STARTER_QUERIES.md +147 -0
- package/content/guidance/b2c-cli/b2c-code/SKILL.md +146 -0
- package/content/guidance/b2c-cli/b2c-config/SKILL.md +462 -0
- package/content/guidance/b2c-cli/b2c-content/SKILL.md +176 -0
- package/content/guidance/b2c-cli/b2c-debug/SKILL.md +138 -0
- package/content/guidance/b2c-cli/b2c-docs/SKILL.md +301 -0
- package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +135 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +97 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/SECURITY.md +75 -0
- package/content/guidance/b2c-cli/b2c-import-set-migrations/SKILL.md +265 -0
- package/content/guidance/b2c-cli/b2c-job/SKILL.md +64 -0
- package/content/guidance/b2c-cli/b2c-job/references/EXPORT.md +121 -0
- package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +55 -0
- package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +119 -0
- package/content/guidance/b2c-cli/b2c-logs/SKILL.md +249 -0
- package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +315 -0
- package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +207 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/BUNDLE-COMMANDS.md +203 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/ENVIRONMENT-COMMANDS.md +218 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/PROJECT-COMMANDS.md +154 -0
- package/content/guidance/b2c-cli/b2c-sandbox/SKILL.md +112 -0
- package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +126 -0
- package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +66 -0
- package/content/guidance/b2c-cli/b2c-scapi-schemas/references/CLI-EXAMPLES.md +108 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +57 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/IMPORT-OPTIONS.md +118 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/METADATA-XML.md +381 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/WORKFLOWS.md +182 -0
- package/content/guidance/b2c-cli/b2c-sites/SKILL.md +112 -0
- package/content/guidance/b2c-cli/b2c-slas/SKILL.md +182 -0
- package/content/guidance/b2c-cli/b2c-webdav/SKILL.md +186 -0
- package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +68 -0
- package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +75 -0
- package/content/guidance/b2c-ops/b2c-job-health/references/job-logs.md +21 -0
- package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +66 -0
- package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +87 -0
- package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +87 -0
- package/content/guidance/b2c-ops/b2c-production-triage/references/escalation.md +57 -0
- package/content/guidance/index.json +1949 -0
- package/content/guidance/storefront-next/sfnext-accessibility/SKILL.md +103 -0
- package/content/guidance/storefront-next/sfnext-accessibility/references/checklist.md +64 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/SKILL.md +91 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/content/guidance/storefront-next/sfnext-authentication/SKILL.md +127 -0
- package/content/guidance/storefront-next/sfnext-authentication/references/COOKIES.md +39 -0
- package/content/guidance/storefront-next/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/SKILL.md +67 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/content/guidance/storefront-next/sfnext-components/SKILL.md +153 -0
- package/content/guidance/storefront-next/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/content/guidance/storefront-next/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/content/guidance/storefront-next/sfnext-components/references/STORYBOOK.md +54 -0
- package/content/guidance/storefront-next/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/content/guidance/storefront-next/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/content/guidance/storefront-next/sfnext-configuration/SKILL.md +163 -0
- package/content/guidance/storefront-next/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/content/guidance/storefront-next/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/SKILL.md +140 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/SCAPI-FETCHER.md +39 -0
- package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +127 -0
- package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +59 -0
- package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +118 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +68 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/EXTENSION-EXAMPLES.md +79 -0
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +93 -0
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +86 -0
- package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +152 -0
- package/content/guidance/storefront-next/sfnext-i18n/references/locale-config.md +35 -0
- package/content/guidance/storefront-next/sfnext-overview/SKILL.md +101 -0
- package/content/guidance/storefront-next/sfnext-page-designer/SKILL.md +202 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md +111 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +168 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/content/guidance/storefront-next/sfnext-performance/SKILL.md +102 -0
- package/content/guidance/storefront-next/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/content/guidance/storefront-next/sfnext-project-setup/SKILL.md +147 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/SKILL.md +70 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/content/guidance/storefront-next/sfnext-revalidation/SKILL.md +121 -0
- package/content/guidance/storefront-next/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/content/guidance/storefront-next/sfnext-routing/SKILL.md +123 -0
- package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +65 -0
- package/content/guidance/storefront-next/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/content/guidance/storefront-next/sfnext-scapi/SKILL.md +126 -0
- package/content/guidance/storefront-next/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/SKILL.md +129 -0
- package/content/guidance/storefront-next/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/references/TURNSTILE.md +43 -0
- package/content/guidance/storefront-next/sfnext-seo/SKILL.md +95 -0
- package/content/guidance/storefront-next/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/content/guidance/storefront-next/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/content/guidance/storefront-next/sfnext-state-management/SKILL.md +114 -0
- package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
- package/content/guidance/storefront-next/sfnext-testing/SKILL.md +151 -0
- package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
- package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +97 -0
- package/content/guidance/storefront-next/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/content/guidance/storefront-next/sfnext-theming/SKILL.md +104 -0
- package/content/guidance/storefront-next/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/dist/commands/cap/install.d.ts +1 -0
- package/dist/commands/cap/list.d.ts +1 -0
- package/dist/commands/cap/pull.d.ts +1 -0
- package/dist/commands/cap/tasks.d.ts +1 -0
- package/dist/commands/cap/uninstall.d.ts +1 -0
- package/dist/commands/cip/describe.d.ts +1 -0
- package/dist/commands/cip/query.d.ts +1 -0
- package/dist/commands/cip/report/bot-traffic-share.d.ts +1 -0
- package/dist/commands/cip/report/checkout-funnel-dropoff.d.ts +1 -0
- package/dist/commands/cip/report/controller-error-rate-trend.d.ts +1 -0
- package/dist/commands/cip/report/controller-health-scorecard.d.ts +1 -0
- package/dist/commands/cip/report/customer-registration-trends.d.ts +1 -0
- package/dist/commands/cip/report/discount-depth-breakdown.d.ts +1 -0
- package/dist/commands/cip/report/inventory-stockout-by-location.d.ts +1 -0
- package/dist/commands/cip/report/new-vs-returning-buyer-revenue.d.ts +1 -0
- package/dist/commands/cip/report/ocapi-client-usage.d.ts +1 -0
- package/dist/commands/cip/report/ocapi-requests.d.ts +1 -0
- package/dist/commands/cip/report/payment-method-performance.d.ts +1 -0
- package/dist/commands/cip/report/product-co-purchase-analysis.d.ts +1 -0
- package/dist/commands/cip/report/promotion-discount-analysis.d.ts +1 -0
- package/dist/commands/cip/report/promotion-roi-leaderboard.d.ts +1 -0
- package/dist/commands/cip/report/recommender-effectiveness.d.ts +1 -0
- package/dist/commands/cip/report/remote-include-performance.d.ts +1 -0
- package/dist/commands/cip/report/revenue-by-channel.d.ts +1 -0
- package/dist/commands/cip/report/sales-analytics.d.ts +1 -0
- package/dist/commands/cip/report/sales-summary.d.ts +1 -0
- package/dist/commands/cip/report/scapi-cache-hit-ratio.d.ts +1 -0
- package/dist/commands/cip/report/scapi-error-rate-by-status.d.ts +1 -0
- package/dist/commands/cip/report/scapi-latency-distribution.d.ts +1 -0
- package/dist/commands/cip/report/scapi-traffic-latency.d.ts +1 -0
- package/dist/commands/cip/report/search-query-performance.d.ts +1 -0
- package/dist/commands/cip/report/top-referrers.d.ts +1 -0
- package/dist/commands/cip/report/top-selling-products.d.ts +1 -0
- package/dist/commands/cip/report/zero-result-searches.d.ts +1 -0
- package/dist/commands/cip/tables.d.ts +1 -0
- package/dist/commands/code/activate.d.ts +1 -0
- package/dist/commands/code/delete.d.ts +1 -0
- package/dist/commands/code/deploy.d.ts +1 -0
- package/dist/commands/code/download.d.ts +1 -0
- package/dist/commands/code/watch.d.ts +1 -0
- package/dist/commands/commands/search.d.ts +35 -0
- package/dist/commands/commands/search.js +85 -0
- package/dist/commands/commands/search.js.map +1 -0
- package/dist/commands/content/export.d.ts +1 -0
- package/dist/commands/content/list.d.ts +1 -0
- package/dist/commands/content/validate.d.ts +1 -0
- package/dist/commands/debug/cli.d.ts +1 -0
- package/dist/commands/debug/index.d.ts +1 -0
- package/dist/commands/docs/cache.d.ts +1 -0
- package/dist/commands/docs/download.d.ts +1 -0
- package/dist/commands/docs/read.d.ts +1 -0
- package/dist/commands/docs/schema.d.ts +1 -0
- package/dist/commands/docs/search.d.ts +1 -0
- package/dist/commands/docs/skill.d.ts +41 -0
- package/dist/commands/docs/skill.js +183 -0
- package/dist/commands/docs/skill.js.map +1 -0
- package/dist/commands/ecdn/cache/purge.d.ts +1 -0
- package/dist/commands/ecdn/certificates/add.d.ts +1 -0
- package/dist/commands/ecdn/certificates/delete.d.ts +1 -0
- package/dist/commands/ecdn/certificates/list.d.ts +1 -0
- package/dist/commands/ecdn/certificates/update.d.ts +1 -0
- package/dist/commands/ecdn/certificates/validate.d.ts +1 -0
- package/dist/commands/ecdn/cipher-suites/get.d.ts +1 -0
- package/dist/commands/ecdn/cipher-suites/update.d.ts +1 -0
- package/dist/commands/ecdn/firewall/create.d.ts +1 -0
- package/dist/commands/ecdn/firewall/delete.d.ts +1 -0
- package/dist/commands/ecdn/firewall/get.d.ts +1 -0
- package/dist/commands/ecdn/firewall/list.d.ts +1 -0
- package/dist/commands/ecdn/firewall/reorder.d.ts +1 -0
- package/dist/commands/ecdn/firewall/update.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/create.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/delete.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/get.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/list.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/update.d.ts +1 -0
- package/dist/commands/ecdn/logpush/ownership.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/create.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/delete.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/get.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/rules/delete.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/rules/update.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/update.d.ts +1 -0
- package/dist/commands/ecdn/mtls/create.d.ts +1 -0
- package/dist/commands/ecdn/mtls/delete.d.ts +1 -0
- package/dist/commands/ecdn/mtls/get.d.ts +1 -0
- package/dist/commands/ecdn/mtls/issue.d.ts +1 -0
- package/dist/commands/ecdn/mtls/list.d.ts +1 -0
- package/dist/commands/ecdn/mtls/setup.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/delete.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/get.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/set.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/create.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/delete.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/list.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/create.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/delete.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/get.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/list.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/update.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/scripts/get.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/scripts/list.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/create.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/delete.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/get.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/list.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/update.d.ts +1 -0
- package/dist/commands/ecdn/security/get.d.ts +1 -0
- package/dist/commands/ecdn/security/update.d.ts +1 -0
- package/dist/commands/ecdn/speed/get.d.ts +1 -0
- package/dist/commands/ecdn/speed/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/groups/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/groups/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/managed-rules/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/managed-rules/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/migrate.d.ts +1 -0
- package/dist/commands/ecdn/waf/owasp/get.d.ts +1 -0
- package/dist/commands/ecdn/waf/owasp/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/get.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/rulesets/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/rulesets/update.d.ts +1 -0
- package/dist/commands/ecdn/zones/create.d.ts +1 -0
- package/dist/commands/ecdn/zones/list.d.ts +1 -0
- package/dist/commands/job/execution/delete.d.ts +1 -0
- package/dist/commands/job/export.d.ts +1 -0
- package/dist/commands/job/import-set.d.ts +1 -0
- package/dist/commands/job/import.d.ts +1 -0
- package/dist/commands/job/log.d.ts +1 -0
- package/dist/commands/job/run.d.ts +1 -0
- package/dist/commands/job/search.d.ts +1 -0
- package/dist/commands/job/wait.d.ts +1 -0
- package/dist/commands/logs/get.d.ts +1 -0
- package/dist/commands/logs/list.d.ts +1 -0
- package/dist/commands/logs/tail.d.ts +1 -0
- package/dist/commands/metrics/controller.d.ts +1 -0
- package/dist/commands/metrics/ecdn.d.ts +1 -0
- package/dist/commands/metrics/mrt.d.ts +1 -0
- package/dist/commands/metrics/ocapi.d.ts +1 -0
- package/dist/commands/metrics/overall.d.ts +1 -0
- package/dist/commands/metrics/sales.d.ts +1 -0
- package/dist/commands/metrics/scapi-hooks.d.ts +1 -0
- package/dist/commands/metrics/scapi.d.ts +1 -0
- package/dist/commands/metrics/third-party.d.ts +1 -0
- package/dist/commands/mrt/bundle/delete.d.ts +1 -0
- package/dist/commands/mrt/bundle/deploy.d.ts +1 -0
- package/dist/commands/mrt/bundle/download.d.ts +1 -0
- package/dist/commands/mrt/bundle/history.d.ts +1 -0
- package/dist/commands/mrt/bundle/list.d.ts +1 -0
- package/dist/commands/mrt/bundle/save.d.ts +1 -0
- package/dist/commands/mrt/bundle/upload-v2.d.ts +1 -0
- package/dist/commands/mrt/env/access-control/list.d.ts +1 -0
- package/dist/commands/mrt/env/b2c.d.ts +1 -0
- package/dist/commands/mrt/env/clone.d.ts +1 -0
- package/dist/commands/mrt/env/create.d.ts +1 -0
- package/dist/commands/mrt/env/delete.d.ts +1 -0
- package/dist/commands/mrt/env/get.d.ts +1 -0
- package/dist/commands/mrt/env/invalidate.d.ts +1 -0
- package/dist/commands/mrt/env/list.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/clone.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/create.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/delete.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/list.d.ts +1 -0
- package/dist/commands/mrt/env/update.d.ts +1 -0
- package/dist/commands/mrt/env/var/delete.d.ts +1 -0
- package/dist/commands/mrt/env/var/list.d.ts +1 -0
- package/dist/commands/mrt/env/var/push.d.ts +1 -0
- package/dist/commands/mrt/env/var/set.d.ts +1 -0
- package/dist/commands/mrt/org/b2c.d.ts +1 -0
- package/dist/commands/mrt/org/cert/create.d.ts +1 -0
- package/dist/commands/mrt/org/cert/delete.d.ts +1 -0
- package/dist/commands/mrt/org/cert/get.d.ts +1 -0
- package/dist/commands/mrt/org/cert/list.d.ts +1 -0
- package/dist/commands/mrt/org/cert/restart-validation.d.ts +1 -0
- package/dist/commands/mrt/org/list.d.ts +1 -0
- package/dist/commands/mrt/org/member/add.d.ts +1 -0
- package/dist/commands/mrt/org/member/get.d.ts +1 -0
- package/dist/commands/mrt/org/member/list.d.ts +1 -0
- package/dist/commands/mrt/org/member/remove.d.ts +1 -0
- package/dist/commands/mrt/org/member/update.d.ts +1 -0
- package/dist/commands/mrt/project/create.d.ts +1 -0
- package/dist/commands/mrt/project/delete.d.ts +1 -0
- package/dist/commands/mrt/project/get.d.ts +1 -0
- package/dist/commands/mrt/project/list.d.ts +1 -0
- package/dist/commands/mrt/project/member/add.d.ts +1 -0
- package/dist/commands/mrt/project/member/get.d.ts +1 -0
- package/dist/commands/mrt/project/member/list.d.ts +1 -0
- package/dist/commands/mrt/project/member/remove.d.ts +1 -0
- package/dist/commands/mrt/project/member/update.d.ts +1 -0
- package/dist/commands/mrt/project/notification/delete.d.ts +1 -0
- package/dist/commands/mrt/project/notification/get.d.ts +1 -0
- package/dist/commands/mrt/project/update.d.ts +1 -0
- package/dist/commands/mrt/save-credentials.d.ts +1 -0
- package/dist/commands/mrt/tail-logs.d.ts +1 -0
- package/dist/commands/mrt/user/api-key.d.ts +1 -0
- package/dist/commands/mrt/user/email-prefs.d.ts +1 -0
- package/dist/commands/mrt/user/profile.d.ts +1 -0
- package/dist/commands/scaffold/init.js +2 -1
- package/dist/commands/scaffold/init.js.map +1 -1
- package/dist/commands/scapi/custom/status.d.ts +1 -0
- package/dist/commands/scapi/schemas/get.d.ts +1 -0
- package/dist/commands/scapi/schemas/list.d.ts +1 -0
- package/dist/commands/setup/ide/tsserver-plugin.d.ts +1 -0
- package/dist/commands/setup/ide/vscode-types.d.ts +1 -0
- package/dist/commands/setup/index.js +4 -3
- package/dist/commands/setup/index.js.map +1 -1
- package/dist/commands/setup/inspect.d.ts +1 -0
- package/dist/commands/setup/inspect.js +17 -2
- package/dist/commands/setup/inspect.js.map +1 -1
- package/dist/commands/setup/instance/create.d.ts +1 -0
- package/dist/commands/setup/instance/list.d.ts +1 -0
- package/dist/commands/setup/instance/remove.d.ts +1 -0
- package/dist/commands/setup/instance/set-active.d.ts +1 -0
- package/dist/commands/setup/openshell.d.ts +1 -0
- package/dist/commands/setup/skills.d.ts +1 -0
- package/dist/commands/slas/client/create.d.ts +1 -0
- package/dist/commands/slas/client/delete.d.ts +1 -0
- package/dist/commands/slas/client/get.d.ts +1 -0
- package/dist/commands/slas/client/list.d.ts +1 -0
- package/dist/commands/slas/client/open.d.ts +1 -0
- package/dist/commands/slas/client/update.d.ts +1 -0
- package/dist/commands/slas/token.d.ts +1 -0
- package/dist/commands/slas/token.js +2 -1
- package/dist/commands/slas/token.js.map +1 -1
- package/dist/commands/webdav/get.d.ts +1 -0
- package/dist/commands/webdav/mkdir.d.ts +2 -0
- package/dist/commands/webdav/mkdir.js +5 -3
- package/dist/commands/webdav/mkdir.js.map +1 -1
- package/dist/commands/webdav/put.d.ts +2 -0
- package/dist/commands/webdav/put.js +5 -3
- package/dist/commands/webdav/put.js.map +1 -1
- package/dist/commands/webdav/rm.d.ts +1 -0
- package/dist/help.d.ts +25 -0
- package/dist/help.js +96 -0
- package/dist/help.js.map +1 -0
- package/dist/lib/scaffold/generate-helper.js +3 -2
- package/dist/lib/scaffold/generate-helper.js.map +1 -1
- package/dist/lib/skills.d.ts +19 -0
- package/dist/lib/skills.js +75 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/utils/cip/command.d.ts +1 -0
- package/dist/utils/ecdn/zone-command.d.ts +1 -0
- package/dist/utils/slas/client.d.ts +1 -0
- package/oclif.manifest.json +10994 -7653
- package/package.json +11 -5
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Feature prerequisites checklist
|
|
2
|
+
|
|
3
|
+
Verify each item in your project; these come from the shipped docs and config.
|
|
4
|
+
|
|
5
|
+
## Shopper Context
|
|
6
|
+
- Flag: `features.shopperContext.enabled` (default false). When off, the middleware makes no SCAPI calls.
|
|
7
|
+
- Qualifiers come from URL query params (middleware) or `useShopperContext`; state persists in cookies and is sent to SCAPI as a full replace.
|
|
8
|
+
- Customizing supported qualifiers: `docs/README-SHOPPER-CONTEXT.md` "Customization".
|
|
9
|
+
|
|
10
|
+
## Order Management
|
|
11
|
+
- No flag. Needs SOM connected; the order detail loader calls `shopperOrders.getOrder` with `expand: ['oms', 'oms_shipments']`.
|
|
12
|
+
- Return/cancel render only for registered, owning shoppers with item-level availability (`omsData.quantityAvailableToReturn > 0`).
|
|
13
|
+
- ECOM-only orders degrade to tracking.
|
|
14
|
+
|
|
15
|
+
## Delivery estimates
|
|
16
|
+
- SLAS scopes: `sfcc.shopper-delivery-estimates`, `sfcc.shopper-standard`.
|
|
17
|
+
- Commerce App provider bound to `sfcc.app.shipping.estimate`.
|
|
18
|
+
- API `403`/`500` falls back to merchant shipping-method descriptions as general guidance only.
|
|
19
|
+
- Verify by requesting an estimate for a product and destination; troubleshooting section in the doc.
|
|
20
|
+
|
|
21
|
+
## Guest order lookup
|
|
22
|
+
- Flag `guestOrderLookup.enabled`; keys include `orderNumberPattern`, `cooldownSeconds`, `allowedFields`.
|
|
23
|
+
- Cookie secret env var required or the feature fails closed.
|
|
24
|
+
- Access code lifetime is set by SCAPI, email is sent by your hook implementation.
|
|
25
|
+
- When disabled: page routes 404 and action routes return `FEATURE_DISABLED`.
|
|
26
|
+
|
|
27
|
+
## Email cartridge
|
|
28
|
+
1. `sfnext setup-base-cartridge --slas-client-id <id>` (idempotent; reads `SFCC_SHORTCODE`, `SFCC_TENANT_ID`, `SFCC_OAUTH_CLIENT_ID`, `SFCC_OAUTH_CLIENT_SECRET` or `dw.json`).
|
|
29
|
+
2. Deploy: `pnpm cartridge:deploy` (script runs `sfnext deploy-cartridge`). The email-cartridge doc shows a different command spelling; prefer the script in your `package.json`.
|
|
30
|
+
3. Add `app_storefrontnext_base` to the site cartridge path; import the preference metadata; set the `Storefront Hosts` preference to your MRT hostnames.
|
|
31
|
+
4. Set callback mode and callback URIs in storefront config; register the matching URLs in SLAS.
|
|
32
|
+
Also see `storefront-next:sfnext-deployment`.
|
|
33
|
+
|
|
34
|
+
## Extensions
|
|
35
|
+
- Registry entries list `dependencies` (BOPIS -> Store Locator, Multiship).
|
|
36
|
+
- Store Locator, Multiship, BOPIS ship install/uninstall `.mdc` instructions in `instructions/`. Additional BM or backend setup for them is not documented in a single place; check the instructions and each extension folder.
|
|
37
|
+
- Demo extensions use fixtures; replace the API function bodies before production.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sfnext-components
|
|
3
|
+
description: >-
|
|
4
|
+
Build and modify UI components in a Storefront Next storefront: page components with Suspense and use()/Await, createPage and withSuspense, Tailwind v4 token classes, shape tokens (rounded-ui, shadow-ui, border-ui), shadcn/ui primitives in src/components/ui (sync-shadcn), CVA variants, data-slot, DynamicImage, lazy-loaded overlays, and Storybook stories with snapshot tests. Use when creating or editing a component in src/components, adding a shadcn primitive, fixing styling that ignores the theme, writing a *.stories.tsx file, or running pnpm storybook:test. Do not use for re-branding colors, fonts, or logos (use `storefront-next:sfnext-theming`), route loaders (use `storefront-next:sfnext-data-fetching`), or Page Designer registration (use `storefront-next:sfnext-page-designer`).
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Storefront Next Components
|
|
8
|
+
|
|
9
|
+
How to write, style, and verify components in your storefront. Your project already ships the rules in `AGENTS.md`, `docs/README-UI-STYLING.md`, `docs/README-SHAPE-TOKENS.md`, `docs/README-SUSPENSE.md`, and `docs/README-STORYBOOK.md`; this skill is the task-oriented path through them.
|
|
10
|
+
|
|
11
|
+
## Before you create anything
|
|
12
|
+
|
|
13
|
+
1. Search `src/components/` for an existing component (`ls src/components`). Extend or compose it before adding a new one.
|
|
14
|
+
2. Decide the layer:
|
|
15
|
+
- **Primitive** (Button, Card, Dialog): a shadcn fork in `src/components/ui/`. Only shadcn forks live there.
|
|
16
|
+
- **Composite / domain component**: everything else, in `src/components/<kebab-name>/`.
|
|
17
|
+
- **Optional feature**: a folder under `src/extensions/` (see `storefront-next:sfnext-extensions`).
|
|
18
|
+
3. Match the folder shape already used by neighbors:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
src/components/my-widget/
|
|
22
|
+
├── index.tsx # implementation (default or named export)
|
|
23
|
+
├── index.test.tsx # Vitest + Testing Library
|
|
24
|
+
└── stories/
|
|
25
|
+
├── index.stories.tsx # Storybook (stories/ subfolder is required)
|
|
26
|
+
├── my-widget-snapshot.tsx # optional snapshot fixture
|
|
27
|
+
└── __snapshots__/ # generated baselines, commit them
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Every `.ts`/`.tsx` file needs the Apache header enforced by the `custom/header-format` lint rule. Copy it from any existing file (or `AGENTS.md`).
|
|
31
|
+
|
|
32
|
+
## Styling rules
|
|
33
|
+
|
|
34
|
+
- Tailwind utility classes only; merge with `cn()` from `@/lib/utils`. No CSS modules, no per-component CSS files, no `style={{}}` (a truly dynamic API-driven value is the only exception).
|
|
35
|
+
- Global/theme CSS lives in `src/theme/` only (entry `src/theme/index.css`). There is no `src/app.css`.
|
|
36
|
+
- Use semantic token classes, never hard-coded colors. The `custom/color-linter` rule fails `pnpm lint` on raw palette classes such as `text-white` or `bg-red-500`; use `text-primary-foreground`, `text-destructive-foreground`, `bg-card`, `text-muted-foreground`, `border-border`.
|
|
37
|
+
- Header/footer chrome has its own classes: `bg-header-background`, `text-header-foreground`, `bg-header-menu-background`, `bg-footer-background`. Do not write `bg-[--header-background]`.
|
|
38
|
+
- A new token needs two edits: the value in `src/theme/tokens/*.css` and a `--color-x: var(--x)` line inside `@theme inline` in `src/theme/tailwind.css`. See [TOKEN-SYSTEM.md](references/TOKEN-SYSTEM.md).
|
|
39
|
+
- The shipped theme defines one (light) palette; there is no `.dark` token block. Do not promise dark mode in component work.
|
|
40
|
+
- Breakpoints are mobile-first (`sm`, `md`, `lg`, `xl`, `2xl`).
|
|
41
|
+
|
|
42
|
+
### Shape tokens (read before touching Card, Button, Input, Dialog)
|
|
43
|
+
|
|
44
|
+
Radius, shadow, and card border width come from three variables in `src/theme/tokens/core.css`: `--ui-radius`, `--ui-shadow`, `--ui-border-width`, consumed through `rounded-ui`, `shadow-ui`, `border-ui`.
|
|
45
|
+
|
|
46
|
+
- Never add `rounded-xl`, `rounded-none`, `shadow-md`, `shadow-none`, or `border-0` to a primitive or a Card to force a shape. Change the token, or scope it: `<Card className="[--ui-radius:var(--radius-xl)]">`.
|
|
47
|
+
- Always write the source names (`--ui-radius`). Writing the bridge names `--radius-ui` / `--shadow-ui` is a silent no-op.
|
|
48
|
+
- `border-ui` is Card-only. To show a Card border use `[--ui-border-width:1px]`, not `border`.
|
|
49
|
+
|
|
50
|
+
Full mechanism and scoped-override recipes: [SHAPE-TOKENS.md](references/SHAPE-TOKENS.md).
|
|
51
|
+
|
|
52
|
+
## Page components and Suspense
|
|
53
|
+
|
|
54
|
+
Route components receive `loaderData` with deferred fields as unresolved promises. Rules from `AGENTS.md`: one `<Suspense>` per async operation, stable promise identity (never `Promise.all`/`.then` in render; compose in the loader), skeletons where layout is known.
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { Suspense, use } from 'react';
|
|
58
|
+
import { Await } from 'react-router';
|
|
59
|
+
|
|
60
|
+
function Reviews({ promise }: { promise: Promise<ReviewsData> }) {
|
|
61
|
+
const reviews = use(promise);
|
|
62
|
+
return <ReviewList reviews={reviews} />;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default function ProductPage({ loaderData }: { loaderData: PageData }) {
|
|
66
|
+
return (
|
|
67
|
+
<>
|
|
68
|
+
{/* use() needs a small child component */}
|
|
69
|
+
<Suspense fallback={<ReviewsSkeleton />}>
|
|
70
|
+
<Reviews promise={loaderData.reviews} />
|
|
71
|
+
</Suspense>
|
|
72
|
+
|
|
73
|
+
{/* Await resolves inline and supports a local errorElement */}
|
|
74
|
+
<Suspense fallback={<RecsSkeleton />}>
|
|
75
|
+
<Await resolve={loaderData.recommendations}>{(recs) => <Recommendations items={recs} />}</Await>
|
|
76
|
+
</Suspense>
|
|
77
|
+
</>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`createPage` (`@/components/create-page`) wraps a component with the standard Suspense fallback and keys the page so navigations remount it:
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { createPage } from '@/components/create-page';
|
|
86
|
+
|
|
87
|
+
export default createPage({
|
|
88
|
+
component: CategoryView,
|
|
89
|
+
fallback: <CategorySkeleton />, // optional; default is a generic skeleton
|
|
90
|
+
getPageKey: (data) => data?.categoryId, // optional; default is pathname+search+hash
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`withSuspense` (`@/components/with-suspense`) is the lower-level HOC for a single async child. Details: `docs/README-SUSPENSE.md`.
|
|
95
|
+
|
|
96
|
+
## Links, navigation, text
|
|
97
|
+
|
|
98
|
+
- Import `Link`/`NavLink` from `@/components/link` and `useNavigate` from `@/hooks/use-navigate`, never from `react-router`. The wrappers add the site/locale URL prefix; the originals silently drop it. Combine with `href()` for typed params.
|
|
99
|
+
- Strings go through `react-i18next` (`useTranslation`) and prices through `formatCurrency` in `@/lib/currency`. Do not hard-code `'en-US'` or `$`. See `storefront-next:sfnext-i18n`.
|
|
100
|
+
|
|
101
|
+
## Images
|
|
102
|
+
|
|
103
|
+
Use `<DynamicImage>` (`@/components/dynamic-image`) with `widths` (and `heights` for cropping) for product and content images; add `priority="high"` to the LCP image. Behavior is configured under the `images` key of `config.server.ts` (`quality`, `formats`, `fallbackFormat`, `host`, `enableDis`, `realmHostMappings`); see `docs/README-IMAGES.md`. Wrap grids in `DynamicImageProvider` (`@/providers/dynamic-image`) instead of prop-drilling sizes.
|
|
104
|
+
|
|
105
|
+
## Overlays
|
|
106
|
+
|
|
107
|
+
Modals, drawers, and dialogs hidden on first render must be `React.lazy()` and mounted only after first interaction, gated on `open` with `useDeferredUnmount` from `@/hooks/use-deferred-unmount`. Do not keep a sticky "loaded" latch. Pattern: `docs/README-PERFORMANCE.md` ("Lazy Loading for Overlays").
|
|
108
|
+
|
|
109
|
+
## shadcn primitives
|
|
110
|
+
|
|
111
|
+
`src/components/ui/` files are forks of shadcn/ui that you own and may edit in place (shape tokens, `data-slot`, extra props). Do not put non-shadcn components there, and do not hand-copy from the shadcn docs. Use the in-project `sync-shadcn` skill (`.claude/skills/sync-shadcn/`):
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
S=.claude/skills/sync-shadcn/sync.mjs
|
|
115
|
+
node $S add slider # fetch from shadcn, apply shape tokens + import convention, seed baseline
|
|
116
|
+
node $S restyle --all --check # gate: exit 1 if any fork has drifted off the shape-token rules
|
|
117
|
+
node $S restyle src/components/ui/toggle.tsx # normalize one file
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Prefer `add` over `npx shadcn@latest add`: `npx` pulls the older `new-york` registry style and leaves raw `rounded-md`/`shadow-sm` classes you then have to restyle. To pull upstream fixes into an existing fork, use `status` / `sync <name>` / `diff <name>` / `advance <name>` (a 3-way merge that keeps your edits); these need a merge baseline in `.shadcn-baseline/`, which `add` and `sync <name> --bootstrap` create. Read `.claude/skills/sync-shadcn/SKILL.md` for conflict handling. If it mentions a path that does not exist in your project, use the `ui` directory configured in `components.json`.
|
|
121
|
+
|
|
122
|
+
## Stories and verification
|
|
123
|
+
|
|
124
|
+
Each reusable component needs `stories/*.stories.tsx` using `@storybook/react-vite` and a title from the fixed taxonomy (`Products/Product Tile/Product Tile`). `src/components/ui/` is excluded from story coverage. Details and the snapshot fixture pattern: [STORYBOOK.md](references/STORYBOOK.md).
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pnpm typecheck
|
|
128
|
+
pnpm lint # oxlint (color-linter, header, a11y rules) + biome format check
|
|
129
|
+
pnpm test # Vitest
|
|
130
|
+
pnpm storybook:test --type=snapshot # add --update only for intended DOM changes
|
|
131
|
+
pnpm storybook:test --type=a11y # axe-core; new stories must pass
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Interaction and a11y runs need Chromium once (`pnpm exec playwright install chromium`).
|
|
135
|
+
|
|
136
|
+
## More detail
|
|
137
|
+
|
|
138
|
+
- [COMPONENT-AUTHORING.md](references/COMPONENT-AUTHORING.md): worked example, CVA variants, accessibility checklist, CSS component classes vs React components, mask icons
|
|
139
|
+
- [TOKEN-SYSTEM.md](references/TOKEN-SYSTEM.md): token files, bridge, class names
|
|
140
|
+
- [SHAPE-TOKENS.md](references/SHAPE-TOKENS.md): shape token mechanism and traps
|
|
141
|
+
- [STORYBOOK.md](references/STORYBOOK.md): story layout, titles, snapshots
|
|
142
|
+
- [TROUBLESHOOTING.md](references/TROUBLESHOOTING.md): symptom to fix
|
|
143
|
+
|
|
144
|
+
## Related Skills
|
|
145
|
+
|
|
146
|
+
- `storefront-next:sfnext-theming` - Change palette, fonts, logo, and shape for your brand
|
|
147
|
+
- `storefront-next:sfnext-data-fetching` - Loaders that feed data to components
|
|
148
|
+
- `storefront-next:sfnext-page-designer` - Make a component Page Designer-editable
|
|
149
|
+
- `storefront-next:sfnext-extensions` - Extension folders and UI targets
|
|
150
|
+
- `storefront-next:sfnext-testing` - Vitest, Storybook, and e2e testing
|
|
151
|
+
- `storefront-next:sfnext-accessibility` - Accessibility requirements and scans
|
|
152
|
+
- `storefront-next:sfnext-i18n` - Translating component text
|
|
153
|
+
- `storefront-next:sfnext-performance` - Lazy loading, images, bundle size
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Component Authoring
|
|
2
|
+
|
|
3
|
+
## Workflow
|
|
4
|
+
|
|
5
|
+
1. **Search first.** `ls src/components`, and grep for the behavior you need. Prefer composing or extending.
|
|
6
|
+
2. **Pick the layer.** shadcn fork in `src/components/ui/`, or a composite in `src/components/<name>/`, or an extension under `src/extensions/`.
|
|
7
|
+
3. **Implement** with token classes, `cn()`, project link wrappers, i18n, `formatCurrency`.
|
|
8
|
+
4. **Add a test** (`index.test.tsx`, Vitest + Testing Library) and a **story** (see [STORYBOOK.md](STORYBOOK.md)).
|
|
9
|
+
5. **Verify** with `pnpm typecheck`, `pnpm lint`, `pnpm test`, `pnpm storybook:test --type=snapshot`.
|
|
10
|
+
|
|
11
|
+
## Composite example
|
|
12
|
+
|
|
13
|
+
A small presentational component with a variant, token classes, a `data-slot` root, translated text, and a safe price format. Names here are illustrative; check that a component of that name does not already exist.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
/* Apache header (copy from any existing file) */
|
|
17
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
18
|
+
import { useTranslation } from 'react-i18next';
|
|
19
|
+
import { cn } from '@/lib/utils';
|
|
20
|
+
import { formatCurrency } from '@/lib/currency';
|
|
21
|
+
|
|
22
|
+
const promoVariants = cva('inline-flex items-center gap-1 px-2 py-1 text-sm font-medium rounded-ui', {
|
|
23
|
+
variants: {
|
|
24
|
+
tone: {
|
|
25
|
+
default: 'bg-primary text-primary-foreground',
|
|
26
|
+
muted: 'bg-muted text-muted-foreground',
|
|
27
|
+
danger: 'bg-destructive text-destructive-foreground',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: { tone: 'default' },
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
interface PromoPriceProps extends VariantProps<typeof promoVariants> {
|
|
34
|
+
amount: number;
|
|
35
|
+
currency: string;
|
|
36
|
+
locale: string;
|
|
37
|
+
className?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function PromoPrice({ amount, currency, locale, tone, className }: PromoPriceProps) {
|
|
41
|
+
const { t } = useTranslation();
|
|
42
|
+
return (
|
|
43
|
+
<span data-slot="promo-price" className={cn(promoVariants({ tone }), className)}>
|
|
44
|
+
{t('promoPrice.label', { defaultValue: 'Now' })} {formatCurrency(amount, locale, currency)}
|
|
45
|
+
</span>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Add real translation keys to `src/locales/<locale>/translations.json` for every supported locale (see `storefront-next:sfnext-i18n`); do not rely on `defaultValue` in shipped code.
|
|
51
|
+
|
|
52
|
+
## Rules of thumb
|
|
53
|
+
|
|
54
|
+
- **Props over globals.** Keep components presentational; data arrives through props or a narrow hook.
|
|
55
|
+
- **`asChild`** (Radix `Slot`) for polymorphism; do not add an `as` prop.
|
|
56
|
+
- **`data-slot`** on the root and named regions. It is the stable hook for theme CSS and shape-token overrides. It is a convention of the shadcn forks, not a lint rule.
|
|
57
|
+
- **Variants** with `cva`; variant classes use semantic tokens (`text-destructive-foreground`, not `text-white`).
|
|
58
|
+
- **Shape**: no raw `rounded-*`/`shadow-*` on primitives or Cards; see [SHAPE-TOKENS.md](SHAPE-TOKENS.md). `rounded-full` on a pill or avatar and `rounded-t-*` style directional radii are fine.
|
|
59
|
+
- **Context**: split React contexts by concern; avoid one large `AppContext` (every change re-renders every consumer).
|
|
60
|
+
- **Client-only data** goes through loaders or `useFetcher`, not `useEffect` fetches for first render.
|
|
61
|
+
- **Links**: `@/components/link`, `@/hooks/use-navigate`.
|
|
62
|
+
- **Icons**: `lucide-react` (and `@icons-pack/react-simple-icons` for brand icons).
|
|
63
|
+
|
|
64
|
+
## Editing a shadcn primitive
|
|
65
|
+
|
|
66
|
+
Primitives are your fork. It is fine to edit them in place: add a variant, a prop, or a `data-slot`. Keep shape tokens (`rounded-ui`, `shadow-ui`, `border-ui`) and `@/` imports. After editing or syncing, run `node .claude/skills/sync-shadcn/sync.mjs restyle --all --check`. Do not add app-specific components to `src/components/ui/`; wrap the primitive in `src/components/` instead:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { Button } from '@/components/ui/button';
|
|
70
|
+
import { cn } from '@/lib/utils';
|
|
71
|
+
|
|
72
|
+
export function PillButton(props: React.ComponentProps<typeof Button>) {
|
|
73
|
+
return <Button {...props} className={cn('rounded-full', props.className)} />;
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## CSS component class, utility, or React component?
|
|
78
|
+
|
|
79
|
+
Default to a React component when there is markup, props, or logic. Use a CSS component class only for a pure layout bag of properties applied to many different elements, defined in `@layer components` in `src/theme/base.css` so utilities can still override it. The shipped example is `.section-container` (horizontal padding, max width, centered). Do not use `@utility` for overridable multi-property compositions; the utilities layer has the highest specificity and overrides lose.
|
|
80
|
+
|
|
81
|
+
```css
|
|
82
|
+
/* src/theme/base.css */
|
|
83
|
+
@layer components {
|
|
84
|
+
.section-container {
|
|
85
|
+
@apply px-4 sm:px-8 lg:px-16 max-w-screen-2xl mx-auto;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Decorative icons from CSS
|
|
91
|
+
|
|
92
|
+
To add a purely decorative icon to a component you do not want to fork, define the SVG once as a token (a percent-encoded `data:image/svg+xml` URI, with `stroke="black"` because only alpha matters in a mask) in `src/theme/tokens/core.css`, then paint it with a pseudo-element in `src/theme/base.css`:
|
|
93
|
+
|
|
94
|
+
```css
|
|
95
|
+
[data-slot="section-title"]::before {
|
|
96
|
+
content: "";
|
|
97
|
+
display: inline-block;
|
|
98
|
+
width: 1rem;
|
|
99
|
+
height: 1rem;
|
|
100
|
+
background-color: currentColor; /* tracks the text color */
|
|
101
|
+
-webkit-mask: var(--icon-star) center / contain no-repeat;
|
|
102
|
+
mask: var(--icon-star) center / contain no-repeat;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Use `mask` plus `background-color`, not `content: url()` (which cannot inherit `currentColor`). Keep the hooked structure stable. Full write-up with state swapping: `docs/README-UI-STYLING.md`.
|
|
107
|
+
|
|
108
|
+
## Accessibility checklist
|
|
109
|
+
|
|
110
|
+
- Semantic HTML first (`button`, `nav`, `main`, `ul`), ARIA only to fill gaps.
|
|
111
|
+
- Interactive elements are keyboard reachable with a visible focus ring (`focus-visible:ring-ring/50 focus-visible:ring-[3px]`).
|
|
112
|
+
- Text and UI boundaries meet WCAG AA contrast using theme tokens (the token comments in `core.css` record ratios).
|
|
113
|
+
- Images have `alt` (empty string for decorative).
|
|
114
|
+
- Run `pnpm lint:a11y` and `pnpm storybook:test --type=a11y`. See `storefront-next:sfnext-accessibility`.
|
|
115
|
+
|
|
116
|
+
## Page Designer
|
|
117
|
+
|
|
118
|
+
To make a component editable in Page Designer, use the decorators and registry described in `storefront-next:sfnext-page-designer`; do not hand-roll metadata.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Shape Tokens
|
|
2
|
+
|
|
3
|
+
Radius, shadow, and Card border width are driven by three variables so one edit re-skins every shadcn primitive. The project doc is `docs/README-SHAPE-TOKENS.md`; this is the working summary.
|
|
4
|
+
|
|
5
|
+
| Variable | Defined in | Utility |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `--ui-radius` | `src/theme/tokens/core.css` | `rounded-ui` (about 19 primitives) |
|
|
8
|
+
| `--ui-shadow` | `src/theme/tokens/core.css` | `shadow-ui` |
|
|
9
|
+
| `--ui-border-width` | `src/theme/tokens/core.css` | `border-ui` (Card only) |
|
|
10
|
+
|
|
11
|
+
Your starter theme's values are the ones in `core.css` (a square, flat, borderless default is `0` / `none` / `0`). For a rounded, raised look set for example `--ui-radius: var(--radius-xl)` and a soft `--ui-shadow`.
|
|
12
|
+
|
|
13
|
+
## The bridge-variable trap
|
|
14
|
+
|
|
15
|
+
`src/theme/tailwind.css` contains `--radius-ui: var(--ui-radius)` and `--shadow-ui: var(--ui-shadow)` inside `@theme inline`. Tailwind inlines these at compile time, so `--radius-ui` and `--shadow-ui` do not exist at runtime. Writing them is a silent no-op that passes lint and typecheck. Always write `--ui-radius`, `--ui-shadow`, `--ui-border-width`. `border-ui` is an `@utility` that reads `--ui-border-width` at runtime.
|
|
16
|
+
|
|
17
|
+
## Overrides
|
|
18
|
+
|
|
19
|
+
Per instance (Tailwind arbitrary property):
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<Card className="[--ui-border-width:2px] border-primary">
|
|
23
|
+
<Card className="[--ui-radius:var(--radius-2xl)]">
|
|
24
|
+
<Card className="[--ui-shadow:none]">
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Per component or section, in `src/theme/base.css`. Use `[data-slot="card"]` as the hook, and `:where()` to keep specificity low so className overrides still win:
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
.product-card[data-slot="card"] {
|
|
31
|
+
--ui-radius: var(--radius-2xl);
|
|
32
|
+
--ui-shadow: 0 4px 16px -4px rgb(0 0 0 / 0.12);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:where([data-section="auth"]) [data-slot="card"] {
|
|
36
|
+
--ui-border-width: 1px;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The shipped `base.css` already re-enables a 1px Card border for account, auth, checkout, and order-confirmation sections because the default border width is 0. Place later `:where()` blocks after earlier ones that target the same `data-slot`; equal specificity means the later block wins.
|
|
41
|
+
|
|
42
|
+
## Don't
|
|
43
|
+
|
|
44
|
+
| Don't | Why | Do |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `className="rounded-xl"` or `rounded-none` on a primitive | Fights the token; breaks when the token changes | Set `[--ui-radius:...]` or change `core.css` |
|
|
47
|
+
| `className="border"` / `border-2` on Card | `border-ui` reads the variable, both classes coexist | `[--ui-border-width:1px]` |
|
|
48
|
+
| `!rounded-none`, hard-coded `border-radius` / `box-shadow` in CSS | Not token-driven | Override the variable |
|
|
49
|
+
| Styling via Tailwind class selectors (`.bg-cover`) | Breaks on refactor | Target `data-slot` |
|
|
50
|
+
|
|
51
|
+
`cn()` in `src/lib/utils.ts` registers `border-ui` as its own tailwind-merge group, so `cn('border-ui border-border', 'border-primary')` keeps width and swaps color.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Stories and Storybook Checks
|
|
2
|
+
|
|
3
|
+
Project reference: `docs/README-STORYBOOK.md` (taxonomy, decorators, mock routes, play functions) and `docs/README-STORY-COVERAGE.md`.
|
|
4
|
+
|
|
5
|
+
## Layout
|
|
6
|
+
|
|
7
|
+
- Stories go in a `stories/` subfolder beside the component: `cart/cart-content.tsx` is matched by `cart/stories/cart-content.stories.tsx`; `cart/index.tsx` by `cart/stories/index.stories.tsx`. Coverage tooling only recognizes stories there.
|
|
8
|
+
- `src/components/ui/` (shadcn forks) is excluded from story coverage and generated story tests.
|
|
9
|
+
- Snapshot baselines use a fixture file `<name>-snapshot.tsx` next to the story and write to `stories/__snapshots__/`. Copy the small wrapper from `src/components/collapsible-section/stories/collapsible-section-snapshot.tsx`; `product-tile/stories/` shows a richer one.
|
|
10
|
+
|
|
11
|
+
## Minimal story
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
15
|
+
import { PromoBadge } from '../index';
|
|
16
|
+
|
|
17
|
+
const meta: Meta<typeof PromoBadge> = {
|
|
18
|
+
title: 'Products/Promo Badge',
|
|
19
|
+
component: PromoBadge,
|
|
20
|
+
tags: ['autodocs'],
|
|
21
|
+
args: { label: '20% off' },
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default meta;
|
|
25
|
+
type Story = StoryObj<typeof meta>;
|
|
26
|
+
|
|
27
|
+
export const Default: Story = {};
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Import types from `@storybook/react-vite` (not `@storybook/react`). Include the Apache header.
|
|
31
|
+
|
|
32
|
+
## Titles
|
|
33
|
+
|
|
34
|
+
`meta.title` is `Domain/Component` or `Domain/Subgroup/Component`, Title Case With Spaces. Use an existing top-level group: Account, Authentication, Cart, Category, Checkout, Content, Core, Design System, Extensions, Home, Layout, Products, Search. Pick by purpose, not folder. Titles are convention, not lint-enforced; you may restructure the sidebar for your brand.
|
|
35
|
+
|
|
36
|
+
## Writing good stories
|
|
37
|
+
|
|
38
|
+
- Props first; mock at the route boundary via story parameters (`routeLoaderData`, `scapiMock`, `mockRoutes`), not `vi.mock` of hooks.
|
|
39
|
+
- Reuse fixtures from `@/components/__mocks__` and config from `@/test-utils/config` instead of inventing data shapes.
|
|
40
|
+
- No promises or other non-serializable values in `args`.
|
|
41
|
+
- Hide `className` and ReactNode props from Controls (`control: false, table: { disable: true }`).
|
|
42
|
+
- Interactive components: add a `play` function and the `'interaction'` tag.
|
|
43
|
+
|
|
44
|
+
## Commands
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pnpm storybook # dev server on :6006
|
|
48
|
+
pnpm storybook:test --type=snapshot # jsdom snapshot gate
|
|
49
|
+
pnpm storybook:test --type=snapshot --update # refresh baselines after an intended DOM change
|
|
50
|
+
pnpm storybook:test --type=interaction # real Chromium, runs play()
|
|
51
|
+
pnpm storybook:test --type=a11y # axe-core
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Only run `--update` for changes you meant to make, and check the diff is additive before committing. After a theme change (colors, shape), snapshots of DOM markup normally do not change, but visual review in the `Design System/Theme/*` stories is worthwhile.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Token System
|
|
2
|
+
|
|
3
|
+
Your theme lives in `src/theme/`. `src/theme/index.css` is the entry point (it sets Tailwind `@source` scoping and imports `shared.css`). `shared.css` imports, in order: `tw-animate-css`, `tailwind.css`, `tokens/*.css`, `animations.css`, `base.css`, then `overrides/*.css`. `storybook.css` is a second entry used by Storybook with wider `@source` globs.
|
|
4
|
+
|
|
5
|
+
## How a token becomes a class
|
|
6
|
+
|
|
7
|
+
1. A CSS variable is defined in a token file: `--primary: #131315;` (in `:root`).
|
|
8
|
+
2. `src/theme/tailwind.css` bridges it inside an `@theme inline { ... }` block: `--color-primary: var(--primary);`.
|
|
9
|
+
3. Components use the generated utilities: `bg-primary`, `text-primary-foreground`, `border-primary`.
|
|
10
|
+
|
|
11
|
+
To add a token, do both steps 1 and 2. Then use the class. Never use arbitrary values such as `bg-[#131315]` or `bg-[--primary]`.
|
|
12
|
+
|
|
13
|
+
## Token files (`src/theme/tokens/`)
|
|
14
|
+
|
|
15
|
+
| File | Contents |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `core.css` | Surface and text palette (`--background`, `--foreground`, `--card`, `--popover`, `--primary`, `--secondary`, `--tertiary`, `--muted`, `--accent`), `--destructive`/`--success`/`--warning`/`--info` pairs, borders/input/ring/separator, rating, and the shape tokens `--ui-radius`, `--ui-shadow`, `--ui-border-width`. WCAG contrast ratios are annotated in comments. |
|
|
18
|
+
| `status.css` | Warning/active backgrounds, account action colors, `--status-*` (positive, warning, critical, info) |
|
|
19
|
+
| `header.css` | Header, header-menu, footer, and newsletter band colors; `--header-logo-filter` |
|
|
20
|
+
| `swatch.css` | Product swatch and color-pill sizing/colors |
|
|
21
|
+
| `brand.css` | `--brand-*` palette primitives and the hero scrims `--hero-overlay-dark`, `--hero-overlay-light`, `--hero-scrim` |
|
|
22
|
+
| `components.css` | Component-scoped tokens (payment brand colors, cart, product badge) |
|
|
23
|
+
| `custom.css` | Focus and input-background helpers |
|
|
24
|
+
| `sidebar.css`, `agentic.css` | Sidebar palette; agentic-shopping UI palette |
|
|
25
|
+
|
|
26
|
+
Other theme files: `tailwind.css` (font stacks `--font-sans/-serif/-mono`, color bridge, `border-ui` utility), `base.css` (`@font-face`, base layer, `.section-container`, section-scoped shape rules), `animations.css`, and `overrides/*.css` for component-level CSS (navigation, cart sheet, toasts, store locator).
|
|
27
|
+
|
|
28
|
+
## Class cheat sheet
|
|
29
|
+
|
|
30
|
+
| Need | Classes |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Page surface | `bg-background text-foreground` |
|
|
33
|
+
| Card / popover | `bg-card text-card-foreground`, `bg-popover text-popover-foreground` |
|
|
34
|
+
| Primary action | `bg-primary text-primary-foreground hover:bg-primary/90` |
|
|
35
|
+
| Secondary / muted | `bg-secondary text-secondary-foreground`, `bg-muted text-muted-foreground` |
|
|
36
|
+
| Borders | `border-border`, `border-border-subtle`, `border-input`; focus `ring-ring` |
|
|
37
|
+
| Destructive / success / warning / info | `bg-destructive text-destructive-foreground`, and the same pairs for `success`, `warning`, `info` |
|
|
38
|
+
| Status text | `text-status-positive`, `text-status-critical`, `bg-status-critical-bg`, `bg-warning-bg`, `bg-active-bg` |
|
|
39
|
+
| Header | `bg-header-background text-header-foreground border-header-border`, `bg-header-menu-background`, `bg-header-menu-hover-background` |
|
|
40
|
+
| Footer / newsletter | `bg-footer-background text-footer-foreground`, `bg-newsletter-background` |
|
|
41
|
+
| Brand primitives | `bg-brand-black`, `text-brand-white`, `bg-brand-gray-100` (prefer semantic tokens when one fits) |
|
|
42
|
+
|
|
43
|
+
Opacity modifiers work on bridged colors (`bg-primary/90`). Focus ring convention from the shipped Button: `focus-visible:ring-ring/50 focus-visible:ring-[3px]`.
|
|
44
|
+
|
|
45
|
+
`--border` is the darker tier and `--border-subtle` the lighter one; both are set to meet 3:1 contrast against white. If you change them, re-check contrast.
|
|
46
|
+
|
|
47
|
+
## Hard-coded colors
|
|
48
|
+
|
|
49
|
+
`custom/color-linter` (OxLint) rejects raw Tailwind palette utilities in `className` and `cn()` string literals. Fix by picking a semantic token or adding a token as above. Use `pnpm lint` to check.
|
|
50
|
+
|
|
51
|
+
## Dark mode
|
|
52
|
+
|
|
53
|
+
The shipped theme defines a single palette in `:root`; there is no `.dark` token block. Some shadcn primitives still carry `dark:` utilities inherited from upstream, which are inert unless you add a dark palette yourself.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
| Symptom | Cause | Fix |
|
|
4
|
+
|---|---|---|
|
|
5
|
+
| New color class renders nothing | Token defined but not bridged | Add `--color-x: var(--x)` in `@theme inline` in `src/theme/tailwind.css` |
|
|
6
|
+
| `pnpm lint` reports a hard-coded color utility | `custom/color-linter` | Use a semantic token class (`text-primary-foreground` instead of `text-white`) |
|
|
7
|
+
| Header class like `bg-[--header-background]` does nothing | Wrong syntax | Use `bg-header-background` |
|
|
8
|
+
| Setting `--radius-ui` / `--shadow-ui` has no effect | Bridge variables are compile-time only | Set `--ui-radius` / `--ui-shadow` |
|
|
9
|
+
| Card border will not appear | `border` / `border-2` used | `[--ui-border-width:1px]` on the Card |
|
|
10
|
+
| Links lose the site/locale prefix | `Link`/`useNavigate` imported from `react-router` | Import from `@/components/link` and `@/hooks/use-navigate` |
|
|
11
|
+
| Page flickers or re-suspends forever | Several promises in one `<Suspense>`, or promises composed during render | One boundary per promise; compose in the loader |
|
|
12
|
+
| Tailwind class works in dev but not in build or Storybook | File outside the `@source` globs in `src/theme/index.css` / `storybook.css` | Move the file under `src/` or extend the globs; run `pnpm lint:css` |
|
|
13
|
+
| Story not counted or not found | Not in a `stories/` subfolder | Move it to `<component>/stories/` |
|
|
14
|
+
| `pnpm test-storybook:...` not found | Script does not exist | `pnpm storybook:test --type=snapshot` |
|
|
15
|
+
| Snapshot failure after an intended change | Baseline is stale | `pnpm storybook:test --type=snapshot --update`, review the diff |
|
|
16
|
+
| shadcn fork has raw `rounded-md` / `shadow-sm` | Added with `npx shadcn add` | `node .claude/skills/sync-shadcn/sync.mjs restyle <file>` |
|
|
17
|
+
| `sync`/`status` reports no baseline | `.shadcn-baseline/` not seeded | `node .claude/skills/sync-shadcn/sync.mjs sync <name> --bootstrap` |
|
|
18
|
+
| Overlay code appears in the main bundle | Imported synchronously | `React.lazy` + `useDeferredUnmount`; check with `pnpm bundlesize` |
|
|
19
|
+
| Typecheck passes locally, fails after route changes | Stale generated types | `pnpm typecheck` runs `react-router typegen` first; run it, not bare `tsc` |
|