ts-glitter 21.5.2 → 21.5.4

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.
Files changed (89) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/cms-plugin/account-info.js +79 -67
  4. package/lowcode/cms-plugin/account-info.ts +327 -311
  5. package/lowcode/cms-plugin/information/information-module.ts +3 -1
  6. package/lowcode/cms-plugin/list-header-option.js +1 -0
  7. package/lowcode/cms-plugin/list-header-option.ts +1 -0
  8. package/lowcode/cms-plugin/shopping-information.js +468 -0
  9. package/lowcode/cms-plugin/shopping-information.ts +557 -0
  10. package/lowcode/cms-plugin/shopping-market-shopee.js +283 -231
  11. package/lowcode/cms-plugin/shopping-market-shopee.ts +401 -361
  12. package/lowcode/cms-plugin/shopping-order-manager.js +16 -4
  13. package/lowcode/cms-plugin/shopping-order-manager.ts +18 -3
  14. package/lowcode/glitter-base/global/language.js +4 -1
  15. package/lowcode/glitter-base/global/language.ts +4 -2
  16. package/lowcode/glitter-base/route/shopee.js +48 -11
  17. package/lowcode/glitter-base/route/shopee.ts +119 -80
  18. package/lowcode/glitterBundle/plugins/html-render.js +121 -90
  19. package/lowcode/glitterBundle/plugins/html-render.ts +367 -318
  20. package/lowcode/modules/image-library.js +2 -3
  21. package/lowcode/modules/image-library.ts +21 -7
  22. package/lowcode/public-components/checkout/index.js +90 -41
  23. package/lowcode/public-components/checkout/index.ts +101 -49
  24. package/lowcode/public-components/footer/footer-initial.js +11 -2
  25. package/lowcode/public-components/footer/footer-initial.ts +29 -18
  26. package/lowcode/public-components/headers/header-class.js +47 -35
  27. package/lowcode/public-components/headers/header-class.ts +54 -38
  28. package/lowcode/public-components/headers/sy-02.js +1 -1
  29. package/lowcode/public-components/headers/sy-02.ts +1 -1
  30. package/lowcode/public-components/headers/sy-03.js +1 -1
  31. package/lowcode/public-components/headers/sy-03.ts +1 -1
  32. package/lowcode/public-components/headers/sy-04.js +1 -1
  33. package/lowcode/public-components/headers/sy-04.ts +1 -1
  34. package/lowcode/public-components/headers/sy-05.js +1 -2
  35. package/lowcode/public-components/headers/sy-05.ts +1 -1
  36. package/lowcode/public-components/layout-plugin/social-links-01.js +122 -3
  37. package/lowcode/public-components/layout-plugin/social-links-01.ts +135 -10
  38. package/lowcode/public-components/product/pd-card-01.js +23 -14
  39. package/lowcode/public-components/product/pd-card-01.ts +25 -14
  40. package/lowcode/public-components/product/pd-card-02.js +23 -16
  41. package/lowcode/public-components/product/pd-card-02.ts +25 -16
  42. package/lowcode/public-components/product/pd-card-03.js +25 -16
  43. package/lowcode/public-components/product/pd-card-03.ts +27 -16
  44. package/lowcode/public-components/product/pd-class.js +1 -1
  45. package/lowcode/public-components/product/pd-class.ts +1 -1
  46. package/lowcode/public-components/terms-related/index.js +13 -2
  47. package/lowcode/public-components/terms-related/index.ts +15 -2
  48. package/lowcode/public-components/user-manager/um-class.js +490 -501
  49. package/lowcode/public-components/user-manager/um-class.ts +872 -882
  50. package/lowcode/public-components/user-manager/um-info.js +41 -40
  51. package/lowcode/public-components/user-manager/um-info.ts +54 -56
  52. package/lowcode/public-components/user-manager/um-login.js +10 -13
  53. package/lowcode/public-components/user-manager/um-login.ts +15 -23
  54. package/lowcode/public-components/user-manager/um-orderlist.js +60 -51
  55. package/lowcode/public-components/user-manager/um-orderlist.ts +289 -275
  56. package/lowcode/public-components/user-manager/um-rebate.js +104 -82
  57. package/lowcode/public-components/user-manager/um-rebate.ts +294 -267
  58. package/lowcode/public-components/user-manager/um-receive.js +582 -0
  59. package/lowcode/public-components/user-manager/um-receive.ts +599 -0
  60. package/lowcode/public-components/user-manager/um-wishlist.js +72 -68
  61. package/lowcode/public-components/user-manager/um-wishlist.ts +240 -230
  62. package/package.json +1 -1
  63. package/src/api-public/controllers/shopee.js +17 -0
  64. package/src/api-public/controllers/shopee.js.map +1 -1
  65. package/src/api-public/controllers/shopee.ts +32 -0
  66. package/src/api-public/services/monitor.d.ts +1 -0
  67. package/src/api-public/services/post.js +17 -7
  68. package/src/api-public/services/post.js.map +1 -1
  69. package/src/api-public/services/rebate.js +2 -11
  70. package/src/api-public/services/rebate.js.map +1 -1
  71. package/src/api-public/services/rebate.ts +5 -12
  72. package/src/api-public/services/shopee.d.ts +23 -2
  73. package/src/api-public/services/shopee.js +230 -111
  74. package/src/api-public/services/shopee.js.map +1 -1
  75. package/src/api-public/services/shopee.ts +1012 -838
  76. package/src/api-public/services/user.js +2 -2
  77. package/src/api-public/services/user.js.map +1 -1
  78. package/src/api-public/services/user.ts +3 -3
  79. package/src/index.js +17 -7
  80. package/src/index.js.map +1 -1
  81. package/src/modules/tool.d.ts +4 -4
  82. package/src/modules/tool.js +2 -1
  83. package/src/modules/tool.js.map +1 -1
  84. package/src/services/backend-service.js +17 -7
  85. package/src/services/backend-service.js.map +1 -1
  86. package/src/services/template.d.ts +1 -1
  87. package/src/services/template.js +24 -18
  88. package/src/services/template.js.map +1 -1
  89. package/src/services/template.ts +34 -37
