@augeo/smelt 1.2.2
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/.claude/settings.json +11 -0
- package/.github/workflows/verify.yml +64 -0
- package/.gitmodules +3 -0
- package/.prettierignore +25 -0
- package/.prettierrc.cjs +9 -0
- package/.zed/settings.json +21 -0
- package/AGENTS.md +232 -0
- package/LICENSE +21 -0
- package/README.md +266 -0
- package/biome.json +58 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +350 -0
- package/dist/schema.d.mts +265 -0
- package/dist/schema.mjs +21 -0
- package/docs/TESTING.md +293 -0
- package/docs/assets-plan.md +197 -0
- package/docs/build-spec.md +466 -0
- package/docs/library-conversion-plan.md +419 -0
- package/example/.gitattributes +7 -0
- package/example/.shopifyignore +28 -0
- package/example/.theme-check.yml +7 -0
- package/example/blocks/_built--sections--hero--blocks--feature.liquid +52 -0
- package/example/config/settings_schema.json +10 -0
- package/example/layout/theme.liquid +25 -0
- package/example/locales/en.default.json +1 -0
- package/example/package-lock.json +51 -0
- package/example/package.json +20 -0
- package/example/sections/built--sections--hero.liquid +83 -0
- package/example/snippets/built--components--button.liquid +38 -0
- package/example/snippets/built--components--card.liquid +33 -0
- package/example/src/components/button/button.css +13 -0
- package/example/src/components/card/card.css +16 -0
- package/example/src/components/card/card.liquid +9 -0
- package/example/src/sections/hero/blocks/feature/feature.css +11 -0
- package/example/src/sections/hero/blocks/feature/feature.liquid +9 -0
- package/example/src/sections/hero/blocks/feature/feature.schema.ts +14 -0
- package/example/src/sections/hero/hero.css +15 -0
- package/example/src/sections/hero/hero.liquid +16 -0
- package/example/src/sections/hero/hero.schema.ts +26 -0
- package/example/src/sections/hero/hero.test.ts +43 -0
- package/example/src/utilities/labels.ts +5 -0
- package/example/templates/index.liquid +1 -0
- package/example/tsconfig.json +10 -0
- package/example/vitest.config.ts +6 -0
- package/lib/build/build.test.ts +475 -0
- package/lib/build/build.ts +314 -0
- package/lib/build/command.ts +27 -0
- package/lib/build/index.ts +1 -0
- package/lib/cli.ts +17 -0
- package/lib/dev/command.ts +25 -0
- package/lib/dev/index.ts +1 -0
- package/lib/dev/watch.ts +52 -0
- package/lib/resolver.test.ts +275 -0
- package/lib/resolver.ts +156 -0
- package/lib/schema.ts +37 -0
- package/package.json +59 -0
- package/scripts/codegen-schema.ts +66 -0
- package/src/components/button/button.css +13 -0
- package/src/components/button/button.liquid +5 -0
- package/src/components/button/button.ts +5 -0
- package/src/tsconfig.json +10 -0
- package/tests/example.test.ts +101 -0
- package/tsconfig.json +20 -0
- package/tsdown.config.ts +14 -0
- package/vendor/theme-liquid-docs/.gitattributes +10 -0
- package/vendor/theme-liquid-docs/.github/CODEOWNERS +1 -0
- package/vendor/theme-liquid-docs/.github/CODE_OF_CONDUCT.md +73 -0
- package/vendor/theme-liquid-docs/.github/ISSUE_TEMPLATE/bug_report.md +17 -0
- package/vendor/theme-liquid-docs/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- package/vendor/theme-liquid-docs/.github/dependabot.yaml +6 -0
- package/vendor/theme-liquid-docs/.github/workflows/ci.yml +33 -0
- package/vendor/theme-liquid-docs/.github/workflows/cla.yml +27 -0
- package/vendor/theme-liquid-docs/.github/workflows/shopify-dev-preview-automation.yml +86 -0
- package/vendor/theme-liquid-docs/.github/workflows/update-latest.yml +56 -0
- package/vendor/theme-liquid-docs/.prettierrc.json +16 -0
- package/vendor/theme-liquid-docs/.vscode/settings.json +28 -0
- package/vendor/theme-liquid-docs/LICENSE.md +7 -0
- package/vendor/theme-liquid-docs/README.md +48 -0
- package/vendor/theme-liquid-docs/ai/claude/CLAUDE.md +1485 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/assets.mdc +15 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/blocks.mdc +339 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/examples/block-example-group.mdc +103 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/examples/block-example-text.mdc +59 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/examples/section-example.mdc +61 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/examples/snippet-example.mdc +72 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/liquid.mdc +837 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/locales.mdc +100 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/localization.mdc +67 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/mcp.mdc +2 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/schemas.mdc +184 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/sections.mdc +84 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/settings-schema.mdc +51 -0
- package/vendor/theme-liquid-docs/ai/cursor/rules/snippets.mdc +119 -0
- package/vendor/theme-liquid-docs/ai/github/copilot-instructions.md +1485 -0
- package/vendor/theme-liquid-docs/ai/liquid.mdc +638 -0
- package/vendor/theme-liquid-docs/data/filters.json +6148 -0
- package/vendor/theme-liquid-docs/data/latest.json +2 -0
- package/vendor/theme-liquid-docs/data/objects.json +20594 -0
- package/vendor/theme-liquid-docs/data/shopify_system_translations.json +2586 -0
- package/vendor/theme-liquid-docs/data/tags.json +1276 -0
- package/vendor/theme-liquid-docs/package.json +20 -0
- package/vendor/theme-liquid-docs/schemas/manifest_schema.json +31 -0
- package/vendor/theme-liquid-docs/schemas/manifest_theme.json +19 -0
- package/vendor/theme-liquid-docs/schemas/manifest_theme_app_extension.json +10 -0
- package/vendor/theme-liquid-docs/schemas/theme/app_block_entry.json +13 -0
- package/vendor/theme-liquid-docs/schemas/theme/default_setting_values.json +24 -0
- package/vendor/theme-liquid-docs/schemas/theme/local_block_entry.json +25 -0
- package/vendor/theme-liquid-docs/schemas/theme/preset.json +72 -0
- package/vendor/theme-liquid-docs/schemas/theme/preset_blocks.json +91 -0
- package/vendor/theme-liquid-docs/schemas/theme/section.json +208 -0
- package/vendor/theme-liquid-docs/schemas/theme/setting.json +1413 -0
- package/vendor/theme-liquid-docs/schemas/theme/settings.json +10 -0
- package/vendor/theme-liquid-docs/schemas/theme/targetted_block_entry.json +15 -0
- package/vendor/theme-liquid-docs/schemas/theme/theme_block.json +91 -0
- package/vendor/theme-liquid-docs/schemas/theme/theme_block_entry.json +14 -0
- package/vendor/theme-liquid-docs/schemas/theme/theme_settings.json +83 -0
- package/vendor/theme-liquid-docs/schemas/theme/translations.json +63 -0
- package/vendor/theme-liquid-docs/schemas/update/update_extension_schema_v1.json +186 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-nested-blocks.json +18 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-1.json +90 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-2.json +201 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-3.json +29 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-4.json +315 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-5.json +114 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-6.json +63 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-conditional-settings.json +145 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-preset-blocks-as-hash.json +60 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-schema-static-block-preset.json +76 -0
- package/vendor/theme-liquid-docs/tests/fixtures/section-settings.json +34 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-block-1.json +234 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-block-2.json +253 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-block-basics.json +48 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-block-conditional-settings.json +202 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-block-presets-as-hash.json +50 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-block-settings.json +34 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-settings-all-settings.json +313 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-settings-dawn.json +1469 -0
- package/vendor/theme-liquid-docs/tests/fixtures/theme-settings-metadata.json +10 -0
- package/vendor/theme-liquid-docs/tests/fixtures/translations-1.json +14 -0
- package/vendor/theme-liquid-docs/tests/section.spec.ts +367 -0
- package/vendor/theme-liquid-docs/tests/test-constants.ts +58 -0
- package/vendor/theme-liquid-docs/tests/test-helpers.ts +104 -0
- package/vendor/theme-liquid-docs/tests/theme-settings/color_palette.spec.ts +184 -0
- package/vendor/theme-liquid-docs/tests/theme-settings/color_scheme_group.spec.ts +143 -0
- package/vendor/theme-liquid-docs/tests/theme-settings/general.spec.ts +192 -0
- package/vendor/theme-liquid-docs/tests/theme-settings/metaobject.spec.ts +94 -0
- package/vendor/theme-liquid-docs/tests/theme-settings/resource_list.spec.ts +58 -0
- package/vendor/theme-liquid-docs/tests/theme-settings/theme-metadata.spec.ts +59 -0
- package/vendor/theme-liquid-docs/tests/theme_block.spec.ts +266 -0
- package/vendor/theme-liquid-docs/tests/translations_schema.spec.ts +31 -0
- package/vendor/theme-liquid-docs/yarn.lock +543 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Static files (css, js, and images) for theme templates
|
|
3
|
+
globs: assets/*
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Assets
|
|
7
|
+
|
|
8
|
+
The `assets` directory contains static files—such as CSS, JavaScript, images, and icons—that need to be referenced in `.liquid` files or included on your theme.
|
|
9
|
+
|
|
10
|
+
- **No subdirectories:** this directory is flat and cannot contain folders.
|
|
11
|
+
- **Usage:** reference files with the [`asset_url`](mdc:https://shopify.dev/docs/api/liquid/filters/asset_url) filter.
|
|
12
|
+
- **SVG icons:** use the [`inline_asset_content`](mdc:https://shopify.dev/docs/api/liquid/filters/inline_asset_content) filter to include SVGs inline.
|
|
13
|
+
- **Critical static files:** Only include assets (like `critical.css` or global JS) needed on every page. For page or section specific assets, prefer the `{% stylesheet %}` and `{% javascript %}` tags.
|
|
14
|
+
|
|
15
|
+
Keep all images, scripts, stylesheets, and icons required by your theme in this directory.
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Development standards and best practices for creating, configuring, and styling theme blocks, including static and nested blocks, schema configuration, CSS, and usage examples
|
|
3
|
+
globs: blocks/*.liquid
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
# Theme blocks development standards
|
|
7
|
+
|
|
8
|
+
Follow [Shopify's theme blocks documentation](mdc:https:/shopify.dev/docs/storefronts/themes/architecture/blocks/theme-blocks/quick-start?framework=liquid).
|
|
9
|
+
|
|
10
|
+
## Theme block fundamentals
|
|
11
|
+
|
|
12
|
+
Theme blocks are reusable components defined at the theme level that can be:
|
|
13
|
+
- Nested under sections and blocks
|
|
14
|
+
- Configured using settings in the theme editor
|
|
15
|
+
- Given presets and added by merchants
|
|
16
|
+
- Used as [static blocks](mdc:https:/shopify.dev/docs/storefronts/themes/architecture/blocks/theme-blocks/static-blocks#statically-vs-dynamically-rendered-theme-blocks) by theme developers
|
|
17
|
+
|
|
18
|
+
Blocks render in the editor and storefront when they are referenced in [template files](mdc:.cursor/rules/templates.mdc).
|
|
19
|
+
|
|
20
|
+
### Basic block structure
|
|
21
|
+
```liquid
|
|
22
|
+
{% doc %}
|
|
23
|
+
Block description and usage examples
|
|
24
|
+
|
|
25
|
+
@example
|
|
26
|
+
{% content_for 'block', type: 'block-name', id: 'unique-id' %}
|
|
27
|
+
{% enddoc %}
|
|
28
|
+
|
|
29
|
+
<div {{ block.shopify_attributes }} class="block-name">
|
|
30
|
+
<!-- Block content using block.settings -->
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
{% stylesheet %}
|
|
34
|
+
/*
|
|
35
|
+
Scoped CSS for this block
|
|
36
|
+
|
|
37
|
+
Use BEM structure
|
|
38
|
+
CSS written in here should be for components that are exclusively in this block. If the CSS will be used elsewhere, it should instead be written in [assets/base.css](mdc:@assets/base.css)
|
|
39
|
+
*/
|
|
40
|
+
{% endstylesheet %}
|
|
41
|
+
|
|
42
|
+
{% schema %}
|
|
43
|
+
{
|
|
44
|
+
"name": "Block Name",
|
|
45
|
+
"settings": [],
|
|
46
|
+
"presets": []
|
|
47
|
+
}
|
|
48
|
+
{% endschema %}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Static block usage
|
|
52
|
+
|
|
53
|
+
Static blocks are theme blocks that are rendered directly in Liquid templates by developers, rather than being dynamically added through the theme editor. This allows for predetermined block placement with optional default settings.
|
|
54
|
+
|
|
55
|
+
**Basic static block syntax:**
|
|
56
|
+
```liquid
|
|
57
|
+
{% content_for 'block', type: 'text', id: 'header-announcement' %}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Example: Product template with mixed static and dynamic blocks**
|
|
61
|
+
```liquid
|
|
62
|
+
<!-- templates/product.liquid -->
|
|
63
|
+
<div class="product-page">
|
|
64
|
+
{% comment %} Static breadcrumb block {% endcomment %}
|
|
65
|
+
{% content_for 'block', type: 'breadcrumb', id: 'product-breadcrumb' %}
|
|
66
|
+
|
|
67
|
+
<div class="product-main">
|
|
68
|
+
<div class="product-media">
|
|
69
|
+
{% comment %} Static product gallery block {% endcomment %}
|
|
70
|
+
{% content_for 'block', type: 'product-gallery', id: 'main-gallery', settings: {
|
|
71
|
+
enable_zoom: true,
|
|
72
|
+
thumbnails_position: "bottom"
|
|
73
|
+
} %}
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="product-info">
|
|
77
|
+
{% comment %} Static product info blocks {% endcomment %}
|
|
78
|
+
{% content_for 'block', type: 'product-title', id: 'product-title' %}
|
|
79
|
+
{% content_for 'block', type: 'product-price', id: 'product-price' %}
|
|
80
|
+
{% content_for 'block', type: 'product-form', id: 'product-form' %}
|
|
81
|
+
|
|
82
|
+
{% comment %} Dynamic blocks area for additional content {% endcomment %}
|
|
83
|
+
<div class="product-extra-content">
|
|
84
|
+
{% content_for 'blocks' %}
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
{% comment %} Static related products block {% endcomment %}
|
|
90
|
+
{% content_for 'block', type: 'related-products', id: 'related-products', settings: {
|
|
91
|
+
heading: "You might also like",
|
|
92
|
+
limit: 4
|
|
93
|
+
} %}
|
|
94
|
+
</div>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Key points about static blocks:**
|
|
98
|
+
- They have a fixed `id` that makes them identifiable in the theme editor
|
|
99
|
+
- Settings can be overridden in the theme editor despite having defaults
|
|
100
|
+
- They appear in the theme editor as locked blocks that can't be removed or reordered
|
|
101
|
+
- Useful for consistent layout elements that should always be present
|
|
102
|
+
- Can be mixed with dynamic block areas using `{% content_for 'blocks' %}`
|
|
103
|
+
|
|
104
|
+
## Schema configuration
|
|
105
|
+
|
|
106
|
+
See [schemas.mdc](mdc:.cursor/rules/schemas.mdc) for rules on schemas
|
|
107
|
+
|
|
108
|
+
### Advanced schema features
|
|
109
|
+
|
|
110
|
+
#### Exclude wrapper
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"tag": null // No wrapper - must include {{ block.shopify_attributes }} for proper editor function
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Block implementation patterns
|
|
119
|
+
|
|
120
|
+
### Accessing block data
|
|
121
|
+
|
|
122
|
+
**Block settings:**
|
|
123
|
+
```liquid
|
|
124
|
+
{{ block.settings.text }}
|
|
125
|
+
{{ block.settings.heading | escape }}
|
|
126
|
+
{{ block.settings.image | image_url: width: 800 }}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Block properties:**
|
|
130
|
+
```liquid
|
|
131
|
+
{{ block.id }} // Unique block identifier
|
|
132
|
+
{{ block.type }} // Block type name
|
|
133
|
+
{{ block.shopify_attributes }} // Required for theme editor
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Section context:**
|
|
137
|
+
```liquid
|
|
138
|
+
{{ section.id }} // Parent section ID
|
|
139
|
+
{{ section.settings.heading | escape }}
|
|
140
|
+
{{ section.settings.image | image_url: width: 800 }}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Nested blocks implementation
|
|
144
|
+
|
|
145
|
+
### Rendering nested blocks
|
|
146
|
+
```liquid
|
|
147
|
+
<div class="block-container" {{ block.shopify_attributes }}>
|
|
148
|
+
<h2>{{ block.settings.heading | escape }}</h2>
|
|
149
|
+
|
|
150
|
+
<div class="nested-blocks">
|
|
151
|
+
{% content_for 'blocks' %}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Nesting with layout control
|
|
157
|
+
```liquid
|
|
158
|
+
<div
|
|
159
|
+
class="group {{ block.settings.layout_direction }}"
|
|
160
|
+
style="--gap: {{ block.settings.gap }}px;"
|
|
161
|
+
{{ block.shopify_attributes }}
|
|
162
|
+
>
|
|
163
|
+
{% content_for 'blocks' %}
|
|
164
|
+
</div>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Presets with nested blocks
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"presets": [
|
|
171
|
+
{
|
|
172
|
+
"name": "t:names.two_column_layout",
|
|
173
|
+
"category": "Layout",
|
|
174
|
+
"settings": {
|
|
175
|
+
"layout_direction": "horizontal"
|
|
176
|
+
},
|
|
177
|
+
"blocks": [
|
|
178
|
+
{
|
|
179
|
+
"type": "text",
|
|
180
|
+
"settings": {
|
|
181
|
+
"text": "Column 1 content"
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"type": "text",
|
|
186
|
+
"settings": {
|
|
187
|
+
"text": "Column 2 content"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## CSS and styling
|
|
197
|
+
|
|
198
|
+
See [css-standards.mdc](mdc:.cursor/rules/css-standards.mdc) for rules on writing CSS
|
|
199
|
+
|
|
200
|
+
### Scoped styles
|
|
201
|
+
```liquid
|
|
202
|
+
{% stylesheet %}
|
|
203
|
+
.block-name {
|
|
204
|
+
padding: var(--block-padding, 1rem);
|
|
205
|
+
background: var(--block-background, transparent);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.block-name__title {
|
|
209
|
+
font-size: var(--title-size, 1.5rem);
|
|
210
|
+
color: var(--title-color, inherit);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.block-name--primary {
|
|
214
|
+
background-color: var(--color-primary);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.block-name--secondary {
|
|
218
|
+
background-color: var(--color-secondary);
|
|
219
|
+
}
|
|
220
|
+
{% endstylesheet %}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Dynamic CSS variables
|
|
224
|
+
```liquid
|
|
225
|
+
<div
|
|
226
|
+
class="custom-block"
|
|
227
|
+
style="
|
|
228
|
+
--block-padding: {{ block.settings.padding }}px;
|
|
229
|
+
--text-align: {{ block.settings.alignment }};
|
|
230
|
+
--background: {{ block.settings.background_color }};
|
|
231
|
+
"
|
|
232
|
+
{{ block.shopify_attributes }}
|
|
233
|
+
>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Block targeting
|
|
237
|
+
|
|
238
|
+
### Section schema for theme blocks
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"blocks": [
|
|
242
|
+
{ "type": "@theme" }, // Accept all theme blocks
|
|
243
|
+
{ "type": "@app" } // Accept app blocks
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Restricted block targeting
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"blocks": [
|
|
252
|
+
{
|
|
253
|
+
"type": "text",
|
|
254
|
+
"name": "Text Content"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "image",
|
|
258
|
+
"name": "Image Content"
|
|
259
|
+
}
|
|
260
|
+
]
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Common block patterns
|
|
265
|
+
|
|
266
|
+
### Content block
|
|
267
|
+
```liquid
|
|
268
|
+
<div class="content-block {{ block.settings.style }}" {{ block.shopify_attributes }}>
|
|
269
|
+
{% if block.settings.heading != blank %}
|
|
270
|
+
<h3 class="content-block__heading">{{ block.settings.heading | escape }}</h3>
|
|
271
|
+
{% endif %}
|
|
272
|
+
|
|
273
|
+
{% if block.settings.text != blank %}
|
|
274
|
+
<div class="content-block__text">{{ block.settings.text }}</div>
|
|
275
|
+
{% endif %}
|
|
276
|
+
|
|
277
|
+
{% if block.settings.button_text != blank %}
|
|
278
|
+
<a href="{{ block.settings.button_url }}" class="content-block__button">
|
|
279
|
+
{{ block.settings.button_text | escape }}
|
|
280
|
+
</a>
|
|
281
|
+
{% endif %}
|
|
282
|
+
</div>
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Media block
|
|
286
|
+
```liquid
|
|
287
|
+
<div class="media-block" {{ block.shopify_attributes }}>
|
|
288
|
+
{% if block.settings.image %}
|
|
289
|
+
<div class="media-block__image">
|
|
290
|
+
{{ block.settings.image | image_url: width: 800 | image_tag:
|
|
291
|
+
alt: block.settings.image.alt | default: block.settings.alt_text
|
|
292
|
+
}}
|
|
293
|
+
</div>
|
|
294
|
+
{% endif %}
|
|
295
|
+
|
|
296
|
+
{% if block.settings.video %}
|
|
297
|
+
<div class="media-block__video">
|
|
298
|
+
{{ block.settings.video | video_tag: controls: true }}
|
|
299
|
+
</div>
|
|
300
|
+
{% endif %}
|
|
301
|
+
</div>
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Layout block (container)
|
|
305
|
+
```liquid
|
|
306
|
+
<div
|
|
307
|
+
class="layout-block layout-block--{{ block.settings.layout_type }}"
|
|
308
|
+
style="
|
|
309
|
+
--columns: {{ block.settings.columns }};
|
|
310
|
+
--gap: {{ block.settings.gap }}px;
|
|
311
|
+
"
|
|
312
|
+
{{ block.shopify_attributes }}
|
|
313
|
+
>
|
|
314
|
+
{% content_for 'blocks' %}
|
|
315
|
+
</div>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Performance best practices
|
|
319
|
+
|
|
320
|
+
### Conditional rendering
|
|
321
|
+
```liquid
|
|
322
|
+
{% liquid
|
|
323
|
+
assign has_content = false
|
|
324
|
+
if block.settings.heading != blank or block.settings.text != blank
|
|
325
|
+
assign has_content = true
|
|
326
|
+
endif
|
|
327
|
+
%}
|
|
328
|
+
|
|
329
|
+
{% if has_content %}
|
|
330
|
+
<div class="block-content" {{ block.shopify_attributes }}>
|
|
331
|
+
<!-- Content here -->
|
|
332
|
+
</div>
|
|
333
|
+
{% endif %}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Examples referenced
|
|
337
|
+
|
|
338
|
+
[text.liquid](mdc:.cursor/rules/examples/block-example-text.liquid) - Basic content block from existing project
|
|
339
|
+
[group.liquid](mdc:.cursor/rules/examples/block-example-group.liquid) - Container with nested blocks from existing project
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{% doc %}
|
|
2
|
+
Renders a group of blocks with configurable layout direction, gap and
|
|
3
|
+
alignment.
|
|
4
|
+
|
|
5
|
+
All settings apply to only one dimension to reduce configuration complexity.
|
|
6
|
+
|
|
7
|
+
This component is a wrapper concerned only with rendering its children in
|
|
8
|
+
the specified layout direction with appropriate padding and alignment.
|
|
9
|
+
|
|
10
|
+
@example
|
|
11
|
+
{% content_for 'block', type: 'group', id: 'group' %}
|
|
12
|
+
{% enddoc %}
|
|
13
|
+
|
|
14
|
+
<div
|
|
15
|
+
class="group {{ block.settings.layout_direction }}"
|
|
16
|
+
style="
|
|
17
|
+
--padding: {{ block.settings.padding }}px;
|
|
18
|
+
--alignment: {{ block.settings.alignment }};
|
|
19
|
+
"
|
|
20
|
+
{{ block.shopify_attributes }}
|
|
21
|
+
>
|
|
22
|
+
{% content_for 'blocks' %}
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
{% stylesheet %}
|
|
26
|
+
.group {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-wrap: nowrap;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
width: 100%;
|
|
31
|
+
}
|
|
32
|
+
.group--horizontal {
|
|
33
|
+
flex-direction: row;
|
|
34
|
+
justify-content: space-between;
|
|
35
|
+
align-items: center;
|
|
36
|
+
padding: 0 var(--padding);
|
|
37
|
+
}
|
|
38
|
+
.group--vertical {
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
align-items: var(--alignment);
|
|
41
|
+
padding: var(--padding) 0;
|
|
42
|
+
}
|
|
43
|
+
{% endstylesheet %}
|
|
44
|
+
|
|
45
|
+
{% schema %}
|
|
46
|
+
{
|
|
47
|
+
"name": "t:general.group",
|
|
48
|
+
"blocks": [{ "type": "@theme" }],
|
|
49
|
+
"settings": [
|
|
50
|
+
{
|
|
51
|
+
"type": "select",
|
|
52
|
+
"id": "layout_direction",
|
|
53
|
+
"label": "t:labels.layout_direction",
|
|
54
|
+
"default": "group--vertical",
|
|
55
|
+
"options": [
|
|
56
|
+
{ "value": "group--horizontal", "label": "t:options.direction.horizontal" },
|
|
57
|
+
{ "value": "group--vertical", "label": "t:options.direction.vertical" }
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"visible_if": "{{ block.settings.layout_direction == 'group--vertical' }}",
|
|
62
|
+
"type": "select",
|
|
63
|
+
"id": "alignment",
|
|
64
|
+
"label": "t:labels.alignment",
|
|
65
|
+
"default": "flex-start",
|
|
66
|
+
"options": [
|
|
67
|
+
{ "value": "flex-start", "label": "t:options.alignment.left" },
|
|
68
|
+
{ "value": "center", "label": "t:options.alignment.center" },
|
|
69
|
+
{ "value": "flex-end", "label": "t:options.alignment.right" }
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"type": "range",
|
|
74
|
+
"id": "padding",
|
|
75
|
+
"label": "t:labels.padding",
|
|
76
|
+
"default": 0,
|
|
77
|
+
"min": 0,
|
|
78
|
+
"max": 200,
|
|
79
|
+
"step": 2,
|
|
80
|
+
"unit": "px"
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"presets": [
|
|
84
|
+
{
|
|
85
|
+
"name": "t:general.column",
|
|
86
|
+
"category": "t:general.layout",
|
|
87
|
+
"settings": {
|
|
88
|
+
"layout_direction": "group--vertical",
|
|
89
|
+
"alignment": "flex-start",
|
|
90
|
+
"padding": 0
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "t:general.row",
|
|
95
|
+
"category": "t:general.layout",
|
|
96
|
+
"settings": {
|
|
97
|
+
"layout_direction": "group--horizontal",
|
|
98
|
+
"padding": 0
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
{% endschema %}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{% doc %}
|
|
2
|
+
Renders a text block.
|
|
3
|
+
|
|
4
|
+
@example
|
|
5
|
+
{% content_for 'block', type: 'text', id: 'text' %}
|
|
6
|
+
{% enddoc %}
|
|
7
|
+
|
|
8
|
+
<div
|
|
9
|
+
class="text {{ block.settings.text_style }}"
|
|
10
|
+
style="--text-align: {{ block.settings.alignment }}"
|
|
11
|
+
{{ block.shopify_attributes }}
|
|
12
|
+
>
|
|
13
|
+
{{ block.settings.text }}
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
{% stylesheet %}
|
|
17
|
+
.text {
|
|
18
|
+
text-align: var(--text-align);
|
|
19
|
+
}
|
|
20
|
+
.text--title {
|
|
21
|
+
font-size: 2rem;
|
|
22
|
+
font-weight: 700;
|
|
23
|
+
}
|
|
24
|
+
.text--subtitle {
|
|
25
|
+
font-size: 1.5rem;
|
|
26
|
+
}
|
|
27
|
+
{% endstylesheet %}
|
|
28
|
+
|
|
29
|
+
{% schema %}
|
|
30
|
+
{
|
|
31
|
+
"name": "t:general.text",
|
|
32
|
+
"settings": [
|
|
33
|
+
{
|
|
34
|
+
"type": "text",
|
|
35
|
+
"id": "text",
|
|
36
|
+
"label": "t:labels.text",
|
|
37
|
+
"default": "Text"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "select",
|
|
41
|
+
"id": "text_style",
|
|
42
|
+
"label": "t:labels.text_style",
|
|
43
|
+
"options": [
|
|
44
|
+
{ "value": "text--title", "label": "t:options.text_style.title" },
|
|
45
|
+
{ "value": "text--subtitle", "label": "t:options.text_style.subtitle" },
|
|
46
|
+
{ "value": "text--normal", "label": "t:options.text_style.normal" }
|
|
47
|
+
],
|
|
48
|
+
"default": "text--title"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"type": "text_alignment",
|
|
52
|
+
"id": "alignment",
|
|
53
|
+
"label": "t:labels.alignment",
|
|
54
|
+
"default": "left"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"presets": [{ "name": "t:general.text" }]
|
|
58
|
+
}
|
|
59
|
+
{% endschema %}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<div class="example-section full-width">
|
|
2
|
+
{% if section.settings.background_image %}
|
|
3
|
+
<div class="example-section__background">
|
|
4
|
+
{{ section.settings.background_image | image_url: width: 2000 | image_tag }}
|
|
5
|
+
</div>
|
|
6
|
+
{% endif %}
|
|
7
|
+
|
|
8
|
+
<div class="custom-section__content">
|
|
9
|
+
{% content_for 'blocks' %}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
{% stylesheet %}
|
|
14
|
+
.example-section {
|
|
15
|
+
position: relative;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
width: 100%;
|
|
18
|
+
}
|
|
19
|
+
.example-section__background {
|
|
20
|
+
position: absolute;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 100%;
|
|
23
|
+
z-index: -1;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
.example-section__background img {
|
|
27
|
+
position: absolute;
|
|
28
|
+
width: 100%;
|
|
29
|
+
height: auto;
|
|
30
|
+
top: 50%;
|
|
31
|
+
left: 50%;
|
|
32
|
+
transform: translate(-50%, -50%);
|
|
33
|
+
}
|
|
34
|
+
.example-section__content {
|
|
35
|
+
display: grid;
|
|
36
|
+
grid-template-columns: var(--content-grid);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.example-section__content > * {
|
|
40
|
+
grid-column: 2;
|
|
41
|
+
}
|
|
42
|
+
{% endstylesheet %}
|
|
43
|
+
|
|
44
|
+
{% schema %}
|
|
45
|
+
{
|
|
46
|
+
"name": "t:general.custom_section",
|
|
47
|
+
"blocks": [{ "type": "@theme" }],
|
|
48
|
+
"settings": [
|
|
49
|
+
{
|
|
50
|
+
"type": "image_picker",
|
|
51
|
+
"id": "background_image",
|
|
52
|
+
"label": "t:labels.background"
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"presets": [
|
|
56
|
+
{
|
|
57
|
+
"name": "t:general.custom_section"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
{% endschema %}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{% doc %}
|
|
2
|
+
Renders a responsive image that might be wrapped in a link.
|
|
3
|
+
|
|
4
|
+
When `width`, `height` and `crop` are provided, the image will be rendered
|
|
5
|
+
with a fixed aspect ratio.
|
|
6
|
+
|
|
7
|
+
Serves as an example of how to use the `image_url` filter and `image_tag` filter
|
|
8
|
+
as well as how you can use LiquidDoc to document your code.
|
|
9
|
+
|
|
10
|
+
@param {image} image - The image to be rendered
|
|
11
|
+
@param {string} [url] - An optional destination URL for the image
|
|
12
|
+
@param {string} [css_class] - Optional class to be added to the image wrapper
|
|
13
|
+
@param {number} [width] - The highest resolution width of the image to be rendered
|
|
14
|
+
@param {number} [height] - The highest resolution height of the image to be rendered
|
|
15
|
+
@param {string} [crop] - The crop position of the image
|
|
16
|
+
|
|
17
|
+
@example
|
|
18
|
+
{% render 'image', image: product.featured_image %}
|
|
19
|
+
{% render 'image', image: product.featured_image, url: product.url %}
|
|
20
|
+
{% render 'image',
|
|
21
|
+
css_class: 'product__image',
|
|
22
|
+
image: product.featured_image,
|
|
23
|
+
url: product.url,
|
|
24
|
+
width: 1200,
|
|
25
|
+
height: 800,
|
|
26
|
+
crop: 'center',
|
|
27
|
+
%}
|
|
28
|
+
{% enddoc %}
|
|
29
|
+
|
|
30
|
+
{% liquid
|
|
31
|
+
unless height
|
|
32
|
+
assign width = width | default: image.width
|
|
33
|
+
endunless
|
|
34
|
+
|
|
35
|
+
if url
|
|
36
|
+
assign wrapper = 'a'
|
|
37
|
+
else
|
|
38
|
+
assign wrapper = 'div'
|
|
39
|
+
endif
|
|
40
|
+
%}
|
|
41
|
+
|
|
42
|
+
<{{ wrapper }}
|
|
43
|
+
class="image {{ css_class }}"
|
|
44
|
+
{% if url %}
|
|
45
|
+
href="{{ url }}"
|
|
46
|
+
{% endif %}
|
|
47
|
+
>
|
|
48
|
+
{{ image | image_url: width: width, height: height, crop: crop | image_tag }}
|
|
49
|
+
</{{ wrapper }}>
|
|
50
|
+
|
|
51
|
+
{% stylesheet %}
|
|
52
|
+
.image {
|
|
53
|
+
display: block;
|
|
54
|
+
position: relative;
|
|
55
|
+
overflow: hidden;
|
|
56
|
+
width: 100%;
|
|
57
|
+
height: auto;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.image > img {
|
|
61
|
+
width: 100%;
|
|
62
|
+
height: auto;
|
|
63
|
+
}
|
|
64
|
+
{% endstylesheet %}
|
|
65
|
+
|
|
66
|
+
{% javascript %}
|
|
67
|
+
function doSomething() {
|
|
68
|
+
// example
|
|
69
|
+
}
|
|
70
|
+
doSomething()
|
|
71
|
+
{% endjavascript %}
|
|
72
|
+
|