@itenthusiasm/custom-elements 0.7.0 → 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.
@@ -0,0 +1,29 @@
1
+ import type { CheckboxGroup } from "../index.js";
2
+
3
+ declare module "solid-js" {
4
+ namespace JSX {
5
+ interface HTMLElementTags {
6
+ "checkbox-group": CheckboxGroupHTMLAttributes<CheckboxGroup>;
7
+ }
8
+
9
+ interface CheckboxGroupHTMLAttributes<T> extends HTMLAttributes<T> {
10
+ value?: CheckboxGroup["value"];
11
+ name?: CheckboxGroup["name"];
12
+ disabled?: CheckboxGroup["disabled"];
13
+ required?: CheckboxGroup["required"];
14
+ min?: CheckboxGroup["min"] | number;
15
+ max?: CheckboxGroup["max"] | number;
16
+ manual?: CheckboxGroup["manual"];
17
+ valuemissingerror?: CheckboxGroup["valueMissingError"];
18
+ "attr:valuemissingerror"?: CheckboxGroup["valueMissingError"];
19
+ rangeunderflowerror?: CheckboxGroup["rangeUnderflowError"];
20
+ "attr:rangeunderflowerror"?: CheckboxGroup["rangeUnderflowError"];
21
+ rangeoverflowerror?: CheckboxGroup["rangeOverflowError"];
22
+ "attr:rangeoverflowerror"?: CheckboxGroup["rangeOverflowError"];
23
+ }
24
+
25
+ interface ExplicitBoolAttributes {
26
+ checked?: boolean;
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,20 @@
1
+ import type { CheckboxGroup } from "../index.js";
2
+
3
+ declare module "svelte/elements" {
4
+ interface SvelteHTMLElements {
5
+ "checkbox-group": HTMLCheckboxGroupAttributes;
6
+ }
7
+
8
+ interface HTMLCheckboxGroupAttributes extends HTMLAttributes<CheckboxGroup> {
9
+ value?: CheckboxGroup["value"] | null;
10
+ name?: CheckboxGroup["name"] | null;
11
+ disabled?: CheckboxGroup["disabled"] | null;
12
+ required?: CheckboxGroup["required"] | null;
13
+ min?: CheckboxGroup["min"] | number | null;
14
+ max?: CheckboxGroup["max"] | number | null;
15
+ manual?: CheckboxGroup["manual"] | null;
16
+ valuemissingerror?: CheckboxGroup["valueMissingError"] | null;
17
+ rangeunderflowerror?: CheckboxGroup["rangeUnderflowError"] | null;
18
+ rangeoverflowerror?: CheckboxGroup["rangeOverflowError"] | null;
19
+ }
20
+ }
@@ -0,0 +1,40 @@
1
+ import type { HTMLAttributes, PublicProps, EmitFn } from "vue";
2
+ import type { CheckboxGroup } from "../index.js";
3
+
4
+ declare module "vue" {
5
+ // Helper Types
6
+ type Booleanish = boolean | "true" | "false";
7
+ type VueEmitMap<T extends GlobalEventHandlersEventMap> = EmitFn<{ [K in keyof T]: (event: T[K]) => void }>;
8
+ interface VueGlobalHTMLAttributes extends HTMLAttributes, Omit<PublicProps, "class" | "style"> {}
9
+
10
+ /* -------------------- Register Elements -------------------- */
11
+ interface GlobalComponents {
12
+ "checkbox-group": new () => CheckboxGroupVueSFCType;
13
+ }
14
+
15
+ interface IntrinsicElementAttributes {
16
+ "checkbox-group": CheckboxGroupHTMLAttributes;
17
+ }
18
+
19
+ /* -------------------- Checkbox Group -------------------- */
20
+ interface CheckboxGroupHTMLAttributes extends VueGlobalHTMLAttributes {
21
+ value?: CheckboxGroup["value"];
22
+ name?: CheckboxGroup["name"];
23
+ disabled?: CheckboxGroup["disabled"];
24
+ required?: CheckboxGroup["required"];
25
+ min?: CheckboxGroup["min"] | number;
26
+ max?: CheckboxGroup["max"] | number;
27
+ manual?: CheckboxGroup["manual"];
28
+ valuemissingerror?: CheckboxGroup["valueMissingError"];
29
+ rangeunderflowerror?: CheckboxGroup["rangeUnderflowError"];
30
+ rangeoverflowerror?: CheckboxGroup["rangeOverflowError"];
31
+ }
32
+
33
+ interface CheckboxGroupVueSFCType extends CheckboxGroup {
34
+ /** @deprecated Only for use by Vue's templating language */
35
+ $props: CheckboxGroupHTMLAttributes;
36
+
37
+ /** @deprecated Only for use by Vue's templating language */
38
+ $emit: VueEmitMap<HTMLElementEventMap>;
39
+ }
40
+ }
@@ -1,14 +1,4 @@
1
1
  export default ComboboxField;
2
- export type ExposedInternals = Pick<ElementInternals, "labels" | "form" | "validity" | "validationMessage" | "willValidate" | "checkValidity" | "reportValidity">;
3
- export type FieldPropertiesAndMethods = Pick<HTMLInputElement, "name" | "required" | "disabled" | "setCustomValidity">;
4
- /**
5
- * @typedef {Pick<ElementInternals,
6
- "labels" | "form" | "validity" | "validationMessage" | "willValidate" | "checkValidity" | "reportValidity"
7
- >} ExposedInternals
8
- */
9
- /**
10
- * @typedef {Pick<HTMLInputElement, "name" | "required" | "disabled" | "setCustomValidity">} FieldPropertiesAndMethods
11
- */
12
2
  /** @implements {ExposedInternals} @implements {FieldPropertiesAndMethods} */
13
3
  declare class ComboboxField extends HTMLElement implements ExposedInternals, FieldPropertiesAndMethods {
14
4
  /** @returns {true} */
@@ -157,7 +147,7 @@ declare class ComboboxField extends HTMLElement implements ExposedInternals, Fie
157
147
  set filter(value: boolean);
158
148
  /** Activates a textbox that can be used to filter the list of `combobox` `option`s. @returns {boolean} */
159
149
  get filter(): boolean;
160
- set filterMethod(value: Extract<number | typeof Symbol.iterator | "normalize" | "link" | "search" | "small" | "sub" | "sup" | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "at" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" | "codePointAt" | "endsWith" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "strike" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "replaceAll" | "isWellFormed" | "toWellFormed", "startsWith" | "includes">);
150
+ set filterMethod(value: Extract<number | "normalize" | typeof Symbol.iterator | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "at" | "link" | "search" | "small" | "sub" | "sup" | "big" | "blink" | "strike" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" | "codePointAt" | "endsWith" | "repeat" | "startsWith" | "anchor" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "replaceAll" | "isWellFormed" | "toWellFormed", "startsWith" | "includes">);
161
151
  /**
162
152
  * Determines the method used to filter the `option`s as the user types.
163
153
  * - `startsWith`: {@link String.startsWith} will be used to filter the `option`s.
@@ -167,7 +157,7 @@ declare class ComboboxField extends HTMLElement implements ExposedInternals, Fie
167
157
  *
168
158
  * @returns {Extract<keyof String, "startsWith" | "includes">}
169
159
  */
170
- get filterMethod(): Extract<number | typeof Symbol.iterator | "normalize" | "link" | "search" | "small" | "sub" | "sup" | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "at" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" | "codePointAt" | "endsWith" | "repeat" | "startsWith" | "anchor" | "big" | "blink" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "strike" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "replaceAll" | "isWellFormed" | "toWellFormed", "startsWith" | "includes">;
160
+ get filterMethod(): Extract<number | "normalize" | typeof Symbol.iterator | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "includes" | "at" | "link" | "search" | "small" | "sub" | "sup" | "big" | "blink" | "strike" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" | "codePointAt" | "endsWith" | "repeat" | "startsWith" | "anchor" | "bold" | "fixed" | "fontcolor" | "fontsize" | "italics" | "padStart" | "padEnd" | "trimEnd" | "trimStart" | "trimLeft" | "trimRight" | "matchAll" | "replaceAll" | "isWellFormed" | "toWellFormed", "startsWith" | "includes">;
171
161
  set valueIs(value: "unclearable" | "clearable" | "anyvalue");
172
162
  /**
173
163
  * Indicates how a `combobox`'s value will behave.
@@ -232,6 +222,8 @@ declare class ComboboxField extends HTMLElement implements ExposedInternals, Fie
232
222
  /** @private @type {boolean} */ private [editingKey];
233
223
  #private;
234
224
  }
225
+ import type { ExposedInternals } from "../types/helpers.js";
226
+ import type { FieldPropertiesAndMethods } from "../types/helpers.js";
235
227
  import ComboboxOption from "./ComboboxOption.js";
236
228
  import type { ListboxWithChildren } from "./types/helpers.js";
237
229
  /** Internally used to retrieve the value that the `combobox` had when it was focused. */
@@ -1,4 +1,5 @@
1
1
  /** @import {ListboxWithChildren} from "./types/helpers.js" */
2
+ /** @import {ExposedInternals, FieldPropertiesAndMethods} from "../types/helpers.js" */
2
3
  import { setAttributeFor } from "../utils/dom.js";
3
4
  import ComboboxOption from "./ComboboxOption.js";
4
5
  import ComboboxListbox from "./ComboboxListbox.js";
@@ -21,16 +22,6 @@ const attrs = Object.freeze({
21
22
  "aria-expanded": "aria-expanded",
22
23
  });
23
24
 
24
- /**
25
- * @typedef {Pick<ElementInternals,
26
- "labels" | "form" | "validity" | "validationMessage" | "willValidate" | "checkValidity" | "reportValidity"
27
- >} ExposedInternals
28
- */
29
-
30
- /**
31
- * @typedef {Pick<HTMLInputElement, "name" | "required" | "disabled" | "setCustomValidity">} FieldPropertiesAndMethods
32
- */
33
-
34
25
  /** @implements {ExposedInternals} @implements {FieldPropertiesAndMethods} */
35
26
  class ComboboxField extends HTMLElement {
36
27
  /* ------------------------------ Custom Element Settings ------------------------------ */
@@ -588,7 +579,7 @@ class ComboboxField extends HTMLElement {
588
579
  }
589
580
 
590
581
  set disabled(value) {
591
- this.toggleAttribute("disabled", Boolean(value));
582
+ this.toggleAttribute("disabled", value);
592
583
  }
593
584
 
594
585
  /** @returns {HTMLInputElement["required"]} */
@@ -597,7 +588,7 @@ class ComboboxField extends HTMLElement {
597
588
  }
598
589
 
599
590
  set required(value) {
600
- this.toggleAttribute("required", Boolean(value));
591
+ this.toggleAttribute("required", value);
601
592
  }
602
593
 
603
594
  /**
@@ -628,7 +619,7 @@ class ComboboxField extends HTMLElement {
628
619
  }
629
620
 
630
621
  set filter(value) {
631
- this.toggleAttribute("filter", Boolean(value));
622
+ this.toggleAttribute("filter", value);
632
623
  }
633
624
 
634
625
  /**
@@ -2,18 +2,6 @@
2
2
 
3
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
- ## Features and Benefits
6
-
7
- - **Framework Agnostic**: Because this component simply uses custom `HTMLElement`s, it works seamlessly in all JS Frameworks (and in pure-JS applications if that's what you fancy).
8
- - **Integrates with Native Web Forms**: This component [integrates](https://web.dev/articles/more-capable-form-controls) with the web's native `<form>` element, meaning that its value 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 &mdash; all without writing a single line of JS.
9
- - **Works with Various Form Libraries**: The component emits 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 it 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**: When used in [`Select Enhacing Mode`](#select-enhancing-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 component is flexible enough to work with whatever CSS you provide, and its 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, this 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 component is 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
5
  ## Install
18
6
 
19
7
  ```
@@ -220,6 +208,19 @@ import type {} from "@itenthusiasm/custom-elements/Combobox/types/react";
220
208
  // etc. ...
221
209
  ```
222
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
+
223
224
  ### Restyling the Component
224
225
 
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.
package/README.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
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
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 &mdash; 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
+
5
17
  ## Install
6
18
 
7
19
  ```
@@ -24,4 +36,13 @@ Below are the components that this library currently provides. Each component ha
24
36
  <a href="https://stackblitz.com/edit/custom-elements-combobox?file=index.html,src%2Fmain.ts">Stackblitz Form Integration Demo</a>
25
37
  </p>
26
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>&lt;input&gt;</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>
27
48
  </dl>
package/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ export * from "./CheckboxGroup/index.js";
1
2
  export * from "./Combobox/index.js";
2
3
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1 +1,2 @@
1
+ export * from "./CheckboxGroup/index.js";
1
2
  export * from "./Combobox/index.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@itenthusiasm/custom-elements",
3
3
  "type": "module",
4
- "version": "0.7.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",
@@ -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
@@ -1 +1,2 @@
1
+ import type {} from "../CheckboxGroup/types/dom.d.ts";
1
2
  import type {} from "../Combobox/types/dom.d.ts";
@@ -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
@@ -1 +1,2 @@
1
+ import type {} from "../CheckboxGroup/types/preact.d.ts";
1
2
  import type {} from "../Combobox/types/preact.d.ts";
package/types/react.d.ts CHANGED
@@ -1 +1,2 @@
1
+ import type {} from "../CheckboxGroup/types/react.d.ts";
1
2
  import type {} from "../Combobox/types/react.d.ts";
package/types/solid.d.ts CHANGED
@@ -1 +1,2 @@
1
+ import type {} from "../CheckboxGroup/types/solid.d.ts";
1
2
  import type {} from "../Combobox/types/solid.d.ts";
package/types/svelte.d.ts CHANGED
@@ -1 +1,2 @@
1
+ import type {} from "../CheckboxGroup/types/svelte.d.ts";
1
2
  import type {} from "../Combobox/types/svelte.d.ts";
package/types/vue.d.ts CHANGED
@@ -1 +1,2 @@
1
+ import type {} from "../CheckboxGroup/types/vue.d.ts";
1
2
  import type {} from "../Combobox/types/vue.d.ts";