@energysage/es-ds-components 3.0.0-alpha.9 → 3.0.1
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/README.md +0 -3
- package/components/es-accordion-list.vue +29 -12
- package/components/es-carousel.vue +524 -69
- package/components/es-col.vue +5 -5
- package/components/es-container.vue +10 -1
- package/components/es-data-table-column.vue +20 -0
- package/components/es-data-table.vue +35 -88
- package/components/es-error-page.vue +33 -24
- package/components/es-footer.vue +32 -3
- package/components/es-segmented-control.vue +237 -0
- package/components/es-tabs.vue +10 -3
- package/components/icon/ccpa-opt-out.vue +61 -0
- package/nuxt.config.ts +6 -0
- package/package.json +2 -2
- package/types/es-carousel.ts +12 -0
- package/types/index.ts +1 -0
- package/utils/get-es-footer-content.ts +1 -0
|
@@ -1,50 +1,238 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
TODO:
|
|
4
|
+
- circular has quirky behavior when numVisible doesn't match numScroll
|
|
5
|
+
- you can see this in the circular autoplay example
|
|
6
|
+
- i'm not sure if this is fixable
|
|
7
|
+
- prop to position the arrows at the bottom two corners of a full-width slide, like homepage
|
|
8
|
+
*/
|
|
9
|
+
|
|
2
10
|
import Carousel from 'primevue/carousel';
|
|
11
|
+
import sassBreakpoints from '@energysage/es-ds-styles/scss/modules/breakpoints.module.scss';
|
|
12
|
+
import type { EsCarouselBreakpointsInterface } from '../types';
|
|
13
|
+
|
|
14
|
+
// this isn't set in a SASS variable so we can't import it, but it's
|
|
15
|
+
// defined as a constant here so we can easily change it if we need to
|
|
16
|
+
const BASE_FONT_SIZE = 16;
|
|
17
|
+
|
|
18
|
+
// constants that contribute to dots and arrows positioning
|
|
19
|
+
const DOT_SIZE = 14;
|
|
20
|
+
const DOT_SPACING = 16;
|
|
21
|
+
const ARROW_BUTTON_PADDING = 8;
|
|
22
|
+
|
|
23
|
+
// the number of "dots" apart the arrows should be when dots are hidden
|
|
24
|
+
const ARROW_SPACING_WHEN_NO_DOTS = 1;
|
|
25
|
+
|
|
26
|
+
interface IProps {
|
|
27
|
+
arrowSize?: 'sm' | 'lg';
|
|
28
|
+
autoPlay?: boolean;
|
|
29
|
+
autoPlayInterval?: number;
|
|
30
|
+
breakpoints?: EsCarouselBreakpointsInterface;
|
|
31
|
+
circular?: boolean;
|
|
32
|
+
controlGap?: number;
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
items: Array<any>;
|
|
35
|
+
numScroll?: number;
|
|
36
|
+
numVisible?: number;
|
|
37
|
+
peekDesktop?: string;
|
|
38
|
+
peekMobile?: string;
|
|
39
|
+
showArrows?: boolean;
|
|
40
|
+
showDots?: boolean;
|
|
41
|
+
slideGap?: number;
|
|
42
|
+
variant?: 'default' | 'brand';
|
|
43
|
+
}
|
|
44
|
+
const props = withDefaults(defineProps<IProps>(), {
|
|
45
|
+
arrowSize: 'sm',
|
|
46
|
+
autoPlay: false,
|
|
47
|
+
autoPlayInterval: 4000,
|
|
48
|
+
breakpoints: () => ({}),
|
|
49
|
+
circular: false,
|
|
50
|
+
controlGap: 24,
|
|
51
|
+
items: () => [],
|
|
52
|
+
numScroll: 1,
|
|
53
|
+
numVisible: 1,
|
|
54
|
+
peekDesktop: '',
|
|
55
|
+
peekMobile: '',
|
|
56
|
+
showArrows: true,
|
|
57
|
+
showDots: true,
|
|
58
|
+
slideGap: 16,
|
|
59
|
+
variant: 'default',
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const emit = defineEmits<{
|
|
63
|
+
update: [value: number];
|
|
64
|
+
}>();
|
|
65
|
+
|
|
66
|
+
// get the breakpoint pixel numbers from the SASS variables in es-ds-styles
|
|
67
|
+
const parseSassBreakpoint = (breakpoint: string) => parseInt(breakpoint.replace('px', ''), 10);
|
|
68
|
+
const BREAKPOINTS = {
|
|
69
|
+
SM: parseSassBreakpoint(sassBreakpoints.sm),
|
|
70
|
+
MD: parseSassBreakpoint(sassBreakpoints.md),
|
|
71
|
+
LG: parseSassBreakpoint(sassBreakpoints.lg),
|
|
72
|
+
XL: parseSassBreakpoint(sassBreakpoints.xl),
|
|
73
|
+
XXL: parseSassBreakpoint(sassBreakpoints.xxl),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// lower breakpoint values propagate to higher breakpoints unless overridden
|
|
77
|
+
const numVisibleXs = computed(() => props.numVisible);
|
|
78
|
+
const numVisibleSm = computed(() => props.breakpoints?.sm?.numVisible || numVisibleXs.value);
|
|
79
|
+
const numVisibleMd = computed(() => props.breakpoints?.md?.numVisible || numVisibleSm.value);
|
|
80
|
+
const numVisibleLg = computed(() => props.breakpoints?.lg?.numVisible || numVisibleMd.value);
|
|
81
|
+
const numVisibleXl = computed(() => props.breakpoints?.xl?.numVisible || numVisibleLg.value);
|
|
82
|
+
const numVisibleXxl = computed(() => props.breakpoints?.xxl?.numVisible || numVisibleXl.value);
|
|
83
|
+
|
|
84
|
+
// lower breakpoint values propagate to higher breakpoints unless overridden
|
|
85
|
+
const numScrollXs = computed(() => props.numScroll);
|
|
86
|
+
const numScrollSm = computed(() => props.breakpoints?.sm?.numScroll || numScrollXs.value);
|
|
87
|
+
const numScrollMd = computed(() => props.breakpoints?.md?.numScroll || numScrollSm.value);
|
|
88
|
+
const numScrollLg = computed(() => props.breakpoints?.lg?.numScroll || numScrollMd.value);
|
|
89
|
+
const numScrollXl = computed(() => props.breakpoints?.xl?.numScroll || numScrollLg.value);
|
|
90
|
+
const numScrollXxl = computed(() => props.breakpoints?.xxl?.numScroll || numScrollXl.value);
|
|
91
|
+
|
|
92
|
+
// allow customizable spacing between slides
|
|
93
|
+
// but since that's done as side padding around each slide, which moves them in from the container edge
|
|
94
|
+
// to get slides to left and right align with page content
|
|
95
|
+
// we apply a negative margin to either side to bring the container edges back out to match
|
|
96
|
+
const sidePadding = computed(() => `${props.slideGap / 2 / BASE_FONT_SIZE}rem`);
|
|
97
|
+
const negativeMargin = computed(() => `-${sidePadding.value}`);
|
|
98
|
+
|
|
99
|
+
// size of dots and spacing between dots
|
|
100
|
+
const dotSize = `${DOT_SIZE / BASE_FONT_SIZE}rem`;
|
|
101
|
+
const dotSpacing = `${DOT_SPACING / BASE_FONT_SIZE}rem`;
|
|
102
|
+
|
|
103
|
+
// arrow padding
|
|
104
|
+
const arrowPadding = `${ARROW_BUTTON_PADDING / BASE_FONT_SIZE}rem`;
|
|
3
105
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
106
|
+
// arrow size
|
|
107
|
+
const arrowSize = computed(() => (props.arrowSize === 'lg' ? 32 : 24));
|
|
108
|
+
const arrowSizePx = computed(() => `${arrowSize.value}px`);
|
|
109
|
+
const arrowButtonSize = computed(() => arrowSize.value + ARROW_BUTTON_PADDING * 2);
|
|
110
|
+
|
|
111
|
+
// vertical positioning for the arrows
|
|
112
|
+
const distanceFromCarouselBottomToCenterOfDots = computed(() => props.controlGap + DOT_SIZE / 2);
|
|
113
|
+
const arrowPositionBottom = computed(
|
|
114
|
+
() => `-${distanceFromCarouselBottomToCenterOfDots.value + arrowButtonSize.value / 2}px`,
|
|
115
|
+
);
|
|
116
|
+
const dotsMarginTop = computed(() => `${props.controlGap / BASE_FONT_SIZE}rem`);
|
|
117
|
+
|
|
118
|
+
// the number of dots visible at each breakpoint
|
|
119
|
+
const numDotsXs = computed(() =>
|
|
120
|
+
props.showDots
|
|
121
|
+
? Math.ceil((props.items.length - numVisibleXs.value) / numScrollXs.value) + 1
|
|
122
|
+
: ARROW_SPACING_WHEN_NO_DOTS,
|
|
123
|
+
);
|
|
124
|
+
const numDotsSm = computed(() =>
|
|
125
|
+
props.showDots
|
|
126
|
+
? Math.ceil((props.items.length - numVisibleSm.value) / numScrollSm.value) + 1
|
|
127
|
+
: ARROW_SPACING_WHEN_NO_DOTS,
|
|
128
|
+
);
|
|
129
|
+
const numDotsMd = computed(() =>
|
|
130
|
+
props.showDots
|
|
131
|
+
? Math.ceil((props.items.length - numVisibleMd.value) / numScrollMd.value) + 1
|
|
132
|
+
: ARROW_SPACING_WHEN_NO_DOTS,
|
|
133
|
+
);
|
|
134
|
+
const numDotsLg = computed(() =>
|
|
135
|
+
props.showDots
|
|
136
|
+
? Math.ceil((props.items.length - numVisibleLg.value) / numScrollLg.value) + 1
|
|
137
|
+
: ARROW_SPACING_WHEN_NO_DOTS,
|
|
138
|
+
);
|
|
139
|
+
const numDotsXl = computed(() =>
|
|
140
|
+
props.showDots
|
|
141
|
+
? Math.ceil((props.items.length - numVisibleXl.value) / numScrollXl.value) + 1
|
|
142
|
+
: ARROW_SPACING_WHEN_NO_DOTS,
|
|
143
|
+
);
|
|
144
|
+
const numDotsXxl = computed(() =>
|
|
145
|
+
props.showDots
|
|
146
|
+
? Math.ceil((props.items.length - numVisibleXxl.value) / numScrollXxl.value) + 1
|
|
147
|
+
: ARROW_SPACING_WHEN_NO_DOTS,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// calculate the arrow position from center based on the number of dots
|
|
151
|
+
const calculateArrowPosition = (numDots: number): number =>
|
|
152
|
+
(numDots * DOT_SIZE) / 2 + (numDots * DOT_SPACING) / 2 + DOT_SPACING;
|
|
153
|
+
|
|
154
|
+
// determine how much from center we need to move the arrow buttons, based on how many dots there are
|
|
155
|
+
const arrowPositionXs = computed(() => calculateArrowPosition(numDotsXs.value));
|
|
156
|
+
const arrowPositionSm = computed(() => calculateArrowPosition(numDotsSm.value));
|
|
157
|
+
const arrowPositionMd = computed(() => calculateArrowPosition(numDotsMd.value));
|
|
158
|
+
const arrowPositionLg = computed(() => calculateArrowPosition(numDotsLg.value));
|
|
159
|
+
const arrowPositionXl = computed(() => calculateArrowPosition(numDotsXl.value));
|
|
160
|
+
const arrowPositionXxl = computed(() => calculateArrowPosition(numDotsXxl.value));
|
|
161
|
+
|
|
162
|
+
// prev button horizontal position
|
|
163
|
+
const prevArrowTranslateXs = computed(() => `-${arrowPositionXs.value + arrowButtonSize.value}px`);
|
|
164
|
+
const prevArrowTranslateSm = computed(() => `-${arrowPositionSm.value + arrowButtonSize.value}px`);
|
|
165
|
+
const prevArrowTranslateMd = computed(() => `-${arrowPositionMd.value + arrowButtonSize.value}px`);
|
|
166
|
+
const prevArrowTranslateLg = computed(() => `-${arrowPositionLg.value + arrowButtonSize.value}px`);
|
|
167
|
+
const prevArrowTranslateXl = computed(() => `-${arrowPositionXl.value + arrowButtonSize.value}px`);
|
|
168
|
+
const prevArrowTranslateXxl = computed(() => `-${arrowPositionXxl.value + arrowButtonSize.value}px`);
|
|
169
|
+
|
|
170
|
+
// next arrow horizontal position
|
|
171
|
+
const nextArrowTranslateXs = computed(() => `${arrowPositionXs.value}px`);
|
|
172
|
+
const nextArrowTranslateSm = computed(() => `${arrowPositionSm.value}px`);
|
|
173
|
+
const nextArrowTranslateMd = computed(() => `${arrowPositionMd.value}px`);
|
|
174
|
+
const nextArrowTranslateLg = computed(() => `${arrowPositionLg.value}px`);
|
|
175
|
+
const nextArrowTranslateXl = computed(() => `${arrowPositionXl.value}px`);
|
|
176
|
+
const nextArrowTranslateXxl = computed(() => `${arrowPositionXxl.value}px`);
|
|
177
|
+
|
|
178
|
+
// extra space to add below the carousel for the arrows when arrows are on but dots are off
|
|
179
|
+
const arrowsOnlyBottomSpacing = computed(() => `${props.controlGap + arrowButtonSize.value}px`);
|
|
180
|
+
|
|
181
|
+
const responsiveOptions = computed(() => {
|
|
182
|
+
// if no special breakpoints are defined, don't pass in any responsive options
|
|
183
|
+
if (!Object.keys(props.breakpoints).length) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return [
|
|
188
|
+
// XXL breakpoint
|
|
189
|
+
{
|
|
190
|
+
// max width of XXL is infinite, so let's use 9999px
|
|
191
|
+
breakpoint: '9999px',
|
|
192
|
+
numScroll: numScrollXxl.value,
|
|
193
|
+
numVisible: numVisibleXxl.value,
|
|
194
|
+
},
|
|
195
|
+
// XL breakpoint
|
|
196
|
+
{
|
|
197
|
+
// max width of XL is XXL minus one
|
|
198
|
+
breakpoint: `${BREAKPOINTS.XXL - 1}px`,
|
|
199
|
+
numScroll: numScrollXl.value,
|
|
200
|
+
numVisible: numVisibleXl.value,
|
|
201
|
+
},
|
|
202
|
+
// LG breakpoint
|
|
203
|
+
{
|
|
204
|
+
// max width of LG is XL minus one
|
|
205
|
+
breakpoint: `${BREAKPOINTS.XL - 1}px`,
|
|
206
|
+
numScroll: numScrollLg.value,
|
|
207
|
+
numVisible: numVisibleLg.value,
|
|
208
|
+
},
|
|
209
|
+
// MD breakpoint
|
|
210
|
+
{
|
|
211
|
+
// max width of MD is LG minus one
|
|
212
|
+
breakpoint: `${BREAKPOINTS.LG - 1}px`,
|
|
213
|
+
numScroll: numScrollMd.value,
|
|
214
|
+
numVisible: numVisibleMd.value,
|
|
215
|
+
},
|
|
216
|
+
// SM breakpoint
|
|
217
|
+
{
|
|
218
|
+
// max width of SM is MD minus one
|
|
219
|
+
breakpoint: `${BREAKPOINTS.MD - 1}px`,
|
|
220
|
+
numScroll: numScrollSm.value,
|
|
221
|
+
numVisible: numVisibleSm.value,
|
|
222
|
+
},
|
|
223
|
+
// XS breakpoint
|
|
224
|
+
// (this is necessary to avoid weird behavior on mobile)
|
|
225
|
+
{
|
|
226
|
+
// max width of XS is SM minus one
|
|
227
|
+
breakpoint: `${BREAKPOINTS.SM - 1}px`,
|
|
228
|
+
numScroll: props.numScroll,
|
|
229
|
+
numVisible: props.numVisible,
|
|
230
|
+
},
|
|
231
|
+
];
|
|
45
232
|
});
|
|
46
233
|
|
|
47
|
-
const autoplayInterval = ref(props.
|
|
234
|
+
const autoplayInterval = ref(props.autoPlay ? props.autoPlayInterval : 0);
|
|
235
|
+
const isMounted = ref(false);
|
|
48
236
|
const key = ref('');
|
|
49
237
|
|
|
50
238
|
const stopAutoplay = () => {
|
|
@@ -55,6 +243,22 @@ const stopAutoplay = () => {
|
|
|
55
243
|
};
|
|
56
244
|
|
|
57
245
|
onMounted(() => {
|
|
246
|
+
/**
|
|
247
|
+
* avoids an unavoidable SSR issue with responsive carousels (SSR can't know the breakpoint
|
|
248
|
+
* and therefore how many items need to be displayed per page) where circular carousels have
|
|
249
|
+
* their last few items cloned and inserted before the first item in the list, meaning on initial
|
|
250
|
+
* page render, you see those cloned last items listed first rather than the first item.
|
|
251
|
+
*
|
|
252
|
+
* then, upon hydration, the items change and the first item is then listed first.
|
|
253
|
+
*
|
|
254
|
+
* this workaround disables circular functionality for SSR, and swaps to the user-provided
|
|
255
|
+
* setting for it on mount.
|
|
256
|
+
*
|
|
257
|
+
* this flag is also used to hide the extra dots from the mobile view on larger breakpoints
|
|
258
|
+
* before hydration occurs and the number of dots is adjusted to the breakpoint.
|
|
259
|
+
*/
|
|
260
|
+
isMounted.value = true;
|
|
261
|
+
|
|
58
262
|
document.addEventListener('keyup', (e) => {
|
|
59
263
|
if (e.key === 'Escape') {
|
|
60
264
|
// Stop carousel when user presses Escape key, in lieu of pause button
|
|
@@ -69,77 +273,327 @@ onMounted(() => {
|
|
|
69
273
|
<carousel
|
|
70
274
|
:key="key"
|
|
71
275
|
:autoplay-interval="autoplayInterval"
|
|
72
|
-
circular
|
|
73
|
-
|
|
276
|
+
:circular="isMounted && circular"
|
|
277
|
+
class="es-carousel"
|
|
278
|
+
:class="{
|
|
279
|
+
'es-carousel--brand': variant === 'brand',
|
|
280
|
+
'arrows-only': showArrows && !showDots,
|
|
281
|
+
'before-mount': !isMounted,
|
|
282
|
+
circular: circular,
|
|
283
|
+
dots: showDots,
|
|
284
|
+
[`num-dots-sm-${numDotsSm}`]: true,
|
|
285
|
+
[`num-dots-md-${numDotsMd}`]: true,
|
|
286
|
+
[`num-dots-lg-${numDotsLg}`]: true,
|
|
287
|
+
[`num-dots-xl-${numDotsXl}`]: true,
|
|
288
|
+
[`num-dots-xxl-${numDotsXxl}`]: true,
|
|
289
|
+
}"
|
|
290
|
+
:num-scroll="numScroll"
|
|
291
|
+
:num-visible="numVisible"
|
|
74
292
|
:responsive-options="responsiveOptions"
|
|
75
|
-
:show-indicators="
|
|
293
|
+
:show-indicators="showDots"
|
|
294
|
+
:show-navigators="showArrows"
|
|
76
295
|
:value="items"
|
|
77
296
|
:pt="{
|
|
78
297
|
container: {
|
|
79
|
-
class: 'd-flex',
|
|
298
|
+
class: 'es-carousel-container d-flex position-relative',
|
|
80
299
|
},
|
|
81
300
|
indicator: {
|
|
82
|
-
class: 'dot',
|
|
301
|
+
class: 'es-carousel-dot',
|
|
83
302
|
},
|
|
84
303
|
indicators: {
|
|
85
|
-
class: 'd-flex justify-content-center',
|
|
86
|
-
|
|
304
|
+
class: 'es-carousel-dots d-flex justify-content-center',
|
|
305
|
+
},
|
|
306
|
+
indicatorButton: {
|
|
307
|
+
class: 'd-block',
|
|
87
308
|
},
|
|
88
309
|
itemsContent: {
|
|
89
|
-
class:
|
|
310
|
+
class: [
|
|
311
|
+
'w-100 overflow-hidden',
|
|
312
|
+
{
|
|
313
|
+
'es-carousel-peek-desktop': peekDesktop,
|
|
314
|
+
'es-carousel-peek-mobile': peekMobile,
|
|
315
|
+
},
|
|
316
|
+
],
|
|
90
317
|
},
|
|
91
318
|
itemsContainer: {
|
|
92
319
|
class: 'd-flex',
|
|
93
320
|
},
|
|
94
321
|
item: {
|
|
95
|
-
class: '
|
|
322
|
+
class: 'es-carousel-item',
|
|
96
323
|
},
|
|
97
324
|
itemCloned: {
|
|
98
|
-
class: '
|
|
325
|
+
class: 'es-carousel-item',
|
|
99
326
|
},
|
|
100
327
|
previousButton: {
|
|
101
|
-
|
|
328
|
+
class: 'es-carousel-arrow es-carousel-prev-arrow btn btn-outline-primary position-absolute px-sm-50',
|
|
102
329
|
},
|
|
103
330
|
nextButton: {
|
|
104
|
-
|
|
331
|
+
class: 'es-carousel-arrow es-carousel-next-arrow btn btn-outline-primary position-absolute px-sm-50',
|
|
105
332
|
},
|
|
106
|
-
}"
|
|
333
|
+
}"
|
|
334
|
+
@update:page="(value: number) => emit('update', value)">
|
|
107
335
|
<template #item="item">
|
|
108
336
|
<slot
|
|
109
337
|
name="item"
|
|
110
338
|
:item="item.data" />
|
|
111
339
|
</template>
|
|
340
|
+
<template #previousicon>
|
|
341
|
+
<icon-chevron-left />
|
|
342
|
+
</template>
|
|
343
|
+
<template #nexticon>
|
|
344
|
+
<icon-chevron-right />
|
|
345
|
+
</template>
|
|
112
346
|
</carousel>
|
|
113
347
|
</template>
|
|
114
348
|
|
|
115
349
|
<style lang="scss" scoped>
|
|
116
350
|
@use '@energysage/es-ds-styles/scss/variables' as variables;
|
|
117
351
|
@use '@energysage/es-ds-styles/scss/mixins/breakpoints' as breakpoints;
|
|
352
|
+
@use 'sass:map';
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
solution for PrimeVue initially displaying the mobile breakpoint's number of dots on page load
|
|
356
|
+
until hydration, when it then adjusts to the actual breakpoint and corrects the number of dots
|
|
357
|
+
|
|
358
|
+
generate CSS classes for each breakpoint that hide the dots that should be hidden before mount
|
|
359
|
+
*/
|
|
360
|
+
$num-dots-supported: 8;
|
|
361
|
+
.es-carousel.before-mount {
|
|
362
|
+
@each $breakpoint in map.keys(variables.$grid-breakpoints) {
|
|
363
|
+
@include breakpoints.media-breakpoint-up($breakpoint) {
|
|
364
|
+
$infix: breakpoints.breakpoint-infix($breakpoint, variables.$grid-breakpoints);
|
|
365
|
+
@for $i from 1 through $num-dots-supported {
|
|
366
|
+
&.num-dots#{$infix}-#{$i} :deep(.es-carousel-dot:nth-child(#{$i}) ~ .es-carousel-dot) {
|
|
367
|
+
display: none;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* prevent the prev arrow from looking disabled on circular carousels on first paint */
|
|
375
|
+
.es-carousel.before-mount.circular :deep(.es-carousel-prev-arrow:disabled) {
|
|
376
|
+
color: variables.$gray-900;
|
|
377
|
+
}
|
|
378
|
+
.es-carousel.es-carousel--brand.before-mount.circular :deep(.es-carousel-prev-arrow:disabled) {
|
|
379
|
+
color: variables.$blue-900;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* arrows are positioned absolutely, so when arrows are shown but dots are not, we need to reserve space for them */
|
|
383
|
+
.es-carousel.arrows-only {
|
|
384
|
+
padding-bottom: v-bind(arrowsOnlyBottomSpacing);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/* ensure there's enough space between the dots (when present) and the next content on the page */
|
|
388
|
+
.es-carousel.dots {
|
|
389
|
+
padding-bottom: 0.25rem;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* make the carousel card edges align with page content */
|
|
393
|
+
:deep(.es-carousel-container) {
|
|
394
|
+
margin-left: v-bind(negativeMargin);
|
|
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
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* card sizing, based on num visible at each breakpoint */
|
|
411
|
+
:deep(.es-carousel-item) {
|
|
412
|
+
flex: 1 0 calc(100% / v-bind(numVisibleXs));
|
|
413
|
+
padding: 0 v-bind(sidePadding);
|
|
414
|
+
|
|
415
|
+
@include breakpoints.media-breakpoint-up(sm) {
|
|
416
|
+
flex: 1 0 calc(100% / v-bind(numVisibleSm));
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
@include breakpoints.media-breakpoint-up(md) {
|
|
420
|
+
flex: 1 0 calc(100% / v-bind(numVisibleMd));
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
@include breakpoints.media-breakpoint-up(lg) {
|
|
424
|
+
flex: 1 0 calc(100% / v-bind(numVisibleLg));
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
@include breakpoints.media-breakpoint-up(xl) {
|
|
428
|
+
flex: 1 0 calc(100% / v-bind(numVisibleXl));
|
|
429
|
+
}
|
|
118
430
|
|
|
119
|
-
|
|
120
|
-
|
|
431
|
+
@include breakpoints.media-breakpoint-up(xxl) {
|
|
432
|
+
flex: 1 0 calc(100% / v-bind(numVisibleXxl));
|
|
433
|
+
}
|
|
121
434
|
}
|
|
122
435
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
436
|
+
/* previous arrow horizontal positioning at each breakpoint */
|
|
437
|
+
:deep(.es-carousel-prev-arrow) {
|
|
438
|
+
transform: translateX(v-bind(prevArrowTranslateXs));
|
|
439
|
+
|
|
440
|
+
/* keep the "shift 1px down on click" transform from removing our transform */
|
|
441
|
+
&:not(:disabled):not(.disabled):active {
|
|
442
|
+
transform: translateX(v-bind(prevArrowTranslateXs)) translateY(1px);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
@include breakpoints.media-breakpoint-up(sm) {
|
|
446
|
+
transform: translateX(v-bind(prevArrowTranslateSm));
|
|
447
|
+
|
|
448
|
+
&:not(:disabled):not(.disabled):active {
|
|
449
|
+
transform: translateX(v-bind(prevArrowTranslateSm)) translateY(1px);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
@include breakpoints.media-breakpoint-up(md) {
|
|
454
|
+
transform: translateX(v-bind(prevArrowTranslateMd));
|
|
455
|
+
|
|
456
|
+
&:not(:disabled):not(.disabled):active {
|
|
457
|
+
transform: translateX(v-bind(prevArrowTranslateMd)) translateY(1px);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
@include breakpoints.media-breakpoint-up(lg) {
|
|
462
|
+
transform: translateX(v-bind(prevArrowTranslateLg));
|
|
463
|
+
|
|
464
|
+
&:not(:disabled):not(.disabled):active {
|
|
465
|
+
transform: translateX(v-bind(prevArrowTranslateLg)) translateY(1px);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
@include breakpoints.media-breakpoint-up(xl) {
|
|
470
|
+
transform: translateX(v-bind(prevArrowTranslateXl));
|
|
471
|
+
|
|
472
|
+
&:not(:disabled):not(.disabled):active {
|
|
473
|
+
transform: translateX(v-bind(prevArrowTranslateXl)) translateY(1px);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
@include breakpoints.media-breakpoint-up(xxl) {
|
|
478
|
+
transform: translateX(v-bind(prevArrowTranslateXxl));
|
|
479
|
+
|
|
480
|
+
&:not(:disabled):not(.disabled):active {
|
|
481
|
+
transform: translateX(v-bind(prevArrowTranslateXxl)) translateY(1px);
|
|
482
|
+
}
|
|
126
483
|
}
|
|
127
484
|
}
|
|
128
485
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
486
|
+
/* next arrow horizontal positioning at each breakpoint */
|
|
487
|
+
:deep(.es-carousel-next-arrow) {
|
|
488
|
+
transform: translateX(v-bind(nextArrowTranslateXs));
|
|
489
|
+
|
|
490
|
+
/* keep the "shift 1px down on click" transform from removing our transform */
|
|
491
|
+
&:not(:disabled):not(.disabled):active {
|
|
492
|
+
transform: translateX(v-bind(nextArrowTranslateXs)) translateY(1px);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
@include breakpoints.media-breakpoint-up(sm) {
|
|
496
|
+
transform: translateX(v-bind(nextArrowTranslateSm));
|
|
497
|
+
|
|
498
|
+
&:not(:disabled):not(.disabled):active {
|
|
499
|
+
transform: translateX(v-bind(nextArrowTranslateSm)) translateY(1px);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
@include breakpoints.media-breakpoint-up(md) {
|
|
504
|
+
transform: translateX(v-bind(nextArrowTranslateMd));
|
|
505
|
+
|
|
506
|
+
&:not(:disabled):not(.disabled):active {
|
|
507
|
+
transform: translateX(v-bind(nextArrowTranslateMd)) translateY(1px);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
@include breakpoints.media-breakpoint-up(lg) {
|
|
512
|
+
transform: translateX(v-bind(nextArrowTranslateLg));
|
|
513
|
+
|
|
514
|
+
&:not(:disabled):not(.disabled):active {
|
|
515
|
+
transform: translateX(v-bind(nextArrowTranslateLg)) translateY(1px);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
@include breakpoints.media-breakpoint-up(xl) {
|
|
520
|
+
transform: translateX(v-bind(nextArrowTranslateXl));
|
|
521
|
+
|
|
522
|
+
&:not(:disabled):not(.disabled):active {
|
|
523
|
+
transform: translateX(v-bind(nextArrowTranslateXl)) translateY(1px);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
@include breakpoints.media-breakpoint-up(xxl) {
|
|
528
|
+
transform: translateX(v-bind(nextArrowTranslateXxl));
|
|
529
|
+
|
|
530
|
+
&:not(:disabled):not(.disabled):active {
|
|
531
|
+
transform: translateX(v-bind(nextArrowTranslateXxl)) translateY(1px);
|
|
532
|
+
}
|
|
132
533
|
}
|
|
133
534
|
}
|
|
134
535
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
536
|
+
/* prev/next arrow button styling */
|
|
537
|
+
:deep(.es-carousel-arrow) {
|
|
538
|
+
background: unset;
|
|
539
|
+
border: unset;
|
|
540
|
+
bottom: v-bind(arrowPositionBottom);
|
|
541
|
+
box-shadow: none;
|
|
542
|
+
color: variables.$gray-900;
|
|
543
|
+
height: auto;
|
|
544
|
+
left: 50%;
|
|
545
|
+
padding: v-bind(arrowPadding);
|
|
546
|
+
|
|
547
|
+
&:hover {
|
|
548
|
+
color: variables.$gray-700;
|
|
549
|
+
}
|
|
550
|
+
&:focus {
|
|
551
|
+
color: variables.$gray-900;
|
|
138
552
|
}
|
|
553
|
+
&:not(:disabled):not(.disabled):active {
|
|
554
|
+
background: unset;
|
|
555
|
+
box-shadow: none;
|
|
556
|
+
color: variables.$gray-700;
|
|
557
|
+
}
|
|
558
|
+
&:disabled {
|
|
559
|
+
color: variables.$gray-400;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
svg {
|
|
563
|
+
/* use !important to override the inline style on svg icons */
|
|
564
|
+
height: v-bind(arrowSizePx) !important;
|
|
565
|
+
width: v-bind(arrowSizePx) !important;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/* prev/next arrow button styling for the "brand" variant */
|
|
570
|
+
.es-carousel--brand {
|
|
571
|
+
:deep(.es-carousel-arrow) {
|
|
572
|
+
color: variables.$blue-600;
|
|
573
|
+
|
|
574
|
+
&:hover {
|
|
575
|
+
color: variables.$blue-700;
|
|
576
|
+
}
|
|
577
|
+
&:not(:disabled):not(.disabled):active {
|
|
578
|
+
color: variables.$blue-800;
|
|
579
|
+
}
|
|
580
|
+
&:disabled {
|
|
581
|
+
color: variables.$gray-400;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/* dots container */
|
|
587
|
+
:deep(.es-carousel-dots) {
|
|
588
|
+
gap: v-bind(dotSpacing);
|
|
589
|
+
padding-left: 0;
|
|
590
|
+
margin-top: v-bind(dotsMarginTop);
|
|
139
591
|
}
|
|
140
592
|
|
|
141
|
-
|
|
593
|
+
/* each individual dot */
|
|
594
|
+
:deep(.es-carousel-dot) {
|
|
142
595
|
list-style-type: none;
|
|
596
|
+
margin-bottom: 0;
|
|
143
597
|
|
|
144
598
|
&[data-p-highlight='true'] button {
|
|
145
599
|
background-color: variables.$orange-800;
|
|
@@ -149,8 +603,9 @@ onMounted(() => {
|
|
|
149
603
|
background-color: variables.$gray-100;
|
|
150
604
|
border: none;
|
|
151
605
|
border-radius: 50%;
|
|
152
|
-
height:
|
|
153
|
-
|
|
606
|
+
height: v-bind(dotSize);
|
|
607
|
+
padding: 0;
|
|
608
|
+
width: v-bind(dotSize);
|
|
154
609
|
|
|
155
610
|
&:hover {
|
|
156
611
|
opacity: 0.8;
|
package/components/es-col.vue
CHANGED
|
@@ -16,11 +16,11 @@ const undefinedSize = !(props.cols || props.sm || props.md || props.lg || props.
|
|
|
16
16
|
:class="{
|
|
17
17
|
col: undefinedSize,
|
|
18
18
|
[`col-${cols}`]: cols,
|
|
19
|
-
[`col-sm
|
|
20
|
-
[`col-md
|
|
21
|
-
[`col-lg
|
|
22
|
-
[`col-xl
|
|
23
|
-
[`col-xxl
|
|
19
|
+
[`col-sm${sm ? `-${sm}` : ''}`]: sm !== undefined,
|
|
20
|
+
[`col-md${md ? `-${md}` : ''}`]: md !== undefined,
|
|
21
|
+
[`col-lg${lg ? `-${lg}` : ''}`]: lg !== undefined,
|
|
22
|
+
[`col-xl${xl ? `-${xl}` : ''}`]: xl !== undefined,
|
|
23
|
+
[`col-xxl${xxl ? `-${xxl}` : ''}`]: xxl !== undefined,
|
|
24
24
|
}">
|
|
25
25
|
<slot />
|
|
26
26
|
</div>
|