mod-build 4.0.0-alpha.19f → 4.0.0-alpha.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mod-build",
3
- "version": "4.0.0-alpha.19f",
3
+ "version": "4.0.0-alpha.20",
4
4
  "description": "Share components for S3 sites.",
5
5
  "type": "module",
6
6
  "scripts": {
package/siteconfig.js CHANGED
@@ -1,3 +1,23 @@
1
- export const siteData = () => {
2
- return {};
3
- };
1
+ /**
2
+ * Site-specific information that can be used
3
+ * inside HTML template using Handlebars
4
+ */
5
+ export let siteData = () => {
6
+ return {
7
+ primary_trade: 'Home Warranty',
8
+ service: 'home_warranty',
9
+ gtm_container_ID: 'GTM-PZGPJR6',
10
+ qs_gtm_container_ID: 'GTM-PZGPJR6',
11
+ email: 'support@bestcompany.com',
12
+ email_unsub: 'unsubscribe@bestcompany.com',
13
+ domain: 'bestcompany.com',
14
+ company_name: 'BestCompany',
15
+ website_name: 'BestCompany.com',
16
+ useCDN: true,
17
+ isWhiteLabel: true,
18
+ isQSPage: true,
19
+ useAccessibleConfig: true,
20
+ isVite: true,
21
+ pathSubdirectory: 'src/'
22
+ };
23
+ };
@@ -4,9 +4,10 @@
4
4
  {{ fileInclude 'src/templates/components/head.html'
5
5
  page = this
6
6
  path = 'home'
7
- }}
8
- </head>
7
+ }}
8
+ </head>
9
9
  <body>
