@brightspace-ui/core 3.86.5 → 3.87.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.
@@ -48,6 +48,13 @@
48
48
  </template>
49
49
  </d2l-demo-snippet>
50
50
 
51
+ <h2>Disabled checkbox with tooltip</h2>
52
+ <d2l-demo-snippet>
53
+ <template>
54
+ <d2l-input-checkbox checked disabled disabled-tooltip="Explanation for why checkbox is disabled">Disabled checkbox with tooltip</d2l-input-checkbox>
55
+ </template>
56
+ </d2l-demo-snippet>
57
+
51
58
  <h2>Checkbox with label and secondary content</h2>
52
59
  <d2l-demo-snippet>
53
60
  <template>
@@ -1,12 +1,12 @@
1
1
  import '../colors/colors.js';
2
- import { css, html, LitElement } from 'lit';
2
+ import '../tooltip/tooltip.js';
3
+ import { css, html, LitElement, nothing } from 'lit';
3
4
  import { classMap } from 'lit/directives/class-map.js';
4
5
  import { FocusMixin } from '../../mixins/focus/focus-mixin.js';
5
6
  import { getUniqueId } from '../../helpers/uniqueId.js';
6
7
  import { ifDefined } from 'lit/directives/if-defined.js';
7
8
  import { InputInlineHelpMixin } from './input-inline-help.js';
8
9
  import { offscreenStyles } from '../offscreen/offscreen.js';
9
- import { RtlMixin } from '../../mixins/rtl/rtl-mixin.js';
10
10
  import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
11
11
 
12
12
  export const cssSizes = {
@@ -53,7 +53,8 @@ export const checkboxStyles = css`
53
53
  border-width: 2px;
54
54
  outline-width: 0;
55
55
  }
56
- input[type="checkbox"].d2l-input-checkbox:disabled {
56
+ input[type="checkbox"].d2l-input-checkbox:disabled,
57
+ input[type="checkbox"].d2l-input-checkbox[aria-disabled="true"] {
57
58
  opacity: 0.5;
58
59
  }
59
60
  `;
@@ -64,7 +65,7 @@ export const checkboxStyles = css`
64
65
  * @slot inline-help - Help text that will appear below the input. Use this only when other helpful cues are not sufficient, such as a carefully-worded label.
65
66
  * @fires change - Dispatched when the checkbox's state changes
66
67
  */
67
- class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMixin(LitElement)))) {
68
+ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(LitElement))) {
68
69
 
69
70
  static get properties() {
70
71
  return {
@@ -88,6 +89,11 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
88
89
  * @type {boolean}
89
90
  */
90
91
  disabled: { type: Boolean },
92
+ /**
93
+ * Tooltip text when disabled
94
+ * @type {string}
95
+ */
96
+ disabledTooltip: { type: String, attribute: 'disabled-tooltip' },
91
97
  /**
92
98
  * Sets checkbox to an indeterminate state
93
99
  * @type {boolean}
@@ -107,7 +113,8 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
107
113
  * Value of the input
108
114
  * @type {string}
109
115
  */
110
- value: { type: String }
116
+ value: { type: String },
117
+ _isHovered: { state: true },
111
118
  };
112
119
  }
113
120
 
@@ -138,21 +145,12 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
138
145
  display: inline-block;
139
146
  font-size: 0.8rem;
140
147
  font-weight: 400;
141
- margin-left: ${cssSizes.checkboxMargin}rem;
148
+ margin-inline-start: ${cssSizes.checkboxMargin}rem;
142
149
  vertical-align: top;
143
150
  white-space: normal;
144
151
  }
145
- :host([dir="rtl"]) .d2l-input-checkbox-text {
146
- margin-left: 0;
147
- margin-right: ${cssSizes.checkboxMargin}rem;
148
- }
149
152
  :host([aria-label]) .d2l-input-checkbox-text {
150
- margin-left: 0;
151
- margin-right: 0;
152
- }
153
- :host([dir="rtl"][aria-label]) .d2l-input-checkbox-text {
154
- margin-left: 0;
155
- margin-right: 0;
153
+ margin-inline-start: 0;
156
154
  }
157
155
  :host([skeleton]) .d2l-input-checkbox-text.d2l-skeletize::before {
158
156
  bottom: 0.3rem;
@@ -182,8 +180,7 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
182
180
  this.name = '';
183
181
  this.notTabbable = false;
184
182
  this.value = 'on';
185
- this._descriptionId = getUniqueId();
186
- this._inlineHelpId = getUniqueId();
183
+ this._isHovered = false;
187
184
  }
188
185
 
189
186
  static get focusElementSelector() {
@@ -199,27 +196,33 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
199
196
  };
200
197
  const ariaChecked = this.indeterminate ? 'mixed' : undefined;
201
198
  const disabled = this.disabled || this.skeleton;
202
- const offscreenContainer = this.description ? html`<div class="d2l-offscreen" id="${this._descriptionId}">${this.description}</div>` : null;
203
- const ariaDescribedByIds = `${this.description ? this._descriptionId : ''} ${this._hasInlineHelp ? this._inlineHelpId : ''}`.trim();
199
+ const offscreenContainer = this.description ? html`<div class="d2l-offscreen" id="${this.#descriptionId}">${this.description}</div>` : null;
200
+ const ariaDescribedByIds = `${this.description ? this.#descriptionId : ''} ${this._hasInlineHelp ? this.#inlineHelpId : ''}`.trim();
201
+ const disabledTooltip = disabled && this.disabledTooltip ?
202
+ html`<d2l-tooltip align="start" class="vdiff-target" for="${this.#inputId}" ?force-show="${this._isHovered}" position="top">${this.disabledTooltip}</d2l-tooltip>` :
203
+ nothing;
204
204
  return html`
205
- <label>
205
+ <label @mouseleave="${this.#handleMouseLeave}" @mouseenter="${this.#handleMouseEnter}">
206
206
  <span class="d2l-input-checkbox-wrapper d2l-skeletize"><input
207
207
  aria-checked="${ifDefined(ariaChecked)}"
208
208
  aria-describedby="${ifDefined(ariaDescribedByIds.length > 0 ? ariaDescribedByIds : undefined)}"
209
+ aria-disabled="${ifDefined(disabled && this.disabledTooltip ? 'true' : undefined)}"
209
210
  aria-label="${ifDefined(this.ariaLabel)}"
210
- @change="${this._handleChange}"
211
+ @change="${this.#handleChange}"
211
212
  class="d2l-input-checkbox"
212
213
  @click="${this._handleClick}"
213
214
  .checked="${this.checked}"
214
- ?disabled="${disabled}"
215
+ ?disabled="${disabled && !this.disabledTooltip}"
216
+ id="${this.#inputId}"
215
217
  .indeterminate="${this.indeterminate}"
216
218
  name="${ifDefined(this.name)}"
217
219
  tabindex="${ifDefined(tabindex)}"
218
220
  type="checkbox"
219
221
  .value="${this.value}"></span><span class="${classMap(textClasses)}"><slot></slot></span>
220
222
  </label>
221
- ${this._renderInlineHelp(this._inlineHelpId)}
223
+ ${this._renderInlineHelp(this.#inlineHelpId)}
222
224
  ${offscreenContainer}
225
+ ${disabledTooltip}
223
226
  `;
224
227
  }
225
228
 
@@ -232,7 +235,11 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
232
235
  ));
