@gitlab/ui 39.6.1 → 40.0.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/dist/index.js CHANGED
@@ -21,7 +21,7 @@ export { default as GlPaginatedList } from './components/base/paginated_list/pag
21
21
  export { default as GlPopover } from './components/base/popover/popover';
22
22
  export { default as GlProgressBar } from './components/base/progress_bar/progress_bar';
23
23
  export { default as GlToken } from './components/base/token/token';
24
- export { default as GlDeprecatedSkeletonLoading, default as GlSkeletonLoading } from './components/base/skeleton_loading/skeleton_loading';
24
+ export { default as GlDeprecatedSkeletonLoading } from './components/base/skeleton_loading/skeleton_loading';
25
25
  export { default as GlBadge } from './components/base/badge/badge';
26
26
  export { default as GlBanner } from './components/base/banner/banner';
27
27
  export { default as GlButton } from './components/base/button/button';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "39.6.1",
3
+ "version": "40.0.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -83,7 +83,7 @@
83
83
  "@babel/preset-env": "^7.10.2",
84
84
  "@gitlab/eslint-plugin": "12.0.1",
85
85
  "@gitlab/stylelint-config": "4.0.0",
86
- "@gitlab/svgs": "2.11.0",
86
+ "@gitlab/svgs": "2.12.0",
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",
@@ -294,6 +294,7 @@ export const glTransitionDurationSlow = '0.4s'
294
294
  export const glTransitionDurationMedium = '0.2s'
295
295
  export const outlineOffset = '1px'
296
296
  export const outlineWidth = '2px'
297
+ export const outline = '3px'
297
298
  export const focusRing = '0 0 0 1px #fff, 0 0 0 3px #428fdc'
298
299
  export const focusRingInset = 'inset 0 0 0 3px #fff, inset 0 0 0 1px #fff'
299
300
  export const focusRingDark = '0 0 0 1px rgba(0, 0, 0, 0.6), 0 0 0 3px #63a6e9'
@@ -1531,6 +1531,11 @@
1531
1531
  "value": "2px",
1532
1532
  "compiledValue": "2px"
1533
1533
  },
1534
+ {
1535
+ "name": "$outline",
1536
+ "value": "#{$outline-offset + $outline-width}",
1537
+ "compiledValue": "3px"
1538
+ },
1534
1539
  {
1535
1540
  "name": "$focus-ring",
1536
1541
  "value": "0 0 0 $outline-offset $white, 0 0 0 #{$outline-offset + $outline-width} $blue-400",
@@ -47,10 +47,18 @@
47
47
  }
48
48
  }
49
49
 
50
- .gl-form-input {
51
- @each $name, $size in $gl-form-input-sizes {
52
- &-#{$name} {
53
- max-width: $size;
50
+ @each $name, $size in $gl-form-input-sizes {
51
+ .gl-form-input-#{$name} {
52
+ max-width: $size;
53
+ }
54
+
55
+ @each $breakpointName, $breakpointSize in $gl-form-input-sizes {
56
+ @if $breakpointName != xs {
57
+ .gl-#{$breakpointName}-form-input-#{$name} {
58
+ @include gl-media-breakpoint-up($breakpointName) {
59
+ max-width: $size;
60
+ }
61
+ }
54
62
  }
55
63
  }
56
64
  }
