@gitlab/ui 72.14.0 → 73.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/base/sorting/sorting.js +4 -9
  3. package/dist/index.js +0 -1
  4. package/dist/tokens/css/tokens.css +1 -1
  5. package/dist/tokens/css/tokens.dark.css +1 -1
  6. package/dist/tokens/js/tokens.dark.js +1 -1
  7. package/dist/tokens/js/tokens.js +1 -1
  8. package/dist/tokens/scss/_tokens.dark.scss +1 -1
  9. package/dist/tokens/scss/_tokens.scss +1 -1
  10. package/dist/utility_classes.css +1 -1
  11. package/dist/utility_classes.css.map +1 -1
  12. package/dist/utils/play_utils.js +11 -0
  13. package/package.json +4 -1
  14. package/src/components/base/button/button.stories.js +22 -7
  15. package/src/components/base/filtered_search/filtered_search.stories.js +10 -3
  16. package/src/components/base/filtered_search/filtered_search_suggestion_list.stories.js +6 -3
  17. package/src/components/base/filtered_search/filtered_search_term.stories.js +2 -3
  18. package/src/components/base/filtered_search/filtered_search_token.stories.js +5 -20
  19. package/src/components/base/filtered_search/filtered_search_token_segment.stories.js +3 -6
  20. package/src/components/base/form/form_combobox/form_combobox.stories.js +23 -9
  21. package/src/components/base/sorting/sorting.md +0 -63
  22. package/src/components/base/sorting/sorting.spec.js +11 -87
  23. package/src/components/base/sorting/sorting.stories.js +13 -47
  24. package/src/components/base/sorting/sorting.vue +2 -20
  25. package/src/components/base/toast/toast.stories.js +12 -9
  26. package/src/components/base/token_selector/token_selector.stories.js +8 -3
  27. package/src/components/base/tooltip/tooltip.stories.js +13 -3
  28. package/src/components/utilities/animated_number/animated_number.stories.js +0 -13
  29. package/src/index.js +0 -1
  30. package/src/scss/utilities.scss +2 -2
  31. package/src/scss/utility-mixins/typography.scss +1 -1
  32. package/src/utils/play_utils.js +9 -0
  33. package/dist/components/base/sorting/sorting_item.js +0 -109
  34. package/src/components/base/sorting/sorting_item.md +0 -5
  35. package/src/components/base/sorting/sorting_item.spec.js +0 -65
  36. package/src/components/base/sorting/sorting_item.stories.js +0 -50
  37. package/src/components/base/sorting/sorting_item.vue +0 -69
@@ -4,7 +4,6 @@ import GlButton from '../button/button.vue';
4
4
  import GlButtonGroup from '../button_group/button_group.vue';
5
5
  import GlCollapsibleListbox from '../new_dropdowns/listbox/listbox.vue';
6
6
  import { isOption } from '../new_dropdowns/listbox/utils';
7
- import GlDropdown from '../dropdown/dropdown.vue';
8
7
  import { translate } from '../../../utils/i18n';
9
8
 
