@w-lfpup/wctk 0.2.2 → 0.2.4

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.
Files changed (42) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -3
  3. package/dist/events.d.ts +5 -4
  4. package/dist/microtask.d.ts +4 -2
  5. package/dist/microtask.js +2 -2
  6. package/dist/query_selector.js +5 -5
  7. package/dist/wc.js +4 -7
  8. package/package.json +6 -6
  9. package/src/events.ts +11 -5
  10. package/src/microtask.ts +5 -3
  11. package/src/query_selector.ts +6 -4
  12. package/src/wc.ts +4 -9
  13. package/docs/events.md +0 -93
  14. package/docs/microtask.md +0 -32
  15. package/docs/query_selector.md +0 -37
  16. package/docs/wc.md +0 -55
  17. package/examples/counter/index.html +0 -30
  18. package/examples/counter/mod.js +0 -37
  19. package/examples/counter/mod.ts +0 -52
  20. package/examples/form_associated/index.html +0 -31
  21. package/examples/form_associated/mod.js +0 -11
  22. package/examples/form_associated/mod.ts +0 -20
  23. package/examples/form_associated/text_input.js +0 -22
  24. package/examples/form_associated/text_input.ts +0 -31
  25. package/examples/stopwatch/index.html +0 -32
  26. package/examples/stopwatch/mod.js +0 -13
  27. package/examples/stopwatch/mod.ts +0 -13
  28. package/examples/stopwatch/stopwatch.js +0 -48
  29. package/examples/stopwatch/stopwatch.ts +0 -70
  30. package/examples/tsconfig.json +0 -11
  31. package/tests/dist/events.tests.js +0 -60
  32. package/tests/dist/microtask.tests.js +0 -38
  33. package/tests/dist/mod.js +0 -10
  34. package/tests/dist/query_selector.tests.js +0 -43
  35. package/tests/dist/wc.tests.js +0 -41
  36. package/tests/src/events.tests.ts +0 -73
  37. package/tests/src/microtask.tests.ts +0 -54
  38. package/tests/src/mod.ts +0 -11
  39. package/tests/src/query_selector.tests.ts +0 -46
  40. package/tests/src/wc.tests.ts +0 -52
  41. package/tests/tsconfig.json +0 -8
  42. /package/.github/workflows/{builds.yml → tests.yml} +0 -0
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  BSD 3-Clause License
2
2
 
3
- Copyright (c) 2024, Taylor Vann
3
+ Copyright (c) 2024, Brian Taylor Vann
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
6
6
  modification, are permitted provided that the following conditions are met:
package/README.md CHANGED
@@ -6,6 +6,9 @@ An SSR friendly (w)eb(c)omponent (t)ool (k)it without dependencies.
6
6
 
7
7
  ## About
8
8
 
9
+ The `wctk` is a collection of bare-metal facades over vanilla browser apis. They provide the basics for
10
+ events, reactivity, and forms.
11
+
9
12
  There are no base classes, decorators, or mixins.
10
13
 
