@brytdesigns/web-component-form-sync 1.0.5 → 1.0.6

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,121 @@
1
+ import { customShadowlessElement, correctElementType } from '@brytdesigns/web-component-utils';
2
+ import { createMemo, createEffect, on, onCleanup } from 'solid-js';
3
+
4
+ // src/index.ts
5
+
6
+ // src/utils.ts
7
+ function handleRadioOrCheckboxChange(form, input) {
8
+ const element = Array.from(form.elements).find((elem) => {
9
+ return (
10
+ //@ts-ignore
11
+ elem.name === input.name && elem.value === input.value && !elem.checked
12
+ );
13
+ });
14
+ if (!element) return;
15
+ element.checked = true;
16
+ element.dispatchEvent(new Event("change", { bubbles: true }));
17
+ element.dispatchEvent(new Event("input", { bubbles: true }));
18
+ return true;
19
+ }
20
+ function handleDefaultChange(form, input) {
21
+ const element = Array.from(form.elements).find(
22
+ //@ts-ignore
23
+ (elem) => elem.name === input.name && elem.value !== input.value
24
+ );
25
+ if (!element) return;
26
+ element.value = input.value;
27
+ element.dispatchEvent(new Event("change", { bubbles: true }));
28
+ element.dispatchEvent(new Event("input", { bubbles: true }));
29
+ return true;
30
+ }
31
+ function receiveUpdate(form) {
32
+ return function(event) {
33
+ if (event.detail.relatedTarget === form) return;
34
+ const input = event.detail.changedTarget;
35
+ if (input.type === "checkbox")
36
+ return handleRadioOrCheckboxChange(form, input);
37
+ if (input.type === "radio") return handleRadioOrCheckboxChange(form, input);
38
+ return handleDefaultChange(form, input);
39
+ };
40
+ }
41
+ function receiveReset(form) {
42
+ return function(event) {
43
+ if (event.detail.relatedForm === form) return;
44
+ const isReset = Array.from(form.elements).filter(
45
+ // @ts-ignore
46
+ (elem) => elem.checked && !elem.hasAttribute("checked")
47
+ ).length === 0;
48
+ if (isReset) return;
49
+ if (typeof form.reset === "function") form.reset();
50
+ else form.reset.click();
51
+ };
52
+ }
53
+
54
+ // src/components/form-sync.ts
55
+ var FormSync = (props, { element }) => {
56
+ if (!props.name && !props.formId) return;
57
+ const form = createMemo(
58
+ () => element.querySelector(`#${props.formId}`)
59
+ );
60
+ const UPDATE = createMemo(() => `form.update.${props.name}`);
61
+ const RESET = createMemo(() => `form.reset.${props.name}`);
62
+ const handleUpdate = (form2) => (event) => {
63
+ dispatchEvent(
64
+ new CustomEvent(UPDATE(), {
65
+ detail: {
66
+ relatedTarget: form2,
67
+ changedTarget: event.target
68
+ }
69
+ })
70
+ );
71
+ };
72
+ const handleReset = (form2) => (event) => {
73
+ setTimeout(() => {
74
+ dispatchEvent(
75
+ new CustomEvent(RESET(), {
76
+ detail: {
77
+ relatedForm: form2,
78
+ resetForm: event.target
79
+ }
80
+ })
81
+ );
82
+ });
83
+ };
84
+ createEffect(
85
+ on(form, (form2) => {
86
+ if (!form2 || !props.name) return;
87
+ const controller = new AbortController();
88
+ const handleFormUpdate = handleUpdate(form2);
89
+ const handleReceiveUpdate = receiveUpdate(form2);
90
+ const handleFormReset = handleReset(form2);
91
+ const handleReceiveReset = receiveReset(form2);
92
+ element.addEventListener("input", handleFormUpdate, {
93
+ signal: controller.signal
94
+ });
95
+ element.addEventListener("reset", handleFormReset, {
96
+ signal: controller.signal
97
+ });
98
+ addEventListener(UPDATE(), handleReceiveUpdate, {
99
+ signal: controller.signal
100
+ });
101
+ addEventListener(RESET(), handleReceiveReset, {
102
+ signal: controller.signal
103
+ });
104
+ onCleanup(() => {
105
+ controller.abort("Resetting event listeners");
106
+ });
107
+ })
108
+ );
109
+ };
110
+
111
+ // src/index.ts
112
+ customShadowlessElement(
113
+ "form-sync",
114
+ {
115
+ name: "",
116
+ formId: ""
117
+ },
118
+ correctElementType(FormSync)
119
+ );
120
+ //# sourceMappingURL=index.js.map
121
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils.ts","../../src/components/form-sync.ts","../../src/index.ts"],"names":["form"],"mappings":"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","file":"index.js","sourcesContent":["export type FormSyncUpdateEvent = CustomEvent<{\n relatedTarget: HTMLFormElement;\n changedTarget: HTMLInputElement;\n}>;\n\nexport type FormSyncResetEvent = CustomEvent<{\n relatedForm: HTMLFormElement;\n resetForm: HTMLFormElement;\n}>;\n\nexport function handleRadioOrCheckboxChange(\n form: HTMLFormElement,\n input: HTMLInputElement\n) {\n const element = Array.from(form.elements).find((elem) => {\n return (\n //@ts-ignore\n elem.name === input.name && elem.value === input.value && !elem.checked\n );\n }) as HTMLInputElement;\n if (!element) return;\n element.checked = true;\n element.dispatchEvent(new Event(\"change\", { bubbles: true }));\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n return true;\n}\n\nexport function handleDefaultChange(\n form: HTMLFormElement,\n input: HTMLInputElement\n) {\n const element = Array.from(form.elements).find(\n //@ts-ignore\n (elem) => elem.name === input.name && elem.value !== input.value\n ) as HTMLInputElement;\n if (!element) return;\n element.value = input.value;\n\n element.dispatchEvent(new Event(\"change\", { bubbles: true }));\n element.dispatchEvent(new Event(\"input\", { bubbles: true }));\n return true;\n}\n\nexport function receiveUpdate(form: HTMLFormElement) {\n return function (event: FormSyncUpdateEvent) {\n if (event.detail.relatedTarget === form) return;\n const input = event.detail.changedTarget;\n\n if (input.type === \"checkbox\")\n return handleRadioOrCheckboxChange(form, input);\n if (input.type === \"radio\") return handleRadioOrCheckboxChange(form, input);\n\n return handleDefaultChange(form, input);\n };\n}\n\nexport function receiveReset(form: HTMLFormElement) {\n return function (event: FormSyncResetEvent) {\n if (event.detail.relatedForm === form) return;\n const isReset =\n Array.from(form.elements).filter(\n // @ts-ignore\n (elem) => elem.checked && !elem.hasAttribute(\"checked\")\n ).length === 0;\n\n if (isReset) return;\n\n if (typeof form.reset === \"function\") form.reset();\n // If reset button is present, trigger its click event\n // @ts-ignore\n else form.reset.click();\n };\n}\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-utils\";\n\nimport { createEffect, createMemo, on, onCleanup } from \"solid-js\";\n\nimport { receiveUpdate, receiveReset } from \"../utils.js\";\n\ntype FormSyncProps = {\n name: string;\n formId: string;\n};\n\nexport const FormSync: CorrectComponentType<FormSyncProps> = (\n props,\n { element }\n) => {\n if (!props.name && !props.formId) return;\n const form = createMemo(() =>\n element.querySelector<HTMLFormElement>(`#${props.formId}`)\n );\n const UPDATE = createMemo(() => `form.update.${props.name}`);\n const RESET = createMemo(() => `form.reset.${props.name}`);\n\n const handleUpdate = (form: HTMLFormElement) => (event: Event) => {\n dispatchEvent(\n new CustomEvent(UPDATE(), {\n detail: {\n relatedTarget: form,\n changedTarget: event.target,\n },\n })\n );\n };\n\n const handleReset = (form: HTMLFormElement) => (event: Event) => {\n setTimeout(() => {\n dispatchEvent(\n new CustomEvent(RESET(), {\n detail: {\n relatedForm: form,\n resetForm: event.target,\n },\n })\n );\n });\n };\n\n createEffect(\n on(form, (form) => {\n if (!form || !props.name) return;\n const controller = new AbortController();\n const handleFormUpdate = handleUpdate(form);\n const handleReceiveUpdate = receiveUpdate(form);\n\n const handleFormReset = handleReset(form);\n const handleReceiveReset = receiveReset(form);\n\n element.addEventListener(\"input\", handleFormUpdate, {\n signal: controller.signal,\n });\n element.addEventListener(\"reset\", handleFormReset, {\n signal: controller.signal,\n });\n\n //@ts-ignore\n addEventListener(UPDATE(), handleReceiveUpdate, {\n signal: controller.signal,\n });\n //@ts-ignore\n addEventListener(RESET(), handleReceiveReset, {\n signal: controller.signal,\n });\n\n onCleanup(() => {\n controller.abort(\"Resetting event listeners\");\n });\n })\n );\n};\n","import {\n customShadowlessElement,\n correctElementType,\n} from \"@brytdesigns/web-component-utils\";\nimport { FormSync } from \"./components/index.js\";\n\ncustomShadowlessElement(\n \"form-sync\",\n {\n name: \"\",\n formId: \"\",\n },\n correctElementType(FormSync)\n);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brytdesigns/web-component-form-sync",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Web component for syncing the values of multiple forms",
5
5
  "main": "./dist/main/index.js",
6
6
  "module": "./dist/main/index.js",