@formwright/core 0.1.0 → 0.2.2
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 +96 -0
- package/dist/chunk-OWEG6VGP.js +3 -0
- package/dist/chunk-OWEG6VGP.js.map +1 -0
- package/dist/index.cjs +376 -232
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +105 -17
- package/dist/index.d.ts +105 -17
- package/dist/index.js +330 -51
- package/dist/index.js.map +1 -1
- package/dist/reactive.cjs +27 -164
- package/dist/reactive.cjs.map +1 -1
- package/dist/reactive.d.cts +1 -45
- package/dist/reactive.d.ts +1 -45
- package/dist/reactive.js +1 -1
- package/package.json +3 -2
- package/dist/chunk-EZUHEI5F.js +0 -162
- package/dist/chunk-EZUHEI5F.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# @formwright/core
|
|
2
|
+
|
|
3
|
+
> Signal-reactive core and the `Form` class for [Formwright](https://github.com/aliarsalan177/formwright) — a schema-driven, framework-agnostic form engine.
|
|
4
|
+
|
|
5
|
+
Define a form once as plain data — hand-written or LLM-generated — and drive it with
|
|
6
|
+
a tiny, fine-grained reactive core. No virtual DOM, no full re-render: when a value
|
|
7
|
+
changes, only the exact bindings that read it re-run.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @formwright/core @formwright/dom
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Form } from "@formwright/core";
|
|
17
|
+
import "@formwright/dom"; // registers the default DOM renderer
|
|
18
|
+
|
|
19
|
+
const form = new Form(
|
|
20
|
+
{
|
|
21
|
+
id: "signup",
|
|
22
|
+
version: "1.0",
|
|
23
|
+
fields: [
|
|
24
|
+
{
|
|
25
|
+
id: "email",
|
|
26
|
+
type: "email",
|
|
27
|
+
label: "Email",
|
|
28
|
+
validation: { kind: "string", format: "email", required: true },
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "country",
|
|
32
|
+
type: "select",
|
|
33
|
+
label: "Country",
|
|
34
|
+
options: [
|
|
35
|
+
{ label: "United States", value: "US" },
|
|
36
|
+
{ label: "Canada", value: "CA" },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
// Shown only when country === "US"
|
|
40
|
+
{
|
|
41
|
+
id: "state",
|
|
42
|
+
type: "text",
|
|
43
|
+
label: "State",
|
|
44
|
+
visibleWhen: { "==": [{ var: "country" }, "US"] },
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
{ email: "" },
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
form.mount(document.getElementById("root")!);
|
|
52
|
+
await form.submit();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- **Fine-grained reactivity** — a zero-dependency `signal`/`computed`/`effect` core; only the bindings that read a changed value update.
|
|
58
|
+
- **Conditional logic as data** — `visibleWhen` / `enabledWhen` / `requiredWhen` use a sandboxed JSONLogic-style algebra (`==`, `>`, `in`, `and`, `or`, `not`, `var`). No `eval`.
|
|
59
|
+
- **Nested `group` (object) and repeatable `collection` (array) fields** — produce nested payloads (`{ items: { … } }`, `{ contacts: [ … ] }`), with add/remove honoring `minItems`/`maxItems`.
|
|
60
|
+
- **Cross-scope conditions** — names resolve lexically (sibling → enclosing scope → form root), so an outer toggle can hide a field nested inside a group or a collection row.
|
|
61
|
+
- **Built-in validation** — declarative rules (`required`, `min`/`max`, `minLength`/`maxLength`, `pattern`, `format`), or bring any Standard-Schema validator.
|
|
62
|
+
- **Submission pipeline** — `validate → transform → send → onSuccess/onError`, all declarable by name in the schema.
|
|
63
|
+
- **Provider injection** — i18n, data-fetching, and theming referenced in-schema via sigils (`{ $t }`, `{ $query }`, `{ $theme }`).
|
|
64
|
+
- **Render-agnostic** — the `Form` instance owns state; mount it via `@formwright/dom`, a web component, or a framework adapter.
|
|
65
|
+
|
|
66
|
+
## Imperative API
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
form.values; // reactive snapshot (nested for groups/collections)
|
|
70
|
+
form.getValue("billingAddress.name"); // dotted-path access
|
|
71
|
+
form.setValue("country", "US");
|
|
72
|
+
form.isDirty; // computed signals
|
|
73
|
+
form.isValid;
|
|
74
|
+
form.isSubmitting;
|
|
75
|
+
form.on("change", ({ id, value }) => {});
|
|
76
|
+
await form.submit(); // validate → transform → endpoint → onSuccess/onError
|
|
77
|
+
form.reset();
|
|
78
|
+
form.destroy();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Reactivity primitives
|
|
82
|
+
|
|
83
|
+
The core ships its own tiny reactive system, also exported for general use:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { signal, computed, effect, batch } from "@formwright/core/reactive";
|
|
87
|
+
|
|
88
|
+
const count = signal(0);
|
|
89
|
+
const doubled = computed(() => count.get() * 2);
|
|
90
|
+
effect(() => console.log(doubled.get())); // 0
|
|
91
|
+
count.set(5); // logs 10
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-OWEG6VGP.js","sourcesContent":[]}
|