@gitlab/ui 77.4.0 → 77.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.
Files changed (27) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/components/base/new_dropdowns/disclosure/disclosure_dropdown_item.js +22 -12
  3. package/dist/components/base/new_dropdowns/disclosure/mock_data.js +6 -0
  4. package/dist/components/experimental/duo/chat/duo_chat.js +1 -1
  5. package/dist/index.css +1 -1
  6. package/dist/index.css.map +1 -1
  7. package/dist/tokens/css/tokens.css +4 -4
  8. package/dist/tokens/css/tokens.dark.css +4 -1
  9. package/dist/tokens/js/tokens.dark.js +4 -1
  10. package/dist/tokens/js/tokens.js +1 -1
  11. package/dist/tokens/json/tokens.dark.json +9 -9
  12. package/dist/tokens/json/tokens.json +3 -3
  13. package/dist/tokens/scss/_tokens.dark.scss +4 -1
  14. package/dist/tokens/scss/_tokens.scss +4 -4
  15. package/package.json +1 -1
  16. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.md +3 -1
  17. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.spec.js +8 -4
  18. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown_item.spec.js +14 -5
  19. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown_item.vue +11 -5
  20. package/src/components/base/new_dropdowns/disclosure/mock_data.js +7 -0
  21. package/src/components/experimental/duo/chat/duo_chat.scss +6 -0
  22. package/src/components/experimental/duo/chat/duo_chat.vue +1 -1
  23. package/src/tokens/text.dark.tokens.json +19 -0
  24. package/src/tokens/text.dark.tokens.stories.js +13 -0
  25. package/src/tokens/text.tokens.json +3 -3
  26. package/src/tokens/text.tokens.stories.js +1 -1
  27. package/tailwind.defaults.js +28 -16
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 28 Feb 2024 13:41:10 GMT
3
+ * Generated on Fri, 01 Mar 2024 18:36:36 GMT
4
4
  */
5
5
 
6
6
  :root {
7
+ --gl-text-tertiary: #89888d;
8
+ --gl-text-secondary: #737278;
9
+ --gl-text-primary: #333238;
7
10
  --gl-line-height-52: 3.25rem;
8
11
  --gl-line-height-44: 2.75rem;
9
12
  --gl-line-height-42: 2.625rem;
@@ -234,7 +237,4 @@
234
237
  --data-viz-green-200: #b0d97b;
235
238
  --data-viz-green-100: #c6ed94;
236
239
  --data-viz-green-50: #ddfab7;
237
- --gl-text-tertiary: var(--gray-400);
238
- --gl-text-secondary: var(--gray-500);
239
- --gl-text-primary: var(--gray-900);
240
240
  }
@@ -1,9 +1,12 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 28 Feb 2024 13:41:11 GMT
3
+ * Generated on Fri, 01 Mar 2024 18:36:36 GMT
4
4
  */
5
5
 
