@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
package/Combobox/README.md
CHANGED
|
@@ -1,17 +1,269 @@
|
|
|
1
1
|
# Combobox
|
|
2
2
|
|
|
3
|
-
A robust,
|
|
3
|
+
A group of robust, extendable and stylable [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) which work together to function as an accessible [`combobox`](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- **Progressive Enhacement**: When used in `Select Enhacing Mode`, the component will fallback to a regular `<select>` element if JS is disabled or unavailable for your users. This means your forms will _always_ be fully usable and accessible.
|
|
11
|
-
- **Highly Customizable**: The `combobox` component is flexible enough to work with whatever CSS you provide, and its functionality can be enhanced or overriden by [extending](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends) it.
|
|
12
|
-
- **Performant**: Unlike many other alternatives, the `combobox` component has been cleverly designed to work without complex state management tools or aggressive DOM Tree manipulation. This makes it a fast and memory-efficient solution.
|
|
13
|
-
- **No Dependencies**: The `combobox` component is built on the native web platform instead of extending other frameworks or libraries, guaranteeing your bundle size remains as small as possible.
|
|
7
|
+
```
|
|
8
|
+
npm install @itenthusiasm/custom-elements
|
|
9
|
+
```
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<!-- HTML -->
|
|
15
|
+
<form>
|
|
16
|
+
<label for="rating">Rating</label>
|
|
17
|
+
<select-enhancer>
|
|
18
|
+
<combobox-field id="rating" name="rating"></combobox-field>
|
|
19
|
+
<combobox-listbox>
|
|
20
|
+
<combobox-option>1</combobox-option>
|
|
21
|
+
<combobox-option>2</combobox-option>
|
|
22
|
+
<combobox-option>3</combobox-option>
|
|
23
|
+
<combobox-option>4</combobox-option>
|
|
24
|
+
<combobox-option selected>5</combobox-option>
|
|
25
|
+
</combobox-listbox>
|
|
26
|
+
</select-enhancer>
|
|
27
|
+
</form>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
/* JavaScript */
|
|
32
|
+
import { SelectEnhancer, ComboboxField, ComboboxListbox, ComboboxOption } from "@itenthusiasm/custom-elements";
|
|
33
|
+
// or import { SelectEnhancer, ComboboxField, ComboboxListbox, ComboboxOption } from "@itenthusiasm/custom-elements/Combobox";
|
|
34
|
+
|
|
35
|
+
// NOTE: The order in which these Custom Elements are registered is important
|
|
36
|
+
customElements.define("combobox-listbox", ComboboxListbox);
|
|
37
|
+
customElements.define("combobox-field", ComboboxField);
|
|
38
|
+
customElements.define("combobox-option", ComboboxOption);
|
|
39
|
+
customElements.define("select-enhancer", SelectEnhancer);
|
|
40
|
+
|
|
41
|
+
// Retrieve some info about the `combobox`
|
|
42
|
+
const form = document.querySelector("form");
|
|
43
|
+
const formData = new FormData(form);
|
|
44
|
+
console.log(formData.get("rating")); // 5
|
|
45
|
+
|
|
46
|
+
const combobox = document.querySelector("combobox-field");
|
|
47
|
+
console.log(combobox.form === form); // true
|
|
48
|
+
console.log(combobox.value); // 5
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To use the component's built-in styles, you can use our `Combobox.css` file. If you're using a bundler like [Vite](https://vite.dev/), you can just import this directly into one of your JS files.
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
/* JavaScript */
|
|
55
|
+
import { SelectEnhancer, ComboboxField, ComboboxListbox, ComboboxOption } from "@itenthusiasm/custom-elements";
|
|
56
|
+
import "@itenthusiasm/custom-elements/Combobox/Combobox.css";
|
|
57
|
+
|
|
58
|
+
// ...
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If you prefer to load the CSS in a [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/link) tag (which tends to be more efficient), you can copy the `Combobox.css` file to your project, modify it to look the way you want, and then load the CSS file the regular way in your HTML.
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<html>
|
|
65
|
+
<head>
|
|
66
|
+
<link rel="preload" as="style" href="/path/to/my/copy/of/Combobox.css" />
|
|
67
|
+
<!-- ... -->
|
|
68
|
+
</head>
|
|
69
|
+
|
|
70
|
+
<!-- ... -->
|
|
71
|
+
</html>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
In most cases, the `ComboboxField` custom element shown above behaves like an _enhanced_ drop-in replacement for the native [`HTMLSelectElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement). For example, it exposes a `value` property that can be used to get or set the value of the component. The `ComboboxField`'s value will always be synchronized with the state of its `ComboboxOption`s. (This matches the behavior of the native `<select>` element.) For more details on the component's attributes and properties, see the [documentation](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs/combobox-field.md).
|
|
75
|
+
|
|
76
|
+
### Select Enhancing Mode
|
|
77
|
+
|
|
78
|
+
The example HTML displayed at the [beginning](#quickstart) of this document showed the `Combobox` component being used in `Manual Setup Mode`. In `Manual Setup Mode`, the Custom Elements which make up the `Combobox` component are rendered directly to the DOM. This is recommended for SPAs.
|
|
79
|
+
|
|
80
|
+
If your application is server-rendered and you would like the component to be [progressively enhanced](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement), you can use it in `Select Enhancing Mode` instead. This mode is engaged by wrapping a regular [`<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/select) element with the `<select-enhancer>`:
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<!-- HTML -->
|
|
84
|
+
<select-enhancer>
|
|
85
|
+
<select id="rank" name="rank" filter>
|
|
86
|
+
<option value="1">First</option>
|
|
87
|
+
<option value="2">Second</option>
|
|
88
|
+
<option value="3">Third</option>
|
|
89
|
+
<option value="4">Fourth</option>
|
|
90
|
+
<option value="5" selected>Fifth</option>
|
|
91
|
+
</select>
|
|
92
|
+
</select-enhancer>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
In this case, the `<select-enhancer>` will swap the `<select>` and `<option>` elements with the appropriate `<combobox-field>`, `<combobox-listbox>`, and `<combobox-option>` elements when the page loads, copying over all relevant attributes, values, and form states in the process.
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<!-- HTML -->
|
|
99
|
+
<select-enhancer>
|
|
100
|
+
<combobox-field id="rank" name="rank" filter></combobox-field>
|
|
101
|
+
<combobox-listbox>
|
|
102
|
+
<combobox-option value="1">First</combobox-option>
|
|
103
|
+
<combobox-option value="2">Second</combobox-option>
|
|
104
|
+
<combobox-option value="3">Third</combobox-option>
|
|
105
|
+
<combobox-option value="4">Fourth</combobox-option>
|
|
106
|
+
<combobox-option value="5" selected>Fifth</combobox-option>
|
|
107
|
+
</combobox-listbox>
|
|
108
|
+
</select-enhancer>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
> If the elements are created _outside_ of the DOM, then the `<select-enhancer>` will perform this action when the elements are first mounted to the DOM instead.
|
|
112
|
+
|
|
113
|
+
`Select Enhancing Mode` is great for situations where you want your form to remain usable for people who have JS Disabled (or who fail to download it for any other reason).
|
|
114
|
+
|
|
115
|
+
Note that because `Select Enhancing Mode` manipulates the DOM to provide progressive enhancement, you should be careful when using this mode in JS Frameworks that expect to have _full_ control over the DOM. In general, if your list of `option`s is static, then `Select Enhancing Mode` should be safe to use regardless of which JS Framework you're using. However, if your `option`s are _dynamic_, then you should consider rendering a regular `<select>` element on initial render, then a `Manual Setup Mode` Combobox component after initial render. Examples of this can be found in the [documentation](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs/guides/select-enhancement-in-js-frameworks.md).
|
|
116
|
+
|
|
117
|
+
## Tips
|
|
118
|
+
|
|
119
|
+
Below are some quick tips for using the `Combobox` component. If you want to dive deeper into the component's features, we've laid out all the details of the component's attributes, properties, methods, and more in our [documentation](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs). We've also provided a demo of the component on [`StackBlitz`](https://stackblitz.com/edit/custom-elements-combobox?file=index.html,src%2Fmain.ts).
|
|
120
|
+
|
|
121
|
+
### Filter Mode
|
|
122
|
+
|
|
123
|
+
You can use the [`filter`](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs/combobox-field.md#attributes-filter) attribute to enable users to filter the available list of options in a searchbox.
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<!-- Manual Setup Mode -->
|
|
127
|
+
<select-enhancer>
|
|
128
|
+
<combobox-field filter></combobox-field>
|
|
129
|
+
<combobox-listbox>
|
|
130
|
+
<combobox-option value="1">One</combobox-option>
|
|
131
|
+
<combobox-option value="2">Two</combobox-option>
|
|
132
|
+
<combobox-option value="3">Three</combobox-option>
|
|
133
|
+
</combobox-listbox>
|
|
134
|
+
</select-enhancer>
|
|
135
|
+
|
|
136
|
+
<!-- Select Enhancing Mode -->
|
|
137
|
+
<select-enhancer>
|
|
138
|
+
<select filter>
|
|
139
|
+
<option value="1">One</option>
|
|
140
|
+
<option value="2">Two</option>
|
|
141
|
+
<option value="3">Three</option>
|
|
142
|
+
</select>
|
|
143
|
+
</select-enhancer>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Remember that in `Select Enhancing Mode`, all attributes/states will be copied from the `<select>`/`<option>` elements to the `<combobox-field>`/`<combobox-option>` elements on mount / page load.
|
|
147
|
+
|
|
148
|
+
### Configuring the Allowed Values
|
|
149
|
+
|
|
150
|
+
When the `combobox` is in `filter` mode, its allowed values can be configured with the [`valueis`](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs/combobox-field.md#attributes-valueis) attribute. (This attribute does nothing if the component is not in `filter` mode.) There are 3 allowed values:
|
|
151
|
+
|
|
152
|
+
<dl>
|
|
153
|
+
<dt><code>unclearable</code></dt>
|
|
154
|
+
<dd>
|
|
155
|
+
The <code>Combobox</code> component can only be given a value that matches one of its <code>option</code>s. If the user starts filtering the <code>option</code>s and leaves the <code>combobox</code> without selecting an <code>option</code>, then the searchbox text will be reset to the label of the currently-selected <code>option</code>.
|
|
156
|
+
</dd>
|
|
157
|
+
<dt><code>clearable</code> (Default)</dt>
|
|
158
|
+
<dd>
|
|
159
|
+
Same as <code>unclearable</code>, except that the component's value can be cleared. This can happen if the user empties the searchbox, or if the developer sets the <a href="https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs/combobox-field.md#properties-value"><code>ComboboxField.value</code></a> property to an empty string. When the component's value is cleared, the previously-selected <code>option</code> will be deselected (if one exists).
|
|
160
|
+
</dd>
|
|
161
|
+
<dt><code>anyvalue</code></dt>
|
|
162
|
+
<dd>
|
|
163
|
+
The <code>Combobox</code> component accepts any value, even if there is no matching <code>option</code>. If the user types into the <code>combobox</code> and leaves it without selecting an <code>option</code>, then searchbox text will be left alone, and the component will adopt the value of the search text. The component's value can also be set programmatically to any string.
|
|
164
|
+
</dd>
|
|
165
|
+
</dl>
|
|
166
|
+
|
|
167
|
+
```html
|
|
168
|
+
<!-- Manual Setup Mode -->
|
|
169
|
+
<select-enhancer>
|
|
170
|
+
<combobox-field filter valueis="anyvalue"></combobox-field>
|
|
171
|
+
<combobox-listbox>
|
|
172
|
+
<combobox-option value="1">One</combobox-option>
|
|
173
|
+
<combobox-option value="2">Two</combobox-option>
|
|
174
|
+
<combobox-option value="3">Three</combobox-option>
|
|
175
|
+
</combobox-listbox>
|
|
176
|
+
</select-enhancer>
|
|
177
|
+
|
|
178
|
+
<!-- Select Enhancing Mode -->
|
|
179
|
+
<select-enhancer>
|
|
180
|
+
<select filter valueis="anyvalue">
|
|
181
|
+
<option value="1">One</option>
|
|
182
|
+
<option value="2">Two</option>
|
|
183
|
+
<option value="3">Three</option>
|
|
184
|
+
</select>
|
|
185
|
+
</select-enhancer>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Remember that in `Select Enhancing Mode`, all attributes/states will be copied from the `<select>`/`<option>` elements to the `<combobox-field>`/`<combobox-option>` elements on mount / page load.
|
|
189
|
+
|
|
190
|
+
### TS Usage in Other Frameworks
|
|
191
|
+
|
|
192
|
+
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. (This also includes types for _enhanced_ elements like the enhanced `<select>` element.) To define _all_ of our library's Custom Elements within a Framework's "Element Namespace", simply import the appropriate type definition file:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import type {} from "@itenthusiasm/custom-elements/types/react";
|
|
196
|
+
// For Svelte: import type {} from "@itenthusiasm/custom-elements/types/svelte";
|
|
197
|
+
// For Vue: import type {} from "@itenthusiasm/custom-elements/types/vue";
|
|
198
|
+
// etc. ...
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
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.
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
// Define ONLY the `Combobox` component's types in the framework's "Element Namespace"
|
|
205
|
+
import type {} from "@itenthusiasm/custom-elements/Combobox/types/react";
|
|
206
|
+
// For Svelte: import type {} from "@itenthusiasm/custom-elements/Combobox/types/svelte";
|
|
207
|
+
// For Vue: import type {} from "@itenthusiasm/custom-elements/Combobox/types/vue";
|
|
208
|
+
// etc. ...
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
The component also ships with types that enhance the native DOM methods if you need them:
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import type {} from "@itenthusiasm/custom-elements/types/dom";
|
|
215
|
+
// Or more specifically, import type {} from "@itenthusiasm/custom-elements/Combobox/types/dom";
|
|
216
|
+
|
|
217
|
+
// These variables will be properly typed by TypeScript now, instead of just being general `Element` types.
|
|
218
|
+
const combobox = document.querySelector("combobox-field");
|
|
219
|
+
const listbox = document.querySelector("combobox-listbox");
|
|
220
|
+
const options = document.querySelectorAll("combobox-option");
|
|
221
|
+
const selectEnhancer = document.querySelector("select-enhancer");
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Restyling the Component
|
|
225
|
+
|
|
226
|
+
For simplicity, the `Combobox` component ships with its own default styles via the `@itenthusiasm/custom-elements/Combobox/Combobox.css` file. You're welcome to use this file directly in your application if you like. However, if you intend to modify _any_ of the styles to fit your own needs, then we recommend creating your own CSS file for the component instead, using our styles as an initial template.
|
|
227
|
+
|
|
228
|
+
There are some minor nuances that come with restyling the component. You can read about them in our [documentation](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs/guides/styling-the-combobox.md).
|
|
229
|
+
|
|
230
|
+
### Adding Icons / Buttons
|
|
231
|
+
|
|
232
|
+
Oftentimes, people prefer to add items like caret icons to their `combobox`es. The `Combobox` component allows you to do this by simply appending or prepending elements within the `<select-enhancer>`:
|
|
233
|
+
|
|
234
|
+
```html
|
|
235
|
+
<!-- Manual Setup Mode -->
|
|
236
|
+
<select-enhancer>
|
|
237
|
+
<combobox-field name="numbers"></combobox-field>
|
|
238
|
+
<combobox-listbox>
|
|
239
|
+
<combobox-option>1</combobox-option>
|
|
240
|
+
<combobox-option>2</combobox-option>
|
|
241
|
+
<combobox-option>3</combobox-option>
|
|
242
|
+
</combobox-listbox>
|
|
243
|
+
|
|
244
|
+
<svg viewBox="0 0 100 100"><!-- Caret Icon SVG Elements ... --></svg>
|
|
245
|
+
</select-enhancer>
|
|
246
|
+
|
|
247
|
+
<!-- Select Enhancing Mode -->
|
|
248
|
+
<select-enhancer>
|
|
249
|
+
<select name="numbers">
|
|
250
|
+
<option>1</option>
|
|
251
|
+
<option>2</option>
|
|
252
|
+
<option>3</option>
|
|
253
|
+
</select>
|
|
254
|
+
|
|
255
|
+
<svg viewBox="0 0 100 100"><!-- Caret Icon SVG Elements ... --></svg>
|
|
256
|
+
</select-enhancer>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Additional examples of customizing the `Combobox` component's appearance can be found in our [guides](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs/guides/styling-the-combobox.md).
|
|
260
|
+
|
|
261
|
+
## What's Next?
|
|
262
|
+
|
|
263
|
+
To learn more about all that you can accomplish with the `Combobox` component, visit our [documentation](https://github.com/ITenthusiasm/custom-elements/tree/main/src/Combobox/docs). Trust us, you've only seen the beginning of what can be done with this component!
|
|
264
|
+
|
|
265
|
+
If you're too excited to sit and read, you can also play with our [`StackBlitz` Demo](https://stackblitz.com/edit/custom-elements-combobox?file=index.html,src%2Fmain.ts) to see the `Combobox` component in action.
|
|
16
266
|
|
|
17
267
|
<!-- TODO: Link to example of styling our `combobox` to look like GitHub's or ShadcnUI's. Probably put it alongside an example of another styling approach. -->
|
|
268
|
+
|
|
269
|
+
<!-- TODO: Maybe also add some example styles for making the `<select>` look like the `<combobox-field>`? -->
|
|
@@ -37,7 +37,7 @@ declare module "preact" {
|
|
|
37
37
|
defaultSelected?: Signalish<ComboboxOption["defaultSelected"] | undefined>;
|
|
38
38
|
disabled?: Signalish<ComboboxOption["disabled"] | undefined>;
|
|
39
39
|
selected?: Signalish<ComboboxOption["selected"] | undefined>;
|
|
40
|
-
value?: Signalish<ComboboxOption["value"] | undefined>;
|
|
40
|
+
value?: Signalish<ComboboxOption["value"] | number | undefined>;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -31,7 +31,7 @@ declare module "react" {
|
|
|
31
31
|
defaultSelected?: ComboboxOption["defaultSelected"];
|
|
32
32
|
disabled?: ComboboxOption["disabled"];
|
|
33
33
|
selected?: ComboboxOption["selected"];
|
|
34
|
-
value?: ComboboxOption["value"];
|
|
34
|
+
value?: ComboboxOption["value"] | number;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// eslint-disable-next-line @typescript-eslint/no-namespace -- Necessary for type declaration merging
|
|
@@ -20,12 +20,16 @@ declare module "solid-js" {
|
|
|
20
20
|
disabled?: ComboboxField["disabled"];
|
|
21
21
|
filter?: ComboboxField["filter"];
|
|
22
22
|
filtermethod?: ComboboxField["filterMethod"];
|
|
23
|
+
"attr:filtermethod"?: ComboboxField["filterMethod"];
|
|
23
24
|
form?: string;
|
|
24
25
|
name?: ComboboxField["name"];
|
|
25
26
|
nomatchesmessage?: ComboboxField["noMatchesMessage"];
|
|
27
|
+
"attr:nomatchesmessage"?: ComboboxField["noMatchesMessage"];
|
|
26
28
|
required?: ComboboxField["required"];
|
|
27
29
|
valueis?: ComboboxField["valueIs"];
|
|
30
|
+
"attr:valueis"?: ComboboxField["valueIs"];
|
|
28
31
|
valuemissingerror?: ComboboxField["valueMissingError"];
|
|
32
|
+
"attr:valuemissingerror"?: ComboboxField["valueMissingError"];
|
|
29
33
|
|
|
30
34
|
onFilterchange?: EventHandlerUnion<T, Event>;
|
|
31
35
|
onfilterchange?: EventHandlerUnion<T, Event>;
|
|
@@ -38,8 +42,15 @@ declare module "solid-js" {
|
|
|
38
42
|
|
|
39
43
|
interface ComboboxOptionHTMLAttributes<T> extends HTMLAttributes<T> {
|
|
40
44
|
disabled?: ComboboxOption["disabled"];
|
|
41
|
-
selected?: ComboboxOption["
|
|
42
|
-
value?: ComboboxOption["value"];
|
|
45
|
+
selected?: ComboboxOption["defaultSelected"];
|
|
46
|
+
value?: ComboboxOption["value"] | number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ExplicitBoolAttributes {
|
|
50
|
+
filter?: boolean;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
required?: boolean;
|
|
53
|
+
selected?: boolean;
|
|
43
54
|
}
|
|
44
55
|
}
|
|
45
56
|
}
|
|
@@ -15,7 +15,7 @@ declare module "svelte/elements" {
|
|
|
15
15
|
optiontag?: SelectEnhancer["optionTag"] | null;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
interface HTMLComboboxFieldAttributes<T extends EventTarget> extends HTMLAttributes<T> {
|
|
18
|
+
interface HTMLComboboxFieldAttributes<T extends EventTarget = ComboboxField> extends HTMLAttributes<T> {
|
|
19
19
|
disabled?: ComboboxField["disabled"] | null;
|
|
20
20
|
filter?: ComboboxField["filter"] | null;
|
|
21
21
|
filtermethod?: ComboboxField["filterMethod"] | null;
|
|
@@ -38,6 +38,6 @@ declare module "svelte/elements" {
|
|
|
38
38
|
defaultSelected?: ComboboxOption["defaultSelected"] | null;
|
|
39
39
|
disabled?: ComboboxOption["disabled"] | null;
|
|
40
40
|
selected?: ComboboxOption["selected"] | null;
|
|
41
|
-
value?: ComboboxOption["value"] | null;
|
|
41
|
+
value?: ComboboxOption["value"] | number | null;
|
|
42
42
|
}
|
|
43
43
|
}
|
package/Combobox/types/vue.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ declare module "vue" {
|
|
|
65
65
|
defaultSelected?: ComboboxOption["defaultSelected"];
|
|
66
66
|
disabled?: ComboboxOption["disabled"];
|
|
67
67
|
selected?: ComboboxOption["selected"];
|
|
68
|
-
value?: ComboboxOption["value"];
|
|
68
|
+
value?: ComboboxOption["value"] | number;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
interface ComboboxOptionVueSFCType extends ComboboxOption {
|
package/README.md
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
1
|
# @itenthusiasm/custom-elements
|
|
2
2
|
|
|
3
|
-
Robust, accessible, and progressively-enhanceable Web Components for common developer needs.
|
|
3
|
+
Robust, accessible, and progressively-enhanceable [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) for common developer needs. Each component integrates seamlessly into your web applications, whether you use pure HTML/CSS/JS or you use a JS Framework.
|
|
4
|
+
|
|
5
|
+
## Features and Benefits
|
|
6
|
+
|
|
7
|
+
- **Framework Agnostic**: Because the components in this library are built using only Custom `HTMLElement`s, they work seamlessly in all JS Frameworks (and in pure-JS applications).
|
|
8
|
+
- **Integrates with Native Web Forms**: The components in this library [integrate](https://web.dev/articles/more-capable-form-controls) with the web's native `<form>` element, meaning that their values will be seen in the form's [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) and will be automatically [sent to the server](https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Forms/Sending_and_retrieving_form_data) when the form is submitted — all without writing a single line of JS.
|
|
9
|
+
- **Works with Various Form Libraries**: These components emit standard DOM events like [`input`](https://developer.mozilla.org/en-US/docs/Web/API/Element/input_event) and [`change`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event), enabling them to work naturally with reputable form libraries (e.g., the [`Form Observer`](https://github.com/enthusiastic-js/form-observer), [`Conform`](https://conform.guide/), and [`React Hook Form`](https://react-hook-form.com/)).
|
|
10
|
+
- **Progressive Enhacement**: Every form-associated Custom Element in this library progressively enhances the native form controls. This guarantees that your forms will _always_ be fully operable and accessible, even if your users have JS disabled.
|
|
11
|
+
- **Highly Customizable**: These components are flexible enough to work with whatever CSS you provide, and their functionality can be enhanced or overriden through [class extension](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends).
|
|
12
|
+
- **Performant**: Unlike many other alternatives, these components have been cleverly designed to work without complex state management tools or aggressive DOM Tree manipulation. This makes them fast and memory-efficient.
|
|
13
|
+
- **No Dependencies**: The components in this library are built on the native web platform instead of extending other frameworks or libraries, guaranteeing your bundle size remains as small as possible.
|
|
14
|
+
|
|
15
|
+
<!-- TODO: Link to article explaining how progressively-enhanced Form Controls _greatly_ simplify frontend code. -->
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
npm install @itenthusiasm/custom-elements
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Components
|
|
24
|
+
|
|
25
|
+
Below are the components that this library currently provides. Each component has its own `README` which you can view to learn more about how the component operates.
|
|
26
|
+
|
|
27
|
+
<dl>
|
|
28
|
+
<dt id="components-combobox">
|
|
29
|
+
<a href="./Combobox"><code>Combobox</code></a>
|
|
30
|
+
</dt>
|
|
31
|
+
<dd>
|
|
32
|
+
<p>
|
|
33
|
+
Progressively enhances the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/select"><code><select></code></a> element, transforming it into a stylable, (optionally) filterable <a href="https://www.w3.org/TR/wai-aria-1.2/#combobox"><code>combobox</code></a> which meets WAI-ARIA's <a href="https://www.w3.org/WAI/ARIA/apg/patterns/combobox/">accessibility requirements</a>. The <code>Combobox</code> component behaves just like the native form controls, meaning that it dispatches the standard <code>input</code>/<code>change</code> events, is <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements">associated</a> with its owning form, and automatically participates in all form activity, <a href="https://web.dev/articles/more-capable-form-controls">including form submission</a>.
|
|
34
|
+
</p>
|
|
35
|
+
<p>
|
|
36
|
+
<a href="https://stackblitz.com/edit/custom-elements-combobox?file=index.html,src%2Fmain.ts">Stackblitz Form Integration Demo</a>
|
|
37
|
+
</p>
|
|
38
|
+
</dd>
|
|
39
|
+
|
|
40
|
+
<dt id="components-checkbox-group">
|
|
41
|
+
<a href="./CheckboxGroup"><code>CheckboxGroup</code></a>
|
|
42
|
+
</dt>
|
|
43
|
+
<dd>
|
|
44
|
+
<p>
|
|
45
|
+
Wraps a semantic group of checkbox <code><input></code> elements, progressively enhancing them with convenient features like group-level form validation and value management. The <code>CheckboxGroup</code> component behaves just like the native form controls, meaning that it dispatches the standard <code>input</code>/<code>change</code> events, is <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements">associated</a> with its owning form, and automatically participates in all form activity, <a href="https://web.dev/articles/more-capable-form-controls">including form submission</a>.
|
|
46
|
+
</p>
|
|
47
|
+
</dd>
|
|
48
|
+
</dl>
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itenthusiasm/custom-elements",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"description": "Robust, accessible, and progressively-enhanceable Web Components for common developer needs",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"progressive-enhancement"
|
|
34
34
|
],
|
|
35
35
|
"files": [
|
|
36
|
-
"
|
|
36
|
+
"./*/README.md",
|
|
37
37
|
"./**/*.{js,css,d.ts}"
|
|
38
38
|
],
|
|
39
39
|
"exports": {
|
|
@@ -50,6 +50,10 @@
|
|
|
50
50
|
"types": "./Combobox/index.d.ts",
|
|
51
51
|
"default": "./Combobox/index.js"
|
|
52
52
|
},
|
|
53
|
+
"./CheckboxGroup": {
|
|
54
|
+
"types": "./CheckboxGroup/index.d.ts",
|
|
55
|
+
"default": "./CheckboxGroup/index.js"
|
|
56
|
+
},
|
|
53
57
|
"./*": {
|
|
54
58
|
"types": "./*.d.ts",
|
|
55
59
|
"default": "./*.js"
|
package/types/dom.d.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// NOTE: For some reason, TS complains in the JS files if we export a `type`, so we're exporting `interface`s instead.
|
|
2
|
+
/* eslint @typescript-eslint/no-empty-object-type: ["error", { "allowInterfaces": "with-single-extends" }] */
|
|
3
|
+
export interface ExposedInternals
|
|
4
|
+
extends Pick<
|
|
5
|
+
ElementInternals,
|
|
6
|
+
"labels" | "form" | "validity" | "validationMessage" | "willValidate" | "checkValidity" | "reportValidity"
|
|
7
|
+
> {}
|
|
8
|
+
|
|
9
|
+
export interface FieldPropertiesAndMethods
|
|
10
|
+
extends Pick<HTMLInputElement, "name" | "required" | "disabled" | "setCustomValidity"> {}
|
|
11
|
+
|
|
12
|
+
export interface FieldMinMax extends Pick<HTMLInputElement, "min" | "max"> {}
|
package/types/preact.d.ts
CHANGED
package/types/react.d.ts
CHANGED
package/types/solid.d.ts
CHANGED
package/types/svelte.d.ts
CHANGED
package/types/vue.d.ts
CHANGED