@gitlab/ui 123.3.1 → 123.5.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.
@@ -7,6 +7,7 @@ import { isEvent } from '../../../vendor/bootstrap-vue/src/utils/inspect';
7
7
  import GlIcon from '../icon/icon';
8
8
  import GlLoadingIcon from '../loading_icon/loading_icon';
9
9
  import { SPACE, ENTER } from '../new_dropdowns/constants';
10
+ import { glButtonConfig } from '../../../config';
10
11
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
11
12
 
12
13
  //
@@ -78,6 +79,14 @@ var script = {
78
79
  required: false,
79
80
  default: false
80
81
  },
82
+ /**
83
+ * Keep the button accessible when `loading` is `true`.
84
+ */
85
+ accessibleLoading: {
86
+ type: Boolean,
87
+ required: false,
88
+ default: () => glButtonConfig.accessibleLoadingButton
89
+ },
81
90
  /**
82
91
  * CSS classes to add to the button text.
83
92
  */
@@ -237,6 +246,9 @@ var script = {
237
246
  isButtonDisabled() {
238
247
  return this.disabled || this.loading;
239
248
  },
249
+ isButtonAriaDisabled() {
250
+ return this.accessibleLoading && this.isButton && this.loading;
251
+ },
240
252
  buttonClasses() {
241
253
  const classes = ['btn', 'gl-button', `btn-${this.variant}`, `btn-${this.buttonSize}`];
242
254
  if (this.category !== buttonCategoryOptions.primary) {
@@ -247,7 +259,7 @@ var script = {
247
259
  'button-ellipsis-horizontal': this.hasIconOnly && this.icon === 'ellipsis_h',
248
260
  selected: this.selected,
249
261
  'btn-block': this.displayBlock,
250
- disabled: this.disabled
262
+ disabled: this.disabled || this.isButtonAriaDisabled
251
263
  });
252
264
  if (this.label) {
253
265
  classes.push('btn', 'btn-label');
@@ -297,7 +309,12 @@ var script = {
297
309
  ...(this.isNonStandardTag ? {
298
310
  'aria-disabled': String(this.disabled)
299
311
  } : {}),
300
- tabindex: this.tabindex
312
+ tabindex: this.tabindex,
313
+ // We set the `aria-disabled` state for buttons while loading
314
+ ...(this.isButtonAriaDisabled ? {
315
+ 'aria-disabled': 'true',
316
+ disabled: null
317
+ } : {})
301
318
  };
302
319
  if (this.isLink) {
303
320
  return {
@@ -323,11 +340,13 @@ var script = {
323
340
  };
324
341
  },
325
342
  computedListeners() {
326
- return {
327
- click: this.onClick,
328
- keydown: this.onKeydown,
343
+ const listeners = {
329
344
  ...this.$listeners
330
345
  };
346
+ if (this.isButtonAriaDisabled) {
347
+ delete listeners.click;
348
+ }
349
+ return listeners;
331
350
  },
332
351
  componentIs() {
333
352
  if (this.label) {
@@ -366,8 +385,8 @@ var script = {
366
385
  }
367
386
  }
368
387
  },
369
- onClick(event) {
370
- if (this.disabled && isEvent(event)) {
388
+ maybeStopEvent(event) {
389
+ if (this.isButtonAriaDisabled && isEvent(event)) {
371
390
  stopEvent(event);
372
391
  }
373
392
  }
@@ -378,7 +397,7 @@ var script = {
378
397
  const __vue_script__ = script;
379
398
 
380
399
  /* template */
381
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c(_vm.componentIs,_vm._g(_vm._b({directives:[{name:"safe-link",rawName:"v-safe-link:[safeLinkConfig]",arg:_vm.safeLinkConfig}],tag:"component",class:_vm.buttonClasses},'component',_vm.computedPropsAndAttributes,false),_vm.computedListeners),[(_vm.loading)?_c('gl-loading-icon',{staticClass:"gl-button-icon gl-button-loading-indicator",attrs:{"inline":""}}):_vm._e(),_vm._v(" "),(_vm.hasIcon && !(_vm.hasIconOnly && _vm.loading))?_c('gl-icon',{staticClass:"gl-button-icon",attrs:{"name":_vm.icon}}):_vm._e(),_vm._v(" "),_vm._t("emoji"),_vm._v(" "),(!_vm.hasIconOnly)?_c('span',{staticClass:"gl-button-text",class:_vm.buttonTextClasses},[_vm._t("default"),_vm._v(" "),(_vm.hasCount)?_c('span',{staticClass:"gl-button-count"},[_vm._v("\n "+_vm._s(_vm.count)+"\n "),(_vm.countSrText)?_c('span',{staticClass:"gl-sr-only"},[_vm._v(_vm._s(_vm.countSrText))]):_vm._e()]):_vm._e()],2):_vm._e()],2)};
400
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c(_vm.componentIs,_vm._g(_vm._b({directives:[{name:"safe-link",rawName:"v-safe-link:[safeLinkConfig]",arg:_vm.safeLinkConfig}],tag:"component",class:_vm.buttonClasses,on:{"click":_vm.maybeStopEvent,"keydown":_vm.onKeydown}},'component',_vm.computedPropsAndAttributes,false),_vm.computedListeners),[(_vm.loading)?_c('gl-loading-icon',{staticClass:"gl-button-icon gl-button-loading-indicator",attrs:{"inline":""}}):_vm._e(),_vm._v(" "),(_vm.hasIcon && !(_vm.hasIconOnly && _vm.loading))?_c('gl-icon',{staticClass:"gl-button-icon",attrs:{"name":_vm.icon}}):_vm._e(),_vm._v(" "),_vm._t("emoji"),_vm._v(" "),(!_vm.hasIconOnly)?_c('span',{staticClass:"gl-button-text",class:_vm.buttonTextClasses},[_vm._t("default"),_vm._v(" "),(_vm.hasCount)?_c('span',{staticClass:"gl-button-count"},[_vm._v("\n "+_vm._s(_vm.count)+"\n "),(_vm.countSrText)?_c('span',{staticClass:"gl-sr-only"},[_vm._v(_vm._s(_vm.countSrText))]):_vm._e()]):_vm._e()],2):_vm._e()],2)};
382
401
  var __vue_staticRenderFns__ = [];
383
402
 
384
403
  /* style */
package/dist/config.js CHANGED
@@ -35,6 +35,7 @@ const i18n = translationKeys;
35
35
  const defaultConfig = {
36
36
  firstDayOfWeek: 0 // Defaults to 0 (Sunday)
37
37
  };
38
+ const glButtonConfig = {};
38
39
  let configured = false;
39
40
 
40
41
  /**
@@ -44,11 +45,14 @@ let configured = false;
44
45
  * @template TValue=string
45
46
  * @property {undefined | Object} translations Generic translations for component labels to fall back to.
46
47
  * @property {undefined | Number} firstDayOfWeek Configured first day of the week, from 0 (Sunday) to 6 (Saturday).
48
+ * @property {boolean} [accessibleLoadingButton] Temporary flag to enable accessible loading button.
49
+ *
47
50
  */
48
51
  const setConfigs = function () {
49
52
  let {
50
53
  translations,
51
- firstDayOfWeek
54
+ firstDayOfWeek,
55
+ accessibleLoadingButton = false
52
56
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
53
57
  if (configured) {
54
58
  if (process.env.NODE_ENV === 'development') {
@@ -83,6 +87,23 @@ const setConfigs = function () {
83
87
  }
84
88
  Object.assign(i18n, translations);
85
89
  }
90
+
91
+ // Temporary flag to enable the accessible loading button feature.
92
+ // This flag allows the feature to be opt-in during the rollout phase,
93
+ // giving us the flexibility to test and validate its impact on user experience.
94
+
95
+ // The global variable `accessibleLoadingButton` is set to a boolean value
96
+ // to indicate whether the button should be disabled while loading.
97
+
98
+ // Future Plan:
99
+ // Once the accessible loading button feature is validated and stable,
100
+ // we will remove this temporary flag and make the feature the default behavior.
101
+ // At that point, there will be no need for opt-in or opt-out mechanisms for this feature.
102
+ if (typeof accessibleLoadingButton === 'boolean') {
103
+ Object.assign(glButtonConfig, {
104
+ accessibleLoadingButton
105
+ });
106
+ }
86
107
  };
87
108
 
88
- export { setConfigs as default, defaultConfig, i18n };
109
+ export { setConfigs as default, defaultConfig, glButtonConfig, i18n };