10
9
  export default {
@@ -13,7 +12,6 @@ export default {
13
12
  GlButton,
14
13
  GlButtonGroup,
15
14
  GlCollapsibleListbox,
16
- GlDropdown,
17
15
  },
18
16
  directives: {
19
17
  GlTooltip: GlTooltipDirective,
@@ -33,7 +31,7 @@ export default {
33
31
  sortOptions: {
34
32
  type: Array,
35
33
  required: false,
36
- default: null,
34
+ default: () => [],
37
35
  // eslint-disable-next-line unicorn/no-array-callback-reference
38
36
  validator: (sortOptions) => sortOptions.every(isOption),
39
37
  },
@@ -64,7 +62,7 @@ export default {
64
62
  default: null,
65
63
  },
66
64
  /**
67
- * Additional class(es) to apply to the root element of the GlDropdown.
65
+ * Additional class(es) to apply to the root element of the GlCollapsibleListbox.
68
66
  */
69
67
  dropdownClass: {
70
68
  type: String,
@@ -99,9 +97,6 @@ export default {
99
97
  ? translate('GlSorting.sortAscending', 'Sort direction: ascending')
100
98
  : translate('GlSorting.sortDescending', 'Sort direction: descending');
101
99
  },
102
- useListbox() {
103
- return Boolean(this.sortOptions);
104
- },
105
100
  listboxToggleClass() {
106
101
  return [
107
102
  this.dropdownToggleClass,
@@ -144,7 +139,6 @@ export default {
144
139
  <template>
145
140
  <gl-button-group class="gl-sorting">
146
141
  <gl-collapsible-listbox
147
- v-if="useListbox"
148
142
  :toggle-text="text"
149
143
  :items="sortOptions"
150
144
  :selected="sortBy"
@@ -153,18 +147,6 @@ export default {
153
147
  placement="right"
154
148
  @select="onSortByChanged"
155
149
  />
156
- <gl-dropdown
157
- v-else
158
- v-bind="$props"
159
- :text="text"
160
- category="secondary"
161
- :class="dropdownClass"
162
- :toggle-class="dropdownToggleClass"
163
- right
164
- >
165
- <!-- @slot Deprecated slot to place the dropdown items, works best with a gl-sorting-item component. -->
166
- <slot></slot>
167
- </gl-dropdown>
168
150
  <gl-button
169
151
  v-gl-tooltip
170
152
  :title="sortDirectionText"
@@ -1,3 +1,5 @@
1
+ import { userEvent, within, waitFor } from '@storybook/testing-library';
2
+ import { expect } from '@storybook/jest';
1
3
  import Vue from 'vue';
2
4
  import GlButton from '../button/button.vue';
3
5
  import GlToast from './toast';
@@ -7,6 +9,13 @@ Vue.use(GlToast);
7
9
 
8
10
  const components = { GlToast, GlButton };
9
11
 
12
+ const play = async ({ canvasElement }) => {
13
+ const canvas = within(canvasElement);
14
+ const button = canvas.getByRole('button');
15
+ await userEvent.click(button);
16
+ await waitFor(() => expect(within(document).getByRole('status')).toBeVisible());
17
+ };
18
+
10
19
  const Template = (args, { argTypes }) => ({
11
20
  props: Object.keys(argTypes),
12
21
  components,
@@ -19,12 +28,10 @@ const Template = (args, { argTypes }) => ({
19
28
  this.$toast.show('This is the default toast.');
20
29
  },
21
30
  },
22
- mounted() {
23
- this.showToast();
24
- },
25
31
  });
26
32
 
27
33
  export const Default = Template.bind({});
34
+ Default.play = play;
28
35
 
29
36
  export const WithActions = () => ({
30
37
  components,
@@ -42,10 +49,8 @@ export const WithActions = () => ({
42
49
  });
43
50
  },
44
51
  },
45
- mounted() {
46
- this.showToast();
47
- },
48
52
  });
53
+ WithActions.play = play;
49
54
 
50
55
  export const WithLongContent = () => ({
51
56
  components,
@@ -66,10 +71,8 @@ export const WithLongContent = () => ({
66
71
  );
67
72
  },
68
73
  },
69
- mounted() {
70
- this.showToast();
71
- },
72
74
  });
75
+ WithLongContent.play = play;
73
76
 
74
77
  export default {
75
78
  title: 'base/toast',
@@ -1,3 +1,5 @@
1
+ import { userEvent, within, waitFor } from '@storybook/testing-library';
2
+ import { expect } from '@storybook/jest';
1
3
  import readme from './token_selector.md';
2
4
  import GlTokenSelector from './token_selector.vue';
3
5
 
@@ -45,9 +47,6 @@ const Template = (args, { argTypes }) => ({
45
47
  components: { GlTokenSelector },
46
48
  props: Object.keys(argTypes),
47
49
  template,
48
- mounted() {
49
- document.querySelector('.gl-token-selector input[type="text"]').focus();
50
- },
51
50
  data() {
52
51
  return {
53
52
  filteredDropdownItems: [],
@@ -90,6 +89,12 @@ const Template = (args, { argTypes }) => ({
90
89
  export const Default = Template.bind({});
91
90
  Default.tags = ['skip-visual-test'];
92
91
  Default.args = generateProps();
92
+ Default.play = async ({ canvasElement }) => {
93
+ const canvas = within(canvasElement);
94
+ const button = canvas.getByRole('textbox');
95
+ await userEvent.click(button);
96
+ await waitFor(() => expect(canvas.getByRole('menu')).toBeVisible());
97
+ };
93
98
 
94
99
  export default {
95
100
  title: 'base/token_selector',
@@ -1,3 +1,5 @@
1
+ import { userEvent, within, waitFor } from '@storybook/testing-library';
2
+ import { expect } from '@storybook/jest';
1
3
  import { GlTooltipDirective } from '../../../directives/tooltip';
2
4
  import GlButton from '../button/button.vue';
3
5
  import GlTooltip from './tooltip.vue';
@@ -19,31 +21,39 @@ function makeTooltip(modifier = '') {
19
21
  </gl-button>
20
22
  </div>
21
23
  `,
22
- mounted() {
23
- this.$nextTick(() => this.$el.querySelector('button').focus());
24
- },
25
24
  };
26
25
  }
27
26
 
27
+ const play = async ({ canvasElement }) => {
28
+ const canvas = within(canvasElement);
29
+ const button = canvas.getByRole('button');
30
+ await userEvent.click(button);
31
+ await waitFor(() => expect(within(document).getByRole('tooltip')).toBeVisible());
32
+ };
33
+
28
34
  export const TopDefault = (args, argTypes) => ({
29
35
  ...makeTooltip(),
30
36
  props: Object.keys(argTypes),
31
37
  });
38
+ TopDefault.play = play;
32
39
 
33
40
  export const Right = (args, argTypes) => ({
34
41
  ...makeTooltip('.right'),
35
42
  props: Object.keys(argTypes),
36
43
  });
44
+ Right.play = play;
37
45
 
38
46
  export const Bottom = (args, argTypes) => ({
39
47
  ...makeTooltip('.bottom'),
40
48
  props: Object.keys(argTypes),
41
49
  });
50
+ Bottom.play = play;
42
51
 
43
52
  export const Left = (args, argTypes) => ({
44
53
  ...makeTooltip('.left'),
45
54
  props: Object.keys(argTypes),
46
55
  });
56
+ Left.play = play;
47
57
 
48
58
  // A default export contains higher-level info about the component and the stories' settings.
49
59
  export default {
@@ -1,4 +1,3 @@
1
- import { setStoryTimeout } from '../../../utils/test_utils';
2
1
  import readme from './animated_number.md';
3
2
  import GlAnimatedNumber from './animated_number.vue';
4
3
 
@@ -31,26 +30,14 @@ const Template = (args, { argTypes }) => ({
31
30
  template,
32
31
  data() {
33
32
  return {
34
- isLoading: false,
35
- loadTimer: null,
36
33
  updatedNumber: this.initialNumber,
37
34
  };
38
35
  },
39
36
  methods: {
40
- loadView() {
41
- clearTimeout(this.loadTimer);
42
- this.isLoading = true;
43
- this.loadTimer = setStoryTimeout(() => {
44
- this.isLoading = false;
45
- }, 1500);
46
- },
47
37
  updateNumber() {
48
38
  this.updatedNumber = Math.floor(Math.random() * 100);
49
39
  },
50
40
  },
51
- mounted() {
52
- this.loadView();
53
- },
54
41
  });
55
42
 
56
43
  export const InitialAnimate = Template.bind({});
package/src/index.js CHANGED
@@ -76,7 +76,6 @@ export { default as GlDatepicker } from './components/base/datepicker/datepicker
76
76
  export { default as GlDaterangePicker } from './components/base/daterange_picker/daterange_picker.vue';
77
77
  export { default as GlToggle } from './components/base/toggle/toggle.vue';
78
78
  export { default as GlSorting } from './components/base/sorting/sorting.vue';
79
- export { default as GlSortingItem } from './components/base/sorting/sorting_item.vue';
80
79
  export { default as GlInfiniteScroll } from './components/base/infinite_scroll/infinite_scroll.vue';
81
80
  export { default as GlAlert } from './components/base/alert/alert.vue';
82
81
  export { default as GlSegmentedControl } from './components/base/segmented_control/segmented_control.vue';
@@ -8957,12 +8957,12 @@ $gl-animate-skeleton-loader-max-width: 64 * $grid-size;
8957
8957
  margin-bottom: $gl-mb-heading !important;
8958
8958
  }
8959
8959
 
8960
- .gl-heading-0{
8960
+ .gl-heading-display{
8961
8961
  @include gl-heading-scale-800;
8962
8962
  margin-bottom: $gl-mb-heading-display;
8963
8963
  }
8964
8964
 
8965
- .gl-heading-0\!{
8965
+ .gl-heading-display\!{
8966
8966
  @include gl-heading-scale-800;
8967
8967
  margin-bottom: $gl-mb-heading-display !important;
8968
8968
  }
@@ -97,7 +97,7 @@
97
97
  margin-bottom: $gl-mb-heading;
98
98
  }
99
99
 
100
- @mixin gl-heading-0 {
100
+ @mixin gl-heading-display {
101
101
  @include gl-heading-scale-800;
102
102
  margin-bottom: $gl-mb-heading-display;
103
103
  }
@@ -0,0 +1,9 @@
1
+ import { userEvent } from '@storybook/testing-library';
2
+
3
+ export const triggerBlurEvent = async () =>
4
+ userEvent.pointer([
5
+ {
6
+ keys: '[MouseLeft]',
7
+ coords: { x: 0, y: 0 },
8
+ },
9
+ ]);
@@ -1,109 +0,0 @@
1
- import GlDropdownItem from '../dropdown/dropdown_item';
2
- import GlIcon from '../icon/icon';
3
- import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
4
-
5
- /**
6
- * Sorting Item
7
- *
8
- * NOTE: This component is deprecated. Instead, use the `sortOptions` prop of
9
- * `GlSorting`.
10
- *
11
- * This is written as a functional component because it is a simple wrapper over
12
- * the GlDropdownItem component and does not use internal state. Functional
13
- * components are cheaper to render and often used as wrappers like this. We're
14
- * not using the <template functional> syntax here because it does not support
15
- * custom child components wihtout extra work inside GitLab or extra work
16
- * required by the user.
17
- */
18
-
19
- var script = {
20
- name: 'GlSortingItem',
21
- functional: true,
22
- props: {
23
- /**
24
- * Adds a check mark next to the item to indicate it is active.
25
- */
26
- active: {
27
- type: Boolean,
28
- default: false,
29
- required: false
30
- },
31
- /**
32
- * If given, makes the item a link pointing to the given value. Otherwise,
33
- * the item is a button.
34
- */
35
- href: {
36
- type: String,
37
- default: null,
38
- required: false
39
- }
40
- },
41
- /**
42
- * The content of the item.
43
- * @slot default
44
- */
45
- render(createElement, _ref) {
46
- let {
47
- scopedSlots,
48
- data,
49
- props = {}
50
- } = _ref;
51
- const classNames = `gl-sorting-item js-active-icon gl-flex-shrink-0 gl-mr-2 ${props.active ? '' : 'inactive gl-visibility-hidden'}`;
52
- const icon = createElement(GlIcon, {
53
- class: classNames,
54
- attrs: {
55
- name: 'mobile-issue-close',
56
- size: 16,
57
- ariaLabel: 'Selected'
58
- }
59
- });
60
- return createElement(GlDropdownItem, {
61
- ...data,
62
- attrs: {
63
- ...props
64
- },
65
- scopedSlots: {
66
- default: () => {
67
- var _scopedSlots$default;
68
- return [icon, (_scopedSlots$default = scopedSlots.default) === null || _scopedSlots$default === void 0 ? void 0 : _scopedSlots$default.call(scopedSlots)];
69
- }
70
- }
71
- });
72
- }
73
- };
74
-
75
- /* script */
76
- const __vue_script__ = script;
77
-
78
- /* template */
79
-
80
- /* style */
81
- const __vue_inject_styles__ = undefined;
82
- /* scoped */
83
- const __vue_scope_id__ = undefined;
84
- /* module identifier */
85
- const __vue_module_identifier__ = undefined;
86
- /* functional template */
87
- const __vue_is_functional_template__ = undefined;
88
- /* style inject */
89
-
90
- /* style inject SSR */
91
-
92
- /* style inject shadow dom */
93
-
94
-
95
-
96
- const __vue_component__ = __vue_normalize__(
97
- {},
98
- __vue_inject_styles__,
99
- __vue_script__,
100
- __vue_scope_id__,
101
- __vue_is_functional_template__,
102
- __vue_module_identifier__,
103
- false,
104
- undefined,
105
- undefined,
106
- undefined
107
- );
108
-
109
- export default __vue_component__;
@@ -1,5 +0,0 @@
1
- > **NOTE:** This component is deprecated. Instead, use the `sortOptions` prop of `GlSorting`.
2
-
3
- The sorting item component is meant to be used for clickable entries inside a `gl-sorting` component.
4
- This is a wrapper around the `gl-dropdown-item` component and includes a check icon when active,
5
- and an empty space for alignment when not.
@@ -1,65 +0,0 @@
1
- import { shallowMount } from '@vue/test-utils';
2
- import GlDropdownItem from '../dropdown/dropdown_item.vue';
3
- import GlSortingItem from './sorting_item.vue';
4
-
5
- describe('sorting item component', () => {
6
- let wrapper;
7
-
8
- const sortingItemText = 'Some test text';
9
-
10
- const defaultProps = {};
11
-
12
- const findActiveIcon = () => wrapper.find('.js-active-icon');
13
- const findGlDropdownItem = () => wrapper.findComponent(GlDropdownItem);
14
-
15
- const createComponent = (propsData) => {
16
- wrapper = shallowMount(GlSortingItem, {
17
- context: {
18
- props: {
19
- ...defaultProps,
20
- ...propsData,
21
- },
22
- },
23
- slots: {
24
- default: sortingItemText,
25
- },
26
- stubs: {
27
- GlDropdownItem,
28
- },
29
- });
30
- };
31
-
32
- it('should render and display the supplied text', () => {
33
- createComponent();
34
-
35
- expect(wrapper.text()).toBe(sortingItemText);
36
- });
37
-
38
- it('does not show the check icon when the active prop is not provided', () => {
39
- createComponent();
40
-
41
- expect(findActiveIcon().exists()).toBe(true);
42
- expect(findActiveIcon().classes()).toContain('inactive');
43
- });
44
-
45
- it('does render a check icon when the active prop is provided', () => {
46
- createComponent({
47
- active: true,
48
- });
49
-
50
- expect(findActiveIcon().exists()).toBe(true);
51
- expect(findActiveIcon().classes()).not.toContain('inactive');
52
- });
53
-
54
- it('passes the props down to the gl-dropdown-item component', () => {
55
- const url = 'https://about.gitlab.com';
56
-
57
- createComponent({
58
- active: true,
59
- href: url,
60
- });
61
-
62
- expect(findGlDropdownItem().attributes('active')).toBe('true');
63
- expect(findGlDropdownItem().attributes('href')).toBe(url);
64
- });
65
- });
@@ -1,50 +0,0 @@
1
- import { makeContainer } from '../../../utils/story_decorators/container';
2
- import GlSortingItem from './sorting_item.vue';
3
- import GlSorting from './sorting.vue';
4
- import readme from './sorting_item.md';
5
-
6
- const components = {
7
- GlSorting,
8
- GlSortingItem,
9
- };
10
-
11
- const generateProps = ({ href = null, active = false } = {}) => ({
12
- href,
13
- active,
14
- });
15
-
16
- const template = `
17
- <gl-sorting text="Sorting options">
18
- <gl-sorting-item :href="href" :active="active">Some item</gl-sorting-item>
19
- </gl-sorting>`;
20
-
21
- const Template = (args) => ({
22
- components,
23
- props: Object.keys(args),
24
- mounted() {
25
- this.$nextTick(() => this.$el.querySelector('.gl-dropdown-toggle').click());
26
- },
27
- template,
28
- });
29
-
30
- export const Default = Template.bind({});
31
- Default.args = generateProps();
32
-
33
- export const WithHref = Template.bind({});
34
- WithHref.args = generateProps({ href: 'https://about.gitlab.com/' });
35
-
36
- export const WithActive = Template.bind({});
37
- WithActive.args = generateProps({ active: true });
38
-
39
- export default {
40
- title: 'base/sorting/sorting-item',
41
- component: GlSortingItem,
42
- decorators: [makeContainer({ height: '50px', paddingLeft: '100px' })],
43
- parameters: {
44
- docs: {
45
- description: {
46
- component: readme,
47
- },
48
- },
49
- },
50
- };
@@ -1,69 +0,0 @@
1
- <script>
2
- import GlDropdownItem from '../dropdown/dropdown_item.vue';
3
- import GlIcon from '../icon/icon.vue';
4
-
5
- /**
6
- * Sorting Item
7
- *
8
- * NOTE: This component is deprecated. Instead, use the `sortOptions` prop of
9
- * `GlSorting`.
10
- *
11
- * This is written as a functional component because it is a simple wrapper over
12
- * the GlDropdownItem component and does not use internal state. Functional
13
- * components are cheaper to render and often used as wrappers like this. We're
14
- * not using the <template functional> syntax here because it does not support
15
- * custom child components wihtout extra work inside GitLab or extra work
16
- * required by the user.
17
- */
18
-
19
- export default {
20
- name: 'GlSortingItem',
21
- functional: true,
22
- props: {
23
- /**
24
- * Adds a check mark next to the item to indicate it is active.
25
- */
26
- active: {
27
- type: Boolean,
28
- default: false,
29
- required: false,
30
- },
31
- /**
32
- * If given, makes the item a link pointing to the given value. Otherwise,
33
- * the item is a button.
34
- */
35
- href: {
36
- type: String,
37
- default: null,
38
- required: false,
39
- },
40
- },
41
- /**
42
- * The content of the item.
43
- * @slot default
44
- */
45
- render(createElement, { scopedSlots, data, props = {} }) {
46
- const classNames = `gl-sorting-item js-active-icon gl-flex-shrink-0 gl-mr-2 ${
47
- props.active ? '' : 'inactive gl-visibility-hidden'
48
- }`;
49
- const icon = createElement(GlIcon, {
50
- class: classNames,
51
- attrs: {
52
- name: 'mobile-issue-close',
53
- size: 16,
54
- ariaLabel: 'Selected',
55
- },
56
- });
57
-
58
- return createElement(GlDropdownItem, {
59
- ...data,
60
- attrs: {
61
- ...props,
62
- },
63
- scopedSlots: {
64
- default: () => [icon, scopedSlots.default?.()],
65
- },
66
- });
67
- },
68
- };
69
- </script>