@energysage/es-ds-components 3.0.0-alpha.5 → 3.0.0-alpha.7

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 (224) hide show
  1. package/.eslintignore +9 -0
  2. package/.eslintrc.json +3 -0
  3. package/.prettierrc.json +10 -0
  4. package/components/es-accordion-list.vue +112 -0
  5. package/components/es-accordion.vue +7 -0
  6. package/components/es-badge.vue +20 -0
  7. package/components/es-breadcrumbs.vue +43 -30
  8. package/components/es-button.vue +112 -0
  9. package/components/es-card.vue +64 -0
  10. package/components/es-carousel.vue +160 -0
  11. package/components/{b-col.vue → es-col.vue} +11 -11
  12. package/components/es-collapse.vue +40 -36
  13. package/components/es-cta-banner.vue +95 -0
  14. package/components/es-cta-card.vue +60 -0
  15. package/components/es-data-table-simple.vue +73 -0
  16. package/components/es-data-table.vue +126 -0
  17. package/components/es-error-page.vue +120 -0
  18. package/components/es-file-input.vue +331 -0
  19. package/components/es-file-preview-modal.vue +61 -0
  20. package/components/es-footer.vue +163 -0
  21. package/components/es-form-checkbox.vue +40 -0
  22. package/components/es-form-input.vue +130 -0
  23. package/components/es-form-msg.vue +81 -0
  24. package/components/es-form-radio-card.vue +57 -0
  25. package/components/es-form-radio-cards.vue +78 -0
  26. package/components/es-form-textarea.vue +124 -0
  27. package/components/es-form.vue +16 -0
  28. package/components/es-modal.vue +103 -0
  29. package/components/es-nav-bar-account-menu.vue +67 -0
  30. package/components/es-nav-bar-featured-article.vue +60 -0
  31. package/components/es-nav-bar-link.vue +27 -0
  32. package/components/es-nav-bar-product-menu.vue +215 -0
  33. package/components/es-nav-bar-top-level-menu.vue +193 -0
  34. package/components/es-nav-bar-topic-menu.vue +194 -0
  35. package/components/es-nav-bar.vue +396 -0
  36. package/components/es-pagination.vue +66 -0
  37. package/components/es-popover.vue +113 -0
  38. package/components/es-progress-circle.vue +81 -0
  39. package/components/es-progress.vue +36 -0
  40. package/components/es-radio-button-group.vue +53 -0
  41. package/components/es-radio-button.vue +50 -55
  42. package/components/es-rating.vue +120 -0
  43. package/components/es-reviews-io-card-carousel.vue +275 -0
  44. package/components/es-slider.vue +147 -0
  45. package/components/es-spinner.vue +22 -0
  46. package/components/es-support-card.vue +150 -0
  47. package/components/es-support.vue +66 -0
  48. package/components/es-tab.vue +7 -0
  49. package/components/es-tabs.vue +67 -0
  50. package/components/es-verification-code.vue +94 -0
  51. package/components/es-view-more.vue +63 -0
  52. package/components/es-zip-code-form.vue +204 -0
  53. package/components/icon/arrow-clockwise.vue +51 -0
  54. package/components/icon/arrow-counter-clockwise.vue +37 -0
  55. package/components/icon/arrow-cycle.vue +43 -0
  56. package/components/icon/arrow-left.vue +39 -0
  57. package/components/icon/arrow-right.vue +39 -0
  58. package/components/icon/arrow-up.vue +39 -0
  59. package/components/icon/arrow.vue +68 -0
  60. package/components/icon/bank.vue +38 -0
  61. package/components/icon/battery.vue +40 -0
  62. package/components/icon/bell.vue +42 -0
  63. package/components/icon/block.vue +46 -0
  64. package/components/icon/bolt.vue +38 -0
  65. package/components/icon/business.vue +42 -0
  66. package/components/icon/calculator.vue +37 -0
  67. package/components/icon/calendar.vue +46 -0
  68. package/components/icon/cart.vue +46 -0
  69. package/components/icon/chat-add.vue +44 -0
  70. package/components/icon/chat-approve.vue +42 -0
  71. package/components/icon/chat-bubble.vue +40 -0
  72. package/components/icon/chat-dots.vue +42 -0
  73. package/components/icon/check.vue +39 -0
  74. package/components/{icon-chevron-down.vue → icon/chevron-down.vue} +16 -16
  75. package/components/icon/chevron-horizontal.vue +39 -0
  76. package/components/icon/chevron-left.vue +39 -0
  77. package/components/{icon-chevron-right.vue → icon/chevron-right.vue} +16 -16
  78. package/components/icon/chevron-up.vue +39 -0
  79. package/components/icon/circle-alert.vue +46 -0
  80. package/components/icon/circle-check.vue +46 -0
  81. package/components/icon/circle-chevron-down.vue +47 -0
  82. package/components/icon/circle-chevron-left.vue +46 -0
  83. package/components/icon/circle-chevron-right.vue +46 -0
  84. package/components/icon/circle-chevron-up.vue +46 -0
  85. package/components/icon/circle-minus.vue +46 -0
  86. package/components/icon/circle-plus.vue +46 -0
  87. package/components/icon/circle-x.vue +46 -0
  88. package/components/icon/circle.vue +42 -0
  89. package/components/icon/clock.vue +46 -0
  90. package/components/icon/community-solar.vue +37 -0
  91. package/components/icon/companies.vue +43 -0
  92. package/components/icon/contact-us.vue +37 -0
  93. package/components/icon/copy.vue +45 -0
  94. package/components/icon/credit-card.vue +37 -0
  95. package/components/icon/document.vue +45 -0
  96. package/components/icon/electric-vehicle.vue +37 -0
  97. package/components/icon/electricity-circle.vue +39 -0
  98. package/components/icon/envelope.vue +45 -0
  99. package/components/icon/es-leaf.vue +39 -0
  100. package/components/icon/eye.vue +41 -0
  101. package/components/icon/facebook.vue +41 -0
  102. package/components/icon/file-doc.vue +72 -0
  103. package/components/icon/file-docx.vue +72 -0
  104. package/components/icon/file-pdf.vue +72 -0
  105. package/components/icon/flag.vue +37 -0
  106. package/components/icon/folder.vue +41 -0
  107. package/components/icon/gear.vue +37 -0
  108. package/components/icon/gift.vue +37 -0
  109. package/components/icon/hamburger.vue +38 -0
  110. package/components/icon/heart.vue +39 -0
  111. package/components/icon/heat-pump.vue +41 -0
  112. package/components/icon/image.vue +45 -0
  113. package/components/icon/info-blog-post.vue +47 -0
  114. package/components/icon/info.vue +45 -0
  115. package/components/icon/instagram.vue +49 -0
  116. package/components/icon/light-bulb.vue +36 -0
  117. package/components/icon/link-out.vue +38 -0
  118. package/components/icon/linkedin.vue +41 -0
  119. package/components/icon/location.vue +45 -0
  120. package/components/icon/lock-off.vue +45 -0
  121. package/components/icon/lock-on.vue +48 -0
  122. package/components/icon/marketplace.vue +43 -0
  123. package/components/icon/minus.vue +38 -0
  124. package/components/icon/money-bag.vue +37 -0
  125. package/components/icon/money.vue +35 -0
  126. package/components/icon/open-envelope.vue +45 -0
  127. package/components/icon/paper.vue +45 -0
  128. package/components/icon/payback.vue +37 -0
  129. package/components/icon/pencil.vue +45 -0
  130. package/components/icon/person-add.vue +41 -0
  131. package/components/icon/person-check.vue +41 -0
  132. package/components/icon/person-cross.vue +41 -0
  133. package/components/icon/person.vue +41 -0
  134. package/components/icon/phone.vue +41 -0
  135. package/components/icon/play.vue +41 -0
  136. package/components/icon/plus.vue +38 -0
  137. package/components/icon/roof.vue +37 -0
  138. package/components/icon/rooftop-solar.vue +37 -0
  139. package/components/icon/saving.vue +37 -0
  140. package/components/icon/search.vue +43 -0
  141. package/components/icon/settings-horizontal.vue +57 -0
  142. package/components/icon/settings-vertical.vue +57 -0
  143. package/components/icon/shield-with-check.vue +38 -0
  144. package/components/icon/shield.vue +41 -0
  145. package/components/icon/shopping-bag.vue +39 -0
  146. package/components/icon/solar.vue +37 -0
  147. package/components/icon/sound-down.vue +45 -0
  148. package/components/icon/sound-off.vue +41 -0
  149. package/components/icon/sound-on.vue +41 -0
  150. package/components/icon/sound-up.vue +41 -0
  151. package/components/icon/star-empty.vue +38 -0
  152. package/components/icon/star-full.vue +36 -0
  153. package/components/icon/star-half.vue +55 -0
  154. package/components/icon/state-ak.vue +53 -0
  155. package/components/icon/state-al.vue +38 -0
  156. package/components/icon/state-ar.vue +38 -0
  157. package/components/icon/state-az.vue +38 -0
  158. package/components/icon/state-ca.vue +38 -0
  159. package/components/icon/state-co.vue +38 -0
  160. package/components/icon/state-ct.vue +38 -0
  161. package/components/icon/state-dc.vue +52 -0
  162. package/components/icon/state-de.vue +38 -0
  163. package/components/icon/state-fl.vue +38 -0
  164. package/components/icon/state-ga.vue +38 -0
  165. package/components/icon/state-hi.vue +59 -0
  166. package/components/icon/state-ia.vue +38 -0
  167. package/components/icon/state-id.vue +38 -0
  168. package/components/icon/state-il.vue +38 -0
  169. package/components/icon/state-in.vue +38 -0
  170. package/components/icon/state-ks.vue +38 -0
  171. package/components/icon/state-ky.vue +38 -0
  172. package/components/icon/state-la.vue +38 -0
  173. package/components/icon/state-ma.vue +38 -0
  174. package/components/icon/state-md.vue +39 -0
  175. package/components/icon/state-me.vue +38 -0
  176. package/components/icon/state-mi.vue +38 -0
  177. package/components/icon/state-mn.vue +38 -0
  178. package/components/icon/state-mo.vue +38 -0
  179. package/components/icon/state-ms.vue +38 -0
  180. package/components/icon/state-mt.vue +38 -0
  181. package/components/icon/state-nc.vue +38 -0
  182. package/components/icon/state-nd.vue +38 -0
  183. package/components/icon/state-ne.vue +38 -0
  184. package/components/icon/state-nh.vue +38 -0
  185. package/components/icon/state-nj.vue +37 -0
  186. package/components/icon/state-nm.vue +38 -0
  187. package/components/icon/state-nv.vue +38 -0
  188. package/components/icon/state-ny.vue +41 -0
  189. package/components/icon/state-oh.vue +38 -0
  190. package/components/icon/state-ok.vue +38 -0
  191. package/components/icon/state-or.vue +38 -0
  192. package/components/icon/state-pa.vue +38 -0
  193. package/components/icon/state-ri.vue +38 -0
  194. package/components/icon/state-sc.vue +38 -0
  195. package/components/icon/state-sd.vue +38 -0
  196. package/components/icon/state-tn.vue +38 -0
  197. package/components/icon/state-tx.vue +38 -0
  198. package/components/icon/state-ut.vue +38 -0
  199. package/components/icon/state-va.vue +38 -0
  200. package/components/icon/state-vt.vue +38 -0
  201. package/components/icon/state-wa.vue +38 -0
  202. package/components/icon/state-wi.vue +38 -0
  203. package/components/icon/state-wv.vue +38 -0
  204. package/components/icon/state-wy.vue +38 -0
  205. package/components/icon/thumbs-up.vue +39 -0
  206. package/components/icon/trash-can.vue +41 -0
  207. package/components/icon/tree.vue +37 -0
  208. package/components/icon/twitter.vue +43 -0
  209. package/components/icon/upload.vue +41 -0
  210. package/components/icon/verified.vue +40 -0
  211. package/components/icon/video-play.vue +41 -0
  212. package/components/icon/wifi.vue +38 -0
  213. package/components/icon/x.vue +38 -0
  214. package/components/icon/youtube.vue +45 -0
  215. package/composables/forms.ts +124 -0
  216. package/lib-utils/mime-type-finder.js +48 -0
  217. package/nuxt.config.ts +43 -9
  218. package/package.json +29 -6
  219. package/tsconfig.json +2 -2
  220. package/utils/get-es-footer-content.js +90 -0
  221. package/utils/get-es-nav-bar-account-content.js +55 -0
  222. package/utils/get-es-nav-bar-global-content.js +474 -0
  223. /package/components/{b-container.vue → es-container.vue} +0 -0
  224. /package/components/{b-row.vue → es-row.vue} +0 -0
