@gitlab/ui 107.6.1 → 107.7.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 +14 -0
- package/dist/components/base/new_dropdowns/base_dropdown/base_dropdown.js +69 -12
- package/dist/components/base/new_dropdowns/base_dropdown/constants.js +3 -2
- package/dist/components/base/new_dropdowns/disclosure/disclosure_dropdown.js +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/tailwind.css +1 -1
- package/dist/tailwind.css.map +1 -1
- package/package.json +3 -3
- package/src/components/base/button_group/button_group.scss +7 -1
- package/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue +73 -11
- package/src/components/base/new_dropdowns/base_dropdown/constants.js +2 -1
- package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.vue +1 -0
- package/src/components/base/new_dropdowns/dropdown.scss +16 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [107.7.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v107.6.2...v107.7.0) (2025-01-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **Dropdown:** Add indicator ([065c810](https://gitlab.com/gitlab-org/gitlab-ui/commit/065c810e49345d97748f7c3341604641372ad5b8))
|
|
7
|
+
|
|
8
|
+
## [107.6.2](https://gitlab.com/gitlab-org/gitlab-ui/compare/v107.6.1...v107.6.2) (2025-01-30)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **GlButtonGroup:** Fix specificity problem ([837d85c](https://gitlab.com/gitlab-org/gitlab-ui/commit/837d85c744068fc4d44301b75a6d672fac757e77))
|
|
14
|
+
|
|
1
15
|
## [107.6.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v107.6.0...v107.6.1) (2025-01-27)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import uniqueId from 'lodash/uniqueId';
|
|
2
|
-
import { offset, autoPlacement, shift, size, autoUpdate, computePosition } from '@floating-ui/dom';
|
|
2
|
+
import { offset, autoPlacement, shift, arrow, size, autoUpdate, computePosition } from '@floating-ui/dom';
|
|
3
3
|
import { buttonCategoryOptions, dropdownVariantOptions, buttonSizeOptions, dropdownPlacements, dropdownAllowedAutoPlacements } from '../../../../utils/constants';
|
|
4
4
|
import { POSITION_ABSOLUTE, POSITION_FIXED, GL_DROPDOWN_CONTENTS_CLASS, GL_DROPDOWN_BEFORE_CLOSE, GL_DROPDOWN_SHOWN, GL_DROPDOWN_HIDDEN, ENTER, SPACE, ARROW_DOWN, GL_DROPDOWN_FOCUS_CONTENT } from '../constants';
|
|
5
5
|
import { logWarning, isElementFocusable, isElementTabbable } from '../../../../utils/utils';
|
|
6
6
|
import { OutsideDirective } from '../../../../directives/outside/outside';
|
|
7
7
|
import GlButton from '../../button/button';
|
|
8
8
|
import GlIcon from '../../icon/icon';
|
|
9
|
-
import { DEFAULT_OFFSET, FIXED_WIDTH_CLASS } from './constants';
|
|
9
|
+
import { DEFAULT_OFFSET, FIXED_WIDTH_CLASS, ARROW_X_MINIMUM } from './constants';
|
|
10
10
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
11
11
|
|
|
12
12
|
const BASE_DROPDOWN_CLASS = 'gl-new-dropdown';
|
|
@@ -257,7 +257,9 @@ var script = {
|
|
|
257
257
|
middleware: [offset(this.offset), autoPlacement({
|
|
258
258
|
alignment,
|
|
259
259
|
allowedPlacements: dropdownAllowedAutoPlacements[this.placement]
|
|
260
|
-
}), shift(),
|
|
260
|
+
}), shift(), arrow({
|
|
261
|
+
element: this.$refs.dropdownArrow
|
|
262
|
+
}), size({
|
|
261
263
|
apply: _ref => {
|
|
262
264
|
var _this$nonScrollableCo;
|
|
263
265
|
let {
|
|
@@ -265,9 +267,7 @@ var script = {
|
|
|
265
267
|
elements
|
|
266
268
|
} = _ref;
|
|
267
269
|
const contentsEl = elements.floating.querySelector(`.${GL_DROPDOWN_CONTENTS_CLASS}`);
|
|
268
|
-
if (!contentsEl)
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
270
|
+
if (!contentsEl) return;
|
|
271
271
|
const contentsAvailableHeight = availableHeight - ((_this$nonScrollableCo = this.nonScrollableContentHeight) !== null && _this$nonScrollableCo !== void 0 ? _this$nonScrollableCo : 0) - DEFAULT_OFFSET;
|
|
272
272
|
Object.assign(contentsEl.style, {
|
|
273
273
|
maxHeight: `${Math.max(contentsAvailableHeight, 0)}px`
|
|
@@ -302,19 +302,38 @@ var script = {
|
|
|
302
302
|
Use 'a' or 'button' element instead or make sure to add 'role="button"' along with 'tabindex' otherwise.`, this.$el);
|
|
303
303
|
}
|
|
304
304
|
},
|
|
305
|
+
getArrowOffsets(actualPlacement) {
|
|
306
|
+
// Try to extract the base direction (top, bottom, left, right) from the placement
|
|
307
|
+
const direction = actualPlacement === null || actualPlacement === void 0 ? void 0 : actualPlacement.split('-')[0];
|
|
308
|
+
const offsetConfigs = {
|
|
309
|
+
top: {
|
|
310
|
+
staticSide: 'bottom',
|
|
311
|
+
rotation: '225deg'
|
|
312
|
+
},
|
|
313
|
+
bottom: {
|
|
314
|
+
staticSide: 'top',
|
|
315
|
+
rotation: '45deg'
|
|
316
|
+
},
|
|
317
|
+
left: {
|
|
318
|
+
staticSide: 'right',
|
|
319
|
+
rotation: '135deg'
|
|
320
|
+
},
|
|
321
|
+
right: {
|
|
322
|
+
staticSide: 'left',
|
|
323
|
+
rotation: '315deg'
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
return offsetConfigs[direction] || offsetConfigs.bottom;
|
|
327
|
+
},
|
|
305
328
|
async startFloating() {
|
|
306
329
|
this.calculateNonScrollableAreaHeight();
|
|
307
330
|
this.observer = new MutationObserver(this.calculateNonScrollableAreaHeight);
|
|
308
331
|
this.observer.observe(this.$refs.content, {
|
|
309
|
-
attributes: false,
|
|
310
332
|
childList: true,
|
|
311
333
|
subtree: true
|
|
312
334
|
});
|
|
313
335
|
this.stopAutoUpdate = autoUpdate(this.toggleElement, this.$refs.content, async () => {
|
|
314
|
-
const
|
|
315
|
-
x,
|
|
316
|
-
y
|
|
317
|
-
} = await computePosition(this.toggleElement, this.$refs.content, this.floatingUIConfig);
|
|
336
|
+
const result = await computePosition(this.toggleElement, this.$refs.content, this.floatingUIConfig);
|
|
318
337
|
|
|
319
338
|
/**
|
|
320
339
|
* Due to the asynchronous nature of computePosition, it's technically possible for the
|
|
@@ -322,10 +341,48 @@ var script = {
|
|
|
322
341
|
* early to prevent a TypeError.
|
|
323
342
|
*/
|
|
324
343
|
if (!this.$refs.content) return;
|
|
344
|
+
const {
|
|
345
|
+
x,
|
|
346
|
+
y,
|
|
347
|
+
middlewareData,
|
|
348
|
+
placement
|
|
349
|
+
} = result;
|
|
350
|
+
|
|
351
|
+
// Get offsets based on actual placement, not requested placement
|
|
352
|
+
const {
|
|
353
|
+
rotation,
|
|
354
|
+
staticSide
|
|
355
|
+
} = this.getArrowOffsets(placement);
|
|
356
|
+
|
|
357
|
+
// Assign dropdown window position
|
|
325
358
|
Object.assign(this.$refs.content.style, {
|
|
326
359
|
left: `${x}px`,
|
|
327
360
|
top: `${y}px`
|
|
328
361
|
});
|
|
362
|
+
|
|
363
|
+
// Assign arrow position
|
|
364
|
+
if (middlewareData && middlewareData.arrow) {
|
|
365
|
+
const {
|
|
366
|
+
x: arrowX,
|
|
367
|
+
y: arrowY
|
|
368
|
+
} = middlewareData.arrow;
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Clamp arrow X position to a minimum of 24px from the edge of the dropdown.
|
|
372
|
+
* This prevents wide toggles from pushing the arrow to the very edge of the dropdown.
|
|
373
|
+
*/
|
|
374
|
+
const toggleRect = this.toggleElement.getBoundingClientRect();
|
|
375
|
+
const contentRect = this.$refs.content.getBoundingClientRect();
|
|
376
|
+
const clampedArrowX = toggleRect.width > contentRect.width ? Math.min(Math.max(arrowX, ARROW_X_MINIMUM), contentRect.width - ARROW_X_MINIMUM) : arrowX;
|
|
377
|
+
Object.assign(this.$refs.dropdownArrow.style, {
|
|
378
|
+
left: arrowX != null ? `${clampedArrowX}px` : '',
|
|
379
|
+
top: arrowY != null ? `${arrowY}px` : '',
|
|
380
|
+
right: '',
|
|
381
|
+
bottom: '',
|
|
382
|
+
[staticSide]: '-4px',
|
|
383
|
+
transform: `rotate(${rotation})`
|
|
384
|
+
});
|
|
385
|
+
}
|
|
329
386
|
});
|
|
330
387
|
},
|
|
331
388
|
stopFloating() {
|
|
@@ -435,7 +492,7 @@ var script = {
|
|
|
435
492
|
const __vue_script__ = script;
|
|
436
493
|
|
|
437
494
|
/* template */
|
|
438
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{directives:[{name:"outside",rawName:"v-outside.click.focusin",value:(_vm.close),expression:"close",modifiers:{"click":true,"focusin":true}}],class:[_vm.$options.BASE_DROPDOWN_CLASS, { '!gl-block': _vm.block }]},[_c(_vm.toggleComponent,_vm._g(_vm._b({ref:"toggle",tag:"component",attrs:{"id":_vm.toggleId,"data-testid":"base-dropdown-toggle"},on:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"esc",27,$event.key,["Esc","Escape"])){ return null; }$event.stopPropagation();$event.preventDefault();return _vm.close.apply(null, arguments)}}},'component',_vm.toggleAttributes,false),_vm.toggleListeners),[_vm._t("toggle",function(){return [_c('span',{staticClass:"gl-new-dropdown-button-text",class:{ 'gl-sr-only': _vm.textSrOnly }},[_vm._v("\n "+_vm._s(_vm.toggleText)+"\n ")]),_vm._v(" "),(!_vm.noCaret)?_c('gl-icon',{staticClass:"gl-button-icon gl-new-dropdown-chevron",attrs:{"name":"chevron-down"}}):_vm._e()]})],2),_vm._v(" "),_c('div',{ref:"content",staticClass:"gl-new-dropdown-panel",class:_vm.panelClasses,attrs:{"id":_vm.baseDropdownId,"data-testid":"base-dropdown-menu"},on:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"esc",27,$event.key,["Esc","Escape"])){ return null; }$event.stopPropagation();$event.preventDefault();return _vm.closeAndFocus.apply(null, arguments)}}},[_c('div',{staticClass:"gl-new-dropdown-inner"},[_vm._t("default")],2)])],1)};
|
|
495
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{directives:[{name:"outside",rawName:"v-outside.click.focusin",value:(_vm.close),expression:"close",modifiers:{"click":true,"focusin":true}}],class:[_vm.$options.BASE_DROPDOWN_CLASS, { '!gl-block': _vm.block }]},[_c(_vm.toggleComponent,_vm._g(_vm._b({ref:"toggle",tag:"component",attrs:{"id":_vm.toggleId,"data-testid":"base-dropdown-toggle"},on:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"esc",27,$event.key,["Esc","Escape"])){ return null; }$event.stopPropagation();$event.preventDefault();return _vm.close.apply(null, arguments)}}},'component',_vm.toggleAttributes,false),_vm.toggleListeners),[_vm._t("toggle",function(){return [_c('span',{staticClass:"gl-new-dropdown-button-text",class:{ 'gl-sr-only': _vm.textSrOnly }},[_vm._v("\n "+_vm._s(_vm.toggleText)+"\n ")]),_vm._v(" "),(!_vm.noCaret)?_c('gl-icon',{staticClass:"gl-button-icon gl-new-dropdown-chevron",attrs:{"name":"chevron-down"}}):_vm._e()]})],2),_vm._v(" "),_c('div',{ref:"content",staticClass:"gl-new-dropdown-panel",class:_vm.panelClasses,attrs:{"id":_vm.baseDropdownId,"data-testid":"base-dropdown-menu"},on:{"keydown":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"esc",27,$event.key,["Esc","Escape"])){ return null; }$event.stopPropagation();$event.preventDefault();return _vm.closeAndFocus.apply(null, arguments)}}},[_c('div',{ref:"dropdownArrow",staticClass:"gl-new-dropdown-arrow"}),_vm._v(" "),_c('div',{staticClass:"gl-new-dropdown-inner"},[_vm._t("default")],2)])],1)};
|
|
439
496
|
var __vue_staticRenderFns__ = [];
|
|
440
497
|
|
|
441
498
|
/* style */
|
|
@@ -340,7 +340,7 @@ var script = {
|
|
|
340
340
|
const __vue_script__ = script;
|
|
341
341
|
|
|
342
342
|
/* template */
|
|
343
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-base-dropdown',{ref:"baseDropdown",staticClass:"gl-disclosure-dropdown",attrs:{"aria-labelledby":_vm.toggleAriaLabelledBy,"toggle-id":_vm.toggleId,"toggle-text":_vm.toggleText,"toggle-class":_vm.toggleClass,"text-sr-only":_vm.textSrOnly,"category":_vm.category,"variant":_vm.variant,"size":_vm.size,"icon":_vm.icon,"disabled":_vm.disabled,"loading":_vm.loading,"no-caret":_vm.noCaret,"placement":_vm.placement,"block":_vm.block,"offset":_vm.dropdownOffset,"fluid-width":_vm.fluidWidth,"positioning-strategy":_vm.positioningStrategy},on:_vm._d({},[_vm.$options.events.GL_DROPDOWN_SHOWN,_vm.onShow,_vm.$options.events.GL_DROPDOWN_HIDDEN,_vm.onHide,_vm.$options.events.GL_DROPDOWN_BEFORE_CLOSE,_vm.onBeforeClose,_vm.$options.events.GL_DROPDOWN_FOCUS_CONTENT,_vm.onKeydown]),scopedSlots:_vm._u([(_vm.hasCustomToggle)?{key:"toggle",fn:function(){return [_vm._t("toggle")]},proxy:true}:null],null,true)},[_vm._v(" "),_vm._t("header"),_vm._v(" "),_c(_vm.disclosureTag,{ref:"content",tag:"component",class:_vm.$options.GL_DROPDOWN_CONTENTS_CLASS,attrs:{"id":_vm.disclosureId,"aria-labelledby":_vm.listAriaLabelledBy || _vm.toggleId,"data-testid":"disclosure-content","tabindex":"-1"},on:{"keydown":_vm.onKeydown,"click":_vm.handleAutoClose}},[_vm._t("default",function(){return [_vm._l((_vm.items),function(item,index){return [(_vm.isItem(item))?[_c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"item":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([('list-item' in _vm.$scopedSlots)?{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":item})]},proxy:true}:null],null,true)})]:[_c('gl-disclosure-dropdown-group',{key:item.name,attrs:{"bordered":index !== 0,"group":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([(_vm.$scopedSlots['group-label'])?{key:"group-label",fn:function(){return [_vm._t("group-label",null,{"group":item})]},proxy:true}:null,(_vm.$scopedSlots['list-item'])?{key:"default",fn:function(){return _vm._l((item.items),function(groupItem){return _c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"item":groupItem},on:{"action":_vm.handleAction},scopedSlots:_vm._u([{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":groupItem})]},proxy:true}],null,true)})})},proxy:true}:null],null,true)})]]})]})],2),_vm._v(" "),_vm._t("footer")],2)};
|
|
343
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-base-dropdown',{ref:"baseDropdown",staticClass:"gl-disclosure-dropdown",attrs:{"aria-labelledby":_vm.toggleAriaLabelledBy,"arrow-element":_vm.$refs.disclosureArrow,"toggle-id":_vm.toggleId,"toggle-text":_vm.toggleText,"toggle-class":_vm.toggleClass,"text-sr-only":_vm.textSrOnly,"category":_vm.category,"variant":_vm.variant,"size":_vm.size,"icon":_vm.icon,"disabled":_vm.disabled,"loading":_vm.loading,"no-caret":_vm.noCaret,"placement":_vm.placement,"block":_vm.block,"offset":_vm.dropdownOffset,"fluid-width":_vm.fluidWidth,"positioning-strategy":_vm.positioningStrategy},on:_vm._d({},[_vm.$options.events.GL_DROPDOWN_SHOWN,_vm.onShow,_vm.$options.events.GL_DROPDOWN_HIDDEN,_vm.onHide,_vm.$options.events.GL_DROPDOWN_BEFORE_CLOSE,_vm.onBeforeClose,_vm.$options.events.GL_DROPDOWN_FOCUS_CONTENT,_vm.onKeydown]),scopedSlots:_vm._u([(_vm.hasCustomToggle)?{key:"toggle",fn:function(){return [_vm._t("toggle")]},proxy:true}:null],null,true)},[_vm._v(" "),_vm._t("header"),_vm._v(" "),_c(_vm.disclosureTag,{ref:"content",tag:"component",class:_vm.$options.GL_DROPDOWN_CONTENTS_CLASS,attrs:{"id":_vm.disclosureId,"aria-labelledby":_vm.listAriaLabelledBy || _vm.toggleId,"data-testid":"disclosure-content","tabindex":"-1"},on:{"keydown":_vm.onKeydown,"click":_vm.handleAutoClose}},[_vm._t("default",function(){return [_vm._l((_vm.items),function(item,index){return [(_vm.isItem(item))?[_c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"item":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([('list-item' in _vm.$scopedSlots)?{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":item})]},proxy:true}:null],null,true)})]:[_c('gl-disclosure-dropdown-group',{key:item.name,attrs:{"bordered":index !== 0,"group":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([(_vm.$scopedSlots['group-label'])?{key:"group-label",fn:function(){return [_vm._t("group-label",null,{"group":item})]},proxy:true}:null,(_vm.$scopedSlots['list-item'])?{key:"default",fn:function(){return _vm._l((item.items),function(groupItem){return _c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"item":groupItem},on:{"action":_vm.handleAction},scopedSlots:_vm._u([{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":groupItem})]},proxy:true}],null,true)})})},proxy:true}:null],null,true)})]]})]})],2),_vm._v(" "),_vm._t("footer")],2)};
|
|
344
344
|
var __vue_staticRenderFns__ = [];
|
|
345
345
|
|
|
346
346
|
/* style */
|