11
14
  All features are compositional and designed for SSR and [declarative shadow dom](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM#declaratively_with_html).
@@ -59,9 +62,6 @@ The following examples demonstrate several common SSR use cases:
59
62
 
60
63
  ## Design Goals
61
64
 
62
- The `wctk` is a collection of bare-metal facades over vanilla browser apis. They provide the basics for
63
- events, reactivity, and forms.
64
-
65
65
  If you know vanilla javascript and the DOM you are good to go.
66
66
 
67
67
  The `wctk` is designed with SSR and declarative shadow dom in mind. Developers
package/dist/events.d.ts CHANGED
@@ -1,19 +1,20 @@
1
1
  interface GenericEventListener<E extends Event> {
2
2
  (evt: E): void;
3
3
  }
4
- interface GenericEventListenerObject<E extends Event> {
4
+ interface GenericEventListenerObject<E extends Event> extends EventListenerObject {
5
5
  handleEvent(object: E): void;
6
6
  }
7
7
  type GenericCallbacks<E extends Event> = GenericEventListener<E> | GenericEventListenerObject<E>;
8
- type EventMap = Partial<{
9
- [Property in keyof GlobalEventHandlersEventMap]: GenericCallbacks<GlobalEventHandlersEventMap[Property]>;
8
+ type EventMaps = DocumentEventMap & GlobalEventHandlersEventMap & ElementEventMap;
9
+ type ListenerMap = Partial<{
10
+ [Property in keyof EventMaps]: GenericCallbacks<EventMaps[Property]>;
10
11
  }> | Record<string, EventListenerOrEventListenerObject>;
11
12
  interface EventElementInterface {
12
13
  addEventListener: Element["addEventListener"];
13
14
  removeEventListener: Element["removeEventListener"];
14
15
  }
15
16
  export interface EventParamsInterface {
16
- listeners: EventMap;
17
+ listeners: ListenerMap;
17
18
  connected?: boolean;
18
19
  target: EventElementInterface;
19
20
  }
@@ -1,10 +1,12 @@
1
1
  export interface MicrotaskInterface {
2
2
  queue(): void;
3
3
  }
4
- type Callback = () => void;
4
+ interface Callback {
5
+ (): void;
6
+ }
5
7
  export declare class Microtask implements MicrotaskInterface {
6
8
  #private;
7
- constructor(callback: Callback);
8
9
  queue: () => void;
10
+ constructor(callback: Callback);
9
11
  }
10
12
  export {};
package/dist/microtask.js CHANGED
@@ -1,17 +1,17 @@
1
1
  export class Microtask {
2
2
  #queued = false;
3
3
  #callback;
4
+ #microtask = this.#unboundMicrotask.bind(this);
5
+ queue = this.#queue.bind(this);
4
6
  constructor(callback) {
5
7
  this.#callback = callback;
6
8
  }
7
- queue = this.#queue.bind(this);
8
9
  #queue() {
9
10
  if (this.#queued)
10
11
  return;
11
12
  this.#queued = true;
12
13
  window.queueMicrotask(this.#microtask);
13
14
  }
14
- #microtask = this.#unboundMicrotask.bind(this);
15
15
  #unboundMicrotask() {
16
16
  this.#queued = false;
17
17
  this.#callback();
@@ -13,11 +13,11 @@ export class QuerySelector {
13
13
  return query;
14
14
  }
15
15
  querySelectorAll(selector) {
16
- let results = this.#queryAlls.get(selector);
17
- if (results)
18
- return results;
19
- let query = Array.from(this.#parentNode.querySelectorAll(selector));
20
- this.#queryAlls.set(selector, query);
16
+ let query = this.#queryAlls.get(selector);
17
+ if (!query) {
18
+ query = Array.from(this.#parentNode.querySelectorAll(selector));
19
+ this.#queryAlls.set(selector, query);
20
+ }
21
21
  return query;
22
22
  }
23
23
  deleteAll() {
package/dist/wc.js CHANGED
@@ -8,13 +8,10 @@ export class Wc {
8
8
  constructor(params) {
9
9
  let { adoptedStyleSheets, host, formState, formValue, shadowRootInit } = params;
10
10
  this.#internals = host.attachInternals();
11
- if (this.#internals.shadowRoot) {
12
- this.#declarative = true;
13
- this.#shadowRoot = this.#internals.shadowRoot;
14
- }
15
- else {
16
- this.#shadowRoot = host.attachShadow(shadowRootInit ?? shadowRootInitFallback);
17
- }
11
+ this.#declarative = null !== this.#internals.shadowRoot;
12
+ this.#shadowRoot =
13
+ this.#internals.shadowRoot ??
14
+ host.attachShadow(shadowRootInit ?? shadowRootInitFallback);
18
15
  this.adoptedStyleSheets = adoptedStyleSheets ?? [];
19
16
  if (formValue)
20
17
  this.setFormValue(formValue, formState);
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "main": "dist/mod.js",
5
5
  "description": "A bare-metal webcomponent toolkit",
6
6
  "license": "BSD-3-Clause",
7
- "version": "0.2.2",
7
+ "version": "0.2.4",
8
8
  "scripts": {
9
9
  "prepare": "npm run build",
10
10
  "build": "npm run build:src && npm run build:tests && npm run build:examples",
@@ -15,13 +15,13 @@
15
15
  "test:browsers": "npx jackrabbit_webdriver jr.json tests/dist/mod.js",
16
16
  "format": "prettier --write ./"
17
17
  },
18
- "devDependencies": {
19
- "@w-lfpup/jackrabbit": "^0.3.2",
20
- "prettier": "^3.8.3",
21
- "typescript": "^6.0.2"
22
- },
23
18
  "repository": {
24
19
  "type": "git",
25
20
  "url": "git+https://github.com/w-lfpup/wctk-js.git"
21
+ },
22
+ "devDependencies": {
23
+ "@w-lfpup/jackrabbit": "^0.3.3",
24
+ "prettier": "^3.8.4",
25
+ "typescript": "^6.0.3"
26
26
  }
27
27
  }
package/src/events.ts CHANGED
@@ -2,7 +2,9 @@ interface GenericEventListener<E extends Event> {
2
2
  (evt: E): void;
3
3
  }
4
4
 
5
- interface GenericEventListenerObject<E extends Event> {
5
+ interface GenericEventListenerObject<
6
+ E extends Event,
7
+ > extends EventListenerObject {
6
8
  handleEvent(object: E): void;
7
9
  }
8
10
 
@@ -10,10 +12,14 @@ type GenericCallbacks<E extends Event> =
10
12
  | GenericEventListener<E>
11
13
  | GenericEventListenerObject<E>;
12
14
 
13
- type EventMap =
15
+ type EventMaps = DocumentEventMap &
16
+ GlobalEventHandlersEventMap &
17
+ ElementEventMap;
18
+
19
+ type ListenerMap =
14
20
  | Partial<{
15
- [Property in keyof GlobalEventHandlersEventMap]: GenericCallbacks<
16
- GlobalEventHandlersEventMap[Property]
21
+ [Property in keyof EventMaps]: GenericCallbacks<
22
+ EventMaps[Property]
17
23
  >;
18
24
  }>
19
25
  | Record<string, EventListenerOrEventListenerObject>;
@@ -26,7 +32,7 @@ interface EventElementInterface {
26
32
  }
27
33
 
28
34
  export interface EventParamsInterface {
29
- listeners: EventMap;
35
+ listeners: ListenerMap;
30
36
  connected?: boolean;
31
37
  target: EventElementInterface;
32
38
  }
package/src/microtask.ts CHANGED
@@ -2,17 +2,20 @@ export interface MicrotaskInterface {
2
2
  queue(): void;
3
3
  }
4
4
 
5
- type Callback = () => void;
5
+ interface Callback {
6
+ (): void;
7
+ }
6
8
 
7
9
  export class Microtask implements MicrotaskInterface {
8
10
  #queued = false;
9
11
  #callback: Callback;
12
+ #microtask = this.#unboundMicrotask.bind(this);
13
+ queue = this.#queue.bind(this);
10
14
 
11
15
  constructor(callback: Callback) {
12
16
  this.#callback = callback;
13
17
  }
14
18
 
15
- queue = this.#queue.bind(this);
16
19
  #queue() {
17
20
  if (this.#queued) return;
18
21
  this.#queued = true;
@@ -20,7 +23,6 @@ export class Microtask implements MicrotaskInterface {
20
23
  window.queueMicrotask(this.#microtask);
21
24
  }
22
25
 
23
- #microtask = this.#unboundMicrotask.bind(this);
24
26
  #unboundMicrotask() {
25
27
  this.#queued = false;
26
28
  this.#callback();
@@ -18,15 +18,17 @@ export class QuerySelector implements QuerySelectorInterface {
18
18
 
19
19
  let query = this.#parentNode.querySelector(selector) ?? undefined;
20
20
  this.#queries.set(selector, query);
21
+
21
22
  return query;
22
23
  }
23
24
 
24
25
  querySelectorAll(selector: string): Element[] {
25
- let results = this.#queryAlls.get(selector);
26
- if (results) return results;
26
+ let query = this.#queryAlls.get(selector);
27
+ if (!query) {
28
+ query = Array.from(this.#parentNode.querySelectorAll(selector));
29
+ this.#queryAlls.set(selector, query);
30
+ }
27
31
 
28
- let query = Array.from(this.#parentNode.querySelectorAll(selector));
29
- this.#queryAlls.set(selector, query);
30
32
  return query;
31
33
  }
32
34
 
package/src/wc.ts CHANGED
@@ -36,15 +36,10 @@ export class Wc implements WcInterface {
36
36
  params;
37
37
 
38
38
  this.#internals = host.attachInternals();
39
-
40
- if (this.#internals.shadowRoot) {
41
- this.#declarative = true;
42
- this.#shadowRoot = this.#internals.shadowRoot;
43
- } else {
44
- this.#shadowRoot = host.attachShadow(
45
- shadowRootInit ?? shadowRootInitFallback,
46
- );
47
- }
39
+ this.#declarative = null !== this.#internals.shadowRoot;
40
+ this.#shadowRoot =
41
+ this.#internals.shadowRoot ??
42
+ host.attachShadow(shadowRootInit ?? shadowRootInitFallback);
48
43
 
49
44
  this.adoptedStyleSheets = adoptedStyleSheets ?? [];
50
45
  if (formValue) this.setFormValue(formValue, formState);
package/docs/events.md DELETED
@@ -1,93 +0,0 @@
1
- # Events Controller
2
-
3
- Add event listeners to webcomponents.
4
-
5
- ## How to use
6
-
7
- Add an `Events` controller to a webcomponent. Use a params object on instantiation.
8
-
9
- ### Params
10
-
11
- An Events `params` object has three properties:
12
-
13
- ```ts
14
- interface EventParams {
15
- connected?: boolean;
16
- listeners: Record<string, EventListenerOrEventListenerObject>;
17
- target: EventTarget;
18
- }
19
- ```
20
-
21
- The `Events` controller adds event listeners on a `target` node.
22
-
23
- The `target` node can be a shadowRoot, a document, or the custom element itself.
24
-
25
- ### Controller
26
-
27
- Here is an example of using the `Events` controller.
28
-
29
- ```ts
30
- import { Events, Wc } from "wctk";
31
-
32
- class MyElement extends HTMLElement {
33
- #wc = new Wc({ this: host });
34
-
35
- #ec = new Events({
36
- target: this.#wc.shadowRoot,
37
- listeners: {
38
- click: this.#onClick.bind(this),
39
- keydown: this.#onKeyDown.bind(this),
40
- },
41
- });
42
-
43
- #onClick(e: PointerEvent) {
44
- // do something with pointer events here!
45
- }
46
-
47
- #onKeyDown(e: KeyboardEvent) {
48
- // do something with key events here!
49
- }
50
-
51
- // lifecycle method
52
- connectedCallback() {
53
- this.#ec.connect();
54
- }
55
-
56
- // lifecycle method
57
- disconnectedCallback() {
58
- this.#ec.disconnect();
59
- }
60
- }
61
- ```
62
-
63
- ### Shortcut life-cycle methods
64
-
65
- In the example below, the `connected` property is set to true and listeners are immediately added to the `target`.
66
-
67
- ```ts
68
- import { Events, Wc } from "wctk";
69
-
70
- class MyElement extends HTMLElement {
71
- #wc = new Wc({ this: host });
72
- #ec = new Events({
73
- connected: true,
74
- target: this.#wc.shadowRoot,
75
- listeners: {
76
- click: this.#onClick.bind(this),
77
- keydown: this.#onKeyDown.bind(this),
78
- },
79
- });
80
-
81
- #onClick(e: PointerEvent) {
82
- // do something with pointer events here!
83
- }
84
-
85
- #onKeyDown(e: KeyEvent) {
86
- // do something with key events here!
87
- }
88
- }
89
- ```
90
-
91
- ### More complex interactions
92
-
93
- If your component requires more complex declarative interactions, consider [superaction](https://github.com/w-lfpup/superaction-js/)
package/docs/microtask.md DELETED
@@ -1,32 +0,0 @@
1
- # Microtask Controller
2
-
3
- Add callbacks to the `microtask queue`.
4
-
5
- ## How to use
6
-
7
- Add a `Microtask` controller to a webcomponent. Provide a callback.
8
-
9
- Call `Microtask.queue()` to push the callback to the microtask queue.
10
-
11
- In the example below, a `Microtask` controller queues a render when the `width` attribute changes.
12
-
13
- ```ts
14
- import { Microtask } from "wctk";
15
-
16
- class MyElement extends HTMLElement {
17
- static observedAttributes = ["width"];
18
-
19
- #rc = new Microtask(this.#render.bind(this));
20
-
21
- #render() {
22
- // update DOM here!
23
- }
24
-
25
- // lifecycle method
26
- attributeChangedCallback() {
27
- this.#rc.queue();
28
- }
29
- }
30
- ```
31
-
32
- The `Microtask.queue()` method can be called multiple times per event loop but the callback will only be called _once_ during the microtaskqueue phase of the event-loop.
@@ -1,37 +0,0 @@
1
- # QuerySelector Controller
2
-
3
- Lazily map selector queries.
4
-
5
- ## How to use
6
-
7
- Add a `QuerySelector` controller to a webcomponent.
8
-
9
- ```html
10
- <my-element>
11
- <template shadowrootmode="closed">
12
- <span greeting>UwU</span>
13
- </template>
14
- </my-element>
15
- ```
16
-
17
- Every query is cached. Call `<QuerySelector>.deleteAll()` to reset the cache (helpful after a new render).
18
-
19
- ```ts
20
- import { QuerySelector } from "wctk";
21
-
22
- class MyElement extends HTMLElement {
23
- #wc = new Wc({ host: this });
24
- #qc = new QuerySelector(this.#wc.shadowRoot);
25
-
26
- showcaseApi() {
27
- // first Element or undefined
28
- let greeting = this.#qc.querySelector("[greeting]");
29
-
30
- // Element[]
31
- let greetings = this.#qc.querySelectorAll("[greeting]");
32
-
33
- // create new cache
34
- this.#qc.deleteAll();
35
- }
36
- }
37
- ```
package/docs/wc.md DELETED
@@ -1,55 +0,0 @@
1
- # Wc Controller
2
-
3
- Build a webcomponent.
4
-
5
- ## How to use
6
-
7
- Add a `Wc` controller to a custom element:
8
-
9
- ```ts
10
- import { Wc } from "wctk";
11
-
12
- class MyElement extends HTMLElement {
13
- #wc = new Wc({ host: this });
14
- }
15
- ```
16
-
17
- ## Adopted stylesheets and form values
18
-
19
- The `Wc` controller interfaces with core web componet APIs like adopted stylesheets and form values.
20
-
21
- ```ts
22
- class MyElement extends HTMLElement {
23
- #wc = new Wc({
24
- host: this,
25
- // https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#options
26
- shadowRootInit: { mode: "open" },
27
- adoptedStyleSheets: [],
28
- formValue: "^_^",
29
- formState: ":3",
30
- });
31
-
32
- showcaseApi() {
33
- // true if declarative shadow dom is present
34
- this.#wc.delcarative;
35
-
36
- // https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot
37
- this.#wc.shadowRoot;
38
-
39
- // https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/adoptedStyleSheets
40
- this.#wc.adopedStylesheets;
41
-
42
- // https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue
43
- this.#wc.setFormValue(value, state);
44
-
45
- // https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity
46
- this.#wc.checkValidity();
47
-
48
- // https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity
49
- this.#wc.reportValidity();
50
-
51
- // https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity
52
- this.#wc.setValidity(flags, message);
53
- }
54
- }
55
- ```
@@ -1,30 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en-us">
3
- <head>
4
- <meta charset=utf-8>
5
- <meta name=viewport content="width=device-width, initial-scale=1">
6
- <script type="importmap">
7
- {
8
- "imports": {
9
- "wctk": "../../dist/mod.js"
10
- }
11
- }
12
- </script>
13
- <script src="./mod.js" type=module></script>
14
- </head>
15
- <body>
16
- <main>
17
- <!-- webcomponent -->
18
- <counter-wc>
19
- <template shadowrootmode="closed">
20
- <button decrease>-</button>
21
- <slot></slot>
22
- <button increase>+</button>
23
- </template>
24
-
25
- <!-- DOM content -->
26
- <span>42</span>
27
- </counter-wc>
28
- </main>
29
- </body>
30
- </html>
@@ -1,37 +0,0 @@
1
- import { Wc, Events } from "wctk";
2
- class Counter extends HTMLElement {
3
- #wc = new Wc({ host: this });
4
- #ev = new Events({
5
- connected: true,
6
- target: this.#wc.shadowRoot,
7
- listeners: {
8
- click: this.#clickHandler.bind(this),
9
- },
10
- });
11
- #state = getStateFromDOM(this.#wc.shadowRoot);
12
- #clickHandler(e) {
13
- let increment = getIncrement(e);
14
- if (increment) {
15
- this.#state.count += increment;
16
- let el = this.#state.el;
17
- if (el)
18
- el.textContent = this.#state.count.toString();
19
- }
20
- }
21
- }
22
- function getStateFromDOM(shadowRoot) {
23
- let slot = shadowRoot.querySelector("slot");
24
- let el;
25
- if (slot)
26
- for (let slotted of slot.assignedNodes()) {
27
- if (slotted instanceof HTMLSpanElement)
28
- el = slotted;
29
- }
30
- return { el, count: parseInt(el?.textContent ?? "0") };
31
- }
32
- function getIncrement(e) {
33
- if (e.target instanceof HTMLButtonElement) {
34
- return e.target.hasAttribute("increase") ? 1 : -1;
35
- }
36
- }
37
- customElements.define("counter-wc", Counter);
@@ -1,52 +0,0 @@
1
- /*
2
- Custom Element with state and interactivity.
3
- */
4
-
5
- import { Wc, Events } from "wctk";
6
-
7
- interface State {
8
- el: HTMLSpanElement | undefined;
9
- count: number;
10
- }
11
-
12
- class Counter extends HTMLElement {
13
- #wc = new Wc({ host: this });
14
-
15
- #ev = new Events({
16
- connected: true,
17
- target: this.#wc.shadowRoot,
18
- listeners: {
19
- click: this.#clickHandler.bind(this),
20
- },
21
- });
22
-
23
- #state: State = getStateFromDOM(this.#wc.shadowRoot);
24
-
25
- #clickHandler(e: PointerEvent) {
26
- let increment = getIncrement(e);
27
- if (increment) {
28
- this.#state.count += increment;
29
- let el = this.#state.el;
30
- if (el) el.textContent = this.#state.count.toString();
31
- }
32
- }
33
- }
34
-
35
- function getStateFromDOM(shadowRoot: ShadowRoot): State {
36
- let slot = shadowRoot.querySelector("slot");
37
- let el: HTMLSpanElement | undefined;
38
- if (slot)
39
- for (let slotted of slot.assignedNodes()) {
40
- if (slotted instanceof HTMLSpanElement) el = slotted;
41
- }
42
-
43
- return { el, count: parseInt(el?.textContent ?? "0") };
44
- }
45
-
46
- function getIncrement(e: Event) {
47
- if (e.target instanceof HTMLButtonElement) {
48
- return e.target.hasAttribute("increase") ? 1 : -1;
49
- }
50
- }
51
-
52
- customElements.define("counter-wc", Counter);
@@ -1,31 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en-us">
3
- <head>
4
- <meta charset=utf-8>
5
- <meta name=viewport content="width=device-width, initial-scale=1">
6
- <script type="importmap">
7
- {
8
- "imports": {
9
- "wctk": "../../dist/mod.js"
10
- }
11
- }
12
- </script>
13
- <script src="./mod.js" type=module></script>
14
- </head>
15
- <body>
16
- <main>
17
- <form>
18
- <!-- html component input -->
19
- <input name="html_element">
20
- <!-- custom element input -->
21
- <text-input name="web_component">
22
- <template shadowrootmode="closed">
23
- <input>
24
- </template>
25
- </text-input>
26
- <button type="submit">submit !</button>
27
- </form>
28
- <pre results></pre>
29
- </main>
30
- </body>
31
- </html>
@@ -1,11 +0,0 @@
1
- import { TextInput } from "./text_input.js";
2
- customElements.define("text-input", TextInput);
3
- const results = document.querySelector("[results]");
4
- document.addEventListener("submit", function (e) {
5
- if (!(e.target instanceof HTMLFormElement))
6
- return;
7
- e.preventDefault();
8
- let formdata = new FormData(e.target);
9
- if (results)
10
- results.textContent = JSON.stringify(Object.fromEntries(formdata), undefined, " ");
11
- });
@@ -1,20 +0,0 @@
1
- import { TextInput } from "./text_input.js";
2
-
3
- customElements.define("text-input", TextInput);
4
-
5
- const results = document.querySelector("[results]");
6
-
7
- document.addEventListener("submit", function (e: SubmitEvent) {
8
- if (!(e.target instanceof HTMLFormElement)) return;
9
-
10
- e.preventDefault();
11
-
12
- let formdata: FormData = new FormData(e.target);
13
-
14
- if (results)
15
- results.textContent = JSON.stringify(
16
- Object.fromEntries(formdata),
17
- undefined,
18
- " ",
19
- );
20
- });