@zohofinance/commerce 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -0
- package/package.json +2 -2
- package/ts-dist/mocks/init-theme/.claude/CLAUDE.md +6 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/SKILL.md +242 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/inputs/figma.md +81 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/inputs/screenshot.md +54 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/inputs/url.md +88 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/spec-table.md +102 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/accessibility.md +110 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/performance.md +127 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/tokens.md +87 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-section-from-design.20260528/verification/visual-diff.md +123 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/SKILL.md +605 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/design-tokens.md +105 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/page-json-contract.md +58 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/qa-accessibility.md +35 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/reference-lookup.md +94 -0
- package/ts-dist/mocks/init-theme/.claude/skills/.archive/zcommerce-theme-builder.20260528/section-anatomy.md +109 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/SKILL.md +313 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/agent-hierarchy.md +142 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/ask-developer.md +113 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/bootstrap.md +260 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/build-metrics.md +89 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/code-quality.md +186 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/common-pages-agent.md +97 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/dev-server-and-urls.md +127 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/exemplars.md +79 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/figma-discovery.md +138 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/figma-extraction.md +132 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/image-sources.md +84 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/inputs/guidelines-frame.md +178 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/page-builder.md +322 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/page-orchestrator.md +199 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/parallel-fanout.md +152 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/a11y.mjs +129 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/lint-section.mjs +502 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/perf.mjs +134 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/pixel-diff.mjs +206 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/scripts/record-build-metrics.mjs +118 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/section-builder.md +131 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/subagent-escalation.md +75 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/transcription-rules.md +98 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/verification.md +227 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/visual-verify-loop.md +117 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/_index.md +4 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/assets.md +105 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/best-practices.md +212 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/custom-scripts.md +294 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/i18n.md +155 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/introduction.md +91 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/layouts.md +158 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/pages.md +156 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/_index.md +4 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/filters.md +419 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/global-objects.md +415 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/schema-types.md +926 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/reference/tags.md +259 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/sections.md +203 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/setup-guide.md +424 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/snippets.md +70 -0
- package/ts-dist/mocks/init-theme/.claude/skills/theme-from-figma/zcommerce-docs/theme-structure.md +252 -0
- package/ts-dist/mocks/init-theme/.cursor/PLAYBOOK.md +144 -0
- package/ts-dist/mocks/init-theme/.cursor/README.md +6 -0
- package/ts-dist/mocks/init-theme/.cursor/agents/figma-desktop-mobile-parallel.md +48 -0
- package/ts-dist/mocks/init-theme/.cursor/agents/visual-compare.md +221 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/add-field.md +83 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/add-theme-setting.md +200 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/assemble-page.md +72 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/audit-page.md +57 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/build-page-sections.md +110 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/build-section.md +418 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/build-theme.md +307 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/compare-section.md +358 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/create-theme.md +77 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/extract-tokens.md +43 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/fix-section.md +92 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/impact.md +50 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/qa-a11y.md +66 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/qa-i18n.md +110 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/qa-layout.md +127 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/qa-performance.md +72 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/qa-section.md +84 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/qa-sections.md +48 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/qa-theme.md +85 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/redesign-section.md +177 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/refactor-section.md +185 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/sync-theme-settings.md +132 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/validate-page.md +60 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/validate-section-group.md +88 -0
- package/ts-dist/mocks/init-theme/.cursor/commands/validate-theme-settings.md +119 -0
- package/ts-dist/mocks/init-theme/.cursor/examples/design-instructions-template.md +151 -0
- package/ts-dist/mocks/init-theme/.cursor/mcp.json +18 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/README.md +160 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/accessibility.mdc +24 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/add-field.mdc +222 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/add-theme-setting.mdc +39 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/assemble-page.mdc +130 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/audit-page.mdc +92 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/build-section.mdc +178 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/build-theme.mdc +47 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/compare-section.mdc +94 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/create-theme.mdc +78 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/css.mdc +137 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/design-spec-extraction.mdc +255 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/extract-tokens.mdc +43 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/figma-mcp-resolution.mdc +40 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/fix-section.mdc +154 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/general.mdc +30 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/i18n.mdc +85 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/javascript.mdc +85 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/liquid-no-hardcoded-strings.mdc +42 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/liquid.mdc +171 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/mobile-desktop-setting-meta.mdc +34 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/naming-convention.mdc +64 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/pages.mdc +120 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/performance.mdc +51 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/qa-section.mdc +134 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/redesign-section.mdc +147 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/schema-sync.mdc +110 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/schema.mdc +360 -0
- package/ts-dist/mocks/init-theme/.cursor/rules/share-urls.mdc +68 -0
- package/ts-dist/mocks/init-theme/.cursor/skills/browser-verify.md +128 -0
- package/ts-dist/mocks/init-theme/.cursor/skills/design-tokens.md +105 -0
- package/ts-dist/mocks/init-theme/.cursor/skills/page-json-contract.md +87 -0
- package/ts-dist/mocks/init-theme/.cursor/skills/qa-accessibility.md +35 -0
- package/ts-dist/mocks/init-theme/.cursor/skills/reference-lookup.md +88 -0
- package/ts-dist/mocks/init-theme/.cursor/skills/section-anatomy.md +173 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: JavaScript rules — applies to all themes
|
|
3
|
+
globs: ["assets/*.js"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# JavaScript Rules — b2bizmart Theme
|
|
7
|
+
|
|
8
|
+
## Core Principles
|
|
9
|
+
- Vanilla JS only — NO jQuery, NO external UI frameworks
|
|
10
|
+
- Use class-based Web Components (extend HTMLElement) for interactive section components
|
|
11
|
+
- All async operations use `fetch()` with proper error handling
|
|
12
|
+
- Dispatch custom events for cross-component communication
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Web Component Pattern
|
|
17
|
+
```javascript
|
|
18
|
+
class MyComponent extends HTMLElement {
|
|
19
|
+
connectedCallback() {
|
|
20
|
+
this.init();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
init() {
|
|
24
|
+
// setup logic
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
customElements.define('my-component', MyComponent);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Custom Event Pattern
|
|
34
|
+
```javascript
|
|
35
|
+
// Dispatch
|
|
36
|
+
this.dispatchEvent(new CustomEvent('my-component:updated', {
|
|
37
|
+
bubbles: true,
|
|
38
|
+
detail: { data: value }
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
// Listen
|
|
42
|
+
document.addEventListener('my-component:updated', (e) => {
|
|
43
|
+
const { data } = e.detail;
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Fetch Pattern
|
|
50
|
+
```javascript
|
|
51
|
+
async function fetchData(url) {
|
|
52
|
+
try {
|
|
53
|
+
const response = await fetch(url, {
|
|
54
|
+
method: 'GET',
|
|
55
|
+
headers: { 'Content-Type': 'application/json' }
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
|
|
58
|
+
return await response.json();
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error('Fetch error:', error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## DOM Query Patterns
|
|
68
|
+
```javascript
|
|
69
|
+
// Prefer attribute selectors for component hooks
|
|
70
|
+
const el = this.querySelector('[data-cart-count]');
|
|
71
|
+
const items = this.querySelectorAll('[data-product-card]');
|
|
72
|
+
|
|
73
|
+
// Use data attributes for JS hooks, not CSS classes
|
|
74
|
+
// ✅ data-sidebar-overlay
|
|
75
|
+
// ❌ .js-sidebar-overlay
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Script Loading in Liquid
|
|
81
|
+
```liquid
|
|
82
|
+
<script src="{{ 'component.js' | asset_url }}" defer></script>
|
|
83
|
+
```
|
|
84
|
+
- Always `defer` — never `async` unless specifically needed
|
|
85
|
+
- Load at top of the section `.liquid` file that uses the component
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: No hardcoded user-facing strings in Liquid files — always use i18n translation keys
|
|
3
|
+
globs: **/*.liquid
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# No Hardcoded Strings in Liquid Templates
|
|
8
|
+
|
|
9
|
+
Every user-facing string in a `.liquid` file **must** come from the i18n locale files (`i18n/en.default.json` or `i18n/en.default.schema.json`). Never write raw text directly in the markup.
|
|
10
|
+
|
|
11
|
+
## Rules
|
|
12
|
+
|
|
13
|
+
1. Use `{{ 'key.path' | t }}` for runtime translations (`en.default.json`).
|
|
14
|
+
2. Use `"t:key.path"` inside `{% schema %}` blocks for editor labels/defaults (`en.default.schema.json`).
|
|
15
|
+
3. If the required key does not exist yet, **add it** to the appropriate locale JSON file and then reference it.
|
|
16
|
+
4. HTML attributes that render visible text (`alt`, `title`, `placeholder`, `aria-label`, button text, headings, paragraphs, etc.) must all use translation filters/keys.
|
|
17
|
+
|
|
18
|
+
## Examples
|
|
19
|
+
|
|
20
|
+
```liquid
|
|
21
|
+
❌ BAD — hardcoded string
|
|
22
|
+
<h2>Shop by Category</h2>
|
|
23
|
+
<input placeholder="Search products">
|
|
24
|
+
<button>Add to Cart</button>
|
|
25
|
+
|
|
26
|
+
✅ GOOD — translated
|
|
27
|
+
<h2>{{ 'category.heading' | t }}</h2>
|
|
28
|
+
<input placeholder="{{ 'header.blocks.header_search.search_placeholder' | t }}">
|
|
29
|
+
<button>{{ 'product.add_to_cart' | t }}</button>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```liquid
|
|
33
|
+
❌ BAD — hardcoded schema label
|
|
34
|
+
{% schema %}
|
|
35
|
+
{ "settings": [{ "label": "Background color" }] }
|
|
36
|
+
{% endschema %}
|
|
37
|
+
|
|
38
|
+
✅ GOOD — translated schema label
|
|
39
|
+
{% schema %}
|
|
40
|
+
{ "settings": [{ "label": "t:sections.banner.settings.bg_color.label" }] }
|
|
41
|
+
{% endschema %}
|
|
42
|
+
```
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Liquid templating rules — applies to all themes
|
|
3
|
+
globs: ["**/*.liquid"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Liquid Rules — b2bizmart Theme
|
|
7
|
+
|
|
8
|
+
## Core Principles
|
|
9
|
+
- This is a CUSTOM Liquid system, not standard Shopify
|
|
10
|
+
- NEVER assume standard Shopify objects like `shop`, `product`, `collection`, `cart` behave identically
|
|
11
|
+
- Always use `{% render 'snippet-name' %}` — NEVER `{% include %}`
|
|
12
|
+
- Always escape user-generated output: `{{ value | escape }}`
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Global Objects Available
|
|
17
|
+
```liquid
|
|
18
|
+
{{ organization.organizationName }} → store name
|
|
19
|
+
{{ organization.logo.url }} → logo image URL
|
|
20
|
+
{{ organization.email }}
|
|
21
|
+
{{ organization.phone }}
|
|
22
|
+
{{ organization.social_media_list }} → array of social links
|
|
23
|
+
{{ organization.customer_accounts_enabled }} → boolean
|
|
24
|
+
{{ pageinfo.origin }} → base URL for internal links (e.g. /home, /cart)
|
|
25
|
+
{{ default_menu.menuItems }} → array of nav items
|
|
26
|
+
{{ cart.item_count }} → cart item count
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Asset References
|
|
32
|
+
```liquid
|
|
33
|
+
{{ 'filename.js' | asset_url }} → JS file URL
|
|
34
|
+
{{ 'filename.css' | asset_url }} → CSS file URL
|
|
35
|
+
{{ 'filename.svg' | asset_url }} → SVG/image file URL
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Internal Links
|
|
41
|
+
Always prefix internal URLs with `{{ pageinfo.origin }}`:
|
|
42
|
+
```liquid
|
|
43
|
+
<a href="{{ pageinfo.origin }}/home">Home</a>
|
|
44
|
+
<a href="{{ pageinfo.origin }}/cart">Cart</a>
|
|
45
|
+
<a href="{{ pageinfo.origin }}/wishlists">Wishlist</a>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Accessing Settings in Liquid
|
|
51
|
+
```liquid
|
|
52
|
+
{{ section.settings.field_id }} → text, range, color, checkbox
|
|
53
|
+
{{ section.settings.url_field.handle }} → url type: the path
|
|
54
|
+
{{ section.settings.url_field.display_name }} → url type: the label
|
|
55
|
+
{{ section.settings.select_field.value }} → select type: the value
|
|
56
|
+
{{ section.settings.select_field.display_name }} → select type: the label
|
|
57
|
+
{{ section.settings.image_field.url }} → image_picker type: the filename/url
|
|
58
|
+
{{ section.settings.video_media.url }} → media_picker type: video filename/url
|
|
59
|
+
{{ section.settings.video_media.is_video }} → media_picker type: boolean flag
|
|
60
|
+
{{ section.settings.menu_field.handle }} → menu type: the handle
|
|
61
|
+
{{ section.settings.menu_field.display_name }} → menu type: the label
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Rendering Snippets
|
|
67
|
+
```liquid
|
|
68
|
+
{% render 'snippet-name' %}
|
|
69
|
+
{% render 'snippet-name', variable: value %}
|
|
70
|
+
{% render 'snippet-name', section: section %}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Loop Patterns
|
|
76
|
+
Always handle empty states in loops:
|
|
77
|
+
```liquid
|
|
78
|
+
{% if items.size > 0 %}
|
|
79
|
+
{% for item in items %}
|
|
80
|
+
...
|
|
81
|
+
{% endfor %}
|
|
82
|
+
{% else %}
|
|
83
|
+
<p>No items found.</p>
|
|
84
|
+
{% endif %}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Navigation Menu Loop
|
|
90
|
+
```liquid
|
|
91
|
+
{% for menuItem in default_menu.menuItems %}
|
|
92
|
+
<a href="{{ menuItem.url }}">{{ menuItem.name }}</a>
|
|
93
|
+
{% endfor %}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## CSS Patterns
|
|
99
|
+
Use Tailwind utility classes + CSS custom properties together:
|
|
100
|
+
```liquid
|
|
101
|
+
<div class="flex items-center gap-4" style="color: var(--color-heading); background-color: var(--color-background);">
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Available CSS Custom Properties
|
|
105
|
+
```
|
|
106
|
+
--color-primary
|
|
107
|
+
--color-on-primary
|
|
108
|
+
--color-heading
|
|
109
|
+
--color-background
|
|
110
|
+
--color-border
|
|
111
|
+
--color-header-bg
|
|
112
|
+
--section-padding-x
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Image Rendering
|
|
118
|
+
```liquid
|
|
119
|
+
<img
|
|
120
|
+
src="{{ section.settings.image_field.url }}"
|
|
121
|
+
alt="{{ section.settings.alt_text | escape }}"
|
|
122
|
+
width="800"
|
|
123
|
+
height="600"
|
|
124
|
+
loading="lazy"
|
|
125
|
+
>
|
|
126
|
+
```
|
|
127
|
+
- Always include `width`, `height`, `alt`, and `loading` attributes
|
|
128
|
+
- Use `loading="eager"` only for above-the-fold images (hero, header logo)
|
|
129
|
+
- ❌ NEVER use `{{ image | img_url }}` — that is standard Shopify syntax
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Script Loading
|
|
134
|
+
```liquid
|
|
135
|
+
<script src="{{ 'component.js' | asset_url }}" defer></script>
|
|
136
|
+
```
|
|
137
|
+
- Always use `defer` for non-critical scripts
|
|
138
|
+
- Load scripts at the top of the section file that needs them
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Section Tag
|
|
143
|
+
```liquid
|
|
144
|
+
<section class="section-name" id="section-{{ section.id }}">
|
|
145
|
+
...
|
|
146
|
+
</section>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Liquid Assign Block Pattern
|
|
152
|
+
Use `{% liquid %}` for multiple assignments:
|
|
153
|
+
```liquid
|
|
154
|
+
{% liquid
|
|
155
|
+
assign field_one = section.settings.field_one
|
|
156
|
+
assign field_two = section.settings.field_two.value
|
|
157
|
+
assign show_item = section.settings.show_item
|
|
158
|
+
%}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Style Block for Dynamic CSS
|
|
164
|
+
```liquid
|
|
165
|
+
{% style %}
|
|
166
|
+
#section-{{ section.id }} {
|
|
167
|
+
padding-top: {{ section.settings.padding_top }}px;
|
|
168
|
+
padding-bottom: {{ section.settings.padding_bottom }}px;
|
|
169
|
+
}
|
|
170
|
+
{% endstyle %}
|
|
171
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Schema settings tied to mobile or desktop breakpoints — meta and neutral labels
|
|
3
|
+
globs: **/*.liquid,**/i18n/**/*.json
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Mobile / desktop settings in section & block schema
|
|
8
|
+
|
|
9
|
+
## When to set `meta`
|
|
10
|
+
|
|
11
|
+
- If a setting **only applies to one breakpoint** (small screen vs `md`+ / large screen), or is the **mobile-specific** or **desktop-specific** member of a pair, it **must** include `"meta"`.
|
|
12
|
+
- Use **only**:
|
|
13
|
+
- **`"meta": "mobile"`** — small-screen / default (pre-`md`) behavior.
|
|
14
|
+
- **`"meta": "desktop"`** — large-screen / `md`+ behavior.
|
|
15
|
+
- Settings that are **truly global** (same value at all breakpoints) **do not** need `mobile` / `desktop` meta.
|
|
16
|
+
|
|
17
|
+
This applies to **any** setting type: `image_picker`, `select`, `text`, `richtext`, `color`, `range`, `checkbox`, etc.—not only font-size controls.
|
|
18
|
+
|
|
19
|
+
## Neutral naming (labels)
|
|
20
|
+
|
|
21
|
+
- **Do not** put the words *mobile* or *desktop* in the merchant-facing **label** or locale schema `label` when `meta` already encodes the breakpoint.
|
|
22
|
+
- Use a **generic, semantic** label that describes **what** the setting controls (e.g. “Image”, “Font size”, “Padding”, “Background color”), repeated for both members of a pair if appropriate—the editor groups them by `meta`.
|
|
23
|
+
- Prefer setting **ids** that encode breakpoint when paired: `*_mobile` / `*_desktop` (or `mobile_*` / `desktop_*` if that matches existing conventions), so Liquid and JSON stay clear without relying on label text.
|
|
24
|
+
|
|
25
|
+
## Implementation notes
|
|
26
|
+
|
|
27
|
+
- **Pairs:** Two settings, same conceptual label text, different `id` and `meta` (e.g. two “Image” pickers with `meta: "mobile"` and `meta: "desktop"`—same pattern as separate banner images).
|
|
28
|
+
- **Font size:** Use two `select`s (mobile + desktop), base Tailwind classes for mobile and `md:` / `lg:` for desktop; optionally fall back in Liquid to a legacy single key for older saved data.
|
|
29
|
+
- **Locale files:** Mirror labels under the same `t:` paths the schema references; keep breakpoint out of visible copy.
|
|
30
|
+
|
|
31
|
+
## Do not
|
|
32
|
+
|
|
33
|
+
- Use invented meta values (e.g. `"all"`, `"typography"`) for breakpoint-specific controls unless the product’s schema spec explicitly defines them.
|
|
34
|
+
- Duplicate breakpoint words in labels when `meta` is present.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Naming convention for Liquid variables, CSS classes, and HTML IDs across all template files.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Naming Convention
|
|
7
|
+
|
|
8
|
+
## 1. Liquid Variables — `snake_case`
|
|
9
|
+
|
|
10
|
+
All Liquid variables (assigned with `assign`, `capture`, loop variables, etc.) must use `snake_case`.
|
|
11
|
+
|
|
12
|
+
```liquid
|
|
13
|
+
❌ BAD
|
|
14
|
+
{% assign colorClass = 'text-red' %}
|
|
15
|
+
{% assign color-class = 'text-red' %}
|
|
16
|
+
|
|
17
|
+
✅ GOOD
|
|
18
|
+
{% assign color_class = 'text-red' %}
|
|
19
|
+
{% assign heading_font_size = 'text-2xl' %}
|
|
20
|
+
{% assign outer_section_classes = 'pt-5 pb-6' %}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2. CSS Classes — `kebab-case`
|
|
26
|
+
|
|
27
|
+
All class names (Tailwind utility overrides, custom classes, data attributes used as class hooks) must use `kebab-case`.
|
|
28
|
+
|
|
29
|
+
```liquid
|
|
30
|
+
❌ BAD
|
|
31
|
+
<div class="colorClass sectionWrapper">
|
|
32
|
+
<div class="color_class section_wrapper">
|
|
33
|
+
|
|
34
|
+
✅ GOOD
|
|
35
|
+
<div class="color-class section-wrapper">
|
|
36
|
+
<div class="page-max-width no-scrollbar scroll-smooth">
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 3. HTML IDs — `camelCase`
|
|
42
|
+
|
|
43
|
+
All `id` attributes on HTML elements must use `camelCase`.
|
|
44
|
+
|
|
45
|
+
```liquid
|
|
46
|
+
❌ BAD
|
|
47
|
+
<div id="color_class">
|
|
48
|
+
<div id="color-class">
|
|
49
|
+
|
|
50
|
+
✅ GOOD
|
|
51
|
+
<div id="colorClass">
|
|
52
|
+
<input id="searchInput">
|
|
53
|
+
<section id="blogPageHero">
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Quick Reference
|
|
59
|
+
|
|
60
|
+
| Context | Convention | Example |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| Liquid `assign` / `capture` / loop var | `snake_case` | `title_font_scale_mobile` |
|
|
63
|
+
| HTML `class` attribute | `kebab-case` | `blog-card-wrapper` |
|
|
64
|
+
| HTML `id` attribute | `camelCase` | `blogCardWrapper` |
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Page JSON template rules — applies to all themes
|
|
3
|
+
globs: ["pages/*.json"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Page JSON Rules — b2bizmart Theme
|
|
7
|
+
|
|
8
|
+
## Structure
|
|
9
|
+
Every page JSON file follows this structure:
|
|
10
|
+
```jsonc
|
|
11
|
+
{
|
|
12
|
+
"layout": "theme",
|
|
13
|
+
"sections": {
|
|
14
|
+
"section-key": {
|
|
15
|
+
"type": "section-file-name", // matches filename in sections/ (no .liquid)
|
|
16
|
+
"settings": {
|
|
17
|
+
// direct settings for the section
|
|
18
|
+
},
|
|
19
|
+
"blocks": {
|
|
20
|
+
"block-key": {
|
|
21
|
+
"type": "block-type-name", // local: bare name; theme: zc_theme__<name>
|
|
22
|
+
"settings": {
|
|
23
|
+
// block-level settings
|
|
24
|
+
},
|
|
25
|
+
"blocks": {}, // optional — nested theme block children
|
|
26
|
+
"block_order": [] // optional — nested child order
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"block_order": ["block-key"] // controls render order
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"order": ["section-key"] // controls section render order
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Settings Values in Page JSON
|
|
39
|
+
When writing settings values in page JSON, always use the correct type format:
|
|
40
|
+
|
|
41
|
+
### Select
|
|
42
|
+
```jsonc
|
|
43
|
+
"layout_type": { "display_name": "Left Alignment", "value": "left-alignment" }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### URL
|
|
47
|
+
```jsonc
|
|
48
|
+
"my_url": { "display_name": "Home", "handle": "/home" }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Image
|
|
52
|
+
```jsonc
|
|
53
|
+
"background_image": { "url": "filename.webp", "enable_customisation": true }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Menu
|
|
57
|
+
```jsonc
|
|
58
|
+
"footer_menu": { "display_name": "Footer Menu", "handle": "footer-menu" }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Checkbox
|
|
62
|
+
```jsonc
|
|
63
|
+
"show_banner": false
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Range / Number
|
|
67
|
+
```jsonc
|
|
68
|
+
"overlay_opacity": 50
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Color
|
|
72
|
+
```jsonc
|
|
73
|
+
"overlay_color": "#000000"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Text
|
|
77
|
+
```jsonc
|
|
78
|
+
"heading": "My Heading Text"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Special Page Settings
|
|
84
|
+
Some pages have reserved settings:
|
|
85
|
+
```jsonc
|
|
86
|
+
// category pages
|
|
87
|
+
"page_type": "category",
|
|
88
|
+
"isCategoryPage": true
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Available Page Files
|
|
94
|
+
```
|
|
95
|
+
pages/404.json
|
|
96
|
+
pages/blog.json
|
|
97
|
+
pages/cart.json
|
|
98
|
+
pages/categories.json
|
|
99
|
+
pages/checkout.json
|
|
100
|
+
pages/collection.json
|
|
101
|
+
pages/index.json
|
|
102
|
+
pages/orders.json
|
|
103
|
+
pages/page.json
|
|
104
|
+
pages/payment.json
|
|
105
|
+
pages/product.json
|
|
106
|
+
pages/sitemap.json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Rules
|
|
112
|
+
- `"layout"` is always `"theme"` unless using `"accounts"` or `"sitemap"` layouts
|
|
113
|
+
- `"order"` array controls top-to-bottom section render order — always keep in sync with `"sections"` keys
|
|
114
|
+
- `"block_order"` array controls block render order — always keep in sync with `"blocks"` keys
|
|
115
|
+
- Section `"type"` must exactly match the filename in `sections/` (without `.liquid`)
|
|
116
|
+
- Block `"type"` must be allowed by the section's schema:
|
|
117
|
+
- **Local block:** bare name defined inline in the section schema `blocks` array
|
|
118
|
+
- **Theme block:** `zc_theme__<name>` where `blocks/<name>.liquid` exists and the section schema lists `@theme` or that specific type
|
|
119
|
+
- Nested theme blocks may have their own `"blocks"` and `"block_order"` inside a parent block instance
|
|
120
|
+
- ❌ NEVER use standard Shopify `"template"` wrapper objects
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Performance standards for theme sections and templates
|
|
3
|
+
globs: **
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Performance Guidelines
|
|
8
|
+
|
|
9
|
+
Apply these rules when building or editing any Liquid section/snippet/template.
|
|
10
|
+
|
|
11
|
+
## Images & Media (LCP / CLS)
|
|
12
|
+
- Prefer `width` and `height` on every `<img>` to prevent layout shift (CLS)
|
|
13
|
+
- Use `loading="eager"` only for above-the-fold/LCP candidates; otherwise `loading="lazy"`
|
|
14
|
+
- Avoid huge source images relative to display size; flag oversized dimensions and prefer appropriately sized assets where possible
|
|
15
|
+
- Always use the platform image object URL (`{{ field.url }}` / `{{ section.settings.image.url }}`) rather than legacy filters like `| img_url`
|
|
16
|
+
- Avoid background images for critical content images; prefer `<img>` so the browser can optimize loading
|
|
17
|
+
- If motion is prominent (auto-playing/looping), provide a way to pause/stop and keep motion subtle
|
|
18
|
+
|
|
19
|
+
## CSS (render cost / maintainability)
|
|
20
|
+
- Prefer Tailwind utility classes for static styling; keep `{% style %}` for:
|
|
21
|
+
- dynamic values from settings (e.g. `{{ section.settings.padding_top }}px`)
|
|
22
|
+
- CSS custom properties / theme variables
|
|
23
|
+
- stateful/complex selectors scoped to `#section-{{ section.id }}`
|
|
24
|
+
- Scope any `{% style %}` rules to `#section-{{ section.id }}` to avoid global style recalculation and collisions
|
|
25
|
+
- Avoid expensive selectors (deep descendant chains, overly broad `*`, heavy attribute selectors) unless necessary
|
|
26
|
+
- Don’t animate layout properties (`width`, `height`, `top/left`, `margin`); prefer `transform` and `opacity`
|
|
27
|
+
|
|
28
|
+
## JavaScript (main-thread / TTI)
|
|
29
|
+
- Only load JS when the section actually needs it (don’t include scripts “just in case”)
|
|
30
|
+
- Use `defer` on section scripts; do not block rendering with synchronous scripts
|
|
31
|
+
- Bind events via delegation when possible; avoid adding many per-item listeners in loops
|
|
32
|
+
- Avoid layout thrashing (repeated `getBoundingClientRect` + style writes); batch reads then writes
|
|
33
|
+
- Respect reduced motion: avoid forcing animations when `prefers-reduced-motion` is set
|
|
34
|
+
|
|
35
|
+
## Liquid / HTML (server + DOM cost)
|
|
36
|
+
- Guard loops with empty states (`{% else %}`) or `size > 0` checks to avoid rendering large empty scaffolds
|
|
37
|
+
- Avoid repeated heavy computations/filters inside loops; pre-assign in a top `{% liquid %}` block when possible
|
|
38
|
+
- Keep DOM shallow: avoid unnecessary wrappers and deeply nested markup
|
|
39
|
+
- Avoid duplicating identical SVG markup many times; prefer a snippet render if reused
|
|
40
|
+
|
|
41
|
+
## Fonts & Text
|
|
42
|
+
- Avoid defining custom fonts per-section; rely on theme-level font loading
|
|
43
|
+
- Prefer system-safe fallbacks and avoid large icon-font files for small icon sets
|
|
44
|
+
|
|
45
|
+
## What to report in QA
|
|
46
|
+
- Mark **PERFORMANCE ⚠️ REVIEW** when you see:
|
|
47
|
+
- above-the-fold images not eager / missing dimensions
|
|
48
|
+
- oversized images for their rendered size
|
|
49
|
+
- large `{% style %}` blocks full of static rules that should be Tailwind
|
|
50
|
+
- non-deferred scripts or unnecessary JS on initial load
|
|
51
|
+
- excessive DOM nesting or repeated heavy Liquid work in loops
|