@primate/marko 0.9.0 → 0.10.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/lib/private/I18NModule.d.ts +5 -0
- package/lib/private/I18NModule.js +2 -0
- package/lib/private/client/Data.d.ts +5 -0
- package/lib/private/client/Data.js +2 -0
- package/lib/private/client/Payload.d.ts +7 -0
- package/lib/private/client/Payload.js +2 -0
- package/lib/private/client/app.d.ts +5 -0
- package/lib/private/client/app.js +53 -0
- package/lib/private/client/root.d.ts +15 -0
- package/lib/private/client/root.js +16 -0
- package/lib/private/create-root.d.ts +3 -0
- package/lib/private/create-root.js +20 -0
- package/lib/private/default.js +84 -2
- package/lib/private/i18n.d.ts +3 -0
- package/lib/private/i18n.js +38 -0
- package/lib/private/init.d.ts +2 -2
- package/lib/private/init.js +5 -4
- package/lib/private/request/store.d.ts +14 -0
- package/lib/private/request/store.js +20 -0
- package/lib/public/Field.d.ts +2 -0
- package/lib/public/Field.js +2 -0
- package/lib/public/Form.d.ts +2 -0
- package/lib/public/Form.js +2 -0
- package/lib/public/app.d.ts +2 -0
- package/lib/public/app.js +2 -0
- package/lib/public/browser.d.ts +6 -0
- package/lib/public/browser.js +8 -0
- package/lib/public/i18n.d.ts +2 -0
- package/lib/public/i18n.js +2 -0
- package/lib/public/tags.d.ts +3 -0
- package/lib/public/tags.js +3 -0
- package/package.json +16 -5
- package/src/private/tags/Field.marko +44 -0
- package/src/private/tags/Form.marko +110 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import root from "#client/root";
|
|
2
|
+
import client from "@primate/core/client";
|
|
3
|
+
import RootView from "marko:root";
|
|
4
|
+
export default class MarkoApp {
|
|
5
|
+
static mount(_, data) {
|
|
6
|
+
const interactive = !data.ssr || data.csr;
|
|
7
|
+
if (!interactive)
|
|
8
|
+
return;
|
|
9
|
+
let instance;
|
|
10
|
+
let current = data;
|
|
11
|
+
let initial = data.ssr;
|
|
12
|
+
const key = (next) => `${next.views.join("\0")}\0${next.request.url}`;
|
|
13
|
+
const render = (next, remount = false) => {
|
|
14
|
+
current = next;
|
|
15
|
+
const props = root.toProps(next);
|
|
16
|
+
if (!remount && instance !== undefined) {
|
|
17
|
+
instance.update?.(props);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
instance?.destroy?.();
|
|
21
|
+
document.body.replaceChildren();
|
|
22
|
+
instance = RootView.mount(props, document.body);
|
|
23
|
+
};
|
|
24
|
+
const invalidate = () => render(current, true);
|
|
25
|
+
const mods = globalThis.__primate_i18n__ ?? [];
|
|
26
|
+
for (const mod of mods) {
|
|
27
|
+
mod.invalidate(invalidate);
|
|
28
|
+
}
|
|
29
|
+
if (!data.ssr) {
|
|
30
|
+
render(data, true);
|
|
31
|
+
}
|
|
32
|
+
if (data.csr) {
|
|
33
|
+
const start = () => client.boot((next, update) => {
|
|
34
|
+
if (initial && key(next) === key(current)) {
|
|
35
|
+
initial = false;
|
|
36
|
+
current = next;
|
|
37
|
+
update?.();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
initial = false;
|
|
41
|
+
render(next, instance === undefined);
|
|
42
|
+
update?.();
|
|
43
|
+
});
|
|
44
|
+
if (document.readyState === "loading") {
|
|
45
|
+
window.addEventListener("DOMContentLoaded", start, { once: true });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
start();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type Data from "#client/Data";
|
|
2
|
+
import type { Dict } from "@rcompat/type";
|
|
3
|
+
export type RootProps = {
|
|
4
|
+
views: unknown[];
|
|
5
|
+
props: Dict[];
|
|
6
|
+
request: Data["request"] & {
|
|
7
|
+
url: URL;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
declare function toProps(data: Data): RootProps;
|
|
11
|
+
declare const root: {
|
|
12
|
+
toProps: typeof toProps;
|
|
13
|
+
};
|
|
14
|
+
export default root;
|
|
15
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as views from "marko:views";
|
|
2
|
+
function toProps(data) {
|
|
3
|
+
return {
|
|
4
|
+
views: data.views.map(name => views[name]),
|
|
5
|
+
props: data.props,
|
|
6
|
+
request: {
|
|
7
|
+
...data.request,
|
|
8
|
+
url: new URL(data.request.url),
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
const root = {
|
|
13
|
+
toProps,
|
|
14
|
+
};
|
|
15
|
+
export default root;
|
|
16
|
+
//# sourceMappingURL=root.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export default (depth) => {
|
|
2
|
+
const view = (i) => `<\${input.views[${i}]} ...input.props[${i}] />`;
|
|
3
|
+
const layout = (i, child) => [
|
|
4
|
+
`<if=input.views[${i + 1}]>`,
|
|
5
|
+
`<\${input.views[${i}]} ...input.props[${i}]>`,
|
|
6
|
+
child,
|
|
7
|
+
"</>",
|
|
8
|
+
"</if>",
|
|
9
|
+
"<else>",
|
|
10
|
+
view(i),
|
|
11
|
+
"</else>",
|
|
12
|
+
].join("\n");
|
|
13
|
+
const body = Array.from({ length: depth }, (_, i) => i)
|
|
14
|
+
.reduceRight((child, i) => layout(i, child), view(depth));
|
|
15
|
+
return `import { request } from "@primate/marko/app";
|
|
16
|
+
<const/{ context, path, ...public_request }=input.request/>
|
|
17
|
+
<const/_request=request.set(public_request)/>
|
|
18
|
+
${body}`;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=create-root.js.map
|
package/lib/private/default.js
CHANGED
|
@@ -1,11 +1,93 @@
|
|
|
1
|
+
import create_root from "#create-root";
|
|
1
2
|
import init from "#init";
|
|
2
3
|
import { compileSync } from "@marko/compiler";
|
|
3
4
|
import frontend from "@primate/core/frontend";
|
|
5
|
+
const styles = new Map();
|
|
6
|
+
let style_id = 0;
|
|
7
|
+
let root_dir = "";
|
|
8
|
+
let root_file = "";
|
|
9
|
+
let root_dom = "";
|
|
10
|
+
function resolveVirtualDependency(_from, dependency) {
|
|
11
|
+
if (!dependency.virtualPath.endsWith(".css")) {
|
|
12
|
+
return dependency.virtualPath;
|
|
13
|
+
}
|
|
14
|
+
const path = `marko:style:${style_id++}`;
|
|
15
|
+
styles.set(path, {
|
|
16
|
+
code: dependency.code,
|
|
17
|
+
module: dependency.virtualPath.endsWith(".module.css"),
|
|
18
|
+
});
|
|
19
|
+
return path;
|
|
20
|
+
}
|
|
21
|
+
function compile(text, file, output, root = false) {
|
|
22
|
+
return compileSync(text, root || file.path.startsWith("root:")
|
|
23
|
+
? root_file
|
|
24
|
+
: file.path, {
|
|
25
|
+
output,
|
|
26
|
+
resolveVirtualDependency,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const plugin = {
|
|
30
|
+
name: "marko-primate",
|
|
31
|
+
setup(build) {
|
|
32
|
+
build.onResolve({ filter: /^marko:style:/ }, args => ({
|
|
33
|
+
path: args.path,
|
|
34
|
+
namespace: "marko-style",
|
|
35
|
+
}));
|
|
36
|
+
build.onLoad({ filter: /.*/, namespace: "marko-style" }, args => {
|
|
37
|
+
const style = styles.get(args.path);
|
|
38
|
+
return style === undefined
|
|
39
|
+
? null
|
|
40
|
+
: {
|
|
41
|
+
contents: style.code,
|
|
42
|
+
loader: style.module ? "local-css" : "css",
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
build.onResolve({ filter: /^\.\/root\.marko$/ }, args => {
|
|
46
|
+
if (args.namespace !== "marko" || args.importer !== "marko:root") {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
path: root_file,
|
|
51
|
+
namespace: "file",
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
build.onLoad({ filter: /.*/, namespace: "file" }, args => {
|
|
55
|
+
if (args.path !== root_file)
|
|
56
|
+
return null;
|
|
57
|
+
return {
|
|
58
|
+
contents: root_dom,
|
|
59
|
+
loader: "js",
|
|
60
|
+
resolveDir: root_dir,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
};
|
|
4
65
|
export default frontend({
|
|
5
66
|
...init,
|
|
67
|
+
root: {
|
|
68
|
+
create: create_root,
|
|
69
|
+
},
|
|
6
70
|
compile: {
|
|
7
|
-
server: (text, file) =>
|
|
8
|
-
client: (text) =>
|
|
71
|
+
server: (text, file) => compile(text, file, "html").code,
|
|
72
|
+
client: (text, file, root, hydrate) => {
|
|
73
|
+
if (root && hydrate) {
|
|
74
|
+
root_dom = compile(text, file, "dom", true).code;
|
|
75
|
+
return {
|
|
76
|
+
js: `${compile(text, file, "hydrate", true).code}
|
|
77
|
+
export { default } from "./root.marko";`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
js: compile(text, file, "dom", root).code,
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
onBuild(app, options) {
|
|
86
|
+
root_dir = app.root.path;
|
|
87
|
+
root_file = app.root.join("root.marko").path;
|
|
88
|
+
app.plugin("server", plugin);
|
|
89
|
+
app.plugin("client", plugin);
|
|
90
|
+
return init.onBuild?.(app, options);
|
|
9
91
|
},
|
|
10
92
|
});
|
|
11
93
|
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import request from "#request/store";
|
|
2
|
+
export default function i18n(source) {
|
|
3
|
+
let invalidate = () => undefined;
|
|
4
|
+
let forced;
|
|
5
|
+
const get = () => source.locale.get();
|
|
6
|
+
const set = (locale) => {
|
|
7
|
+
forced = locale;
|
|
8
|
+
source.locale.set(locale);
|
|
9
|
+
invalidate();
|
|
10
|
+
};
|
|
11
|
+
const restore = (next) => {
|
|
12
|
+
const before = source.locale.get();
|
|
13
|
+
source.restore(next);
|
|
14
|
+
if (forced !== undefined) {
|
|
15
|
+
source.locale.set(forced);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (source.locale.get() !== before)
|
|
19
|
+
invalidate();
|
|
20
|
+
};
|
|
21
|
+
const value = ((...args) => {
|
|
22
|
+
return source(...args);
|
|
23
|
+
});
|
|
24
|
+
value.defaultLocale = source.defaultLocale;
|
|
25
|
+
value.locales = source.locales;
|
|
26
|
+
value.catalogs = source.catalogs;
|
|
27
|
+
value.currency = source.currency;
|
|
28
|
+
value.locale = { get, set };
|
|
29
|
+
value.restore = restore;
|
|
30
|
+
value.invalidate = (fn) => { invalidate = fn; };
|
|
31
|
+
source.restore();
|
|
32
|
+
request.subscribe(next => {
|
|
33
|
+
restore(next);
|
|
34
|
+
});
|
|
35
|
+
(globalThis.__primate_i18n__ ??= []).push(value);
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=i18n.js.map
|
package/lib/private/init.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Init } from "@primate/core/frontend";
|
|
2
|
-
import type {
|
|
3
|
-
declare const module: Init<
|
|
2
|
+
import type { Template } from "marko/src/runtime/html/index.js";
|
|
3
|
+
declare const module: Init<Template>;
|
|
4
4
|
export default module;
|
|
5
5
|
//# sourceMappingURL=init.d.ts.map
|
package/lib/private/init.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const module = {
|
|
2
2
|
name: "marko",
|
|
3
3
|
extensions: [".marko"],
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
conditions: ["marko"],
|
|
5
|
+
layouts: true,
|
|
6
|
+
client: true,
|
|
7
|
+
async render(component, props) {
|
|
8
|
+
return { body: (await component.render(props)).toString() };
|
|
8
9
|
},
|
|
9
10
|
};
|
|
10
11
|
export default module;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type Input = {
|
|
2
|
+
url: string | URL;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
};
|
|
5
|
+
type Subscriber = (value: MarkoRequest) => void;
|
|
6
|
+
type MarkoRequest = {
|
|
7
|
+
url: URL;
|
|
8
|
+
set(value: Input): void;
|
|
9
|
+
subscribe(subscriber: Subscriber): () => void;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
};
|
|
12
|
+
declare const request: MarkoRequest;
|
|
13
|
+
export default request;
|
|
14
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const subscribers = new Set();
|
|
2
|
+
const request = {
|
|
3
|
+
set(value) {
|
|
4
|
+
Object.assign(request, {
|
|
5
|
+
...value,
|
|
6
|
+
url: value.url instanceof URL ? value.url : new URL(value.url),
|
|
7
|
+
});
|
|
8
|
+
for (const subscriber of subscribers) {
|
|
9
|
+
subscriber(request);
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
subscribe(subscriber) {
|
|
13
|
+
subscribers.add(subscriber);
|
|
14
|
+
return () => {
|
|
15
|
+
subscribers.delete(subscriber);
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
export default request;
|
|
20
|
+
//# sourceMappingURL=store.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primate/marko",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Marko for Primate",
|
|
5
5
|
"homepage": "https://primate.run/docs/frontend/marko",
|
|
6
6
|
"bugs": "https://github.com/primate-run/primate/issues",
|
|
@@ -14,18 +14,24 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"/lib/**/*.js",
|
|
16
16
|
"/lib/**/*.d.ts",
|
|
17
|
+
"/src/**/*.marko",
|
|
17
18
|
"!/**/*.spec.*"
|
|
18
19
|
],
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"@marko/compiler": "^5.39.63",
|
|
21
22
|
"@rcompat/fs": "^0.33.2",
|
|
22
|
-
"marko": "^
|
|
23
|
-
"@primate/core": "^0.
|
|
23
|
+
"marko": "^6.1.2",
|
|
24
|
+
"@primate/core": "^0.8.0"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
|
-
"@
|
|
27
|
+
"@rcompat/type": "^0.17.0",
|
|
28
|
+
"@types/marko": "^4.6.9",
|
|
29
|
+
"esbuild": "^0.28.0"
|
|
27
30
|
},
|
|
28
31
|
"imports": {
|
|
32
|
+
"#tags/*": {
|
|
33
|
+
"marko": "./src/private/tags/*.marko"
|
|
34
|
+
},
|
|
29
35
|
"#*": {
|
|
30
36
|
"@primate/source": "./src/private/*.ts",
|
|
31
37
|
"default": "./lib/private/*.js"
|
|
@@ -34,12 +40,17 @@
|
|
|
34
40
|
"exports": {
|
|
35
41
|
".": {
|
|
36
42
|
"@primate/source": "./src/public/default.ts",
|
|
43
|
+
"browser": "./lib/public/browser.js",
|
|
37
44
|
"runtime": "./lib/public/runtime.js",
|
|
38
45
|
"default": "./lib/public/default.js"
|
|
46
|
+
},
|
|
47
|
+
"./*": {
|
|
48
|
+
"@primate/source": "./src/public/*.ts",
|
|
49
|
+
"default": "./lib/public/*.js"
|
|
39
50
|
}
|
|
40
51
|
},
|
|
41
52
|
"scripts": {
|
|
42
|
-
"build": "npm run clean &&
|
|
53
|
+
"build": "npm run clean && tsgo",
|
|
43
54
|
"clean": "rm -rf ./lib",
|
|
44
55
|
"lint": "eslint ."
|
|
45
56
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import client from "@primate/core/client";
|
|
2
|
+
|
|
3
|
+
export interface Input {
|
|
4
|
+
value: unknown;
|
|
5
|
+
method: "delete" | "patch" | "post" | "put";
|
|
6
|
+
url: string;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
map?: (value: unknown) => unknown;
|
|
9
|
+
path?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
<let/value=input.value/>
|
|
13
|
+
<let/error=null/>
|
|
14
|
+
<let/loading=false/>
|
|
15
|
+
|
|
16
|
+
<const/update=async (updater) => {
|
|
17
|
+
const previous = value;
|
|
18
|
+
const next = updater(value);
|
|
19
|
+
error = null;
|
|
20
|
+
loading = true;
|
|
21
|
+
value = next;
|
|
22
|
+
try {
|
|
23
|
+
await client.validateField({
|
|
24
|
+
initial: input.value,
|
|
25
|
+
method: input.method.toUpperCase(),
|
|
26
|
+
url: input.url,
|
|
27
|
+
headers: input.headers,
|
|
28
|
+
map: input.map,
|
|
29
|
+
path: input.path,
|
|
30
|
+
}, next);
|
|
31
|
+
loading = false;
|
|
32
|
+
} catch (e) {
|
|
33
|
+
error = e;
|
|
34
|
+
loading = false;
|
|
35
|
+
value = previous;
|
|
36
|
+
}
|
|
37
|
+
}/>
|
|
38
|
+
|
|
39
|
+
<return={
|
|
40
|
+
value,
|
|
41
|
+
error,
|
|
42
|
+
loading,
|
|
43
|
+
update
|
|
44
|
+
}/>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import client from "@primate/core/client";
|
|
2
|
+
|
|
3
|
+
<const/error_view=errors => {
|
|
4
|
+
const view = [...errors.form];
|
|
5
|
+
|
|
6
|
+
Object.defineProperty(view, "fields", {
|
|
7
|
+
value: errors.fields,
|
|
8
|
+
enumerable: false,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
return view;
|
|
12
|
+
}/>
|
|
13
|
+
|
|
14
|
+
<let/id=`form-${crypto.randomUUID()}`/>
|
|
15
|
+
<let/submitting=false/>
|
|
16
|
+
<let/submitted=false/>
|
|
17
|
+
<let/result/>
|
|
18
|
+
<let/errors=error_view({ form: [], fields: {} })/>
|
|
19
|
+
<let/values=input.initial ?? {}/>
|
|
20
|
+
<let/controller/>
|
|
21
|
+
<let/action/>
|
|
22
|
+
<let/contentType/>
|
|
23
|
+
<let/method/>
|
|
24
|
+
|
|
25
|
+
<const/action_meta=typeof document === "undefined" ? {
|
|
26
|
+
method: input.action === undefined ? undefined : "POST",
|
|
27
|
+
contentType: input.action?.contentType,
|
|
28
|
+
} : {
|
|
29
|
+
action: input.action,
|
|
30
|
+
method: input.action === undefined ? undefined : "POST",
|
|
31
|
+
contentType: input.action?.contentType,
|
|
32
|
+
}/>
|
|
33
|
+
|
|
34
|
+
<const/set_action=meta => {
|
|
35
|
+
if ("action" in meta) {
|
|
36
|
+
action = meta.action;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
method = meta.method;
|
|
40
|
+
contentType = meta.contentType;
|
|
41
|
+
}/>
|
|
42
|
+
|
|
43
|
+
<const/_action=set_action(action_meta)/>
|
|
44
|
+
|
|
45
|
+
<const/create_controller=() => {
|
|
46
|
+
if (controller !== undefined) return controller;
|
|
47
|
+
|
|
48
|
+
const fallback_action = action === undefined && method !== undefined
|
|
49
|
+
? ({ body }) => fetch(globalThis.location.pathname, {
|
|
50
|
+
method,
|
|
51
|
+
headers: contentType === undefined || contentType === "multipart/form-data"
|
|
52
|
+
? {}
|
|
53
|
+
: { "Content-Type": contentType },
|
|
54
|
+
body: contentType === "application/json"
|
|
55
|
+
? JSON.stringify(body)
|
|
56
|
+
: contentType === "application/x-www-form-urlencoded"
|
|
57
|
+
? new URLSearchParams(body)
|
|
58
|
+
: body,
|
|
59
|
+
})
|
|
60
|
+
: undefined;
|
|
61
|
+
|
|
62
|
+
controller = client.createForm({
|
|
63
|
+
id,
|
|
64
|
+
action: action ?? fallback_action,
|
|
65
|
+
contentType,
|
|
66
|
+
method,
|
|
67
|
+
path: input.path,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return controller;
|
|
71
|
+
}/>
|
|
72
|
+
|
|
73
|
+
<const/submit=async (event, element) => {
|
|
74
|
+
event?.preventDefault?.();
|
|
75
|
+
|
|
76
|
+
const controller = create_controller();
|
|
77
|
+
|
|
78
|
+
submitting = true;
|
|
79
|
+
|
|
80
|
+
await controller.submit({
|
|
81
|
+
preventDefault() {
|
|
82
|
+
event?.preventDefault?.();
|
|
83
|
+
},
|
|
84
|
+
stopPropagation() {
|
|
85
|
+
event?.stopPropagation?.();
|
|
86
|
+
},
|
|
87
|
+
currentTarget: element ?? document.getElementById(id),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const snapshot = controller.read();
|
|
91
|
+
|
|
92
|
+
id = snapshot.id;
|
|
93
|
+
submitting = snapshot.submitting;
|
|
94
|
+
submitted = snapshot.submitted;
|
|
95
|
+
result = snapshot.result;
|
|
96
|
+
errors = error_view(snapshot.errors);
|
|
97
|
+
}/>
|
|
98
|
+
|
|
99
|
+
<const/field=name => {
|
|
100
|
+
const field_errors = errors.fields[name] ?? [];
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
name,
|
|
104
|
+
value: values[name],
|
|
105
|
+
error: field_errors[0] ?? null,
|
|
106
|
+
errors: field_errors,
|
|
107
|
+
};
|
|
108
|
+
}/>
|
|
109
|
+
|
|
110
|
+
<return={ id, submitting, submitted, result, errors, values, field, submit }/>
|