@gitlab/ui 128.2.3 → 128.4.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.
@@ -1,6 +1,6 @@
1
1
  import { extend } from '../../vue';
2
2
  import { NAME_TOOLTIP } from '../../constants/components';
3
- import { EVENT_NAME_OPEN, EVENT_NAME_CLOSE, EVENT_NAME_DISABLE, EVENT_NAME_ENABLE, EVENT_NAME_SHOW, EVENT_NAME_SHOWN, EVENT_NAME_HIDE, EVENT_NAME_HIDDEN, EVENT_NAME_DISABLED, EVENT_NAME_ENABLED, MODEL_EVENT_NAME_PREFIX } from '../../constants/events';
3
+ import { EVENT_NAME_DISABLE, EVENT_NAME_ENABLE, EVENT_NAME_SHOW, EVENT_NAME_SHOWN, EVENT_NAME_HIDE, EVENT_NAME_HIDDEN, EVENT_NAME_DISABLED, EVENT_NAME_ENABLED, EVENT_NAME_OPEN, EVENT_NAME_CLOSE, MODEL_EVENT_NAME_PREFIX } from '../../constants/events';
4
4
  import { PROP_TYPE_OBJECT, PROP_TYPE_STRING, PROP_TYPE_NUMBER_STRING, PROP_TYPE_NUMBER_OBJECT_STRING, PROP_TYPE_BOOLEAN, PROP_TYPE_ARRAY_STRING, PROP_TYPE_FUNCTION } from '../../constants/props';
5
5
  import { HTMLElement, SVGElement } from '../../constants/safe-types';
6
6
  import { useParentMixin } from '../../mixins/use-parent';