@@ -96,20 +96,25 @@ export class HeaderClass {
96
96
  outline: 0;
97
97
  }
98
98
 
99
- .${classPrefix}-cart-container {
99
+ .${classPrefix}-cart-header {
100
100
  display: flex;
101
+ flex-direction: column;
101
102
  width: 100%;
102
- align-items: center;
103
+ margin-bottom: 12px;
103
104
  padding: 0;
104
- margin-bottom: 18px;
105
105
  padding: 12px;
106
106
  border-bottom: 1px solid #dddddd;
107
+ position: sticky;
108
+ top: 0;
109
+ background-color: #fff;
110
+ z-index: 2;
107
111
  }
108
112
 
109
- .${classPrefix}-cart-title {
110
- letter-spacing: 4px;
111
- font-size: 22px;
112
- font-weight: 700;
113
+ .${classPrefix}-cart-div {
114
+ display: flex;
115
+ align-items: center;
116
+ justify-content: space-between;
117
+ width: 100%;
113
118
  }
114
119
 
115
120
  .${classPrefix}-shipping-title {
@@ -175,20 +180,30 @@ export class HeaderClass {
175
180
  if (vm.loading) {
176
181
  return html ` <div class="w-100 vh-100 bg-white">${this.spinner()}</div>`;
177
182
  }
178
- return html ` <div class="position-relative">
179
- <div class="${classPrefix}-cart-container align-items-center">
180
- <div
181
- class="d-flex align-items-center justify-content-center fs-5 py-3 px-2"
182
- style="cursor:pointer;"
183
- onclick="${gvc.event(() => {
183
+ return html ` <div class="position-relative" style="padding-bottom: 120px;">
184
+ <div class="${classPrefix}-cart-header">
185
+ <div class="${classPrefix}-cart-div">
186
+ <div
187
+ class="d-flex align-items-center justify-content-center fs-5 py-3 px-2"
188
+ style="cursor:pointer;"
189
+ onclick="${gvc.event(() => {
184
190
  gvc.glitter.closeDrawer();
185
191
  })}"
186
- >
187
- <i class="fa-sharp fa-solid fa-angle-left"></i>
192
+ >
193
+ <i class="fa-sharp fa-solid fa-angle-left"></i>
194
+ </div>
195
+ <div class="flex-fill"></div>
196
+ ${goToCheckoutButton(ApiCart.globalCart)}
188
197
  </div>
189
- <div class="${classPrefix}-cart-title">${Language.text('cart')}</div>
190
- <div class="flex-fill"></div>
191
- ${goToCheckoutButton(ApiCart.globalCart)}
198
+ ${(() => {
199
+ if (vm.dataList.length === 0) {
200
+ return '';
201
+ }
202
+ const num = vm.dataList.reduce((sum, item) => sum + item.count * item.price, 0);
203
+ return html `<div class="text-end px-2 py-1 fw-bold">
204
+ ${Language.text('cart_subtotal')} $ ${num.toLocaleString()}
205
+ </div>`;
206
+ })()}
192
207
  </div>
193
208
  ${(() => {
194
209
  if (vm.dataList.length === 0) {
@@ -235,31 +250,28 @@ export class HeaderClass {
235
250
  </div>
236
251
  <div class="d-flex flex-column gap-1 flex-fill">
237
252
  <div class="${classPrefix}-title pe-3">${item.title}</div>
238
- <div class="${classPrefix}-spec ">
253
+ <div class="${classPrefix}-spec">
239
254
  ${(() => {
240
255
  const spec = (() => {
241
- if (item.spec) {
242
- return item.spec.map((dd, index) => {
243
- try {
244
- return (item.specs[index].option.find((d1) => {
245
- return d1.title === dd;
246
- }).language_title[Language.getLanguage()] || dd);
247
- }
248
- catch (e) {
249
- return dd;
250
- }
251
- });
252
- }
253
- else {
256
+ if (!item.spec)
254
257
  return [];
255
- }
258
+ return item.spec.map((dd, index) => {
259
+ try {
260
+ return (item.specs[index].option.find((d1) => {
261
+ return d1.title === dd;
262
+ }).language_title[Language.getLanguage()] || dd);
263
+ }
264
+ catch (e) {
265
+ return dd;
266
+ }
267
+ });
256
268
  })();
257
269
  return spec.join(' / ');
258
270
  })()}
259
271
  </div>
260
272
  <div class="d-flex align-items-center justify-content-between">
261
- <div class="d-flex align-items-center gap-1" style="font-size:14px;">
262
- ${Language.text('quantity')} :<select
273
+ <div class="d-flex align-items-center gap-2" style="font-size: 14px;">
274
+ ${Language.text('quantity')}<select
263
275
  class="${classPrefix}-select"
264
276
  style="width: 100px;"
265
277
  onchange="${gvc.event(e => {
@@ -121,20 +121,25 @@ export class HeaderClass {
121
121
  outline: 0;
122
122
  }
123
123
 
124
- .${classPrefix}-cart-container {
124
+ .${classPrefix}-cart-header {
125
125
  display: flex;
126
+ flex-direction: column;
126
127
  width: 100%;
127
- align-items: center;
128
+ margin-bottom: 12px;
128
129
  padding: 0;
129
- margin-bottom: 18px;
130
130
  padding: 12px;
131
131
  border-bottom: 1px solid #dddddd;
132
+ position: sticky;
133
+ top: 0;
134
+ background-color: #fff;
135
+ z-index: 2;
132
136
  }
133
137
 
134
- .${classPrefix}-cart-title {
135
- letter-spacing: 4px;
136
- font-size: 22px;
137
- font-weight: 700;
138
+ .${classPrefix}-cart-div {
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: space-between;
142
+ width: 100%;
138
143
  }
139
144
 
140
145
  .${classPrefix}-shipping-title {
@@ -203,20 +208,32 @@ export class HeaderClass {
203
208
  if (vm.loading) {
204
209
  return html` <div class="w-100 vh-100 bg-white">${this.spinner()}</div>`;
205
210
  }
206
- return html` <div class="position-relative">
207
- <div class="${classPrefix}-cart-container align-items-center">
208
- <div
209
- class="d-flex align-items-center justify-content-center fs-5 py-3 px-2"
210
- style="cursor:pointer;"
211
- onclick="${gvc.event(() => {
212
- gvc.glitter.closeDrawer();
213
- })}"
214
- >
215
- <i class="fa-sharp fa-solid fa-angle-left"></i>
211
+ return html` <div class="position-relative" style="padding-bottom: 120px;">
212
+ <div class="${classPrefix}-cart-header">
213
+ <div class="${classPrefix}-cart-div">
214
+ <div
215
+ class="d-flex align-items-center justify-content-center fs-5 py-3 px-2"
216
+ style="cursor:pointer;"
217
+ onclick="${gvc.event(() => {
218
+ gvc.glitter.closeDrawer();
219
+ })}"
220
+ >
221
+ <i class="fa-sharp fa-solid fa-angle-left"></i>
222
+ </div>
223
+ <div class="flex-fill"></div>
224
+ ${goToCheckoutButton(ApiCart.globalCart)}
216
225
  </div>
217
- <div class="${classPrefix}-cart-title">${Language.text('cart')}</div>
218
- <div class="flex-fill"></div>
219
- ${goToCheckoutButton(ApiCart.globalCart)}
226
+ ${(() => {
227
+ if (vm.dataList.length === 0) {
228
+ return '';
229
+ }
230
+
231
+ const num = vm.dataList.reduce((sum, item) => sum + item.count * item.price, 0);
232
+
233
+ return html`<div class="text-end px-2 py-1 fw-bold">
234
+ ${Language.text('cart_subtotal')} $ ${num.toLocaleString()}
235
+ </div>`;
236
+ })()}
220
237
  </div>
221
238
  ${(() => {
222
239
  if (vm.dataList.length === 0) {
@@ -263,31 +280,30 @@ export class HeaderClass {
263
280
  </div>
264
281
  <div class="d-flex flex-column gap-1 flex-fill">
265
282
  <div class="${classPrefix}-title pe-3">${item.title}</div>
266
- <div class="${classPrefix}-spec ">
283
+ <div class="${classPrefix}-spec">
267
284
  ${(() => {
268
285
  const spec: any = (() => {
269
- if (item.spec) {
270
- return item.spec.map((dd: string, index: number) => {
271
- try {
272
- return (
273
- (item.specs[index] as any).option.find((d1: any) => {
274
- return d1.title === dd;
275
- }).language_title[Language.getLanguage()] || dd
276
- );
277
- } catch (e) {
278
- return dd;
279
- }
280
- });
281
- } else {
282
- return [];
283
- }
286
+ if (!item.spec) return [];
287
+
288
+ return item.spec.map((dd, index) => {
289
+ try {
290
+ return (
291
+ (item.specs[index] as any).option.find((d1: any) => {
292
+ return d1.title === dd;
293
+ }).language_title[Language.getLanguage()] || dd
294
+ );
295
+ } catch (e) {
296
+ return dd;
297
+ }
298
+ });
284
299
  })();
300
+
285
301
  return spec.join(' / ');
286
302
  })()}
287
303
  </div>
288
304
  <div class="d-flex align-items-center justify-content-between">
289
- <div class="d-flex align-items-center gap-1" style="font-size:14px;">
290
- ${Language.text('quantity')} :<select
305
+ <div class="d-flex align-items-center gap-2" style="font-size: 14px;">
306
+ ${Language.text('quantity')}<select
291
307
  class="${classPrefix}-select"
292
308
  style="width: 100px;"
293
309
  onchange="${gvc.event(e => {
@@ -38,7 +38,7 @@ export class Sy02 {
38
38
  <div class="d-flex align-items-center justify-content-center h-100 w-100 gap-2">
39
39
  <!--手機版選單-->
40
40
  <div
41
- class="${PdClass.isShoppingPage() ? `d-none` : `d-flex d-lg-none`} align-items-center justify-content-center"
41
+ class="d-flex d-lg-none align-items-center justify-content-center"
42
42
  style="width:40px !important;height:40px !important;"
43
43
  onclick="${gvc.event(() => {
44
44
  gvc.glitter.setDrawer(gvc.bindView(() => {
@@ -42,7 +42,7 @@ export class Sy02 {
42
42
  <div class="d-flex align-items-center justify-content-center h-100 w-100 gap-2">
43
43
  <!--手機版選單-->
44
44
  <div
45
- class="${PdClass.isShoppingPage() ? `d-none`:`d-flex d-lg-none`} align-items-center justify-content-center"
45
+ class="d-flex d-lg-none align-items-center justify-content-center"
46
46
  style="width:40px !important;height:40px !important;"
47
47
  onclick="${gvc.event(() => {
48
48
  gvc.glitter.setDrawer(
@@ -38,7 +38,7 @@ export class Sy03 {
38
38
  >
39
39
  <!--手機版選單-->
40
40
  <div
41
- class=" align-items-center justify-content-center ${PdClass.isShoppingPage() ? `d-none` : `d-flex d-lg-none`} "
41
+ class=" align-items-center justify-content-center d-flex d-lg-none "
42
42
  style="width:45px !important;height:40px !important;"
43
43
  onclick="${gvc.event(() => {
44
44
  gvc.glitter.setDrawer(gvc.bindView(() => {
@@ -41,7 +41,7 @@ export class Sy03 {
41
41
  >
42
42
  <!--手機版選單-->
43
43
  <div
44
- class=" align-items-center justify-content-center ${PdClass.isShoppingPage() ? `d-none`:`d-flex d-lg-none`} "
44
+ class=" align-items-center justify-content-center d-flex d-lg-none "
45
45
  style="width:45px !important;height:40px !important;"
46
46
  onclick="${gvc.event(() => {
47
47
  gvc.glitter.setDrawer(
@@ -31,7 +31,7 @@ export class Sy04 {
31
31
  <div class="d-flex align-items-center justify-content-center h-100 gap-2">
32
32
  <!--手機版選單-->
33
33
  <div
34
- class="${PdClass.isShoppingPage() ? `d-none` : `d-flex d-lg-none`} align-items-center justify-content-center"
34
+ class="d-flex d-lg-none align-items-center justify-content-center"
35
35
  style="width:40px !important;height:40px !important;"
36
36
  onclick="${gvc.event(() => {
37
37
  gvc.glitter.setDrawer(gvc.bindView(() => {
@@ -34,7 +34,7 @@ export class Sy04 {
34
34
  <div class="d-flex align-items-center justify-content-center h-100 gap-2">
35
35
  <!--手機版選單-->
36
36
  <div
37
- class="${PdClass.isShoppingPage() ? `d-none`:`d-flex d-lg-none`} align-items-center justify-content-center"
37
+ class="d-flex d-lg-none align-items-center justify-content-center"
38
38
  style="width:40px !important;height:40px !important;"
39
39
  onclick="${gvc.event(() => {
40
40
  gvc.glitter.setDrawer(
@@ -4,7 +4,6 @@ import { LanguageView } from "../public/language-view.js";
4
4
  import { Color } from "../public/color.js";
5
5
  import { HeadInitial } from './head-initial.js';
6
6
  import { HeaderMobile } from './header-mobile.js';
7
- import { PdClass } from '../product/pd-class.js';
8
7
  const html = String.raw;
9
8
  export class Sy05 {
10
9
  static main(gvc, widget, subData) {
@@ -28,7 +27,7 @@ export class Sy05 {
28
27
  <div class="d-flex align-items-center justify-content-center h-100 w-100 gap-2">
29
28
  <!--手機版選單-->
30
29
  <div
31
- class="${PdClass.isShoppingPage() ? `d-none` : `d-flex d-lg-none`} align-items-center justify-content-center"
30
+ class="d-flex d-lg-none align-items-center justify-content-center"
32
31
  style="width:40px !important;height:40px !important;"
33
32
  onclick="${gvc.event(() => {
34
33
  gvc.glitter.setDrawer(gvc.bindView(() => {
@@ -35,7 +35,7 @@ export class Sy05 {
35
35
  <div class="d-flex align-items-center justify-content-center h-100 w-100 gap-2">
36
36
  <!--手機版選單-->
37
37
  <div
38
- class="${PdClass.isShoppingPage() ? `d-none`:`d-flex d-lg-none`} align-items-center justify-content-center"
38
+ class="d-flex d-lg-none align-items-center justify-content-center"
39
39
  style="width:40px !important;height:40px !important;"
40
40
  onclick="${gvc.event(() => {
41
41
  gvc.glitter.setDrawer(
@@ -1,8 +1,127 @@
1
+ const html = String.raw;
2
+ const css = String.raw;
1
3
  export class SocialLinks01 {
2
4
  static main(obj) {
3
- console.log(obj);
4
- console.log(`formData=>`, obj.widget.formData);
5
- return `<div>hello</div>`;
5
+ function scrollToTop() {
6
+ window.scrollTo({
7
+ top: 0,
8
+ behavior: 'smooth',
9
+ });
10
+ }
11
+ const gvc = obj.gvc;
12
+ const vm = {
13
+ id: gvc.glitter.getUUID(),
14
+ };
15
+ const pageData = obj.widget.formData;
16
+ const socialList = pageData.social_list;
17
+ const supportSocial = ['fb', 'ig', 'line'];
18
+ const socialIMG = {
19
+ fb: 'https://d3jnmi1tfjgtti.cloudfront.net/file/252530754/5968764.png',
20
+ ig: 'https://d3jnmi1tfjgtti.cloudfront.net/file/252530754/Instagram_logo_2022.png',
21
+ line: 'https://d3jnmi1tfjgtti.cloudfront.net/file/252530754/LINE_Brand_icon.png',
22
+ other: 'https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/link-solid.svg',
23
+ };
24
+ const gotoTopImg = 'https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/arrow-up-to-line-light.svg';
25
+ gvc.addStyle(css `
26
+ .floating-action-panel {
27
+ position: fixed;
28
+ bottom: 30px;
29
+ right: 30px;
30
+ display: flex;
31
+ flex-direction: column; /* 垂直排列 */
32
+ align-items: center;
33
+ gap: 10px; /* 按鈕間距 */
34
+ z-index: 1000;
35
+ }
36
+
37
+ .social-links {
38
+ display: flex;
39
+ flex-direction: column;
40
+ gap: 8px;
41
+ }
42
+
43
+ .social-link {
44
+ color: #007bff;
45
+ text-decoration: none;
46
+ font-size: 14px;
47
+ }
48
+
49
+ .social-link:hover {
50
+ text-decoration: underline;
51
+ }
52
+
53
+ .social-link:hover {
54
+ text-decoration: underline;
55
+ }
56
+
57
+ .component-circle {
58
+ background-color: transparent;
59
+ border: none;
60
+ padding: 2px;
61
+ cursor: pointer;
62
+ border-radius: 50%;
63
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
64
+ }
65
+
66
+ .component-img {
67
+ width: 40px;
68
+ height: 40px;
69
+ object-fit: contain;
70
+ }
71
+
72
+ .component-circle:hover .component-img {
73
+ opacity: 0.8;
74
+ }
75
+
76
+ .up-to-top.hidden {
77
+ display: none;
78
+ }
79
+ `);
80
+ return gvc.bindView({
81
+ bind: vm.id,
82
+ view: () => {
83
+ return html `
84
+ <div class="floating-action-panel">
85
+ <div class="social-links">
86
+ ${socialList
87
+ .map(socialLink => {
88
+ var _a;
89
+ const imgSrc = supportSocial.includes(socialLink.social_type)
90
+ ? socialIMG[socialLink.social_type]
91
+ : socialIMG.other;
92
+ return html `
93
+ <a href="${socialLink.link}" class="component-circle">
94
+ <img src="${(_a = socialLink.icon) !== null && _a !== void 0 ? _a : imgSrc}" alt="Go to top" class="component-img" />
95
+ </a>
96
+ `;
97
+ })
98
+ .join('')}
99
+ </div>
100
+ <button
101
+ class="component-circle up-to-top hidden"
102
+ onclick="${gvc.event(() => {
103
+ scrollToTop();
104
+ })}"
105
+ >
106
+ <img src="${gotoTopImg}" alt="Go to top" class="component-img" />
107
+ </button>
108
+ </div>
109
+ `;
110
+ }, divCreate: {},
111
+ onInitial: () => {
112
+ window.onscroll = function () {
113
+ const scrollPosition = window.scrollY;
114
+ const threshold = window.innerHeight / 2;
115
+ const panel = document.querySelector('.up-to-top');
116
+ if (scrollPosition >= threshold) {
117
+ panel.classList.remove('hidden');
118
+ }
119
+ else {
120
+ panel.classList.add('hidden');
121
+ }
122
+ };
123
+ }
124
+ });
6
125
  }
7
126
  }
8
127
  window.glitter.setModule(import.meta.url, SocialLinks01);
@@ -1,15 +1,140 @@
1
1
  import { GVC } from '../../glitterBundle/GVController.js';
2
2
 
3
- export class SocialLinks01{
4
- public static main(obj:{
5
- gvc:GVC,
6
- widget:any,
7
- subData:any
8
- }){
9
- console.log(obj)
10
- console.log(`formData=>`,obj.widget.formData)
11
- return `<div>hello</div>`
3
+ interface SocialLink {
4
+ social_type: string;
5
+ link: string;
6
+ icon: string
7
+ }
8
+
9
+ const html = String.raw;
10
+ const css = String.raw;
11
+
12
+ export class SocialLinks01 {
13
+ public static main(obj: { gvc: GVC; widget: any; subData: any }) {
14
+ function scrollToTop() {
15
+ window.scrollTo({
16
+ top: 0,
17
+ behavior: 'smooth',
18
+ });
19
+ }
20
+ const gvc = obj.gvc;
21
+ const vm = {
22
+ id:gvc.glitter.getUUID(),
23
+ };
24
+
25
+ const pageData = obj.widget.formData;
26
+ const socialList: SocialLink[] = pageData.social_list;
27
+ const supportSocial = ['fb', 'ig', 'line'];
28
+ const socialIMG: Record<string, string> = {
29
+ fb: 'https://d3jnmi1tfjgtti.cloudfront.net/file/252530754/5968764.png',
30
+ ig: 'https://d3jnmi1tfjgtti.cloudfront.net/file/252530754/Instagram_logo_2022.png',
31
+ line: 'https://d3jnmi1tfjgtti.cloudfront.net/file/252530754/LINE_Brand_icon.png',
32
+ other: 'https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/link-solid.svg',
33
+ };
34
+ const gotoTopImg = 'https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/arrow-up-to-line-light.svg';
35
+ gvc.addStyle(css`
36
+ .floating-action-panel {
37
+ position: fixed;
38
+ bottom: 30px;
39
+ right: 30px;
40
+ display: flex;
41
+ flex-direction: column; /* 垂直排列 */
42
+ align-items: center;
43
+ gap: 10px; /* 按鈕間距 */
44
+ z-index: 1000;
45
+ }
46
+
47
+ .social-links {
48
+ display: flex;
49
+ flex-direction: column;
50
+ gap: 8px;
51
+ }
52
+
53
+ .social-link {
54
+ color: #007bff;
55
+ text-decoration: none;
56
+ font-size: 14px;
57
+ }
58
+
59
+ .social-link:hover {
60
+ text-decoration: underline;
61
+ }
62
+
63
+ .social-link:hover {
64
+ text-decoration: underline;
65
+ }
66
+
67
+ .component-circle {
68
+ background-color: transparent;
69
+ border: none;
70
+ padding: 2px;
71
+ cursor: pointer;
72
+ border-radius: 50%;
73
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
74
+ }
75
+
76
+ .component-img {
77
+ width: 40px;
78
+ height: 40px;
79
+ object-fit: contain;
80
+ }
81
+
82
+ .component-circle:hover .component-img {
83
+ opacity: 0.8;
84
+ }
85
+
86
+ .up-to-top.hidden {
87
+ display: none;
88
+ }
89
+ `);
90
+ return gvc.bindView({
91
+ bind:vm.id,
92
+ view:()=>{
93
+ return html`
94
+ <div class="floating-action-panel">
95
+ <div class="social-links">
96
+ ${socialList
97
+ .map(socialLink => {
98
+ const imgSrc = supportSocial.includes(socialLink.social_type)
99
+ ? socialIMG[socialLink.social_type]
100
+ : socialIMG.other;
101
+ return html`
102
+ <a href="${socialLink.link}" class="component-circle">
103
+ <img src="${socialLink.icon??imgSrc}" alt="Go to top" class="component-img" />
104
+ </a>
105
+ `;
106
+ })
107
+ .join('')}
108
+ </div>
109
+ <button
110
+ class="component-circle up-to-top hidden"
111
+ onclick="${gvc.event(() => {
112
+ scrollToTop();
113
+ })}"
114
+ >
115
+ <img src="${gotoTopImg}" alt="Go to top" class="component-img" />
116
+ </button>
117
+ </div>
118
+ `;
119
+ },divCreate:{}
120
+ ,onInitial:()=>{
121
+ (window as any).onscroll = function() {
122
+ const scrollPosition = window.scrollY;
123
+
124
+ const threshold = window.innerHeight / 2;
125
+
126
+ const panel = document.querySelector('.up-to-top');
127
+
128
+ if (scrollPosition >= threshold) {
129
+ panel!.classList.remove('hidden');
130
+ } else {
131
+ panel!.classList.add('hidden');
132
+ }
133
+ };
134
+ }
135
+ })
136
+
12
137
  }
13
138
  }
14
139
 
15
- (window as any).glitter.setModule(import.meta.url,SocialLinks01)
140
+ (window as any).glitter.setModule(import.meta.url, SocialLinks01);