@gitlab/ui 62.4.0 → 62.5.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.
- package/CHANGELOG.md +14 -0
- package/README.md +0 -19
- package/dist/components/base/avatar/avatar.js +2 -2
- package/dist/components/base/avatar_labeled/avatar_labeled.js +20 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/utils/utils.js +28 -11
- package/package.json +26 -25
- package/src/components/base/avatar/avatar.vue +2 -0
- package/src/components/base/avatar_labeled/avatar_labeled.scss +1 -0
- package/src/components/base/avatar_labeled/avatar_labeled.spec.js +18 -5
- package/src/components/base/avatar_labeled/avatar_labeled.stories.js +35 -0
- package/src/components/base/avatar_labeled/avatar_labeled.vue +22 -2
- package/src/components/base/badge/badge.md +0 -2
- package/src/components/base/button/button.md +0 -2
- package/src/components/base/filtered_search/filtered_search.md +0 -2
- package/src/components/base/keyset_pagination/keyset_pagination.md +0 -4
- package/src/components/base/markdown/markdown.md +0 -2
- package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.md +0 -2
- package/src/components/utilities/friendly_wrap/friendly_wrap.md +0 -8
- package/src/components/utilities/intersperse/intersperse.md +0 -8
- package/src/components/utilities/sprintf/sprintf.md +0 -2
- package/src/components/utilities/truncate/truncate.md +0 -2
- package/src/directives/safe_html/safe_html.md +0 -2
- package/src/utils/utils.js +32 -10
package/dist/utils/utils.js
CHANGED
|
@@ -44,21 +44,38 @@ function hexToRgba(hex) {
|
|
|
44
44
|
const [r, g, b] = rgbFromHex(hex);
|
|
45
45
|
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
46
46
|
}
|
|
47
|
+
function toSrgb(value) {
|
|
48
|
+
const normalized = value / 255;
|
|
49
|
+
return normalized <= 0.03928 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
|
|
50
|
+
}
|
|
51
|
+
function relativeLuminance(rgb) {
|
|
52
|
+
// WCAG 2.1 formula: https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
|
|
53
|
+
// -
|
|
54
|
+
// WCAG 3.0 will use APAC
|
|
55
|
+
// Using APAC would be the ultimate goal, but was dismissed by engineering as of now
|
|
56
|
+
// See https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/3418#note_1370107090
|
|
57
|
+
return 0.2126 * toSrgb(rgb[0]) + 0.7152 * toSrgb(rgb[1]) + 0.0722 * toSrgb(rgb[2]);
|
|
58
|
+
}
|
|
47
59
|
function colorFromBackground(backgroundColor) {
|
|
48
|
-
let
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
let color;
|
|
61
|
+
const lightColor = rgbFromHex('#FFFFFF');
|
|
62
|
+
const darkColor = rgbFromHex('#1f1e24');
|
|
51
63
|
if (backgroundColor.startsWith('#')) {
|
|
52
|
-
|
|
64
|
+
color = rgbFromHex(backgroundColor);
|
|
53
65
|
} else if (backgroundColor.startsWith('rgba(')) {
|
|
54
|
-
|
|
66
|
+
color = rgbFromString(backgroundColor, 5);
|
|
55
67
|
} else if (backgroundColor.startsWith('rgb(')) {
|
|
56
|
-
|
|
68
|
+
color = rgbFromString(backgroundColor, 4);
|
|
57
69
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
const luminance = relativeLuminance(color);
|
|
71
|
+
const lightLuminance = relativeLuminance(lightColor);
|
|
72
|
+
const darkLuminance = relativeLuminance(darkColor);
|
|
73
|
+
const contrastLight = (lightLuminance + 0.05) / (luminance + 0.05);
|
|
74
|
+
const contrastDark = (luminance + 0.05) / (darkLuminance + 0.05);
|
|
75
|
+
|
|
76
|
+
// Using a threshold contrast of 2.4 instead of 3
|
|
77
|
+
// as this will solve weird color combinations in the mid tones
|
|
78
|
+
return contrastLight >= 2.4 || contrastLight > contrastDark ? labelColorOptions.light : labelColorOptions.dark;
|
|
62
79
|
}
|
|
63
80
|
function uid() {
|
|
64
81
|
return Math.random().toString(36).substring(2);
|
|
@@ -156,4 +173,4 @@ function filterVisible(els) {
|
|
|
156
173
|
return (els || []).filter(isVisible);
|
|
157
174
|
}
|
|
158
175
|
|
|
159
|
-
export { colorFromBackground, debounceByAnimationFrame, filterVisible, focusFirstFocusableElement, hexToRgba, isDev, isElementFocusable, isElementTabbable, logWarning, rgbFromHex, rgbFromString, stopEvent, throttle, uid };
|
|
176
|
+
export { colorFromBackground, debounceByAnimationFrame, filterVisible, focusFirstFocusableElement, hexToRgba, isDev, isElementFocusable, isElementTabbable, logWarning, relativeLuminance, rgbFromHex, rgbFromString, stopEvent, throttle, toSrgb, uid };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "62.
|
|
3
|
+
"version": "62.5.1",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
"clean": "rm -r dist storybook scss_to_js/scss_variables.* src/scss/utilities.scss",
|
|
30
30
|
"cy:run": "cypress run --browser firefox",
|
|
31
31
|
"start": "yarn storybook",
|
|
32
|
-
"storybook": "yarn storybook-prep &&
|
|
33
|
-
"storybook-vue3": "yarn storybook-prep && VUE_VERSION=3
|
|
32
|
+
"storybook": "yarn storybook-prep && storybook dev --ci --host localhost --port 9001 -c .storybook",
|
|
33
|
+
"storybook-vue3": "yarn storybook-prep && VUE_VERSION=3 storybook dev --ci --host localhost --port 9001 -c .storybook",
|
|
34
34
|
"storybook-prep": "run-s generate-utilities build-scss-variables copy-fonts",
|
|
35
|
-
"storybook-static": "yarn storybook-prep &&
|
|
35
|
+
"storybook-static": "yarn storybook-prep && storybook build -c .storybook -o storybook",
|
|
36
36
|
"pretest:unit": "yarn build-scss-variables",
|
|
37
37
|
"test": "run-s test:unit test:visual",
|
|
38
|
-
"test:integration": "NODE_ENV=test start-server-and-test start http://localhost:9001 cy:run",
|
|
38
|
+
"test:integration": "NODE_ENV=test start-server-and-test start http://localhost:9001/iframe.html cy:run",
|
|
39
39
|
"test:unit": "NODE_ENV=test jest --testPathIgnorePatterns storyshots.spec.js",
|
|
40
40
|
"test:unit:watch": "yarn test:unit --watch",
|
|
41
41
|
"test:unit:debug": "NODE_ENV=test node --inspect node_modules/.bin/jest --testPathIgnorePatterns storyshot.spec.js --watch --runInBand",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"test:visual": "./bin/run-visual-tests.sh 'jest ./tests/storyshots.spec.js'",
|
|
46
46
|
"test:visual:minimal": "node ./bin/run_minimal_visual_tests.js",
|
|
47
47
|
"test:visual:update": "./bin/run-visual-tests.sh 'JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE=1 jest ./tests/storyshots.spec.js --updateSnapshot'",
|
|
48
|
-
"test:visual:internal": "NODE_ENV=test IS_VISUAL_TEST=true start-test http-get://localhost:9001",
|
|
48
|
+
"test:visual:internal": "NODE_ENV=test IS_VISUAL_TEST=true start-test http-get://localhost:9001/iframe.html",
|
|
49
49
|
"prettier": "prettier --check '**/*.{js,vue}'",
|
|
50
50
|
"prettier:fix": "prettier --write '**/*.{js,vue}'",
|
|
51
51
|
"eslint": "eslint --max-warnings 0 --ext .js,.vue .",
|
|
@@ -78,8 +78,6 @@
|
|
|
78
78
|
"vue": "^2.6.10"
|
|
79
79
|
},
|
|
80
80
|
"resolutions": {
|
|
81
|
-
"@storybook/vue/webpack": "^5.9.0",
|
|
82
|
-
"@storybook/vue3/vue-loader": "^17.0.0",
|
|
83
81
|
"chokidar": "^3.5.2",
|
|
84
82
|
"sane": "^5.0.1"
|
|
85
83
|
},
|
|
@@ -87,24 +85,26 @@
|
|
|
87
85
|
"@arkweid/lefthook": "0.7.7",
|
|
88
86
|
"@babel/core": "^7.21.4",
|
|
89
87
|
"@babel/preset-env": "^7.21.4",
|
|
90
|
-
"@
|
|
88
|
+
"@babel/preset-react": "^7.18.6",
|
|
89
|
+
"@gitlab/eslint-plugin": "19.0.0",
|
|
91
90
|
"@gitlab/fonts": "^1.2.0",
|
|
92
91
|
"@gitlab/stylelint-config": "4.1.0",
|
|
93
|
-
"@gitlab/svgs": "3.
|
|
92
|
+
"@gitlab/svgs": "3.42.0",
|
|
94
93
|
"@rollup/plugin-commonjs": "^11.1.0",
|
|
95
94
|
"@rollup/plugin-node-resolve": "^7.1.3",
|
|
96
95
|
"@rollup/plugin-replace": "^2.3.2",
|
|
97
|
-
"@storybook/addon-a11y": "
|
|
98
|
-
"@storybook/addon-docs": "
|
|
99
|
-
"@storybook/addon-essentials": "
|
|
100
|
-
"@storybook/addon-storyshots": "
|
|
101
|
-
"@storybook/addon-storyshots-puppeteer": "
|
|
102
|
-
"@storybook/addon-viewport": "
|
|
103
|
-
"@storybook/builder-webpack5": "
|
|
104
|
-
"@storybook/
|
|
105
|
-
"@storybook/
|
|
106
|
-
"@storybook/vue": "
|
|
107
|
-
"@storybook/vue3": "
|
|
96
|
+
"@storybook/addon-a11y": "7.0.7",
|
|
97
|
+
"@storybook/addon-docs": "7.0.7",
|
|
98
|
+
"@storybook/addon-essentials": "7.0.7",
|
|
99
|
+
"@storybook/addon-storyshots": "7.0.7",
|
|
100
|
+
"@storybook/addon-storyshots-puppeteer": "7.0.7",
|
|
101
|
+
"@storybook/addon-viewport": "7.0.7",
|
|
102
|
+
"@storybook/builder-webpack5": "7.0.7",
|
|
103
|
+
"@storybook/theming": "7.0.7",
|
|
104
|
+
"@storybook/vue": "7.0.7",
|
|
105
|
+
"@storybook/vue-webpack5": "7.0.7",
|
|
106
|
+
"@storybook/vue3": "7.0.7",
|
|
107
|
+
"@storybook/vue3-webpack5": "7.0.7",
|
|
108
108
|
"@vue/compat": "^3.2.40",
|
|
109
109
|
"@vue/compiler-sfc": "^3.2.40",
|
|
110
110
|
"@vue/test-utils": "1.3.0",
|
|
@@ -115,15 +115,13 @@
|
|
|
115
115
|
"babel-jest": "29.0.1",
|
|
116
116
|
"babel-loader": "^8.0.5",
|
|
117
117
|
"babel-plugin-require-context-hook": "^1.0.0",
|
|
118
|
-
"babel-preset-vue": "^2.0.2",
|
|
119
118
|
"bootstrap": "4.6.2",
|
|
120
|
-
"cypress": "
|
|
119
|
+
"cypress": "12.10.0",
|
|
121
120
|
"emoji-regex": "^10.0.0",
|
|
122
121
|
"eslint": "8.38.0",
|
|
123
122
|
"eslint-import-resolver-jest": "3.0.2",
|
|
124
123
|
"eslint-plugin-cypress": "2.13.2",
|
|
125
124
|
"eslint-plugin-storybook": "0.6.11",
|
|
126
|
-
"file-loader": "^4.2.0",
|
|
127
125
|
"glob": "^7.2.0",
|
|
128
126
|
"identity-obj-proxy": "^3.0.0",
|
|
129
127
|
"inquirer-select-directory": "^1.2.0",
|
|
@@ -142,6 +140,8 @@
|
|
|
142
140
|
"prettier": "2.6.2",
|
|
143
141
|
"puppeteer": "15.5.0",
|
|
144
142
|
"raw-loader": "^0.5.1",
|
|
143
|
+
"react": "^18.2.0",
|
|
144
|
+
"react-dom": "^18.2.0",
|
|
145
145
|
"rollup": "^2.53.1",
|
|
146
146
|
"rollup-plugin-babel": "^4.4.0",
|
|
147
147
|
"rollup-plugin-postcss": "^3.1.1",
|
|
@@ -153,7 +153,8 @@
|
|
|
153
153
|
"sass-loader": "^10.2.0",
|
|
154
154
|
"sass-true": "^6.1.0",
|
|
155
155
|
"start-server-and-test": "^1.10.6",
|
|
156
|
-
"storybook
|
|
156
|
+
"storybook": "7.0.7",
|
|
157
|
+
"storybook-dark-mode": "3.0.0",
|
|
157
158
|
"stylelint": "14.9.1",
|
|
158
159
|
"stylelint-config-prettier": "9.0.4",
|
|
159
160
|
"stylelint-prettier": "2.0.0",
|
|
@@ -130,6 +130,7 @@ export default {
|
|
|
130
130
|
:alt="alt"
|
|
131
131
|
:class="['gl-avatar', { 'gl-avatar-circle': isCircle }, sizeClasses]"
|
|
132
132
|
@error="handleLoadError"
|
|
133
|
+
v-on="$listeners"
|
|
133
134
|
/>
|
|
134
135
|
<div
|
|
135
136
|
v-else
|
|
@@ -139,6 +140,7 @@ export default {
|
|
|
139
140
|
sizeClasses,
|
|
140
141
|
identiconBackgroundClass,
|
|
141
142
|
]"
|
|
143
|
+
v-on="$listeners"
|
|
142
144
|
>
|
|
143
145
|
{{ identiconText }}
|
|
144
146
|
</div>
|
|
@@ -63,13 +63,26 @@ describe('avatar labeled', () => {
|
|
|
63
63
|
buildWrapper({ label, subLabel, labelLink: 'http://label', subLabelLink: 'http://subLabel' });
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
describe('with label link', () => {
|
|
67
|
+
const findLabelLink = () => wrapper.findAllComponents(GlLink).at(0);
|
|
68
|
+
|
|
69
|
+
it('displays the label link', () => {
|
|
70
|
+
const labelLink = findLabelLink();
|
|
71
|
+
expect(labelLink.text()).toBe(label);
|
|
72
|
+
expect(labelLink.attributes('href')).toBe('http://label');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('navigates to label link when avatar is clicked', () => {
|
|
76
|
+
const labelLink = findLabelLink();
|
|
77
|
+
const labelLinkClickSpy = jest.spyOn(labelLink.element, 'click');
|
|
78
|
+
|
|
79
|
+
wrapper.findComponent(Avatar).vm.$emit('click');
|
|
80
|
+
|
|
81
|
+
expect(labelLinkClickSpy).toHaveBeenCalled();
|
|
82
|
+
});
|
|
70
83
|
});
|
|
71
84
|
|
|
72
|
-
it('displays the
|
|
85
|
+
it('displays the sub-label link', () => {
|
|
73
86
|
const subLabelLink = wrapper.findAllComponents(GlLink).at(1);
|
|
74
87
|
expect(subLabelLink.text()).toBe(subLabel);
|
|
75
88
|
expect(subLabelLink.attributes('href')).toBe('http://subLabel');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Vue from 'vue';
|
|
2
2
|
import GlBadge from '../badge/badge.vue';
|
|
3
3
|
import GlButton from '../button/button.vue';
|
|
4
|
+
import GlIcon from '../icon/icon.vue';
|
|
4
5
|
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
5
6
|
import { avatarSizeOptions, avatarShapeOptions, tooltipPlacements } from '../../../utils/constants';
|
|
6
7
|
import avatarPath from '../../../../static/img/avatar.png';
|
|
@@ -17,12 +18,14 @@ const generateProps = ({
|
|
|
17
18
|
size = 32,
|
|
18
19
|
shape = 'circle',
|
|
19
20
|
src = avatarPath,
|
|
21
|
+
labelLink,
|
|
20
22
|
} = {}) => ({
|
|
21
23
|
label,
|
|
22
24
|
subLabel,
|
|
23
25
|
size,
|
|
24
26
|
shape,
|
|
25
27
|
src,
|
|
28
|
+
labelLink,
|
|
26
29
|
});
|
|
27
30
|
|
|
28
31
|
const generateTooltipProps = ({ tooltipText = 'Avatar tooltip', placement = 'top' } = {}) => ({
|
|
@@ -111,6 +114,38 @@ export const WithDefaultSlot = (args, { argTypes }) => ({
|
|
|
111
114
|
});
|
|
112
115
|
WithDefaultSlot.args = generateProps({ size: 64 });
|
|
113
116
|
|
|
117
|
+
export const WithLinks = (args, { argTypes }) => ({
|
|
118
|
+
components: { GlAvatarLabeled, GlBadge, GlIcon },
|
|
119
|
+
props: Object.keys(argTypes),
|
|
120
|
+
template: `
|
|
121
|
+
<gl-avatar-labeled
|
|
122
|
+
:shape="shape"
|
|
123
|
+
:size="size"
|
|
124
|
+
:label-link="labelLink"
|
|
125
|
+
:src="src"
|
|
126
|
+
:label="label"
|
|
127
|
+
>
|
|
128
|
+
<template #meta>
|
|
129
|
+
<gl-icon
|
|
130
|
+
v-gl-tooltip="'Public - The project can be accessed without any authentication.'"
|
|
131
|
+
name="earth"
|
|
132
|
+
class="gl-text-secondary gl-ml-2"
|
|
133
|
+
/>
|
|
134
|
+
</template>
|
|
135
|
+
<div class="gl-max-w-75">
|
|
136
|
+
<p class="gl-mb-0 gl-mt-2 gl-font-sm">GitLab is an open source end-to-end software development platform with built-in version control, issue tracking, code review, CI/CD, and more. Self-host GitLab on your own servers, in a container, or on a cloud provider.</p>
|
|
137
|
+
</div>
|
|
138
|
+
</gl-avatar-labeled>
|
|
139
|
+
`,
|
|
140
|
+
});
|
|
141
|
+
WithLinks.args = generateProps({
|
|
142
|
+
size: 48,
|
|
143
|
+
shape: 'rect',
|
|
144
|
+
label: 'GitLab.org / GitLab',
|
|
145
|
+
subLabel: '',
|
|
146
|
+
labelLink: 'https://gitlab.com/gitlab-org/gitlab',
|
|
147
|
+
});
|
|
148
|
+
|
|
114
149
|
export default {
|
|
115
150
|
title: 'base/avatar/labeled',
|
|
116
151
|
component: GlAvatarLabeled,
|
|
@@ -36,17 +36,37 @@ export default {
|
|
|
36
36
|
hasSubLabelLink() {
|
|
37
37
|
return Boolean(this.subLabelLink);
|
|
38
38
|
},
|
|
39
|
+
avatarListeners() {
|
|
40
|
+
if (this.hasLabelLink) {
|
|
41
|
+
return {
|
|
42
|
+
...this.$listeners,
|
|
43
|
+
click: this.onAvatarClick,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return this.$listeners;
|
|
48
|
+
},
|
|
49
|
+
avatarCssClasses() {
|
|
50
|
+
return {
|
|
51
|
+
'gl-cursor-pointer': this.hasLabelLink,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
methods: {
|
|
56
|
+
onAvatarClick() {
|
|
57
|
+
this.$refs.labelLink.$el.click();
|
|
58
|
+
},
|
|
39
59
|
},
|
|
40
60
|
};
|
|
41
61
|
</script>
|
|
42
62
|
<template>
|
|
43
63
|
<div class="gl-avatar-labeled">
|
|
44
|
-
<gl-avatar v-bind="$attrs" alt v-on="
|
|
64
|
+
<gl-avatar v-bind="$attrs" :class="avatarCssClasses" alt v-on="avatarListeners" />
|
|
45
65
|
<div class="gl-avatar-labeled-labels gl-text-left!">
|
|
46
66
|
<div
|
|
47
67
|
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-text-left! gl-mx-n1 gl-my-n1"
|
|
48
68
|
>
|
|
49
|
-
<gl-link v-if="hasLabelLink" :href="labelLink" class="gl-avatar-link">
|
|
69
|
+
<gl-link v-if="hasLabelLink" ref="labelLink" :href="labelLink" class="gl-avatar-link">
|
|
50
70
|
<span class="gl-avatar-labeled-label">{{ label }}</span>
|
|
51
71
|
</gl-link>
|
|
52
72
|
<span v-else class="gl-avatar-labeled-label">{{ label }}</span>
|
|
@@ -19,9 +19,7 @@ with the necessary classes added to make it look like a button, it shares the sa
|
|
|
19
19
|
Icon-only buttons must have an accessible name.
|
|
20
20
|
You can provide one with the `aria-label` attribute, which is read out by screen readers.
|
|
21
21
|
|
|
22
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
23
22
|
```html
|
|
24
|
-
|
|
25
23
|
<gl-button icon="close" aria-label="Close" />
|
|
26
24
|
```
|
|
27
25
|
|
|
@@ -71,8 +71,6 @@ const availableTokens = [
|
|
|
71
71
|
Pass the list of tokens to the search component. Optionally, you can use `v-model` to receive
|
|
72
72
|
realtime updates:
|
|
73
73
|
|
|
74
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
75
74
|
```html
|
|
76
|
-
|
|
77
75
|
<gl-filtered-search :available-tokens="tokens" v-model="value" terms-as-tokens />
|
|
78
76
|
```
|
|
@@ -10,9 +10,7 @@ is to `v-bind` to the
|
|
|
10
10
|
[`PageInfo`](https://docs.gitlab.com/ee/api/graphql/reference/#pageinfo) type
|
|
11
11
|
returned by the endpoint:
|
|
12
12
|
|
|
13
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
14
13
|
```html
|
|
15
|
-
|
|
16
14
|
<gl-keyset-pagination v-bind="pageInfo" />
|
|
17
15
|
```
|
|
18
16
|
|
|
@@ -27,9 +25,7 @@ can't be translated.
|
|
|
27
25
|
|
|
28
26
|
Example:
|
|
29
27
|
|
|
30
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
31
28
|
```html
|
|
32
|
-
|
|
33
29
|
<gl-keyset-pagination v-bind="pageInfo" :prev-text="__('Prev')" :next-text="__('Next')" />
|
|
34
30
|
```
|
|
35
31
|
|
|
@@ -40,9 +40,7 @@ selector to the root element that contains the markdown-generated HTML.
|
|
|
40
40
|
|
|
41
41
|
Set the `compact` property to true in `GlMarkdown` to apply the compact markdown styles.
|
|
42
42
|
|
|
43
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
44
43
|
```html
|
|
45
|
-
|
|
46
44
|
<gl-markdown compact></gl-compact>
|
|
47
45
|
```
|
|
48
46
|
|
|
@@ -4,9 +4,7 @@ to make sure this is the right dropdown component for you.
|
|
|
4
4
|
|
|
5
5
|
### Basic usage
|
|
6
6
|
|
|
7
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
8
7
|
```html
|
|
9
|
-
|
|
10
8
|
<gl-disclosure-dropdown-dropdown toggle-text="Actions" :items="items" />
|
|
11
9
|
```
|
|
12
10
|
|
|
@@ -21,17 +21,13 @@ wbr {
|
|
|
21
21
|
By default, `GlFriendlyWrap` wraps text with slashes (`/`) as the break-symbol, which is especially
|
|
22
22
|
useful when displaying paths or URLs:
|
|
23
23
|
|
|
24
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
25
24
|
```html
|
|
26
|
-
|
|
27
25
|
<gl-friendly-wrap text="/some/file/path" />
|
|
28
26
|
```
|
|
29
27
|
|
|
30
28
|
The code above renders to the following HTML:
|
|
31
29
|
|
|
32
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
33
30
|
```html
|
|
34
|
-
|
|
35
31
|
<span class="text-break">/<wbr>some/<wbr>file/<wbr>path</span>
|
|
36
32
|
```
|
|
37
33
|
|
|
@@ -48,9 +44,7 @@ Multiple custom break-symbols can be defined via the `GlFriendlyWrap` prop:
|
|
|
48
44
|
|
|
49
45
|
Which renders to:
|
|
50
46
|
|
|
51
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
52
47
|
```html
|
|
53
|
-
|
|
54
48
|
<span class="text-break">some;<wbr>text-<wbr>that.<wbr>needs;<wbr>to-<wbr>be.<wbr>wrapped</span>
|
|
55
49
|
```
|
|
56
50
|
|
|
@@ -67,8 +61,6 @@ Symbols can be words too:
|
|
|
67
61
|
|
|
68
62
|
Which renders to:
|
|
69
63
|
|
|
70
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
71
64
|
```html
|
|
72
|
-
|
|
73
65
|
<span class="text-break">it goes on and<wbr> on and<wbr> on and<wbr> on</span>
|
|
74
66
|
```
|
|
@@ -34,9 +34,7 @@ consistent formatting.
|
|
|
34
34
|
|
|
35
35
|
This renders to the following HTML:
|
|
36
36
|
|
|
37
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
38
37
|
```html
|
|
39
|
-
|
|
40
38
|
<span><span>Item 1</span>, <span>Item 2</span>, <span>Item 3</span></span>
|
|
41
39
|
```
|
|
42
40
|
|
|
@@ -54,9 +52,7 @@ A custom separator can be defined via the `separator` prop:
|
|
|
54
52
|
|
|
55
53
|
This renders to the following HTML:
|
|
56
54
|
|
|
57
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
58
55
|
```html
|
|
59
|
-
|
|
60
56
|
<span><span>Item 1</span>/<span>Item 2</span>/<span>Item 3</span></span>
|
|
61
57
|
```
|
|
62
58
|
|
|
@@ -74,9 +70,7 @@ A custom last separator can be defined via the `lastSeparator` prop:
|
|
|
74
70
|
|
|
75
71
|
This renders to the following HTML:
|
|
76
72
|
|
|
77
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
78
73
|
```html
|
|
79
|
-
|
|
80
74
|
<span><span>Item 1</span>, <span>Item 2</span>, and <span>Item 3</span></span>
|
|
81
75
|
```
|
|
82
76
|
|
|
@@ -91,8 +85,6 @@ A custom last separator used on two items will only place `lastSeparator` betwee
|
|
|
91
85
|
|
|
92
86
|
This renders to the following HTML:
|
|
93
87
|
|
|
94
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
95
88
|
```html
|
|
96
|
-
|
|
97
89
|
<span><span>Item 1</span> and <span>Item 2</span></span>
|
|
98
90
|
```
|
|
@@ -130,9 +130,7 @@ export default {
|
|
|
130
130
|
|
|
131
131
|
The example above renders to this HTML:
|
|
132
132
|
|
|
133
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
134
133
|
```html
|
|
135
|
-
|
|
136
134
|
<div>Written by <span>Some author</span></div>
|
|
137
135
|
```
|
|
138
136
|
|
|
@@ -4,9 +4,7 @@ The `GlTruncate` component lets you truncate the long texts with ellipsis.
|
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
8
7
|
```html
|
|
9
|
-
|
|
10
8
|
<gl-truncate :text="text" :position="position" />
|
|
11
9
|
```
|
|
12
10
|
|
|
@@ -46,9 +46,7 @@ const config = { ALLOWED_TAGS: ['b'] };
|
|
|
46
46
|
const config = { ALLOWED_TAGS: [] };
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
<!-- Empty initial line is a workaround for https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2102 -->
|
|
50
49
|
```html
|
|
51
|
-
|
|
52
50
|
<div v-safe-html:[config]="rawHtml"></div>
|
|
53
51
|
```
|
|
54
52
|
|
package/src/utils/utils.js
CHANGED
|
@@ -49,23 +49,45 @@ export function hexToRgba(hex, opacity = 1) {
|
|
|
49
49
|
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
export function toSrgb(value) {
|
|
53
|
+
const normalized = value / 255;
|
|
54
|
+
return normalized <= 0.03928 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function relativeLuminance(rgb) {
|
|
58
|
+
// WCAG 2.1 formula: https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
|
|
59
|
+
// -
|
|
60
|
+
// WCAG 3.0 will use APAC
|
|
61
|
+
// Using APAC would be the ultimate goal, but was dismissed by engineering as of now
|
|
62
|
+
// See https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/3418#note_1370107090
|
|
63
|
+
return 0.2126 * toSrgb(rgb[0]) + 0.7152 * toSrgb(rgb[1]) + 0.0722 * toSrgb(rgb[2]);
|
|
64
|
+
}
|
|
65
|
+
|
|
52
66
|
export function colorFromBackground(backgroundColor) {
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
|
|
67
|
+
let color;
|
|
68
|
+
const lightColor = rgbFromHex('#FFFFFF');
|
|
69
|
+
const darkColor = rgbFromHex('#1f1e24');
|
|
56
70
|
|
|
57
71
|
if (backgroundColor.startsWith('#')) {
|
|
58
|
-
|
|
72
|
+
color = rgbFromHex(backgroundColor);
|
|
59
73
|
} else if (backgroundColor.startsWith('rgba(')) {
|
|
60
|
-
|
|
74
|
+
color = rgbFromString(backgroundColor, 5);
|
|
61
75
|
} else if (backgroundColor.startsWith('rgb(')) {
|
|
62
|
-
|
|
76
|
+
color = rgbFromString(backgroundColor, 4);
|
|
63
77
|
}
|
|
64
78
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
const luminance = relativeLuminance(color);
|
|
80
|
+
const lightLuminance = relativeLuminance(lightColor);
|
|
81
|
+
const darkLuminance = relativeLuminance(darkColor);
|
|
82
|
+
|
|
83
|
+
const contrastLight = (lightLuminance + 0.05) / (luminance + 0.05);
|
|
84
|
+
const contrastDark = (luminance + 0.05) / (darkLuminance + 0.05);
|
|
85
|
+
|
|
86
|
+
// Using a threshold contrast of 2.4 instead of 3
|
|
87
|
+
// as this will solve weird color combinations in the mid tones
|
|
88
|
+
return contrastLight >= 2.4 || contrastLight > contrastDark
|
|
89
|
+
? labelColorOptions.light
|
|
90
|
+
: labelColorOptions.dark;
|
|
69
91
|
}
|
|
70
92
|
|
|
71
93
|
export function uid() {
|