@@ -103,9 +103,9 @@ const BTooltip = /*#__PURE__*/extend({
103
103
  },
104
104
  [MODEL_PROP_NAME_ENABLED](newValue) {
105
105
  if (newValue) {
106
- this.doDisable();
106
+ this[EVENT_NAME_DISABLE]();
107
107
  } else {
108
- this.doEnable();
108
+ this[EVENT_NAME_ENABLE]();
109
109
  }
110
110
  },
111
111
  localShow(newValue) {
@@ -134,11 +134,6 @@ const BTooltip = /*#__PURE__*/extend({
134
134
  this.$nextTick(this.updateContent);
135
135
  },
136
136
  beforeDestroy() {
137
- // Shutdown our local event listeners
138
- this.$off(EVENT_NAME_OPEN, this.doOpen);
139
- this.$off(EVENT_NAME_CLOSE, this.doClose);
140
- this.$off(EVENT_NAME_DISABLE, this.doDisable);
141
- this.$off(EVENT_NAME_ENABLE, this.doEnable);
142
137
  // Destroy the tip instance
143
138
  if (this.$_toolpop) {
144
139
  this.$_toolpop.$destroy();
@@ -174,16 +169,8 @@ const BTooltip = /*#__PURE__*/extend({
174
169
  // Initially disabled?
175
170
  if (this[MODEL_PROP_NAME_ENABLED]) {
176
171
  // Initially disabled
177
- this.doDisable();
172
+ this[EVENT_NAME_DISABLE]();
178
173
  }
179
- // Listen to open signals from others
180
- this.$on(EVENT_NAME_OPEN, this.doOpen);
181
- // Listen to close signals from others
182
- this.$on(EVENT_NAME_CLOSE, this.doClose);
183
- // Listen to disable signals from others
184
- this.$on(EVENT_NAME_DISABLE, this.doDisable);
185
- // Listen to enable signals from others
186
- this.$on(EVENT_NAME_ENABLE, this.doEnable);
187
174
  // Initially show tooltip?
188
175
  if (this.localShow) {
189
176
  $toolpop.show();
@@ -255,17 +242,17 @@ const BTooltip = /*#__PURE__*/extend({
255
242
  this.$emit(EVENT_NAME_ENABLED, bvEvent);
256
243
  }
257
244
  },
258
- // --- Local event listeners ---
259
- doOpen() {
245
+ // --- Public methods for programmatic control ---
246
+ [EVENT_NAME_OPEN]() {
260
247
  !this.localShow && this.$_toolpop && this.$_toolpop.show();
261
248
  },
262
- doClose() {
249
+ [EVENT_NAME_CLOSE]() {
263
250
  this.localShow && this.$_toolpop && this.$_toolpop.hide();
264
251
  },
265
- doDisable() {
252
+ [EVENT_NAME_DISABLE]() {
266
253
  this.$_toolpop && this.$_toolpop.disable();
267
254
  },
268
- doEnable() {
255
+ [EVENT_NAME_ENABLE]() {
269
256
  this.$_toolpop && this.$_toolpop.enable();
270
257
  }
271
258
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "128.2.3",
3
+ "version": "128.4.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -146,8 +146,8 @@
146
146
  "mockdate": "^3.0.5",
147
147
  "module-alias": "^2.2.3",
148
148
  "pikaday": "^1.8.0",
149
- "playwright": "^1.57.0",
150
- "playwright-core": "^1.57.0",
149
+ "playwright": "^1.58.0",
150
+ "playwright-core": "^1.58.0",
151
151
  "postcss": "8.5.6",
152
152
  "postcss-loader": "8.2.0",
153
153
  "postcss-scss": "4.0.9",
@@ -159,13 +159,13 @@
159
159
  "rollup-plugin-string": "^3.0.0",
160
160
  "rollup-plugin-svg": "^2.0.0",
161
161
  "rollup-plugin-vue": "^5.1.9",
162
- "sass": "^1.97.2",
162
+ "sass": "^1.97.3",
163
163
  "sass-loader": "^10.5.2",
164
164
  "sass-true": "^9",
165
165
  "start-server-and-test": "^2.1.3",
166
166
  "storybook": "^7.6.20",
167
167
  "storybook-dark-mode": "4.0.2",
168
- "style-dictionary": "^5.1.4",
168
+ "style-dictionary": "^5.2.0",
169
169
  "style-loader": "^4",
170
170
  "tailwindcss": "3.4.19",
171
171
  "vue": "2.7.16",
@@ -60,8 +60,10 @@ $breadcrumb-max-width: $grid-size * 16;
60
60
 
61
61
  .gl-breadcrumb-item-md {
62
62
  @apply gl-text-base;
63
+ }
63
64
 
64
- /**
65
+ .gl-breadcrumb-item {
66
+ /**
65
67
  * If the last/only item, which is always visible, has a very long title,
66
68
  * it could overflow the breadcrumb component. This CSS makes sure it
67
69
  * shows an ellipsis instead.
@@ -69,7 +71,8 @@ $breadcrumb-max-width: $grid-size * 16;
69
71
  * would then not take the real unshrunk width of that item into account.
70
72
  */
71
73
  &.gl-breadcrumb-only-item {
72
- @apply gl-max-w-full gl-shrink;
74
+ @apply gl-shrink;
75
+ max-width: var(--gl-breadcrumb-truncated-item-max-width, 100%);
73
76
 
74
77
  a {
75
78
  @apply gl-max-w-full gl-overflow-hidden gl-text-ellipsis gl-text-nowrap;
@@ -151,14 +151,22 @@ export default {
151
151
  } else {
152
152
  this.resizeDone = true;
153
153
  }
154
- this.clipboardButtonWidth = this.showClipboardButton
155
- ? this.$refs.clipboardButton.$el.clientWidth
156
- : 0;
154
+ this.updateClipboardButtonWidth();
157
155
  },
158
156
  beforeDestroy() {
159
157
  this.disableAutoResize();
160
158
  },
161
159
  methods: {
160
+ updateClipboardButtonWidth() {
161
+ if (!this.showClipboardButton) {
162
+ this.clipboardButtonWidth = 0;
163
+ return;
164
+ }
165
+
166
+ const element = this.$refs.clipboardButton.$el;
167
+ const marginLeft = parseInt(getComputedStyle(element).marginLeft, 10);
168
+ this.clipboardButtonWidth = element.offsetWidth + marginLeft;
169
+ },
162
170
  resetItems() {
163
171
  this.fittingItems = [...this.items];
164
172
  this.overflowingItems = [];
@@ -214,6 +222,15 @@ export default {
214
222
  }
215
223
  }
216
224
 
225
+ const truncatedItemMaxWidth = Math.max(
226
+ 0,
227
+ containerWidth - (this.dropdownWidth + this.clipboardButtonWidth),
228
+ );
229
+ this.$el.style.setProperty(
230
+ '--gl-breadcrumb-truncated-item-max-width',
231
+ `${truncatedItemMaxWidth}px`,
232
+ );
233
+
217
234
  this.resizeDone = true;
218
235
  },
219
236
  isLastItem(index) {
@@ -27,11 +27,12 @@ export default {
27
27
  *
28
28
  * @typedef {object} FieldDefinition
29
29
  * @template TValue=string
30
- * @property {string} label - Label text to show for this field.
30
+ * @property {string | null | undefined} label - Label text to show for this field. When explicitly set to null, the label is suppressed. When undefined or not provided, the field name is used as the label.
31
31
  * @property {undefined | Object} groupAttrs - Properties that are passed to the group wrapping this field.
32
32
  * @property {undefined | Object} inputAttrs - Properties that are passed to the actual input for this field.
33
33
  * @property {undefined | function(string): TValue} mapValue - Function that maps the inputted string value to the field's actual value (e.g. a Number).
34
34
  * @property {undefined | Array<function(TValue): string | undefined>=} validators - Collection of validator functions.
35
+ * @property {undefined | boolean} fieldset - When true, renders the form group as a fieldset with legend instead of div with label.
35
36
  *
36
37
  * @type {{ [key: string]: FieldDefinition }}
37
38
  */
@@ -140,7 +141,7 @@ export default {
140
141
  return {
141
142
  ...field,
142
143
  id,
143
- label: field.label || fieldName,
144
+ label: this.getFieldLabel(field, fieldName),
144
145
  inputSlot,
145
146
  groupPassthroughSlots,
146
147
  afterSlotName,
@@ -179,6 +180,10 @@ export default {
179
180
 
180
181
  return this.hasAllFieldsValid();
181
182
  },
183
+ getFieldLabel(field, fieldName) {
184
+ if (field.label === null) return undefined;
185
+ return field.label || fieldName;
186
+ },
182
187
  getMappedValue(fieldName, val) {
183
188
  const field = this.fields[fieldName];
184
189
 
@@ -271,7 +276,7 @@ export default {
271
276
  v-bind="field.groupAttrs"
272
277
  :key="field.id"
273
278
  :label="field.label"
274
- :label-for="field.id"
279
+ :label-for="field.fieldset ? undefined : field.id"
275
280
  :invalid-feedback="fieldValidationProps[fieldName].invalidFeedback"
276
281
  :state="fieldValidationProps[fieldName].state"
277
282
  >
@@ -71,7 +71,7 @@ export default {
71
71
  </script>
72
72
  <template>
73
73
  <b-form-group v-bind="$attrs" class="gl-form-group" :label-class="actualLabelClass">
74
- <template #label>
74
+ <template v-if="$attrs.label || $scopedSlots.label" #label>
75
75
  <slot name="label">
76
76
  {{ $attrs.label }}
77
77
  <span v-if="optional" class="optional-label" data-testid="optional-label">{{
@@ -103,8 +103,8 @@ export default {
103
103
 
104
104
  return [];
105
105
  },
106
- close(e) {
107
- this.$refs[popoverRefName].doClose();
106
+ closePopover(e) {
107
+ this.$refs[popoverRefName].close();
108
108
  /**
109
109
  * Emitted when the close button is clicked (requires showCloseButton to be `true`).
110
110
  */
@@ -135,7 +135,7 @@ export default {
135
135
  <close-button
136
136
  :class="{ 'gl-float-right gl-mt-2': !hasTitle }"
137
137
  data-testid="close-button"
138
- @click="close"
138
+ @click="closePopover"
139
139
  />
140
140
  </div>
141
141
  </template>
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { GlUniqueId } from '../../../utils/unique_id';
2
+ import uniqueId from 'lodash/uniqueId';
3
3
  import { tokensValidator } from './helpers';
4
4
  import GlTokenContainer from './token_container.vue';
5
5
  import GlTokenSelectorDropdown from './token_selector_dropdown.vue';
@@ -252,7 +252,7 @@ export default {
252
252
  },
253
253
  created() {
254
254
  // Each instance must have a unique ID for proper ARIA relationships
255
- this.uniqueId = `token-selector-${GlUniqueId()}`;
255
+ this.uniqueId = uniqueId('token-selector-');
256
256
  },
257
257
  methods: {
258
258
  handleFocus(event) {
@@ -12,7 +12,7 @@ export default (tooltipRefName) => ({
12
12
  * https://bootstrap-vue.org/docs/components/tooltip#programmatically-show-and-hide-tooltip
13
13
  */
14
14
  tooltipActionEvents.forEach((event) =>
15
- this.$on(event, () => this.$refs[tooltipRefName].$emit(event)),
15
+ this.$on(event, () => this.$refs[tooltipRefName][event]()),
16
16
  );
17
17
  },
18
18
  beforeDestroy() {
@@ -141,9 +141,9 @@ export const BTooltip = /*#__PURE__*/ extend({
141
141
  },
142
142
  [MODEL_PROP_NAME_ENABLED](newValue) {
143
143
  if (newValue) {
144
- this.doDisable()
144
+ this[EVENT_NAME_DISABLE]()
145
145
  } else {
146
- this.doEnable()
146
+ this[EVENT_NAME_ENABLE]()
147
147
  }
148
148
  },
149
149
  localShow(newValue) {
@@ -172,11 +172,6 @@ export const BTooltip = /*#__PURE__*/ extend({
172
172
  this.$nextTick(this.updateContent)
173
173
  },
174
174
  beforeDestroy() {
175
- // Shutdown our local event listeners
176
- this.$off(EVENT_NAME_OPEN, this.doOpen)
177
- this.$off(EVENT_NAME_CLOSE, this.doClose)
178
- this.$off(EVENT_NAME_DISABLE, this.doDisable)
179
- this.$off(EVENT_NAME_ENABLE, this.doEnable)
180
175
  // Destroy the tip instance
181
176
  if (this.$_toolpop) {
182
177
  this.$_toolpop.$destroy()
@@ -212,16 +207,8 @@ export const BTooltip = /*#__PURE__*/ extend({
212
207
  // Initially disabled?
213
208
  if (this[MODEL_PROP_NAME_ENABLED]) {
214
209
  // Initially disabled
215
- this.doDisable()
210
+ this[EVENT_NAME_DISABLE]()
216
211
  }
217
- // Listen to open signals from others
218
- this.$on(EVENT_NAME_OPEN, this.doOpen)
219
- // Listen to close signals from others
220
- this.$on(EVENT_NAME_CLOSE, this.doClose)
221
- // Listen to disable signals from others
222
- this.$on(EVENT_NAME_DISABLE, this.doDisable)
223
- // Listen to enable signals from others
224
- this.$on(EVENT_NAME_ENABLE, this.doEnable)
225
212
  // Initially show tooltip?
226
213
  if (this.localShow) {
227
214
  $toolpop.show()
@@ -293,17 +280,17 @@ export const BTooltip = /*#__PURE__*/ extend({
293
280
  this.$emit(EVENT_NAME_ENABLED, bvEvent)
294
281
  }
295
282
  },
296
- // --- Local event listeners ---
297
- doOpen() {
283
+ // --- Public methods for programmatic control ---
284
+ [EVENT_NAME_OPEN]() {
298
285
  !this.localShow && this.$_toolpop && this.$_toolpop.show()
299
286
  },
300
- doClose() {
287
+ [EVENT_NAME_CLOSE]() {
301
288
  this.localShow && this.$_toolpop && this.$_toolpop.hide()
302
289
  },
303
- doDisable() {
290
+ [EVENT_NAME_DISABLE]() {
304
291
  this.$_toolpop && this.$_toolpop.disable()
305
292
  },
306
- doEnable() {
293
+ [EVENT_NAME_ENABLE]() {
307
294
  this.$_toolpop && this.$_toolpop.enable()
308
295
  }
309
296
  },
@@ -1,18 +0,0 @@
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 };
@@ -1,17 +0,0 @@
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
- };