@itenthusiasm/custom-elements 0.0.3 → 0.9.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/CheckboxGroup/CheckboxGroup.d.ts +86 -0
- package/CheckboxGroup/CheckboxGroup.js +389 -0
- package/CheckboxGroup/README.md +546 -0
- package/CheckboxGroup/index.d.ts +2 -0
- package/CheckboxGroup/index.js +2 -0
- package/CheckboxGroup/types/dom.d.ts +7 -0
- package/CheckboxGroup/types/preact.d.ts +23 -0
- package/CheckboxGroup/types/react.d.ts +23 -0
- package/CheckboxGroup/types/solid.d.ts +29 -0
- package/CheckboxGroup/types/svelte.d.ts +20 -0
- package/CheckboxGroup/types/vue.d.ts +40 -0
- package/Combobox/Combobox.css +8 -7
- package/Combobox/ComboboxField.d.ts +8 -19
- package/Combobox/ComboboxField.js +127 -89
- package/Combobox/README.md +262 -10
- package/Combobox/types/preact.d.ts +1 -1
- package/Combobox/types/react.d.ts +1 -1
- package/Combobox/types/solid.d.ts +13 -2
- package/Combobox/types/svelte.d.ts +2 -2
- package/Combobox/types/vue.d.ts +1 -1
- package/README.md +46 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +6 -2
- package/types/dom.d.ts +1 -0
- package/types/helpers.d.ts +12 -0
- package/types/preact.d.ts +1 -0
- package/types/react.d.ts +1 -0
- package/types/solid.d.ts +1 -0
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +1 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
# The `CheckboxGroup` Element
|
|
2
|
+
|
|
3
|
+
The `CheckboxGroup` is a Custom Element which progressively enhances a semantic group of checkbox `input` elements, providing the group with convenient features like seameless form validation and easier value management.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install @itenthusiasm/custom-elements
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<!-- HTML -->
|
|
15
|
+
<form>
|
|
16
|
+
<checkbox-group id="toppings" name="toppings" min="2" max="4">
|
|
17
|
+
<fieldset>
|
|
18
|
+
<label for="toppings">Toppings</label>
|
|
19
|
+
|
|
20
|
+
<div>
|
|
21
|
+
<input id="pepperoni" type="checkbox" value="pepperoni" checked />
|
|
22
|
+
<label for="pepperoni">Pepperoni</label>
|
|
23
|
+
|
|
24
|
+
<input id="sausage" type="checkbox" value="sausage" />
|
|
25
|
+
<label for="sausage">Sausage</label>
|
|
26
|
+
|
|
27
|
+
<input id="onions" type="checkbox" value="onions" />
|
|
28
|
+
<label for="onions">Onions</label>
|
|
29
|
+
|
|
30
|
+
<input id="peppers" type="checkbox" value="peppers" />
|
|
31
|
+
<label for="peppers">Peppers</label>
|
|
32
|
+
|
|
33
|
+
<input id="olives" type="checkbox" value="olives" />
|
|
34
|
+
<label for="olives">Olives</label>
|
|
35
|
+
</div>
|
|
36
|
+
</fieldset>
|
|
37
|
+
</checkbox-group>
|
|
38
|
+
</form>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
> **NOTE: Only the `<fieldset>` element is allowed to be a direct descendant of a `<checkbox-group>`.**
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
/* JavaScript */
|
|
45
|
+
import { CheckboxGroup } from "@itenthusiasm/custom-elements";
|
|
46
|
+
// or import { CheckboxGroup } from "@itenthusiasm/custom-elements/CheckboxGroup";
|
|
47
|
+
|
|
48
|
+
customElements.define("checkbox-group", CheckboxGroup);
|
|
49
|
+
|
|
50
|
+
// Retrieve some info about the `checkbox-group`
|
|
51
|
+
const form = document.querySelector("form");
|
|
52
|
+
const formData = new FormData(form);
|
|
53
|
+
console.log(formData.getAll("toppings")); // ["pepperoni"]
|
|
54
|
+
|
|
55
|
+
const checkboxGroup = document.querySelector("checkbox-group");
|
|
56
|
+
console.log(checkboxGroup.form === form); // true
|
|
57
|
+
console.log(checkboxGroup.value); // ["pepperoni"]
|
|
58
|
+
|
|
59
|
+
// Right now, the group is invalid because the `min` attribute dictates that at least 2 items must be selected
|
|
60
|
+
console.log(checkboxGroup.validity.valid); // false
|
|
61
|
+
console.log(checkboxGroup.validity.rangeUnderflow); // true
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Progressive Enhancement
|
|
65
|
+
|
|
66
|
+
The example HTML displayed at the [beginning](#quickstart) of this document is fully functional, but it only works when JavaScript is enabled for your application. To ensure that your checkbox group will work even when JavaScript is disabled, you should render your checkbox group the "old fashioned way".
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<form>
|
|
70
|
+
<checkbox-group min="2" max="4">
|
|
71
|
+
<fieldset>
|
|
72
|
+
<legend>Toppings</legend>
|
|
73
|
+
|
|
74
|
+
<div>
|
|
75
|
+
<input id="pepperoni" name="toppings" type="checkbox" value="pepperoni" checked />
|
|
76
|
+
<label for="pepperoni">Pepperoni</label>
|
|
77
|
+
|
|
78
|
+
<input id="sausage" name="toppings" type="checkbox" value="sausage" />
|
|
79
|
+
<label for="sausage">Sausage</label>
|
|
80
|
+
|
|
81
|
+
<input id="onions" name="toppings" type="checkbox" value="onions" />
|
|
82
|
+
<label for="onions">Onions</label>
|
|
83
|
+
|
|
84
|
+
<input id="peppers" name="toppings" type="checkbox" value="peppers" />
|
|
85
|
+
<label for="peppers">Peppers</label>
|
|
86
|
+
|
|
87
|
+
<input id="olives" name="toppings" type="checkbox" value="olives" />
|
|
88
|
+
<label for="olives">Olives</label>
|
|
89
|
+
</div>
|
|
90
|
+
</fieldset>
|
|
91
|
+
</checkbox-group>
|
|
92
|
+
</form>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The above HTML will work even if JavaScript is disabled. When the user submits the form provided above, an array of values containing every item which the user selected will be sent to the server (even when JS is disabled).
|
|
96
|
+
|
|
97
|
+
Remember that client-side form validation for checkbox groups is a feature provided by the `CheckboxGroup` Web Component (meaning that JavaScript must be enabled). So you'll need server-side validation in place to enforce that the minimum/maximum number of items is selected to cover the case where a user has JS disabled. (That said, you should _always_ write server-side validation anyway to ensure the security and integrity of your web applications.)
|
|
98
|
+
|
|
99
|
+
When the `CheckboxGroup` Custom Element is registered and mounted to the DOM, it transforms the HTML above into the following:
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<form>
|
|
103
|
+
<checkbox-group id="RANDOMLY_GENERATED_ID" name="toppings" min="2" max="4">
|
|
104
|
+
<fieldset role="none">
|
|
105
|
+
<label for="RANDOMLY_GENERATED_ID">Toppings</label>
|
|
106
|
+
|
|
107
|
+
<div>
|
|
108
|
+
<input id="pepperoni" type="checkbox" value="pepperoni" form="" checked />
|
|
109
|
+
<label for="pepperoni">Pepperoni</label>
|
|
110
|
+
|
|
111
|
+
<input id="sausage" type="checkbox" value="sausage" form="" />
|
|
112
|
+
<label for="sausage">Sausage</label>
|
|
113
|
+
|
|
114
|
+
<input id="onions" type="checkbox" value="onions" form="" />
|
|
115
|
+
<label for="onions">Onions</label>
|
|
116
|
+
|
|
117
|
+
<input id="peppers" type="checkbox" value="peppers" form="" />
|
|
118
|
+
<label for="peppers">Peppers</label>
|
|
119
|
+
|
|
120
|
+
<input id="olives" type="checkbox" value="olives" form="" />
|
|
121
|
+
<label for="olives">Olives</label>
|
|
122
|
+
</div>
|
|
123
|
+
</fieldset>
|
|
124
|
+
</checkbox-group>
|
|
125
|
+
</form>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
As you can see from the transformed markup above, the `CheckboxGroup` does a few things. It...
|
|
129
|
+
|
|
130
|
+
1. Replaces the `<legend>` element with a `<label>` element.
|
|
131
|
+
- The `CheckboxGroup` can only be labeled by a `<label>` element, not a `<legend>` element. This is the reason for replacing the `<legend>`, and it is the reason for the randomly-generated `id` as well. If you provide your own `id` to the `<checkbox-group>` element, then the component will use that ID instead of randomly generating its own.
|
|
132
|
+
- If no `<legend>` is found on mount, then the component will not try to create an accessible label for itself.
|
|
133
|
+
2. Transfers the `name` attribute (if it exists) from the `checkbox`es to itself.
|
|
134
|
+
- Since the `<checkbox-group>` itself is a form control, and since it represents the whole group of `checkbox`es, it is the only form control in the group that needs the `name` attribute.
|
|
135
|
+
3. Dissociates the `checkbox`es from the wrapping `<form>`.
|
|
136
|
+
- This is done by applying the empty `[form=""]` attribute to all the `checkbox`es, and it is done to avoid running into edge cases where events or form data could be processed in a duplicated fashion. Again, since the `<checkbox-group>` is a form control representing the whole group of `checkbox`es, it is the only form control that needs to be associated with the `<form>`.
|
|
137
|
+
4. Applies the `none` role to the `<fieldset>` element.
|
|
138
|
+
- `<fieldset>`s typically have the accessible [`group`](https://w3c.github.io/aria/#group) role. The `<checkbox-group>` element also has this role, so `[role="none"]` is applied to the `<fieldset>` to avoid duplicating accessibility information.
|
|
139
|
+
|
|
140
|
+
Although it wasn't shown in the example above, the `<checkbox-group>` does one last thing on mount: It transfers all of the `<fieldset>`'s attributes to itself. This can be useful, for example, for transferring important accessibility attributes (like `aria-describedby`) from the `<fieldset>` to the `<checkbox-group>` after your application's JavaScript has loaded.
|
|
141
|
+
|
|
142
|
+
> Note: No matter what role the `<fieldset>` has on mount, the `<checkbox-group>` will always end up with a `group` role after mounting, and the `<fieldset>` will always end up with a `none` role.
|
|
143
|
+
|
|
144
|
+
### Progressive Enhancement in JS Frameworks
|
|
145
|
+
|
|
146
|
+
Some JS frameworks (such as React) may get confused if you remove elements from the DOM with tools other than what the framework provides. This makes the `<legend>` replacement feature of the `<checkbox-group>` component problematic. To preserve this progressive enhancement behavior without breaking the expectations of your framework, you can write a component that performs the `<legend>` replacement itself. Here is an example in React:
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { useState, useEffect } from "react";
|
|
150
|
+
import type {} from "@itenthusiasm/custom-elements/react";
|
|
151
|
+
// Or import type {} from "@itenthusiasm/custom-elements/CheckboxGroup/react";
|
|
152
|
+
|
|
153
|
+
interface CheckboxGroupProps extends React.ComponentProps<"checkbox-group"> {
|
|
154
|
+
label?: string;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export default function CheckboxGroup({ label, children, ...rest }: CheckboxGroupProps) {
|
|
158
|
+
const [mounted, setMounted] = useState(false);
|
|
159
|
+
useEffect(() => setMounted(true), []);
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<checkbox-group {...(mounted ? rest : undefined)} manual>
|
|
163
|
+
<fieldset {...(mounted ? undefined : (rest as React.ComponentProps<"fieldset">))}>
|
|
164
|
+
{!!label && (mounted ? <label htmlFor={rest.id}>{label}</label> : <legend>{label}</legend>)}
|
|
165
|
+
|
|
166
|
+
{children}
|
|
167
|
+
</fieldset>
|
|
168
|
+
</checkbox-group>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Notice the [`manual`](#attributes-manual) attribute that was applied to the `<checkbox-group>`. This tells the component _not_ to remove or add any children on its own, giving developers the freedom to make such modifications themselves. Note that the `CheckboxGroup` will still perform other automated actions unrelated to DOM insertion/removal in this mode, such as altering the `name` and `form` attributes of every `checkbox` inserted into it. These other actions are all safe for JS frameworks.
|
|
174
|
+
|
|
175
|
+
## TypeScript Usage in JS Frameworks
|
|
176
|
+
|
|
177
|
+
Many JS frameworks, such as Svelte and React, often define their own "Element Namespaces". Because of this, most frameworks are not able (on their own) to recognize the correct attributes, properties, and event listeners that belong to the Custom Elements which you use. Thankfully, our library ships with TypeScript types that tell the various JS Frameworks about the existence and shape of our Custom Elements. To define _all_ of our library's Custom Elements within a Framework's "Element Namespace", simply import the appropriate type definition file:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import type {} from "@itenthusiasm/custom-elements/types/react";
|
|
181
|
+
// For Svelte: import type {} from "@itenthusiasm/custom-elements/types/svelte";
|
|
182
|
+
// For Vue: import type {} from "@itenthusiasm/custom-elements/types/vue";
|
|
183
|
+
// etc. ...
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
If you only intend to use _some_ of the Custom Elements provided by this library, then you should only import the types for those components.
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
// Define ONLY the `CheckboxGroup` component's types in the framework's "Element Namespace"
|
|
190
|
+
import type {} from "@itenthusiasm/custom-elements/CheckboxGroup/types/react";
|
|
191
|
+
// For Svelte: import type {} from "@itenthusiasm/custom-elements/CheckboxGroup/types/svelte";
|
|
192
|
+
// For Vue: import type {} from "@itenthusiasm/custom-elements/CheckboxGroup/types/vue";
|
|
193
|
+
// etc. ...
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The component also ships with types that enhance the native DOM methods if you need them:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import type {} from "@itenthusiasm/custom-elements/types/dom";
|
|
200
|
+
// Or more specifically, import type {} from "@itenthusiasm/custom-elements/CheckboxGroup/types/dom";
|
|
201
|
+
|
|
202
|
+
// This variable will be properly typed by TypeScript now, instead of just being a general `Element` type.
|
|
203
|
+
const checkboxGroup = document.querySelector("checkbox-group");
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Accessibility
|
|
207
|
+
|
|
208
|
+
For accessibility purposes, it is recommended to render your grouped `checkbox`es using HTML that semantic and clear. Instead of using the generic and vague `<div>` element, prefer using the list-related elements such as `<ul>` and `<li>`:
|
|
209
|
+
|
|
210
|
+
```html
|
|
211
|
+
<form>
|
|
212
|
+
<checkbox-group min="2" max="4">
|
|
213
|
+
<fieldset>
|
|
214
|
+
<legend>Toppings</legend>
|
|
215
|
+
|
|
216
|
+
<ul>
|
|
217
|
+
<li>
|
|
218
|
+
<input id="pepperoni" name="toppings" type="checkbox" value="pepperoni" checked />
|
|
219
|
+
<label for="pepperoni">Pepperoni</label>
|
|
220
|
+
</li>
|
|
221
|
+
|
|
222
|
+
<li>
|
|
223
|
+
<input id="sausage" name="toppings" type="checkbox" value="sausage" />
|
|
224
|
+
<label for="sausage">Sausage</label>
|
|
225
|
+
</li>
|
|
226
|
+
|
|
227
|
+
<li>
|
|
228
|
+
<input id="onions" name="toppings" type="checkbox" value="onions" />
|
|
229
|
+
<label for="onions">Onions</label>
|
|
230
|
+
</li>
|
|
231
|
+
</ul>
|
|
232
|
+
</fieldset>
|
|
233
|
+
</checkbox-group>
|
|
234
|
+
</form>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This is recommended because it will enable Screen Readers to see and announce the number of `checkbox`es in a list if the markup structure shown above is used. This helps your users know where they are, and what they should expect.
|
|
238
|
+
|
|
239
|
+
## CSS Styles
|
|
240
|
+
|
|
241
|
+
Because the `<checkbox-group>` is simply a wrapper around the `<fieldset>` element, it does not need any custom CSS. Therefore, the library does not ship any custom CSS for this component. You can style the `<checkbox-group>`, `<fieldset>`, and other elements as usual.
|
|
242
|
+
|
|
243
|
+
## Restrictions
|
|
244
|
+
|
|
245
|
+
The `CheckboxGroup` Custom Element enforces the following restrictions:
|
|
246
|
+
|
|
247
|
+
1. Only the `<fieldset>` element is allowed to be a direct descendant of a `<checkbox-group>`.
|
|
248
|
+
2. Checkboxes (`<input type="checkbox">`) are the only kind of form controls allowed within the `<checkbox-group>`. Other kinds of form controls are forbidden. However, all _non-form-control_ elements are permitted within the `<checkbox-group>` (as demonstrated in the examples above).
|
|
249
|
+
3. Nesting `<checkbox-group>`s is not supported.
|
|
250
|
+
|
|
251
|
+
## API
|
|
252
|
+
|
|
253
|
+
This section describes the attributes, properties, and events associated with the `CheckboxGroup` Custom Element.
|
|
254
|
+
|
|
255
|
+
### Attributes
|
|
256
|
+
|
|
257
|
+
As a Custom Element, the `CheckboxGroup` supports all of the [global attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes). The attributes which are _specific_ to the `CheckboxGroup` are as follows:
|
|
258
|
+
|
|
259
|
+
<dl>
|
|
260
|
+
<dt id="attributes-name">
|
|
261
|
+
<a href="#attributes-name"><code>name</code></a>
|
|
262
|
+
</dt>
|
|
263
|
+
<dd>
|
|
264
|
+
<p>
|
|
265
|
+
Same as the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#name"><code>name</code></a> attribute seen on native form controls like the <code><input></code> element. Ensures that the element's value will be submitted to the server under the specified <code>name</code> on form submission. The name can also be used to access the element via the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements"><code>HTMLFormElement.elements</code></a> property of the owning form.
|
|
266
|
+
</p>
|
|
267
|
+
<p>This attribute is reflected by the <a href="#properties-name"><code>CheckboxGroup.name</code></a> property.</p>
|
|
268
|
+
</dd>
|
|
269
|
+
|
|
270
|
+
<dt id="attributes-disabled">
|
|
271
|
+
<a href="#attributes-disabled"><code>disabled</code></a>
|
|
272
|
+
</dt>
|
|
273
|
+
<dd>
|
|
274
|
+
<p>
|
|
275
|
+
Same as the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/disabled"><code>disabled</code></a> boolean attribute seen on native form controls like the <code><input></code> element. When this attribute is present, the entire <code>CheckboxGroup</code> component (including the checkboxes that it owns) will become non-interactive, and its value will not be sent to the server.
|
|
276
|
+
</p>
|
|
277
|
+
<p>This attribute is reflected by the <a href="#properties-disabled"><code>CheckboxGroup.disabled</code></a> property.</p>
|
|
278
|
+
</dd>
|
|
279
|
+
|
|
280
|
+
<dt id="attributes-required">
|
|
281
|
+
<a href="#attributes-required"><code>required</code></a>
|
|
282
|
+
</dt>
|
|
283
|
+
<dd>
|
|
284
|
+
<p>
|
|
285
|
+
Same as the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/required"><code>required</code></a> boolean attribute seen on native form controls like the <code><input></code> element. Indicates that the element's owning form cannot be submitted if its value is an empty array (i.e., if no checkboxes are selected).
|
|
286
|
+
</p>
|
|
287
|
+
<blockquote>
|
|
288
|
+
<p>
|
|
289
|
+
NOTE: In general, you should always prefer the <a href="#attributes-min"><code>min</code></a> attribute to the <code>required</code> attribute. This is because the <code>required</code> attribute is effectively the same as setting <code>[min="1"]</code>. The <code>min</code> attribute is more succinct and vastly more flexible.
|
|
290
|
+
</p>
|
|
291
|
+
</blockquote>
|
|
292
|
+
<p>This attribute is reflected by the <a href="#properties-required"><code>CheckboxGroup.required</code></a> property.</p>
|
|
293
|
+
</dd>
|
|
294
|
+
|
|
295
|
+
<dt id="attributes-valuemissingerror">
|
|
296
|
+
<a href="#attributes-valuemissingerror"><code>valuemissingerror</code></a>
|
|
297
|
+
</dt>
|
|
298
|
+
<dd>
|
|
299
|
+
<p>
|
|
300
|
+
Determines the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/validationMessage"><code>validationMessage</code></a> that the element will display if it has a <a href="https://developer.mozilla.org/en-US/docs/Web/API/ValidityState/valueMissing"><code>ValidityState.valueMissing</code></a> error. The element enters this error state if its value is an empty array when it has the <a href="#attributes-required"><code>required</code></a> attribute. If the element's <code>required</code> constraint is broken when its owning form is submitted, then form submission will fail, and the <code>valuemissingerror</code> will be shown to the user in an error message bubble.
|
|
301
|
+
</p>
|
|
302
|
+
<p>
|
|
303
|
+
To learn more about client-side form validation, see MDN's <a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation"><em>Client-side Form Validation</em></a> tutorial. If you're looking for a robust form validation library that works with Custom Elements, try the <a href="https://github.com/enthusiastic-js/form-observer/tree/main/docs/form-validity-observer"><code>FormValidityObserver</code></a>.
|
|
304
|
+
</p>
|
|
305
|
+
<p>This attribute is reflected by the <a href="#properties-valueMissingError"><code>CheckboxGroup.valueMissingError</code></a> property.</p>
|
|
306
|
+
</dd>
|
|
307
|
+
|
|
308
|
+
<dt id="attributes-min">
|
|
309
|
+
<a href="#attributes-min"><code>min</code></a>
|
|
310
|
+
</dt>
|
|
311
|
+
<dd>
|
|
312
|
+
<p>
|
|
313
|
+
Same as the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#min"><code>min</code></a> attribute found on the native <code><input></code> element. Indicates that the element's owning form cannot be submitted until the minimum required number of items are selected. Note that the constraint is only applied if the attribute is a valid number.
|
|
314
|
+
</p>
|
|
315
|
+
<p>This attribute is reflected by the <a href="#properties-min"><code>CheckboxGroup.min</code></a> property.</p>
|
|
316
|
+
</dd>
|
|
317
|
+
|
|
318
|
+
<dt id="attributes-rangeunderflowerror">
|
|
319
|
+
<a href="#attributes-rangeunderflowerror"><code>rangeunderflowerror</code></a>
|
|
320
|
+
</dt>
|
|
321
|
+
<dd>
|
|
322
|
+
<p>
|
|
323
|
+
Determines the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/validationMessage"><code>validationMessage</code></a> that the element will display if it has a <a href="https://developer.mozilla.org/en-US/docs/Web/API/ValidityState/rangeUnderflow"><code>ValidityState.rangeUnderflow</code></a> error. The element enters this error state if the user has selected a number of items less than the value specified by the <a href="#attributes-min"><code>min</code></a> attribute. If the element's <code>min</code> constraint is broken when its owning form is submitted, then form submission will fail, and the <code>rangeunderflowerror</code> will be shown to the user in an error message bubble.
|
|
324
|
+
</p>
|
|
325
|
+
<blockquote>
|
|
326
|
+
<p>
|
|
327
|
+
NOTE: If the element's <code>min</code> and <a href="#attributes-required"><code>required</code></a> constraints are both broken, then only the <code>rangeunderflowerror</code> will be shown. This is to minimize the number of steps the user will need to take to fix the form control's value.
|
|
328
|
+
</p>
|
|
329
|
+
</blockquote>
|
|
330
|
+
<p>This attribute is reflected by the <a href="#properties-rangeUnderflowError"><code>CheckboxGroup.rangeUnderflowError</code></a> property.</p>
|
|
331
|
+
</dd>
|
|
332
|
+
|
|
333
|
+
<dt id="attributes-max">
|
|
334
|
+
<a href="#attributes-max"><code>max</code></a>
|
|
335
|
+
</dt>
|
|
336
|
+
<dd>
|
|
337
|
+
<p>
|
|
338
|
+
Same as the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#max"><code>max</code></a> attribute found on the native <code><input></code> element. Indicates that the element's owning form cannot be submitted until the number of selected items is less than or equal to the maximum allowed amount. Note that the constraint is only applied if the attribute is a valid number.
|
|
339
|
+
</p>
|
|
340
|
+
<blockquote>
|
|
341
|
+
<p>NOTE: You should always ensure that the <code>max</code> attribute is greater than or equal to the <a href="#attributes-min"><code>min</code></a> attribute.</p>
|
|
342
|
+
</blockquote>
|
|
343
|
+
<p>This attribute is reflected by the <a href="#properties-max"><code>CheckboxGroup.max</code></a> property.</p>
|
|
344
|
+
</dd>
|
|
345
|
+
|
|
346
|
+
<dt id="attributes-rangeoverflowerror">
|
|
347
|
+
<a href="#attributes-rangeoverflowerror"><code>rangeoverflowerror</code></a>
|
|
348
|
+
</dt>
|
|
349
|
+
<dd>
|
|
350
|
+
<p>
|
|
351
|
+
Determines the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/validationMessage"><code>validationMessage</code></a> that the element will display if it has a <a href="https://developer.mozilla.org/en-US/docs/Web/API/ValidityState/rangeOverflow"><code>ValidityState.rangeOverflow</code></a> error. The element enters this error state if the user has selected a number of items greater than the value specified by the <a href="#attributes-max"><code>max</code></a> attribute. If the element's <code>max</code> constraint is broken when its owning form is submitted, then form submission will fail, and the <code>rangeoverflowerror</code> will be shown to the user in an error message bubble.
|
|
352
|
+
</p>
|
|
353
|
+
<p>This attribute is reflected by the <a href="#properties-rangeOverflowError"><code>CheckboxGroup.rangeOverflowError</code></a> property.</p>
|
|
354
|
+
</dd>
|
|
355
|
+
|
|
356
|
+
<dt id="attributes-manual">
|
|
357
|
+
<a href="#attributes-manual"><code>manual</code></a>
|
|
358
|
+
</dt>
|
|
359
|
+
<dd>
|
|
360
|
+
<p>
|
|
361
|
+
A boolean attribute indicating that the <code>CheckboxGroup</code> should not replace its <code><fieldset></code>'s accessible label (<code><legend></code>) with its own (<code><label></code>) when mounted. You should only enable this property if you intend to perform the label replacement yourself.
|
|
362
|
+
</p>
|
|
363
|
+
<p>
|
|
364
|
+
Note that the other automated actions unrelated to DOM insertion/removal that are described in the <a href="#progressive-enhancement"><em>Progressive Enhancement</em></a> section will still occur even when this mode is turned on. (This is for accessibility purposes.)
|
|
365
|
+
</p>
|
|
366
|
+
<p>This attribute is reflected by the <a href="#properties-manual"><code>CheckboxGroup.manual</code></a> property.</p>
|
|
367
|
+
</dd>
|
|
368
|
+
</dl>
|
|
369
|
+
|
|
370
|
+
## Properties
|
|
371
|
+
|
|
372
|
+
As a Custom Element, the `CheckboxGroup` inherits all of the methods and properties of the [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) interface. The properties which are _specific_ to the `CheckboxGroup` are as follows:
|
|
373
|
+
|
|
374
|
+
<dl>
|
|
375
|
+
<dt id="properties-value">
|
|
376
|
+
<a href="#properties-value"><code>value</code></a>
|
|
377
|
+
</dt>
|
|
378
|
+
<dd>
|
|
379
|
+
<p>Sets or retrieves the value of the element. Type is <code>string[]</code>.</p>
|
|
380
|
+
<p>
|
|
381
|
+
When this property is set, every checkbox with a <code>value</code> corresponding to an item in the array will be checked; all other checkboxes will be unchecked. If an item in the provided array has no corresponding checkbox, then it will be deleted.
|
|
382
|
+
</p>
|
|
383
|
+
</dd>
|
|
384
|
+
|
|
385
|
+
<dt id="properties-name">
|
|
386
|
+
<a href="#properties-name"><code>name</code></a>
|
|
387
|
+
</dt>
|
|
388
|
+
<dd>
|
|
389
|
+
Same as the <code>name</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/name"><code><input></code></a> element: It reflects the value of the <a href="#attributes-name"><code>name</code></a> attribute. Type is <code>string</code>.
|
|
390
|
+
</dd>
|
|
391
|
+
|
|
392
|
+
<dt id="properties-disabled">
|
|
393
|
+
<a href="#properties-disabled"><code>disabled</code></a>
|
|
394
|
+
</dt>
|
|
395
|
+
<dd>
|
|
396
|
+
Same as the boolean <code>disabled</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/disabled"><code><input></code></a> element: It reflects the value of the <a href="#attributes-disabled"><code>disabled</code></a> attribute.
|
|
397
|
+
</dd>
|
|
398
|
+
|
|
399
|
+
<dt id="properties-required">
|
|
400
|
+
<a href="#properties-required"><code>required</code></a>
|
|
401
|
+
</dt>
|
|
402
|
+
<dd>
|
|
403
|
+
Same as the boolean <code>required</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/required"><code><input></code></a> element: It reflects the value of the <a href="#attributes-required"><code>required</code></a> attribute.
|
|
404
|
+
</dd>
|
|
405
|
+
|
|
406
|
+
<dt id="properties-valueMissingError">
|
|
407
|
+
<a href="#properties-valueMissingError"><code>valueMissingError</code></a>
|
|
408
|
+
</dt>
|
|
409
|
+
<dd>Reflects the <a href="#attributes-valuemissingerror"><code>valuemissingerror</code></a> attribute. Type is <code>string</code>.</dd>
|
|
410
|
+
|
|
411
|
+
<dt id="properties-min">
|
|
412
|
+
<a href="#properties-min"><code>min</code></a>
|
|
413
|
+
</dt>
|
|
414
|
+
<dd>
|
|
415
|
+
Same as the <code>min</code> property found on the native <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/min"><code><input></code></a> element: It reflects the value of the <a href="#attributes-min"><code>min</code></a> attribute. Type is <code>string</code>.
|
|
416
|
+
</dd>
|
|
417
|
+
|
|
418
|
+
<dt id="properties-rangeUnderflowError">
|
|
419
|
+
<a href="#properties-rangeUnderflowError"><code>rangeUnderflowError</code></a>
|
|
420
|
+
</dt>
|
|
421
|
+
<dd>Reflects the <a href="#attributes-rangeunderflowerror"><code>rangeunderflowerror</code></a> attribute. Type is <code>string</code>.</dd>
|
|
422
|
+
|
|
423
|
+
<dt id="properties-max">
|
|
424
|
+
<a href="#properties-max"><code>max</code></a>
|
|
425
|
+
</dt>
|
|
426
|
+
<dd>
|
|
427
|
+
Same as the <code>max</code> property found on the native <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/max"><code><input></code></a> element: It reflects the value of the <a href="#attributes-max"><code>max</code></a> attribute. Type is <code>string</code>.
|
|
428
|
+
</dd>
|
|
429
|
+
|
|
430
|
+
<dt id="properties-rangeOverflowError">
|
|
431
|
+
<a href="#properties-rangeOverflowError"><code>rangeOverflowError</code></a>
|
|
432
|
+
</dt>
|
|
433
|
+
<dd>Reflects the <a href="#attributes-rangeoverflowerror"><code>rangeoverflowerror</code></a> attribute. Type is <code>string</code>.</dd>
|
|
434
|
+
|
|
435
|
+
<dt id="properties-manual">
|
|
436
|
+
<a href="#properties-manual"><code>manual</code></a>
|
|
437
|
+
</dt>
|
|
438
|
+
<dd>A <code>boolean</code> property which reflects the value of the <a href="#attributes-manual"><code>manual</code></a> attribute.</dd>
|
|
439
|
+
|
|
440
|
+
<dt id="properties-fieldset">
|
|
441
|
+
<a href="#properties-fieldset"><code>fieldset</code></a>
|
|
442
|
+
</dt>
|
|
443
|
+
<dd>
|
|
444
|
+
<p>
|
|
445
|
+
Returns the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFieldSetElement"><code>HTMLFieldSetElement</code></a> wrapped by the <code>CheckboxGroup</code>. Useful for <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFieldSetElement/elements">iterating</a> over all of the group's checkboxes programmatically.
|
|
446
|
+
</p>
|
|
447
|
+
</dd>
|
|
448
|
+
|
|
449
|
+
<dt id="properties-labels">
|
|
450
|
+
<a href="#properties-labels"><code>labels</code></a>
|
|
451
|
+
</dt>
|
|
452
|
+
<dd>
|
|
453
|
+
Same as the read-only <code>labels</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/labels"><code><input></code></a> element: Returns a <a href="https://developer.mozilla.org/en-US/docs/Web/API/NodeList"><code>NodeList</code></a> of all the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/label"><code><label></code></a> elements associated with the <code>CheckboxGroup</code>.
|
|
454
|
+
</dd>
|
|
455
|
+
|
|
456
|
+
<dt id="properties-form">
|
|
457
|
+
<a href="#properties-form"><code>form</code></a>
|
|
458
|
+
</dt>
|
|
459
|
+
<dd>
|
|
460
|
+
Same as the read-only <code>form</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/form"><code><input></code></a> element: Returns the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement"><code>HTMLFormElement</code></a> with which the <code>CheckboxGroup</code> is associated. Returns <code>null</code> if no <code><form></code> owns the element.
|
|
461
|
+
</dd>
|
|
462
|
+
|
|
463
|
+
<dt id="properties-validity">
|
|
464
|
+
<a href="#properties-validity"><code>validity</code></a>
|
|
465
|
+
</dt>
|
|
466
|
+
<dd>
|
|
467
|
+
Same as the read-only <code>validity</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/validity"><code><input></code></a> element: Returns the element's <a href="https://developer.mozilla.org/en-US/docs/Web/API/ValidityState"><code>ValidityState</code></a> object.
|
|
468
|
+
</dd>
|
|
469
|
+
|
|
470
|
+
<dt id="properties-validationMessage">
|
|
471
|
+
<a href="#properties-validationMessage"><code>validationMessage</code></a>
|
|
472
|
+
</dt>
|
|
473
|
+
<dd>
|
|
474
|
+
Same as the read-only <code>validationMessage</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/validationMessage"><code><input></code></a> element: Returns the message that will be displayed to users when the <code>CheckboxGroup</code> fails constraint validation. Type is <code>string</code>. To learn more about client-side form validation and when the user is shown an error message bubble, see MDN's <a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation"><em>Client-side Form Validation</em></a> tutorial.
|
|
475
|
+
</dd>
|
|
476
|
+
|
|
477
|
+
<dt id="properties-willValidate">
|
|
478
|
+
<a href="#properties-willValidate"><code>willValidate</code></a>
|
|
479
|
+
</dt>
|
|
480
|
+
<dd>
|
|
481
|
+
Same as the read-only boolean <code>willValidate</code> property found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/willValidate"><code><input></code></a> element: Returns <code>false</code> if the element will skip constraint validation. See <a href="https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate">MDN's Documentation</a> for more info on how <code>willValidate</code> is determined for form controls.
|
|
482
|
+
</dd>
|
|
483
|
+
</dl>
|
|
484
|
+
|
|
485
|
+
## Methods
|
|
486
|
+
|
|
487
|
+
In addition to the methods that exist on the [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) interface, the `CheckboxGroup` defines the instance methods listed below.
|
|
488
|
+
|
|
489
|
+
<dl>
|
|
490
|
+
<dt id="methods-checkValidity">
|
|
491
|
+
<a href="#methods-checkValidity"><code>checkValidity()</code></a> Signature: <code>() => boolean</code>
|
|
492
|
+
</dt>
|
|
493
|
+
<dd>
|
|
494
|
+
<p>
|
|
495
|
+
Same as the <code>checkValidity()</code> method found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/checkValidity"><code><input></code></a> element: Returns <code>true</code> if the element passes constraint validation. Otherwise, returns <code>false</code>. If validation fails, an <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/invalid_event"><code>invalid</code></a> event will be fired on the element, but the element <em>will not</em> display an error message bubble.
|
|
496
|
+
</p>
|
|
497
|
+
</dd>
|
|
498
|
+
|
|
499
|
+
<dt id="methods-reportValidity">
|
|
500
|
+
<a href="#methods-reportValidity"><code>reportValidity()</code></a> Signature: <code>() => boolean</code>
|
|
501
|
+
</dt>
|
|
502
|
+
<dd>
|
|
503
|
+
<p>
|
|
504
|
+
Same as the <code>reportValidity()</code> method found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/reportValidity"><code><input></code></a> element: Behaves the same as the <a href="#methods-checkValidity"><code>checkValidity()</code></a> method. However, it <em>will</em> display an error message bubble if the element fails constraint validation, as long as the <code>invalid</code> event has not been canceled.
|
|
505
|
+
</p>
|
|
506
|
+
</dd>
|
|
507
|
+
|
|
508
|
+
<dt id="methods-setCustomValidity">
|
|
509
|
+
<a href="#methods-setCustomValidity"><code>setCustomValidity()</code></a> Signature: <code>(error: string) => void</code>
|
|
510
|
+
</dt>
|
|
511
|
+
<dd>
|
|
512
|
+
<p>
|
|
513
|
+
Same as the <code>setCustomValidity()</code> method found on native form controls like the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setCustomValidity"><code><input></code></a> element: Marks the element as invalid by giving it a custom error message. This error state/message takes precedence over all other error states/messages (such as the <code>required</code> error state/message and all the other ones). Note that any form control which has a custom error message will always fail constraint validation. (This is also true for native form controls.) To remove the error, call this method with an empty string.
|
|
514
|
+
</p>
|
|
515
|
+
</dd>
|
|
516
|
+
</dl>
|
|
517
|
+
|
|
518
|
+
## Events
|
|
519
|
+
|
|
520
|
+
As a Custom Element, the <code>CheckboxGroup</code> supports all of the events for the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement"><code>HTMLElement</code></a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element"><code>Element</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node"><code>Node</code></a> interfaces. Additionally, it supports the events below. You can listen for them by using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</code></a> method.
|
|
521
|
+
|
|
522
|
+
<dl>
|
|
523
|
+
<dt id="events-input">
|
|
524
|
+
<a href="#events-input"><code>input</code></a>
|
|
525
|
+
</dt>
|
|
526
|
+
<dd>
|
|
527
|
+
<p>
|
|
528
|
+
Fires whenever the user toggles the state of a checkbox in a <code>CheckboxGroup</code> with their Mouse or Keyboard.
|
|
529
|
+
</p>
|
|
530
|
+
<p>
|
|
531
|
+
Just like the native event for <code><input type="checkbox"></code> elements, this event is not cancelable, and its type is <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event"><code>Event</code></a>. Note: Although this event is not cancelable, it is possible to prevent a user's attempt at toggling a checkbox from succeeding by canceling the corresponding <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event"><code>click</code></a> event.
|
|
532
|
+
</p>
|
|
533
|
+
<blockquote>
|
|
534
|
+
<p>
|
|
535
|
+
Note: The <code>CheckboxGroup</code> "absorbs" the <code>input</code> and <code>change</code> events dispatched by its checkboxes. Thus, if you want to listen for either of those events, you'll need to listen for them on the <code>CheckboxGroup</code>, not on the checkboxes.
|
|
536
|
+
</p>
|
|
537
|
+
</blockquote>
|
|
538
|
+
</dd>
|
|
539
|
+
|
|
540
|
+
<dt id="events-change">
|
|
541
|
+
<a href="#events-change"><code>change</code></a>
|
|
542
|
+
</dt>
|
|
543
|
+
<dd>
|
|
544
|
+
<p>Identical to the <a href="#events-input"><code>input</code></a> event, but fired <em>after</em> the <code>input</code> event.</p>
|
|
545
|
+
</dd>
|
|
546
|
+
</dl>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CheckboxGroup } from "../index.js";
|
|
2
|
+
|
|
3
|
+
declare module "preact" {
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace -- Necessary for type declaration merging
|
|
5
|
+
namespace JSX {
|
|
6
|
+
interface IntrinsicElements {
|
|
7
|
+
"checkbox-group": CheckboxGroupHTMLAttributes<CheckboxGroup>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface CheckboxGroupHTMLAttributes<T extends EventTarget = CheckboxGroup> extends HTMLAttributes<T> {
|
|
11
|
+
value?: Signalish<CheckboxGroup["value"] | undefined>;
|
|
12
|
+
name?: Signalish<CheckboxGroup["name"] | undefined>;
|
|
13
|
+
disabled?: Signalish<CheckboxGroup["disabled"] | undefined>;
|
|
14
|
+
required?: Signalish<CheckboxGroup["required"] | undefined>;
|
|
15
|
+
min?: Signalish<CheckboxGroup["min"] | number | undefined>;
|
|
16
|
+
max?: Signalish<CheckboxGroup["max"] | number | undefined>;
|
|
17
|
+
manual?: Signalish<CheckboxGroup["manual"] | undefined>;
|
|
18
|
+
valuemissingerror?: Signalish<CheckboxGroup["valueMissingError"] | undefined>;
|
|
19
|
+
rangeunderflowerror?: Signalish<CheckboxGroup["rangeUnderflowError"] | undefined>;
|
|
20
|
+
rangeoverflowerror?: Signalish<CheckboxGroup["rangeOverflowError"] | undefined>;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CheckboxGroup } from "../index.js";
|
|
2
|
+
|
|
3
|
+
declare module "react" {
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace -- Necessary for type declaration merging
|
|
5
|
+
namespace JSX {
|
|
6
|
+
interface IntrinsicElements {
|
|
7
|
+
"checkbox-group": React.DetailedHTMLProps<React.CheckboxGroupHTMLAttributes<CheckboxGroup>, CheckboxGroup>;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface CheckboxGroupHTMLAttributes<T> extends HTMLAttributes<T> {
|
|
12
|
+
value?: CheckboxGroup["value"];
|
|
13
|
+
name?: CheckboxGroup["name"];
|
|
14
|
+
disabled?: CheckboxGroup["disabled"];
|
|
15
|
+
required?: CheckboxGroup["required"];
|
|
16
|
+
min?: CheckboxGroup["min"] | number;
|
|
17
|
+
max?: CheckboxGroup["max"] | number;
|
|
18
|
+
manual?: CheckboxGroup["manual"];
|
|
19
|
+
valuemissingerror?: CheckboxGroup["valueMissingError"];
|
|
20
|
+
rangeunderflowerror?: CheckboxGroup["rangeUnderflowError"];
|
|
21
|
+
rangeoverflowerror?: CheckboxGroup["rangeOverflowError"];
|
|
22
|
+
}
|
|
23
|
+
}
|