vite-plugin-react-shopify 1.0.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/README.md +407 -0
- package/dist/index.d.ts +261 -0
- package/dist/index.js +638 -0
- package/dist/runtime/Liquid.client.d.ts +6 -0
- package/dist/runtime/Liquid.client.js +7 -0
- package/dist/runtime/Liquid.d.ts +11 -0
- package/dist/runtime/Liquid.js +10 -0
- package/dist/runtime/settings.d.ts +8 -0
- package/dist/runtime/settings.js +44 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# vite-plugin-react-shopify
|
|
2
|
+
|
|
3
|
+
使用 React 组件编写 Shopify 主题的 Section、Block 和 Template。在构建时通过 SSG(Static Site Generation)将 React 组件编译为 Shopify Liquid 文件,运行时由 React 进行水合(hydration)。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add vite-plugin-react-shopify
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 快速开始
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// vite.config.ts
|
|
15
|
+
import vitePluginShopify from "vite-plugin-react-shopify";
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
plugins: [
|
|
19
|
+
vitePluginShopify({
|
|
20
|
+
themeRoot: ".", // 主题根目录,默认 "./"
|
|
21
|
+
sourceCodeDir: "frontend", // 源码目录,默认 "frontend"
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// frontend/sections/HelloWorld.tsx
|
|
29
|
+
import type { ShopifyMeta } from "vite-plugin-react-shopify";
|
|
30
|
+
|
|
31
|
+
export const shopifyMeta = {
|
|
32
|
+
name: "Hello World",
|
|
33
|
+
presets: [{ name: "Hello World" }],
|
|
34
|
+
} satisfies ShopifyMeta;
|
|
35
|
+
|
|
36
|
+
export default function HelloWorld() {
|
|
37
|
+
return <h1>Hello, World!</h1>;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
构建后生成 `sections/react-hello-world.liquid`。
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 目录结构
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
my-theme/
|
|
49
|
+
├── frontend/ ← React 源码
|
|
50
|
+
│ ├── sections/
|
|
51
|
+
│ │ └── HelloWorld.tsx
|
|
52
|
+
│ ├── blocks/
|
|
53
|
+
│ │ └── TextBlock.tsx
|
|
54
|
+
│ └── templates/
|
|
55
|
+
│ └── index.tsx
|
|
56
|
+
├── sections/ ← 生成的 Liquid + 原生 Liquid
|
|
57
|
+
├── blocks/
|
|
58
|
+
├── templates/
|
|
59
|
+
├── snippets/
|
|
60
|
+
│ └── shopify-importmap.liquid ← 自动生成的 importmap
|
|
61
|
+
└── assets/ ← Vite 构建产物(可通过 buildDir 配置子目录)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
源码放在 `frontend/` 下,按 Shopify 类型分目录。构建后生成对应的 `.liquid` 文件到主题根目录的 `sections/`、`blocks/`、`templates/` 下。
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 组件约定
|
|
69
|
+
|
|
70
|
+
每个 React 组件必须导出两样东西:
|
|
71
|
+
|
|
72
|
+
### 1. `shopifyMeta` — Shopify Schema 定义
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
export const shopifyMeta = {
|
|
76
|
+
name: "组件名称", // 必填,在 Shopify 编辑器中显示的名称
|
|
77
|
+
type: "section", // 可选,覆盖目录推断的类型
|
|
78
|
+
tag: "section", // 可选,外层 HTML 标签,默认 "div"
|
|
79
|
+
class: "custom-class", // 可选,外层附加的 CSS 类名
|
|
80
|
+
limit: 1, // 可选,每页最大数量
|
|
81
|
+
max_blocks: 10, // 可选,最大子 block 数
|
|
82
|
+
settings: [...], // 可选,设置项
|
|
83
|
+
blocks: [...], // 可选,接受的子 block 类型
|
|
84
|
+
presets: [...], // 可选,编辑器预设
|
|
85
|
+
enabled_on: {...}, // 可选,启用条件
|
|
86
|
+
disabled_on: {...}, // 可选,禁用条件
|
|
87
|
+
templates: [...], // 可选,适用的模板
|
|
88
|
+
} satisfies ShopifyMeta;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 2. `default export` — React 组件
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
export default function MyComponent(props) {
|
|
95
|
+
return <div>...</div>;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 类型推断
|
|
100
|
+
|
|
101
|
+
文件名和目录决定目标类型:
|
|
102
|
+
|
|
103
|
+
| 源码路径 | 目标类型 | 生成文件 |
|
|
104
|
+
|----------|----------|----------|
|
|
105
|
+
| `frontend/sections/X.tsx` | `section` | `sections/react-x.liquid` |
|
|
106
|
+
| `frontend/blocks/X.tsx` | `block` | `blocks/react-x.liquid` |
|
|
107
|
+
| `frontend/templates/X.tsx` | `template` | `templates/page.react-x.liquid` |
|
|
108
|
+
|
|
109
|
+
可通过 `shopifyMeta.type` 覆盖。
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 设置 (Settings)
|
|
114
|
+
|
|
115
|
+
使用 `SettingSchema` 类型定义设置项。`SettingSchema` 是根据 `type` 字段判别(discriminated union)的联合类型 —— 每种 type 只接受 Shopify 文档中合法的字段,无效字段会在编译时报错:
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import type { SettingSchema } from "vite-plugin-react-shopify";
|
|
119
|
+
|
|
120
|
+
const settings = [
|
|
121
|
+
{
|
|
122
|
+
type: "text",
|
|
123
|
+
id: "title",
|
|
124
|
+
label: "Title",
|
|
125
|
+
default: "Hello",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
type: "select",
|
|
129
|
+
id: "layout",
|
|
130
|
+
label: "Layout",
|
|
131
|
+
default: "grid",
|
|
132
|
+
options: [
|
|
133
|
+
{ value: "grid", label: "Grid" },
|
|
134
|
+
{ value: "list", label: "List" },
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: "range",
|
|
139
|
+
id: "columns",
|
|
140
|
+
label: "Columns",
|
|
141
|
+
default: 3,
|
|
142
|
+
min: 1,
|
|
143
|
+
max: 6,
|
|
144
|
+
step: 1,
|
|
145
|
+
},
|
|
146
|
+
] satisfies SettingSchema[];
|
|
147
|
+
|
|
148
|
+
// 也可以直接引用具体类型:
|
|
149
|
+
import type { SelectSetting, RangeSetting } from "vite-plugin-react-shopify";
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 基本输入类型
|
|
153
|
+
|
|
154
|
+
| 类型 | 额外字段 | `default` |
|
|
155
|
+
|------|----------|-----------|
|
|
156
|
+
| `checkbox` | — | 可选 `boolean` |
|
|
157
|
+
| `number` | `placeholder` | 可选 `number` |
|
|
158
|
+
| `radio` | `options`(必填) | 可选 `string` |
|
|
159
|
+
| `range` | `min`(必填)、`max`(必填)、`step`、`unit` | **必填** `number` |
|
|
160
|
+
| `select` | `options`(必填) | 可选 `string` |
|
|
161
|
+
| `text` | `placeholder` | 可选 `string` |
|
|
162
|
+
| `textarea` | `placeholder` | 可选 `string` |
|
|
163
|
+
|
|
164
|
+
### 专用输入类型
|
|
165
|
+
|
|
166
|
+
| 类型 | 额外字段 |
|
|
167
|
+
|------|----------|
|
|
168
|
+
| `article` | —(不支持 `default`) |
|
|
169
|
+
| `article_list` | `limit` |
|
|
170
|
+
| `blog` | —(不支持 `default`) |
|
|
171
|
+
| `collection` | —(不支持 `default`) |
|
|
172
|
+
| `collection_list` | `limit` |
|
|
173
|
+
| `color` | — |
|
|
174
|
+
| `color_background` | — |
|
|
175
|
+
| `color_scheme` | — |
|
|
176
|
+
| `color_scheme_group` | `definition`(必填)、`role`(必填) |
|
|
177
|
+
| `font_picker` | —(`default` **必填** `string`) |
|
|
178
|
+
| `html` | `placeholder` |
|
|
179
|
+
| `image_picker` | —(不支持 `default`) |
|
|
180
|
+
| `inline_richtext` | — |
|
|
181
|
+
| `link_list` | —(`default` 限制为 `"main-menu"` / `"footer"`) |
|
|
182
|
+
| `liquid` | — |
|
|
183
|
+
| `metaobject` | `metaobject_type`(必填) |
|
|
184
|
+
| `metaobject_list` | `metaobject_type`(必填)、`limit` |
|
|
185
|
+
| `page` | —(不支持 `default`) |
|
|
186
|
+
| `product` | —(不支持 `default`) |
|
|
187
|
+
| `product_list` | `limit` |
|
|
188
|
+
| `richtext` | — |
|
|
189
|
+
| `text_alignment` | —(`default` 限制为 `"left"` / `"center"` / `"right"`) |
|
|
190
|
+
| `url` | — |
|
|
191
|
+
| `video` | —(不支持 `default`) |
|
|
192
|
+
| `video_url` | `accept`(必填)、`placeholder` |
|
|
193
|
+
|
|
194
|
+
### 侧边栏类型(非输入,仅显示信息)
|
|
195
|
+
|
|
196
|
+
`header`、`paragraph`、`line_break`。与输入类型不同,侧边栏类型不保存值,仅用于组织和描述设置项。使用 `content` 字段代替 `id`/`label`:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
const settings = [
|
|
200
|
+
{ type: "header", content: "Typography", info: "Customize text styles below." },
|
|
201
|
+
{ type: "font_picker", id: "heading_font", label: "Heading font", default: "helvetica_n4" },
|
|
202
|
+
{ type: "paragraph", content: "Set your brand colors for buttons and accents." },
|
|
203
|
+
{ type: "color", id: "accent_color", label: "Accent color", default: "#000000" },
|
|
204
|
+
{ type: "line_break" },
|
|
205
|
+
{ type: "checkbox", id: "dark_mode", label: "Enable dark mode", default: false },
|
|
206
|
+
] satisfies SettingSchema[];
|
|
207
|
+
|
|
208
|
+
Setting 的 `id` 会作为 React 组件的 prop 名传入。Shopify 编辑器修改 setting 后,水合层会读取 `{{ section.settings | json }}` 将最新值传给组件。设置值通过 `useShopifySettings()` hook 读取。
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 预设 (Presets)
|
|
213
|
+
|
|
214
|
+
预设让组件可以在编辑器中通过"添加 Section/Block"面板直接添加:
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
export const shopifyMeta = {
|
|
218
|
+
name: "Hero Banner",
|
|
219
|
+
presets: [
|
|
220
|
+
{ name: "Hero (Light)", category: "Banners" },
|
|
221
|
+
{
|
|
222
|
+
name: "Hero (Dark)",
|
|
223
|
+
category: "Banners",
|
|
224
|
+
settings: { bg_color: "#000", text_color: "#fff" },
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
} satisfies ShopifyMeta;
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 子 Block(嵌套)
|
|
233
|
+
|
|
234
|
+
Section 或 Block 可以声明接受的子 block 类型:
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
export const shopifyMeta = {
|
|
238
|
+
name: "Group",
|
|
239
|
+
blocks: [{ type: "@theme" }], // 接受所有主题 block
|
|
240
|
+
} satisfies ShopifyMeta;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- `"@theme"` 接受当前主题中所有已注册的 block
|
|
244
|
+
- `"类型名"` 只接受特定类型的 block(如 `"text"` 匹配 `blocks/text.liquid`)
|
|
245
|
+
- 插件会自动在生成的 Liquid 中插入 `{% content_for 'blocks' %}`
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## CSS 样式
|
|
250
|
+
|
|
251
|
+
使用 CSS Module 为组件添加样式。CSS 会在构建时被内联到生成的 Liquid 的 `{% stylesheet %}` 块中,由 Shopify 统一注入到 `<head>`,避免 FOUC 和额外 HTTP 请求。
|
|
252
|
+
|
|
253
|
+
```css
|
|
254
|
+
/* frontend/sections/Hero.module.css */
|
|
255
|
+
.hero {
|
|
256
|
+
display: grid;
|
|
257
|
+
padding: 2rem;
|
|
258
|
+
}
|
|
259
|
+
.hero-title {
|
|
260
|
+
font-size: 3rem;
|
|
261
|
+
font-weight: 700;
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
// frontend/sections/Hero.tsx
|
|
267
|
+
import styles from "./Hero.module.css";
|
|
268
|
+
|
|
269
|
+
export default function Hero() {
|
|
270
|
+
return (
|
|
271
|
+
<div className={styles["hero"]}>
|
|
272
|
+
<h1 className={styles["hero-title"]}>Title</h1>
|
|
273
|
+
</div>
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
生成的 Liquid 中会包含:
|
|
279
|
+
|
|
280
|
+
```liquid
|
|
281
|
+
{% stylesheet %}
|
|
282
|
+
._hero_abc123{display:grid;padding:2rem}
|
|
283
|
+
._hero-title_abc123{font-size:3rem;font-weight:700}
|
|
284
|
+
{% endstylesheet %}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
> **注意**:SSG 预渲染的 HTML 使用未经过 Vite hash 处理的类名。浏览器加载后 React 水合会替换为正确的 hash 类名。这是 CSS Module + SSG 的已知权衡。
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 配置选项
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
vitePluginShopify({
|
|
295
|
+
// === 路径配置 ===
|
|
296
|
+
themeRoot: ".", // 主题根目录
|
|
297
|
+
sourceCodeDir: "frontend", // React 源码目录(相对于 themeRoot)
|
|
298
|
+
snippetFile: "shopify-importmap.liquid", // importmap 片段文件名
|
|
299
|
+
buildDir: "assets", // Vite 构建产物输出目录(相对于 themeRoot)
|
|
300
|
+
|
|
301
|
+
// === SSG 配置 ===
|
|
302
|
+
ssg: {
|
|
303
|
+
directories: ["sections", "blocks", "templates"], // 扫描的目录
|
|
304
|
+
prefix: { // 生成文件的命名前缀
|
|
305
|
+
template: "page.react-", // templates → page.react-xxx.liquid
|
|
306
|
+
section: "react-", // sections → react-xxx.liquid
|
|
307
|
+
block: "react-", // blocks → react-xxx.liquid
|
|
308
|
+
},
|
|
309
|
+
outputName: "", // 自定义输出模板,留空使用前缀规则
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
// === Import Map 配置 ===
|
|
313
|
+
importMap: {
|
|
314
|
+
react: "https://esm.sh/react@19",
|
|
315
|
+
reactDomClient: "https://esm.sh/react-dom@19/client",
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## 命名约定
|
|
323
|
+
|
|
324
|
+
### 默认命名规则
|
|
325
|
+
|
|
326
|
+
| 源码文件 | 目标类型 | 生成文件 |
|
|
327
|
+
|----------|----------|----------|
|
|
328
|
+
| `frontend/sections/MySection.tsx` | section | `sections/react-my-section.liquid` |
|
|
329
|
+
| `frontend/blocks/MyBlock.tsx` | block | `blocks/react-my-block.liquid` |
|
|
330
|
+
| `frontend/templates/Index.tsx` | template | `templates/page.react-index.liquid` |
|
|
331
|
+
|
|
332
|
+
- 组件文件名通过 `toKebabCase` 转换为 kebab-case:
|
|
333
|
+
- `HelloWorld` → `hello-world`
|
|
334
|
+
- `FAQSection` → `faq-section`
|
|
335
|
+
|
|
336
|
+
### 自定义命名(`outputName`)
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
ssg: {
|
|
340
|
+
outputName: "{target}s/{kebab}" // 按类型分目录,不添加前缀
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
支持占位符:`{type}`、`{kebab}`、`{pascal}`、`{target}`。
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 水合(Hydration)与编辑器事件
|
|
349
|
+
|
|
350
|
+
### 水合流程
|
|
351
|
+
|
|
352
|
+
1. **SSG 预渲染**:构建时 React 组件渲染为静态 HTML,嵌入 `<div data-ssg-hydrate>`
|
|
353
|
+
2. **Settings 透传**:Liquid 中 `<script type="application/json" data-ssg-props>` 包含 `{{ section.settings | json }}`
|
|
354
|
+
3. **Hydration JS**:Vite 为每个组件生成独立的 hydration chunk,读取 settings JSON 并调用 `hydrateRoot`
|
|
355
|
+
|
|
356
|
+
### 编辑器事件
|
|
357
|
+
|
|
358
|
+
Hydration 脚本自动监听 Shopify 编辑器的 Section 生命周期事件:
|
|
359
|
+
|
|
360
|
+
| 事件 | 行为 |
|
|
361
|
+
|------|------|
|
|
362
|
+
| `shopify:section:load` | Section 被添加或重新渲染时,重新 hydrate 组件 |
|
|
363
|
+
| `shopify:section:unload` | Section 被删除或即将重新渲染时,unmount React 根节点 |
|
|
364
|
+
|
|
365
|
+
当用户在编辑器中修改 setting 时:Shopify 重新渲染 Section HTML → 触发 `unload`(清理旧 root)→ 触发 `load`(用新 props 重新 hydrate)。
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 运行时
|
|
370
|
+
|
|
371
|
+
### Liquid 组件
|
|
372
|
+
|
|
373
|
+
在 JSX 中嵌入原始 Liquid 代码:
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
import { Liquid } from "vite-plugin-react-shopify/runtime";
|
|
377
|
+
|
|
378
|
+
export default function Section() {
|
|
379
|
+
return (
|
|
380
|
+
<div>
|
|
381
|
+
<Liquid>{`{% if section.settings.show_title %}`}</Liquid>
|
|
382
|
+
<h1>Title</h1>
|
|
383
|
+
<Liquid>{`{% endif %}`}</Liquid>
|
|
384
|
+
</div>
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Import Map
|
|
390
|
+
|
|
391
|
+
插件自动生成 `snippets/shopify-importmap.liquid`,包含 React 和 ReactDOM 的 CDN import map。在主题 `layout/theme.liquid` 的 `<head>` 中引入:
|
|
392
|
+
|
|
393
|
+
```liquid
|
|
394
|
+
{% render 'shopify-importmap' %}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## 注意事项
|
|
400
|
+
|
|
401
|
+
1. **React / ReactDOM 不打包进 bundle**:通过 import map 从 CDN 加载,避免重复打包和体积膨胀
|
|
402
|
+
2. **CSS Module hash 差异**:SSG 预渲染的 HTML 使用原始类名,水合后才会替换为 hash 类名。如需完美匹配,建议使用全局 CSS 而非 CSS Module,或接受短暂的样式跳跃
|
|
403
|
+
3. **SSG 使用默认 props 渲染**:构建时的预渲染使用组件的默认 prop 值,编辑器中修改 setting 后会通过水合更新
|
|
404
|
+
4. **Template 类型不包裹**:`type: "template"` 的组件 HTML 直接输出,不添加 section/block 外层结构,适用于整页模板
|
|
405
|
+
5. **Section 必须有预设才能通过编辑器添加**:没有 `presets` 的 section 需要手动在 JSON 模板中引用,编辑器无法直接添加
|
|
406
|
+
6. **`{% content_for 'blocks' %}` 自动插入**:当 `shopifyMeta.blocks` 非空时,插件自动在生成的 Liquid 中插入子 block 渲染标签
|
|
407
|
+
7. **构建产物默认输出到 `assets/`**:如需与其他静态资源隔离,可设置 `buildDir: "assets/build"` 将产物输出到子目录,然后在 `.gitignore` 中添加 `assets/build/` 忽略该目录
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
interface Options {
|
|
4
|
+
themeRoot?: string;
|
|
5
|
+
sourceCodeDir?: string;
|
|
6
|
+
snippetFile?: string;
|
|
7
|
+
buildDir?: string;
|
|
8
|
+
ssg?: SSGOptions;
|
|
9
|
+
importMap?: ImportMapOptions;
|
|
10
|
+
}
|
|
11
|
+
interface SSGOptions {
|
|
12
|
+
directories?: string[];
|
|
13
|
+
prefix?: {
|
|
14
|
+
template?: string;
|
|
15
|
+
section?: string;
|
|
16
|
+
block?: string;
|
|
17
|
+
};
|
|
18
|
+
outputName?: string;
|
|
19
|
+
}
|
|
20
|
+
interface ImportMapOptions {
|
|
21
|
+
react?: string;
|
|
22
|
+
reactDomClient?: string;
|
|
23
|
+
}
|
|
24
|
+
type ShopifyBlockType = "template" | "section" | "block";
|
|
25
|
+
type SettingValue = string | number | boolean;
|
|
26
|
+
type InputSettings = Record<string, SettingValue>;
|
|
27
|
+
interface BaseSettingSchema {
|
|
28
|
+
id: string;
|
|
29
|
+
label: string;
|
|
30
|
+
info?: string;
|
|
31
|
+
}
|
|
32
|
+
interface CheckboxSetting extends BaseSettingSchema {
|
|
33
|
+
type: "checkbox";
|
|
34
|
+
default?: boolean;
|
|
35
|
+
}
|
|
36
|
+
interface NumberSetting extends BaseSettingSchema {
|
|
37
|
+
type: "number";
|
|
38
|
+
default?: number;
|
|
39
|
+
placeholder?: string;
|
|
40
|
+
}
|
|
41
|
+
interface RadioSetting extends BaseSettingSchema {
|
|
42
|
+
type: "radio";
|
|
43
|
+
options: {
|
|
44
|
+
value: string;
|
|
45
|
+
label: string;
|
|
46
|
+
}[];
|
|
47
|
+
default?: string;
|
|
48
|
+
}
|
|
49
|
+
interface RangeSetting extends BaseSettingSchema {
|
|
50
|
+
type: "range";
|
|
51
|
+
min: number;
|
|
52
|
+
max: number;
|
|
53
|
+
step?: number;
|
|
54
|
+
unit?: string;
|
|
55
|
+
default: number;
|
|
56
|
+
}
|
|
57
|
+
interface SelectSetting extends BaseSettingSchema {
|
|
58
|
+
type: "select";
|
|
59
|
+
options: {
|
|
60
|
+
value: string;
|
|
61
|
+
label: string;
|
|
62
|
+
group?: string;
|
|
63
|
+
}[];
|
|
64
|
+
default?: string;
|
|
65
|
+
}
|
|
66
|
+
interface TextSetting extends BaseSettingSchema {
|
|
67
|
+
type: "text";
|
|
68
|
+
default?: string;
|
|
69
|
+
placeholder?: string;
|
|
70
|
+
}
|
|
71
|
+
interface TextareaSetting extends BaseSettingSchema {
|
|
72
|
+
type: "textarea";
|
|
73
|
+
default?: string;
|
|
74
|
+
placeholder?: string;
|
|
75
|
+
}
|
|
76
|
+
interface ArticleSetting extends BaseSettingSchema {
|
|
77
|
+
type: "article";
|
|
78
|
+
}
|
|
79
|
+
interface ArticleListSetting extends BaseSettingSchema {
|
|
80
|
+
type: "article_list";
|
|
81
|
+
limit?: number;
|
|
82
|
+
}
|
|
83
|
+
interface BlogSetting extends BaseSettingSchema {
|
|
84
|
+
type: "blog";
|
|
85
|
+
}
|
|
86
|
+
interface CollectionSetting extends BaseSettingSchema {
|
|
87
|
+
type: "collection";
|
|
88
|
+
}
|
|
89
|
+
interface CollectionListSetting extends BaseSettingSchema {
|
|
90
|
+
type: "collection_list";
|
|
91
|
+
limit?: number;
|
|
92
|
+
}
|
|
93
|
+
interface ColorSetting extends BaseSettingSchema {
|
|
94
|
+
type: "color";
|
|
95
|
+
default?: string;
|
|
96
|
+
}
|
|
97
|
+
interface ColorBackgroundSetting extends BaseSettingSchema {
|
|
98
|
+
type: "color_background";
|
|
99
|
+
default?: string;
|
|
100
|
+
}
|
|
101
|
+
interface ColorSchemeSetting extends BaseSettingSchema {
|
|
102
|
+
type: "color_scheme";
|
|
103
|
+
default?: string;
|
|
104
|
+
}
|
|
105
|
+
interface ColorSchemeRole {
|
|
106
|
+
text: string;
|
|
107
|
+
background: string | {
|
|
108
|
+
solid: string;
|
|
109
|
+
gradient?: string;
|
|
110
|
+
};
|
|
111
|
+
links?: string;
|
|
112
|
+
icons?: string;
|
|
113
|
+
primary_button?: string | {
|
|
114
|
+
solid: string;
|
|
115
|
+
gradient?: string;
|
|
116
|
+
};
|
|
117
|
+
on_primary_button?: string;
|
|
118
|
+
primary_button_border?: string;
|
|
119
|
+
secondary_button?: string | {
|
|
120
|
+
solid: string;
|
|
121
|
+
gradient?: string;
|
|
122
|
+
};
|
|
123
|
+
on_secondary_button?: string;
|
|
124
|
+
secondary_button_border?: string;
|
|
125
|
+
}
|
|
126
|
+
interface ColorSchemeGroupSetting extends BaseSettingSchema {
|
|
127
|
+
type: "color_scheme_group";
|
|
128
|
+
definition: InputSettingSchema[];
|
|
129
|
+
role: ColorSchemeRole;
|
|
130
|
+
}
|
|
131
|
+
interface FontPickerSetting extends BaseSettingSchema {
|
|
132
|
+
type: "font_picker";
|
|
133
|
+
default: string;
|
|
134
|
+
}
|
|
135
|
+
interface HtmlSetting extends BaseSettingSchema {
|
|
136
|
+
type: "html";
|
|
137
|
+
default?: string;
|
|
138
|
+
placeholder?: string;
|
|
139
|
+
}
|
|
140
|
+
interface ImagePickerSetting extends BaseSettingSchema {
|
|
141
|
+
type: "image_picker";
|
|
142
|
+
}
|
|
143
|
+
interface InlineRichtextSetting extends BaseSettingSchema {
|
|
144
|
+
type: "inline_richtext";
|
|
145
|
+
default?: string;
|
|
146
|
+
}
|
|
147
|
+
interface LinkListSetting extends BaseSettingSchema {
|
|
148
|
+
type: "link_list";
|
|
149
|
+
default?: "main-menu" | "footer" | string;
|
|
150
|
+
}
|
|
151
|
+
interface LiquidSetting extends BaseSettingSchema {
|
|
152
|
+
type: "liquid";
|
|
153
|
+
default?: string;
|
|
154
|
+
}
|
|
155
|
+
interface MetaobjectSetting extends BaseSettingSchema {
|
|
156
|
+
type: "metaobject";
|
|
157
|
+
metaobject_type: string;
|
|
158
|
+
}
|
|
159
|
+
interface MetaobjectListSetting extends BaseSettingSchema {
|
|
160
|
+
type: "metaobject_list";
|
|
161
|
+
metaobject_type: string;
|
|
162
|
+
limit?: number;
|
|
163
|
+
}
|
|
164
|
+
interface PageSetting extends BaseSettingSchema {
|
|
165
|
+
type: "page";
|
|
166
|
+
}
|
|
167
|
+
interface ProductSetting extends BaseSettingSchema {
|
|
168
|
+
type: "product";
|
|
169
|
+
}
|
|
170
|
+
interface ProductListSetting extends BaseSettingSchema {
|
|
171
|
+
type: "product_list";
|
|
172
|
+
limit?: number;
|
|
173
|
+
}
|
|
174
|
+
interface RichtextSetting extends BaseSettingSchema {
|
|
175
|
+
type: "richtext";
|
|
176
|
+
default?: string;
|
|
177
|
+
}
|
|
178
|
+
interface TextAlignmentSetting extends BaseSettingSchema {
|
|
179
|
+
type: "text_alignment";
|
|
180
|
+
default?: "left" | "center" | "right";
|
|
181
|
+
}
|
|
182
|
+
interface UrlSetting extends BaseSettingSchema {
|
|
183
|
+
type: "url";
|
|
184
|
+
default?: string;
|
|
185
|
+
}
|
|
186
|
+
interface VideoSetting extends BaseSettingSchema {
|
|
187
|
+
type: "video";
|
|
188
|
+
}
|
|
189
|
+
interface VideoUrlSetting extends BaseSettingSchema {
|
|
190
|
+
type: "video_url";
|
|
191
|
+
accept: ("youtube" | "vimeo")[];
|
|
192
|
+
placeholder?: string;
|
|
193
|
+
}
|
|
194
|
+
interface HeaderSetting {
|
|
195
|
+
type: "header";
|
|
196
|
+
content: string;
|
|
197
|
+
info?: string;
|
|
198
|
+
}
|
|
199
|
+
interface ParagraphSetting {
|
|
200
|
+
type: "paragraph";
|
|
201
|
+
content: string;
|
|
202
|
+
}
|
|
203
|
+
interface LineBreakSetting {
|
|
204
|
+
type: "line_break";
|
|
205
|
+
}
|
|
206
|
+
type SettingType = InputSettingSchema["type"];
|
|
207
|
+
type InputSettingSchema = CheckboxSetting | NumberSetting | RadioSetting | RangeSetting | SelectSetting | TextSetting | TextareaSetting | ArticleSetting | ArticleListSetting | BlogSetting | CollectionSetting | CollectionListSetting | ColorSetting | ColorBackgroundSetting | ColorSchemeSetting | ColorSchemeGroupSetting | FontPickerSetting | HtmlSetting | ImagePickerSetting | InlineRichtextSetting | LinkListSetting | LiquidSetting | MetaobjectSetting | MetaobjectListSetting | PageSetting | ProductSetting | ProductListSetting | RichtextSetting | TextAlignmentSetting | UrlSetting | VideoSetting | VideoUrlSetting;
|
|
208
|
+
type SidebarSetting = HeaderSetting | ParagraphSetting | LineBreakSetting;
|
|
209
|
+
type SettingSchema = InputSettingSchema | SidebarSetting;
|
|
210
|
+
/** @deprecated Use {@link SettingSchema} instead */
|
|
211
|
+
type SchemaSetting = SettingSchema;
|
|
212
|
+
interface ShopifyMeta {
|
|
213
|
+
type?: ShopifyBlockType;
|
|
214
|
+
name: string;
|
|
215
|
+
tag?: string;
|
|
216
|
+
class?: string;
|
|
217
|
+
limit?: number;
|
|
218
|
+
params?: string[];
|
|
219
|
+
settings?: SettingSchema[];
|
|
220
|
+
blocks?: {
|
|
221
|
+
type: string;
|
|
222
|
+
name?: string;
|
|
223
|
+
settings?: SettingSchema[];
|
|
224
|
+
}[];
|
|
225
|
+
max_blocks?: number;
|
|
226
|
+
presets?: PresetDefinition[];
|
|
227
|
+
enabled_on?: Record<string, string>[];
|
|
228
|
+
disabled_on?: Record<string, string>[];
|
|
229
|
+
templates?: string[];
|
|
230
|
+
}
|
|
231
|
+
interface PresetDefinition {
|
|
232
|
+
name: string;
|
|
233
|
+
category?: string;
|
|
234
|
+
settings?: InputSettings;
|
|
235
|
+
blocks?: PresetBlock[];
|
|
236
|
+
}
|
|
237
|
+
interface PresetBlock {
|
|
238
|
+
type: string;
|
|
239
|
+
id?: string;
|
|
240
|
+
static?: boolean;
|
|
241
|
+
settings?: InputSettings;
|
|
242
|
+
blocks?: PresetBlock[];
|
|
243
|
+
}
|
|
244
|
+
interface SSGEntry {
|
|
245
|
+
filePath: string;
|
|
246
|
+
componentName: string;
|
|
247
|
+
kebabName: string;
|
|
248
|
+
targetType: ShopifyBlockType;
|
|
249
|
+
meta: Required<Pick<ShopifyMeta, "name">> & ShopifyMeta;
|
|
250
|
+
}
|
|
251
|
+
type ValueForType<T extends string> = T extends "checkbox" ? boolean : T extends "number" | "range" ? number : string;
|
|
252
|
+
type InferSettings<T extends readonly {
|
|
253
|
+
type: string;
|
|
254
|
+
id: string;
|
|
255
|
+
}[]> = {
|
|
256
|
+
[K in T[number] as K["id"]]: ValueForType<K["type"]>;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
declare const vitePluginShopify: (options?: Options) => Plugin[];
|
|
260
|
+
|
|
261
|
+
export { type ArticleListSetting, type ArticleSetting, type BlogSetting, type CheckboxSetting, type CollectionListSetting, type CollectionSetting, type ColorBackgroundSetting, type ColorSchemeGroupSetting, type ColorSchemeRole, type ColorSchemeSetting, type ColorSetting, type FontPickerSetting, type HeaderSetting, type HtmlSetting, type ImagePickerSetting, type ImportMapOptions, type InferSettings, type InlineRichtextSetting, type InputSettingSchema, type InputSettings, type LineBreakSetting, type LinkListSetting, type LiquidSetting, type MetaobjectListSetting, type MetaobjectSetting, type NumberSetting, type Options, type PageSetting, type ParagraphSetting, type PresetBlock, type PresetDefinition, type ProductListSetting, type ProductSetting, type RadioSetting, type RangeSetting, type RichtextSetting, type SSGEntry, type SSGOptions, type SchemaSetting, type SelectSetting, type SettingSchema, type SettingType, type SettingValue, type ShopifyBlockType, type ShopifyMeta, type SidebarSetting, type TextAlignmentSetting, type TextSetting, type TextareaSetting, type UrlSetting, type VideoSetting, type VideoUrlSetting, vitePluginShopify as default };
|