@@ -0,0 +1,194 @@
1
+ <script lang="js">
2
+ export default {
3
+ name: 'EsNavBarTopicMenu',
4
+ props: {
5
+ homeName: {
6
+ type: String,
7
+ required: true,
8
+ },
9
+ homeLink: {
10
+ type: String,
11
+ required: true,
12
+ },
13
+ closeButtonText: {
14
+ type: String,
15
+ required: true,
16
+ },
17
+ items: {
18
+ type: Array,
19
+ required: true,
20
+ },
21
+ link: {
22
+ type: String,
23
+ default: '',
24
+ },
25
+ newTab: {
26
+ type: Boolean,
27
+ default: false,
28
+ },
29
+ name: {
30
+ type: String,
31
+ required: true,
32
+ },
33
+ showItemsOnMobile: {
34
+ type: Boolean,
35
+ default: true,
36
+ },
37
+ subHeading: {
38
+ type: String,
39
+ default: '',
40
+ },
41
+ },
42
+ computed: {
43
+ checkboxId() {
44
+ return `topMenu-${this.name}`;
45
+ },
46
+ },
47
+ };
48
+ </script>
49
+
50
+ <template>
51
+ <li
52
+ class="topic-group border-0 mb-lg-200"
53
+ :class="{ 'nav-item': showItemsOnMobile }">
54
+ <!-- desktop header, if it's a link -->
55
+ <es-nav-bar-link
56
+ v-if="link"
57
+ class="dropdown-item nav-link topic-menu-header d-none d-lg-block font-size-sm mb-lg-50 position-relative px-lg-0 py-lg-50 text-gray"
58
+ :href="link"
59
+ :target="newTab ? '_blank' : null">
60
+ <span class="align-items-center eyebrow d-flex link-name">
61
+ {{ name }}
62
+ <icon-arrow-right
63
+ class="d-none d-lg-inline-block ml-25"
64
+ height="24px"
65
+ width="24px" />
66
+ </span>
67
+ <span
68
+ v-if="subHeading"
69
+ class="d-block link-subheading">
70
+ {{ subHeading }}
71
+ </span>
72
+ </es-nav-bar-link>
73
+ <!-- desktop header, if it's not a link -->
74
+ <p
75
+ v-else
76
+ class="dropdown-toggle topic-menu-header eyebrow align-items-center d-none d-lg-block mb-lg-50 position-relative px-lg-0 py-lg-50">
77
+ <span class="d-block">
78
+ {{ name }}
79
+ </span>
80
+ <span
81
+ v-if="subHeading"
82
+ class="d-block">
83
+ {{ subHeading }}
84
+ </span>
85
+ </p>
86
+ <!-- mobile nav item, tapping which drills down to submenu -->
87
+ <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
88
+ <label
89
+ :for="checkboxId"
90
+ class="dropdown-label nav-item-border-mobile nav-link align-items-center d-lg-none justify-content-between w-100 h-100 font-weight-bold"
91
+ :class="{
92
+ 'd-flex': showItemsOnMobile,
93
+ 'd-none': !showItemsOnMobile,
94
+ }">
95
+ {{ name }}
96
+ <icon-chevron-right
97
+ class="expand-icon"
98
+ style="height: 24px" />
99
+ </label>
100
+ <input
101
+ :id="checkboxId"
102
+ :name="checkboxId"
103
+ type="checkbox"
104
+ class="menu-checkbox" />
105
+ <div class="menu submenu">
106
+ <div class="menu-header">
107
+ <div class="col-3" />
108
+ <div class="col-6 align-self-center text-center py-100">
109
+ <div class="nav-es-logo-mobile align-items-center d-flex">
110
+ <slot name="logo" />
111
+ </div>
112
+ <span class="sr-only">
113
+ {{ homeName }}
114
+ </span>
115
+ </div>
116
+ <div class="d-flex col-3 justify-content-end">
117
+ <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
118
+ <label
119
+ for="data--main-menu"
120
+ class="mb-0">
121
+ <icon-x class="menu-toggle align-self-center" />
122
+ <span class="sr-only">
123
+ {{ closeButtonText }}
124
+ </span>
125
+ </label>
126
+ </div>
127
+ </div>
128
+ <ul
129
+ class="visible-lg list-unstyled"
130
+ style="top: 0">
131
+ <li class="nav-item col-lg-12 d-lg-none mb-50">
132
+ <div class="col-2">
133
+ <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
134
+ <label
135
+ :for="checkboxId"
136
+ class="menu-toggle d-flex w-100 h-100 mb-0 align-items-center font-size-sm">
137
+ <icon-arrow-left
138
+ class="expand-icon"
139
+ style="height: 24px" />
140
+ </label>
141
+ </div>
142
+ <div class="col-8 align-self-center text-center py-100">
143
+ <es-nav-bar-link
144
+ v-if="link"
145
+ class="nav-link font-weight-bold d-flex w-100 h-100 justify-content-center align-items-center"
146
+ :href="link"
147
+ :target="newTab ? '_blank' : null">
148
+ {{ name }}
149
+ </es-nav-bar-link>
150
+ <div
151
+ v-else
152
+ class="h-100">
153
+ <span
154
+ class="nav-item justify-content-center align-items-center d-flex font-weight-boldest h-100 text-decoration-none w-100">
155
+ {{ name }}
156
+ </span>
157
+ </div>
158
+ </div>
159
+ <div class="col-2">&nbsp;</div>
160
+ </li>
161
+ <li
162
+ v-for="item in items"
163
+ :key="item.name">
164
+ <es-nav-bar-link
165
+ class="dropdown-item nav-item nav-item-border-mobile nav-link d-flex align-items-center ml-lg-0 px-lg-0 py-lg-50"
166
+ :class="{ 'font-weight-bold': item.emphasize }"
167
+ :href="item.link"
168
+ :target="item.newTab ? '_blank' : null">
169
+ {{ item.name }}
170
+ </es-nav-bar-link>
171
+ </li>
172
+ </ul>
173
+ </div>
174
+ <!-- mobile link, shown only if we have a link and don't want to show child items on mobile -->
175
+ <es-nav-bar-link
176
+ v-if="link"
177
+ class="nav-item nav-item-menu nav-item-border-mobile nav-link d-lg-none w-100 text-decoration-none"
178
+ :class="{
179
+ 'd-none': showItemsOnMobile,
180
+ 'd-block': !showItemsOnMobile,
181
+ }"
182
+ :href="link"
183
+ :target="newTab ? '_blank' : null">
184
+ <span class="d-block eyebrow link-name">
185
+ {{ name }}
186
+ </span>
187
+ <span
188
+ v-if="subHeading"
189
+ class="d-block font-size-sm link-subheading">
190
+ {{ subHeading }}
191
+ </span>
192
+ </es-nav-bar-link>
193
+ </li>
194
+ </template>
@@ -0,0 +1,396 @@
1
+ <script lang="js">
2
+ export default {
3
+ name: 'EsNavBar',
4
+ props: {
5
+ accountContent: {
6
+ type: Object,
7
+ required: true,
8
+ },
9
+ globalContent: {
10
+ type: Object,
11
+ required: true,
12
+ },
13
+ },
14
+ mounted() {
15
+ // CUSTOM GLOBAL-NAV SCRIPT STARTS
16
+
17
+ // Function to collapse all open menus
18
+ function uncheck_menus() {
19
+ document.querySelectorAll('.menu-checkbox').forEach((element) => {
20
+ const checkbox = element;
21
+ checkbox.checked = false;
22
+ });
23
+ }
24
+
25
+ // Create an overlay to obscure page contents
26
+ const overlay = document.querySelector('.content-overlay');
27
+
28
+ // Function to show/hide overlay
29
+ function show_overlay(overlay_visible) {
30
+ if (overlay_visible) {
31
+ overlay.classList.add('show');
32
+ } else {
33
+ overlay.classList.remove('show');
34
+ }
35
+ }
36
+
37
+ // Show overlay and lock scrolling on body when menu is open
38
+ function show_mobile_menus() {
39
+ show_overlay(true);
40
+ document.body.style.overflow = 'hidden';
41
+ }
42
+
43
+ // Close all submenus, hide overlay, and unlock scrolling when menu is closed
44
+ function collapse_mobile_menus() {
45
+ uncheck_menus();
46
+ show_overlay(false);
47
+ document.body.style.overflow = 'visible';
48
+ }
49
+
50
+ // Create a checkbox used to determine if any mobile menus are open
51
+ const mainMenuCheckbox = document.querySelector('.main-menu-checkbox');
52
+ const accountMenuCheckbox = document.querySelector('.account-menu-checkbox');
53
+
54
+ // Collapse all open menus on window resize
55
+ window.addEventListener('resize', () => {
56
+ if (mainMenuCheckbox.checked || accountMenuCheckbox.checked) {
57
+ collapse_mobile_menus();
58
+ }
59
+ });
60
+
61
+ // Collapse all open menus on overlay click
62
+ overlay.addEventListener('click', () => {
63
+ collapse_mobile_menus();
64
+ });
65
+
66
+ // Show overlay on hovers for desktop only
67
+ document
68
+ .querySelectorAll(
69
+ // eslint-disable-next-line max-len
70
+ '.nav-es-container .nav-item .dropdown-toggle, .nav-es-container .nav-item .dropdown-menu, .nav-es-container .nav-item.has-dropdown',
71
+ )
72
+ .forEach((element) => {
73
+ element.addEventListener('mouseover', () => {
74
+ show_overlay(true);
75
+ });
76
+ element.addEventListener('mouseout', () => {
77
+ // Hide overlay on mouseout on desktop not mobile
78
+ show_overlay(mainMenuCheckbox.checked || accountMenuCheckbox.checked);
79
+ });
80
+ });
81
+
82
+ // Toggle menu display on main menu open/close
83
+ mainMenuCheckbox.addEventListener('change', (event) => {
84
+ if (event.target.checked) {
85
+ show_mobile_menus();
86
+ } else {
87
+ collapse_mobile_menus();
88
+ }
89
+ });
90
+
91
+ // Toggle menu display on account menu open/close
92
+ accountMenuCheckbox.addEventListener('change', (event) => {
93
+ if (event.target.checked) {
94
+ show_mobile_menus();
95
+ } else {
96
+ collapse_mobile_menus();
97
+ }
98
+ });
99
+
100
+ // get logged in/out state and display appropriate menu
101
+ const menuDisplay = ({ loggedOut }) => {
102
+ if (loggedOut) {
103
+ // logged out so allow loggedOut menu and the compare buttons to be visible
104
+ document.querySelectorAll('.nav-es-container .loggedOut').forEach((element) => {
105
+ // eslint-disable-next-line no-param-reassign
106
+ element.style.display = null;
107
+ });
108
+ } else {
109
+ // logged in so allow logged in menu to be visible, and show name with appropriate layout
110
+ document.querySelectorAll('.nav-es-container .loggedIn').forEach((element) => {
111
+ // eslint-disable-next-line no-param-reassign
112
+ element.style.display = null;
113
+ });
114
+ document.querySelector('.nav-es-container .icon-dropdown .dropdown-toggle').style.display = 'flex';
115
+ const selector = '.nav-es-container .icon-dropdown .dropdown-toggle .first-name';
116
+ document.querySelectorAll(selector).forEach((element) => {
117
+ // eslint-disable-next-line no-param-reassign
118
+ element.style.display = 'block';
119
+ });
120
+ }
121
+ };
122
+
123
+ fetch('/api/account-first-name/', {
124
+ headers: { Accept: 'application/json' },
125
+ method: 'GET',
126
+ })
127
+ .then((response) => response.json())
128
+ .then((data) => {
129
+ const name = data?.first_name || null;
130
+ const selector = '.nav-es-container .icon-dropdown .dropdown-toggle .first-name';
131
+ document.querySelectorAll(selector).forEach((element) => {
132
+ // eslint-disable-next-line no-param-reassign
133
+ element.innerHTML = name;
134
+ });
135
+ menuDisplay({ loggedOut: name === null });
136
+ })
137
+ .catch((e) => {
138
+ // eslint-disable-next-line no-console
139
+ console.log('error', e);
140
+ menuDisplay({ loggedOut: true });
141
+ });
142
+
143
+ // closes mobile menus upon navigating 'back' to the site
144
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event
145
+ window.addEventListener('pageshow', () => {
146
+ collapse_mobile_menus();
147
+ });
148
+
149
+ // set up options for sticky nav intersection observer
150
+ const intersectionOptions = {
151
+ rootMargin: '0px',
152
+ threshold: 0.0,
153
+ };
154
+
155
+ // set up callback for sticky nav intersection observer
156
+ const intersectionCallback = (entries) => {
157
+ entries.forEach((entry) => {
158
+ if (entry.isIntersecting) {
159
+ entry.target.classList.remove('scrolled');
160
+ } else {
161
+ entry.target.classList.add('scrolled');
162
+ }
163
+ });
164
+ };
165
+
166
+ // initialize intersection observer to detect when nav scrolls out of viewport
167
+ // https://www.smashingmagazine.com/2021/07/dynamic-header-intersection-observer/
168
+ const observer = new IntersectionObserver(intersectionCallback, intersectionOptions);
169
+ const targetEl = document.querySelector('#nav-main');
170
+ observer.observe(targetEl);
171
+
172
+ // CUSTOM GLOBAL-NAV SCRIPT ENDS
173
+ },
174
+ };
175
+ </script>
176
+
177
+ <template>
178
+ <div
179
+ id="nav-main"
180
+ class="nav-es-container">
181
+ <div class="content-overlay" />
182
+ <nav class="nav-es-global navbar navbar-expand navbar-light py-0 font-size-base">
183
+ <!-- mobile hamburger menu button -->
184
+ <div class="d-flex d-lg-none col-2 px-0">
185
+ <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
186
+ <label
187
+ for="data--main-menu"
188
+ class="mb-0">
189
+ <icon-hamburger class="menu-toggle align-self-center" />
190
+ <span class="sr-only">
191
+ {{ globalContent.mobileNavButtonAltText }}
192
+ </span>
193
+ </label>
194
+ </div>
195
+ <!-- mobile logo -->
196
+ <es-nav-bar-link
197
+ class="d-flex d-lg-none col-8 align-self-center justify-content-center px-0"
198
+ :href="globalContent.home.link">
199
+ <div class="nav-es-logo-mobile align-items-center d-flex">
200
+ <slot name="logo" />
201
+ </div>
202
+ <span class="sr-only">
203
+ {{ globalContent.home.name }}
204
+ </span>
205
+ </es-nav-bar-link>
206
+ <!-- mobile account menu trigger -->
207
+ <div class="d-flex d-lg-none justify-content-end col-2 px-0">
208
+ <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
209
+ <label
210
+ class="mb-0 text-decoration-none"
211
+ for="data--account-menu">
212
+ <icon-person class="align-self-center account-icon" />
213
+ <span class="sr-only">
214
+ {{ accountContent.mobileAccountButtonAltText }}
215
+ </span>
216
+ </label>
217
+ </div>
218
+ <input
219
+ id="data--main-menu"
220
+ class="menu-checkbox main-menu-checkbox"
221
+ aria-labelledby="data--main-menu"
222
+ type="checkbox" />
223
+ <!-- first-level menu on mobile, the whole nav on desktop-->
224
+ <div
225
+ id="navbarNavDropdown"
226
+ class="menu top-level-menu align-items-start d-flex flex-grow-1">
227
+ <!-- mobile menu header -->
228
+ <div class="menu-header d-lg-none d-flex align-items-center justify-content-center h-100 mb-50">
229
+ <div class="col-3" />
230
+ <div class="col-6 align-self-center text-center py-100">
231
+ <div class="nav-es-logo-mobile align-items-center d-flex">
232
+ <slot name="logo" />
233
+ </div>
234
+ </div>
235
+ <div class="d-flex col-3 justify-content-end">
236
+ <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
237
+ <label
238
+ for="data--main-menu"
239
+ class="mb-0">
240
+ <icon-x class="menu-toggle align-self-center" />
241
+ <span class="sr-only">
242
+ {{ globalContent.mobileCloseButtonAltText }}
243
+ </span>
244
+ </label>
245
+ </div>
246
+ </div>
247
+ <div class="navbar-nav d-flex flex-column w-100">
248
+ <!-- top-level items on mobile, full top bar on desktop -->
249
+ <es-container
250
+ class="align-items-start d-flex flex-lg-nowrap justify-content-between top-level-nav">
251
+ <es-nav-bar-link
252
+ class="navbar-brand d-none d-lg-block"
253
+ :href="globalContent.home.link">
254
+ <div class="nav-es-logo-desktop pt-100">
255
+ <slot name="logo" />
256
+ </div>
257
+ <span class="sr-only">
258
+ {{ globalContent.home.name }}
259
+ </span>
260
+ </es-nav-bar-link>
261
+ <!-- top level menus -->
262
+ <es-nav-bar-top-level-menu
263
+ v-for="topLevelMenu in globalContent.topLevelMenus"
264
+ :key="topLevelMenu.name"
265
+ :home-name="globalContent.home.name"
266
+ :home-link="globalContent.home.link"
267
+ :close-button-text="globalContent.mobileCloseButtonAltText"
268
+ :featured-article="topLevelMenu.featuredArticle"
269
+ :icon="topLevelMenu.icon"
270
+ :link="topLevelMenu.link"
271
+ :main-menu-text="globalContent.mainMenuText"
272
+ :name="topLevelMenu.name"
273
+ :sub-heading="topLevelMenu.subHeading"
274
+ :topics="topLevelMenu.topics">
275
+ <template #logo>
276
+ <slot name="logo" />
277
+ </template>
278
+ </es-nav-bar-top-level-menu>
279
+ <!-- desktop account menu -->
280
+ <es-nav-bar-account-menu
281
+ :auth-items="accountContent.loggedIn.items"
282
+ class="d-none d-lg-block pt-100"
283
+ :logged-out="accountContent.loggedOut" />
284
+ </es-container>
285
+ <!-- mobile+desktop product menus -->
286
+ <es-container class="d-flex flex-lg-nowrap justify-content-lg-end product-menu">
287
+ <div class="row">
288
+ <es-nav-bar-product-menu
289
+ v-for="product in globalContent.products"
290
+ :key="product.name"
291
+ :home-name="globalContent.home.name"
292
+ :home-link="globalContent.home.link"
293
+ :close-button-text="globalContent.mobileCloseButtonAltText"
294
+ :featured-article="product.featuredArticle"
295
+ :items="product.items"
296
+ :link="product.link"
297
+ :main-menu-text="globalContent.mainMenuText"
298
+ :new-tab="product.newTab"
299
+ :name="product.name"
300
+ :see-all-text="globalContent.seeAllText"
301
+ :topics="product.topics">
302
+ <template #logo>
303
+ <slot name="logo" />
304
+ </template>
305
+ </es-nav-bar-product-menu>
306
+ </div>
307
+ </es-container>
308
+ </div>
309
+ </div>
310
+ <!-- mobile account menu checkbox -->
311
+ <input
312
+ id="data--account-menu"
313
+ class="menu-checkbox account-menu-checkbox"
314
+ aria-labelledby="data--account-menu"
315
+ type="checkbox" />
316
+ <!-- mobile account menu -->
317
+ <div class="menu top-level-menu align-items-start d-flex d-lg-none flex-grow-1">
318
+ <!-- menu header -->
319
+ <div class="menu-header d-lg-none d-flex align-items-center justify-content-center h-100">
320
+ <div class="col-3" />
321
+ <div class="col-6 align-self-center text-center py-100">
322
+ <div class="nav-es-logo-mobile align-items-center d-flex">
323
+ <slot name="logo" />
324
+ </div>
325
+ </div>
326
+ <div class="d-flex col-3 justify-content-end">
327
+ <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->
328
+ <label
329
+ for="data--account-menu"
330
+ class="mb-0">
331
+ <icon-x class="menu-toggle align-self-center" />
332
+ <span class="sr-only">
333
+ {{ globalContent.mobileCloseButtonAltText }}
334
+ </span>
335
+ </label>
336
+ </div>
337
+ </div>
338
+ <!-- logged in menu -->
339
+ <ul
340
+ class="loggedIn navbar-nav w-100"
341
+ style="display: none">
342
+ <li
343
+ v-for="item in accountContent.loggedIn.items"
344
+ :key="item.name">
345
+ <es-nav-bar-link
346
+ class="dropdown-item nav-item nav-item-border-mobile nav-link align-items-center d-flex px-lg-100 py-lg-50 font-weight-bold"
347
+ :href="item.link">
348
+ {{ item.name }}
349
+ </es-nav-bar-link>
350
+ </li>
351
+ </ul>
352
+ <!-- logged out menu -->
353
+ <ul
354
+ class="loggedOut navbar-nav w-100"
355
+ style="display: none">
356
+ <li>
357
+ <es-button
358
+ :href="accountContent.loggedOut.signIn.link"
359
+ class="m-100 w-100 text-white font-weight-bold">
360
+ {{ accountContent.loggedOut.signIn.name }}
361
+ </es-button>
362
+ </li>
363
+ <li class="d-flex justify-content-center">
364
+ <es-button
365
+ :href="accountContent.loggedOut.createAccount.link"
366
+ :outline="true"
367
+ class="mx-100 w-100 font-weight-bold">
368
+ {{ accountContent.loggedOut.createAccount.name }}
369
+ </es-button>
370
+ </li>
371
+ </ul>
372
+ </div>
373
+ </nav>
374
+ <!-- sticky nav bar -->
375
+ <nav class="nav-es-sticky bg-white d-none d-lg-block position-fixed py-25">
376
+ <es-container class="align-items-center d-flex justify-content-between">
377
+ <!-- EnergySage logo -->
378
+ <es-nav-bar-link
379
+ class="navbar-brand d-none d-lg-block"
380
+ :href="globalContent.home.link">
381
+ <div class="nav-es-logo-desktop-sticky">
382
+ <slot name="logo" />
383
+ </div>
384
+ <span class="sr-only">
385
+ {{ globalContent.home.name }}
386
+ </span>
387
+ </es-nav-bar-link>
388
+ <!-- desktop account menu -->
389
+ <es-nav-bar-account-menu
390
+ :auth-items="accountContent.loggedIn.items"
391
+ class="d-none d-lg-block"
392
+ :logged-out="accountContent.loggedOut" />
393
+ </es-container>
394
+ </nav>
395
+ </div>
396
+ </template>
@@ -0,0 +1,66 @@
1
+ <script setup lang="ts">
2
+ import Paginator from 'primevue/paginator';
3
+
4
+ const props = defineProps({
5
+ totalRows: {
6
+ type: Number,
7
+ required: true,
8
+ },
9
+ perPage: {
10
+ type: Number,
11
+ required: true,
12
+ },
13
+ listId: {
14
+ type: String,
15
+ required: true,
16
+ },
17
+ align: {
18
+ type: String,
19
+ default: 'left',
20
+ },
21
+ });
22
+
23
+ const model = defineModel<number>();
24
+ const first = ref();
25
+
26
+ watch(model, (newVal) => {
27
+ first.value = (newVal - 1) * props.perPage;
28
+ });
29
+
30
+ const updatePage = (newFirst: number) => {
31
+ model.value = newFirst / props.perPage + 1;
32
+ };
33
+
34
+ const passThrough = {
35
+ root: {
36
+ class: [
37
+ 'pagination',
38
+ { 'justify-content-center': props.align === 'center', 'justify-content-end': props.align === 'right' },
39
+ ],
40
+ },
41
+ firstPageButton: { class: 'paginator-button' },
42
+ previousPageButton: { class: 'paginator-button' },
43
+ nextPageButton: { class: 'paginator-button' },
44
+ lastPageButton: { class: 'paginator-button' },
45
+ current: { class: 'px-100 current-page-report' },
46
+ };
47
+ </script>
48
+
49
+ <template>
50
+ <paginator
51
+ v-model:first="first"
52
+ :rows="perPage"
53
+ :total-records="totalRows"
54
+ template="FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink"
55
+ current-page-report-template="{currentPage} of {totalPages}"
56
+ :aria-controls="listId"
57
+ :pt="passThrough"
58
+ @update:first="updatePage">
59
+ <template #prevpagelinkicon>
60
+ <icon-chevron-left />
61
+ </template>
62
+ <template #nextpagelinkicon>
63
+ <icon-chevron-right />
64
+ </template>
65
+ </paginator>
66
+ </template>