@@ -15,25 +15,54 @@ describe('GlFormInput', () => {
15
15
  };
16
16
 
17
17
  describe('size prop', () => {
18
- // Exclude the default null value
19
- const sizes = Object.values(formInputSizes).filter(Boolean);
18
+ describe('when number is passed', () => {
19
+ // Exclude the default null value
20
+ const sizes = Object.values(formInputSizes).filter(Boolean);
20
21
 
21
- it.each(sizes)('adds correct class for size %s', (size) => {
22
- createComponent({ size });
22
+ it.each(sizes)('adds correct class for size %s', (size) => {
23
+ createComponent({ size });
23
24
 
24
- expect(wrapper.classes()).toEqual(['gl-form-input', `gl-form-input-${size}`]);
25
- });
25
+ expect(wrapper.classes()).toEqual(['gl-form-input', `gl-form-input-${size}`]);
26
+ });
27
+
28
+ it('does not add a size class if not given the size prop', () => {
29
+ createComponent();
30
+
31
+ expect(wrapper.classes()).toEqual(['gl-form-input']);
32
+ });
26
33
 
27
- it('does not add a size class if not given the size prop', () => {
28
- createComponent();
34
+ it('does not add a size class if passed null', () => {
35
+ createComponent({ size: null });
29
36
 
30
- expect(wrapper.classes()).toEqual(['gl-form-input']);
37
+ expect(wrapper.classes()).toEqual(['gl-form-input']);
38
+ });
31
39
  });
32
40
 
33
- it('does not add a size class if passed null', () => {
34
- createComponent({ size: null });
41
+ describe('when object is passed', () => {
42
+ describe('when `default` key is provided', () => {
43
+ it('adds responsive CSS classes and base class', () => {
44
+ createComponent({ size: { default: 'md', md: 'lg', lg: 'xl' } });
45
+
46
+ expect(wrapper.classes()).toEqual([
47
+ 'gl-form-input',
48
+ 'gl-form-input-md',
49
+ 'gl-md-form-input-lg',
50
+ 'gl-lg-form-input-xl',
51
+ ]);
52
+ });
53
+ });
54
+
55
+ describe('when `default` key is not provided', () => {
56
+ it('adds responsive CSS classes', () => {
57
+ createComponent({ size: { md: 'lg', lg: 'xl' } });
35
58
 
36
- expect(wrapper.classes()).toEqual(['gl-form-input']);
59
+ expect(wrapper.classes()).toEqual([
60
+ 'gl-form-input',
61
+ 'gl-md-form-input-lg',
62
+ 'gl-lg-form-input-xl',
63
+ ]);
64
+ });
65
+ });
37
66
  });
38
67
  });
39
68
 
@@ -57,6 +57,25 @@ export const Sizes = (args, { argTypes }) => ({
57
57
  });
58
58
  Sizes.args = {};
59
59
 
60
+ export const ResponsiveSizes = (args, { argTypes }) => ({
61
+ components: { GlFormInput },
62
+ props: Object.keys(argTypes),
63
+ template: `
64
+ <div>
65
+ <gl-form-input
66
+ :size="{ default: 'md', md: 'lg', lg: 'xl' }"
67
+ value="With \`default\` key"
68
+ />
69
+ <gl-form-input
70
+ class="gl-mt-4"
71
+ :size="{ md: 'lg', lg: 'xl' }"
72
+ value="Without \`default\` key"
73
+ />
74
+ </div>
75
+ `,
76
+ });
77
+ ResponsiveSizes.args = {};
78
+
60
79
  export default {
61
80
  title: 'base/form/form-input',
62
81
  component: GlFormInput,
@@ -1,5 +1,7 @@
1
1
  <script>
2
+ import { isObject } from 'lodash';
2
3
  import { BFormInput } from 'bootstrap-vue';
4
+
3
5
  import { formInputSizes } from '../../../../utils/constants';
4
6
 
5
7
  const MODEL_PROP = 'value';
@@ -19,17 +21,34 @@ export default {
19
21
  * Maximum width of the input
20
22
  */
21
23
  size: {
22
- type: String,
24
+ type: [String, Object],
23
25
  required: false,
24
26
  default: null,
25
- validator: (value) => Object.values(formInputSizes).includes(value),
27
+ validator: (value) => {
28
+ const sizes = isObject(value) ? Object.values(value) : [value];
29
+
30
+ return sizes.every((size) => Object.values(formInputSizes).includes(size));
31
+ },
26
32
  },
27
33
  },
28
34
  computed: {
29
35
  cssClasses() {
30
- return {
31
- [`gl-form-input-${this.size}`]: this.size !== null,
32
- };
36
+ if (this.size === null) {
37
+ return [];
38
+ }
39
+
40
+ if (isObject(this.size)) {
41
+ const { default: defaultSize, ...nonDefaultSizes } = this.size;
42
+
43
+ return [
44
+ ...(defaultSize ? [`gl-form-input-${defaultSize}`] : []),
45
+ ...Object.entries(nonDefaultSizes).map(
46
+ ([breakpoint, size]) => `gl-${breakpoint}-form-input-${size}`
47
+ ),
48
+ ];
49
+ }
50
+
51
+ return [`gl-form-input-${this.size}`];
33
52
  },
34
53
  listeners() {
35
54
  return {
@@ -73,7 +73,7 @@ describe('Infinite Scroll component', () => {
73
73
 
74
74
  expect(wrapper.emitted('bottomReached')).toBeFalsy();
75
75
 
76
- mockScrollTo({ top: INITIAL_HEIGHT });
76
+ mockScrollTo({ top: INITIAL_HEIGHT - 0.5 });
77
77
  expect(wrapper.emitted('bottomReached')).toBeTruthy();
78
78
  });
79
79
 
@@ -7,6 +7,7 @@ const throttleDuration = 1000;
7
7
  * Values in pixels, should be a small amount.
8
8
  */
9
9
  export const adjustScrollGap = 5;
10
+ const THRESHOLD = 1;
10
11
 
11
12
  export default {
12
13
  props: {
@@ -138,9 +139,9 @@ export default {
138
139
  return this.$refs.infiniteContainer.scrollTop;
139
140
  },
140
141
  handleScroll: throttle(function handleScrollThrottled() {
141
- if (this.scrollTop() + this.maxListHeight >= this.itemsListHeight()) {
142
+ if (Math.abs(this.itemsListHeight() - this.maxListHeight - this.scrollTop()) < THRESHOLD) {
142
143
  this.bottomReached();
143
- } else if (this.scrollTop() === 0) {
144
+ } else if (this.scrollTop() <= THRESHOLD) {
144
145
  this.topReached();
145
146
  }
146
147
  }),
@@ -67,5 +67,5 @@ If you want to use custom template for rendering the listbox item, use the `list
67
67
  </span>
68
68
  </span>
69
69
  </template>
70
- </gl-litsbox>
70
+ </gl-listbox>
71
71
  ```
@@ -37,7 +37,6 @@
37
37
 
38
38
  > .gl-tab-counter-badge {
39
39
  font-weight: inherit;
40
- color: inherit;
41
40
  @include gl-ml-2;
42
41
  }
43
42
  }
@@ -1,5 +1,6 @@
1
1
  import { range } from 'lodash';
2
2
  import { GlTabs, GlTab, GlScrollableTabs, GlBadge } from '../../../../index';
3
+ import { badgeVariantOptions } from '../../../../utils/constants';
3
4
  import readme from './tabs.md';
4
5
 
5
6
  const components = {
@@ -152,28 +153,18 @@ export const WithCounterBadges = (_args, { argTypes }) => ({
152
153
  props: Object.keys(argTypes),
153
154
  components: { ...components, GlBadge },
154
155
  template: wrap(`
155
- <gl-tab>
156
+ <gl-tab
157
+ v-for="variant in $options.badgeVariantOptions"
158
+ :key="variant"
159
+ >
156
160
  <template #title>
157
161
  <span>Tab</span>
158
- <gl-badge size="sm" class="gl-tab-counter-badge">500</gl-badge>
162
+ <gl-badge size="sm" class="gl-tab-counter-badge" :variant="variant">500</gl-badge>
159
163
  <span class="sr-only">items</span>
160
164
  </template>
161
- Tab panel 1
162
- </gl-tab>
163
- <gl-tab>
164
- <template #title>
165
- <span>Tab</span>
166
- <gl-badge size="sm" class="gl-tab-counter-badge">250</gl-badge>
167
- <span class="sr-only">items</span>
168
- </template>
169
- Tab panel 2
170
- </gl-tab>
171
- <gl-tab>
172
- <template #title>
173
- <span>Tab</span>
174
- </template>
175
- Tab panel 3
165
+ Tab panel {{ variant }}
176
166
  </gl-tab>`),
167
+ badgeVariantOptions,
177
168
  });
178
169
 
179
170
  export const WithActions = (_args, { argTypes }) => ({
package/src/index.js CHANGED
@@ -28,10 +28,7 @@ export { default as GlPaginatedList } from './components/base/paginated_list/pag
28
28
  export { default as GlPopover } from './components/base/popover/popover.vue';
29
29
  export { default as GlProgressBar } from './components/base/progress_bar/progress_bar.vue';
30
30
  export { default as GlToken } from './components/base/token/token.vue';
31
- export {
32
- default as GlSkeletonLoading,
33
- default as GlDeprecatedSkeletonLoading,
34
- } from './components/base/skeleton_loading/skeleton_loading.vue';
31
+ export { default as GlDeprecatedSkeletonLoading } from './components/base/skeleton_loading/skeleton_loading.vue';
35
32
  export { default as GlBadge } from './components/base/badge/badge.vue';
36
33
  export { default as GlBanner } from './components/base/banner/banner.vue';
37
34
  export { default as GlButton } from './components/base/button/button.vue';
@@ -420,6 +420,7 @@ $gl-transition-duration-medium: 0.2s;
420
420
  // Focus ring
421
421
  $outline-offset: 1px;
422
422
  $outline-width: 2px;
423
+ $outline: #{$outline-offset + $outline-width};
423
424
  $focus-ring: 0 0 0 $outline-offset $white, 0 0 0 #{$outline-offset + $outline-width} $blue-400;
424
425
  $focus-ring-inset: inset 0 0 0 #{$outline-width + $outline-offset} $white,
425
426
  inset 0 0 0 $outline-offset $white;