@energysage/es-ds-components 3.0.0-alpha.14 → 3.0.0-alpha.16

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.
@@ -14,8 +14,7 @@ const props = withDefaults(defineProps<Props>(), {
14
14
  variant: 'default',
15
15
  });
16
16
 
17
- // eslint-disable-next-line vue/require-prop-types
18
- const model = defineModel();
17
+ const model = defineModel<string>();
19
18
 
20
19
  // get the list of elements provided as children to the default slot
21
20
  const initialChildren = useSlots().default?.() || [];
@@ -29,7 +28,9 @@ initialChildren.forEach((child) => {
29
28
  }
30
29
  });
31
30
 
32
- const activeIndex = ref();
31
+ type ActiveChildren = null | number | number[];
32
+
33
+ const activeIndex: Ref<ActiveChildren> = ref(null);
33
34
 
34
35
  watch(model, (newVal) => {
35
36
  if (newVal) {
@@ -39,19 +40,30 @@ watch(model, (newVal) => {
39
40
 
40
41
  const accordionTabs = children.map((child, index) => {
41
42
  if (child.props.id === props.initialExpandedId || child.props.id === model.value) {
42
- activeIndex.value = index;
43
+ if (props.allowMultipleExpand) {
44
+ activeIndex.value = [index];
45
+ } else {
46
+ activeIndex.value = index;
47
+ }
43
48
  }
44
49
  return child.children;
45
50
  });
46
51
 
47
- const updateActiveIndex = (index: any) => {
52
+ const updateActiveIndex = (index: ActiveChildren) => {
48
53
  if (model.value) {
49
- model.value = children[index]?.props.id || '';
54
+ if (typeof index === 'number') {
55
+ model.value = children[index]?.props.id || '';
56
+ } else if (index === null) {
57
+ model.value = '';
58
+ }
59
+ // There's another case where index will be an array. In that case, v-model is unsupported as specified
60
+ // in the documentation, so no update is made
50
61
  }
51
62
  };
52
63
  </script>
53
64
 
54
65
  <template>
66
+ <!-- @vue-expect-error PrimeVue's type information is wrong -->
55
67
  <accordion
56
68
  :multiple="allowMultipleExpand"
57
69
  :active-index="activeIndex"
@@ -4,7 +4,6 @@
4
4
  - circular has quirky behavior when numVisible doesn't match numScroll
5
5
  - you can see this in the circular autoplay example
6
6
  - i'm not sure if this is fixable
7
- - figure out peek behavior
8
7
  - prop to position the arrows at the bottom two corners of a full-width slide, like homepage
9
8
  */
10
9
 
@@ -35,6 +34,8 @@ interface IProps {
35
34
  items: Array<any>;
36
35
  numScroll?: number;
37
36
  numVisible?: number;
37
+ peekDesktop?: string;
38
+ peekMobile?: string;
38
39
  showArrows?: boolean;
39
40
  showDots?: boolean;
40
41
  slideGap?: number;
@@ -50,6 +51,8 @@ const props = withDefaults(defineProps<IProps>(), {
50
51
  items: () => [],
51
52
  numScroll: 1,
52
53
  numVisible: 1,
54
+ peekDesktop: '',
55
+ peekMobile: '',
53
56
  showArrows: true,
54
57
  showDots: true,
55
58
  slideGap: 16,
@@ -114,22 +117,34 @@ const dotsMarginTop = computed(() => `${props.controlGap / BASE_FONT_SIZE}rem`);
114
117
 
115
118
  // the number of dots visible at each breakpoint
116
119
  const numDotsXs = computed(() =>
117
- props.showDots ? Math.ceil(props.items.length / numVisibleXs.value) : ARROW_SPACING_WHEN_NO_DOTS,
120
+ props.showDots
121
+ ? Math.ceil((props.items.length - numVisibleXs.value) / numScrollXs.value) + 1
122
+ : ARROW_SPACING_WHEN_NO_DOTS,
118
123
  );
119
124
  const numDotsSm = computed(() =>
120
- props.showDots ? Math.ceil(props.items.length / numVisibleSm.value) : ARROW_SPACING_WHEN_NO_DOTS,
125
+ props.showDots
126
+ ? Math.ceil((props.items.length - numVisibleSm.value) / numScrollSm.value) + 1
127
+ : ARROW_SPACING_WHEN_NO_DOTS,
121
128
  );
122
129
  const numDotsMd = computed(() =>
123
- props.showDots ? Math.ceil(props.items.length / numVisibleMd.value) : ARROW_SPACING_WHEN_NO_DOTS,
130
+ props.showDots
131
+ ? Math.ceil((props.items.length - numVisibleMd.value) / numScrollMd.value) + 1
132
+ : ARROW_SPACING_WHEN_NO_DOTS,
124
133
  );
125
134
  const numDotsLg = computed(() =>
126
- props.showDots ? Math.ceil(props.items.length / numVisibleLg.value) : ARROW_SPACING_WHEN_NO_DOTS,
135
+ props.showDots
136
+ ? Math.ceil((props.items.length - numVisibleLg.value) / numScrollLg.value) + 1
137
+ : ARROW_SPACING_WHEN_NO_DOTS,
127
138
  );
128
139
  const numDotsXl = computed(() =>
129
- props.showDots ? Math.ceil(props.items.length / numVisibleXl.value) : ARROW_SPACING_WHEN_NO_DOTS,
140
+ props.showDots
141
+ ? Math.ceil((props.items.length - numVisibleXl.value) / numScrollXl.value) + 1
142
+ : ARROW_SPACING_WHEN_NO_DOTS,
130
143
  );
131
144
  const numDotsXxl = computed(() =>
132
- props.showDots ? Math.ceil(props.items.length / numVisibleXxl.value) : ARROW_SPACING_WHEN_NO_DOTS,
145
+ props.showDots
146
+ ? Math.ceil((props.items.length - numVisibleXxl.value) / numScrollXxl.value) + 1
147
+ : ARROW_SPACING_WHEN_NO_DOTS,
133
148
  );
134
149
 
135
150
  // calculate the arrow position from center based on the number of dots
@@ -292,7 +307,13 @@ onMounted(() => {
292
307
  class: 'd-block',
293
308
  },
294
309
  itemsContent: {
295
- class: 'w-100 overflow-hidden',
310
+ class: [
311
+ 'w-100 overflow-hidden',
312
+ {
313
+ 'es-carousel-peek-desktop': peekDesktop,
314
+ 'es-carousel-peek-mobile': peekMobile,
315
+ },
316
+ ],
296
317
  },
297
318
  itemsContainer: {
298
319
  class: 'd-flex',
@@ -372,6 +393,18 @@ $num-dots-supported: 8;
372
393
  :deep(.es-carousel-container) {
373
394
  margin-left: v-bind(negativeMargin);
374
395
  margin-right: v-bind(negativeMargin);
396
+
397
+ > div.es-carousel-peek-desktop {
398
+ @include breakpoints.media-breakpoint-up(lg) {
399
+ padding-right: v-bind(peekDesktop);
400
+ }
401
+ }
402
+
403
+ > div.es-carousel-peek-mobile {
404
+ @include breakpoints.media-breakpoint-down(sm) {
405
+ padding-right: v-bind(peekMobile);
406
+ }
407
+ }
375
408
  }
376
409
 
377
410
  /* card sizing, based on num visible at each breakpoint */
@@ -25,6 +25,27 @@ export default {
25
25
  return this.content.copyrightText.replace('{currentYear}', new Date().getFullYear());
26
26
  },
27
27
  },
28
+ mounted() {
29
+ // TODO: update with GTM tag in prod once we've gone live
30
+ // See https://tagmanager.google.com/#/container/accounts/2920232696/containers/8806152/workspaces/126/tags
31
+ // for GTM script that triggers this event.
32
+ window.addEventListener('OneTrustLoadedCb', () => {
33
+ (window as any).OneTrust.OnConsentChanged(() => {
34
+ // OneTrust modal should modify cookie values, a hard-refresh will
35
+ // trigger re-loading GTM with updated cookie values, which in turn
36
+ // will only fire tags aligned with new preferences
37
+ window.location.reload();
38
+ return false;
39
+ });
40
+ document.querySelectorAll('.toggle-info-display').forEach((elem) => {
41
+ // Function closure to ensure event only fires on one elem
42
+ elem.addEventListener('click', (e) => {
43
+ e.stopImmediatePropagation();
44
+ (window as any).OneTrust.ToggleInfoDisplay();
45
+ });
46
+ });
47
+ });
48
+ },
28
49
  };
29
50
  </script>
30
51
 
@@ -120,16 +141,26 @@ export default {
120
141
  <!-- Trademark Info -->
121
142
  <!-- Legal -->
122
143
  <hr class="border-top border-blue-500 m-0" />
123
- <div class="row justify-content-center pt-100">
144
+ <div class="row pt-100">
124
145
  <div
125
146
  v-for="link in content.legalLinks"
126
147
  :key="link.text"
127
- class="col col-6 col-lg-auto font-size-75 font-weight-semibold font-size-md-50 font-weight-md-normal mt-25 mb-50 px-lg-300">
148
+ class="col col-6 col-lg-auto">
128
149
  <es-nav-bar-link
150
+ v-if="link.url"
129
151
  :href="link.url"
130
- class="text-reset font-weight-normal">
152
+ class="text-reset font-weight-normal font-size-75 font-size-md-50 font-weight-md-normal mt-25 mb-50 pr-lg-300">
131
153
  {{ link.text }}
132
154
  </es-nav-bar-link>
155
+ <div v-else>
156
+ <icon-ccpa-opt-out />
157
+ <es-button
158
+ inline
159
+ class="toggle-info-display text-reset font-weight-normal font-size-75 font-size-md-50 font-weight-md-normal ml-1"
160
+ variant="link">
161
+ {{ link.text }}
162
+ </es-button>
163
+ </div>
133
164
  </div>
134
165
  </div>
135
166
  <!-- Legal -->
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ export default {
3
+ name: 'IconCcpaOptOut',
4
+ props: {
5
+ /**
6
+ * Width
7
+ */
8
+ width: {
9
+ type: String,
10
+ default: '30px',
11
+ required: false,
12
+ },
13
+ /**
14
+ * Height
15
+ */
16
+ height: {
17
+ type: String,
18
+ default: '14px',
19
+ required: false,
20
+ },
21
+ },
22
+ };
23
+ </script>
24
+
25
+ <template>
26
+ <svg
27
+ xmlns="http://www.w3.org/2000/svg"
28
+ xml:space="preserve"
29
+ id="Layer_1"
30
+ :style="{
31
+ height: height,
32
+ width: width,
33
+ }"
34
+ aria-label="California Consumer Privacy Act (CCPA) Opt-Out Icon"
35
+ role="img"
36
+ x="0"
37
+ y="0"
38
+ version="1.1"
39
+ viewBox="0 0 30 14">
40
+ <g
41
+ id="Final-Copy-2"
42
+ style="display: inline">
43
+ <path
44
+ class="st0"
45
+ d="M7.4,12.8h6.8l3.1-11.6H7.4C4.2,1.2,1.6,3.8,1.6,7S4.2,12.8,7.4,12.8z"
46
+ style="fill: #fff" />
47
+ <path
48
+ id="path2"
49
+ d="M22.6 0H7.4c-3.9 0-7 3.1-7 7s3.1 7 7 7h15.2c3.9 0 7-3.1 7-7s-3.2-7-7-7zm-21 7c0-3.2 2.6-5.8 5.8-5.8h9.9l-3.1 11.6H7.4c-3.2 0-5.8-2.6-5.8-5.8Z"
50
+ style="clip-rule: evenodd; fill: #06f; fill-rule: evenodd" />
51
+ <path
52
+ id="x"
53
+ d="M24.6 4c.2.2.2.6 0 .8L22.5 7l2.2 2.2c.2.2.2.6 0 .8-.2.2-.6.2-.8 0l-2.2-2.2-2.2 2.2c-.2.2-.6.2-.8 0-.2-.2-.2-.6 0-.8L20.8 7l-2.2-2.2c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0l2.2 2.2L23.8 4c.2-.2.6-.2.8 0Z"
54
+ style="fill: #fff" />
55
+ <path
56
+ id="y"
57
+ d="M12.7 4.1c.2.2.3.6.1.8L8.6 9.8c-.1.1-.2.2-.3.2-.2.1-.5.1-.7-.1L5.4 7.7c-.2-.2-.2-.6 0-.8.2-.2.6-.2.8 0L8 8.6l3.8-4.5c.2-.2.6-.2.9 0z"
58
+ style="fill: #06f" />
59
+ </g>
60
+ </svg>
61
+ </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@energysage/es-ds-components",
3
- "version": "3.0.0-alpha.14",
3
+ "version": "3.0.0-alpha.16",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "An EnergySage Vue component library",
@@ -76,6 +76,7 @@ export default (
76
76
  { text: 'Privacy policy', url: `${ES_DOMAIN}/privacy-policy/` },
77
77
  { text: 'Mobile terms of use', url: `${ES_DOMAIN}/mobile-terms-of-use/` },
78
78
  { text: 'Non-discrimination policy', url: `${ES_DOMAIN}/nondiscrimination/` },
79
+ { text: 'Your privacy choices' },
79
80
  ],
80
81
  copyrightText: '© Copyright 2009-{currentYear} EnergySage, Inc. All rights reserved.',
81
82
  trademarkText: `ENERGYSAGE is a registered trademark and the EnergySage logo is a trademark of EnergySage, Inc.