@gitlab/ui 122.9.0 → 122.10.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/dist/components/base/banner/banner.js +12 -2
- package/dist/components/base/token_selector/token_container.js +1 -6
- package/dist/components/base/token_selector/token_selector.js +28 -5
- package/dist/components/base/token_selector/token_selector_dropdown.js +1 -1
- package/dist/utils/unique_id.js +18 -0
- package/package.json +5 -5
- package/src/components/base/banner/banner.vue +13 -2
- package/src/components/base/token_selector/token_container.vue +1 -11
- package/src/components/base/token_selector/token_selector.vue +33 -4
- package/src/components/base/token_selector/token_selector_dropdown.vue +4 -2
- package/src/utils/unique_id.js +17 -0
|
@@ -3,6 +3,7 @@ import { translate } from '../../../utils/i18n';
|
|
|
3
3
|
import CloseButton from '../../shared_components/close_button/close_button';
|
|
4
4
|
import GlButton from '../button/button';
|
|
5
5
|
import GlCard from '../card/card';
|
|
6
|
+
import GlIllustration from '../illustration/illustration';
|
|
6
7
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
7
8
|
|
|
8
9
|
var script = {
|
|
@@ -10,7 +11,8 @@ var script = {
|
|
|
10
11
|
components: {
|
|
11
12
|
CloseButton,
|
|
12
13
|
GlButton,
|
|
13
|
-
GlCard
|
|
14
|
+
GlCard,
|
|
15
|
+
GlIllustration
|
|
14
16
|
},
|
|
15
17
|
props: {
|
|
16
18
|
/**
|
|
@@ -43,6 +45,14 @@ var script = {
|
|
|
43
45
|
required: false,
|
|
44
46
|
default: null
|
|
45
47
|
},
|
|
48
|
+
/**
|
|
49
|
+
* The illustration's name.
|
|
50
|
+
*/
|
|
51
|
+
illustrationName: {
|
|
52
|
+
type: String,
|
|
53
|
+
required: false,
|
|
54
|
+
default: null
|
|
55
|
+
},
|
|
46
56
|
/**
|
|
47
57
|
* The illustration's URL.
|
|
48
58
|
*/
|
|
@@ -104,7 +114,7 @@ const __vue_script__ = script;
|
|
|
104
114
|
/* template */
|
|
105
115
|
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-card',{staticClass:"gl-banner gl-py-6 gl-pl-6 gl-pr-8",class:{
|
|
106
116
|
'gl-banner-introduction': _vm.isIntroducing,
|
|
107
|
-
},attrs:{"body-class":"gl-flex !gl-p-0"}},[(_vm.svgPath)?_c('div',{staticClass:"gl-banner-illustration"},[_c('img',{attrs:{"src":_vm.svgPath,"alt":""}})]):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-banner-content"},[_c('h2',{staticClass:"gl-banner-title"},[_vm._v(_vm._s(_vm.title))]),_vm._v(" "),_vm._t("default"),_vm._v(" "),_c('gl-button',_vm._b({attrs:{"variant":"confirm","category":"primary","data-testid":"gl-banner-primary-button","href":_vm.buttonLink},on:{"click":_vm.primaryButtonClicked}},'gl-button',_vm.buttonAttributes,false),[_vm._v(_vm._s(_vm.buttonText))]),_vm._v(" "),_vm._t("actions")],2),_vm._v(" "),_c('close-button',{staticClass:"gl-banner-close",attrs:{"label":_vm.dismissLabel},on:{"click":_vm.handleClose}})],1)};
|
|
117
|
+
},attrs:{"body-class":"gl-flex !gl-p-0"}},[(_vm.svgPath || _vm.illustrationName)?_c('div',{staticClass:"gl-banner-illustration"},[(_vm.illustrationName)?_c('gl-illustration',{attrs:{"name":_vm.illustrationName}}):(_vm.svgPath)?_c('img',{attrs:{"src":_vm.svgPath,"alt":""}}):_vm._e()],1):_vm._e(),_vm._v(" "),_c('div',{staticClass:"gl-banner-content"},[_c('h2',{staticClass:"gl-banner-title"},[_vm._v(_vm._s(_vm.title))]),_vm._v(" "),_vm._t("default"),_vm._v(" "),_c('gl-button',_vm._b({attrs:{"variant":"confirm","category":"primary","data-testid":"gl-banner-primary-button","href":_vm.buttonLink},on:{"click":_vm.primaryButtonClicked}},'gl-button',_vm.buttonAttributes,false),[_vm._v(_vm._s(_vm.buttonText))]),_vm._v(" "),_vm._t("actions")],2),_vm._v(" "),_c('close-button',{staticClass:"gl-banner-close",attrs:{"label":_vm.dismissLabel},on:{"click":_vm.handleClose}})],1)};
|
|
108
118
|
var __vue_staticRenderFns__ = [];
|
|
109
119
|
|
|
110
120
|
/* style */
|
|
@@ -16,11 +16,6 @@ var script = {
|
|
|
16
16
|
validator: tokensValidator,
|
|
17
17
|
required: true
|
|
18
18
|
},
|
|
19
|
-
state: {
|
|
20
|
-
type: Boolean,
|
|
21
|
-
required: false,
|
|
22
|
-
default: null
|
|
23
|
-
},
|
|
24
19
|
registerFocusOnToken: {
|
|
25
20
|
type: Function,
|
|
26
21
|
required: true
|
|
@@ -130,7 +125,7 @@ var script = {
|
|
|
130
125
|
const __vue_script__ = script;
|
|
131
126
|
|
|
132
127
|
/* template */
|
|
133
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-flex gl-w-full gl-flex-nowrap gl-items-start"},[_c('div',{staticClass:"gl-flex gl-grow gl-flex-wrap gl-items-start"},[_c('div',{ref:"tokenContainer",staticClass:"-gl-mx-1 -gl-my-1 gl-flex gl-w-auto gl-list-none gl-flex-wrap gl-items-center gl-p-0",
|
|
128
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-flex gl-w-full gl-flex-nowrap gl-items-start"},[_c('div',{staticClass:"gl-flex gl-grow gl-flex-wrap gl-items-start"},[_c('div',{ref:"tokenContainer",staticClass:"-gl-mx-1 -gl-my-1 gl-flex gl-w-auto gl-list-none gl-flex-wrap gl-items-center gl-p-0",on:{"keydown":[function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"left",37,$event.key,["Left","ArrowLeft"])){ return null; }if('button' in $event && $event.button !== 0){ return null; }return _vm.handleLeftArrow.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"right",39,$event.key,["Right","ArrowRight"])){ return null; }if('button' in $event && $event.button !== 2){ return null; }return _vm.handleRightArrow.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"home",undefined,$event.key,undefined)){ return null; }return _vm.handleHome.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"end",undefined,$event.key,undefined)){ return null; }return _vm.handleEnd.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"delete",[8,46],$event.key,["Backspace","Delete","Del"])){ return null; }return _vm.handleDelete.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"esc",27,$event.key,["Esc","Escape"])){ return null; }return _vm.handleEscape.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"tab",9,$event.key,"Tab")){ return null; }if($event.ctrlKey||$event.shiftKey||$event.altKey||$event.metaKey){ return null; }$event.preventDefault();return _vm.handleTab.apply(null, arguments)}]}},_vm._l((_vm.tokens),function(token,index){return _c('div',{key:token.id,ref:"tokens",refInFor:true,staticClass:"gl-token-selector-token-container gl-px-1 gl-py-2 gl-outline-none",attrs:{"data-token-id":token.id,"data-testid":"gl-token-selector-tokens","tabindex":"-1"},on:{"focus":function($event){_vm.bindFocusEvent ? _vm.handleTokenFocus(index) : null;}}},[_c('gl-token',{staticClass:"gl-cursor-default",class:token.class,style:(token.style),attrs:{"view-only":_vm.viewOnly},on:{"close":function($event){return _vm.handleClose(token)}}},[_vm._t("token-content",function(){return [_c('span',[_vm._v("\n "+_vm._s(token.name)+"\n ")])]},{"token":token})],2)],1)}),0),_vm._v(" "),_vm._t("text-input")],2),_vm._v(" "),(_vm.showClearAllButton)?_c('div',{staticClass:"gl-ml-3 gl-p-1"},[_c('gl-button',{attrs:{"size":"small","aria-label":"Clear all","icon":"clear","category":"tertiary","data-testid":"clear-all-button"},on:{"click":function($event){$event.stopPropagation();return _vm.$emit('clear-all')}}})],1):_vm._e()])};
|
|
134
129
|
var __vue_staticRenderFns__ = [];
|
|
135
130
|
|
|
136
131
|
/* style */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { GlUniqueId } from '../../../utils/unique_id';
|
|
2
2
|
import { tokensValidator } from './helpers';
|
|
3
3
|
import GlTokenContainer from './token_container';
|
|
4
4
|
import GlTokenSelectorDropdown from './token_selector_dropdown';
|
|
@@ -6,7 +6,7 @@ import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
|
6
6
|
|
|
7
7
|
var script = {
|
|
8
8
|
name: 'GlTokenSelector',
|
|
9
|
-
componentId:
|
|
9
|
+
componentId: `token-selector-${GlUniqueId()}`,
|
|
10
10
|
components: {
|
|
11
11
|
GlTokenContainer,
|
|
12
12
|
GlTokenSelectorDropdown
|
|
@@ -75,7 +75,7 @@ var script = {
|
|
|
75
75
|
default: ''
|
|
76
76
|
},
|
|
77
77
|
/**
|
|
78
|
-
* The autocomplete attribute value for the underlying `input` element
|
|
78
|
+
* The HTML5 autocomplete attribute value for the underlying `input` element.
|
|
79
79
|
*/
|
|
80
80
|
autocomplete: {
|
|
81
81
|
type: String,
|
|
@@ -83,7 +83,21 @@ var script = {
|
|
|
83
83
|
default: 'off'
|
|
84
84
|
},
|
|
85
85
|
/**
|
|
86
|
-
* The `aria-
|
|
86
|
+
* The `aria-label` attribute value for the underlying `input` element.
|
|
87
|
+
* Input must have an aria-label or aria-labelledby prop or it will be inaccessible.
|
|
88
|
+
*
|
|
89
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-label
|
|
90
|
+
*/
|
|
91
|
+
ariaLabel: {
|
|
92
|
+
type: String,
|
|
93
|
+
required: false,
|
|
94
|
+
default: null
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* The `aria-labelledby` attribute value for the underlying `input` element.
|
|
98
|
+
* String must match the unique ID on a text element to create an accessible label.
|
|
99
|
+
*
|
|
100
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-labelledby
|
|
87
101
|
*/
|
|
88
102
|
ariaLabelledby: {
|
|
89
103
|
type: String,
|
|
@@ -364,6 +378,15 @@ var script = {
|
|
|
364
378
|
clearAll() {
|
|
365
379
|
this.$emit('input', []);
|
|
366
380
|
this.focusTextInput();
|
|
381
|
+
},
|
|
382
|
+
handleAriaInvalid() {
|
|
383
|
+
const {
|
|
384
|
+
state
|
|
385
|
+
} = this;
|
|
386
|
+
return state === false ? 'true' : null;
|
|
387
|
+
},
|
|
388
|
+
handleAriaActiveDescendent(value) {
|
|
389
|
+
return value ? `${this.$options.componentId}-dropdown-item-${value.id}` : null;
|
|
367
390
|
}
|
|
368
391
|
}
|
|
369
392
|
};
|
|
@@ -380,7 +403,7 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
|
|
|
380
403
|
_vm.containerClass,
|
|
381
404
|
_vm.stateClass ],on:{"click":_vm.handleContainerClick}},[(_vm.showEmptyPlaceholder)?_vm._t("empty-placeholder"):_vm._e(),_vm._v(" "),_c('gl-token-container',{attrs:{"tokens":_vm.selectedTokens,"state":_vm.state,"register-focus-on-token":_vm.registerFocusOnToken,"view-only":_vm.viewOnly,"show-clear-all-button":_vm.showClearAllButton},on:{"token-remove":_vm.removeToken,"cancel-focus":_vm.cancelTokenFocus,"clear-all":_vm.clearAll},scopedSlots:_vm._u([{key:"token-content",fn:function(ref){
|
|
382
405
|
var token = ref.token;
|
|
383
|
-
return [_vm._t("token-content",null,{"token":token})]}},{key:"text-input",fn:function(){return [_c('input',_vm._b({ref:"textInput",staticClass:"gl-token-selector-input gl-h-auto gl-w-4/10 gl-grow gl-border-none gl-bg-transparent gl-px-1 gl-font-regular gl-text-base gl-leading-normal gl-text-default gl-outline-none",attrs:{"type":"text","autocomplete":_vm.autocomplete,"aria-labelledby":_vm.ariaLabelledby,"placeholder":_vm.placeholder,"disabled":_vm.viewOnly},domProps:{"value":_vm.inputText},on:{"input":function($event){_vm.inputText = $event.target.value;},"focus":_vm.handleFocus,"blur":_vm.handleBlur,"keydown":[function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"enter",13,$event.key,"Enter")){ return null; }return _vm.handleEnter.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"esc",27,$event.key,["Esc","Escape"])){ return null; }return _vm.handleEscape.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"delete",[8,46],$event.key,["Backspace","Delete","Del"])){ return null; }return _vm.handleBackspace.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"up",38,$event.key,["Up","ArrowUp"])){ return null; }$event.preventDefault();return _vm.dropdownEventHandlers.handleUpArrow.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"down",40,$event.key,["Down","ArrowDown"])){ return null; }$event.preventDefault();return _vm.dropdownEventHandlers.handleDownArrow.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"home",undefined,$event.key,undefined)){ return null; }return _vm.dropdownEventHandlers.handleHomeKey.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"end",undefined,$event.key,undefined)){ return null; }return _vm.dropdownEventHandlers.handleEndKey.apply(null, arguments)},function($event){$event.stopPropagation();return _vm.$emit('keydown', $event)}],"click":_vm.handleInputClick}},'input',_vm.textInputAttrs,false))]},proxy:true}],null,true)})],2),_vm._v(" "),_c('gl-token-selector-dropdown',{attrs:{"menu-class":_vm.menuClass,"show":_vm.dropdownIsOpen,"loading":_vm.loading,"dropdown-items":_vm.filteredDropdownItems,"selected-tokens":_vm.selectedTokens,"input-text":_vm.inputText,"user-defined-token-can-be-added":_vm.userDefinedTokenCanBeAdded,"component-id":_vm.$options.componentId,"register-dropdown-event-handlers":_vm.registerDropdownEventHandlers,"register-reset-focused-dropdown-item":_vm.registerResetFocusedDropdownItem},on:{"dropdown-item-click":_vm.addToken,"show":_vm.openDropdown},scopedSlots:_vm._u([{key:"loading-content",fn:function(){return [_vm._t("loading-content")]},proxy:true},{key:"user-defined-token-content",fn:function(){return [_vm._t("user-defined-token-content",null,{"inputText":_vm.inputText})]},proxy:true},{key:"no-results-content",fn:function(){return [_vm._t("no-results-content")]},proxy:true},{key:"dropdown-item-content",fn:function(ref){
|
|
406
|
+
return [_vm._t("token-content",null,{"token":token})]}},{key:"text-input",fn:function(){return [_c('input',_vm._b({ref:"textInput",staticClass:"gl-token-selector-input gl-h-auto gl-w-4/10 gl-grow gl-border-none gl-bg-transparent gl-px-1 gl-font-regular gl-text-base gl-leading-normal gl-text-default gl-outline-none",attrs:{"type":"text","aria-activedescendant":_vm.handleAriaActiveDescendent(_vm.focusedDropdownItem),"autocomplete":_vm.autocomplete,"aria-controls":_vm.$options.componentId,"aria-expanded":_vm.dropdownIsOpen.toString(),"aria-invalid":_vm.handleAriaInvalid(),"aria-label":_vm.ariaLabelledby ? null : _vm.ariaLabel,"aria-labelledby":_vm.ariaLabelledby,"placeholder":_vm.placeholder,"disabled":_vm.viewOnly,"aria-autocomplete":"list","role":"combobox"},domProps:{"value":_vm.inputText},on:{"input":function($event){_vm.inputText = $event.target.value;},"focus":_vm.handleFocus,"blur":_vm.handleBlur,"keydown":[function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"enter",13,$event.key,"Enter")){ return null; }return _vm.handleEnter.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"esc",27,$event.key,["Esc","Escape"])){ return null; }return _vm.handleEscape.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"delete",[8,46],$event.key,["Backspace","Delete","Del"])){ return null; }return _vm.handleBackspace.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"up",38,$event.key,["Up","ArrowUp"])){ return null; }$event.preventDefault();return _vm.dropdownEventHandlers.handleUpArrow.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"down",40,$event.key,["Down","ArrowDown"])){ return null; }$event.preventDefault();return _vm.dropdownEventHandlers.handleDownArrow.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"home",undefined,$event.key,undefined)){ return null; }return _vm.dropdownEventHandlers.handleHomeKey.apply(null, arguments)},function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,"end",undefined,$event.key,undefined)){ return null; }return _vm.dropdownEventHandlers.handleEndKey.apply(null, arguments)},function($event){$event.stopPropagation();return _vm.$emit('keydown', $event)}],"click":_vm.handleInputClick}},'input',_vm.textInputAttrs,false))]},proxy:true}],null,true)})],2),_vm._v(" "),_c('gl-token-selector-dropdown',{attrs:{"menu-class":_vm.menuClass,"show":_vm.dropdownIsOpen,"loading":_vm.loading,"dropdown-items":_vm.filteredDropdownItems,"selected-tokens":_vm.selectedTokens,"input-text":_vm.inputText,"user-defined-token-can-be-added":_vm.userDefinedTokenCanBeAdded,"component-id":_vm.$options.componentId,"register-dropdown-event-handlers":_vm.registerDropdownEventHandlers,"register-reset-focused-dropdown-item":_vm.registerResetFocusedDropdownItem},on:{"dropdown-item-click":_vm.addToken,"input":_vm.handleAriaActiveDescendent,"show":_vm.openDropdown},scopedSlots:_vm._u([{key:"loading-content",fn:function(){return [_vm._t("loading-content")]},proxy:true},{key:"user-defined-token-content",fn:function(){return [_vm._t("user-defined-token-content",null,{"inputText":_vm.inputText})]},proxy:true},{key:"no-results-content",fn:function(){return [_vm._t("no-results-content")]},proxy:true},{key:"dropdown-item-content",fn:function(ref){
|
|
384
407
|
var dropdownItem = ref.dropdownItem;
|
|
385
408
|
return [_vm._t("dropdown-item-content",null,{"dropdownItem":dropdownItem})]}},{key:"dropdown-footer",fn:function(){return [_vm._t("dropdown-footer")]},proxy:true}],null,true),model:{value:(_vm.focusedDropdownItem),callback:function ($$v) {_vm.focusedDropdownItem=$$v;},expression:"focusedDropdownItem"}})],1)};
|
|
386
409
|
var __vue_staticRenderFns__ = [];
|
|
@@ -188,7 +188,7 @@ var script = {
|
|
|
188
188
|
const __vue_script__ = script;
|
|
189
189
|
|
|
190
190
|
/* template */
|
|
191
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"dropdown b-dropdown gl-dropdown gl-relative",class:{ show: _vm.show }},[_c('ul',{ref:"dropdownMenu",staticClass:"dropdown-menu gl-absolute",class:[{ show: _vm.show }, _vm.menuClass],attrs:{"
|
|
191
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"dropdown b-dropdown gl-dropdown gl-relative",class:{ show: _vm.show }},[_c('ul',{ref:"dropdownMenu",staticClass:"dropdown-menu gl-absolute",class:[{ show: _vm.show }, _vm.menuClass],attrs:{"id":_vm.componentId,"role":"listbox"}},[(_vm.loading)?_c('gl-dropdown-item',{attrs:{"disabled":""}},[_vm._t("loading-content",function(){return [_vm._v("Searching...")]})],2):_vm._e(),_vm._v(" "),_vm._l((_vm.dropdownItems),function(dropdownItem){return _c('gl-dropdown-item',{key:dropdownItem.id,ref:"dropdownItems",refInFor:true,attrs:{"id":_vm.dropdownItemIdAttribute(dropdownItem),"data-dropdown-item-id":dropdownItem.id,"active":_vm.dropdownItemIsFocused(dropdownItem),"aria-selected":_vm.dropdownItemIsFocused(dropdownItem).toString(),"active-class":"is-focused","role":"option","tabindex":"-1"},on:{"click":function($event){return _vm.handleDropdownItemClick(dropdownItem)}}},[_c('div',{staticClass:"-gl-mx-4 -gl-my-3 gl-px-4 gl-py-3",on:{"mousedown":function($event){return _vm.handleMousedown(dropdownItem)}}},[_vm._t("dropdown-item-content",function(){return [_vm._v("\n "+_vm._s(dropdownItem.name)+"\n ")]},{"dropdownItem":dropdownItem})],2)])}),_vm._v(" "),(_vm.userDefinedTokenCanBeAdded)?_c('gl-dropdown-item',{ref:_vm.userDefinedToken.id,attrs:{"id":_vm.dropdownItemIdAttribute(_vm.userDefinedToken),"data-dropdown-item-id":_vm.userDefinedToken.id,"active":_vm.dropdownItemIsFocused(_vm.userDefinedToken),"active-class":"is-focused","tabindex":"-1"},on:{"click":function($event){return _vm.handleDropdownItemClick(_vm.userDefinedToken)}}},[_c('div',{staticClass:"-gl-mx-4 -gl-my-3 gl-px-4 gl-py-3",on:{"mousedown":function($event){return _vm.handleMousedown(_vm.userDefinedToken)}}},[_vm._t("user-defined-token-content",function(){return [_vm._v("\n Add \""+_vm._s(_vm.inputText)+"\"\n ")]},{"inputText":_vm.inputText})],2)]):(!_vm.dropdownItems.length)?_c('gl-dropdown-item',{attrs:{"disabled":""}},[_vm._t("no-results-content",function(){return [_vm._v("No matches found")]})],2):_vm._e(),_vm._v(" "),_vm._t("dropdown-footer")],2)])};
|
|
192
192
|
var __vue_staticRenderFns__ = [];
|
|
193
193
|
|
|
194
194
|
/* style */
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function uses browser native crypto to return a sixteen
|
|
3
|
+
* character base16 encoded string. It is often used to
|
|
4
|
+
* generate collision-resistant IDs for aria markup such
|
|
5
|
+
* as aria-activedescendant and aria-controls.
|
|
6
|
+
*
|
|
7
|
+
* @returns String
|
|
8
|
+
*/
|
|
9
|
+
const GlUniqueId = () => {
|
|
10
|
+
if (typeof window !== 'undefined' && window.crypto) {
|
|
11
|
+
const arr32 = new Uint32Array(2);
|
|
12
|
+
window.crypto.getRandomValues(arr32);
|
|
13
|
+
return Array.from(arr32, id => id.toString(16)).join('');
|
|
14
|
+
}
|
|
15
|
+
throw new Error('Cannot generate a unique ID');
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { GlUniqueId };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "122.
|
|
3
|
+
"version": "122.10.0",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"@babel/preset-react": "^7.27.1",
|
|
104
104
|
"@cypress/grep": "^4.1.1",
|
|
105
105
|
"@gitlab/fonts": "^1.3.1",
|
|
106
|
-
"@gitlab/svgs": "3.
|
|
106
|
+
"@gitlab/svgs": "3.147.0",
|
|
107
107
|
"@jest/test-sequencer": "30.1.3",
|
|
108
108
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
109
109
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
"cypress-real-events": "^1.15.0",
|
|
140
140
|
"dompurify": "^3.1.2",
|
|
141
141
|
"emoji-regex": "^10.5.0",
|
|
142
|
-
"esbuild": "^0.25.
|
|
142
|
+
"esbuild": "^0.25.10",
|
|
143
143
|
"gitlab-api-async-iterator": "^1.3.1",
|
|
144
144
|
"glob": "11.0.3",
|
|
145
145
|
"globby": "^14.1.0",
|
|
@@ -165,10 +165,10 @@
|
|
|
165
165
|
"rollup-plugin-string": "^3.0.0",
|
|
166
166
|
"rollup-plugin-svg": "^2.0.0",
|
|
167
167
|
"rollup-plugin-vue": "^5.1.9",
|
|
168
|
-
"sass": "^1.
|
|
168
|
+
"sass": "^1.93.0",
|
|
169
169
|
"sass-loader": "^10.5.2",
|
|
170
170
|
"sass-true": "^9",
|
|
171
|
-
"start-server-and-test": "^2.1.
|
|
171
|
+
"start-server-and-test": "^2.1.2",
|
|
172
172
|
"storybook": "^7.6.20",
|
|
173
173
|
"storybook-dark-mode": "4.0.2",
|
|
174
174
|
"style-dictionary": "^5.0.4",
|
|
@@ -4,6 +4,7 @@ import { translate } from '../../../utils/i18n';
|
|
|
4
4
|
import CloseButton from '../../shared_components/close_button/close_button.vue';
|
|
5
5
|
import GlButton from '../button/button.vue';
|
|
6
6
|
import GlCard from '../card/card.vue';
|
|
7
|
+
import GlIllustration from '../illustration/illustration.vue';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
9
10
|
name: 'GlBanner',
|
|
@@ -11,6 +12,7 @@ export default {
|
|
|
11
12
|
CloseButton,
|
|
12
13
|
GlButton,
|
|
13
14
|
GlCard,
|
|
15
|
+
GlIllustration,
|
|
14
16
|
},
|
|
15
17
|
props: {
|
|
16
18
|
/**
|
|
@@ -43,6 +45,14 @@ export default {
|
|
|
43
45
|
required: false,
|
|
44
46
|
default: null,
|
|
45
47
|
},
|
|
48
|
+
/**
|
|
49
|
+
* The illustration's name.
|
|
50
|
+
*/
|
|
51
|
+
illustrationName: {
|
|
52
|
+
type: String,
|
|
53
|
+
required: false,
|
|
54
|
+
default: null,
|
|
55
|
+
},
|
|
46
56
|
/**
|
|
47
57
|
* The illustration's URL.
|
|
48
58
|
*/
|
|
@@ -107,8 +117,9 @@ export default {
|
|
|
107
117
|
}"
|
|
108
118
|
body-class="gl-flex !gl-p-0"
|
|
109
119
|
>
|
|
110
|
-
<div v-if="svgPath" class="gl-banner-illustration">
|
|
111
|
-
<
|
|
120
|
+
<div v-if="svgPath || illustrationName" class="gl-banner-illustration">
|
|
121
|
+
<gl-illustration v-if="illustrationName" :name="illustrationName" />
|
|
122
|
+
<img v-else-if="svgPath" :src="svgPath" alt="" />
|
|
112
123
|
</div>
|
|
113
124
|
<div class="gl-banner-content">
|
|
114
125
|
<h2 class="gl-banner-title">{{ title }}</h2>
|
|
@@ -13,11 +13,6 @@ export default {
|
|
|
13
13
|
validator: tokensValidator,
|
|
14
14
|
required: true,
|
|
15
15
|
},
|
|
16
|
-
state: {
|
|
17
|
-
type: Boolean,
|
|
18
|
-
required: false,
|
|
19
|
-
default: null,
|
|
20
|
-
},
|
|
21
16
|
registerFocusOnToken: {
|
|
22
17
|
type: Function,
|
|
23
18
|
required: true,
|
|
@@ -133,11 +128,6 @@ export default {
|
|
|
133
128
|
<div
|
|
134
129
|
ref="tokenContainer"
|
|
135
130
|
class="-gl-mx-1 -gl-my-1 gl-flex gl-w-auto gl-list-none gl-flex-wrap gl-items-center gl-p-0"
|
|
136
|
-
role="listbox"
|
|
137
|
-
aria-multiselectable="false"
|
|
138
|
-
aria-orientation="horizontal"
|
|
139
|
-
:aria-invalid="state === false && 'true'"
|
|
140
|
-
aria-label="token list"
|
|
141
131
|
@keydown.left="handleLeftArrow"
|
|
142
132
|
@keydown.right="handleRightArrow"
|
|
143
133
|
@keydown.home="handleHome"
|
|
@@ -152,7 +142,7 @@ export default {
|
|
|
152
142
|
:key="token.id"
|
|
153
143
|
:data-token-id="token.id"
|
|
154
144
|
class="gl-token-selector-token-container gl-px-1 gl-py-2 gl-outline-none"
|
|
155
|
-
|
|
145
|
+
data-testid="gl-token-selector-tokens"
|
|
156
146
|
tabindex="-1"
|
|
157
147
|
@focus="bindFocusEvent ? handleTokenFocus(index) : null"
|
|
158
148
|
>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import
|
|
2
|
+
import { GlUniqueId } from '../../../utils/unique_id';
|
|
3
3
|
import { tokensValidator } from './helpers';
|
|
4
4
|
import GlTokenContainer from './token_container.vue';
|
|
5
5
|
import GlTokenSelectorDropdown from './token_selector_dropdown.vue';
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
8
|
name: 'GlTokenSelector',
|
|
9
|
-
componentId:
|
|
9
|
+
componentId: `token-selector-${GlUniqueId()}`,
|
|
10
10
|
components: {
|
|
11
11
|
GlTokenContainer,
|
|
12
12
|
GlTokenSelectorDropdown,
|
|
@@ -75,7 +75,7 @@ export default {
|
|
|
75
75
|
default: '',
|
|
76
76
|
},
|
|
77
77
|
/**
|
|
78
|
-
* The autocomplete attribute value for the underlying `input` element
|
|
78
|
+
* The HTML5 autocomplete attribute value for the underlying `input` element.
|
|
79
79
|
*/
|
|
80
80
|
autocomplete: {
|
|
81
81
|
type: String,
|
|
@@ -83,7 +83,21 @@ export default {
|
|
|
83
83
|
default: 'off',
|
|
84
84
|
},
|
|
85
85
|
/**
|
|
86
|
-
* The `aria-
|
|
86
|
+
* The `aria-label` attribute value for the underlying `input` element.
|
|
87
|
+
* Input must have an aria-label or aria-labelledby prop or it will be inaccessible.
|
|
88
|
+
*
|
|
89
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-label
|
|
90
|
+
*/
|
|
91
|
+
ariaLabel: {
|
|
92
|
+
type: String,
|
|
93
|
+
required: false,
|
|
94
|
+
default: null,
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* The `aria-labelledby` attribute value for the underlying `input` element.
|
|
98
|
+
* String must match the unique ID on a text element to create an accessible label.
|
|
99
|
+
*
|
|
100
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-labelledby
|
|
87
101
|
*/
|
|
88
102
|
ariaLabelledby: {
|
|
89
103
|
type: String,
|
|
@@ -382,6 +396,13 @@ export default {
|
|
|
382
396
|
this.$emit('input', []);
|
|
383
397
|
this.focusTextInput();
|
|
384
398
|
},
|
|
399
|
+
handleAriaInvalid() {
|
|
400
|
+
const { state } = this;
|
|
401
|
+
return state === false ? 'true' : null;
|
|
402
|
+
},
|
|
403
|
+
handleAriaActiveDescendent(value) {
|
|
404
|
+
return value ? `${this.$options.componentId}-dropdown-item-${value.id}` : null;
|
|
405
|
+
},
|
|
385
406
|
},
|
|
386
407
|
};
|
|
387
408
|
</script>
|
|
@@ -428,10 +449,17 @@ export default {
|
|
|
428
449
|
type="text"
|
|
429
450
|
class="gl-token-selector-input gl-h-auto gl-w-4/10 gl-grow gl-border-none gl-bg-transparent gl-px-1 gl-font-regular gl-text-base gl-leading-normal gl-text-default gl-outline-none"
|
|
430
451
|
:value="inputText"
|
|
452
|
+
:aria-activedescendant="handleAriaActiveDescendent(focusedDropdownItem)"
|
|
431
453
|
:autocomplete="autocomplete"
|
|
454
|
+
:aria-controls="$options.componentId"
|
|
455
|
+
:aria-expanded="dropdownIsOpen.toString()"
|
|
456
|
+
:aria-invalid="handleAriaInvalid()"
|
|
457
|
+
:aria-label="ariaLabelledby ? null : ariaLabel"
|
|
432
458
|
:aria-labelledby="ariaLabelledby"
|
|
433
459
|
:placeholder="placeholder"
|
|
434
460
|
:disabled="viewOnly"
|
|
461
|
+
aria-autocomplete="list"
|
|
462
|
+
role="combobox"
|
|
435
463
|
v-bind="textInputAttrs"
|
|
436
464
|
@input="inputText = $event.target.value"
|
|
437
465
|
@focus="handleFocus"
|
|
@@ -462,6 +490,7 @@ export default {
|
|
|
462
490
|
:register-dropdown-event-handlers="registerDropdownEventHandlers"
|
|
463
491
|
:register-reset-focused-dropdown-item="registerResetFocusedDropdownItem"
|
|
464
492
|
@dropdown-item-click="addToken"
|
|
493
|
+
@input="handleAriaActiveDescendent"
|
|
465
494
|
@show="openDropdown"
|
|
466
495
|
>
|
|
467
496
|
<template #loading-content
|
|
@@ -199,10 +199,10 @@ export default {
|
|
|
199
199
|
<template>
|
|
200
200
|
<div class="dropdown b-dropdown gl-dropdown gl-relative" :class="{ show }">
|
|
201
201
|
<ul
|
|
202
|
+
:id="componentId"
|
|
202
203
|
ref="dropdownMenu"
|
|
203
|
-
role="
|
|
204
|
+
role="listbox"
|
|
204
205
|
class="dropdown-menu gl-absolute"
|
|
205
|
-
:aria-activedescendant="dropdownItemIdAttribute(focusedDropdownItem)"
|
|
206
206
|
:class="[{ show }, menuClass]"
|
|
207
207
|
>
|
|
208
208
|
<gl-dropdown-item v-if="loading" disabled>
|
|
@@ -216,7 +216,9 @@ export default {
|
|
|
216
216
|
:key="dropdownItem.id"
|
|
217
217
|
:data-dropdown-item-id="dropdownItem.id"
|
|
218
218
|
:active="dropdownItemIsFocused(dropdownItem)"
|
|
219
|
+
:aria-selected="dropdownItemIsFocused(dropdownItem).toString()"
|
|
219
220
|
active-class="is-focused"
|
|
221
|
+
role="option"
|
|
220
222
|
tabindex="-1"
|
|
221
223
|
@click="handleDropdownItemClick(dropdownItem)"
|
|
222
224
|
>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function uses browser native crypto to return a sixteen
|
|
3
|
+
* character base16 encoded string. It is often used to
|
|
4
|
+
* generate collision-resistant IDs for aria markup such
|
|
5
|
+
* as aria-activedescendant and aria-controls.
|
|
6
|
+
*
|
|
7
|
+
* @returns String
|
|
8
|
+
*/
|
|
9
|
+
export const GlUniqueId = () => {
|
|
10
|
+
if (typeof window !== 'undefined' && window.crypto) {
|
|
11
|
+
const arr32 = new Uint32Array(2);
|
|
12
|
+
window.crypto.getRandomValues(arr32);
|
|
13
|
+
return Array.from(arr32, (id) => id.toString(16)).join('');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
throw new Error('Cannot generate a unique ID');
|
|
17
|
+
};
|