233
236
  }
234
237
 
235
- _handleChange(e) {
238
+ #descriptionId = getUniqueId();
239
+ #inlineHelpId = getUniqueId();
240
+ #inputId = getUniqueId();
241
+
242
+ #handleChange(e) {
236
243
  this.checked = e.target.checked;
237
244
  this.indeterminate = false;
238
245
  this.dispatchEvent(new CustomEvent(
@@ -241,16 +248,13 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
241
248
  ));
242
249
  }
243
250
 
244
- /**
245
- * This is needed only for Legacy-Edge AND going from indeterminate to checked/unchecked.
246
- * When the indeterminate state is set, and the checkbox is clicked, the _handleChange
247
- * function is NOT triggered, therefore we have to detect the click and handle it ourselves.
248
- */
249
- _handleClick() {
250
- const browserType = window.navigator.userAgent;
251
- if (this.indeterminate && (browserType.indexOf('Edge') > -1)) {
252
- this.simulateClick();
253
- }
251
+ #handleMouseEnter() {
252
+ this._isHovered = true;
253
+ }
254
+
255
+ #handleMouseLeave() {
256
+ this._isHovered = false;
254
257
  }
258
+
255
259
  }
256
260
  customElements.define('d2l-input-checkbox', InputCheckbox);
@@ -5024,6 +5024,11 @@
5024
5024
  "description": "ACCESSIBILITY: Additional information communicated to screenreader users when focusing on the input",
5025
5025
  "type": "string"
5026
5026
  },
5027
+ {
5028
+ "name": "disabled-tooltip",
5029
+ "description": "Tooltip text when disabled",
5030
+ "type": "string"
5031
+ },
5027
5032
  {
5028
5033
  "name": "checked",
5029
5034
  "description": "Checked state",
@@ -5079,6 +5084,12 @@
5079
5084
  "description": "ACCESSIBILITY: Additional information communicated to screenreader users when focusing on the input",
5080
5085
  "type": "string"
5081
5086
  },
5087
+ {
5088
+ "name": "disabledTooltip",
5089
+ "attribute": "disabled-tooltip",
5090
+ "description": "Tooltip text when disabled",
5091
+ "type": "string"
5092
+ },
5082
5093
  {
5083
5094
  "name": "checked",
5084
5095
  "attribute": "checked",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.86.5",
3
+ "version": "3.87.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",