@gitlab/ui 72.1.0 → 72.2.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": "72.1.0",
3
+ "version": "72.2.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -94,22 +94,22 @@
94
94
  "@gitlab/eslint-plugin": "19.2.0",
95
95
  "@gitlab/fonts": "^1.3.0",
96
96
  "@gitlab/stylelint-config": "5.0.1",
97
- "@gitlab/svgs": "3.72.0",
97
+ "@gitlab/svgs": "3.73.0",
98
98
  "@rollup/plugin-commonjs": "^11.1.0",
99
99
  "@rollup/plugin-node-resolve": "^7.1.3",
100
100
  "@rollup/plugin-replace": "^2.3.2",
101
- "@storybook/addon-a11y": "7.5.3",
102
- "@storybook/addon-docs": "7.5.3",
103
- "@storybook/addon-essentials": "7.5.3",
104
- "@storybook/addon-storyshots": "7.5.3",
105
- "@storybook/addon-storyshots-puppeteer": "7.5.3",
106
- "@storybook/addon-viewport": "7.5.3",
107
- "@storybook/builder-webpack5": "7.5.3",
108
- "@storybook/theming": "7.5.3",
109
- "@storybook/vue": "7.5.3",
110
- "@storybook/vue-webpack5": "7.5.3",
111
- "@storybook/vue3": "7.5.3",
112
- "@storybook/vue3-webpack5": "7.5.3",
101
+ "@storybook/addon-a11y": "7.6.5",
102
+ "@storybook/addon-docs": "7.6.5",
103
+ "@storybook/addon-essentials": "7.6.5",
104
+ "@storybook/addon-storyshots": "7.6.5",
105
+ "@storybook/addon-storyshots-puppeteer": "7.6.5",
106
+ "@storybook/addon-viewport": "7.6.5",
107
+ "@storybook/builder-webpack5": "7.6.5",
108
+ "@storybook/theming": "7.6.5",
109
+ "@storybook/vue": "7.6.5",
110
+ "@storybook/vue-webpack5": "7.6.5",
111
+ "@storybook/vue3": "7.6.5",
112
+ "@storybook/vue3-webpack5": "7.6.5",
113
113
  "@vue/compat": "^3.2.40",
114
114
  "@vue/compiler-sfc": "^3.2.40",
115
115
  "@vue/test-utils": "1.3.0",
@@ -127,7 +127,7 @@
127
127
  "cypress-real-events": "^1.11.0",
128
128
  "dompurify": "^3.0.0",
129
129
  "emoji-regex": "^10.0.0",
130
- "eslint": "8.55.0",
130
+ "eslint": "8.56.0",
131
131
  "eslint-import-resolver-jest": "3.0.2",
132
132
  "eslint-plugin-cypress": "2.15.1",
133
133
  "eslint-plugin-storybook": "0.6.15",
@@ -161,8 +161,8 @@
161
161
  "sass-loader": "^10.2.0",
162
162
  "sass-true": "^6.1.0",
163
163
  "start-server-and-test": "^1.10.6",
164
- "storybook": "7.5.3",
165
- "storybook-dark-mode": "3.0.1",
164
+ "storybook": "7.6.5",
165
+ "storybook-dark-mode": "3.0.3",
166
166
  "style-dictionary": "^3.8.0",
167
167
  "stylelint": "15.10.2",
168
168
  "vue": "2.7.15",
