@brightspace-ui/core 3.42.0 → 3.44.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.
@@ -76,6 +76,7 @@ export const DialogMixin = superclass => class extends RtlMixin(superclass) {
76
76
  this._handleDropdownOpenClose = this._handleDropdownOpenClose.bind(this);
77
77
  this._handleMvcDialogOpen = this._handleMvcDialogOpen.bind(this);
78
78
  this._inIframe = false;
79
+ this._isDialogMixin = true;
79
80
  this._isFullHeight = false;
80
81
  this._height = 0;
81
82
  this._left = 0;
@@ -71,6 +71,7 @@ class FormNestedDemo extends LitElement {
71
71
  </div>
72
72
  <d2l-floating-buttons always-float>
73
73
  <d2l-button primary @click=${this._submit}>Save</d2l-button>
74
+ <d2l-button @click=${this._reset}>Reset</d2l-button>
74
75
  </d2l-floating-buttons>
75
76
  </d2l-form>
76
77
  `;
@@ -85,6 +86,10 @@ class FormNestedDemo extends LitElement {
85
86
  e.preventDefault();
86
87
  }
87
88
 
89
+ _reset() {
90
+ if (this.shadowRoot) this.shadowRoot.querySelector('#root').resetValidation();
91
+ }
92
+
88
93
  _submit() {
89
94
  if (this.shadowRoot) this.shadowRoot.querySelector('#root').submit();
90
95
  }
@@ -18,6 +18,7 @@ invalid state.
18
18
  | `name` | String | The name of the form control. Submitted with the form as part of a name/value pair. |
19
19
 
20
20
  **Methods:**
21
+ - `resetValidation()`: Resets any validation errors on the form element. Note that this does not reset any form element value.
21
22
  - `setFormValue(value)`: Sets the current value of the form control. Submitted with the form as part of a name/value pair. `value` may be a:
22
23
  1. An `Object`: `{ 'key1': val, 'key2': val }`
23
24
  - When an `Object` is provided, all keys-value pairs will be submitted. To avoid collision it is recommended that you prefix each key with the component's `name` property value.
@@ -114,6 +114,7 @@ If you're looking to emulate native form element submission, `d2l-form-native` m
114
114
  ### Methods
115
115
  - `submit()`: Submits the form. This will first perform validation on all elements within the form including nested `d2l-form` elements.
116
116
  - **Note:** If validation succeeds, the form data will be aggregated and passed back to the caller via the `d2l-form-submit` event. It will not be submitted by the form itself.
117
+ - `resetValidation()`: Resets the validation errors. Note that this does not reset any form values. Daylight dialog components (e.g., `d2l-dialog`) will automatically run this method on close.
117
118
  - `async validate()`: Validates the form and any nested `d2l-form` elements without submitting even if validation succeeds for all elements. Returns a `Map` mapping from an element to the list of error messages associated with it.
118
119
  - **Note:** The return value will include elements and errors from both the root form and any nested descendant forms.
119
120
 
@@ -227,6 +227,18 @@ export const FormElementMixin = superclass => class extends LocalizeCoreElement(
227
227
  await this.updatedComplete;
228
228
  }
229
229
 
230
+ resetValidation() {
231
+ this.invalid = false;
232
+ this.validationError = null;
233
+ this._errors = [];
234
+
235
+ this.childErrors.forEach((_, ele) => {
236
+ if (!isCustomFormElement(ele)) return;
237
+ ele.resetValidation();
238
+ });
239
+ this.childErrors = new Map();
240
+ }
241
+
230
242
  setFormValue(formValue) {
231
243
  this.formValue = formValue;
232
244
  }
@@ -1,5 +1,6 @@
1
1
  import { css, html, LitElement } from 'lit';
2
2
  import { findFormElements, flattenMap, getFormElementData, isCustomFormElement, isNativeFormElement } from './form-helper.js';
3
+ import { findComposedAncestor } from '../../helpers/dom.js';
3
4
  import { FormMixin } from './form-mixin.js';
4
5
 
5
6
  /**
@@ -55,6 +56,12 @@ class Form extends FormMixin(LitElement) {
55
56
  this._isSubForm = false;
56
57
  }
57
58
 
59
+ firstUpdated(changedProperties) {
60
+ super.firstUpdated(changedProperties);
61
+
62
+ this._setupDialogValidationReset();
63
+ }
64
+
58
65
  render() {
59
66
  let errorSummary = null;
60
67
  if (this._isRootForm()) {
@@ -77,6 +84,26 @@ class Form extends FormMixin(LitElement) {
77
84
  this._submitData(submitter);
78
85
  }
79
86
 
87
+ resetValidation() {
88
+ const formElements = this._findFormElements();
89
+ for (const ele of formElements) {
90
+ if (this._hasSubForms(ele)) {
91
+ const forms = this._getSubForms(ele);
92
+ for (const form of forms) {
93
+ form.resetValidation();
94
+ }
95
+ } else {
96
+ if (isCustomFormElement(ele)) {
97
+ ele.resetValidation();
98
+ } else if (isNativeFormElement(ele)) {
99
+ this._displayValid(ele);
100
+ }
101
+ }
102
+ }
103
+ this._errors = new Map();
104
+ this._tooltips = new Map();
105
+ }
106
+
80
107
  async submit() {
81
108
  return this.requestSubmit(null);
82
109
  }
@@ -165,6 +192,21 @@ class Form extends FormMixin(LitElement) {
165
192
 
166
193
  }
167
194
 
195
+ _setupDialogValidationReset() {
196
+ const flag = window.D2L?.LP?.Web?.UI?.Flags.Flag('GAUD-6979-dialog-close-reset-validation', true) ?? true;
197
+ if (!flag) return;
198
+
199
+ const dialogAncestor = findComposedAncestor(
200
+ this,
201
+ node => node?._isDialogMixin
202
+ );
203
+ if (!dialogAncestor) return;
204
+
205
+ dialogAncestor.addEventListener('d2l-dialog-close', () => {
206
+ this.resetValidation();
207
+ });
208
+ }
209
+
168
210
  async _submitData(submitter) {
169
211
  this._dirty = false;
170
212
 
@@ -54,13 +54,13 @@ The `<d2l-input-checkbox>` element can be used to get a checkbox and optional vi
54
54
 
55
55
  | Property | Type | Description |
56
56
  |---|---|---|
57
- | `aria-label` | String | Set instead of placing label inside to hide the visible label |
57
+ | `aria-label` | String | Overrides the text in the `Default` slot for screenreader users |
58
58
  | `checked` | Boolean | Checked state |
59
- | `description` | String | A description to be added to the `input` for accessibility |
59
+ | `description` | String | Additional information communicated to screenreader users when focusing on the input |
60
60
  | `disabled` | Boolean | Disables the input |
61
61
  | `indeterminate` | Boolean | Sets checkbox to an indeterminate state |
62
62
  | `name` | String | Name of the input |
63
- | `not-tabbable` | Boolean | Sets `tabindex="-1"` on the checkbox |
63
+ | `not-tabbable` | Boolean | Sets `tabindex="-1"` on the checkbox. Note that an alternative method of focusing is necessary to implement if using this property. |
64
64
  | `value` | String | Value of the input |
65
65
 
66
66
  ### Events
@@ -75,18 +75,10 @@ checkbox.addEventListener('change', (e) => {
75
75
 
76
76
  ### Slots
77
77
 
78
+ * `default`: Primary text that will appear next to the input box and function as the label for the checkbox.
78
79
  * `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.
79
80
  <!-- docs: end hidden content -->
80
81
 
81
- ### Accessibility Properties
82
-
83
- To make your usage of `d2l-input-checkbox` accessible, use the following properties when applicable:
84
-
85
- | Attribute | Description |
86
- |---|---|
87
- | `aria-label` | Use when text on checkbox does not provide enough context |
88
- | `description` | Use when label on input does not provide enough context. |
89
-
90
82
  ### Methods
91
83
 
92
84
  - `simulateClick()`: useful for testing, it simulates the user clicking on the checkbox, which toggles the state of the checkbox and fires the `change` event
@@ -135,3 +127,9 @@ As an alternative to using the `<d2l-input-checkbox>` custom element, you can st
135
127
  </script>
136
128
  <d2l-my-checkbox-elem></d2l-my-checkbox-elem>
137
129
  ```
130
+
131
+ ## Accessibility
132
+
133
+ The `d2l-input-checkbox` component follows W3C's best practice recommendations for a [checkbox](https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/). This means that the component works in the following way:
134
+ - The `Space` key is used to select a focused checkbox (not the `Enter` key)
135
+ - The `aria-checked` state is set to `true`, `false` or `mixed` to represent if it's selected, unselected, or partially selected
@@ -69,7 +69,7 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
69
69
  static get properties() {
70
70
  return {
71
71
  /**
72
- * Use when text on checkbox does not provide enough context
72
+ * ACCESSIBILITY: Overrides the text in the `Default` slot for screenreader users
73
73
  * @type {string}
74
74
  */
75
75
  ariaLabel: { type: String, attribute: 'aria-label' },
@@ -79,7 +79,7 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
79
79
  */
80
80
  checked: { type: Boolean },
81
81
  /**
82
- * Additional information communicated in the aria-describedby on the input
82
+ * ACCESSIBILITY: Additional information communicated to screenreader users when focusing on the input
83
83
  * @type {string}
84
84
  */
85
85
  description: { type: String },
@@ -99,7 +99,7 @@ class InputCheckbox extends InputInlineHelpMixin(FocusMixin(SkeletonMixin(RtlMix
99
99
  */
100
100
  name: { type: String },
101
101
  /**
102
- * Sets "tabindex="-1"" on the checkbox
102
+ * ACCESSIBILITY: ADVANCED: Sets "tabindex="-1"" on the checkbox. Note that an alternative method of focusing is necessary to implement if using this property.
103
103
  * @type {boolean}
104
104
  */
105
105
  notTabbable: { type: Boolean, attribute: 'not-tabbable' },
@@ -4934,12 +4934,12 @@
4934
4934
  "attributes": [
4935
4935
  {
4936
4936
  "name": "aria-label",
4937
- "description": "Use when text on checkbox does not provide enough context",
4937
+ "description": "ACCESSIBILITY: Overrides the text in the `Default` slot for screenreader users",
4938
4938
  "type": "string"
4939
4939
  },
4940
4940
  {
4941
4941
  "name": "description",
4942
- "description": "Additional information communicated in the aria-describedby on the input",
4942
+ "description": "ACCESSIBILITY: Additional information communicated to screenreader users when focusing on the input",
4943
4943
  "type": "string"
4944
4944
  },
4945
4945
  {
@@ -4968,7 +4968,7 @@
4968
4968
  },
4969
4969
  {
4970
4970
  "name": "not-tabbable",
4971
- "description": "Sets \"tabindex=\"-1\"\" on the checkbox",
4971
+ "description": "ACCESSIBILITY: ADVANCED: Sets \"tabindex=\"-1\"\" on the checkbox. Note that an alternative method of focusing is necessary to implement if using this property.",
4972
4972
  "type": "boolean",
4973
4973
  "default": "false"
4974
4974
  },
@@ -4988,13 +4988,13 @@
4988
4988
  {
4989
4989
  "name": "ariaLabel",
4990
4990
  "attribute": "aria-label",
4991
- "description": "Use when text on checkbox does not provide enough context",
4991
+ "description": "ACCESSIBILITY: Overrides the text in the `Default` slot for screenreader users",
4992
4992
  "type": "string"
4993
4993
  },
4994
4994
  {
4995
4995
  "name": "description",
4996
4996
  "attribute": "description",
4997
- "description": "Additional information communicated in the aria-describedby on the input",
4997
+ "description": "ACCESSIBILITY: Additional information communicated to screenreader users when focusing on the input",
4998
4998
  "type": "string"
4999
4999
  },
5000
5000
  {
@@ -5028,7 +5028,7 @@
5028
5028
  {
5029
5029
  "name": "notTabbable",
5030
5030
  "attribute": "not-tabbable",
5031
- "description": "Sets \"tabindex=\"-1\"\" on the checkbox",
5031
+ "description": "ACCESSIBILITY: ADVANCED: Sets \"tabindex=\"-1\"\" on the checkbox. Note that an alternative method of focusing is necessary to implement if using this property.",
5032
5032
  "type": "boolean",
5033
5033
  "default": "false"
5034
5034
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.42.0",
3
+ "version": "3.44.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",