@gitlab/ui 40.3.0 → 40.6.0

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": "@gitlab/ui",
3
- "version": "40.3.0",
3
+ "version": "40.6.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -87,15 +87,15 @@
87
87
  "@rollup/plugin-commonjs": "^11.1.0",
88
88
  "@rollup/plugin-node-resolve": "^7.1.3",
89
89
  "@rollup/plugin-replace": "^2.3.2",
90
- "@storybook/addon-a11y": "6.4.22",
91
- "@storybook/addon-docs": "6.4.22",
92
- "@storybook/addon-essentials": "6.4.22",
90
+ "@storybook/addon-a11y": "6.5.0",
91
+ "@storybook/addon-docs": "6.5.0",
92
+ "@storybook/addon-essentials": "6.5.0",
93
93
  "@storybook/addon-knobs": "6.4.0",
94
- "@storybook/addon-storyshots": "6.4.22",
95
- "@storybook/addon-storyshots-puppeteer": "6.4.22",
96
- "@storybook/addon-viewport": "6.4.22",
97
- "@storybook/theming": "6.4.22",
98
- "@storybook/vue": "6.4.22",
94
+ "@storybook/addon-storyshots": "6.5.0",
95
+ "@storybook/addon-storyshots-puppeteer": "6.5.0",
96
+ "@storybook/addon-viewport": "6.5.0",
97
+ "@storybook/theming": "6.5.0",
98
+ "@storybook/vue": "6.5.0",
99
99
  "@vue/test-utils": "1.3.0",
100
100
  "autoprefixer": "^9.7.6",
101
101
  "babel-jest": "^26.6.3",
@@ -1,7 +1,7 @@
1
1
  $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $green-50, $orange-50,
2
2
  $gray-50;
3
3
 