@@ -77,7 +77,7 @@ export const CustomActions = () => ({
77
77
  <gl-alert>
78
78
  Lorem ipsum dolor sit amet
79
79
  <template #actions>
80
- <gl-toggle v-model="toggle" />
80
+ <gl-toggle v-model="toggle" label="label-name" label-position="hidden" />
81
81
  </template>
82
82
  </gl-alert>`,
83
83
  });
@@ -2183,6 +2183,14 @@ $gl-animate-skeleton-loader-max-width: 64 * $grid-size;
2183
2183
  box-shadow: inset 0 0 0 $gl-border-size-1 $orange-600 !important
2184
2184
  }
2185
2185
 
2186
+ .gl-inset-border-1-red-300 {
2187
+ box-shadow: inset 0 0 0 $gl-border-size-1 $red-300
2188
+ }
2189
+
2190
+ .gl-inset-border-1-red-300\! {
2191
+ box-shadow: inset 0 0 0 $gl-border-size-1 $red-300 !important
2192
+ }
2193
+
2186
2194
  .gl-inset-border-1-red-400 {
2187
2195
  box-shadow: inset 0 0 0 $gl-border-size-1 $red-400
2188
2196
  }
@@ -2744,6 +2752,14 @@ $gl-animate-skeleton-loader-max-width: 64 * $grid-size;
2744
2752
  color: $orange-900 !important;
2745
2753
  }
2746
2754
 
2755
+ .gl-text-red-300 {
2756
+ color: $red-300;
2757
+ }
2758
+
2759
+ .gl-text-red-300\! {
2760
+ color: $red-300 !important;
2761
+ }
2762
+
2747
2763
  .gl-text-red-500 {
2748
2764
  color: $red-500;
2749
2765
  }
@@ -113,6 +113,10 @@
113
113
  box-shadow: inset 0 0 0 $gl-border-size-1 $orange-600;
114
114
  }
115
115
 
116
+ @mixin gl-inset-border-1-red-300 {
117
+ box-shadow: inset 0 0 0 $gl-border-size-1 $red-300;
118
+ }
119
+
116
120
  @mixin gl-inset-border-1-red-400 {
117
121
  box-shadow: inset 0 0 0 $gl-border-size-1 $red-400;
118
122
  }
@@ -169,6 +169,10 @@
169
169
  color: $orange-900;
170
170
  }
171
171
 
172
+ @mixin gl-text-red-300 {
173
+ color: $red-300;
174
+ }
175
+
172
176
  @mixin gl-text-red-500 {
173
177
  color: $red-500;
174
178
  }
@@ -1,17 +1,76 @@
1
- import { colorFromBackground } from '../utils/utils';
1
+ import { colorFromBackground, relativeLuminance, rgbFromHex } from '../utils/utils';
2
+ import { WHITE, GRAY_950 } from '../../dist/tokens/js/tokens';
3
+
4
+ const CONTRAST_LEVELS = [
5
+ {
6
+ grade: 'F',
7
+ min: 0,
8
+ max: 3,
9
+ },
10
+ {
11
+ grade: 'AA+',
12
+ min: 3,
13
+ max: 4.5,
14
+ },
15
+ {
16
+ grade: 'AA',
17
+ min: 4.5,
18
+ max: 7,
19
+ },
20
+ {
21
+ grade: 'AAA',
22
+ min: 7,
23
+ max: 22,
24
+ },
25
+ ];
2
26
 
3
27
  export const methods = {
28
+ isAlpha(value) {
29
+ return value.startsWith('rgba(');
30
+ },
4
31
  getTokenName(name, key) {
5
32
  return [name, key].filter(Boolean).join('.');
6
33
  },
7
34
  getTextColorClass(value) {
8
- if (value.startsWith('rgba(')) return '';
35
+ if (this.isAlpha(value)) return '';
9
36
  const textColorVariant = colorFromBackground(value, 4.5);
10
37
  return {
11
38
  'gl-text-gray-950': textColorVariant === 'dark',
12
39
  'gl-text-white': textColorVariant === 'light',
13
40
  };
14
41
  },
42
+ getColorContrast(foreground = 'light', background) {
43
+ const foregroundColor = {
44
+ light: WHITE,
45
+ dark: GRAY_950,
46
+ };
47
+ // Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
48
+ const foregroundLuminance = relativeLuminance(rgbFromHex(foregroundColor[foreground])) + 0.05;
49
+ const backgroundLuminance = relativeLuminance(rgbFromHex(background)) + 0.05;
50
+
51
+ let score = foregroundLuminance / backgroundLuminance;
52
+ if (backgroundLuminance > foregroundLuminance) {
53
+ score = 1 / score;
54
+ }
55
+
56
+ const level = CONTRAST_LEVELS.find(({ min, max }) => {
57
+ return score >= min && score < max;
58
+ });
59
+
60
+ return {
61
+ score: (Math.round(score * 10) / 10).toFixed(1),
62
+ level,
63
+ };
64
+ },
65
+ getColorContrastClass(foreground, background) {
66
+ const { grade } = this.getColorContrast(foreground, background).level;
67
+ const isFail = grade === 'F';
68
+ const classes = {
69
+ light: isFail ? 'gl-inset-border-1-red-500 gl-text-red-500' : 'gl-text-gray-950',
70
+ dark: isFail ? 'gl-inset-border-1-red-300 gl-text-red-300' : 'gl-text-white',
71
+ };
72
+ return classes[foreground];
73
+ },
15
74
  };
16
75
 
17
76
  export const template = `
@@ -21,12 +80,30 @@ export const template = `
21
80
  <li
22
81
  v-for="(token, key) in tokens"
23
82
  :key="key"
24
- class="gl-display-flex gl-justify-content-space-between gl-gap-3 gl-p-3"
83
+ class="gl-display-flex gl-flex-wrap gl-align-items-center gl-justify-content-space-between gl-gap-3 gl-p-3"
25
84
  :class="getTextColorClass(token.$value)"
26
85
  :style="{ backgroundColor: token.$value }"
27
86
  >
28
87
  <code class="gl-reset-color">{{ getTokenName(name, key) }}</code>
29
- <code class="gl-reset-color">{{ token.$value }}</code>
88
+ <div class="gl-display-flex gl-align-items-center gl-gap-3">
89
+ <code class="gl-reset-color">{{ token.$value }}</code>
90
+ <code
91
+ v-if="!isAlpha(token.$value)"
92
+ class="gl-w-10 gl-text-center gl-rounded-base gl-font-xs gl-p-2 gl-bg-gray-900"
93
+ :class="getColorContrastClass('dark', token.$value)"
94
+ >
95
+ {{ getColorContrast('dark', token.$value).level.grade }}
96
+ {{ getColorContrast('dark', token.$value).score }}
97
+ </code>
98
+ <code
99
+ v-if="!isAlpha(token.$value)"
100
+ class="gl-w-10 gl-text-center gl-rounded-base gl-font-xs gl-p-2 gl-bg-white"
101
+ :class="getColorContrastClass('light', token.$value)"
102
+ >
103
+ {{ getColorContrast('light', token.$value).level.grade }}
104
+ {{ getColorContrast('light', token.$value).score }}
105
+ </code>
106
+ </div>
30
107
  </li>
31
108
  </ul>
32
109
  `;