zz-shopify-components 0.12.0 → 0.12.1-beta.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.
@@ -236,6 +236,10 @@ body.zz-dialog-open {
236
236
  background: #FC6C0F;
237
237
  color: #fff;
238
238
  }
239
+ .zz-btn.zz-btn-primary.zz-btn-blue {
240
+ background: #378DDD;
241
+ color: #fff;
242
+ }
239
243
  .zz-btn.zz-btn-primary-round.zz-btn-black {
240
244
  background: #000000;
241
245
  color: #fff;
@@ -261,7 +265,11 @@ body.zz-dialog-open {
261
265
  color: #FC6C0F;
262
266
  border: 1.5px solid #FC6C0F;
263
267
  }
264
-
268
+ .zz-btn.zz-btn-default.zz-btn-blue {
269
+ background: transparent;
270
+ color: #378DDD;
271
+ border: 1.5px solid #378DDD;
272
+ }
265
273
  .zz-btn.zz-btn-round.zz-btn-black {
266
274
  background: transparent;
267
275
  color: #000000;
@@ -281,6 +289,18 @@ body.zz-dialog-open {
281
289
  border-radius: 30px;
282
290
  }
283
291
 
292
+ .zz-btn-link.zz-btn-blue {
293
+ color: #378DDD;
294
+ }
295
+ .zz-btn-link.zz-btn-orange {
296
+ color: #FC6C0F;
297
+ }
298
+ .zz-btn-link.zz-btn-white {
299
+ color: #fff;
300
+ }
301
+ .zz-btn-link.zz-btn-black {
302
+ color: #000000;
303
+ }
284
304
 
285
305
  .zz-btn:hover {
286
306
  opacity: 0.8;
@@ -328,6 +348,9 @@ body.zz-dialog-open {
328
348
  }
329
349
  }
330
350
 
351
+ .zz-btn-shape-round {
352
+ border-radius: 90px;
353
+ }
331
354
  .zz-video {
332
355
  border-radius: inherit;
333
356
  }
@@ -338,7 +361,7 @@ body.zz-dialog-open {
338
361
  display: grid;
339
362
  place-items: center;
340
363
  pointer-events: none; /* 不阻挡点击 */
341
- z-index: 2147483647; /* 最高层 */
364
+ z-index: 9999; /* 最高层 */
342
365
  }
343
366
  .zz-toast-box{
344
367
  pointer-events: auto;
@@ -347,25 +370,29 @@ body.zz-dialog-open {
347
370
  padding: 12px 16px;
348
371
  border-radius: 12px;
349
372
  background: #fff;
350
- color: #b42318; /* 错误红 */
351
- border: 1px solid rgba(180,35,24,.25);
352
- box-shadow: 0 10px 30px rgba(0,0,0,.15);
353
- font: 14px/1.4 -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,'PingFang SC','Hiragino Sans GB','Microsoft Yahei',sans-serif;
354
- text-align: center;
373
+ color: #161110;
374
+ box-shadow: 0px 2px 16px 0px #00000026;
375
+ font-size: 14px;
376
+ text-align: left;
355
377
  word-break: break-word;
356
378
  transform: translateZ(0) scale(.96);
357
379
  opacity: 0;
358
380
  transition: transform .18s ease, opacity .18s ease;
381
+ line-height: 1.2;
382
+ display: inline-flex;
383
+
384
+ }
385
+ .zz-toast-icon {
386
+ margin-right: 4px;
387
+ padding: 0px 2px;
388
+ }
389
+ @media screen and (min-width: 1024px) {
390
+ .zz-toast-msg{
391
+ font-size: 16px;
392
+ }
393
+
359
394
  }
360
395
  .zz-toast-box.show{
361
396
  opacity: 1;
362
397
  transform: translateZ(0) scale(1);
363
398
  }
364
- .zz-toast-title{
365
- display:inline-block;
366
- margin-bottom: 2px;
367
- font-weight: 600;
368
- }
369
- .zz-toast-msg{
370
- display:block;
371
- }
@@ -172,6 +172,47 @@ if (!customElements.get('zz-video-button')) {
172
172
  let toastEl = null;
173
173
  let hideTimer = null;
174
174
 
175
+ const toastIcon = {
176
+ error: `<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
177
+ <g clip-path="url(#clip0_19382_20972)">
178
+ <circle cx="9" cy="9" r="9" fill="#FF4D4F"/>
179
+ <path d="M6.24231 6.17188L11.8992 11.8287" stroke="white" stroke-linecap="round"/>
180
+ <path d="M6.24231 11.8281L11.8992 6.17127" stroke="white" stroke-linecap="round"/>
181
+ </g>
182
+ <defs>
183
+ <clipPath id="clip0_19382_20972">
184
+ <rect width="18" height="18" fill="white"/>
185
+ </clipPath>
186
+ </defs>
187
+ </svg>
188
+ `,
189
+ success: `<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
190
+ <g clip-path="url(#clip0_19382_20921)">
191
+ <circle cx="9" cy="9" r="9" fill="#5BC726"/>
192
+ <path d="M5 9L7.82843 11.8284L12.7782 6.87868" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
193
+ </g>
194
+ <defs>
195
+ <clipPath id="clip0_19382_20921">
196
+ <rect width="18" height="18" fill="white"/>
197
+ </clipPath>
198
+ </defs>
199
+ </svg>
200
+ `,
201
+ warning: `<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
202
+ <g clip-path="url(#clip0_19382_20989)">
203
+ <circle cx="9" cy="9" r="9" fill="#FAAD14"/>
204
+ <path d="M8.99994 5L8.99994 10" stroke="white" stroke-linecap="round"/>
205
+ <circle cx="9.00001" cy="12.8" r="0.8" fill="white"/>
206
+ </g>
207
+ <defs>
208
+ <clipPath id="clip0_19382_20989">
209
+ <rect width="18" height="18" fill="white"/>
210
+ </clipPath>
211
+ </defs>
212
+ </svg>
213
+ `,
214
+ };
215
+
175
216
  function createToast() {
176
217
  const layer = document.createElement('div');
177
218
  layer.className = 'zz-toast-layer';
@@ -182,51 +223,46 @@ if (!customElements.get('zz-video-button')) {
182
223
  box.className = 'zz-toast-box';
183
224
  box.setAttribute('role', 'alert');
184
225
 
185
- // const title = document.createElement('span');
186
- // title.className = 'zz-toast-title';
187
- // title.textContent = '错误';
188
-
189
226
  const msg = document.createElement('span');
190
227
  msg.className = 'zz-toast-msg';
191
228
 
192
- // box.appendChild(title);
229
+ const icon = document.createElement('span');
230
+ icon.className = 'zz-toast-icon';
231
+
232
+ box.appendChild(icon);
193
233
  box.appendChild(msg);
194
234
  layer.appendChild(box);
195
235
  document.body.appendChild(layer);
196
236
 
197
- return { layer, box, msg };
237
+ return { layer, box, msg, icon };
198
238
  }
199
239
 
200
240
  /**
201
241
  * 显示错误 Toast
202
242
  * @param {string} message - 要显示的错误文字
203
- * @param {{duration?:number,title?:string}} [opts]
243
+ * @param {{duration?:number,type?:string}} [opts]
204
244
  */
205
245
  function zzShowToast(message, opts = {}) {
206
-
207
246
  if (!toastEl) {
208
247
  toastEl = createToast();
209
248
  }
210
249
 
211
- // 可选标题(默认“错误”)
212
- if(opts.title) {
213
- toastEl.title.textContent = opts.title;
214
- }
215
-
216
250
  // 更新文本
217
251
  toastEl.msg.textContent = message ?? '';
252
+ if (opts.type) {
253
+ toastEl.icon.innerHTML = toastIcon[opts.type];
254
+ } else {
255
+ toastEl.icon.innerHTML = '';
256
+ }
218
257
 
219
258
  // 重新插入到 body 末尾,保证在最上层
220
259
  document.body.appendChild(toastEl.layer);
221
-
222
260
  // 显示动画
223
261
  requestAnimationFrame(() => {
224
262
  toastEl.box.classList.add('show');
225
263
  });
226
-
227
264
  // 清理上一次的计时器
228
265
  clearTimeout(hideTimer);
229
-
230
266
  const duration = Math.max(500, Number(opts.duration || 2000));
231
267
  hideTimer = setTimeout(() => {
232
268
  toastEl.box.classList.remove('show');
@@ -241,4 +277,3 @@ if (!customElements.get('zz-video-button')) {
241
277
  // 暴露到全局
242
278
  window.zzShowToast = zzShowToast;
243
279
  })();
244
-
@@ -0,0 +1,19 @@
1
+ {% schema %}
2
+ {
3
+ "name": "Snippets Test",
4
+ "settings": [
5
+ ],
6
+ "presets": [
7
+ {
8
+ "name": "Snippets Test"
9
+ }
10
+ ]
11
+ }
12
+ {% endschema %}
13
+
14
+
15
+ <div class="tw-flex tw-flex-col tw-gap-4 tw-justify-center tw-items-center">
16
+
17
+ <button onclick="zzShowToast('test dfis0o dsjoi sjdoi jsod jsdo dsoi', {type: 'error'})">test</button>
18
+ <button onclick="zzShowToast('test dfis0o dsjoi sjdoi jsod jsdo dsoi josd Judson hjds dsjio dsjo dsj aj ewoi sdjo ds ojds sdjo jaso jo aiji')">test</button>
19
+ </div>
@@ -0,0 +1,239 @@
1
+ {% schema %}
2
+ {
3
+ "name": "Button v2",
4
+ "settings": [
5
+ {
6
+ "type": "text",
7
+ "id": "text",
8
+ "label": "按钮文字",
9
+ "default": "按钮"
10
+ },
11
+
12
+ {
13
+ "type": "select",
14
+ "id": "function_type",
15
+ "label": "功能类型",
16
+ "options": [
17
+ {
18
+ "value": "link",
19
+ "label": "链接"
20
+ },
21
+ {
22
+ "value": "link_map",
23
+ "label": "多国家映射"
24
+ },
25
+ ],
26
+ "default": "link"
27
+ },
28
+ {
29
+ "type": "url",
30
+ "id": "url",
31
+ "label": "按钮链接",
32
+ "visible_if": "{{ block.settings.function_type == 'link' }}"
33
+ },
34
+ {
35
+ "type": "textarea",
36
+ "id": "links",
37
+ "label": "Sites Link Map",
38
+ "info": "国家对应链接的表,国家即是国家选择器上显示的字段,国家和路由之间用冒号隔开( 冒号后要加空格)。国家之间换行,“default”为其他未写的默认的链接 EG: Canada: https://hoverair.com/ default: https://hoverair.com/ ",
39
+ "visible_if": "{{ block.settings.function_type == 'link_map' }}"
40
+ },
41
+ {
42
+ "type": "select",
43
+ "id": "type",
44
+ "label": "按钮类型",
45
+ "options": [
46
+ {
47
+ "value": "primary",
48
+ "label": "primary"
49
+ },
50
+ {
51
+ "value": "default",
52
+ "label": "default"
53
+ },
54
+ {
55
+ "value": "link",
56
+ "label": "link"
57
+ },
58
+ ],
59
+ "default": "primary"
60
+ },
61
+ {
62
+ "type": "select",
63
+ "id": "shape",
64
+ "label": "按钮形状",
65
+ "options": [
66
+ {
67
+ "value": "default",
68
+ "label": "default"
69
+ },
70
+ {
71
+ "value": "round",
72
+ "label": "round"
73
+ },
74
+ ],
75
+ "default": "default"
76
+ },
77
+ {
78
+ "type": "select",
79
+ "id": "color",
80
+ "label": "按钮颜色",
81
+ "options": [
82
+ {
83
+ "value": "black",
84
+ "label": "black"
85
+ },
86
+ {
87
+ "value": "white",
88
+ "label": "white"
89
+ },
90
+ {
91
+ "value": "orange",
92
+ "label": "orange"
93
+ },
94
+ {
95
+ "value": "blue",
96
+ "label": "blue"
97
+ }
98
+ ],
99
+ "default": "black",
100
+ },
101
+ {
102
+ "type": "select",
103
+ "id": "size",
104
+ "label": "按钮大小",
105
+ "options": [
106
+ {
107
+ "value": "large",
108
+ "label": "large"
109
+ },
110
+ {
111
+ "value": "medium",
112
+ "label": "medium"
113
+ },
114
+ {
115
+ "value": "small",
116
+ "label": "small"
117
+ }
118
+ ],
119
+ "default": "medium"
120
+ },
121
+ {
122
+ "type": "select",
123
+ "id": "mobile_width",
124
+ "label": "移动端按钮宽度",
125
+ "options": [
126
+ { "value": "full", "label": "全宽" },
127
+ { "value": "auto", "label": "自动" }
128
+ ],
129
+ "default": "auto"
130
+ },
131
+ {
132
+ "type": "select",
133
+ "id": "postfix_icon",
134
+ "label": "后缀图标",
135
+ "options": [
136
+ { "value": "none", "label": "不展示" },
137
+ { "value": "download", "label": "下载" },
138
+ { "value": "arrow-right", "label": "向右箭头" }
139
+ ],
140
+ "default": "none"
141
+ },
142
+ {
143
+ "type": "number",
144
+ "id": "icon_size",
145
+ "label": "图标大小(px)",
146
+ "default": 15
147
+ },
148
+ {
149
+ "type": "number",
150
+ "id": "icon_left_margin",
151
+ "label": "图标左边距(px)",
152
+ "default": 0
153
+ },
154
+ {
155
+ "type": "number",
156
+ "id": "icon_right_margin",
157
+ "label": "图标右边距(px)",
158
+ "default": 0
159
+ },
160
+ {
161
+ "type": "text",
162
+ "id": "btn_id",
163
+ "label": "按钮id属性值",
164
+ },
165
+ {
166
+ "type": "text",
167
+ "id": "modal_id",
168
+ "label": "按钮触发modal的id",
169
+ },
170
+ {
171
+ "type": "text",
172
+ "id": "click_event_class_name",
173
+ "label": "点击事件统计 classname",
174
+ },
175
+ ],
176
+ "presets": [
177
+ {
178
+ "name": "Button v2"
179
+ },
180
+ {
181
+ "name": "按钮 v2"
182
+ }
183
+ ]
184
+ }
185
+ {% endschema %}
186
+
187
+
188
+ {% assign btn_class = 'zz-button' | append: block.id %}
189
+
190
+ <style>
191
+
192
+ {% if block.settings.mobile_width == 'full' %}
193
+ @media (max-width: 1024px) {
194
+ #shopify-block-{{ block.id }} {
195
+ width: 100%;
196
+ box-sizing: border-box;
197
+ }
198
+ }
199
+ {% endif %}
200
+ </style>
201
+
202
+ {% render 'zz-button-v2',
203
+ href: block.settings.url,
204
+ type: block.settings.type,
205
+ color: block.settings.color,
206
+ text: block.settings.text,
207
+ size: block.settings.size,
208
+ postfix_icon: block.settings.postfix_icon,
209
+ icon_size: block.settings.icon_size,
210
+ icon_left_margin: block.settings.icon_left_margin,
211
+ icon_right_margin: block.settings.icon_right_margin,
212
+ width: block.settings.mobile_width,
213
+ shape: block.settings.shape,
214
+ class_name: btn_class,
215
+ btn_id: block.settings.btn_id,
216
+ modal_id: block.settings.modal_id
217
+ %}
218
+
219
+
220
+
221
+ <script>
222
+ document.addEventListener('DOMContentLoaded', (event) => {
223
+ const btn = document.getElementsByClassName('{{ btn_class }}')
224
+ if(btn && btn[0]) {
225
+ btn[0].addEventListener('click', (event) => {
226
+ dataLayer.push({
227
+ event: "{{ block.settings.click_event_class_name }}",
228
+ timestamp: new Date().toISOString(),
229
+ });
230
+ });
231
+ {% if block.settings.function_type == 'link_map' %}
232
+ if(window.bindSiteJump) {
233
+ bindSiteJump(btn[0], {{ block.settings.links | json }})
234
+ }
235
+ {% endif %}
236
+ }
237
+
238
+ })
239
+ </script>
@@ -389,6 +389,10 @@
389
389
  } else {
390
390
  zzShowToast('Please fill in all required fields!');
391
391
  }
392
+ dataLayer.push({
393
+ event: "edu_page_form_submit",
394
+ timestamp: new Date().toISOString(),
395
+ });
392
396
  });
393
397
 
394
398
  // 实时验证
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zz-shopify-components",
3
- "version": "0.12.0",
3
+ "version": "0.12.1-beta.0",
4
4
  "description": "Reusable Shopify components for theme projects",
5
5
  "keywords": [
6
6
  "shopify",
@@ -0,0 +1,77 @@
1
+ {% comment %}
2
+ 按钮配置选项:
3
+ type:按钮类型
4
+ - primary:主要按钮
5
+ - default:默认按钮
6
+ - link:链接按钮
7
+
8
+ shape: 按钮形状
9
+ - default:默认
10
+ - round:圆角
11
+
12
+ color:按钮颜色
13
+ - black:黑色
14
+ - white:白色
15
+ - orange:橙色
16
+
17
+ size:按钮尺寸
18
+ - large:大号
19
+ - medium:中号(默认)
20
+ - small:小号
21
+
22
+ 其他参数:
23
+ - href:链接地址
24
+ - backdrop_filter:毛玻璃效果 true/false
25
+ - icon:图标名称
26
+ - text:按钮文字
27
+ - class_name:自定义类名
28
+ {% endcomment %}
29
+
30
+ {% assign btn_type = type | default: 'primary' %}
31
+ {% assign btn_color = color | default: 'black' %}
32
+ {% assign btn_size = size | default: 'medium' %}
33
+ {% assign icon_size = icon_size | default: 15 %}
34
+ {% assign width = width | default: 'auto' %}
35
+
36
+ <style>
37
+ .zz-btn-icon {
38
+ display: flex;
39
+ }
40
+ </style>
41
+
42
+ {% if href %}
43
+ {% if btn_type == 'link' %}
44
+ <a href="{{ href | default: '#' }}" {% if btn_id != blank %} id="{{ btn_id }}" {% endif %} class="zz-btn-link tw-text-[#378DDD] tw-inline-flex tw-items-center tw-text-[12px] lg:tw-text-[14px] tw-no-underline zz-btn-link-{{ btn_size }} {% if width == 'full' %} tw-w-full {% endif %} {{ class_name }}">
45
+ <span class="zz-btn-text">{{ text }}</span>
46
+ {% if postfix_icon %}<span class="zz-btn-icon" style="margin-left: {{ icon_left_margin }}px; margin-right: {{ icon_right_margin }}px;">
47
+ {% render 'zz-icon', icon_name: postfix_icon, icon_size: icon_size %}
48
+ </span>{% endif %}
49
+ </a>
50
+ {% else %}
51
+ <a
52
+ href="{{ href | default: '#' }}"
53
+ {% if btn_id != blank %} id="{{ btn_id }}" {% endif %}
54
+ class="zz-btn zz-btn-{{ btn_type }} zz-btn-{{ btn_color }} zz-btn-shape-{{ shape }} zz-btn-{{ btn_size }} {% if width == 'full' %} tw-w-full {% endif %} {{ class_name }}"
55
+ {% if backdrop_filter %}
56
+ style="backdrop-filter: blur(12px);background: #FFFFFF0F;"
57
+ {% endif %}
58
+ >
59
+ {% if icon %}<span class="zz-btn-icon">{{ icon }}</span>{% endif %}
60
+ <span class="zz-btn-text">{{ text }}</span>
61
+ </a>
62
+ {% endif %}
63
+
64
+ {% else %}
65
+
66
+ <button
67
+ class="zz-btn zz-btn-{{ btn_type }} zz-btn-{{ btn_color }} zz-btn-shape-{{ shape }} zz-btn-{{ btn_size }} {% if width == 'full' %} tw-w-full {% endif %} {{ width }} {{ class_name }}"
68
+ {% if modal_id != blank %} data-zz-modal-target="#{{ modal_id }}" {% endif %}
69
+ {% if btn_id != blank %} id="{{ btn_id }}" {% endif %}
70
+ {% if backdrop_filter %}
71
+ style="backdrop-filter: blur(12px);background: #FFFFFF0F;"
72
+ {% endif %}
73
+ >
74
+ {% if icon %}<span class="zz-btn-icon">{{ icon }}</span>{% endif %}
75
+ <span class="zz-btn-text">{{ text }}</span>
76
+ </button>
77
+ {% endif %}