@brightspace-ui/core 3.42.0 → 3.44.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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",