tide-design-system 2.2.3 → 2.2.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.
package/package.json CHANGED
@@ -61,7 +61,7 @@
61
61
  "main": "dist/tide-design-system.cjs",
62
62
  "module": "dist/tide-design-system.esm.js",
63
63
  "types": "dist/tide-design-system.esm.d.ts",
64
- "version": "2.2.3",
64
+ "version": "2.2.4",
65
65
  "dependencies": {
66
66
  "@floating-ui/vue": "^1.1.6"
67
67
  }
@@ -4,38 +4,27 @@
4
4
  }
5
5
 
6
6
  .tide-grid-layout {
7
- --tide-max-content-width: var(--tide-1232px);
8
- --tide-column-count: 12;
9
- --tide-column-width: minmax(0, calc((var(--tide-max-content-width) - var(--tide-gap-count) * var(--tide-gap-width)) / var(--tide-column-count)));
10
- --tide-gap-count: calc(var(--tide-column-count) - 1);
11
- --tide-gap-width: var(--tide-spacing-1);
12
- --tide-gutter-width: var(--tide-spacing-1);
13
- --tide-gutter-width-offset: calc(var(--tide-gutter-width) - var(--tide-gap-width));
7
+ --tide-max-content-width: var(--tide-1232px);
8
+ --tide-column-width: minmax(0, var(--tide-max-content-width));
9
+ --tide-gutter-width: var(--tide-spacing-1);
14
10
 
15
11
  display: grid;
16
12
  grid-auto-rows: min-content;
17
13
  grid-template-columns:
18
- minmax(var(--tide-gutter-width-offset), 1fr)
19
- repeat(var(--tide-column-count), var(--tide-column-width))
20
- minmax(var(--tide-gutter-width-offset), 1fr);
21
- gap: var(--tide-spacing-1) var(--tide-gap-width);
14
+ minmax(var(--tide-gutter-width), 1fr)
15
+ var(--tide-column-width)
16
+ minmax(var(--tide-gutter-width), 1fr);
22
17
  }
23
18
 
24
19
  @media (min-width: 768px) {
25
- .tide-grid-layout {
26
- --tide-gutter-width: var(--tide-spacing-2);
27
- }
20
+ .tide-grid-layout {--tide-gutter-width: var(--tide-spacing-2);}
28
21
  }
29
22
 