6
6
  :root.gl-dark {
7
+ --gl-text-tertiary: #737278;
8
+ --gl-text-secondary: #89888d;
9
+ --gl-text-primary: #ececef;
7
10
  --red-950: #fff4f3;
8
11
  --red-900: #fcf1ef;
9
12
  --red-800: #fdd4cd;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 28 Feb 2024 13:41:11 GMT
3
+ * Generated on Fri, 01 Mar 2024 18:36:36 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#133a03";
@@ -199,3 +199,6 @@ export const RED_700 = "#fcb5aa";
199
199
  export const RED_800 = "#fdd4cd";
200
200
  export const RED_900 = "#fcf1ef";
201
201
  export const RED_950 = "#fff4f3";
202
+ export const GL_TEXT_PRIMARY = "#ececef";
203
+ export const GL_TEXT_SECONDARY = "#89888d";
204
+ export const GL_TEXT_TERTIARY = "#737278";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 28 Feb 2024 13:41:10 GMT
3
+ * Generated on Fri, 01 Mar 2024 18:36:36 GMT
4
4
  */
5
5
 
6
6
  export const DATA_VIZ_GREEN_50 = "#ddfab7";
@@ -4801,10 +4801,10 @@
4801
4801
  "value": "#ececef",
4802
4802
  "$type": "color",
4803
4803
  "themeable": true,
4804
- "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.tokens.json",
4805
- "isSource": false,
4804
+ "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.dark.tokens.json",
4805
+ "isSource": true,
4806
4806
  "original": {
4807
- "value": "{gray.900}",
4807
+ "value": "#ececef",
4808
4808
  "$type": "color",
4809
4809
  "themeable": true
4810
4810
  },
@@ -4819,10 +4819,10 @@
4819
4819
  "value": "#89888d",
4820
4820
  "$type": "color",
4821
4821
  "themeable": true,
4822
- "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.tokens.json",
4823
- "isSource": false,
4822
+ "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.dark.tokens.json",
4823
+ "isSource": true,
4824
4824
  "original": {
4825
- "value": "{gray.500}",
4825
+ "value": "#89888d",
4826
4826
  "$type": "color",
4827
4827
  "themeable": true
4828
4828
  },
@@ -4837,10 +4837,10 @@
4837
4837
  "value": "#737278",
4838
4838
  "$type": "color",
4839
4839
  "themeable": true,
4840
- "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.tokens.json",
4841
- "isSource": false,
4840
+ "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.dark.tokens.json",
4841
+ "isSource": true,
4842
4842
  "original": {
4843
- "value": "{gray.400}",
4843
+ "value": "#737278",
4844
4844
  "$type": "color",
4845
4845
  "themeable": true
4846
4846
  },
@@ -4804,7 +4804,7 @@
4804
4804
  "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.tokens.json",
4805
4805
  "isSource": false,
4806
4806
  "original": {
4807
- "value": "{gray.900}",
4807
+ "value": "#333238",
4808
4808
  "$type": "color",
4809
4809
  "themeable": true
4810
4810
  },
@@ -4822,7 +4822,7 @@
4822
4822
  "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.tokens.json",
4823
4823
  "isSource": false,
4824
4824
  "original": {
4825
- "value": "{gray.500}",
4825
+ "value": "#737278",
4826
4826
  "$type": "color",
4827
4827
  "themeable": true
4828
4828
  },
@@ -4840,7 +4840,7 @@
4840
4840
  "filePath": "/builds/gitlab-org/gitlab-ui/src/tokens/text.tokens.json",
4841
4841
  "isSource": false,
4842
4842
  "original": {
4843
- "value": "{gray.400}",
4843
+ "value": "#89888d",
4844
4844
  "$type": "color",
4845
4845
  "themeable": true
4846
4846
  },
@@ -1,7 +1,10 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Wed, 28 Feb 2024 13:41:11 GMT
3
+ // Generated on Fri, 01 Mar 2024 18:36:36 GMT
4
4
 
5
+ $gl-text-tertiary: #737278 !default;
6
+ $gl-text-secondary: #89888d !default;
7
+ $gl-text-primary: #ececef !default;
5
8
  $red-950: #fff4f3;
6
9
  $red-900: #fcf1ef;
7
10
  $red-800: #fdd4cd;
@@ -1,7 +1,10 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Wed, 28 Feb 2024 13:41:10 GMT
3
+ // Generated on Fri, 01 Mar 2024 18:36:36 GMT
4
4
 
5
+ $gl-text-tertiary: #89888d !default;
6
+ $gl-text-secondary: #737278 !default;
7
+ $gl-text-primary: #333238 !default;
5
8
  $gl-line-height-52: 3.25rem;
6
9
  $gl-line-height-44: 2.75rem;
7
10
  $gl-line-height-42: 2.625rem;
@@ -232,6 +235,3 @@ $data-viz-green-300: #94c25e !default;
232
235
  $data-viz-green-200: #b0d97b !default;
233
236
  $data-viz-green-100: #c6ed94 !default;
234
237
  $data-viz-green-50: #ddfab7 !default;
235
- $gl-text-tertiary: $gray-400 !default;
236
- $gl-text-secondary: $gray-500 !default;
237
- $gl-text-primary: $gray-900 !default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "77.4.0",
3
+ "version": "77.6.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -64,7 +64,7 @@ After closing, `GlDisclosureDropdown` emits a `hidden` event.
64
64
  ## Setting disclosure dropdown items
65
65
 
66
66
  Use the `items` prop to provide actions/links to the disclosure dropdown. Each
67
- item can be either an item or a group. For `Item`s, provide an `href` string to
67
+ item can be either an item or a group. For `Item`s, provide an `href` or `to` string to
68
68
  make them render as links. Otherwise, they will be buttons. Provide an `action`
69
69
  function to items to be called when they are pressed, or, listen for the
70
70
  `action` event on the top-level component. Both will receive the given item as
@@ -81,6 +81,8 @@ type Item = {
81
81
  text: string;
82
82
  // href link
83
83
  href?: string;
84
+ // or, a Vue router link with `to`
85
+ to?: string;
84
86
  // Item action
85
87
  action?: (item: Item) => void;
86
88
  // Set of extra attributes applied directly to the element
@@ -140,6 +140,7 @@ describe('GlDisclosureDropdown', () => {
140
140
  let firstItem;
141
141
  let secondItem;
142
142
  let thirdItem;
143
+ let fourthItem;
143
144
 
144
145
  beforeEach(() => {
145
146
  buildWrapper({ items: mockItems });
@@ -147,6 +148,7 @@ describe('GlDisclosureDropdown', () => {
147
148
  firstItem = findListItem(0);
148
149
  secondItem = findListItem(1);
149
150
  thirdItem = findListItem(2);
151
+ fourthItem = findListItem(3);
150
152
  });
151
153
 
152
154
  it('should move the focus from toggle and down the list of items on `ARROW_DOWN` and stop on the last item', async () => {
@@ -160,7 +162,9 @@ describe('GlDisclosureDropdown', () => {
160
162
  await secondItem.trigger('keydown', { code: ARROW_DOWN });
161
163
  expect(thirdItem.element).toHaveFocus();
162
164
  await thirdItem.trigger('keydown', { code: ARROW_DOWN });
163
- expect(thirdItem.element).toHaveFocus();
165
+ expect(fourthItem.element).toHaveFocus();
166
+ await fourthItem.trigger('keydown', { code: ARROW_DOWN });
167
+ expect(fourthItem.element).toHaveFocus();
164
168
  });
165
169
 
166
170
  it('should move the focus up the list of items on `ARROW_UP` and stop on the first item', async () => {
@@ -182,9 +186,9 @@ describe('GlDisclosureDropdown', () => {
182
186
  );
183
187
  expect(firstItem.element).toHaveFocus();
184
188
  await firstItem.trigger('keydown', { code: END });
185
- expect(thirdItem.element).toHaveFocus();
186
- await thirdItem.trigger('keydown', { code: END });
187
- expect(thirdItem.element).toHaveFocus();
189
+ expect(fourthItem.element).toHaveFocus();
190
+ await fourthItem.trigger('keydown', { code: END });
191
+ expect(fourthItem.element).toHaveFocus();
188
192
  });
189
193
 
190
194
  it('should move focus to the first item on `HOME` keydown', async () => {
@@ -1,4 +1,5 @@
1
1
  import { mount } from '@vue/test-utils';
2
+ import { BLink } from 'bootstrap-vue';
2
3
  import { ENTER, SPACE } from '../constants';
3
4
  import { mockItems } from './mock_data';
4
5
 
@@ -47,21 +48,29 @@ describe('GlDisclosureDropdownItem', () => {
47
48
  });
48
49
  });
49
50
 
50
- describe('when item has a `href`', () => {
51
- const item = mockItems[0];
51
+ describe.each`
52
+ prop | mockItem
53
+ ${'href'} | ${0}
54
+ ${'to'} | ${3}
55
+ `('when item has a `$prop`', ({ prop, mockItem }) => {
56
+ const item = mockItems[mockItem];
52
57
 
53
58
  beforeEach(() => {
54
59
  buildWrapper({ item });
55
60
  });
56
61
 
57
- const findLink = () => wrapper.find('a.gl-new-dropdown-item-content');
62
+ const findLink = () => wrapper.findComponent(BLink);
58
63
 
59
64
  it('should render a link', () => {
60
65
  expect(findLink().exists()).toBe(true);
61
66
  });
62
67
 
63
- it('should set correct attributes', () => {
64
- expect(findLink().attributes('href')).toBe(item.href);
68
+ it('should set correct class', () => {
69
+ expect(findLink().classes()).toContain('gl-new-dropdown-item-content');
70
+ });
71
+
72
+ it('should set correct props and attributes', () => {
73
+ expect(findLink().props(prop)).toBe(item[prop]);
65
74
  expect(findLink().attributes()).toEqual(expect.objectContaining(item.extraAttrs));
66
75
  });
67
76
 
@@ -1,4 +1,5 @@
1
1
  <script>
2
+ import { BLink } from 'bootstrap-vue';
2
3
  import { ENTER, SPACE } from '../constants';
3
4
  import { stopEvent } from '../../../../utils/utils';
4
5
  import { isItem } from './utils';
@@ -9,6 +10,7 @@ export const ITEM_CLASS = 'gl-new-dropdown-item';
9
10
  export default {
10
11
  name: DISCLOSURE_DROPDOWN_ITEM_NAME,
11
12
  ITEM_CLASS,
13
+ components: { BLink },
12
14
  props: {
13
15
  item: {
14
16
  type: Object,
@@ -19,7 +21,7 @@ export default {
19
21
  },
20
22
  computed: {
21
23
  isLink() {
22
- return typeof this.item?.href === 'string';
24
+ return typeof this.item?.href === 'string' || typeof this.item?.to === 'string';
23
25
  },
24
26
  isCustomContent() {
25
27
  return Boolean(this.$scopedSlots.default);
@@ -29,9 +31,10 @@ export default {
29
31
 
30
32
  if (this.isLink)
31
33
  return {
32
- is: 'a',
34
+ is: BLink,
33
35
  attrs: {
34
36
  href: item.href,
37
+ to: item.to,
35
38
  ...item.extraAttrs,
36
39
  },
37
40
  listeners: {
@@ -85,9 +88,12 @@ export default {
85
88
  * the `a/button` to be the target of the event as it might have additional attributes.
86
89
  * E.g. `a` might have `target` attribute.
87
90
  */
88
- this.$refs.item?.dispatchEvent(
89
- new MouseEvent('click', { bubbles: true, cancelable: true })
90
- );
91
+ const e = new MouseEvent('click', { bubbles: true, cancelable: true });
92
+ if (this.isLink) {
93
+ this.$refs.item.$el.dispatchEvent(e);
94
+ } else {
95
+ this.$refs.item?.dispatchEvent(e);
96
+ }
91
97
  }
92
98
  }
93
99
  },
@@ -28,6 +28,13 @@ export const mockItems = [
28
28
  target: '_blank',
29
29
  },
30
30
  },
31
+ {
32
+ text: 'Edit merge request',
33
+ to: '/edit',
34
+ extraAttrs: {
35
+ 'data-uuid': '1234',
36
+ },
37
+ },
31
38
  ];
32
39
 
33
40
  export const mockItemsCustomItem = [
@@ -17,6 +17,7 @@
17
17
  transition: none;
18
18
  }
19
19
 
20
+ /* TODO: Avoid mixing duo-chat styles with other GitLab UI components not intended as utilities. Refactor and remove all `gl-drawer` instances out of this file. */
20
21
  .gl-drawer-body-scrim-on-footer {
21
22
  &::before {
22
23
  background: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10);
@@ -26,6 +27,11 @@
26
27
  .gl-drawer-body {
27
28
  overflow-y: auto;
28
29
  }
30
+
31
+ .gl-drawer-header,
32
+ .gl-drawer-body > * {
33
+ @include gl-p-5;
34
+ }
29
35
  }
30
36
 
31
37
  .duo-chat-history {
@@ -355,7 +355,7 @@ export default {
355
355
  <aside
356
356
  v-if="!isHidden"
357
357
  id="chat-component"
358
- class="markdown-code-block gl-drawer gl-drawer-default gl-max-h-full gl-bottom-0 gl-shadow-none gl-border-l gl-border-t duo-chat"
358
+ class="markdown-code-block gl-drawer gl-max-h-full gl-bottom-0 gl-shadow-none gl-border-l gl-border-t duo-chat"
359
359
  role="complementary"
360
360
  data-testid="chat-component"
361
361
  >
@@ -0,0 +1,19 @@
1
+ {
2
+ "text": {
3
+ "primary": {
4
+ "$value": "#ececef",
5
+ "$type": "color",
6
+ "themeable": true
7
+ },
8
+ "secondary": {
9
+ "$value": "#89888d",
10
+ "$type": "color",
11
+ "themeable": true
12
+ },
13
+ "tertiary": {
14
+ "$value": "#737278",
15
+ "$type": "color",
16
+ "themeable": true
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,13 @@
1
+ import COMPILED_TOKENS from '../../dist/tokens/json/tokens.dark.json';
2
+ import { createDesignTokenStory } from './common_story_options';
3
+
4
+ export const Default = createDesignTokenStory({
5
+ containerClass: 'gl-bg-gray-950',
6
+ tokens: COMPILED_TOKENS.text,
7
+ isBackgroundColorStory: false,
8
+ });
9
+
10
+ // eslint-disable-next-line storybook/csf-component
11
+ export default {
12
+ title: 'tokens/text/dark',
13
+ };
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "text": {
3
3
  "primary": {
4
- "$value": "{gray.900}",
4
+ "$value": "#333238",
5
5
  "$type": "color",
6
6
  "themeable": true
7
7
  },
8
8
  "secondary": {
9
- "$value": "{gray.500}",
9
+ "$value": "#737278",
10
10
  "$type": "color",
11
11
  "themeable": true
12
12
  },
13
13
  "tertiary": {
14
- "$value": "{gray.400}",
14
+ "$value": "#89888d",
15
15
  "$type": "color",
16
16
  "themeable": true
17
17
  }
@@ -8,5 +8,5 @@ export const Default = createDesignTokenStory({
8
8
 
9
9
  // eslint-disable-next-line storybook/csf-component
10
10
  export default {
11
- title: 'tokens/text',
11
+ title: 'tokens/text/light',
12
12
  };
@@ -1,23 +1,36 @@
1
- const baseColorTokens = require('./src/tokens/color.tokens.json');
2
- const themeColorTokens = require('./src/tokens/color.theme.tokens.json');
1
+ const COMPILED_TOKENS = require('./dist/tokens/json/tokens.json');
2
+
3
+ const cssCustomPropertyWithValue = (token) => {
4
+ const path = [token.prefix !== false ? 'gl' : false, ...token.path].filter(Boolean);
5
+ return `var(--${path.join('-')}, ${token.value})`;
6
+ };
3
7
 
4
8
  const baseColors = ['blue', 'gray', 'green', 'orange', 'purple', 'red'].reduce((acc, color) => {
5
- acc[color] = {};
6
- Object.entries(baseColorTokens[color]).forEach(([shade, { $value }]) => {
7
- acc[color][shade] = `var(--${color}-${shade}, ${$value})`;
9
+ Object.entries(COMPILED_TOKENS[color]).forEach(([, token]) => {
10
+ acc[token.path.join('-')] = cssCustomPropertyWithValue(token);
8
11
  });
9
12
  return acc;
10
13
  }, {});
11
14
 
12
- const themeColors = Object.entries(themeColorTokens.theme).reduce((acc, [color, shades]) => {
13
- const colorKey = `theme-${color}`;
14
- acc[colorKey] = {};
15
- Object.entries(shades).forEach(([shade, { $value }]) => {
16
- acc[colorKey][shade] = `var(--${colorKey}-${shade}, ${$value})`;
15
+ const themeColors = Object.entries(COMPILED_TOKENS.theme).reduce((acc, [, scales]) => {
16
+ Object.entries(scales).forEach(([, token]) => {
17
+ acc[token.path.join('-')] = cssCustomPropertyWithValue(token);
17
18
  });
18
19
  return acc;
19
20
  }, {});
20
21
 
22
+ const textColors = Object.entries(COMPILED_TOKENS.text).reduce((acc, [scale, token]) => {
23
+ acc[scale] = cssCustomPropertyWithValue(token);
24
+ return acc;
25
+ }, {});
26
+
27
+ const colors = {
28
+ white: cssCustomPropertyWithValue(COMPILED_TOKENS.white),
29
+ black: cssCustomPropertyWithValue(COMPILED_TOKENS.black),
30
+ ...baseColors,
31
+ ...themeColors,
32
+ };
33
+
21
34
  const gridSize = 0.5; // rem
22
35
  const spacing = {
23
36
  0: '0',
@@ -65,12 +78,7 @@ module.exports = {
65
78
  lg: '992px',
66
79
  xl: '1200px',
67
80
  },
68
- colors: {
69
- white: `var(--white, ${baseColorTokens.white.$value})`,
70
- black: `var(--black, ${baseColorTokens.black.$value})`,
71
- ...baseColors,
72
- ...themeColors,
73
- },
81
+ colors,
74
82
  spacing,
75
83
  fontSize: {
76
84
  xs: '0.625rem',
@@ -85,5 +93,9 @@ module.exports = {
85
93
  semibold: 500,
86
94
  bold: 600,
87
95
  },
96
+ textColor: {
97
+ ...colors,
98
+ ...textColors,
99
+ },
88
100
  },
89
101
  };