4
- .gl-avatar {
4
+ @mixin gl-avatar {
5
5
  @include gl-border-1;
6
6
  @include gl-border-solid;
7
7
  @include gl-border-gray-a-08;
@@ -9,7 +9,7 @@ $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $gree
9
9
  @include gl-flex-shrink-0;
10
10
  }
11
11
 
12
- .gl-avatar-s16 {
12
+ @mixin gl-avatar-s16 {
13
13
  @include gl-w-5;
14
14
  @include gl-h-5;
15
15
  @include gl-font-sm;
@@ -17,7 +17,7 @@ $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $gree
17
17
  @include gl-rounded-small;
18
18
  }
19
19
 
20
- .gl-avatar-s24 {
20
+ @mixin gl-avatar-s24 {
21
21
  @include gl-w-6;
22
22
  @include gl-h-6;
23
23
  @include gl-font-sm;
@@ -25,7 +25,7 @@ $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $gree
25
25
  @include gl-rounded-base;
26
26
  }
27
27
 
28
- .gl-avatar-s32 {
28
+ @mixin gl-avatar-s32 {
29
29
  @include gl-w-7;
30
30
  @include gl-h-7;
31
31
  @include gl-font-base;
@@ -33,7 +33,7 @@ $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $gree
33
33
  @include gl-rounded-base;
34
34
  }
35
35
 
36
- .gl-avatar-s48 {
36
+ @mixin gl-avatar-s48 {
37
37
  @include gl-w-9;
38
38
  @include gl-h-9;
39
39
  @include gl-font-size-h2;
@@ -41,7 +41,7 @@ $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $gree
41
41
  @include gl-rounded-lg;
42
42
  }
43
43
 
44
- .gl-avatar-s64 {
44
+ @mixin gl-avatar-s64 {
45
45
  @include gl-w-11;
46
46
  @include gl-h-11;
47
47
  @include gl-font-size-h-display;
@@ -49,7 +49,7 @@ $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $gree
49
49
  @include gl-rounded-lg;
50
50
  }
51
51
 
52
- .gl-avatar-s96 {
52
+ @mixin gl-avatar-s96 {
53
53
  @include gl-w-13;
54
54
  @include gl-h-13;
55
55
  @include gl-font-size-h-display-xl;
@@ -57,6 +57,142 @@ $gl-avatar-identicon-bgs: $red-50, $purple-50, $theme-indigo-50, $blue-50, $gree
57
57
  @include gl-rounded-lg;
58
58
  }
59
59
 
60
+ .gl-avatar {
61
+ @include gl-avatar;
62
+ }
63
+
64
+ .gl-avatar-s16 {
65
+ @include gl-avatar-s16;
66
+ }
67
+
68
+ .gl-avatar-s24 {
69
+ @include gl-avatar-s24;
70
+ }
71
+
72
+ .gl-avatar-s32 {
73
+ @include gl-avatar-s32;
74
+ }
75
+
76
+ .gl-avatar-s48 {
77
+ @include gl-avatar-s48;
78
+ }
79
+
80
+ .gl-avatar-s64 {
81
+ @include gl-avatar-s64;
82
+ }
83
+
84
+ .gl-avatar-s96 {
85
+ @include gl-avatar-s96;
86
+ }
87
+
88
+ .gl-sm-avatar-s16 {
89
+ @include gl-media-breakpoint-up(sm) {
90
+ @include gl-avatar-s16;
91
+ }
92
+ }
93
+
94
+ .gl-md-avatar-s16 {
95
+ @include gl-media-breakpoint-up(md) {
96
+ @include gl-avatar-s16;
97
+ }
98
+ }
99
+
100
+ .gl-lg-avatar-s16 {
101
+ @include gl-media-breakpoint-up(lg) {
102
+ @include gl-avatar-s16;
103
+ }
104
+ }
105
+
106
+ .gl-sm-avatar-s24 {
107
+ @include gl-media-breakpoint-up(sm) {
108
+ @include gl-avatar-s24;
109
+ }
110
+ }
111
+
112
+ .gl-md-avatar-s24 {
113
+ @include gl-media-breakpoint-up(md) {
114
+ @include gl-avatar-s24;
115
+ }
116
+ }
117
+
118
+ .gl-lg-avatar-s24 {
119
+ @include gl-media-breakpoint-up(lg) {
120
+ @include gl-avatar-s24;
121
+ }
122
+ }
123
+
124
+ .gl-sm-avatar-s32 {
125
+ @include gl-media-breakpoint-up(sm) {
126
+ @include gl-avatar-s32;
127
+ }
128
+ }
129
+
130
+ .gl-md-avatar-s32 {
131
+ @include gl-media-breakpoint-up(md) {
132
+ @include gl-avatar-s32;
133
+ }
134
+ }
135
+
136
+ .gl-lg-avatar-s32 {
137
+ @include gl-media-breakpoint-up(lg) {
138
+ @include gl-avatar-s32;
139
+ }
140
+ }
141
+
142
+ .gl-sm-avatar-s48 {
143
+ @include gl-media-breakpoint-up(sm) {
144
+ @include gl-avatar-s48;
145
+ }
146
+ }
147
+
148
+ .gl-md-avatar-s48 {
149
+ @include gl-media-breakpoint-up(md) {
150
+ @include gl-avatar-s48;
151
+ }
152
+ }
153
+
154
+ .gl-lg-avatar-s48 {
155
+ @include gl-media-breakpoint-up(lg) {
156
+ @include gl-avatar-s48;
157
+ }
158
+ }
159
+
160
+ .gl-sm-avatar-s64 {
161
+ @include gl-media-breakpoint-up(sm) {
162
+ @include gl-avatar-s64;
163
+ }
164
+ }
165
+
166
+ .gl-md-avatar-s64 {
167
+ @include gl-media-breakpoint-up(md) {
168
+ @include gl-avatar-s64;
169
+ }
170
+ }
171
+
172
+ .gl-lg-avatar-s64 {
173
+ @include gl-media-breakpoint-up(lg) {
174
+ @include gl-avatar-s64;
175
+ }
176
+ }
177
+
178
+ .gl-sm-avatar-s96 {
179
+ @include gl-media-breakpoint-up(sm) {
180
+ @include gl-avatar-s96;
181
+ }
182
+ }
183
+
184
+ .gl-md-avatar-s96 {
185
+ @include gl-media-breakpoint-up(md) {
186
+ @include gl-avatar-s96;
187
+ }
188
+ }
189
+
190
+ .gl-lg-avatar-s96 {
191
+ @include gl-media-breakpoint-up(lg) {
192
+ @include gl-avatar-s96;
193
+ }
194
+ }
195
+
60
196
  .gl-avatar-circle {
61
197
  @include gl-rounded-full;
62
198
  }
@@ -18,16 +18,42 @@ describe('GlAvatar', () => {
18
18
  expect(wrapper.props('size')).toBe(avatarSizeOptions[1]);
19
19
  });
20
20
 
21
- it.each([96, 64, 48, 32, 24, 16])('accepts size %s', (size) => {
22
- createWrapper({ size });
21
+ describe('when number is passed', () => {
22
+ it.each([96, 64, 48, 32, 24, 16])('accepts size %s', (size) => {
23
+ createWrapper({ size });
23
24
 
24
- expect(wrapper.props('size')).toBe(size);
25
+ expect(wrapper.props('size')).toBe(size);
26
+ });
27
+
28
+ it.each([12, 28, 36, 54, 98])('displays an error for size %s', (size) => {
29
+ createWrapper({ size });
30
+
31
+ expect(wrapper).toHaveLoggedVueErrors();
32
+ });
33
+
34
+ it('adds correct CSS class to avatar', () => {
35
+ createWrapper({ size: 16 });
36
+
37
+ expect(wrapper.classes()).toContain('gl-avatar-s16');
38
+ });
25
39
  });
26
40
 
27
- it.each([12, 28, 36, 54, 98])('displays an error for size %s', (size) => {
28
- createWrapper({ size });
41
+ describe('when object is passed', () => {
42
+ it('displays error if any of the sizes are invalid', () => {
43
+ createWrapper({ size: { default: 16, md: 32, lg: 65 } });
44
+
45
+ expect(wrapper).toHaveLoggedVueErrors();
46
+ });
47
+
48
+ it('adds correct CSS classes to avatar', () => {
49
+ createWrapper({ size: { default: 16, md: 32, lg: 64 } });
29
50
 
30
- expect(wrapper).toHaveLoggedVueErrors();
51
+ expect(wrapper.classes()).toContain(
52
+ 'gl-avatar-s16',
53
+ 'gl-md-avatar-s32',
54
+ 'gl-lg-avatar-s64'
55
+ );
56
+ });
31
57
  });
32
58
  });
33
59
  });
@@ -59,6 +59,22 @@ export const Image = (args, { argTypes }) => ({
59
59
  });
60
60
  Image.args = generateImageProps();
61
61
 
62
+ export const ResponsiveImage = (args, { argTypes }) => ({
63
+ components,
64
+ props: Object.keys(argTypes),
65
+ template: `
66
+ <gl-avatar
67
+ :size="size"
68
+ :shape="shape"
69
+ src="https://about.gitlab.com/images/press/gitlab-summit-south-africa.jpg"
70
+ />
71
+ `,
72
+ });
73
+ ResponsiveImage.args = generateImageProps({ size: { default: 24, sm: 32, md: 48, lg: 96 } });
74
+ ResponsiveImage.argTypes = {
75
+ size: { control: 'object' },
76
+ };
77
+
62
78
  export const ProjectFallback = (args, { argTypes }) => ({
63
79
  components,
64
80
  props: Object.keys(argTypes),
@@ -1,5 +1,6 @@
1
1
  <!-- eslint-disable vue/multi-word-component-names -->
2
2
  <script>
3
+ import { isNumber } from 'lodash';
3
4
  import { avatarShapeOptions, avatarSizeOptions } from '../../../utils/constants';
4
5
  import { getAvatarChar } from '../../../utils/string_utils';
5
6
 
@@ -28,18 +29,24 @@ export default {
28
29
  default: 'avatar',
29
30
  },
30
31
  size: {
31
- type: Number,
32
+ type: [Number, Object],
32
33
  required: false,
33
34
  default: avatarSizeOptions[1],
34
35
  validator: (value) => {
35
- const isValidSize = avatarSizeOptions.includes(value);
36
+ const sizes = isNumber(value) ? [value] : Object.values(value);
37
+
38
+ const areValidSizes = sizes.every((size) => {
39
+ const isValidSize = avatarSizeOptions.includes(size);
40
+
41
+ if (!isValidSize) {
42
+ /* eslint-disable-next-line no-console */
43
+ console.error(`Avatar size should be one of [${avatarSizeOptions}], received: ${size}`);
44
+ }
36
45
 
37
- if (!isValidSize) {
38
- /* eslint-disable-next-line no-console */
39
- console.error(`Avatar size should be one of [${avatarSizeOptions}], received: ${value}`);
40
- }
46
+ return isValidSize;
47
+ });
41
48
 
42
- return isValidSize;
49
+ return areValidSizes;
43
50
  },
44
51
  },
45
52
  shape: {
@@ -49,8 +56,19 @@ export default {
49
56
  },
50
57
  },
51
58
  computed: {
52
- sizeClass() {
53
- return `gl-avatar-s${this.size}`;
59
+ sizeClasses() {
60
+ if (isNumber(this.size)) {
61
+ return `gl-avatar-s${this.size}`;
62
+ }
63
+
64
+ const { default: defaultSize, ...nonDefaultSizes } = this.size;
65
+
66
+ return [
67
+ `gl-avatar-s${defaultSize || avatarSizeOptions[1]}`,
68
+ ...Object.entries(nonDefaultSizes).map(
69
+ ([breakpoint, size]) => `gl-${breakpoint}-avatar-s${size}`
70
+ ),
71
+ ];
54
72
  },
55
73
  isCircle() {
56
74
  return this.shape === avatarShapeOptions.circle;
@@ -74,14 +92,14 @@ export default {
74
92
  v-if="src"
75
93
  :src="src"
76
94
  :alt="alt"
77
- :class="['gl-avatar', { 'gl-avatar-circle': isCircle }, sizeClass]"
95
+ :class="['gl-avatar', { 'gl-avatar-circle': isCircle }, sizeClasses]"
78
96
  />
79
97
  <div
80
98
  v-else
81
99
  :class="[
82
100
  'gl-avatar gl-avatar-identicon',
83
101
  { 'gl-avatar-circle': isCircle },
84
- sizeClass,
102
+ sizeClasses,
85
103
  identiconBackgroundClass,
86
104
  ]"
87
105
  >
@@ -195,5 +195,14 @@ describe('line component', () => {
195
195
 
196
196
  expect(findLegend().props('layout')).toBe(LEGEND_LAYOUT_TABLE);
197
197
  });
198
+ it('can be hidden', async () => {
199
+ createShallowWrapper({
200
+ showLegend: false,
201
+ });
202
+
203
+ await wrapper.vm.$nextTick();
204
+
205
+ expect(findLegend().exists()).toBe(false);
206
+ });
198
207
  });
199
208
  });
@@ -62,6 +62,7 @@ const template = `<gl-line-chart
62
62
  :thresholds="thresholds"
63
63
  :annotations="annotations"
64
64
  :includeLegendAvgMax="includeLegendAvgMax"
65
+ :showLegend="showLegend"
65
66
  />`;
66
67
 
67
68
  const generateProps = ({
@@ -70,7 +71,9 @@ const generateProps = ({
70
71
  thresholds = [],
71
72
  annotations = [],
72
73
  includeLegendAvgMax = true,
74
+ showLegend = true,
73
75
  } = {}) => ({
76
+ showLegend,
74
77
  includeLegendAvgMax,
75
78
  option,
76
79
  thresholds,
@@ -173,6 +176,27 @@ WithToolbox.args = generateProps({
173
176
  },
174
177
  });
175
178
 
179
+ export const NoLegend = Template.bind({});
180
+ NoLegend.args = generateProps({
181
+ data: [
182
+ {
183
+ name: 'Time Series',
184
+ data: generateTimeSeries(),
185
+ },
186
+ ],
187
+ option: {
188
+ animation: false,
189
+ xAxis: {
190
+ type: 'time',
191
+ name: 'Time',
192
+ axisLabel: {
193
+ formatter: timeSeriesDateFormatter,
194
+ },
195
+ },
196
+ },
197
+ showLegend: false,
198
+ });
199
+
176
200
  export default {
177
201
  title: 'charts/line-chart',
178
202
  component: GlLineChart,
@@ -117,6 +117,11 @@ export default {
117
117
  return [LEGEND_LAYOUT_INLINE, LEGEND_LAYOUT_TABLE].indexOf(layout) !== -1;
118
118
  },
119
119
  },
120
+ showLegend: {
121
+ type: Boolean,
122
+ required: false,
123
+ default: true,
124
+ },
120
125
  },
121
126
  data() {
122
127
  // Part of the tooltip related data can be
@@ -230,6 +235,9 @@ export default {
230
235
  legendStyle() {
231
236
  return { paddingLeft: `${grid.left}px` };
232
237
  },
238
+ hasLegend() {
239
+ return this.compiledOptions && this.showLegend;
240
+ },
233
241
  seriesInfo() {
234
242
  return this.compiledOptions.series.reduce((acc, series, index) => {
235
243
  if (series.type === 'line') {
@@ -366,7 +374,7 @@ export default {
366
374
  <tooltip-default-format v-else :tooltip-content="dataTooltipContent" />
367
375
  </chart-tooltip>
368
376
  <chart-legend
369
- v-if="compiledOptions"
377
+ v-if="hasLegend"
370
378
  :chart="chart"
371
379
  :style="legendStyle"
372
380
  :series-info="seriesInfo"
@@ -418,6 +418,14 @@
418
418
  background-color: $purple-50 !important
419
419
  }
420
420
 
421
+ .gl-bg-purple-800 {
422
+ background-color: $purple-800
423
+ }
424
+
425
+ .gl-bg-purple-800\! {
426
+ background-color: $purple-800 !important
427
+ }
428
+
421
429
  .gl-bg-red-50 {
422
430
  background-color: $red-50
423
431
  }
@@ -1197,6 +1205,14 @@
1197
1205
  border-color: $blue-700 !important;
1198
1206
  }
1199
1207
 
1208
+ .gl-border-purple-700 {
1209
+ border-color: $purple-700;
1210
+ }
1211
+
1212
+ .gl-border-purple-700\! {
1213
+ border-color: $purple-700 !important;
1214
+ }
1215
+
1200
1216
  .gl-border-gray-a-08 {
1201
1217
  border-color: $t-gray-a-08;
1202
1218
  }
@@ -2475,6 +2491,14 @@
2475
2491
  color: $purple-700 !important;
2476
2492
  }
2477
2493
 
2494
+ .gl-text-purple-800 {
2495
+ color: $purple-800;
2496
+ }
2497
+
2498
+ .gl-text-purple-800\! {
2499
+ color: $purple-800 !important;
2500
+ }
2501
+
2478
2502
  .gl-text-theme-indigo-200 {
2479
2503
  color: $theme-indigo-200;
2480
2504
  }
@@ -4723,6 +4747,14 @@
4723
4747
  min-height: $gl-spacing-scale-7 !important;
4724
4748
  }
4725
4749
 
4750
+ .gl-min-h-8 {
4751
+ min-height: $gl-spacing-scale-8;
4752
+ }
4753
+
4754
+ .gl-min-h-8\! {
4755
+ min-height: $gl-spacing-scale-8 !important;
4756
+ }
4757
+
4726
4758
  .gl-max-w-15 {
4727
4759
  max-width: $gl-spacing-scale-15;
4728
4760
  }
@@ -146,6 +146,10 @@
146
146
  background-color: $purple-50;
147
147
  }
148
148
 
149
+ @mixin gl-bg-purple-800 {
150
+ background-color: $purple-800;
151
+ }
152
+
149
153
  @mixin gl-bg-red-50 {
150
154
  background-color: $red-50;
151
155
  }
@@ -147,6 +147,10 @@
147
147
  border-color: $blue-700;
148
148
  }
149
149
 
150
+ @mixin gl-border-purple-700 {
151
+ border-color: $purple-700;
152
+ }
153
+
150
154
  @mixin gl-border-gray-a-08 {
151
155
  border-color: $t-gray-a-08;
152
156
  }
@@ -193,6 +193,10 @@
193
193
  color: $purple-700;
194
194
  }
195
195
 
196
+ @mixin gl-text-purple-800 {
197
+ color: $purple-800;
198
+ }
199
+
196
200
  @mixin gl-text-theme-indigo-200 {
197
201
  color: $theme-indigo-200;
198
202
  }
@@ -329,6 +329,10 @@
329
329
  min-height: $gl-spacing-scale-7;
330
330
  }
331
331
 
332
+ @mixin gl-min-h-8 {
333
+ min-height: $gl-spacing-scale-8;
334
+ }
335
+
332
336
  @mixin gl-max-w-15 {
333
337
  max-width: $gl-spacing-scale-15;
334
338
  }