@gitlab/ui 71.9.1 → 71.11.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/CHANGELOG.md +15 -0
- package/dist/components/charts/area/area.js +11 -22
- package/dist/components/charts/bar/bar.js +3 -4
- package/dist/components/charts/column/column.js +5 -22
- package/dist/components/charts/heatmap/heatmap.js +4 -9
- package/dist/components/charts/line/line.js +11 -22
- package/dist/components/experimental/duo/chat/duo_chat.js +9 -5
- package/dist/tokens/common_story_options.js +1 -0
- package/dist/tokens/css/tokens.css +14 -1
- package/dist/tokens/css/tokens.dark.css +1 -1
- package/dist/tokens/js/tokens.dark.js +1 -1
- package/dist/tokens/js/tokens.js +14 -1
- package/dist/tokens/json/tokens.dark.grouped.json +14 -1
- package/dist/tokens/json/tokens.dark.json +264 -0
- package/dist/tokens/json/tokens.grouped.json +14 -1
- package/dist/tokens/json/tokens.json +264 -0
- package/dist/tokens/scss/_tokens.dark.scss +1 -1
- package/dist/tokens/scss/_tokens.scss +14 -1
- package/package.json +1 -1
- package/src/components/charts/area/area.spec.js +82 -7
- package/src/components/charts/area/area.stories.js +24 -6
- package/src/components/charts/area/area.vue +21 -27
- package/src/components/charts/bar/bar.spec.js +7 -43
- package/src/components/charts/bar/bar.vue +3 -4
- package/src/components/charts/column/__snapshots__/column_chart.spec.js.snap +0 -12
- package/src/components/charts/column/column.vue +1 -23
- package/src/components/charts/column/column_chart.spec.js +13 -27
- package/src/components/charts/heatmap/heatmap.vue +4 -14
- package/src/components/charts/line/line.spec.js +120 -38
- package/src/components/charts/line/line.stories.js +21 -4
- package/src/components/charts/line/line.vue +21 -32
- package/src/components/experimental/duo/chat/duo_chat.spec.js +18 -0
- package/src/components/experimental/duo/chat/duo_chat.vue +11 -5
- package/src/scss/variables.scss +0 -7
- package/src/tokens/color.transparency.tokens.json +84 -0
- package/src/tokens/color.transparency.tokens.stories.js +26 -0
- package/src/tokens/common_story_options.js +1 -0
|
@@ -2,7 +2,11 @@ import { nextTick } from 'vue';
|
|
|
2
2
|
import { shallowMount } from '@vue/test-utils';
|
|
3
3
|
|
|
4
4
|
import { LEGEND_LAYOUT_INLINE, LEGEND_LAYOUT_TABLE } from '~/utils/charts/constants';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
createMockChartInstance,
|
|
7
|
+
ChartTooltipStub,
|
|
8
|
+
chartTooltipStubData,
|
|
9
|
+
} from '~helpers/chart_stubs';
|
|
6
10
|
import { expectHeightAutoClasses } from '~helpers/chart_height';
|
|
7
11
|
|
|
8
12
|
import Chart from '../chart/chart.vue';
|
|
@@ -27,10 +31,13 @@ describe('line component', () => {
|
|
|
27
31
|
|
|
28
32
|
const emitChartCreated = () => findChart().vm.$emit('created', mockChartInstance);
|
|
29
33
|
|
|
30
|
-
const createShallowWrapper = (props = {},
|
|
34
|
+
const createShallowWrapper = ({ props = {}, ...options } = {}) => {
|
|
31
35
|
wrapper = shallowMount(LineChart, {
|
|
32
36
|
propsData: { option, data: [], ...props },
|
|
33
|
-
|
|
37
|
+
stubs: {
|
|
38
|
+
'chart-tooltip': ChartTooltipStub,
|
|
39
|
+
},
|
|
40
|
+
...options,
|
|
34
41
|
});
|
|
35
42
|
emitChartCreated();
|
|
36
43
|
};
|
|
@@ -59,12 +66,14 @@ describe('line component', () => {
|
|
|
59
66
|
|
|
60
67
|
it('are displayed if passed via annotations props', async () => {
|
|
61
68
|
createShallowWrapper({
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
props: {
|
|
70
|
+
annotations: [
|
|
71
|
+
{
|
|
72
|
+
min: '',
|
|
73
|
+
max: '',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
68
77
|
});
|
|
69
78
|
|
|
70
79
|
await nextTick();
|
|
@@ -74,20 +83,22 @@ describe('line component', () => {
|
|
|
74
83
|
|
|
75
84
|
it('are displayed if passed via option props', async () => {
|
|
76
85
|
createShallowWrapper({
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
props: {
|
|
87
|
+
option: {
|
|
88
|
+
series: [
|
|
89
|
+
{
|
|
90
|
+
name: 'annotations',
|
|
91
|
+
markPoint: {
|
|
92
|
+
data: [
|
|
93
|
+
{
|
|
94
|
+
xAxis: 10,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
data: [],
|
|
87
99
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
],
|
|
100
|
+
],
|
|
101
|
+
},
|
|
91
102
|
},
|
|
92
103
|
});
|
|
93
104
|
|
|
@@ -112,8 +123,8 @@ describe('line component', () => {
|
|
|
112
123
|
},
|
|
113
124
|
};
|
|
114
125
|
|
|
115
|
-
createShallowWrapper(
|
|
116
|
-
{
|
|
126
|
+
createShallowWrapper({
|
|
127
|
+
props: {
|
|
117
128
|
annotations: [
|
|
118
129
|
{
|
|
119
130
|
min: '',
|
|
@@ -121,12 +132,7 @@ describe('line component', () => {
|
|
|
121
132
|
},
|
|
122
133
|
],
|
|
123
134
|
},
|
|
124
|
-
|
|
125
|
-
stubs: {
|
|
126
|
-
'chart-tooltip': ChartTooltipStub,
|
|
127
|
-
},
|
|
128
|
-
}
|
|
129
|
-
);
|
|
135
|
+
});
|
|
130
136
|
|
|
131
137
|
wrapper.vm.onChartDataPointMouseOver(params);
|
|
132
138
|
|
|
@@ -137,13 +143,83 @@ describe('line component', () => {
|
|
|
137
143
|
});
|
|
138
144
|
});
|
|
139
145
|
|
|
140
|
-
describe('data tooltip
|
|
141
|
-
|
|
146
|
+
describe('data tooltip', () => {
|
|
147
|
+
it('is initialized', async () => {
|
|
142
148
|
createShallowWrapper();
|
|
149
|
+
|
|
150
|
+
await nextTick();
|
|
151
|
+
|
|
152
|
+
expect(findDataTooltip().props()).toMatchObject({
|
|
153
|
+
useDefaultTooltipFormatter: true,
|
|
154
|
+
chart: mockChartInstance,
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe('is customized via slots', () => {
|
|
159
|
+
const { params, title, content } = chartTooltipStubData;
|
|
160
|
+
|
|
161
|
+
it('customizes tooltip value', async () => {
|
|
162
|
+
const tooltipValueSlot = jest.fn().mockReturnValue('Value');
|
|
163
|
+
|
|
164
|
+
createShallowWrapper({
|
|
165
|
+
scopedSlots: {
|
|
166
|
+
'tooltip-value': tooltipValueSlot,
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
await nextTick();
|
|
170
|
+
|
|
171
|
+
expect(tooltipValueSlot).toHaveBeenCalledWith({ value: 9 });
|
|
172
|
+
expect(findDataTooltip().text()).toBe('Value');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('customizes title', async () => {
|
|
176
|
+
const tooltipTitleSlot = jest.fn().mockReturnValue('Title');
|
|
177
|
+
|
|
178
|
+
createShallowWrapper({
|
|
179
|
+
scopedSlots: {
|
|
180
|
+
'tooltip-title': tooltipTitleSlot,
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
await nextTick();
|
|
184
|
+
|
|
185
|
+
expect(tooltipTitleSlot).toHaveBeenCalledWith({
|
|
186
|
+
params,
|
|
187
|
+
title,
|
|
188
|
+
});
|
|
189
|
+
expect(findDataTooltip().text()).toBe('Title');
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('customizes content', async () => {
|
|
193
|
+
const tooltipContentSlot = jest.fn().mockReturnValue('Title');
|
|
194
|
+
|
|
195
|
+
createShallowWrapper({
|
|
196
|
+
scopedSlots: {
|
|
197
|
+
'tooltip-content': tooltipContentSlot,
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
await nextTick();
|
|
201
|
+
|
|
202
|
+
expect(tooltipContentSlot).toHaveBeenCalledWith({
|
|
203
|
+
params,
|
|
204
|
+
content,
|
|
205
|
+
});
|
|
206
|
+
expect(findDataTooltip().text()).toBe('Title');
|
|
207
|
+
});
|
|
143
208
|
});
|
|
144
209
|
|
|
145
|
-
it('is
|
|
146
|
-
|
|
210
|
+
it('is customized via formatting function', async () => {
|
|
211
|
+
createShallowWrapper({
|
|
212
|
+
props: {
|
|
213
|
+
formatTooltipText: jest.fn(),
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
await nextTick();
|
|
218
|
+
|
|
219
|
+
expect(findDataTooltip().props()).toMatchObject({
|
|
220
|
+
useDefaultTooltipFormatter: false,
|
|
221
|
+
chart: mockChartInstance,
|
|
222
|
+
});
|
|
147
223
|
});
|
|
148
224
|
});
|
|
149
225
|
|
|
@@ -158,7 +234,9 @@ describe('line component', () => {
|
|
|
158
234
|
|
|
159
235
|
it('is inline if correct prop value is set', async () => {
|
|
160
236
|
createShallowWrapper({
|
|
161
|
-
|
|
237
|
+
props: {
|
|
238
|
+
legendLayout: LEGEND_LAYOUT_INLINE,
|
|
239
|
+
},
|
|
162
240
|
});
|
|
163
241
|
|
|
164
242
|
await nextTick();
|
|
@@ -168,7 +246,9 @@ describe('line component', () => {
|
|
|
168
246
|
|
|
169
247
|
it('is tabular if correct prop value is set', async () => {
|
|
170
248
|
createShallowWrapper({
|
|
171
|
-
|
|
249
|
+
props: {
|
|
250
|
+
legendLayout: LEGEND_LAYOUT_TABLE,
|
|
251
|
+
},
|
|
172
252
|
});
|
|
173
253
|
|
|
174
254
|
await nextTick();
|
|
@@ -177,7 +257,9 @@ describe('line component', () => {
|
|
|
177
257
|
});
|
|
178
258
|
it('can be hidden', async () => {
|
|
179
259
|
createShallowWrapper({
|
|
180
|
-
|
|
260
|
+
props: {
|
|
261
|
+
showLegend: false,
|
|
262
|
+
},
|
|
181
263
|
});
|
|
182
264
|
|
|
183
265
|
await nextTick();
|
|
@@ -188,7 +270,7 @@ describe('line component', () => {
|
|
|
188
270
|
|
|
189
271
|
describe('height', () => {
|
|
190
272
|
expectHeightAutoClasses({
|
|
191
|
-
createComponent: createShallowWrapper,
|
|
273
|
+
createComponent: (props) => createShallowWrapper({ props }),
|
|
192
274
|
findContainer: () => wrapper,
|
|
193
275
|
findChart,
|
|
194
276
|
});
|
|
@@ -56,7 +56,7 @@ const defaultOptions = {
|
|
|
56
56
|
},
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const template = `<gl-line-chart
|
|
59
|
+
const template = (content = '') => `<gl-line-chart
|
|
60
60
|
:data="data"
|
|
61
61
|
:option="option"
|
|
62
62
|
:thresholds="thresholds"
|
|
@@ -64,7 +64,9 @@ const template = `<gl-line-chart
|
|
|
64
64
|
:includeLegendAvgMax="includeLegendAvgMax"
|
|
65
65
|
:showLegend="showLegend"
|
|
66
66
|
:height="height"
|
|
67
|
-
|
|
67
|
+
>
|
|
68
|
+
${content}
|
|
69
|
+
</gl-line-chart>`;
|
|
68
70
|
|
|
69
71
|
const generateProps = ({
|
|
70
72
|
data = defaultData,
|
|
@@ -87,7 +89,7 @@ const generateProps = ({
|
|
|
87
89
|
const Template = (_args, { argTypes }) => ({
|
|
88
90
|
props: Object.keys(argTypes),
|
|
89
91
|
components,
|
|
90
|
-
template,
|
|
92
|
+
template: template(),
|
|
91
93
|
});
|
|
92
94
|
|
|
93
95
|
export const Default = Template.bind({});
|
|
@@ -99,7 +101,7 @@ WithThreshold.args = generateProps({
|
|
|
99
101
|
});
|
|
100
102
|
|
|
101
103
|
export const WithAnnotationsAsProps = Template.bind({});
|
|
102
|
-
WithAnnotationsAsProps.
|
|
104
|
+
WithAnnotationsAsProps.storyName = 'with annotations as props (recommended)';
|
|
103
105
|
WithAnnotationsAsProps.args = generateProps({
|
|
104
106
|
...mockAnnotationsConfigs,
|
|
105
107
|
data: [
|
|
@@ -200,6 +202,21 @@ NoLegend.args = generateProps({
|
|
|
200
202
|
showLegend: false,
|
|
201
203
|
});
|
|
202
204
|
|
|
205
|
+
export const WithCustomTooltip = (_args, { argTypes }) => ({
|
|
206
|
+
props: Object.keys(argTypes),
|
|
207
|
+
components,
|
|
208
|
+
template: template(`
|
|
209
|
+
<template #tooltip-title="{ params }">{{params && params.value}}</template>
|
|
210
|
+
<template #tooltip-content="{ params }">
|
|
211
|
+
<div v-for="p in params && params.seriesData">{{p.seriesName}}: {{p.value[1]}}</div>
|
|
212
|
+
</template>
|
|
213
|
+
`),
|
|
214
|
+
});
|
|
215
|
+
WithCustomTooltip.args = generateProps();
|
|
216
|
+
WithCustomTooltip.parameters = {
|
|
217
|
+
storyshots: { disable: true },
|
|
218
|
+
};
|
|
219
|
+
|
|
203
220
|
export default {
|
|
204
221
|
title: 'charts/line-chart',
|
|
205
222
|
component: GlLineChart,
|
|
@@ -30,8 +30,6 @@ import {
|
|
|
30
30
|
mergeSeriesToOptions,
|
|
31
31
|
mergeAnnotationAxisToOptions,
|
|
32
32
|
lineStyle,
|
|
33
|
-
// eslint-disable-next-line import/no-deprecated
|
|
34
|
-
getDefaultTooltipContent,
|
|
35
33
|
} from '../../../utils/charts/config';
|
|
36
34
|
import {
|
|
37
35
|
LEGEND_LAYOUT_INLINE,
|
|
@@ -44,7 +42,6 @@ import {
|
|
|
44
42
|
} from '../../../utils/charts/constants';
|
|
45
43
|
import { colorFromDefaultPalette } from '../../../utils/charts/theme';
|
|
46
44
|
import { seriesHasAnnotations, isDataPointAnnotation } from '../../../utils/charts/utils';
|
|
47
|
-
import TooltipDefaultFormat from '../../shared_components/charts/tooltip_default_format.vue';
|
|
48
45
|
import Chart from '../chart/chart.vue';
|
|
49
46
|
import ChartLegend from '../legend/legend.vue';
|
|
50
47
|
import ChartTooltip from '../tooltip/tooltip.vue';
|
|
@@ -55,7 +52,6 @@ export default {
|
|
|
55
52
|
Chart,
|
|
56
53
|
ChartLegend,
|
|
57
54
|
ChartTooltip,
|
|
58
|
-
TooltipDefaultFormat,
|
|
59
55
|
},
|
|
60
56
|
inheritAttrs: false,
|
|
61
57
|
props: {
|
|
@@ -83,6 +79,12 @@ export default {
|
|
|
83
79
|
required: false,
|
|
84
80
|
default: true,
|
|
85
81
|
},
|
|
82
|
+
/**
|
|
83
|
+
* Callback called when showing or refreshing a tooltip.
|
|
84
|
+
* **Deprecated:** Use slots `#tooltip-title`, `#tooltip-content` or `#tooltip-value`.
|
|
85
|
+
*
|
|
86
|
+
* @deprecated Use slots `#tooltip-title`, `#tooltip-content` or `#tooltip-value`.
|
|
87
|
+
*/
|
|
86
88
|
formatTooltipText: {
|
|
87
89
|
type: Function,
|
|
88
90
|
required: false,
|
|
@@ -137,8 +139,6 @@ export default {
|
|
|
137
139
|
// https://gitlab.com/gitlab-org/gitlab-ui/-/issues/618
|
|
138
140
|
return {
|
|
139
141
|
chart: null,
|
|
140
|
-
dataTooltipTitle: '',
|
|
141
|
-
dataTooltipContent: {},
|
|
142
142
|
showAnnotationsTooltip: false,
|
|
143
143
|
annotationsTooltipTitle: '',
|
|
144
144
|
annotationsTooltipContent: '',
|
|
@@ -146,7 +146,6 @@ export default {
|
|
|
146
146
|
left: '0',
|
|
147
147
|
top: '0',
|
|
148
148
|
},
|
|
149
|
-
selectedFormatTooltipText: this.formatTooltipText || this.defaultFormatTooltipText,
|
|
150
149
|
};
|
|
151
150
|
},
|
|
152
151
|
computed: {
|
|
@@ -187,7 +186,7 @@ export default {
|
|
|
187
186
|
axisPointer: {
|
|
188
187
|
show: true,
|
|
189
188
|
label: {
|
|
190
|
-
formatter: this.
|
|
189
|
+
formatter: this.formatTooltipText,
|
|
191
190
|
},
|
|
192
191
|
},
|
|
193
192
|
axisTick: {
|
|
@@ -260,13 +259,6 @@ export default {
|
|
|
260
259
|
this.chart.off('mouseover', this.onChartDataPointMouseOver);
|
|
261
260
|
},
|
|
262
261
|
methods: {
|
|
263
|
-
defaultFormatTooltipText(params) {
|
|
264
|
-
// eslint-disable-next-line import/no-deprecated
|
|
265
|
-
const { xLabels, tooltipContent } = getDefaultTooltipContent(params, this.options.yAxis.name);
|
|
266
|
-
|
|
267
|
-
this.$set(this, 'dataTooltipContent', tooltipContent);
|
|
268
|
-
this.dataTooltipTitle = xLabels.join(', ');
|
|
269
|
-
},
|
|
270
262
|
defaultAnnotationTooltipText(params) {
|
|
271
263
|
return {
|
|
272
264
|
title: params.data.xAxis,
|
|
@@ -314,9 +306,6 @@ export default {
|
|
|
314
306
|
};
|
|
315
307
|
}
|
|
316
308
|
},
|
|
317
|
-
onLabelChange(params) {
|
|
318
|
-
this.selectedFormatTooltipText(params);
|
|
319
|
-
},
|
|
320
309
|
},
|
|
321
310
|
HEIGHT_AUTO_CLASSES,
|
|
322
311
|
};
|
|
@@ -347,21 +336,21 @@ export default {
|
|
|
347
336
|
</template>
|
|
348
337
|
<div>{{ annotationsTooltipContent }}</div>
|
|
349
338
|
</chart-tooltip>
|
|
350
|
-
<chart-tooltip
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
339
|
+
<chart-tooltip
|
|
340
|
+
v-if="chart"
|
|
341
|
+
ref="dataTooltip"
|
|
342
|
+
:chart="chart"
|
|
343
|
+
:use-default-tooltip-formatter="!formatTooltipText"
|
|
344
|
+
>
|
|
345
|
+
<template v-if="$scopedSlots['tooltip-title']" #title="scope">
|
|
346
|
+
<slot name="tooltip-title" v-bind="scope"></slot>
|
|
347
|
+
</template>
|
|
348
|
+
<template v-if="$scopedSlots['tooltip-content']" #default="scope">
|
|
349
|
+
<slot name="tooltip-content" v-bind="scope"></slot>
|
|
350
|
+
</template>
|
|
351
|
+
<template v-if="$scopedSlots['tooltip-value']" #tooltip-value="scope">
|
|
352
|
+
<slot name="tooltip-value" v-bind="scope"></slot>
|
|
357
353
|
</template>
|
|
358
|
-
<slot v-if="formatTooltipText" name="tooltip-content"></slot>
|
|
359
|
-
<tooltip-default-format v-else :tooltip-content="dataTooltipContent">
|
|
360
|
-
<template v-if="$scopedSlots['tooltip-value']" #tooltip-value="scope">
|
|
361
|
-
<!-- @slot Tooltip value formatter -->
|
|
362
|
-
<slot name="tooltip-value" v-bind="scope"></slot>
|
|
363
|
-
</template>
|
|
364
|
-
</tooltip-default-format>
|
|
365
354
|
</chart-tooltip>
|
|
366
355
|
<chart-legend
|
|
367
356
|
v-if="hasLegend"
|
|
@@ -444,6 +444,15 @@ describe('GlDuoChat', () => {
|
|
|
444
444
|
await nextTick();
|
|
445
445
|
expect(findSlashCommandsCard().exists()).toBe(false);
|
|
446
446
|
});
|
|
447
|
+
|
|
448
|
+
it('shows default placeholder in the chat input', () => {
|
|
449
|
+
createComponent({
|
|
450
|
+
propsData: {
|
|
451
|
+
withSlashCommands: false,
|
|
452
|
+
},
|
|
453
|
+
});
|
|
454
|
+
expect(findChatInput().attributes('placeholder')).toBe('GitLab Duo Chat');
|
|
455
|
+
});
|
|
447
456
|
});
|
|
448
457
|
|
|
449
458
|
describe('with the `withSlashCommands` enabled', () => {
|
|
@@ -478,6 +487,15 @@ describe('GlDuoChat', () => {
|
|
|
478
487
|
});
|
|
479
488
|
});
|
|
480
489
|
|
|
490
|
+
it('shows the correct placeholder in the chat input', () => {
|
|
491
|
+
createComponent({
|
|
492
|
+
propsData: {
|
|
493
|
+
withSlashCommands: true,
|
|
494
|
+
},
|
|
495
|
+
});
|
|
496
|
+
expect(findChatInput().attributes('placeholder')).toBe('Type "/" for slash commands');
|
|
497
|
+
});
|
|
498
|
+
|
|
481
499
|
describe('when the prompt includes the "/" character or no characters', () => {
|
|
482
500
|
it.each(['', '//', '\\', 'foo', '/foo'])(
|
|
483
501
|
'does not render the slash commands if prompt is "$prompt"',
|
|
@@ -24,7 +24,8 @@ export const i18n = {
|
|
|
24
24
|
CHAT_LEGAL_GENERATED_BY_AI: 'Responses generated by AI',
|
|
25
25
|
CHAT_EMPTY_STATE_TITLE: 'Ask a question',
|
|
26
26
|
CHAT_EMPTY_STATE_DESC: 'AI generated explanations will appear here.',
|
|
27
|
-
|
|
27
|
+
CHAT_PROMPT_PLACEHOLDER_DEFAULT: 'GitLab Duo Chat',
|
|
28
|
+
CHAT_PROMPT_PLACEHOLDER_WITH_COMMANDS: 'Type "/" for slash commands',
|
|
28
29
|
CHAT_SUBMIT_LABEL: 'Send chat message.',
|
|
29
30
|
CHAT_LEGAL_DISCLAIMER:
|
|
30
31
|
"May provide inappropriate responses not representative of GitLab's views. Do not input personal data.",
|
|
@@ -45,17 +46,17 @@ export const slashCommands = [
|
|
|
45
46
|
{
|
|
46
47
|
name: '/tests',
|
|
47
48
|
shouldSubmit: false,
|
|
48
|
-
description: 'Write tests for the
|
|
49
|
+
description: 'Write tests for the selected snippet.',
|
|
49
50
|
},
|
|
50
51
|
{
|
|
51
52
|
name: '/refactor',
|
|
52
53
|
shouldSubmit: false,
|
|
53
|
-
description: 'Refactor the
|
|
54
|
+
description: 'Refactor the selected snippet.',
|
|
54
55
|
},
|
|
55
56
|
{
|
|
56
57
|
name: '/explain',
|
|
57
58
|
shouldSubmit: false,
|
|
58
|
-
description: 'Explain the
|
|
59
|
+
description: 'Explain the selected snippet.',
|
|
59
60
|
},
|
|
60
61
|
];
|
|
61
62
|
|
|
@@ -215,6 +216,11 @@ export default {
|
|
|
215
216
|
);
|
|
216
217
|
return startsWithSlash && this.filteredSlashCommands.length && !startsWithSlashCommand;
|
|
217
218
|
},
|
|
219
|
+
inputPlaceholder() {
|
|
220
|
+
return this.withSlashCommands
|
|
221
|
+
? i18n.CHAT_PROMPT_PLACEHOLDER_WITH_COMMANDS
|
|
222
|
+
: i18n.CHAT_PROMPT_PLACEHOLDER_DEFAULT;
|
|
223
|
+
},
|
|
218
224
|
},
|
|
219
225
|
watch: {
|
|
220
226
|
isLoading() {
|
|
@@ -471,7 +477,7 @@ export default {
|
|
|
471
477
|
data-testid="chat-prompt-input"
|
|
472
478
|
class="gl-absolute gl-h-full! gl-py-4! gl-bg-transparent! gl-rounded-top-right-none gl-rounded-bottom-right-none gl-shadow-none!"
|
|
473
479
|
:class="{ 'gl-text-truncate': !prompt }"
|
|
474
|
-
:placeholder="
|
|
480
|
+
:placeholder="inputPlaceholder"
|
|
475
481
|
:disabled="isLoading"
|
|
476
482
|
autofocus
|
|
477
483
|
@keydown.enter.exact.native.prevent
|
package/src/scss/variables.scss
CHANGED
|
@@ -58,13 +58,6 @@ $white-dark: #eaeaea !default;
|
|
|
58
58
|
$white-transparent: rgba(255, 255, 255, 0.8) !default;
|
|
59
59
|
$transparent-rgba: rgba($white, 0);
|
|
60
60
|
|
|
61
|
-
$t-gray-a-02: rgba($gray-950, 0.02) !default;
|
|
62
|
-
$t-gray-a-04: rgba($gray-950, 0.04) !default;
|
|
63
|
-
$t-gray-a-06: rgba($gray-950, 0.06) !default;
|
|
64
|
-
$t-gray-a-08: rgba($gray-950, 0.08) !default;
|
|
65
|
-
$t-gray-a-16: rgba($gray-950, 0.16) !default;
|
|
66
|
-
$t-gray-a-24: rgba($gray-950, 0.24) !default;
|
|
67
|
-
|
|
68
61
|
// Text
|
|
69
62
|
$gl-text-color: $gray-900 !default;
|
|
70
63
|
$gl-text-color-secondary: $gray-500 !default;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"t-gray-a": {
|
|
3
|
+
"02": {
|
|
4
|
+
"$value": "rgba(31, 30, 36, 0.02)",
|
|
5
|
+
"$type": "color",
|
|
6
|
+
"themeable": true,
|
|
7
|
+
"prefix": false
|
|
8
|
+
},
|
|
9
|
+
"04": {
|
|
10
|
+
"$value": "rgba(31, 30, 36, 0.04)",
|
|
11
|
+
"$type": "color",
|
|
12
|
+
"themeable": true,
|
|
13
|
+
"prefix": false
|
|
14
|
+
},
|
|
15
|
+
"06": {
|
|
16
|
+
"$value": "rgba(31, 30, 36, 0.06)",
|
|
17
|
+
"$type": "color",
|
|
18
|
+
"themeable": true,
|
|
19
|
+
"prefix": false
|
|
20
|
+
},
|
|
21
|
+
"08": {
|
|
22
|
+
"$value": "rgba(31, 30, 36, 0.08)",
|
|
23
|
+
"$type": "color",
|
|
24
|
+
"themeable": true,
|
|
25
|
+
"prefix": false
|
|
26
|
+
},
|
|
27
|
+
"16": {
|
|
28
|
+
"$value": "rgba(31, 30, 36, 0.16)",
|
|
29
|
+
"$type": "color",
|
|
30
|
+
"themeable": true,
|
|
31
|
+
"prefix": false
|
|
32
|
+
},
|
|
33
|
+
"24": {
|
|
34
|
+
"$value": "rgba(31, 30, 36, 0.24)",
|
|
35
|
+
"$type": "color",
|
|
36
|
+
"themeable": true,
|
|
37
|
+
"prefix": false
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"t-white-a": {
|
|
41
|
+
"02": {
|
|
42
|
+
"$value": "rgba(255, 255, 255, 0.02)",
|
|
43
|
+
"$type": "color",
|
|
44
|
+
"themeable": true,
|
|
45
|
+
"prefix": false
|
|
46
|
+
},
|
|
47
|
+
"04": {
|
|
48
|
+
"$value": "rgba(255, 255, 255, 0.04)",
|
|
49
|
+
"$type": "color",
|
|
50
|
+
"themeable": true,
|
|
51
|
+
"prefix": false
|
|
52
|
+
},
|
|
53
|
+
"06": {
|
|
54
|
+
"$value": "rgba(255, 255, 255, 0.06)",
|
|
55
|
+
"$type": "color",
|
|
56
|
+
"themeable": true,
|
|
57
|
+
"prefix": false
|
|
58
|
+
},
|
|
59
|
+
"08": {
|
|
60
|
+
"$value": "rgba(255, 255, 255, 0.08)",
|
|
61
|
+
"$type": "color",
|
|
62
|
+
"themeable": true,
|
|
63
|
+
"prefix": false
|
|
64
|
+
},
|
|
65
|
+
"16": {
|
|
66
|
+
"$value": "rgba(255, 255, 255, 0.16)",
|
|
67
|
+
"$type": "color",
|
|
68
|
+
"themeable": true,
|
|
69
|
+
"prefix": false
|
|
70
|
+
},
|
|
71
|
+
"24": {
|
|
72
|
+
"$value": "rgba(255, 255, 255, 0.24)",
|
|
73
|
+
"$type": "color",
|
|
74
|
+
"themeable": true,
|
|
75
|
+
"prefix": false
|
|
76
|
+
},
|
|
77
|
+
"36": {
|
|
78
|
+
"$value": "rgba(255, 255, 255, 0.36)",
|
|
79
|
+
"$type": "color",
|
|
80
|
+
"themeable": true,
|
|
81
|
+
"prefix": false
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { methods, template } from './common_story_options';
|
|
2
|
+
import colorTokens from './color.transparency.tokens.json';
|
|
3
|
+
|
|
4
|
+
const generateProps = ({ name = '', tokens = colorTokens } = {}) => ({
|
|
5
|
+
name,
|
|
6
|
+
tokens,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const Gray = (args, { argTypes }) => ({
|
|
10
|
+
props: Object.keys(argTypes),
|
|
11
|
+
methods,
|
|
12
|
+
template,
|
|
13
|
+
});
|
|
14
|
+
Gray.args = generateProps({ name: 't-gray-a', tokens: colorTokens['t-gray-a'] });
|
|
15
|
+
|
|
16
|
+
export const White = (args, { argTypes }) => ({
|
|
17
|
+
props: Object.keys(argTypes),
|
|
18
|
+
methods,
|
|
19
|
+
template: `<div class="gl-bg-gray-900 gl-text-white">${template}</div>`,
|
|
20
|
+
});
|
|
21
|
+
White.args = generateProps({ name: 't-white-a', tokens: colorTokens['t-white-a'] });
|
|
22
|
+
|
|
23
|
+
// eslint-disable-next-line storybook/csf-component
|
|
24
|
+
export default {
|
|
25
|
+
title: 'tokens/color/transparency',
|
|
26
|
+
};
|
|
@@ -5,6 +5,7 @@ export const methods = {
|
|
|
5
5
|
return [name, key].filter(Boolean).join('.');
|
|
6
6
|
},
|
|
7
7
|
getTextColorClass(value) {
|
|
8
|
+
if (value.startsWith('rgba(')) return '';
|
|
8
9
|
const textColorVariant = colorFromBackground(value, 4.5);
|
|
9
10
|
return {
|
|
10
11
|
'gl-text-gray-950': textColorVariant === 'dark',
|