30
- @media (min-width: 992px) {
31
- .tide-grid-layout {
32
- --tide-gap-width: var(--tide-spacing-2);
33
- }
23
+ @media (min-width: 1232px) {
24
+ .tide-grid-layout {--tide-gutter-width: var(--tide-spacing-4);}
34
25
  }
35
26
 
36
- .tide-grid-xl {
37
- --tide-max-content-width: var(--tide-1920px);
38
- }
27
+ .tide-grid-xl {--tide-max-content-width: var(--tide-1920px);}
39
28
 
40
29
  .tide-grid-layout > *,
41
30
  .tide-grid-item {
@@ -43,31 +32,3 @@
43
32
  }
44
33
 
45
34
  .tide-fluid {grid-column: 1 / -1;}
46
-
47
- .tide-start-0 {grid-column-start: 1;}
48
- .tide-start-1 {grid-column-start: 2;}
49
- .tide-start-2 {grid-column-start: 3;}
50
- .tide-start-3 {grid-column-start: 4;}
51
- .tide-start-4 {grid-column-start: 5;}
52
- .tide-start-5 {grid-column-start: 6;}
53
- .tide-start-6 {grid-column-start: 7;}
54
- .tide-start-7 {grid-column-start: 8;}
55
- .tide-start-8 {grid-column-start: 9;}
56
- .tide-start-9 {grid-column-start: 10;}
57
- .tide-start-10 {grid-column-start: 11;}
58
- .tide-start-11 {grid-column-start: 12;}
59
- .tide-start-12 {grid-column-start: 13;}
60
-
61
- .tide-end-1 {grid-column-end: 3;}
62
- .tide-end-2 {grid-column-end: 4;}
63
- .tide-end-3 {grid-column-end: 5;}
64
- .tide-end-4 {grid-column-end: 6;}
65
- .tide-end-5 {grid-column-end: 7;}
66
- .tide-end-6 {grid-column-end: 8;}
67
- .tide-end-7 {grid-column-end: 9;}
68
- .tide-end-8 {grid-column-end: 10;}
69
- .tide-end-9 {grid-column-end: 11;}
70
- .tide-end-10 {grid-column-end: 12;}
71
- .tide-end-11 {grid-column-end: 13;}
72
- .tide-end-12 {grid-column-end: 14;}
73
- .tide-end-13 {grid-column-end: 15;}
@@ -1,5 +1,4 @@
1
1
  /* Medium breakpoint */
2
- @media (min-width: 992px) {}
3
2
  @media (min-width: 992px) {
4
3
  /* Reusable CSS Utility Library */
5
4
  /* Position */
@@ -27,14 +27,17 @@
27
27
  CSS.BORDER.RADIUS.QUARTER,
28
28
  CSS.PADDING.Y.QUARTER,
29
29
  CSS.PADDING.X.HALF,
30
+ CSS.ELLIPSIS,
30
31
  CSS.FONT.ROLE.LABEL_2,
32
+ CSS.WHITESPACE_WRAP.OFF,
31
33
  ]"
32
34
  >
33
35
  <TideIcon
36
+ :class="[CSS.FLEX.SHRINK.OFF]"
34
37
  :icon="props.iconLeading"
35
38
  v-if="props.iconLeading"
36
39
  />
37
40
 
38
- {{ props.label }}
41
+ <span :class="[CSS.ELLIPSIS]">{{ props.label }}</span>
39
42
  </div>
40
43
  </template>
@@ -25,11 +25,17 @@
25
25
  CSS.GAP.QUARTER,
26
26
  CSS.PADDING.Y.QUARTER,
27
27
  CSS.PADDING.X.HALF,
28
+ CSS.ELLIPSIS,
28
29
  CSS.FONT.ROLE.LABEL_2,
30
+ CSS.WHITESPACE_WRAP.OFF,
29
31
  ]"
30
32
  >
31
- <TideIcon :icon="ICON.AWARD_STAR" />
32
- <div :class="[]">
33
+ <TideIcon
34
+ :class="[CSS.FLEX.SHRINK.OFF]"
35
+ :icon="ICON.AWARD_STAR"
36
+ />
37
+
38
+ <div :class="[CSS.ELLIPSIS]">
33
39
  <span>{{ props.years }} year trusted partner</span>
34
40
  </div>
35
41
  </div>
@@ -17,11 +17,16 @@
17
17
  CSS.BORDER.RADIUS.QUARTER,
18
18
  CSS.PADDING.Y.QUARTER,
19
19
  CSS.PADDING.X.HALF,
20
+ CSS.ELLIPSIS,
21
+ CSS.WHITESPACE_WRAP.OFF,
20
22
  ]"
21
23
  >
22
- <TideIcon :icon="ICON.VERIFIED" />
24
+ <TideIcon
25
+ :class="[CSS.FLEX.SHRINK.OFF]"
26
+ :icon="ICON.VERIFIED"
27
+ />
23
28
 
24
- <span>Verified vehicle</span>
29
+ <span :class="[CSS.ELLIPSIS]">Verified vehicle</span>
25
30
  </div>
26
31
  </template>
27
32
 
@@ -7,7 +7,9 @@
7
7
  import { CSS } from '@/types/Styles';
8
8
 
9
9
  type Props = {
10
+ bleed?: number;
10
11
  isFloating?: boolean;
12
+ isHeadline1?: boolean;
11
13
  isHideawayButtons?: boolean;
12
14
  isTouchscreen?: boolean;
13
15
  subtitle?: string;
@@ -15,7 +17,9 @@
15
17
  };
16
18
 
