@brightspace-ui/core 3.178.0 → 3.180.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.
@@ -168,7 +168,7 @@ class ButtonIcon extends SlottedIconMixin(PropertyRequiredMixin(ThemeMixin(Butto
168
168
  ${this._renderIcon()}
169
169
  </button>
170
170
  ${this.description ? html`<span id="${this._describedById}" hidden>${this.description}</span>` : null}
171
- ${this.disabled && this.disabledTooltip ? html`<d2l-tooltip for="${this._buttonId}">${this.disabledTooltip}</d2l-tooltip>` : ''}
171
+ ${this.disabled && this.disabledTooltip ? html`<d2l-tooltip class="vdiff-target" for="${this._buttonId}">${this.disabledTooltip}</d2l-tooltip>` : ''}
172
172
  `;
173
173
  }
174
174
 
@@ -49,6 +49,8 @@ Import and use the `<d2l-link>` web component instead of the native `<a>` elemen
49
49
  |--|--|--|
50
50
  | `aria-label` | String | Label to provide more context for screen reader users when the link text is not enough |
51
51
  | `href` | String, required | URL or URL fragment of the link |
52
+ | `disabled` | Boolean | Disables the link |
53
+ | `disabled-tooltip` | String | Tooltip text when disabled |
52
54
  | `download` | String | If the attribute is provided, it will prompt the user to download the resource instead of navigating to it. Additionally, if the attribute is provided with a value, that value will be used for the filename. |
53
55
  | `main` | Boolean | Whether to apply the "main" link style |
54
56
  | `lines` | Number | The number of lines to display before truncating text with an ellipsis. The text will not be truncated unless a value is specified. |
@@ -92,6 +92,20 @@
92
92
  </template>
93
93
  </d2l-demo-snippet>
94
94
 
95
+ <h2>Disabled</h2>
96
+ <d2l-demo-snippet>
97
+ <template>
98
+ <d2l-link disabled href="https://www.d2l.com" target="_blank">Disabled Link</d2l-link>
99
+ </template>
100
+ </d2l-demo-snippet>
101
+
102
+ <h2>Disabled with Tooltip</h2>
103
+ <d2l-demo-snippet>
104
+ <template>
105
+ <d2l-link disabled disabled-tooltip="This link is disabled because you do not have permission" href="https://www.d2l.com" target="_blank">Disabled Link with Tooltip</d2l-link>
106
+ </template>
107
+ </d2l-demo-snippet>
108
+
95
109
  </d2l-demo-page>
96
110
  </body>
97
111
  </html>
@@ -1,11 +1,13 @@
1
1
  import '../colors/colors.js';
2
2
  import '../icons/icon.js';
3
+ import '../tooltip/tooltip.js';
3
4
  import { css, html, LitElement, nothing } from 'lit';
4
5
  import { getOverflowDeclarations, overflowEllipsisDeclarations } from '../../helpers/overflow.js';
5
6
  import { _generateLinkStyles } from './link-styles.js';
6
7
  import { classMap } from 'lit/directives/class-map.js';
7
8
  import { FocusMixin } from '../../mixins/focus/focus-mixin.js';
8
9
  import { getFlag } from '../../helpers/flags.js';
10
+ import { getUniqueId } from '../../helpers/uniqueId.js';
9
11
  import { ifDefined } from 'lit/directives/if-defined.js';
10
12
  import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
11
13
  import { offscreenStyles } from '../offscreen/offscreen.js';
@@ -28,6 +30,16 @@ class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
28
30
  * @type {string}
29
31
  */
30
32
  ariaLabel: { type: String, attribute: 'aria-label' },
33
+ /**
34
+ * Disables the link
35
+ * @type {boolean}
36
+ */
37
+ disabled: { type: Boolean, reflect: true },
38
+ /**
39
+ * Tooltip text when disabled
40
+ * @type {string}
41
+ */
42
+ disabledTooltip: { type: String, attribute: 'disabled-tooltip', reflect: true },
31
43
  /**
32
44
  * Download a URL instead of navigating to it
33
45
  * @type {boolean}
@@ -113,6 +125,24 @@ class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
113
125
  --d2l-icon-fill-color: var(--d2l-color-celestine-minus-1);
114
126
  }
115
127
 
128
+ :host([disabled]:not([disabled-tooltip])) a:hover {
129
+ color: var(--d2l-color-celestine);
130
+ text-decoration: none;
131
+ }
132
+ :host([disabled]:not([disabled-tooltip])) a:hover d2l-icon {
133
+ --d2l-icon-fill-color: var(--d2l-color-celestine);
134
+ }
135
+ a[aria-disabled="true"],
136
+ a[aria-disabled="true"]:active {
137
+ cursor: default;
138
+ }
139
+ a[aria-disabled="true"] .d2l-link-content {
140
+ opacity: 0.74;
141
+ }
142
+ a[aria-disabled="true"] d2l-icon {
143
+ opacity: 0.64;
144
+ }
145
+
116
146
  @media print {
117
147
  d2l-icon {
118
148
  display: none;
@@ -124,6 +154,7 @@ class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
124
154
 
125
155
  constructor() {
126
156
  super();
157
+ this.disabled = false;
127
158
  this.download = false;
128
159
  this.main = false;
129
160
  this.small = false;
@@ -141,6 +172,7 @@ class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
141
172
  'd2l-link-small': this.small
142
173
  };
143
174
  const spanClasses = {
175
+ 'd2l-link-content': true,
144
176
  'truncate': this.lines > 1,
145
177
  'truncate-one': this.lines === 1
146
178
  };
@@ -148,6 +180,9 @@ class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
148
180
  const newWindowElements = (this.target === '_blank')
149
181
  ? html`<span id="new-window"><span style="font-size: 0;">&nbsp;</span><d2l-icon icon="tier1:new-window"></d2l-icon></span><span class="d2l-offscreen">${this.localize('components.link.open-in-new-window')}</span>`
150
182
  : nothing;
183
+ const disabledTooltip = this.disabled && this.disabledTooltip
184
+ ? html`<d2l-tooltip class="vdiff-target" for="${this.#linkId}">${this.disabledTooltip}</d2l-tooltip>`
185
+ : nothing;
151
186
 
152
187
  /*
153
188
  * NOTICE:
@@ -155,14 +190,27 @@ class Link extends LocalizeCoreElement(FocusMixin(LitElement)) {
155
190
  * Do not modify for readability!
156
191
  */
157
192
  return html`<a
193
+ aria-disabled="${ifDefined(this.disabled ? 'true' : undefined)}"
158
194
  aria-label="${ifDefined(this.ariaLabel)}"
159
195
  class="${classMap(linkClasses)}"
196
+ @click="${this.#handleClick}"
160
197
  ?download="${this.download}"
161
- href="${ifDefined(this.href)}"
198
+ href="${ifDefined(!this.disabled ? this.href : undefined)}"
199
+ id="${this.#linkId}"
200
+ tabindex="${ifDefined(this.disabled && this.disabledTooltip ? 0 : undefined)}"
162
201
  target="${ifDefined(this.target)}"
163
202
  ><span
164
203
  class="${classMap(spanClasses)}"
165
- style="${styleMap(styles)}"><slot></slot></span>${newWindowElements}</a>`;
204
+ style="${styleMap(styles)}"><slot></slot></span>${newWindowElements}</a>${disabledTooltip}`;
205
+ }
206
+
207
+ #linkId = getUniqueId();
208
+
209
+ #handleClick(e) {
210
+ if (this.disabled) {
211
+ e.stopPropagation();
212
+ e.preventDefault();
213
+ }
166
214
  }
167
215
 
168
216
  }
