@gitlab/ui 64.1.0 → 64.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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [64.2.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v64.1.1...v64.2.0) (2023-06-02)
2
+
3
+
4
+ ### Features
5
+
6
+ * **GlFilteredSearchToken:** Pass input attributes to data segment ([e8dcc5f](https://gitlab.com/gitlab-org/gitlab-ui/commit/e8dcc5f8fb8ff4b6fa78f1e46b899a18990d39c8))
7
+
8
+ ## [64.1.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v64.1.0...v64.1.1) (2023-06-01)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **dropdowns:** auto-focus only once dropdown is properly positioned ([fe6c39d](https://gitlab.com/gitlab-org/gitlab-ui/commit/fe6c39dee065cbbc35dd225ea0e565dba368af14))
14
+
1
15
  # [64.1.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v64.0.2...v64.1.0) (2023-05-30)
2
16
 
3
17
 
@@ -81,6 +81,11 @@ var script = {
81
81
  type: Boolean,
82
82
  required: false,
83
83
  default: false
84
+ },
85
+ dataSegmentInputAttributes: {
86
+ type: Object,
87
+ required: false,
88
+ default: () => ({})
84
89
  }
85
90
  },
86
91
  data() {
@@ -322,7 +327,7 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
322
327
  var inputValue = ref.inputValue;
323
328
  return [_c('gl-token',{staticClass:"gl-filtered-search-token-type",class:_vm.getAdditionalSegmentClasses(_vm.$options.segments.SEGMENT_TITLE),attrs:{"view-only":""}},[_vm._v("\n "+_vm._s(inputValue)+"\n ")])]}}])}),_vm._v(" "),_c('gl-filtered-search-token-segment',{key:"operator-segment",attrs:{"active":_vm.isSegmentActive(_vm.$options.segments.SEGMENT_OPERATOR),"cursor-position":_vm.intendedCursorPosition,"options":_vm.operators,"option-text-field":"value","custom-input-keydown-handler":_vm.handleOperatorKeydown,"view-only":_vm.viewOnly},on:{"activate":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_OPERATOR)},"backspace":_vm.replaceWithTermIfEmpty,"complete":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_DATA)},"deactivate":function($event){return _vm.$emit('deactivate')},"previous":_vm.activatePreviousTitleSegment,"next":_vm.activateNextDataSegment},scopedSlots:_vm._u([{key:"view",fn:function(){return [_c('gl-token',{staticClass:"gl-filtered-search-token-operator",class:_vm.getAdditionalSegmentClasses(_vm.$options.segments.SEGMENT_OPERATOR),attrs:{"variant":"search-value","view-only":""}},[_vm._v("\n "+_vm._s(_vm.operatorDescription)+"\n ")])]},proxy:true},{key:"option",fn:function(ref){
324
329
  var option = ref.option;
325
- return [_c('div',{staticClass:"gl-display-flex"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.description : option.value)+"\n "),(option.description)?_c('span',{staticClass:"gl-filtered-search-token-operator-description"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.value : option.description)+"\n ")]):_vm._e()])]}}]),model:{value:(_vm.tokenValue.operator),callback:function ($$v) {_vm.$set(_vm.tokenValue, "operator", $$v);},expression:"tokenValue.operator"}}),_vm._v(" "),(_vm.hasDataOrDataSegmentIsCurrentlyActive)?_c('gl-filtered-search-token-segment',{key:"data-segment",attrs:{"active":_vm.isSegmentActive(_vm.$options.segments.SEGMENT_DATA),"cursor-position":_vm.intendedCursorPosition,"multi-select":_vm.config.multiSelect,"options":_vm.config.options,"view-only":_vm.viewOnly},on:{"activate":_vm.activateDataSegment,"backspace":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_OPERATOR)},"complete":_vm.handleComplete,"select":function($event){return _vm.$emit('select', $event)},"submit":function($event){return _vm.$emit('submit')},"deactivate":function($event){return _vm.$emit('deactivate')},"split":function($event){return _vm.$emit('split', $event)},"previous":_vm.activatePreviousOperatorSegment,"next":function($event){return _vm.$emit('next')}},scopedSlots:_vm._u([{key:"suggestions",fn:function(){return [_vm._t("suggestions")]},proxy:true},{key:"view",fn:function(ref){
330
+ return [_c('div',{staticClass:"gl-display-flex"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.description : option.value)+"\n "),(option.description)?_c('span',{staticClass:"gl-filtered-search-token-operator-description"},[_vm._v("\n "+_vm._s(_vm.showFriendlyText ? option.value : option.description)+"\n ")]):_vm._e()])]}}]),model:{value:(_vm.tokenValue.operator),callback:function ($$v) {_vm.$set(_vm.tokenValue, "operator", $$v);},expression:"tokenValue.operator"}}),_vm._v(" "),(_vm.hasDataOrDataSegmentIsCurrentlyActive)?_c('gl-filtered-search-token-segment',{key:"data-segment",attrs:{"active":_vm.isSegmentActive(_vm.$options.segments.SEGMENT_DATA),"cursor-position":_vm.intendedCursorPosition,"multi-select":_vm.config.multiSelect,"options":_vm.config.options,"view-only":_vm.viewOnly,"search-input-attributes":_vm.dataSegmentInputAttributes},on:{"activate":_vm.activateDataSegment,"backspace":function($event){return _vm.activateSegment(_vm.$options.segments.SEGMENT_OPERATOR)},"complete":_vm.handleComplete,"select":function($event){return _vm.$emit('select', $event)},"submit":function($event){return _vm.$emit('submit')},"deactivate":function($event){return _vm.$emit('deactivate')},"split":function($event){return _vm.$emit('split', $event)},"previous":_vm.activatePreviousOperatorSegment,"next":function($event){return _vm.$emit('next')}},scopedSlots:_vm._u([{key:"suggestions",fn:function(){return [_vm._t("suggestions")]},proxy:true},{key:"view",fn:function(ref){
326
331
  var inputValue = ref.inputValue;
327
332
  return [_vm._t("view-token",function(){return [_c('gl-token',_vm._g({staticClass:"gl-filtered-search-token-data",class:_vm.getAdditionalSegmentClasses(_vm.$options.segments.SEGMENT_DATA),attrs:{"variant":"search-value","view-only":_vm.viewOnly}},_vm.eventListeners),[_c('span',{staticClass:"gl-filtered-search-token-data-content"},[_vm._t("view",function(){return [_vm._v(_vm._s(inputValue))]},null,{ inputValue: inputValue })],2)])]},null,{
328
333
  inputValue: inputValue,
@@ -138,7 +138,6 @@ var script = {
138
138
  data() {
139
139
  return {
140
140
  visible: false,
141
- openedYet: false,
142
141
  baseDropdownId: uniqueId('base-dropdown-')
143
142
  };
144
143
  },
@@ -264,7 +263,7 @@ var script = {
264
263
  Use 'a' or 'button' element instead or make sure to add 'role="button"' along with 'tabindex' otherwise.`, this.$el);
265
264
  }
266
265
  },
267
- startFloating() {
266
+ async startFloating() {
268
267
  this.calculateNonScrollableAreaHeight();
269
268
  this.observer = new MutationObserver(this.calculateNonScrollableAreaHeight);
270
269
  this.observer.observe(this.$refs.content, {
@@ -272,22 +271,26 @@ var script = {
272
271
  childList: true,
273
272
  subtree: true
274
273
  });
275
- this.stopAutoUpdate = autoUpdate(this.toggleElement, this.$refs.content, async () => {
276
- const {
277
- x,
278
- y
279
- } = await computePosition(this.toggleElement, this.$refs.content, this.floatingUIConfig);
274
+ await new Promise(resolve => {
275
+ const stopAutoUpdate = autoUpdate(this.toggleElement, this.$refs.content, async () => {
276
+ const {
277
+ x,
278
+ y
279
+ } = await computePosition(this.toggleElement, this.$refs.content, this.floatingUIConfig);
280
280
 
281
- /**
282
- * Due to the asynchronous nature of computePosition, it's technically possible for the
283
- * component to have been destroyed by the time the promise resolves. In such case, we exit
284
- * early to prevent a TypeError.
285
- */
286
- if (!this.$refs.content) return;
287
- Object.assign(this.$refs.content.style, {
288
- left: `${x}px`,
289
- top: `${y}px`
281
+ /**
282
+ * Due to the asynchronous nature of computePosition, it's technically possible for the
283
+ * component to have been destroyed by the time the promise resolves. In such case, we exit
284
+ * early to prevent a TypeError.
285
+ */
286
+ if (!this.$refs.content) return;
287
+ Object.assign(this.$refs.content.style, {
288
+ left: `${x}px`,
289
+ top: `${y}px`
290
+ });
291
+ resolve(stopAutoUpdate);
290
292
  });
293
+ this.stopAutoUpdate = stopAutoUpdate;
291
294
  });
292
295
  },
293
296
  stopFloating() {
@@ -298,12 +301,15 @@ var script = {
298
301
  async toggle() {
299
302
  this.visible = !this.visible;
300
303
  if (this.visible) {
304
+ // The dropdown needs to be actually visible before we compute its position with Floating UI.
305
+ await this.$nextTick();
306
+
301
307
  /**
302
- * We defer the following logic to the next tick as all that comes next relies on the
303
- * dropdown actually being visible.
308
+ * We wait until the dropdown's position has been computed before emitting the `shown` event.
309
+ * This ensures that, if the parent component attempts to focus an inner element, the dropdown
310
+ * is already properly placed in the page. Otherwise, the page would scroll back to the top.
304
311
  */
305
- await this.$nextTick();
306
- this.startFloating();
312
+ await this.startFloating();
307
313
  this.$emit(GL_DROPDOWN_SHOWN);
308
314
  } else {
309
315
  this.stopFloating();
@@ -57,6 +57,35 @@ const mockGroups = [{
57
57
  value: 'v2.1'
58
58
  }]
59
59
  }];
60
+ const mockGroupsWithTextSrOnly = [{
61
+ text: 'Default',
62
+ options: [{
63
+ text: 'main',
64
+ value: 'main'
65
+ }, {
66
+ text: 'development',
67
+ value: 'development'
68
+ }],
69
+ textSrOnly: true
70
+ }, {
71
+ text: 'Feature branches',
72
+ options: [{
73
+ text: 'feature/add-avatar',
74
+ value: 'add'
75
+ }, {
76
+ text: 'feature/improve-panel',
77
+ value: 'improve'
78
+ }]
79
+ }, {
80
+ text: 'Bugfix branches',
81
+ options: [{
82
+ text: 'fix/border-of-avatar',
83
+ value: 'fix-border'
84
+ }, {
85
+ text: 'fix/radius-panel',
86
+ value: 'fix-radius'
87
+ }]
88
+ }];
60
89
  const mockUsers = [{
61
90
  value: 'mikegreiling',
62
91
  text: 'Mike Greiling',
@@ -74,4 +103,4 @@ const mockUsers = [{
74
103
  icon: 'bin'
75
104
  }];
76
105
 
77
- export { mockGroups, mockOptions, mockUsers };
106
+ export { mockGroups, mockGroupsWithTextSrOnly, mockOptions, mockUsers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "64.1.0",
3
+ "version": "64.2.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -85,7 +85,7 @@
85
85
  "devDependencies": {
86
86
  "@arkweid/lefthook": "0.7.7",
87
87
  "@babel/core": "^7.22.1",
88
- "@babel/preset-env": "^7.22.2",
88
+ "@babel/preset-env": "^7.22.4",
89
89
  "@babel/preset-react": "^7.22.3",
90
90
  "@gitlab/eslint-plugin": "19.0.0",
91
91
  "@gitlab/fonts": "^1.2.0",
@@ -210,6 +210,21 @@ describe('Filtered search token', () => {
210
210
  expect(wrapper.emitted().replace[0][0].value).toStrictEqual({ data: '' });
211
211
  });
212
212
 
213
+ it('sets input attributes on data segment when provided', () => {
214
+ const dataSegmentInputAttributes = {
215
+ placeholder: 'YYYY-MM-DD',
216
+ id: 'this-id',
217
+ };
218
+ createComponent({
219
+ active: true,
220
+ dataSegmentInputAttributes,
221
+ value: { operator: '=', data: 'something' },
222
+ });
223
+ expect(findDataSegment().props().searchInputAttributes).toStrictEqual(
224
+ dataSegmentInputAttributes
225
+ );
226
+ });
227
+
213
228
  describe('integration tests', () => {
214
229
  beforeAll(() => {
215
230
  if (!HTMLElement.prototype.scrollIntoView) {
@@ -1,6 +1,7 @@
1
1
  import PortalVue from 'portal-vue';
2
2
  import Vue from 'vue';
3
3
  import GlIcon from '../icon/icon.vue';
4
+ import GlDatepicker from '../datepicker/datepicker.vue';
4
5
  import { provide } from './common_story_options';
5
6
  import GlFilteredSearchSuggestion from './filtered_search_suggestion.vue';
6
7
  import readme from './filtered_search_token.md';
@@ -153,6 +154,53 @@ export const WithStaticOptions = (args, { argTypes }) => ({
153
154
  });
154
155
  WithStaticOptions.args = generateProps();
155
156
 
157
+ // eslint-disable-next-line no-unused-vars
158
+ export const WithDataSegmentInputAttributes = (args, { argTypes }) => ({
159
+ components: {
160
+ GlFilteredSearchToken,
161
+ GlDatepicker,
162
+ },
163
+ provide,
164
+ props: ['active'],
165
+ data() {
166
+ return {
167
+ value: { operator: '<', data: null },
168
+ config: {
169
+ title: 'Date',
170
+ operators: [
171
+ { value: '<', description: 'before' },
172
+ { value: '>', description: 'after' },
173
+ ],
174
+ },
175
+ dataSegmentInputAttributes: {
176
+ placeholder: 'YYYY-MM-DD',
177
+ id: 'this-id',
178
+ },
179
+ };
180
+ },
181
+ mounted() {
182
+ this.$nextTick(() => {
183
+ document.activeElement.blur();
184
+ });
185
+ },
186
+ template: `
187
+ <div>
188
+ <div> {{ value }} </div>
189
+ <div class="gl-border-1 gl-border-solid gl-border-gray-200">
190
+ <gl-filtered-search-token
191
+ v-model="value"
192
+ class="gl-h-full"
193
+ :config="config"
194
+ :active="active"
195
+ :data-segment-input-attributes="dataSegmentInputAttributes"
196
+ />
197
+ <gl-datepicker target='#this-id' />
198
+ </div>
199
+ </div>
200
+ `,
201
+ });
202
+ WithDataSegmentInputAttributes.args = generateProps();
203
+
156
204
  export default {
157
205
  title: 'base/filtered-search/token',
158
206
  component: GlFilteredSearchToken,
@@ -78,6 +78,11 @@ export default {
78
78
  required: false,
79
79
  default: false,
80
80
  },
81
+ dataSegmentInputAttributes: {
82
+ type: Object,
83
+ required: false,
84
+ default: () => ({}),
85
+ },
81
86
  },
82
87
  data() {
83
88
  return {
@@ -405,6 +410,7 @@ export default {
405
410
  :multi-select="config.multiSelect"
406
411
  :options="config.options"
407
412
  :view-only="viewOnly"
413
+ :search-input-attributes="dataSegmentInputAttributes"
408
414
  @activate="activateDataSegment"
409
415
  @backspace="activateSegment($options.segments.SEGMENT_OPERATOR)"
410
416
  @complete="handleComplete"
@@ -62,7 +62,7 @@ describe('base dropdown', () => {
62
62
  expect(autoUpdate).toHaveBeenCalledTimes(1);
63
63
  });
64
64
 
65
- it("stops Floating UI's when closing the dropdown", async () => {
65
+ it('stops Floating UI when closing the dropdown', async () => {
66
66
  buildWrapper();
67
67
  await findDefaultDropdownToggle().trigger('click');
68
68
  await findDefaultDropdownToggle().trigger('click');
@@ -71,7 +71,7 @@ describe('base dropdown', () => {
71
71
  expect(mockStopAutoUpdate).toHaveBeenCalledTimes(1);
72
72
  });
73
73
 
74
- it("restarts Floating UI's when reopening the dropdown", async () => {
74
+ it('restarts Floating UI when reopening the dropdown', async () => {
75
75
  buildWrapper();
76
76
  await findDefaultDropdownToggle().trigger('click');
77
77
  await findDefaultDropdownToggle().trigger('click');
@@ -335,6 +335,11 @@ describe('base dropdown', () => {
335
335
  });
336
336
 
337
337
  describe('toggle visibility', () => {
338
+ beforeEach(() => {
339
+ autoUpdate.mockImplementation(jest.requireActual('@floating-ui/dom').autoUpdate);
340
+ computePosition.mockImplementation(() => Promise.resolve);
341
+ });
342
+
338
343
  it('should toggle menu visibility on toggle click', async () => {
339
344
  const toggle = findCustomDropdownToggle();
340
345
  const firstToggleChild = findFirstToggleElement();
@@ -150,7 +150,6 @@ export default {
150
150
  data() {
151
151
  return {
152
152
  visible: false,
153
- openedYet: false,
154
153
  baseDropdownId: uniqueId('base-dropdown-'),
155
154
  };
156
155
  },
@@ -282,7 +281,7 @@ export default {
282
281
  );
283
282
  }
284
283
  },
285
- startFloating() {
284
+ async startFloating() {
286
285
  this.calculateNonScrollableAreaHeight();
287
286
  this.observer = new MutationObserver(this.calculateNonScrollableAreaHeight);
288
287
  this.observer.observe(this.$refs.content, {
@@ -291,24 +290,29 @@ export default {
291
290
  subtree: true,
292
291
  });
293
292
 
294
- this.stopAutoUpdate = autoUpdate(this.toggleElement, this.$refs.content, async () => {
295
- const { x, y } = await computePosition(
296
- this.toggleElement,
297
- this.$refs.content,
298
- this.floatingUIConfig
299
- );
293
+ await new Promise((resolve) => {
294
+ const stopAutoUpdate = autoUpdate(this.toggleElement, this.$refs.content, async () => {
295
+ const { x, y } = await computePosition(
296
+ this.toggleElement,
297
+ this.$refs.content,
298
+ this.floatingUIConfig
299
+ );
300
300
 
301
- /**
302
- * Due to the asynchronous nature of computePosition, it's technically possible for the
303
- * component to have been destroyed by the time the promise resolves. In such case, we exit
304
- * early to prevent a TypeError.
305
- */
306
- if (!this.$refs.content) return;
301
+ /**
302
+ * Due to the asynchronous nature of computePosition, it's technically possible for the
303
+ * component to have been destroyed by the time the promise resolves. In such case, we exit
304
+ * early to prevent a TypeError.
305
+ */
306
+ if (!this.$refs.content) return;
307
+
308
+ Object.assign(this.$refs.content.style, {
309
+ left: `${x}px`,
310
+ top: `${y}px`,
311
+ });
307
312
 
308
- Object.assign(this.$refs.content.style, {
309
- left: `${x}px`,
310
- top: `${y}px`,
313
+ resolve(stopAutoUpdate);
311
314
  });
315
+ this.stopAutoUpdate = stopAutoUpdate;
312
316
  });
313
317
  },
314
318
  stopFloating() {
@@ -319,12 +323,16 @@ export default {
319
323
  this.visible = !this.visible;
320
324
 
321
325
  if (this.visible) {
326
+ // The dropdown needs to be actually visible before we compute its position with Floating UI.
327
+ await this.$nextTick();
328
+
322
329
  /**
323
- * We defer the following logic to the next tick as all that comes next relies on the
324
- * dropdown actually being visible.
330
+ * We wait until the dropdown's position has been computed before emitting the `shown` event.
331
+ * This ensures that, if the parent component attempts to focus an inner element, the dropdown
332
+ * is already properly placed in the page. Otherwise, the page would scroll back to the top.
325
333
  */
326
- await this.$nextTick();
327
- this.startFloating();
334
+ await this.startFloating();
335
+
328
336
  this.$emit(GL_DROPDOWN_SHOWN);
329
337
  } else {
330
338
  this.stopFloating();
@@ -18,7 +18,7 @@ import GlIntersectionObserver from '../../../utilities/intersection_observer/int
18
18
  import GlCollapsibleListbox, { ITEM_SELECTOR } from './listbox.vue';
19
19
  import GlListboxItem from './listbox_item.vue';
20
20
  import GlListboxGroup from './listbox_group.vue';
21
- import { mockOptions, mockGroups } from './mock_data';
21
+ import { mockOptions, mockGroups, mockGroupsWithTextSrOnly } from './mock_data';
22
22
 
23
23
  jest.mock('@floating-ui/dom');
24
24
  autoUpdate.mockImplementation(() => {
@@ -398,14 +398,13 @@ describe('GlCollapsibleListbox', () => {
398
398
  });
399
399
 
400
400
  it('passes the `textSrOnly` prop', () => {
401
- const mockGroupsWithTextSrOnly = JSON.parse(JSON.stringify(mockGroups));
402
- mockGroupsWithTextSrOnly[0].textSrOnly = true;
403
- mockGroupsWithTextSrOnly[1].textSrOnly = false;
404
401
  buildWrapper({ items: mockGroupsWithTextSrOnly });
405
402
 
406
403
  const groups = findListboxGroups();
407
404
 
408
- const expectedTextSrOnlyProps = mockGroupsWithTextSrOnly.map((group) => group.textSrOnly);
405
+ const expectedTextSrOnlyProps = mockGroupsWithTextSrOnly.map(
406
+ (group) => group.textSrOnly ?? false
407
+ );
409
408
  const actualTextSrOnlyProps = groups.wrappers.map((group) => group.props('textSrOnly'));
410
409
 
411
410
  expect(actualTextSrOnlyProps).toEqual(expectedTextSrOnlyProps);
@@ -24,7 +24,7 @@ import {
24
24
  } from '../../../../utils/stories_constants';
25
25
  import { POSITION } from '../../../utilities/truncate/constants';
26
26
  import readme from './listbox.md';
27
- import { mockOptions, mockGroups, mockUsers } from './mock_data';
27
+ import { mockOptions, mockGroups, mockGroupsWithTextSrOnly, mockUsers } from './mock_data';
28
28
  import { flattenedOptions } from './utils';
29
29
  import GlCollapsibleListbox from './listbox.vue';
30
30
 
@@ -462,6 +462,33 @@ export const CustomGroupsAndItems = makeGroupedExample({
462
462
  `),
463
463
  });
464
464
 
465
+ export const GroupWithoutLabel = (args, { argTypes }) => ({
466
+ props: Object.keys(argTypes),
467
+ components: {
468
+ GlBadge,
469
+ GlCollapsibleListbox,
470
+ },
471
+ data() {
472
+ return {
473
+ selected: mockGroupsWithTextSrOnly[1].options[1].value,
474
+ };
475
+ },
476
+ mounted() {
477
+ if (this.startOpened) {
478
+ openListbox(this);
479
+ }
480
+ },
481
+ template: template(`
482
+ <template #list-item="{ item }">
483
+ {{ item.text }} <gl-badge v-if="item.value === 'main'" size="sm">default</gl-badge>
484
+ </template>
485
+ `),
486
+ });
487
+ GroupWithoutLabel.args = generateProps({
488
+ items: mockGroupsWithTextSrOnly,
489
+ headerText: 'Select branch',
490
+ });
491
+
465
492
  export default {
466
493
  title: 'base/new-dropdowns/listbox',
467
494
  component: GlCollapsibleListbox,
@@ -67,6 +67,49 @@ export const mockGroups = [
67
67
  },
68
68
  ];
69
69
 
70
+ export const mockGroupsWithTextSrOnly = [
71
+ {
72
+ text: 'Default',
73
+ options: [
74
+ {
75
+ text: 'main',
76
+ value: 'main',
77
+ },
78
+ {
79
+ text: 'development',
80
+ value: 'development',
81
+ },
82
+ ],
83
+ textSrOnly: true,
84
+ },
85
+ {
86
+ text: 'Feature branches',
87
+ options: [
88
+ {
89
+ text: 'feature/add-avatar',
90
+ value: 'add',
91
+ },
92
+ {
93
+ text: 'feature/improve-panel',
94
+ value: 'improve',
95
+ },
96
+ ],
97
+ },
98
+ {
99
+ text: 'Bugfix branches',
100
+ options: [
101
+ {
102
+ text: 'fix/border-of-avatar',
103
+ value: 'fix-border',
104
+ },
105
+ {
106
+ text: 'fix/radius-panel',
107
+ value: 'fix-radius',
108
+ },
109
+ ],
110
+ },
111
+ ];
112
+
70
113
  export const mockUsers = [
71
114
  {
72
115
  value: 'mikegreiling',
@@ -21,7 +21,7 @@
21
21
  @return $value;
22
22
  }
23
23
 
24
- $converted: $value / $font-size-base;
24
+ $converted: calc($value / $font-size-base);
25
25
 
26
26
  @return strip-unit($converted) * 1rem;
27
27
  }
@@ -54,7 +54,7 @@
54
54
  $min-width: px-to-rem($min-width);
55
55
  $max-width: px-to-rem($max-width);
56
56
 
57
- $slope: ($max - $min) / ($max-width - $min-width);
57
+ $slope: calc(($max - $min) / ($max-width - $min-width));
58
58
  $intersection: (-$min-width * $slope) + $min;
59
59
 
60
60
  // Use calc() inside of clamp() function to work around SassC