gg-wf-scripts 2.5.0 → 3.0.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/README.md +33 -0
- package/dist/action-engine.d.ts +2 -0
- package/dist/action-engine.js +97 -0
- package/dist/action-engine.js.map +1 -0
- package/dist/actions.d.ts +5 -0
- package/dist/actions.js +2 -0
- package/dist/actions.js.map +1 -0
- package/dist/attrs.d.ts +59 -0
- package/dist/attrs.js +67 -0
- package/dist/attrs.js.map +1 -0
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +28 -0
- package/dist/auth.js.map +1 -0
- package/dist/bridges.d.ts +1 -0
- package/dist/bridges.js +43 -0
- package/dist/bridges.js.map +1 -0
- package/dist/data-engine.d.ts +2 -0
- package/dist/data-engine.js +153 -0
- package/dist/data-engine.js.map +1 -0
- package/dist/dialog.d.ts +1 -0
- package/dist/dialog.js +93 -0
- package/dist/dialog.js.map +1 -0
- package/dist/dom-observer.d.ts +4 -0
- package/dist/dom-observer.js +47 -0
- package/dist/dom-observer.js.map +1 -0
- package/dist/engine-deps.d.ts +23 -0
- package/dist/engine-deps.js +2 -0
- package/dist/engine-deps.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/form-action-engine.d.ts +2 -0
- package/dist/form-action-engine.js +173 -0
- package/dist/form-action-engine.js.map +1 -0
- package/dist/form-actions.d.ts +10 -0
- package/dist/form-actions.js +2 -0
- package/dist/form-actions.js.map +1 -0
- package/dist/form-visibility.d.ts +1 -0
- package/dist/form-visibility.js +109 -0
- package/dist/form-visibility.js.map +1 -0
- package/dist/helpers/dom.d.ts +16 -0
- package/dist/helpers/dom.js +39 -0
- package/dist/helpers/dom.js.map +1 -0
- package/dist/helpers/form-field.d.ts +19 -0
- package/dist/helpers/form-field.js +58 -0
- package/dist/helpers/form-field.js.map +1 -0
- package/dist/helpers/path.d.ts +2 -0
- package/dist/helpers/path.js +9 -0
- package/dist/helpers/path.js.map +1 -0
- package/dist/helpers/run-handler.d.ts +26 -0
- package/dist/helpers/run-handler.js +36 -0
- package/dist/helpers/run-handler.js.map +1 -0
- package/dist/helpers/run-with-loading.d.ts +6 -0
- package/dist/helpers/run-with-loading.js +28 -0
- package/dist/helpers/run-with-loading.js.map +1 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/queries.d.ts +1 -0
- package/dist/queries.js +2 -0
- package/dist/queries.js.map +1 -0
- package/dist/query-params.d.ts +19 -0
- package/dist/query-params.js +160 -0
- package/dist/query-params.js.map +1 -0
- package/dist/switch-engine.d.ts +1 -0
- package/dist/switch-engine.js +28 -0
- package/dist/switch-engine.js.map +1 -0
- package/package.json +25 -2
- package/src/action-engine.js +0 -64
- package/src/actions.js +0 -14
- package/src/auth.js +0 -28
- package/src/bridges.js +0 -31
- package/src/data-engine.js +0 -165
- package/src/dialog.js +0 -86
- package/src/form-action-engine.js +0 -149
- package/src/form-actions.js +0 -21
- package/src/form-visibility.js +0 -122
- package/src/helpers/dom.js +0 -35
- package/src/helpers/log.js +0 -34
- package/src/helpers/path.js +0 -4
- package/src/index.js +0 -60
- package/src/queries.js +0 -14
- package/src/query-params.js +0 -144
- package/src/switch-engine.js +0 -22
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.js","sourceRoot":"","sources":["../src/dialog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared MutationObserver. Engines call `onElement(selector, handler)` to be
|
|
3
|
+
* notified when a matching element is present at start time **or** later
|
|
4
|
+
* inserted into the DOM (Webflow IX, CMS templates, custom elements). One
|
|
5
|
+
* observer for the whole library — not one per engine.
|
|
6
|
+
*
|
|
7
|
+
* `start()` returns the global teardown; `onElement()` returns a per-handler
|
|
8
|
+
* teardown so engines can clean up their own subscriptions in dispose().
|
|
9
|
+
*/
|
|
10
|
+
const subscriptions = [];
|
|
11
|
+
let observer = null;
|
|
12
|
+
export function onElement(selector, handler) {
|
|
13
|
+
const sub = { selector, handler };
|
|
14
|
+
subscriptions.push(sub);
|
|
15
|
+
document.querySelectorAll(selector).forEach(handler);
|
|
16
|
+
return () => {
|
|
17
|
+
const idx = subscriptions.indexOf(sub);
|
|
18
|
+
if (idx >= 0)
|
|
19
|
+
subscriptions.splice(idx, 1);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function startDomObserver() {
|
|
23
|
+
if (observer)
|
|
24
|
+
return () => { };
|
|
25
|
+
observer = new MutationObserver((mutations) => {
|
|
26
|
+
for (const m of mutations) {
|
|
27
|
+
m.addedNodes.forEach((node) => {
|
|
28
|
+
if (!(node instanceof Element))
|
|
29
|
+
return;
|
|
30
|
+
for (const sub of subscriptions) {
|
|
31
|
+
if (node.matches(sub.selector))
|
|
32
|
+
sub.handler(node);
|
|
33
|
+
node
|
|
34
|
+
.querySelectorAll(sub.selector)
|
|
35
|
+
.forEach((el) => sub.handler(el));
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
41
|
+
return () => {
|
|
42
|
+
observer?.disconnect();
|
|
43
|
+
observer = null;
|
|
44
|
+
subscriptions.length = 0;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=dom-observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom-observer.js","sourceRoot":"","sources":["../src/dom-observer.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,MAAM,aAAa,GAAmB,EAAE,CAAC;AACzC,IAAI,QAAQ,GAA4B,IAAI,CAAC;AAE7C,MAAM,UAAU,SAAS,CACvB,QAAgB,EAChB,OAAuB;IAEvB,MAAM,GAAG,GAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAChD,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO,GAAG,EAAE;QACV,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,GAAG,IAAI,CAAC;YAAE,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,IAAI,QAAQ;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAC9B,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;QAC5C,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBAC5B,IAAI,CAAC,CAAC,IAAI,YAAY,OAAO,CAAC;oBAAE,OAAO;gBACvC,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;oBAChC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;wBAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAClD,IAAI;yBACD,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC;yBAC9B,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,OAAO,GAAG,EAAE;QACV,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,QAAQ,GAAG,IAAI,CAAC;QAChB,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { GgErrorEvent } from "./errors.js";
|
|
2
|
+
import type { Query } from "./queries.js";
|
|
3
|
+
import type { Action } from "./actions.js";
|
|
4
|
+
import type { FormAction } from "./form-actions.js";
|
|
5
|
+
/**
|
|
6
|
+
* The minimum surface every engine needs. Engines should depend on this (or a
|
|
7
|
+
* superset) instead of the full `App<TContext>` so they're easier to test and
|
|
8
|
+
* the dependency graph stays explicit.
|
|
9
|
+
*/
|
|
10
|
+
export type EngineCore<TContext> = {
|
|
11
|
+
context: TContext;
|
|
12
|
+
debug: boolean;
|
|
13
|
+
emitError: (event: GgErrorEvent) => void;
|
|
14
|
+
};
|
|
15
|
+
export type DataEngineDeps<TContext> = EngineCore<TContext> & {
|
|
16
|
+
queries: Record<string, Query<TContext>>;
|
|
17
|
+
};
|
|
18
|
+
export type ActionEngineDeps<TContext> = EngineCore<TContext> & {
|
|
19
|
+
actions: Record<string, Action<TContext>>;
|
|
20
|
+
};
|
|
21
|
+
export type FormActionEngineDeps<TContext> = EngineCore<TContext> & {
|
|
22
|
+
formActions: Record<string, FormAction<TContext>>;
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-deps.js","sourceRoot":"","sources":["../src/engine-deps.ts"],"names":[],"mappings":""}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emitted whenever a registered query, action, or form action throws — and
|
|
3
|
+
* for non-throwing failure modes the engines detect (missing handler, wrong
|
|
4
|
+
* return shape). Subscribe via `app.onError(handler)` to forward to Sentry,
|
|
5
|
+
* Datadog, or any other error tracker.
|
|
6
|
+
*/
|
|
7
|
+
export type GgErrorEvent = {
|
|
8
|
+
/** Engine label, e.g. "[gg-action]", "[gg-data]", "[gg-form-action]". */
|
|
9
|
+
prefix: string;
|
|
10
|
+
/** Handler id (the value of the gg-action / gg-data / gg-form-action attr). */
|
|
11
|
+
id: string;
|
|
12
|
+
/** The thrown error or a string describing the non-throw failure. */
|
|
13
|
+
error: unknown;
|
|
14
|
+
/** Engine-specific context: trigger element, form, params, etc. */
|
|
15
|
+
fields?: Record<string, unknown>;
|
|
16
|
+
};
|
|
17
|
+
export type ErrorHandler = (event: GgErrorEvent) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Internal helper that owns the subscriber list. Lives on the App instance.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createErrorBus(): {
|
|
22
|
+
subscribe: (handler: ErrorHandler) => () => void;
|
|
23
|
+
emit: (event: GgErrorEvent) => void;
|
|
24
|
+
clear: () => void;
|
|
25
|
+
};
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal helper that owns the subscriber list. Lives on the App instance.
|
|
3
|
+
*/
|
|
4
|
+
export function createErrorBus() {
|
|
5
|
+
const handlers = [];
|
|
6
|
+
return {
|
|
7
|
+
subscribe(handler) {
|
|
8
|
+
handlers.push(handler);
|
|
9
|
+
return () => {
|
|
10
|
+
const idx = handlers.indexOf(handler);
|
|
11
|
+
if (idx >= 0)
|
|
12
|
+
handlers.splice(idx, 1);
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
emit(event) {
|
|
16
|
+
handlers.forEach((h) => {
|
|
17
|
+
try {
|
|
18
|
+
h(event);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
console.error("[gg] onError handler threw:", err);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
clear() {
|
|
26
|
+
handlers.length = 0;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,MAAM,UAAU,cAAc;IAK5B,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,OAAO;QACL,SAAS,CAAC,OAAO;YACf,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,OAAO,GAAG,EAAE;gBACV,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACtC,IAAI,GAAG,IAAI,CAAC;oBAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACxC,CAAC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,KAAK;YACR,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACrB,IAAI,CAAC;oBACH,CAAC,CAAC,KAAK,CAAC,CAAC;gBACX,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK;YACH,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { ATTR, SEL } from "./attrs.js";
|
|
2
|
+
import { populateFields } from "./helpers/dom.js";
|
|
3
|
+
import { findInputs } from "./helpers/form-field.js";
|
|
4
|
+
import { runHandler } from "./helpers/run-handler.js";
|
|
5
|
+
import { runWithLoading } from "./helpers/run-with-loading.js";
|
|
6
|
+
import { onElement } from "./dom-observer.js";
|
|
7
|
+
import { getParams } from "./query-params.js";
|
|
8
|
+
function clearFieldError(form, name) {
|
|
9
|
+
findInputs(form, name).forEach((el) => {
|
|
10
|
+
el.removeAttribute(ATTR.formFieldInvalid);
|
|
11
|
+
});
|
|
12
|
+
const escaped = CSS.escape(name);
|
|
13
|
+
form
|
|
14
|
+
.querySelectorAll(`[${ATTR.formFieldError}="${escaped}"]`)
|
|
15
|
+
.forEach((el) => {
|
|
16
|
+
el.textContent = "";
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function clearFormErrors(form) {
|
|
20
|
+
form.querySelectorAll(SEL.formFieldInvalid).forEach((el) => {
|
|
21
|
+
el.removeAttribute(ATTR.formFieldInvalid);
|
|
22
|
+
});
|
|
23
|
+
form.querySelectorAll(SEL.formFieldError).forEach((el) => {
|
|
24
|
+
el.textContent = "";
|
|
25
|
+
});
|
|
26
|
+
form.querySelectorAll(SEL.formError).forEach((el) => {
|
|
27
|
+
el.textContent = "";
|
|
28
|
+
});
|
|
29
|
+
form.querySelectorAll(SEL.formErrorList).forEach((list) => {
|
|
30
|
+
const template = list.querySelector(SEL.listTemplate);
|
|
31
|
+
Array.from(list.children).forEach((child) => {
|
|
32
|
+
if (child !== template)
|
|
33
|
+
child.remove();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function applyFieldErrors(form, fieldErrors) {
|
|
38
|
+
fieldErrors.forEach(({ name, message }) => {
|
|
39
|
+
if (!name)
|
|
40
|
+
return;
|
|
41
|
+
findInputs(form, name).forEach((el) => {
|
|
42
|
+
el.setAttribute(ATTR.formFieldInvalid, "true");
|
|
43
|
+
});
|
|
44
|
+
const escaped = CSS.escape(name);
|
|
45
|
+
form
|
|
46
|
+
.querySelectorAll(`[${ATTR.formFieldError}="${escaped}"]`)
|
|
47
|
+
.forEach((el) => {
|
|
48
|
+
el.textContent = message ?? "";
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function applyErrorList(form, fieldErrors) {
|
|
53
|
+
form.querySelectorAll(SEL.formErrorList).forEach((list) => {
|
|
54
|
+
const template = list.querySelector(SEL.listTemplate);
|
|
55
|
+
if (!template) {
|
|
56
|
+
console.warn(`[${ATTR.formErrorList}] no [${ATTR.listTemplate}] inside list:`, list);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
fieldErrors.forEach((record) => {
|
|
60
|
+
const clone = template.cloneNode(true);
|
|
61
|
+
clone.removeAttribute(ATTR.listTemplate);
|
|
62
|
+
clone.style.display = "";
|
|
63
|
+
populateFields(clone, record);
|
|
64
|
+
list.appendChild(clone);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function applyFormError(form, error) {
|
|
69
|
+
if (error == null)
|
|
70
|
+
return;
|
|
71
|
+
const message = typeof error === "string" ? error : String(error);
|
|
72
|
+
form.querySelectorAll(SEL.formError).forEach((el) => {
|
|
73
|
+
el.textContent = message;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function bindFieldClearOnInput(form) {
|
|
77
|
+
if (form.__ggFormErrorBound)
|
|
78
|
+
return;
|
|
79
|
+
form.__ggFormErrorBound = true;
|
|
80
|
+
form.addEventListener("input", (e) => {
|
|
81
|
+
const target = e.target;
|
|
82
|
+
if (!(target instanceof Element))
|
|
83
|
+
return;
|
|
84
|
+
const name = target.getAttribute("name");
|
|
85
|
+
if (!name)
|
|
86
|
+
return;
|
|
87
|
+
if (target.hasAttribute(ATTR.formFieldInvalid)) {
|
|
88
|
+
clearFieldError(form, name);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async function handleSubmit(form, event, deps) {
|
|
93
|
+
const id = form.getAttribute(ATTR.formAction);
|
|
94
|
+
if (!id)
|
|
95
|
+
return;
|
|
96
|
+
const action = deps.formActions[id];
|
|
97
|
+
if (!action) {
|
|
98
|
+
console.warn(`[gg-form-action] no form action registered for "${id}"`);
|
|
99
|
+
deps.emitError({
|
|
100
|
+
prefix: "[gg-form-action]",
|
|
101
|
+
id,
|
|
102
|
+
error: "no form action registered",
|
|
103
|
+
fields: { form },
|
|
104
|
+
});
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
if (form.hasAttribute(ATTR.loading))
|
|
109
|
+
return;
|
|
110
|
+
if (form.hasAttribute(ATTR.confirm)) {
|
|
111
|
+
const text = form.getAttribute(ATTR.confirmText) || "Are you sure?";
|
|
112
|
+
if (!window.confirm(text))
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
clearFormErrors(form);
|
|
116
|
+
const formData = new FormData(form);
|
|
117
|
+
const params = getParams();
|
|
118
|
+
const submitControls = form.querySelectorAll('button[type="submit"], button:not([type]), input[type="submit"]');
|
|
119
|
+
const handlerResult = await runWithLoading([form, ...submitControls], () => runHandler({
|
|
120
|
+
prefix: "[gg-form-action]",
|
|
121
|
+
id,
|
|
122
|
+
fields: {
|
|
123
|
+
form,
|
|
124
|
+
formData: Object.fromEntries(formData),
|
|
125
|
+
params: Object.fromEntries(params),
|
|
126
|
+
},
|
|
127
|
+
debug: deps.debug,
|
|
128
|
+
emitError: deps.emitError,
|
|
129
|
+
}, () => action(deps.context, formData, params)));
|
|
130
|
+
if (!handlerResult.ok) {
|
|
131
|
+
applyFormError(form, "Something went wrong. Please try again.");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const result = handlerResult.value;
|
|
135
|
+
if (result && result.ok === false) {
|
|
136
|
+
const failure = result;
|
|
137
|
+
const fieldErrors = Array.isArray(failure.field_errors)
|
|
138
|
+
? failure.field_errors
|
|
139
|
+
: [];
|
|
140
|
+
applyFieldErrors(form, fieldErrors);
|
|
141
|
+
applyErrorList(form, fieldErrors);
|
|
142
|
+
applyFormError(form, failure.error);
|
|
143
|
+
if (!fieldErrors.length && failure.error == null) {
|
|
144
|
+
console.warn(`[gg-form-action] "${id}" returned ok:false with no error or field_errors`);
|
|
145
|
+
}
|
|
146
|
+
deps.emitError({
|
|
147
|
+
prefix: "[gg-form-action]",
|
|
148
|
+
id,
|
|
149
|
+
error: failure.error ?? "validation",
|
|
150
|
+
fields: { form, fieldErrors },
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
export function initFormActionEngine(deps) {
|
|
155
|
+
const unbind = onElement(SEL.formAction, (el) => {
|
|
156
|
+
if (el instanceof HTMLFormElement)
|
|
157
|
+
bindFieldClearOnInput(el);
|
|
158
|
+
});
|
|
159
|
+
const onSubmit = (e) => {
|
|
160
|
+
const form = e.target;
|
|
161
|
+
if (form instanceof HTMLFormElement &&
|
|
162
|
+
form.hasAttribute(ATTR.formAction)) {
|
|
163
|
+
bindFieldClearOnInput(form);
|
|
164
|
+
handleSubmit(form, e, deps);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
document.addEventListener("submit", onSubmit);
|
|
168
|
+
return () => {
|
|
169
|
+
unbind();
|
|
170
|
+
document.removeEventListener("submit", onSubmit);
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=form-action-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-action-engine.js","sourceRoot":"","sources":["../src/form-action-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type FormFieldError = {
|
|
2
|
+
name: string;
|
|
3
|
+
message: string;
|
|
4
|
+
};
|
|
5
|
+
export type FormActionResult = {
|
|
6
|
+
ok: boolean;
|
|
7
|
+
error?: unknown;
|
|
8
|
+
field_errors?: FormFieldError[];
|
|
9
|
+
};
|
|
10
|
+
export type FormAction<TContext = unknown> = (context: TContext, formData: FormData, params: URLSearchParams) => Promise<FormActionResult | void> | FormActionResult | void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-actions.js","sourceRoot":"","sources":["../src/form-actions.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function initFormVisibility(): () => void;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ATTR, SEL } from "./attrs.js";
|
|
2
|
+
import { readField } from "./helpers/form-field.js";
|
|
3
|
+
import { onElement } from "./dom-observer.js";
|
|
4
|
+
const TRANSITION_MS = 200;
|
|
5
|
+
function parseConditions(attr) {
|
|
6
|
+
return attr
|
|
7
|
+
.split(",")
|
|
8
|
+
.map((pair) => {
|
|
9
|
+
const [name, value] = pair.split(":");
|
|
10
|
+
return { name: name?.trim() ?? "", value: value?.trim() ?? "" };
|
|
11
|
+
})
|
|
12
|
+
.filter((p) => p.name && p.value);
|
|
13
|
+
}
|
|
14
|
+
function matchesAny(scope, conditions) {
|
|
15
|
+
return conditions.some(({ name, value }) => readField(scope, name) === value);
|
|
16
|
+
}
|
|
17
|
+
const bindings = new WeakMap();
|
|
18
|
+
function setupVisibility(el) {
|
|
19
|
+
if (bindings.has(el))
|
|
20
|
+
return;
|
|
21
|
+
const attr = el.getAttribute(ATTR.visibleWhen);
|
|
22
|
+
if (!attr)
|
|
23
|
+
return;
|
|
24
|
+
const scope = el.closest(SEL.formScopeOrForm);
|
|
25
|
+
if (!scope) {
|
|
26
|
+
console.warn(`[${ATTR.visibleWhen}] element is not inside a <form> or [${ATTR.formScope}]:`, el);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const conditions = parseConditions(attr);
|
|
30
|
+
el.style.transition = "none";
|
|
31
|
+
el.style.opacity = "0";
|
|
32
|
+
el.style.display = "none";
|
|
33
|
+
el.style.pointerEvents = "none";
|
|
34
|
+
el.setAttribute("inert", "");
|
|
35
|
+
el.setAttribute("aria-hidden", "true");
|
|
36
|
+
let lastState = false;
|
|
37
|
+
let hideTimer;
|
|
38
|
+
function show() {
|
|
39
|
+
if (hideTimer !== undefined) {
|
|
40
|
+
clearTimeout(hideTimer);
|
|
41
|
+
hideTimer = undefined;
|
|
42
|
+
}
|
|
43
|
+
el.removeAttribute("inert");
|
|
44
|
+
el.removeAttribute("aria-hidden");
|
|
45
|
+
el.style.display = "";
|
|
46
|
+
el.style.pointerEvents = "";
|
|
47
|
+
requestAnimationFrame(() => {
|
|
48
|
+
el.style.opacity = "1";
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function hide() {
|
|
52
|
+
el.style.opacity = "0";
|
|
53
|
+
el.style.pointerEvents = "none";
|
|
54
|
+
el.setAttribute("inert", "");
|
|
55
|
+
el.setAttribute("aria-hidden", "true");
|
|
56
|
+
hideTimer = setTimeout(() => {
|
|
57
|
+
el.style.display = "none";
|
|
58
|
+
hideTimer = undefined;
|
|
59
|
+
}, TRANSITION_MS);
|
|
60
|
+
}
|
|
61
|
+
function evaluate() {
|
|
62
|
+
const shouldShow = matchesAny(scope, conditions);
|
|
63
|
+
if (shouldShow === lastState)
|
|
64
|
+
return;
|
|
65
|
+
lastState = shouldShow;
|
|
66
|
+
if (shouldShow)
|
|
67
|
+
show();
|
|
68
|
+
else
|
|
69
|
+
hide();
|
|
70
|
+
}
|
|
71
|
+
scope.addEventListener("change", evaluate);
|
|
72
|
+
scope.addEventListener("input", evaluate);
|
|
73
|
+
requestAnimationFrame(() => {
|
|
74
|
+
el.style.transition = `opacity ${TRANSITION_MS}ms ease`;
|
|
75
|
+
evaluate();
|
|
76
|
+
});
|
|
77
|
+
bindings.set(el, {
|
|
78
|
+
el,
|
|
79
|
+
scope,
|
|
80
|
+
conditions,
|
|
81
|
+
evaluate,
|
|
82
|
+
cleanup: () => {
|
|
83
|
+
scope.removeEventListener("change", evaluate);
|
|
84
|
+
scope.removeEventListener("input", evaluate);
|
|
85
|
+
if (hideTimer !== undefined)
|
|
86
|
+
clearTimeout(hideTimer);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
export function initFormVisibility() {
|
|
91
|
+
const tracked = [];
|
|
92
|
+
const unbind = onElement(SEL.visibleWhen, (el) => {
|
|
93
|
+
if (!(el instanceof HTMLElement))
|
|
94
|
+
return;
|
|
95
|
+
tracked.push(el);
|
|
96
|
+
setupVisibility(el);
|
|
97
|
+
});
|
|
98
|
+
return () => {
|
|
99
|
+
unbind();
|
|
100
|
+
tracked.forEach((el) => {
|
|
101
|
+
const b = bindings.get(el);
|
|
102
|
+
if (b) {
|
|
103
|
+
b.cleanup();
|
|
104
|
+
bindings.delete(el);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=form-visibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-visibility.js","sourceRoot":"","sources":["../src/form-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,aAAa,GAAG,GAAG,CAAC;AAI1B,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAa,EAAE;QACvB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;IAClE,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,UAAU,CAAC,KAAiB,EAAE,UAAuB;IAC5D,OAAO,UAAU,CAAC,IAAI,CACpB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,CACtD,CAAC;AACJ,CAAC;AAUD,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAwB,CAAC;AAErD,SAAS,eAAe,CAAC,EAAe;IACtC,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAAE,OAAO;IAE7B,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CACV,IAAI,IAAI,CAAC,WAAW,wCAAwC,IAAI,CAAC,SAAS,IAAI,EAC9E,EAAE,CACH,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAEzC,EAAE,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;IAC7B,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;IACvB,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IAC1B,EAAE,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;IAChC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC7B,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAEvC,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,SAAoD,CAAC;IAEzD,SAAS,IAAI;QACX,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,SAAS,GAAG,SAAS,CAAC;QACxB,CAAC;QACD,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC5B,EAAE,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QAClC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;QACtB,EAAE,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC;QAC5B,qBAAqB,CAAC,GAAG,EAAE;YACzB,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,IAAI;QACX,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;QACvB,EAAE,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;QAChC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC7B,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACvC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YAC1B,SAAS,GAAG,SAAS,CAAC;QACxB,CAAC,EAAE,aAAa,CAAC,CAAC;IACpB,CAAC;IAED,SAAS,QAAQ;QACf,MAAM,UAAU,GAAG,UAAU,CAAC,KAAM,EAAE,UAAU,CAAC,CAAC;QAClD,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO;QACrC,SAAS,GAAG,UAAU,CAAC;QACvB,IAAI,UAAU;YAAE,IAAI,EAAE,CAAC;;YAClB,IAAI,EAAE,CAAC;IACd,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3C,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE1C,qBAAqB,CAAC,GAAG,EAAE;QACzB,EAAE,CAAC,KAAK,CAAC,UAAU,GAAG,WAAW,aAAa,SAAS,CAAC;QACxD,QAAQ,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE;QACf,EAAE;QACF,KAAK;QACL,UAAU;QACV,QAAQ;QACR,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC9C,KAAK,CAAC,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC7C,IAAI,SAAS,KAAK,SAAS;gBAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACvD,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE;QAC/C,IAAI,CAAC,CAAC,EAAE,YAAY,WAAW,CAAC;YAAE,OAAO;QACzC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,eAAe,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACV,MAAM,EAAE,CAAC;QACT,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;YACrB,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC3B,IAAI,CAAC,EAAE,CAAC;gBACN,CAAC,CAAC,OAAO,EAAE,CAAC;gBACZ,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set textContent on every [gg-field] descendant of `root` to the value
|
|
3
|
+
* at that field's dot-path on `record`. Null / missing values are left
|
|
4
|
+
* as-is (keeps whatever the markup's default content was).
|
|
5
|
+
*/
|
|
6
|
+
export declare function populateFields(root: Element, record: unknown): void;
|
|
7
|
+
/**
|
|
8
|
+
* Write a normalized switch state onto an element.
|
|
9
|
+
* null / undefined become "" so gg-case="" can serve as the empty/default.
|
|
10
|
+
*/
|
|
11
|
+
export declare function setSwitchState(el: Element, value: unknown): void;
|
|
12
|
+
/**
|
|
13
|
+
* Show the [gg-case] child whose value matches the container's current
|
|
14
|
+
* gg-switch-state; hide the rest with display:none.
|
|
15
|
+
*/
|
|
16
|
+
export declare function applySwitchState(container: Element): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getPath } from "./path.js";
|
|
2
|
+
/**
|
|
3
|
+
* Set textContent on every [gg-field] descendant of `root` to the value
|
|
4
|
+
* at that field's dot-path on `record`. Null / missing values are left
|
|
5
|
+
* as-is (keeps whatever the markup's default content was).
|
|
6
|
+
*/
|
|
7
|
+
export function populateFields(root, record) {
|
|
8
|
+
root.querySelectorAll("[gg-field]").forEach((el) => {
|
|
9
|
+
const path = el.getAttribute("gg-field");
|
|
10
|
+
if (!path)
|
|
11
|
+
return;
|
|
12
|
+
const value = getPath(record, path);
|
|
13
|
+
if (value != null)
|
|
14
|
+
el.textContent = String(value);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Write a normalized switch state onto an element.
|
|
19
|
+
* null / undefined become "" so gg-case="" can serve as the empty/default.
|
|
20
|
+
*/
|
|
21
|
+
export function setSwitchState(el, value) {
|
|
22
|
+
el.setAttribute("gg-switch-state", value == null ? "" : String(value));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Show the [gg-case] child whose value matches the container's current
|
|
26
|
+
* gg-switch-state; hide the rest with display:none.
|
|
27
|
+
*/
|
|
28
|
+
export function applySwitchState(container) {
|
|
29
|
+
const state = container.getAttribute("gg-switch-state") ?? "";
|
|
30
|
+
Array.from(container.children).forEach((child) => {
|
|
31
|
+
if (!(child instanceof HTMLElement))
|
|
32
|
+
return;
|
|
33
|
+
if (!child.hasAttribute("gg-case"))
|
|
34
|
+
return;
|
|
35
|
+
const match = child.getAttribute("gg-case") === state;
|
|
36
|
+
child.style.display = match ? "" : "none";
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=dom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../src/helpers/dom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,MAAe;IAC3D,IAAI,CAAC,gBAAgB,CAAc,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;QAC9D,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,KAAK,IAAI,IAAI;YAAE,EAAE,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAW,EAAE,KAAc;IACxD,EAAE,CAAC,YAAY,CAAC,iBAAiB,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAkB;IACjD,MAAM,KAAK,GAAG,SAAS,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IAC9D,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAC/C,IAAI,CAAC,CAAC,KAAK,YAAY,WAAW,CAAC;YAAE,OAAO;QAC5C,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC;YAAE,OAAO;QAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC;QACtD,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type FieldInput = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
|
2
|
+
/**
|
|
3
|
+
* Find every named input/select/textarea matching `name` within `scope`.
|
|
4
|
+
* Used by the data engine, form-action engine, and form-visibility — anywhere
|
|
5
|
+
* we need to read or write a form field by its `name` attribute.
|
|
6
|
+
*/
|
|
7
|
+
export declare function findInputs(scope: ParentNode, name: string): FieldInput[];
|
|
8
|
+
/**
|
|
9
|
+
* Read the current value of a named field. For radio/checkbox groups, returns
|
|
10
|
+
* the value of the checked input (or null if none checked). Returns null when
|
|
11
|
+
* no matching input exists. Trimmed for text-like inputs.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readField(scope: ParentNode, name: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Write a value into every input matching `name`, dispatching input/change so
|
|
16
|
+
* downstream listeners (visibility, query-bind) react. Skipped when value is
|
|
17
|
+
* null/undefined, so callers can pass `getPath(record, name)` directly.
|
|
18
|
+
*/
|
|
19
|
+
export declare function writeField(scope: ParentNode, name: string, value: unknown): void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find every named input/select/textarea matching `name` within `scope`.
|
|
3
|
+
* Used by the data engine, form-action engine, and form-visibility — anywhere
|
|
4
|
+
* we need to read or write a form field by its `name` attribute.
|
|
5
|
+
*/
|
|
6
|
+
export function findInputs(scope, name) {
|
|
7
|
+
const escaped = CSS.escape(name);
|
|
8
|
+
return Array.from(scope.querySelectorAll(`input[name="${escaped}"], select[name="${escaped}"], textarea[name="${escaped}"]`));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Read the current value of a named field. For radio/checkbox groups, returns
|
|
12
|
+
* the value of the checked input (or null if none checked). Returns null when
|
|
13
|
+
* no matching input exists. Trimmed for text-like inputs.
|
|
14
|
+
*/
|
|
15
|
+
export function readField(scope, name) {
|
|
16
|
+
const inputs = findInputs(scope, name);
|
|
17
|
+
if (!inputs.length)
|
|
18
|
+
return null;
|
|
19
|
+
const first = inputs[0];
|
|
20
|
+
const type = (first.getAttribute("type") || "").toLowerCase();
|
|
21
|
+
if (type === "radio" || type === "checkbox") {
|
|
22
|
+
for (const input of inputs) {
|
|
23
|
+
if (input instanceof HTMLInputElement && input.checked) {
|
|
24
|
+
return input.value;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return first.value.trim();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Write a value into every input matching `name`, dispatching input/change so
|
|
33
|
+
* downstream listeners (visibility, query-bind) react. Skipped when value is
|
|
34
|
+
* null/undefined, so callers can pass `getPath(record, name)` directly.
|
|
35
|
+
*/
|
|
36
|
+
export function writeField(scope, name, value) {
|
|
37
|
+
if (value == null)
|
|
38
|
+
return;
|
|
39
|
+
findInputs(scope, name).forEach((el) => {
|
|
40
|
+
if (el instanceof HTMLInputElement) {
|
|
41
|
+
if (el.type === "checkbox") {
|
|
42
|
+
el.checked = Boolean(value);
|
|
43
|
+
}
|
|
44
|
+
else if (el.type === "radio") {
|
|
45
|
+
el.checked = String(el.value) === String(value);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
el.value = String(value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
el.value = String(value);
|
|
53
|
+
}
|
|
54
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
55
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=form-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-field.js","sourceRoot":"","sources":["../../src/helpers/form-field.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,IAAY;IACxD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC,IAAI,CACf,KAAK,CAAC,gBAAgB,CACpB,eAAe,OAAO,oBAAoB,OAAO,sBAAsB,OAAO,IAAI,CACnF,CACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,IAAY;IACvD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9D,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAC5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,YAAY,gBAAgB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBACvD,OAAO,KAAK,CAAC,KAAK,CAAC;YACrB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAiB,EACjB,IAAY,EACZ,KAAc;IAEd,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO;IAC1B,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;QACrC,IAAI,EAAE,YAAY,gBAAgB,EAAE,CAAC;YACnC,IAAI,EAAE,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC3B,EAAE,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC/B,EAAE,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Resolve a dot-path on an object, e.g. getPath(row, "school.name"). */
|
|
2
|
+
export function getPath(obj, path) {
|
|
3
|
+
return path.split(".").reduce((acc, key) => {
|
|
4
|
+
if (acc == null)
|
|
5
|
+
return undefined;
|
|
6
|
+
return acc[key];
|
|
7
|
+
}, obj);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=path.js.map
|