@@ -70,7 +70,7 @@ The list components are fairly complex and aim to be usable by all our users. In
70
70
 
71
71
  * When the `grid` attribute is used on the `d2l-list` component, it enables the list to follow the [Grid Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/). More details on this are [below](#aria-layout-grid).
72
72
 
73
- * When using the `d2l-list-item-nav` component and/or mixin, usage of the `current` attribute adds the `aria-current` attribute to "page" for the `current` item and "location" for any parent and ancestors of the item. The components work together to keep these attributes up-to-date on subsequent selection.
73
+ * When using the `d2l-list-item-nav` component and/or mixin, usage of the `current` attribute adds the `aria-current` attribute to "page" for the `current` item and "location" for any parent and ancestors of the item. The components work together to keep these attributes up-to-date on subsequent selection.
74
74
 
75
75
  * Usage of the new `current` attribute over the existing `selected` attribute corresponds to `aria-current` and also leaves open the possibility of using both `current` and selection behavior together.
76
76
 
@@ -635,6 +635,7 @@ The `d2l-list-item` provides the appropriate `listitem` semantics for children w
635
635
 
636
636
  | Property | Type | Description |
637
637
  |---|---|---|
638
+ | `keyboard-drag-disabled` | Boolean | Disables keyboard dragging interaction. If enabled while implementing drag & drop, a keyboard alternative should be provided for the dragging functionality. |
638
639
  | `draggable` | Boolean | Whether the item is draggable |
639
640
  | `drag-handle-text` | String | The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode. |
640
641
  | `drag-target-handle-only` | Boolean | Make the drag target the drag handle only. |
@@ -23,6 +23,7 @@ class ListDemoNested extends LitElement {
23
23
  demoItemKey: { type: String, attribute: 'demo-item-key' },
24
24
  isDraggable: { attribute: 'is-draggable', type: Boolean },
25
25
  selectable: { type: Boolean },
26
+ keyboardDragDisabled: { type: Boolean, attribute: 'keyboard-drag-disabled' },
26
27
  disableExpandFeature: { type: Boolean, attribute: 'disable-expand-feature' },
27
28
  expanded: { type: Boolean },
28
29
  includeSecondaryActions: { type: Boolean, attribute: 'include-secondary-actions' },
@@ -203,6 +204,7 @@ class ListDemoNested extends LitElement {
203
204
  return html`
204
205
  <d2l-list-item
205
206
  action-href="${this.includeActionHref ? 'http://www.d2l.com' : ''}"
207
+ ?keyboard-drag-disabled="${this.keyboardDragDisabled}"
206
208
  ?draggable="${this.isDraggable}"
207
209
  drag-handle-text="${item.primaryText}"
208
210
  ?drop-nested="${item.dropNested}"
@@ -46,6 +46,14 @@
46
46
  </template>
47
47
  </d2l-demo-snippet>
48
48
 
49
+ <h2>Disable Keyboard Drag</h2>
50
+
51
+ <d2l-demo-snippet>
52
+ <template>
53
+ <d2l-demo-list-nested demo-item-key="imgPrimaryAndSupporting" is-draggable selectable keyboard-drag-disabled></d2l-demo-list-nested>
54
+ </template>
55
+ </d2l-demo-snippet>
56
+
49
57
 
50
58
  </d2l-demo-page>
51
59
 
@@ -250,6 +250,11 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
250
250
 
251
251
  static get properties() {
252
252
  return {
253
+ /**
254
+ * **Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.
255
+ * @type {boolean}
256
+ */
257
+ keyboardDragDisabled: { type: Boolean, attribute: 'keyboard-drag-disabled' },
253
258
  /**
254
259
  * **Drag & drop:** Whether the item is draggable
255
260
  * @type {boolean}
@@ -862,6 +867,7 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
862
867
  <d2l-list-item-drag-handle
863
868
  id="${this._itemDragId}"
864
869
  class="${classMap(classes)}"
870
+ ?disabled="${this.keyboardDragDisabled}"
865
871
  text="${ifDefined(this.dragHandleText)}"
866
872
  keyboard-text-info="${ifDefined(this._keyboardTextInfo)}"
867
873
  @focusin="${this._onFocusinDragHandle}"
@@ -174,12 +174,7 @@ class ListItemDragHandle extends LocalizeCoreElement(FocusMixin(LitElement)) {
174
174
  }
175
175
 
176
176
  _onDraggerButtonClick() {
177
- this.activateKeyboardMode();
178
- }
179
-
180
- _onDraggerButtonKeydown(e) {
181
- if (e.keyCode !== keyCodes.ENTER && e.keyCode !== keyCodes.SPACE) return;
182
- e.preventDefault();
177
+ if (this.disabled) return;
183
178
  this.activateKeyboardMode();
184
179
  }
185
180
 
@@ -287,7 +282,6 @@ class ListItemDragHandle extends LocalizeCoreElement(FocusMixin(LitElement)) {
287
282
  <button
288
283
  class="d2l-list-item-drag-handle-dragger-button d2l-list-item-drag-handle-button"
289
284
  @click="${this._onDraggerButtonClick}"
290
- @keydown="${this._onDraggerButtonKeydown}"
291
285
  aria-label="${this._defaultLabel}"
292
286
  ?disabled="${this.disabled}">
293
287
  <d2l-icon icon="tier1:dragger" class="d2l-button-dragger-icon"></d2l-icon>
@@ -8483,6 +8483,11 @@
8483
8483
  "description": "ACCESSIBILITY: Label to provide more context for screen reader users when the link text is not enough",
8484
8484
  "type": "string"
8485
8485
  },
8486
+ {
8487
+ "name": "disabled-tooltip",
8488
+ "description": "Tooltip text when disabled",
8489
+ "type": "string"
8490
+ },
8486
8491
  {
8487
8492
  "name": "href",
8488
8493
  "description": "REQUIRED: URL or URL fragment of the link",
@@ -8493,6 +8498,12 @@
8493
8498
  "description": "Where to display the linked URL",
8494
8499
  "type": "string"
8495
8500
  },
8501
+ {
8502
+ "name": "disabled",
8503
+ "description": "Disables the link",
8504
+ "type": "boolean",
8505
+ "default": "false"
8506
+ },
8496
8507
  {
8497
8508
  "name": "download",
8498
8509
  "description": "Download a URL instead of navigating to it",
@@ -8525,6 +8536,12 @@
8525
8536
  "description": "ACCESSIBILITY: Label to provide more context for screen reader users when the link text is not enough",
8526
8537
  "type": "string"
8527
8538
  },
8539
+ {
8540
+ "name": "disabledTooltip",
8541
+ "attribute": "disabled-tooltip",
8542
+ "description": "Tooltip text when disabled",
8543
+ "type": "string"
8544
+ },
8528
8545
  {
8529
8546
  "name": "href",
8530
8547
  "attribute": "href",
@@ -8537,6 +8554,13 @@
8537
8554
  "description": "Where to display the linked URL",
8538
8555
  "type": "string"
8539
8556
  },
8557
+ {
8558
+ "name": "disabled",
8559
+ "attribute": "disabled",
8560
+ "description": "Disables the link",
8561
+ "type": "boolean",
8562
+ "default": "false"
8563
+ },
8540
8564
  {
8541
8565
  "name": "download",
8542
8566
  "attribute": "download",
@@ -8653,6 +8677,10 @@
8653
8677
  "name": "selectable",
8654
8678
  "type": "boolean"
8655
8679
  },
8680
+ {
8681
+ "name": "keyboard-drag-disabled",
8682
+ "type": "boolean"
8683
+ },
8656
8684
  {
8657
8685
  "name": "disable-expand-feature",
8658
8686
  "type": "boolean"
@@ -8711,6 +8739,11 @@
8711
8739
  "attribute": "selectable",
8712
8740
  "type": "boolean"
8713
8741
  },
8742
+ {
8743
+ "name": "keyboardDragDisabled",
8744
+ "attribute": "keyboard-drag-disabled",
8745
+ "type": "boolean"
8746
+ },
8714
8747
  {
8715
8748
  "name": "disableExpandFeature",
8716
8749
  "attribute": "disable-expand-feature",
@@ -8907,6 +8940,11 @@
8907
8940
  "type": "boolean",
8908
8941
  "default": "false"
8909
8942
  },
8943
+ {
8944
+ "name": "keyboard-drag-disabled",
8945
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
8946
+ "type": "boolean"
8947
+ },
8910
8948
  {
8911
8949
  "name": "drag-handle-text",
8912
8950
  "description": "**Drag & drop:** The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode.",
@@ -9028,6 +9066,12 @@
9028
9066
  {
9029
9067
  "name": "selectionInfo"
9030
9068
  },
9069
+ {
9070
+ "name": "keyboardDragDisabled",
9071
+ "attribute": "keyboard-drag-disabled",
9072
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
9073
+ "type": "boolean"
9074
+ },
9031
9075
  {
9032
9076
  "name": "dragHandleText",
9033
9077
  "attribute": "drag-handle-text",
@@ -9268,6 +9312,11 @@
9268
9312
  "type": "boolean",
9269
9313
  "default": "false"
9270
9314
  },
9315
+ {
9316
+ "name": "keyboard-drag-disabled",
9317
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
9318
+ "type": "boolean"
9319
+ },
9271
9320
  {
9272
9321
  "name": "drag-handle-text",
9273
9322
  "description": "**Drag & drop:** The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode.",
@@ -9396,6 +9445,12 @@
9396
9445
  {
9397
9446
  "name": "selectionInfo"
9398
9447
  },
9448
+ {
9449
+ "name": "keyboardDragDisabled",
9450
+ "attribute": "keyboard-drag-disabled",
9451
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
9452
+ "type": "boolean"
9453
+ },
9399
9454
  {
9400
9455
  "name": "dragHandleText",
9401
9456
  "attribute": "drag-handle-text",
@@ -9766,6 +9821,11 @@
9766
9821
  "type": "boolean",
9767
9822
  "default": "false"
9768
9823
  },
9824
+ {
9825
+ "name": "keyboard-drag-disabled",
9826
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
9827
+ "type": "boolean"
9828
+ },
9769
9829
  {
9770
9830
  "name": "drag-handle-text",
9771
9831
  "description": "**Drag & drop:** The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode.",
@@ -9906,6 +9966,12 @@
9906
9966
  {
9907
9967
  "name": "selectionInfo"
9908
9968
  },
9969
+ {
9970
+ "name": "keyboardDragDisabled",
9971
+ "attribute": "keyboard-drag-disabled",
9972
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
9973
+ "type": "boolean"
9974
+ },
9909
9975
  {
9910
9976
  "name": "dragHandleText",
9911
9977
  "attribute": "drag-handle-text",
@@ -10080,6 +10146,11 @@
10080
10146
  "type": "boolean",
10081
10147
  "default": "false"
10082
10148
  },
10149
+ {
10150
+ "name": "keyboard-drag-disabled",
10151
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
10152
+ "type": "boolean"
10153
+ },
10083
10154
  {
10084
10155
  "name": "drag-handle-text",
10085
10156
  "description": "**Drag & drop:** The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode.",
@@ -10213,6 +10284,12 @@
10213
10284
  {
10214
10285
  "name": "selectionInfo"
10215
10286
  },
10287
+ {
10288
+ "name": "keyboardDragDisabled",
10289
+ "attribute": "keyboard-drag-disabled",
10290
+ "description": "**Drag & drop:** Disables keyboard dragging interaction. If draggable, a keyboard alternative should be provided for the dragging functionality.",
10291
+ "type": "boolean"
10292
+ },
10216
10293
  {
10217
10294
  "name": "dragHandleText",
10218
10295
  "attribute": "drag-handle-text",
@@ -35,7 +35,7 @@ export function isInteractive(ele, elems, roles) {
35
35
  return true;
36
36
  }
37
37
  const role = (ele.getAttribute('role') || '');
38
- return (nodeName === 'a' && ele.hasAttribute('href')) || roles[role] || false;
38
+ return (nodeName === 'a' && (ele.hasAttribute('href') || ele.getAttribute('tabindex') === '0')) || roles[role] || false;
39
39
  }
40
40
 
41
41
  export function isInteractiveInComposedPath(composedPath, predicate, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.178.0",
3
+ "version": "3.180.0",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",