10
+ {{ log this }}
10
11
  {{#header}}
11
12
  {{ fileInclude 'src/accessible-components/header/header.html'
12
13
  header = this
@@ -1,5 +1,4 @@
1
1
  import fs from "node:fs";
2
- import merge from "lodash.merge";
3
2
  import { seasons } from "../data/seasons.js";
4
3
  import gulpHandlebarsFileInclude from "gulp-handlebars-file-include";
5
4
 
@@ -0,0 +1,5 @@
1
+ import './google-tag-manager-head.js'
2
+ import './heap-addeventproperties-identify.js'
3
+ import './heap-tracking.js'
4
+ import './heap-vwo.js'
5
+ import './visual-website-optimizer.js'
@@ -0,0 +1,9 @@
1
+ @import "_contact-us.scss";
2
+ @import "_google-address-autocomplete.scss";
3
+ @import "_mixins.scss";
4
+ @import "_modal-pages.scss";
5
+ @import "_modernize-colors.scss";
6
+ @import "_qs-footer.scss";
7
+ @import "_quote-footer-v1.scss";
8
+ @import "_quote-footer-v2.scss";
9
+ @import "_quote-footer-v3.scss";
@@ -1,20 +1,16 @@
1
1
  <!-- an example of the head component for v4.0.0 -->
2
2
  <meta charset="UTF-8" />
3
- <link rel="icon" type="image/svg+xml" href="/{{#if page.headConfig.faviconPath}}{{page.headConfig.faviconPath}}{{else}}favicon.svg"{{/if}} />
3
+ <link rel="icon" type="image/svg+xml" href="{{#if page.headConfig.faviconPath}}{{page.headConfig.faviconPath}}{{else}}favicon.svg"{{/if}} />
4
4
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
5
 
6
- <!-- assets links afterBegin -->
7
- {{#if page.headConfig.useModAnalytics}}
8
- <script src="https://{{this.resourceDomain}}/quote/resources/mod-alytics/modalytics.min.js" {{#if page.headConfig.deferModAnalytics}}defer{{/if}} {{#if page.headConfig.asyncModAnalytics}}async{{/if}}></script>
6
+ {{#if this.page.headConfig.useModAnalytics}}
7
+ <script src="https://{{this.page.nodeEnv}}/quote/resources/mod-alytics/modalytics.min.js" {{#if page.headConfig.deferModAnalytics}}defer{{/if}} {{#if page.headConfig.asyncModAnalytics}}async{{/if}}></script>
9
8
  {{/if}}
10
-
11
- <!-- Include vwo setup -->
12
- {{#xif "this.page.headConfig.vwoSetup.vwoPathArray.indexOf(this.path) > -1" }}
9
+ {{#xif "this.page.headConfig.vwoSetup.vwoPathArray.includes(this.path)" }}
13
10
  <link rel="preconnect" href="https://dev.visualwebsiteoptimizer.com">
14
- <!-- Do not double hit our analytical resources (Heap/Google Analytics) if the page is going to be redirected by a VWO a/b test-->
15
- <script src="{{ resolveAlias '@/scripts/vendor/visual-website-optimizer.js'}}"></script>
11
+ <script type="module" src="../scripts/vendor/visual-website-optimizer.js"></script>
16
12
  {{else}}
17
- <script src="{{ resolveAlias '@/scripts/url-cleaner.js'}}"></script>
13
+ <script type="module" src="../scripts/url-cleaner.js'"></script>
18
14
  {{/xif}}
19
15
 
20
16
  {{#unless page.headConfig.disableRobots}}
@@ -48,13 +44,13 @@
48
44
 
49
45
  <!-- site title -->
50
46
  <title>
51
- {{#if page.headConfig.inverseTitle}}
47
+ {{#if this.headConfig.inverseTitle}}
52
48
  {{#unless page.headConfig.hideTitleCompanyName}}{{company_name}} | {{/unless}}
53
49
  {{#if this.pageTitle}}
54
50
  {{this.pageTitle}}
55
51
  {{else}}
56
52
  {{#if page.headConfig.title}}
57
- {{page.headConfig.title}}
53
+ {{this.headConfig.title}}
58
54
  {{/if}}
59
55
  {{/if}}
60
56
  {{else}}
package/template.js CHANGED
@@ -3,5 +3,599 @@
3
3
  * inside HTML templates using Handlebars
4
4
  */
5
5
  export const templateData = () => {
6
- return {};
6
+ return {
7
+ page: {
8
+ headConfig: {
9
+ hideTitleCompanyName: true,
10
+ title: 'Testttt',
11
+ description: 'test test test',
12
+ keywords: '',
13
+ faviconPath: '/images/favicon.ico',
14
+ inverseTitle: true,
15
+ useDynamicGtm: true,
16
+ useModAnalytics: true,
17
+ disableOgTags: true,
18
+ noBsBaseStyles: true,
19
+ vwoSetup: {
20
+ vwoPathArray: ['none']
21
+ }
22
+ },
23
+ footAssetsConfig: {
24
+ disableJquery: true,
25
+ disableFormJs: true,
26
+ disableExpandCollapse: true,
27
+ includeCallRailJs: true,
28
+ },
29
+ cssThemes: [
30
+ 'best-company',
31
+ 'best-company-default',
32
+ 'best-company-thankyou-sorry'
33
+ ]
34
+ },
35
+ footer: {
36
+ attributes: {
37
+ class: 'footer--best-company',
38
+ data: {
39
+ 'hide-contractor': ''
40
+ }
41
+ }
42
+ },
43
+ header: {
44
+ logo: {
45
+ picture: {
46
+ img: {
47
+ attributes: {
48
+ src: '/src/assets/images/logo/logo.svg',
49
+ alt: 'Company Name'
50
+ }
51
+ }
52
+ }
53
+ },
54
+ callRail: {
55
+ mobileText: '<span class="hidden visible-sm-up">Call&nbsp;</span>(555) 555-5555',
56
+ phoneNumber: '5555555555'
57
+ }
58
+ },
59
+ hero: {
60
+ formTemplateInclude: 'src/templates/_partials/form.html',
61
+ title: {
62
+ text: 'Lorem ipsum dolor sit amet.'
63
+ },
64
+ subtitle: {
65
+ text: ''
66
+ },
67
+ callRail: {
68
+ text: 'or call (555) 555-5555 '
69
+ },
70
+ /* gradient + graphic option: */
71
+ background: {},
72
+ picture: {
73
+ img: {
74
+ attributes: {
75
+ src: '/src/assets/images/hero/hero.png',
76
+ alt: ''
77
+ }
78
+ }
79
+ }
80
+ /* full-width background image option */
81
+ // background: {
82
+ // includeOverlay: true,
83
+ // picture: {
84
+ // img: {
85
+ // attributes: {
86
+ // class: 'hero__background-image',
87
+ // alt: '',
88
+ // src: '/images/hero/hero-background-full.jpg'
89
+ // }
90
+ // }
91
+ // }
92
+ // }
93
+ },
94
+ progressbar: {
95
+ attributes: {
96
+ class: 'text-align-center'
97
+ },
98
+ includeStepCount: true
99
+ },
100
+ steps: {
101
+ template: 'src/accessible-components/steps/steps.html',
102
+ carouselOptions: {
103
+ attributes: {
104
+ id: 'swiperForm',
105
+ class: 'swiper--form swiper--dynamic-step-height',
106
+ role: 'group',
107
+ tabindex: '0',
108
+ aria: {
109
+ label: 'Multi-Step Form',
110
+ describedby: 'steps-description'
111
+ }
112
+ },
113
+ description: 'Use the buttons on each slide (Go, Next, or Back) or click Enter to move throughout the form steps. Use tab to navigate between input fields. On the final step, the form information will be submitted. When your results load, you will be redirected to a new web page.'
114
+ },
115
+ items: [
116
+ {
117
+ attributes: {
118
+ data: {
119
+ 'step-name': 'zip'
120
+ }
121
+ },
122
+ stepContent: {
123
+ title: {
124
+ text: 'What is your zip code?'
125
+ },
126
+ fields: [
127
+ {
128
+ attributes: {
129
+ name: 'zip',
130
+ class: 'form-input--border-bottom-only'
131
+ }
132
+ }
133
+ ],
134
+ button: {
135
+ attributes: {
136
+ class: 'btn--primary'
137
+ },
138
+ text: 'Next Step'
139
+ }
140
+ }
141
+ },
142
+ {
143
+ attributes: {
144
+ data: {
145
+ 'step-name': 'OwnHome'
146
+ }
147
+ },
148
+ stepContent: {
149
+ fields: [
150
+ {
151
+ fieldType: 'radio',
152
+ radioOptionType: 'group',
153
+ attributes: {
154
+ id: 'OwnHome'
155
+ },
156
+ legend: {
157
+ text: 'Do you own or rent your home?'
158
+ },
159
+ options: [
160
+ {
161
+ attributes: {
162
+ name: 'OwnHome',
163
+ id: 'YesOwnHome',
164
+ value: 'Yes',
165
+ data: {
166
+ required: 'nonempty'
167
+ }
168
+ },
169
+ text: 'Own'
170
+ },
171
+ {
172
+ attributes: {
173
+ name: 'OwnHome',
174
+ id: 'NoRentHome',
175
+ value: 'No',
176
+ data: {
177
+ required: 'nonempty'
178
+ }
179
+ },
180
+ text: 'Rent'
181
+ }
182
+ ],
183
+ errorMessage: 'Professionals need this info to generate a quote.'
184
+ }
185
+ ],
186
+ button: {
187
+ attributes: {
188
+ class: 'btn--primary'
189
+ },
190
+ text: 'Next Step'
191
+ }
192
+ }
193
+ },
194
+ {
195
+ attributes: {
196
+ data: {
197
+ 'step-name': 'ElectricBill'
198
+ }
199
+ },
200
+ stepContent: {
201
+ fields: [
202
+ {
203
+ label: {
204
+ attributes: {
205
+ class: 'step__title',
206
+ for: 'ElectricBill'
207
+ },
208
+ text: 'What‘s your monthly electric bill?'
209
+ },
210
+ fieldType: 'select',
211
+ attributes: {
212
+ class: 'select--border-bottom-only',
213
+ name: 'ElectricBill',
214
+ id: 'ElectricBill'
215
+ },
216
+ options: [
217
+ {
218
+ attributes: {
219
+ value: '',
220
+ disabled: ''
221
+ },
222
+ text: 'Please Select'
223
+ },
224
+ {
225
+ attributes: {
226
+ value: '$300+'
227
+ },
228
+ text: '$300+'
229
+ },
230
+ {
231
+ attributes: {
232
+ value: '$200 - $300'
233
+ },
234
+ text: '$200 - $300'
235
+ },
236
+ {
237
+ attributes: {
238
+ value: '$100 - $200',
239
+ selected: ''
240
+ },
241
+ text: '$100 - $200'
242
+ },
243
+ {
244
+ attributes: {
245
+ value: 'Under $100'
246
+ },
247
+ text: 'Under $100'
248
+ }
249
+ ],
250
+ errorMessage: 'Professionals need this info to generate a quote.'
251
+ }
252
+ ],
253
+ button: {
254
+ attributes: {
255
+ class: 'btn--primary'
256
+ },
257
+ text: 'Next Step'
258
+ }
259
+ }
260
+ },
261
+ {
262
+ attributes: {
263
+ data: {
264
+ 'step-name': 'MultipleCheckMarks'
265
+ }
266
+ },
267
+ stepContent: {
268
+ fields: [
269
+ {
270
+ fieldType: 'checkbox-group',
271
+ legend: {
272
+ text: 'What are you most concerned about?',
273
+ disclaimer: 'Check all that apply.'
274
+ },
275
+ options: [
276
+ {
277
+ attributes: {
278
+ name: 'MultipleCheckMarks',
279
+ value: 'Falling',
280
+ data: {
281
+ required: 'nonempty'
282
+ }
283
+ },
284
+ text: 'Falling'
285
+ },
286
+ {
287
+ attributes: {
288
+ name: 'MultipleCheckMarks',
289
+ value: 'Medical Emergency',
290
+ data: {
291
+ required: 'nonempty'
292
+ }
293
+ },
294
+ text: 'Medical Emergency'
295
+ },
296
+ {
297
+ attributes: {
298
+ name: 'MultipleCheckMarks',
299
+ value: 'Allergy Attack',
300
+ data: {
301
+ required: 'nonempty'
302
+ }
303
+ },
304
+ text: 'Allergy Attack'
305
+ },
306
+ {
307
+ attributes: {
308
+ name: 'MultipleCheckMarks',
309
+ value: 'Other',
310
+ data: {
311
+ required: 'nonempty'
312
+ }
313
+ },
314
+ text: 'Other'
315
+ }
316
+ ],
317
+ errorMessage: 'Professionals need this info to generate a quote.'
318
+ }
319
+ ],
320
+ button: {
321
+ attributes: {
322
+ class: 'btn--primary'
323
+ },
324
+ text: 'Next Step'
325
+ }
326
+ }
327
+ },
328
+ {
329
+ attributes: {
330
+ data: {
331
+ 'step-name': 'UtilityProvider'
332
+ }
333
+ },
334
+ stepContent: {
335
+ fields: [
336
+ {
337
+ fieldType: 'select',
338
+ label: {
339
+ attributes: {
340
+ class: 'step__title',
341
+ for: 'UtilityProvider'
342
+ },
343
+ text: 'Who is your current utility provider?'
344
+ },
345
+ attributes: {
346
+ class: 'select--border-bottom-only',
347
+ name: 'UtilityProvider',
348
+ id: 'UtilityProvider'
349
+ },
350
+ options: [
351
+ {
352
+ text: 'Other',
353
+ value: 'Other'
354
+ }
355
+ ]
356
+ }
357
+ ],
358
+ button: {
359
+ attributes: {
360
+ class: 'btn--primary'
361
+ },
362
+ text: 'Next Step'
363
+ }
364
+ }
365
+ },
366
+ {
367
+ attributes: {
368
+ class: 'step--last',
369
+ data: {
370
+ 'step-name': 'personalInfo'
371
+ }
372
+ },
373
+ stepContent: {
374
+ fields: [
375
+ {
376
+ formGroup: {
377
+ attributes: {
378
+ class: 'form-group--flex-50'
379
+ }
380
+ },
381
+ attributes: {
382
+ name: 'firstName',
383
+ class: 'form-input--border-bottom-only'
384
+ }
385
+ },
386
+ {
387
+ formGroup: {
388
+ attributes: {
389
+ class: 'form-group--flex-50'
390
+ }
391
+ },
392
+ attributes: {
393
+ name: 'lastName',
394
+ class: 'form-input--border-bottom-only'
395
+ }
396
+ },
397
+ {
398
+ attributes: {
399
+ name: 'email',
400
+ class: 'form-input--border-bottom-only'
401
+ }
402
+ },
403
+ {
404
+ attributes: {
405
+ name: 'homePhone',
406
+ class: 'form-input--border-bottom-only'
407
+ }
408
+ },
409
+ {
410
+ attributes: {
411
+ name: 'address',
412
+ class: 'form-input--border-bottom-only'
413
+ },
414
+ labelInInput: 'Street Address'
415
+ },
416
+ {
417
+ formGroup: {
418
+ attributes: {
419
+ class: 'form-group--flex-33'
420
+ }
421
+ },
422
+ fieldType: 'input',
423
+ attributes: {
424
+ class: 'form-input--border-bottom-only',
425
+ name: 'visualCity',
426
+ disabled: '',
427
+ value: ''
428
+ },
429
+ labelInInput: 'City'
430
+ },
431
+ {
432
+ formGroup: {
433
+ attributes: {
434
+ class: 'form-group--flex-33'
435
+ }
436
+ },
437
+ fieldType: 'input',
438
+ attributes: {
439
+ class: 'form-input--border-bottom-only',
440
+ name: 'visualState',
441
+ disabled: '',
442
+ value: ''
443
+ },
444
+ labelInInput: 'State'
445
+ },
446
+ {
447
+ formGroup: {
448
+ attributes: {
449
+ class: 'form-group--flex-33'
450
+ }
451
+ },
452
+ attributes: {
453
+ name: 'zip1',
454
+ class: 'form-input--border-bottom-only'
455
+ }
456
+ },
457
+ {
458
+ fieldType: 'input',
459
+ attributes: {
460
+ name: 'city',
461
+ type: 'hidden',
462
+ value: ''
463
+ }
464
+ },
465
+ {
466
+ fieldType: 'input',
467
+ attributes: {
468
+ name: 'state',
469
+ type: 'hidden',
470
+ value: ''
471
+ }
472
+ }
473
+ ],
474
+ tcpa: {
475
+ placement: 'below-cta'
476
+ },
477
+ button: {
478
+ attributes: {
479
+ class: 'btn--primary'
480
+ },
481
+ text: 'Get Quote'
482
+ }
483
+ }
484
+ }
485
+ ]
486
+ },
487
+ featuredBlock: {
488
+ title: {
489
+ attributes: {
490
+ class: 'text-align-center'
491
+ },
492
+ text: 'About [ Company Name ]'
493
+ },
494
+ columns: [
495
+ {
496
+ attributes: {
497
+ class: 'hidden visible-lg-up'
498
+ },
499
+ picture: {
500
+ img: {
501
+ attributes: {
502
+ src: '/src/assets/images/logo/logo.svg',
503
+ alt: '',
504
+ loading: 'lazy'
505
+ }
506
+ }
507
+ },
508
+ button: {
509
+ tag: 'a',
510
+ attributes: {
511
+ class: 'btn--secondary',
512
+ href: 'tel:5555555555'
513
+ },
514
+ text: 'Call (555) 555-5555'
515
+ }
516
+ },
517
+ {
518
+ description: {
519
+ text: 'Vivamus gravida facilisis arcu, eu vestibulum massa molestie eget. Curabitur sollicitudin justo quis dignissim iaculis. Donec venenatis ullamcorper odio, vel placerat sem porttitor at. Maecenas in enim suscipit, elementum est eget, dignissim ipsum. Nam nec orci id enim congue viverra quis eget dui.'
520
+ }
521
+ },
522
+ {
523
+ attributes: {
524
+ class: 'visible-sm-down hidden visible-md'
525
+ },
526
+ picture: {
527
+ img: {
528
+ attributes: {
529
+ src: '/src/assets/images/logo/logo.svg',
530
+ alt: '',
531
+ loading: 'lazy'
532
+ }
533
+ }
534
+ },
535
+ button: {
536
+ tag: 'a',
537
+ attributes: {
538
+ class: 'btn--secondary',
539
+ href: 'tel:5555555555'
540
+ },
541
+ text: 'Call (555) 555-5555'
542
+ }
543
+ }
544
+ ]
545
+ },
546
+ reviews: {
547
+ title: {
548
+ text: 'What People Are Saying'
549
+ },
550
+ items: [
551
+ {
552
+ starRating: '50',
553
+ showRatingNextToAuthor: true,
554
+ reviewText: 'Duis dui odio, eleifend ac mauris cursus, feugiat mollis felis. Praesent sit amet justo pharetra, tristique purus nec, accumsan leo. Donec viverra, nunc in efficitur sagittis, tortor magna venenatis ante, vel vestibulum sem ex sit amet est. Quisque efficitur, purus eget congue porttitor, dui metus egestas erat, eu auctor quam mi ac metus.',
555
+ excludeQuotes: true,
556
+ authorName: 'Lorem Ipsum',
557
+ date: 'Month Day, Year',
558
+ location: 'City, State'
559
+ },
560
+ {
561
+ starRating: '50',
562
+ showRatingNextToAuthor: true,
563
+ reviewText: 'Donec imperdiet vitae arcu vel dictum. Mauris tempus elit nec orci tempus, non egestas odio semper. Duis laoreet venenatis neque eget euismod. Duis dapibus et orci ac facilisis.',
564
+ excludeQuotes: true,
565
+ authorName: 'Lorem Ipsum',
566
+ date: 'Month Day, Year',
567
+ location: 'City, State'
568
+ },
569
+ {
570
+ starRating: '50',
571
+ showRatingNextToAuthor: true,
572
+ reviewText: 'Suspendisse dapibus felis ut diam egestas, ac tristique sapien laoreet. Maecenas pellentesque vel odio vitae egestas. Vestibulum posuere viverra luctus. Ut ornare ut ligula non accumsan. Etiam hendrerit ex sit amet turpis pretium rhoncus sit amet non est.',
573
+ excludeQuotes: true,
574
+ authorName: 'Lorem Ipsum',
575
+ date: 'Month Day, Year',
576
+ location: 'City, State'
577
+ }
578
+ ]
579
+ },
580
+ matched: {
581
+ icon: '/images/icons/tick.svg',
582
+ heading: 'Thank you!',
583
+ subheading: 'A representative will contact you shortly.',
584
+ call: {
585
+ icon: '/images/icons/call.svg',
586
+ text: 'To get help immediately, please call:',
587
+ phone: '5555555555'
588
+ }
589
+ },
590
+ unmatched: {
591
+ icon: '/images/icons/error.svg',
592
+ heading: 'Whoops, something&nbsp;<br class="visible-sm-down">went wrong...',
593
+ subheading: 'A representative will contact you shortly.',
594
+ call: {
595
+ icon: '/images/icons/call.svg',
596
+ text: 'To get help immediately, please call:',
597
+ phone: '5555555555'
598
+ }
599
+ }
600
+ };
7
601
  };
package/vite.config.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import handlebars from '@vituum/vite-plugin-handlebars'
2
2
  import vituum from 'vituum'
3
- import gulpHandlebarsFileInclude from 'gulp-handlebars-file-include'
4
3
  import eslint from 'vite-plugin-eslint'
5
4
  import path from 'node:path'
6
5
  import { defaultSettings } from './src/data/config.js'
@@ -30,15 +29,15 @@ export default defineConfig((config) => ({
30
29
  viteStaticCopy({
31
30
  targets: [
32
31
  {
33
- src: path.resolve(__dirname, './src/resources'),
32
+ src: './src/resources',
34
33
  dest: './'
35
34
  },
36
35
  {
37
- src: path.resolve(__dirname, './src/fonts'),
36
+ src: './src/fonts',
38
37
  dest: './'
39
38
  },
40
39
  {
41
- src: path.resolve(__dirname, './src/videos'),
40
+ src: './src/videos',
42
41
  dest: './'
43
42
  },
44
43
  ],