@brightspace-ui/core 3.126.4 → 3.127.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.
- package/components/form/README.md +1 -1
- package/components/inputs/README.md +4 -84
- package/components/inputs/docs/form-layout-validation.md +146 -0
- package/components/inputs/docs/input-select-styles.md +33 -31
- package/components/inputs/docs/input-text.md +4 -11
- package/components/inputs/docs/styling-native-inputs.md +11 -0
- package/components/inputs/input-fieldset.js +1 -0
- package/custom-elements.json +4 -0
- package/lang/mi.js +9 -9
- package/package.json +1 -1
- package/components/form/docs/form.md +0 -168
@@ -6,7 +6,7 @@ There are several components and mixins available to help make working with form
|
|
6
6
|
|
7
7
|
Much like a native `<form>` element, `<d2l-form>` groups nested form elements together and controls how their data is validated and submitted. Unlike native `<form>`s, it supports our custom form elements.
|
8
8
|
|
9
|
-
|
9
|
+
See: [Form Layout and Validation](../inputs/docs/form-layout-validation.md)
|
10
10
|
|
11
11
|
## Custom Elements in Forms
|
12
12
|
|
@@ -9,88 +9,8 @@ There are various input components available:
|
|
9
9
|
- [Radio Inputs (input-radio-*)](docs/input-radio.md)
|
10
10
|
- [Search (input-search)](docs/input-search.md)
|
11
11
|
- [Select Lists (input-select-styles)](docs/input-select-styles.md)
|
12
|
-
- [Text (input-text, input-
|
12
|
+
- [Text (input-text, input-textarea)](docs/input-text.md)
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
Groups of inputs (like checkboxes or radios) should be wrapped in a `<fieldset>` which can have label styles applied to it.
|
19
|
-
|
20
|
-
### Visible labels using the `<label>` element
|
21
|
-
|
22
|
-
Import the label styles and include them in your component:
|
23
|
-
|
24
|
-
```javascript
|
25
|
-
import { inputLabelStyles } from '@brightspace-ui/core/components/inputs/input-label-styles.js';
|
26
|
-
|
27
|
-
class MyElem extends LitElement {
|
28
|
-
|
29
|
-
static get styles() {
|
30
|
-
return inputLabelStyles;
|
31
|
-
}
|
32
|
-
|
33
|
-
}
|
34
|
-
```
|
35
|
-
|
36
|
-
Label styles are then applied using the `d2l-input-label` CSS class.
|
37
|
-
|
38
|
-
Wrap the input in a `<label>` element and apply the styles to a nested `<span>` element:
|
39
|
-
|
40
|
-
```html
|
41
|
-
<label>
|
42
|
-
<span class="d2l-input-label">City</span>
|
43
|
-
<select>...</select>
|
44
|
-
</label>
|
45
|
-
```
|
46
|
-
|
47
|
-
Alternately, associate the `<label>` with the input using the `for` and `id` attributes and apply the styles to the label directly:
|
48
|
-
|
49
|
-
```html
|
50
|
-
<label for="myInput" class="d2l-input-label">City</label>
|
51
|
-
<select id="myInput">...</select>
|
52
|
-
```
|
53
|
-
|
54
|
-
For required inputs, add the `d2l-input-label-required` CSS class to the label to get a visual indicator. Don't forget to add `aria-required="true"` to the input so that assistive technology is aware as well.
|
55
|
-
|
56
|
-
```html
|
57
|
-
<label for="myInput" class="d2l-input-label d2l-input-label-required">City</label>
|
58
|
-
<select id="myInput" aria-required="true">...</select>
|
59
|
-
```
|
60
|
-
|
61
|
-
### Hidden labels
|
62
|
-
|
63
|
-
If you wish to visually hide the label, use the `aria-label` attribute on your input instead:
|
64
|
-
|
65
|
-
```html
|
66
|
-
<select aria-label="City">...</select>
|
67
|
-
```
|
68
|
-
|
69
|
-
### Grouping inputs with `<fieldset>`
|
70
|
-
|
71
|
-
When a page contains multiple inputs which are related (for example to form an address), wrap the inputs with `<fieldset>` and `<legend>` elements. Then apply the `d2l-input-label-fieldset` and `d2l-input-label` CSS classes to the `<fieldset>` and `<legend>` elements respectively.
|
72
|
-
|
73
|
-
```html
|
74
|
-
<fieldset class="d2l-input-label-fieldset">
|
75
|
-
<legend class="d2l-input-label">Shipping Address</legend>
|
76
|
-
<!-- set of related inputs go here -->
|
77
|
-
</fieldset>
|
78
|
-
```
|
79
|
-
|
80
|
-
Alternately, the `<d2l-input-fieldset>` component can accomplish this for you. The legend can be visually hidden by applying the `label-hidden` attribute to the component.
|
81
|
-
|
82
|
-
```html
|
83
|
-
<script type="module">
|
84
|
-
import '@brightspace-ui/core/components/inputs/input-fieldset.js';
|
85
|
-
</script>
|
86
|
-
<d2l-input-fieldset label="Shipping Address">
|
87
|
-
<!-- set of related inputs go here -->
|
88
|
-
</d2l-input-fieldset>
|
89
|
-
```
|
90
|
-
|
91
|
-
## Future Enhancements
|
92
|
-
|
93
|
-
- Color input with contrast analysis
|
94
|
-
- Auto-growing textareas
|
95
|
-
|
96
|
-
Looking for an enhancement not listed here? Create a GitHub issue!
|
14
|
+
See also:
|
15
|
+
- [Form Layout and Validation](docs/form-layout-validation.md)
|
16
|
+
- [FormElementMixin](../form/docs/form-element-mixin.md)
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# Form Layout & Validation
|
2
|
+
|
3
|
+
There are several components available for working with collections of inputs. Inputs can be validated and submitted in a form, visually layed out using an input group, and related to each other semantically using an input fieldset.
|
4
|
+
|
5
|
+
<!-- docs: demo display:block -->
|
6
|
+
```html
|
7
|
+
<script type="module">
|
8
|
+
import '@brightspace-ui/core/components/button/button.js';
|
9
|
+
import '@brightspace-ui/core/components/form/form.js';
|
10
|
+
import '@brightspace-ui/core/components/inputs/input-fieldset.js';
|
11
|
+
import '@brightspace-ui/core/components/inputs/input-group.js';
|
12
|
+
import '@brightspace-ui/core/components/inputs/input-text.js';
|
13
|
+
|
14
|
+
const form = document.querySelector('d2l-form');
|
15
|
+
document.querySelector('d2l-button').addEventListener('click', () => form.submit());
|
16
|
+
</script>
|
17
|
+
<d2l-form>
|
18
|
+
<d2l-input-group>
|
19
|
+
<d2l-input-text label="Name" required style="max-width: 200px;"></d2l-input-text>
|
20
|
+
<d2l-input-fieldset label="Address" label-style="heading">
|
21
|
+
<d2l-input-group>
|
22
|
+
<d2l-input-text label="Street" style="max-width: 350px;"></d2l-input-text>
|
23
|
+
<d2l-input-text label="City" style="max-width: 200px;"></d2l-input-text>
|
24
|
+
</d2l-input-group>
|
25
|
+
</d2l-input-fieldset>
|
26
|
+
</d2l-input-group>
|
27
|
+
<d2l-button primary style="margin-top: 1rem;">Submit</d2l-button>
|
28
|
+
</d2l-form>
|
29
|
+
```
|
30
|
+
|
31
|
+
## Form [d2l-form]
|
32
|
+
|
33
|
+
The `<d2l-form>` component is used to wrap inputs which are then validated and submitted together.
|
34
|
+
|
35
|
+
Unlike the standard HTML `<form>` element, `<d2l-form>` supports validating and submitting custom elements. It also displays an aggregated summary of validation errors at the top of the form.
|
36
|
+
|
37
|
+
<!-- docs: demo code properties name:d2l-form sandboxTitle:'Form' display:block -->
|
38
|
+
```html
|
39
|
+
<script type="module">
|
40
|
+
import '@brightspace-ui/core/components/button/button.js';
|
41
|
+
import '@brightspace-ui/core/components/form/form.js';
|
42
|
+
import '@brightspace-ui/core/components/inputs/input-group.js';
|
43
|
+
import '@brightspace-ui/core/components/inputs/input-text.js';
|
44
|
+
import '@brightspace-ui/core/components/inputs/input-textarea.js';
|
45
|
+
|
46
|
+
const form = document.querySelector('d2l-form');
|
47
|
+
form.addEventListener('d2l-form-submit', e => {
|
48
|
+
const data = e.detail.formData;
|
49
|
+
console.log(`name: "${data.name}"`);
|
50
|
+
console.log(`description: "${data.description}"`);
|
51
|
+
});
|
52
|
+
document
|
53
|
+
.querySelector('d2l-button')
|
54
|
+
.addEventListener('click', () => form.submit());
|
55
|
+
</script>
|
56
|
+
<d2l-form>
|
57
|
+
<d2l-input-group>
|
58
|
+
<d2l-input-text label="Name" required style="max-width: 200px;"></d2l-input-text>
|
59
|
+
<d2l-input-textarea label="Description" rows="3" style="max-width: 300px;"></d2l-input-textarea>
|
60
|
+
</d2l-input-group>
|
61
|
+
<d2l-button primary style="margin-top: 1rem;">Submit</d2l-button>
|
62
|
+
</d2l-form>
|
63
|
+
```
|
64
|
+
|
65
|
+
<!-- docs: start hidden content -->
|
66
|
+
### Properties
|
67
|
+
|
68
|
+
| Property | Type | Description |
|
69
|
+
|---|---|---|
|
70
|
+
| `no-nesting` | Boolean, default: `false` | Indicates that the form should opt-out of nesting.<br><br>This means that it will not be submitted or validated if an ancestor form is submitted or validated. However, directly submitting or validating a form with `no-nesting` will still trigger submission and validation for its descendant forms unless they also opt-out using `no-nesting`. |
|
71
|
+
|
72
|
+
### Events
|
73
|
+
- `d2l-form-submit`: Dispatched when the form is submitted. The form data can be obtained from the `detail`'s `formData` property.
|
74
|
+
- `d2l-form-invalid`: Dispatched when the form fails validation. The error map can be obtained from the `detail`'s `errors` property.
|
75
|
+
- `d2l-form-dirty`: Dispatched whenever any form element fires an `input` or `change` event. Can be used to track whether the form is dirty or not.
|
76
|
+
<!-- docs: end hidden content -->
|
77
|
+
|
78
|
+
### Submitting and Handling Form Submissions
|
79
|
+
|
80
|
+
A typical setup will involve listening for the `d2l-form-submit` event on the `<d2l-form>` and calling the form's `submit()` API to trigger the submission.
|
81
|
+
|
82
|
+
Before submission can proceed, all inputs in the form are validated.
|
83
|
+
|
84
|
+
If validation succeeds, the form data will be aggregated and provided to the `d2l-form-submit` event's `detail.formData`. If validation fails, a summary of the errors will be displayed to the user.
|
85
|
+
|
86
|
+
### Nested Forms
|
87
|
+
|
88
|
+
By default, `<d2l-form>` will discover nested descendant `<d2l-form>` elements and include their inputs in its validation and submission process. To opt a form out of this behaviour, set the `no-nesting` attribute.
|
89
|
+
|
90
|
+
When forms are nested, validation is _**atomic**_. Validation will only succeed if validation succeeds for the root form and all nested forms. If any form fails validation, none of them will be submitted.
|
91
|
+
|
92
|
+
Alternatively, nested form submission is _**independent**_. As a result, when nested forms all pass validation, each `<d2l-form>` will fire its own `d2l-form-submit` event with the data associated with that form. This avoids potential collisions when inputs in different forms share the same `name`.
|
93
|
+
|
94
|
+
## Input Group [d2l-input-group]
|
95
|
+
|
96
|
+
When more than one input is displayed together, a `<d2l-input-group>` can be used to apply a consistent gap to elements in its slot, as well as appropriate space between itself and a parent `<d2l-form>`'s validation errors.
|
97
|
+
|
98
|
+
<!-- docs: demo code display:block name:d2l-input-group sandboxTitle:'Input Group' -->
|
99
|
+
```html
|
100
|
+
<script type="module">
|
101
|
+
import '@brightspace-ui/core/components/inputs/input-group.js';
|
102
|
+
import '@brightspace-ui/core/components/inputs/input-text.js';
|
103
|
+
import '@brightspace-ui/core/components/inputs/input-textarea.js';
|
104
|
+
</script>
|
105
|
+
<d2l-input-group>
|
106
|
+
<d2l-input-text label="Name" style="max-width: 200px;"></d2l-input-text>
|
107
|
+
<d2l-input-textarea label="Description" rows="3" style="max-width: 300px;"></d2l-input-textarea>
|
108
|
+
</d2l-input-group>
|
109
|
+
```
|
110
|
+
|
111
|
+
## Input Fieldset [d2l-input-fieldset]
|
112
|
+
|
113
|
+
When inputs are related to each other (for example multiple inputs which together form a mailing address), a `<d2l-input-fieldset>` is used to provide that additional context.
|
114
|
+
|
115
|
+
Within the fieldset, `<d2l-input-group>` can still be used to provide a consistent gap between the inputs.
|
116
|
+
|
117
|
+
<!-- docs: demo code properties display:block name:d2l-input-fieldset sandboxTitle:'Input Fieldset' -->
|
118
|
+
```html
|
119
|
+
<script type="module">
|
120
|
+
import '@brightspace-ui/core/components/inputs/input-fieldset.js';
|
121
|
+
import '@brightspace-ui/core/components/inputs/input-group.js';
|
122
|
+
import '@brightspace-ui/core/components/inputs/input-text.js';
|
123
|
+
</script>
|
124
|
+
<d2l-input-fieldset label="Contact Information" label-style="heading">
|
125
|
+
<d2l-input-group>
|
126
|
+
<d2l-input-text type="tel" label="Phone" style="max-width: 200px;"></d2l-input-text>
|
127
|
+
<d2l-input-text type="email" label="Email" style="max-width: 250px;"></d2l-input-text>
|
128
|
+
</d2l-input-group>
|
129
|
+
</d2l-input-fieldset>
|
130
|
+
```
|
131
|
+
|
132
|
+
<!-- docs: start hidden content -->
|
133
|
+
### Properties
|
134
|
+
|
135
|
+
| Property | Type | Description |
|
136
|
+
|---|---|---|
|
137
|
+
| `label` | String, required | Label for the fieldset
|
138
|
+
| `label-hidden` | Boolean | Hides the label visually |
|
139
|
+
| `label-style` | Boolean | Style of the fieldset label |
|
140
|
+
| `required` | Boolean | Indicates that a value is required for inputs in the fieldset |
|
141
|
+
|
142
|
+
### Slots
|
143
|
+
|
144
|
+
* `Default`: Related input components
|
145
|
+
* `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.
|
146
|
+
<!-- docs: end hidden content -->
|
@@ -15,7 +15,7 @@ A Select List allows the user to select a single option out of a relatively larg
|
|
15
15
|
}
|
16
16
|
render() {
|
17
17
|
return html`
|
18
|
-
<select class="d2l-input-select">
|
18
|
+
<select class="d2l-input-select" aria-label="Options">
|
19
19
|
<option>Option 1</option>
|
20
20
|
<option>Option 2</option>
|
21
21
|
</select>
|
@@ -32,23 +32,22 @@ A Select List allows the user to select a single option out of a relatively larg
|
|
32
32
|
<!-- docs: start best practices -->
|
33
33
|
<!-- docs: start dos -->
|
34
34
|
* Use to allow the user to select a single option from a relatively large list of options
|
35
|
-
* Use to save space / reduce the visual prominence of an exclusive selection option (instead of a choice from 8 radio
|
36
|
-
* Use a Select List to tuck away non-critical options, or options where the default selection is likely to be the most desirable
|
35
|
+
* Use to save space / reduce the visual prominence of an exclusive selection option (instead of a choice from 8 radio inputs)
|
36
|
+
* Use a Select List to tuck away non-critical options, or options where the default selection is likely to be the most desirable
|
37
37
|
<!-- docs: end dos -->
|
38
38
|
|
39
39
|
<!-- docs: start donts -->
|
40
|
-
* Don't use if your options are more than 1-2 words. The cognitive load of comparing options in a Select List is relatively high
|
41
|
-
* Select Lists show the available options offscreen – be careful if the selections you are asking the user to make are on the critical path – see [Dropdowns should be the UI of last resort](https://www.lukew.com/ff/entry.asp?1950) and be careful about your selection
|
42
|
-
* Select Lists are form controls, and should not submit data or
|
43
|
-
|
44
|
-
* Don't use
|
45
|
-
* Don't use for numeric input – a text field with type “number” or a date-picker is much easier to use control
|
40
|
+
* Don't use if your options are more than 1-2 words. The cognitive load of comparing options in a Select List is relatively high.
|
41
|
+
* Select Lists show the available options offscreen – be careful if the selections you are asking the user to make are on the critical path – see [Dropdowns should be the UI of last resort](https://www.lukew.com/ff/entry.asp?1950) and be careful about your selection
|
42
|
+
* Select Lists are form controls, and should not submit data or execute an action without an explicit submit action. Toggling progressive disclosure is OK.
|
43
|
+
* Don't use prompt text in place of a Select List field label – it’s harder to scan and negatively impacts accessibility
|
44
|
+
* Don't use for numeric input – a `<d2l-input-number>` or a date input is much easier to use
|
46
45
|
<!-- docs: end donts -->
|
47
46
|
<!-- docs: end best practices -->
|
48
47
|
|
49
48
|
## Applying styles to native select elements
|
50
49
|
|
51
|
-
Native `<select>` elements can be styled by importing `input-select-styles.js` into your
|
50
|
+
Native `<select>` elements can be styled by importing `input-select-styles.js` into your Lit element and applying the `d2l-input-select` CSS class.
|
52
51
|
|
53
52
|
The styles support the pseudo-classes `disabled`, `focus`, and `hover`, as well as the `aria-invalid` attribute.
|
54
53
|
|
@@ -63,14 +62,14 @@ When applying styles to the native element, we also recommend using the [`Skelet
|
|
63
62
|
|
64
63
|
class TestInputSelect extends SkeletonMixin(LitElement) {
|
65
64
|
static get styles() {
|
66
|
-
return [
|
65
|
+
return [super.styles, selectStyles];
|
67
66
|
}
|
68
67
|
|
69
68
|
render() {
|
70
69
|
return html`
|
71
70
|
<div class="d2l-skeletize">
|
72
71
|
<select
|
73
|
-
aria-label="
|
72
|
+
aria-label="Dinosaur"
|
74
73
|
class="d2l-input-select">
|
75
74
|
<option>Tyrannosaurus</option>
|
76
75
|
<option>Velociraptor</option>
|
@@ -86,34 +85,37 @@ When applying styles to the native element, we also recommend using the [`Skelet
|
|
86
85
|
<d2l-test-input-select></d2l-test-input-select>
|
87
86
|
```
|
88
87
|
|
89
|
-
|
88
|
+
## Labelling
|
90
89
|
|
91
|
-
|
90
|
+
The `aria-label` attribute can be used in places where a non-visible label is desired.
|
92
91
|
|
93
|
-
|
92
|
+
For a visible label, import the label styles and include them in your component's `styles`. Wrap the `<select>` in a `<label>` element and apply the styles by adding the `d2l-input-label` CSS class to a nested `<span>` element:
|
93
|
+
|
94
|
+
<!-- docs: demo code -->
|
94
95
|
```html
|
95
96
|
<script type="module">
|
96
97
|
import { html, LitElement } from 'lit';
|
97
98
|
import { selectStyles } from '@brightspace-ui/core/components/inputs/input-select-styles.js';
|
99
|
+
import { inputLabelStyles } from '@brightspace-ui/core/components/inputs/input-label-styles.js';
|
98
100
|
|
99
101
|
class TestInputSelect extends LitElement {
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
103
|
+
static get styles() {
|
104
|
+
return [inputLabelStyles, selectStyles];
|
105
|
+
}
|
104
106
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
107
|
+
render() {
|
108
|
+
return html`
|
109
|
+
<label>
|
110
|
+
<span class="d2l-input-label">Dinosaur</span>
|
111
|
+
<select class="d2l-input-select">
|
112
|
+
<option>Tyrannosaurus</option>
|
113
|
+
<option>Velociraptor</option>
|
114
|
+
<option>Deinonychus</option>
|
115
|
+
</select>
|
116
|
+
</label>
|
117
|
+
`;
|
118
|
+
}
|
117
119
|
|
118
120
|
}
|
119
121
|
customElements.define('d2l-test-input-select', TestInputSelect);
|
@@ -126,5 +128,5 @@ Use the [`aria-invalid`](https://developer.mozilla.org/en-US/docs/Web/Accessibil
|
|
126
128
|
- Due to applying styles based on a CSS class rather than being its own component, the accessibility provided by `selectStyles` comes purely in the way of following the guidelines for [contrast](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) and [focus](https://www.w3.org/WAI/WCAG21/Understanding/focus-visible.html)
|
127
129
|
- There are several things that can be done to make sure your `select` component is accessible, including:
|
128
130
|
- Following the W3C [Combobox](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) pattern
|
129
|
-
- Using either the `aria-label` or `aria-labelledby` to appropriately assign a label to your component
|
131
|
+
- Using either the `aria-label` attribute, a wrapper `<label>` element or `<label>` with `aria-labelledby` to appropriately assign a label to your component
|
130
132
|
- Using `label` for `optgroup` if you choose to use that element within the select element, so that it can be read out to screenreaders
|
@@ -2,24 +2,17 @@
|
|
2
2
|
|
3
3
|
Text inputs allow users to input, edit, and select text.
|
4
4
|
|
5
|
-
<!-- docs: demo -->
|
5
|
+
<!-- docs: demo display:block -->
|
6
6
|
```html
|
7
7
|
<script type="module">
|
8
|
+
import '@brightspace-ui/core/components/inputs/input-group.js';
|
8
9
|
import '@brightspace-ui/core/components/inputs/input-text.js';
|
9
10
|
import '@brightspace-ui/core/components/inputs/input-textarea.js';
|
10
11
|
</script>
|
11
|
-
<
|
12
|
-
div {
|
13
|
-
width: 100%;
|
14
|
-
}
|
15
|
-
d2l-input-text {
|
16
|
-
padding-bottom: 1rem;
|
17
|
-
}
|
18
|
-
</style>
|
19
|
-
<div>
|
12
|
+
<d2l-input-group>
|
20
13
|
<d2l-input-text label="Name"></d2l-input-text>
|
21
14
|
<d2l-input-textarea label="Description" max-rows="4" rows="4"></d2l-input-textarea>
|
22
|
-
</
|
15
|
+
</d2l-input-group>
|
23
16
|
```
|
24
17
|
|
25
18
|
## Best Practices
|
@@ -203,3 +203,14 @@ Import `input-styles.js` and apply the `d2l-input` CSS class to the native `<te
|
|
203
203
|
</script>
|
204
204
|
<d2l-my-textarea-input-elem></d2l-my-textarea-input-elem>
|
205
205
|
```
|
206
|
+
|
207
|
+
### Grouping inputs with `<fieldset>`
|
208
|
+
|
209
|
+
When a page contains multiple inputs which are related, wrap the inputs with `<fieldset>` and `<legend>` elements. Then apply the `d2l-input-label-fieldset` and `d2l-input-label` CSS classes to the `<fieldset>` and `<legend>` elements respectively.
|
210
|
+
|
211
|
+
```html
|
212
|
+
<fieldset class="d2l-input-label-fieldset">
|
213
|
+
<legend class="d2l-input-label">Shipping Address</legend>
|
214
|
+
<!-- set of related inputs go here -->
|
215
|
+
</fieldset>
|
216
|
+
```
|
@@ -12,6 +12,7 @@ import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
|
|
12
12
|
/**
|
13
13
|
* A component wrapper to be used when a page contains multiple inputs which are related (for example to form an address) to wrap those related inputs.
|
14
14
|
* @slot - Related input components
|
15
|
+
* @slot inline-help - Help text that will appear below the fieldset. Use this only when other helpful cues are not sufficient, such as a carefully-worded label.
|
15
16
|
*/
|
16
17
|
class InputFieldset extends PropertyRequiredMixin(InputInlineHelpMixin(SkeletonMixin(LitElement))) {
|
17
18
|
|
package/custom-elements.json
CHANGED
@@ -6463,6 +6463,10 @@
|
|
6463
6463
|
{
|
6464
6464
|
"name": "",
|
6465
6465
|
"description": "Related input components"
|
6466
|
+
},
|
6467
|
+
{
|
6468
|
+
"name": "inline-help",
|
6469
|
+
"description": "Help text that will appear below the fieldset. Use this only when other helpful cues are not sufficient, such as a carefully-worded label."
|
6466
6470
|
}
|
6467
6471
|
]
|
6468
6472
|
},
|
package/lang/mi.js
CHANGED
@@ -3,7 +3,7 @@ export default {
|
|
3
3
|
"components.breadcrumbs.breadcrumb": "Pānui",
|
4
4
|
"components.button-add.addItem": "Tāpiri Tūemi",
|
5
5
|
"components.button-split.otherOptions": "Other Options",
|
6
|
-
"components.calendar.hasEvents": "He
|
6
|
+
"components.calendar.hasEvents": "He takatu ēnei.",
|
7
7
|
"components.calendar.notSelected": "Kāore i tīpakona.",
|
8
8
|
"components.calendar.selected": "I tīpakona.",
|
9
9
|
"components.calendar.show": "Whakaatu {month}",
|
@@ -33,10 +33,10 @@ export default {
|
|
33
33
|
"components.filter-dimension-set-date-text-value.textMonths": "Ngā marama {num} whakamutunga",
|
34
34
|
"components.filter-dimension-set-date-time-range-value.label": "{text}, whakaroha hei kōwhiri i ngā rā",
|
35
35
|
"components.filter-dimension-set-date-time-range-value.valueTextRange": "{startValue} ki {endValue}",
|
36
|
-
"components.filter-dimension-set-date-time-range-value.valueTextRangeStartOnly": "
|
37
|
-
"components.filter-dimension-set-date-time-range-value.valueTextRangeEndOnly": "
|
36
|
+
"components.filter-dimension-set-date-time-range-value.valueTextRangeStartOnly": "I muri o {startValue}",
|
37
|
+
"components.filter-dimension-set-date-time-range-value.valueTextRangeEndOnly": "I mua i {endValue}",
|
38
38
|
"components.filter-dimension-set-date-time-range-value.text": "Awhe rā ritenga",
|
39
|
-
"components.form-element.defaultError": "{label}
|
39
|
+
"components.form-element.defaultError": "Kāore i te whai mana te {label}",
|
40
40
|
"components.form-element.defaultFieldLabel": "Āpure",
|
41
41
|
"components.form-element.input.email.typeMismatch": "Kāore te īmēra i te tika",
|
42
42
|
"components.form-element.input.number.rangeError": "{minExclusive, select, true {{maxExclusive, select, true {Number me nui ake i te {min} me iti iho i te {max}.} other {Number me nui ake i te {min} me iti iho rānei i te ōrite ki {max}.}}} other {{maxExclusive, select, true {Number me nui ake, ōrite rānei ki {min} and less than {max}.} other {Number me nui ake, ōrite rānei ki {min} me iti iho, ōrite rānei ki {max}.}}}}",
|
@@ -44,7 +44,7 @@ export default {
|
|
44
44
|
"components.form-element.input.number.rangeUnderflow": "{minExclusive, select, true {Number must me nui ake i te {min}.} other {Number me nui ake, ōrite rānei ki {min}.}}",
|
45
45
|
"components.form-element.input.text.tooShort": "Me noho te {label} kia {minlength} ngā pūāhua",
|
46
46
|
"components.form-element.input.url.typeMismatch": "Kāore te URL i te tika",
|
47
|
-
"components.form-element.valueMissing": "{label}
|
47
|
+
"components.form-element.valueMissing": "E hiahiatia ana te {label}",
|
48
48
|
"components.form-error-summary.errorSummary": "{count, plural, one {Tērā {count} hapa i kitea i te mōhiohio i tukuna e koe} other {I te {count} ngā hapa i kitea i te mōhiohio i tukuna e koe}}",
|
49
49
|
"components.form-error-summary.text": "Takahuri taipitopito hapa",
|
50
50
|
"components.input-color.backgroundColor": "Tae papamuri",
|
@@ -70,9 +70,9 @@ export default {
|
|
70
70
|
"components.input-date.errorOutsideRange": "Me noho te rā ki waenga i te {minDate} me te {maxDate}",
|
71
71
|
"components.input-date.openInstructions": "Whakamahia te hōputu rā {format}. Pere whakararo, pēhi rānei i te tāuru hei uru ki te pae-iti.",
|
72
72
|
"components.input-date.now": "Ināianei",
|
73
|
-
"components.input-date.revert": "{label}
|
73
|
+
"components.input-date.revert": "Kua hokia te {label} ki te uara tōmua.",
|
74
74
|
"components.input-date.today": "Āianei",
|
75
|
-
"components.input-date.useDateFormat": "
|
75
|
+
"components.input-date.useDateFormat": "Whakamahia te hōputu rā {format}.",
|
76
76
|
"components.input-number.hintInteger": "Ka whakaae anake tēnei āpure ki ngā uara tau tōpū (kāore he ira)",
|
77
77
|
"components.input-number.hintDecimalDuplicate": "He ira kē kei tēnei tau",
|
78
78
|
"components.input-number.hintDecimalIncorrectComma": "Hei tāpiri i tētahi ira whakamahi i te piko \",\" pūāhua",
|
@@ -112,8 +112,8 @@ export default {
|
|
112
112
|
"components.pageable.info": "{count, plural, one {{countFormatted} Tūemi} other {{countFormatted} Ngā tūemi}}",
|
113
113
|
"components.pageable.info-with-total": "{totalCount, plural, one {{countFormatted} o {totalCountFormatted} Tūemi} other {{countFormatted} o {totalCountFormatted} Ngā tūemi}}",
|
114
114
|
"components.pager-load-more.status-loading": "Uta ana i ētahi atu tūemi",
|
115
|
-
"components.selection.action-max-hint": "{count, plural, one {
|
116
|
-
"components.selection.action-required-hint": "
|
115
|
+
"components.selection.action-max-hint": "{count, plural, one {Kua whakakorehia ina neke atu i te {countFormatted} o ngā tūemi i tīpakohia} other {Kua whakakorehia ina neke atu i te {countFormatted} o ngā tūemi i tīpakohia}}",
|
116
|
+
"components.selection.action-required-hint": "Tīpakohia tētahi tūemi hei whakahaere i tēnei mahi",
|
117
117
|
"components.selection.select-all": "Tīpako Katoa",
|
118
118
|
"components.selection.select-all-items": "Tīpakohia Ngā Tūemi {count} Katoa",
|
119
119
|
"components.selection.selected": "{count} kua tīpakohia",
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@brightspace-ui/core",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.127.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",
|
@@ -1,168 +0,0 @@
|
|
1
|
-
# Form [d2l-form]
|
2
|
-
|
3
|
-
<!-- docs: demo -->
|
4
|
-
```html
|
5
|
-
<script type="module">
|
6
|
-
import '@brightspace-ui/core/components/button/button.js';
|
7
|
-
import '@brightspace-ui/core/components/form/form.js';
|
8
|
-
import '@brightspace-ui/core/components/inputs/input-text.js';
|
9
|
-
import '@brightspace-ui/core/components/inputs/input-textarea.js';
|
10
|
-
|
11
|
-
const button = document.querySelector('d2l-button');
|
12
|
-
const form = document.querySelector('d2l-form#root');
|
13
|
-
button.addEventListener('click', () => {
|
14
|
-
form.submit();
|
15
|
-
});
|
16
|
-
</script>
|
17
|
-
<style>
|
18
|
-
.d2l-form-demo-container {
|
19
|
-
margin-bottom: 10px;
|
20
|
-
}
|
21
|
-
</style>
|
22
|
-
<d2l-form id="root" @d2l-form-submit=${this._onRootSubmit} style="width: 100%;">
|
23
|
-
<div class="d2l-form-demo-split-container">
|
24
|
-
<d2l-form class="d2l-form-demo-main" @d2l-form-submit=${this._onMainSubmit}>
|
25
|
-
<div class="d2l-form-demo-container">
|
26
|
-
<d2l-input-text label="Email" name="email" type="email"></d2l-input-text>
|
27
|
-
</div>
|
28
|
-
<div class="d2l-form-demo-container">
|
29
|
-
<d2l-input-textarea label="Description" name="description" rows="2" max-rows="2" required></d2l-input-textarea>
|
30
|
-
</div>
|
31
|
-
</d2l-form>
|
32
|
-
</div>
|
33
|
-
<d2l-button primary>Save</d2l-button>
|
34
|
-
</d2l-form>
|
35
|
-
```
|
36
|
-
|
37
|
-
The `d2l-form` component can be used to build sections containing interactive controls that are validated and submitted as a group.
|
38
|
-
|
39
|
-
It differs from the native HTML `form` element in 4 ways:
|
40
|
-
1. It supports custom form elements made using the [`FormElementMixin`](./form-element-mixin.md) in addition to native form elements like `input`, `select` and `textarea`.
|
41
|
-
1. Upon validation, it will display an error summary that contains error messages for any elements that failed validation.
|
42
|
-
1. `d2l-form` elements can be nested. If a parent form is validated or submitted it will also trigger the corresponding action for descendent `d2l-form`s unless they explicitly opt-out using `no-nesting`. This means that a `d2l-form` will only pass validation if it and all of its nested descendants pass validation.
|
43
|
-
1. Submission is not handled directly by `d2l-form`. Instead, all form data will be aggregated and passed back to the caller via an event. The caller is then responsible for submitting the data.
|
44
|
-
|
45
|
-
<!-- docs: demo code properties name:d2l-form sandboxTitle:'Form' autoSize:false display:block size:large -->
|
46
|
-
```html
|
47
|
-
<script type="module">
|
48
|
-
import '@brightspace-ui/core/components/form/form.js';
|
49
|
-
import '@brightspace-ui/core/components/inputs/input-text.js';
|
50
|
-
|
51
|
-
const button = document.querySelector('button');
|
52
|
-
const form = document.querySelector('d2l-form#root');
|
53
|
-
button.addEventListener('click', () => {
|
54
|
-
form.submit();
|
55
|
-
});
|
56
|
-
|
57
|
-
const formA = document.querySelector('d2l-form#a');
|
58
|
-
const formB = document.querySelector('d2l-form#b');
|
59
|
-
|
60
|
-
function handleSubmission(e) {
|
61
|
-
const { formData } = e.detail;
|
62
|
-
console.log('Form ' + e.target.id + ' submission data ' + JSON.stringify(formData));
|
63
|
-
}
|
64
|
-
form.addEventListener('d2l-form-submit', (e) => handleSubmission(e));
|
65
|
-
formA.addEventListener('d2l-form-submit', (e) => handleSubmission(e));
|
66
|
-
formB.addEventListener('d2l-form-submit', (e) => handleSubmission(e));
|
67
|
-
</script>
|
68
|
-
<!-- docs: start hidden content -->
|
69
|
-
<style>
|
70
|
-
d2l-input-text {
|
71
|
-
padding: 0.5rem 0;
|
72
|
-
}
|
73
|
-
</style>
|
74
|
-
<!-- docs: end hidden content -->
|
75
|
-
<d2l-form id="root">
|
76
|
-
<select class="d2l-input-select" name="pets" required>
|
77
|
-
<option value="">--Please choose an option--</option>
|
78
|
-
<option value="porpoise">Porpoise</option>
|
79
|
-
<option value="house hippo">House Hippo</option>
|
80
|
-
<option value="spiker monkey">Spider Monkey</option>
|
81
|
-
<option value="capybara">Capybara</option>
|
82
|
-
</select>
|
83
|
-
<d2l-form id="a">
|
84
|
-
<d2l-input-text label="Name" type="text" name="name" required minlength="4"></d2l-input-text>
|
85
|
-
</d2l-form>
|
86
|
-
<d2l-form id="b" no-nesting>
|
87
|
-
<d2l-input-text required label="Email" name="email" type="email"></d2l-input-text>
|
88
|
-
</d2l-form>
|
89
|
-
<button name="action" value="save" type="submit">Save</button>
|
90
|
-
</d2l-form>
|
91
|
-
```
|
92
|
-
|
93
|
-
<!-- docs: start hidden content -->
|
94
|
-
### Properties
|
95
|
-
|
96
|
-
| Property | Type | Description |
|
97
|
-
|---|---|---|
|
98
|
-
| `no-nesting` | Boolean, default: `false` | Indicates that the form should opt-out of nesting.<br><br>This means that it will not be submitted or validated if an ancestor form is submitted or validated. However, directly submitting or validating a form with `no-nesting` will still trigger submission and validation for its descendant forms unless they also opt-out using `no-nesting`. |
|
99
|
-
|
100
|
-
### Events
|
101
|
-
- `d2l-form-submit`: Dispatched when the form is submitted. The form data can be obtained from the `detail`'s `formData` property.
|
102
|
-
- `d2l-form-invalid`: Dispatched when the form fails validation. The error map can be obtained from the `detail`'s `errors` property.
|
103
|
-
- `d2l-form-dirty`: Dispatched whenever any form element fires an `input` or `change` event. Can be used to track whether the form is dirty or not.
|
104
|
-
<!-- docs: end hidden content -->
|
105
|
-
|
106
|
-
### Methods
|
107
|
-
- `submit()`: Submits the form. This will first perform validation on all elements within the form including nested `d2l-form` elements.
|
108
|
-
- **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.
|
109
|
-
- `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.
|
110
|
-
- `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.
|
111
|
-
- **Note:** The return value will include elements and errors from both the root form and any nested descendant forms.
|
112
|
-
|
113
|
-
### Advanced Usages: Nesting
|
114
|
-
|
115
|
-
`d2l-form` supports nesting by default meaning a `d2l-form` will discover descendant `d2l-form` elements. This includes *both*:
|
116
|
-
1. `d2l-form` elements nested directly within the ancestor form's slot
|
117
|
-
1. `d2l-form` elements contained within the shadow DOM of elements nested within the ancestor form's slot.
|
118
|
-
|
119
|
-
Form nesting will only consider descendants relative to the `d2l-form` that `submit` or `validate` is called on. If `submit` is called on a `d2l-form` element, it will not trigger submission for any ancestor forms, only desdenants.
|
120
|
-
|
121
|
-
- **Nested Validation:**
|
122
|
-
- When forms are nested, validation is _**atomic**_. This means that validation will only succeed if validation succeeds for the root form and all nested forms. If any form fails validation, none of them will be submitted.
|
123
|
-
- **Nested Submission:**
|
124
|
-
- When forms are nested, submission is _**independent**_. As a result, when nested forms all pass validation, each `d2l-form` will fire its own `d2l-form-submit` event with the data associated with that form.
|
125
|
-
|
126
|
-
```html
|
127
|
-
<script type="module">
|
128
|
-
import '@brightspace-ui/core/components/form/form.js';
|
129
|
-
</script>
|
130
|
-
<d2l-form id="root">
|
131
|
-
<div>
|
132
|
-
<d2l-form id="a">
|
133
|
-
<d2l-input-text required label="Email" name="email" type="email"></d2l-input-text>
|
134
|
-
<select class="d2l-input-select" name="pets" required>
|
135
|
-
<option value="">--Please choose an option--</option>
|
136
|
-
<option value="porpoise">Porpoise</option>
|
137
|
-
<option value="house hippo">House Hippo</option>
|
138
|
-
<option value="spiker monkey">Spider Monkey</option>
|
139
|
-
<option value="capybara">Capybara</option>
|
140
|
-
</select>
|
141
|
-
<div>
|
142
|
-
<d2l-form id="b">
|
143
|
-
<d2l-input-text label="Description" type="text" name="description" required></d2l-input-text>
|
144
|
-
</d2l-form>
|
145
|
-
</div>
|
146
|
-
</d2l-form>
|
147
|
-
</div>
|
148
|
-
<d2l-form no-nesting id="c">
|
149
|
-
<d2l-input-text label="Name" type="text" name="name" required minlength="4"></d2l-input-text>
|
150
|
-
</d2l-form>
|
151
|
-
<my-ele-with-an-internal-d2l-form id="d">
|
152
|
-
</my-ele-with-an-internal-d2l-form>
|
153
|
-
</d2l-form>
|
154
|
-
```
|
155
|
-
|
156
|
-
#### Example 1
|
157
|
-
In the above example, calling `submit` on the `#root` form will cause forms `#root`, `#a`, `#b`, and `#d` to be validated and submitted.
|
158
|
-
- `d2l-form#root` will be submitted because submit was called on it directly.
|
159
|
-
- `d2l-form#a` will be submitted because it is nested directly within `#root`'s slot.
|
160
|
-
- `d2l-form#b` will be submitted because it is nested within `#d2l-form#a` which was submitted.
|
161
|
-
- The `d2l-form` within the shadow root of `#d` will be submitted because it is within the shadow DOM of an element nested directly within `#root`'s slot.
|
162
|
-
- `d2l-form#c` will _**not**_ be submitted because it has the `no-nesting` attribute despite being nested directly within `#root's` slot.
|
163
|
-
|
164
|
-
#### Example 2
|
165
|
-
In the above example, calling `submit` on form `#a` will cause forms `#a` and `#b` to be validated and submitted.
|
166
|
-
- `d2l-form#a` will be submitted because submit was called on it directly.
|
167
|
-
- `d2l-form#b` will be submitted because it is nested directly within `#a`'s slot.
|
168
|
-
- `d2l-form#root`, `d2l-form#c` and the `d2l-form` within the shadow root of `#d` will _**not**_ be submitted because they are ancestors of `#a` rather than descendants.
|