17
19
  const props = withDefaults(defineProps<Props>(), {
20
+ bleed: undefined,
18
21
  isFloating: false,
22
+ isHeadline1: false,
19
23
  isHideawayButtons: true,
20
24
  isTouchscreen: undefined,
21
25
  subtitle: undefined,
@@ -24,18 +28,32 @@
24
28
 
25
29
  const emit = defineEmits(['change']);
26
30
 
27
- const contentRef = ref();
28
- const frameRef = ref();
31
+ const containerRef = ref();
29
32
 
30
33
  const contentRightEdge = ref();
31
34
  const contentWidth = ref();
32
35
  const currentSlide = ref(0);
33
36
  const frameWidth = ref();
34
37
  const hasOverflow = ref();
38
+ const isFirstSlide = ref();
35
39
  const isLastSlide = ref();
36
40
  const lastPosition = ref();
37
41
  const showButtons = ref();
38
42
 
43
+ const updateContainerBleed = () => {
44
+ if (props.bleed == undefined) return;
45
+
46
+ if (isLastSlide.value && showButtons.value) {
47
+ // Prevent gradient from bleeding off left edge in last position.
48
+ containerRef.value.style.margin = `-${props.bleed}px -${props.bleed}px -${props.bleed}px 0`;
49
+ containerRef.value.style.padding = `${props.bleed}px ${props.bleed}px ${props.bleed}px 0`;
50
+ } else {
51
+ // Prevent gradient from bleeding off right edge in first position.
52
+ containerRef.value.style.margin = `-${props.bleed}px 0 -${props.bleed}px -${props.bleed}px`;
53
+ containerRef.value.style.padding = `${props.bleed}px 0 ${props.bleed}px ${props.bleed}px`;
54
+ }
55
+ };
56
+
39
57
  /**
40
58
  * Measure the current slide based on the scroll
41
59
  * position of the frame. The current slide is
@@ -44,25 +62,30 @@
44
62
  */
45
63
  const measureCurrentSlide = () => {
46
64
  // Get left offset of each slide.
47
- const slideOffsets = Array.from(contentRef.value.children).map((slide: any) => slide.offsetLeft);
65
+ const slideOffsets = Array.from(containerRef.value.children).map((slide: any) => slide.offsetLeft);
48
66
 
49
67
  if (slideOffsets.length === 0) return;
50
68
 
51
69
  // Get closest offset to current scroll position.
52
70
  const closestSlideOffset = slideOffsets.reduce((prev, curr) => {
53
- return Math.abs(curr - frameRef.value.scrollLeft) < Math.abs(prev - frameRef.value.scrollLeft) ? curr : prev;
71
+ return Math.abs(curr - containerRef.value.scrollLeft) < Math.abs(prev - containerRef.value.scrollLeft)
72
+ ? curr
73
+ : prev;
54
74
  });
55
75
 
56
76
  currentSlide.value = slideOffsets.indexOf(closestSlideOffset);
77
+
78
+ updateContainerBleed();
57
79
  };
58
80
 
59
81
  const measureDom = () => {
60
- contentRightEdge.value = frameRef.value.scrollLeft + frameRef.value.clientWidth;
61
- contentWidth.value = contentRef.value.scrollWidth;
62
- frameWidth.value = frameRef.value.clientWidth;
82
+ contentRightEdge.value = containerRef.value.scrollLeft + containerRef.value.clientWidth;
83
+ contentWidth.value = containerRef.value.scrollWidth;
84
+ frameWidth.value = containerRef.value.clientWidth;
63
85
  hasOverflow.value = contentWidth.value > frameWidth.value;
86
+ isFirstSlide.value = currentSlide.value === 0;
64
87
  isLastSlide.value = contentRightEdge.value === contentWidth.value;
65
- lastPosition.value = frameRef.value.scrollWidth - frameRef.value.clientWidth;
88
+ lastPosition.value = containerRef.value.scrollWidth - containerRef.value.clientWidth;
66
89
  showButtons.value = hasOverflow.value && !props.isTouchscreen;
67
90
 
68
91
  measureCurrentSlide();
@@ -74,15 +97,15 @@
74
97
  };
75
98
 
76
99
  const scrollToSlide = (slideIndex: number) => {
77
- frameRef.value.scrollTo({
100
+ containerRef.value.scrollTo({
78
101
  behavior: 'smooth',
79
- left: contentRef.value.children[slideIndex].offsetLeft,
102
+ left: containerRef.value.children[slideIndex].offsetLeft,
80
103
  });
81
104
  };
82
105
 
83
106
  const showNextSlide = () => {
84
107
  if (contentRightEdge.value > contentWidth.value) {
85
- frameRef.value.scrollTo({
108
+ containerRef.value.scrollTo({
86
109
  behavior: 'smooth',
87
110
  left: contentWidth,
88
111
  });
@@ -92,9 +115,7 @@
92
115
  };
93
116
 
94
117
  const showPreviousSlide = () => {
95
- const isFirstSlide = currentSlide.value === 0;
96
-
97
- if (!isFirstSlide) {
118
+ if (!isFirstSlide.value) {
98
119
  scrollToSlide(currentSlide.value - 1);
99
120
  }
100
121
  };
@@ -119,7 +140,14 @@
119
140
 
120
141
  <template>
121
142
  <section
122
- :class="['tide-carousel', CSS.DISPLAY.FLEX, CSS.FLEX.DIRECTION.COLUMN, CSS.GAP.TWO, CSS.WIDTH.MAX_FULL]"
143
+ :class="[
144
+ 'tide-carousel',
145
+ CSS.POSITION.RELATIVE,
146
+ CSS.DISPLAY.FLEX,
147
+ CSS.FLEX.DIRECTION.COLUMN,
148
+ CSS.GAP.TWO,
149
+ CSS.WIDTH.MAX_FULL,
150
+ ]"
123
151
  ref="carouselRef"
124
152
  >
125
153
  <section
@@ -131,7 +159,7 @@
131
159
  v-if="props.title || props.subtitle"
132
160
  >
133
161
  <div
134
- :class="[CSS.FONT.ROLE.DISPLAY_1]"
162
+ :class="[isHeadline1 ? CSS.FONT.ROLE.HEADLINE_1 : CSS.FONT.ROLE.HEADLINE_2]"
135
163
  v-if="props.title"
136
164
  >
137
165
  {{ props.title }}
@@ -168,55 +196,62 @@
168
196
  <slot name="misc" />
169
197
 
170
198
  <div :class="[CSS.POSITION.RELATIVE]">
171
- <div
172
- :class="[CSS.SCROLLBAR.OFF, CSS.SNAP.ON, CSS.OVERFLOW.X.SCROLL, CSS.WIDTH.FULL]"
173
- ref="frameRef"
174
- @scroll="handleScroll"
175
- >
176
- <ul
177
- :class="[CSS.DISPLAY.FLEX, CSS.GAP.ONE, CSS.LIST_BULLETS.OFF]"
178
- ref="contentRef"
179
- >
180
- <slot />
181
- </ul>
182
- </div>
183
-
184
- <div
199
+ <ul
185
200
  :class="[
186
- 'tide-carousel-button-overlay',
187
- CSS.POSITION.ABSOLUTE,
188
- CSS.POSITIONING.TOP,
201
+ 'tide-carousel-container',
189
202
  CSS.DISPLAY.FLEX,
190
- CSS.AXIS1.BETWEEN,
191
- CSS.AXIS2.CENTER,
192
- CSS.WIDTH.FULL,
193
- CSS.HEIGHT.FULL,
194
- CSS.POINTER_EVENTS.OFF,
195
- props.isHideawayButtons ? 'hideaway' : '',
203
+ CSS.GAP.ONE,
204
+ CSS.LIST_BULLETS.OFF,
205
+ CSS.OVERFLOW.X.SCROLL,
206
+ CSS.SCROLLBAR.OFF,
207
+ CSS.SNAP.ON,
196
208
  ]"
197
- v-if="isFloating && showButtons"
209
+ ref="containerRef"
210
+ @scroll="handleScroll"
198
211
  >
199
- <TideButtonIcon
200
- :class="[CSS.MARGIN.LEFT.ONE, CSS.POINTER_EVENTS.ON]"
201
- :disabled="currentSlide === 0"
202
- :icon="ICON.CHEVRON_LEFT"
203
- :priority="PRIORITY.QUATERNARY"
204
- @click="showPreviousSlide"
205
- />
212
+ <slot />
213
+ </ul>
214
+ </div>
206
215
 
207
- <TideButtonIcon
208
- :class="[CSS.MARGIN.RIGHT.ONE, CSS.POINTER_EVENTS.ON]"
209
- :disabled="isLastSlide"
210
- :icon="ICON.CHEVRON_RIGHT"
211
- :priority="PRIORITY.QUATERNARY"
212
- @click="showNextSlide"
213
- />
214
- </div>
216
+ <div
217
+ :class="[
218
+ 'tide-carousel-button-overlay',
219
+ CSS.POSITION.ABSOLUTE,
220
+ CSS.POSITIONING.TOP,
221
+ CSS.DISPLAY.FLEX,
222
+ CSS.AXIS1.BETWEEN,
223
+ CSS.AXIS2.CENTER,
224
+ CSS.WIDTH.FULL,
225
+ CSS.HEIGHT.FULL,
226
+ CSS.POINTER_EVENTS.OFF,
227
+ props.isHideawayButtons ? 'hideaway' : '',
228
+ ]"
229
+ v-if="isFloating && showButtons"
230
+ >
231
+ <TideButtonIcon
232
+ :class="[CSS.MARGIN.LEFT.ONE, CSS.POINTER_EVENTS.ON]"
233
+ :disabled="currentSlide === 0"
234
+ :icon="ICON.CHEVRON_LEFT"
235
+ :priority="PRIORITY.QUATERNARY"
236
+ @click="showPreviousSlide"
237
+ />
238
+
239
+ <TideButtonIcon
240
+ :class="[CSS.MARGIN.RIGHT.ONE, CSS.POINTER_EVENTS.ON]"
241
+ :disabled="isLastSlide"
242
+ :icon="ICON.CHEVRON_RIGHT"
243
+ :priority="PRIORITY.QUATERNARY"
244
+ @click="showNextSlide"
245
+ />
215
246
  </div>
216
247
  </section>
217
248
  </template>
218
249
 
219
250
  <style scoped>
251
+ .tide-carousel-container {
252
+ transition: margin var(--tide-animate), padding var(--tide-animate);
253
+ }
254
+
220
255
  .tide-carousel-button-overlay.hideaway {
221
256
  opacity: 0;
222
257
  }
@@ -1,19 +1,8 @@
1
- import * as STYLES from '@/types/Storybook';
2
1
  import { CSS } from '@/types/Styles';
3
- import {
4
- argTypeBoolean,
5
- formatArgType,
6
- getConstantsByValues,
7
- lineBreak,
8
- prependNoneAsEmpty,
9
- tab,
10
- } from '@/utilities/storybook';
2
+ import { argTypeBoolean, getConstantsByValues, lineBreak, tab } from '@/utilities/storybook';
11
3
 
12
4
  import type { StoryContext } from '@storybook/vue3';
13
5
 
14
- const GRID_END = prependNoneAsEmpty(STYLES.GRID_END);
15
- const GRID_START = prependNoneAsEmpty(STYLES.GRID_START);
16
-
17
6
  const formatArgs = (args: any) => {
18
7
  args.class = formatClassNames(args).join(' ');
19
8
 
@@ -25,8 +14,6 @@ const formatClassNames = (args: any) => {
25
14
 
26
15
  if (args.fluid) classNames.push(CSS.GRID.FLUID);
27
16
  if (args.item) classNames.push(CSS.GRID.ITEM);
28
- if (args.start) classNames.push(args.start);
29
- if (args.end) classNames.push(args.end);
30
17
 
31
18
  return classNames;
32
19
  };
@@ -89,12 +76,6 @@ const render = (args: any) => ({
89
76
 
90
77
  export default {
91
78
  argTypes: {
92
- end: {
93
- ...formatArgType({ GRID_END }),
94
- description: `Ending column of grid item`,
95
- if: { arg: 'fluid', neq: true },
96
- name: 'End',
97
- },
98
79
  fluid: {
99
80
  ...argTypeBoolean,
100
81
  description: `Determines whether grid item should extend to parent bounds`,
@@ -107,12 +88,6 @@ export default {
107
88
  if: { arg: 'fluid', neq: true },
108
89
  name: 'Item',
109
90
  },
110
- start: {
111
- ...formatArgType({ GRID_START }),
112
- description: `Starting column of grid item`,
113
- if: { arg: 'fluid', neq: true },
114
- name: 'Start',
115
- },
116
91
  xl: {
117
92
  ...argTypeBoolean,
118
93
  description: `Increases the maximum content width`,
@@ -120,10 +95,8 @@ export default {
120
95
  },
121
96
  },
122
97
  args: {
123
- end: GRID_END.None,
124
98
  fluid: false,
125
99
  item: false,
126
- start: GRID_START.None,
127
100
  xl: false,
128
101
  },
129
102
  parameters,
@@ -151,159 +124,3 @@ export const XL = {
151
124
  xl: true,
152
125
  },
153
126
  };
154
-
155
- export const Start0 = {
156
- args: {
157
- start: GRID_START['Column 0'],
158
- },
159
- };
160
-
161
- export const Start1 = {
162
- args: {
163
- start: GRID_START['Column 1'],
164
- },
165
- };
166
-
167
- export const Start2 = {
168
- args: {
169
- start: GRID_START['Column 2'],
170
- },
171
- };
172
-
173
- export const Start3 = {
174
- args: {
175
- start: GRID_START['Column 3'],
176
- },
177
- };
178
-
179
- export const Start4 = {
180
- args: {
181
- start: GRID_START['Column 4'],
182
- },
183
- };
184
-
185
- export const Start5 = {
186
- args: {
187
- start: GRID_START['Column 5'],
188
- },
189
- };
190
-
191
- export const Start6 = {
192
- args: {
193
- start: GRID_START['Column 6'],
194
- },
195
- };
196
-
197
- export const Start7 = {
198
- args: {
199
- start: GRID_START['Column 7'],
200
- },
201
- };
202
-
203
- export const Start8 = {
204
- args: {
205
- start: GRID_START['Column 8'],
206
- },
207
- };
208
-
209
- export const Start9 = {
210
- args: {
211
- start: GRID_START['Column 9'],
212
- },
213
- };
214
-
215
- export const Start10 = {
216
- args: {
217
- start: GRID_START['Column 10'],
218
- },
219
- };
220
-
221
- export const Start11 = {
222
- args: {
223
- start: GRID_START['Column 11'],
224
- },
225
- };
226
-
227
- export const Start12 = {
228
- args: {
229
- start: GRID_START['Column 12'],
230
- },
231
- };
232
-
233
- export const End1 = {
234
- args: {
235
- end: GRID_END['Column 1'],
236
- },
237
- };
238
-
239
- export const End2 = {
240
- args: {
241
- end: GRID_END['Column 2'],
242
- },
243
- };
244
-
245
- export const End3 = {
246
- args: {
247
- end: GRID_END['Column 3'],
248
- },
249
- };
250
-
251
- export const End4 = {
252
- args: {
253
- end: GRID_END['Column 4'],
254
- },
255
- };
256
-
257
- export const End5 = {
258
- args: {
259
- end: GRID_END['Column 5'],
260
- },
261
- };
262
-
263
- export const End6 = {
264
- args: {
265
- end: GRID_END['Column 6'],
266
- },
267
- };
268
-
269
- export const End7 = {
270
- args: {
271
- end: GRID_END['Column 7'],
272
- },
273
- };
274
-
275
- export const End8 = {
276
- args: {
277
- end: GRID_END['Column 8'],
278
- },
279
- };
280
-
281
- export const End9 = {
282
- args: {
283
- end: GRID_END['Column 9'],
284
- },
285
- };
286
-
287
- export const End10 = {
288
- args: {
289
- end: GRID_END['Column 10'],
290
- },
291
- };
292
-
293
- export const End11 = {
294
- args: {
295
- end: GRID_END['Column 11'],
296
- },
297
- };
298
-
299
- export const End12 = {
300
- args: {
301
- end: GRID_END['Column 12'],
302
- },
303
- };
304
-
305
- export const End13 = {
306
- args: {
307
- end: GRID_END['Column 13'],
308
- },
309
- };