@wildwinter/expr-editor 0.2.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 ADDED
@@ -0,0 +1,79 @@
1
+ # @wildwinter/expr-editor
2
+
3
+ A **framework-neutral** (vanilla TypeScript + DOM, no React) visual editor for
4
+ [`@wildwinter/expr`](../expr) expressions — the hybrid **pill-strip + AND/OR tree**
5
+ condition builder, with a raw-text fallback, a property picker, and live validation.
6
+
7
+ Scopes, properties and the function/wizard set are **injected** (an `ExpressionSchema`,
8
+ a `Dialect`, a property catalogue and a function-template config), so any expr-based
9
+ authoring tool can mount it — it knows nothing about any one tool's domain.
10
+
11
+ ```ts
12
+ import { mountExpressionEditor } from "@wildwinter/expr-editor";
13
+ import "@wildwinter/expr-editor/styles.css";
14
+
15
+ const editor = mountExpressionEditor(hostEl, {
16
+ value: "@gold > 0 and @met_anna", // name-form; "" = always
17
+ schema, // ExpressionSchema (from @wildwinter/expr)
18
+ dialect, // the Dialect (valid scopes + functions)
19
+ catalogue, // properties the picker offers
20
+ functions, // dialect-specific clause templates (optional)
21
+ onChange: (src) => persist(src), // emits name-form on every edit; "" when cleared
22
+ });
23
+ // editor.setValue(src); editor.destroy();
24
+ ```
25
+
26
+ The editor owns its `ExprNode` internally; the **string** (name-form `src`) is the
27
+ contract with the host. See [PORTING-SPEC.md](./PORTING-SPEC.md) for the full model.
28
+
29
+ Notable options beyond the basics:
30
+
31
+ - `mode: "tree" | "flat"` — the AND/OR tree (conditions) or a single inline
32
+ expression (values); flat mode can add a `+ term` affordance via `addTerm`.
33
+ - `wizard` on a function template — `"check_flags"` / `"random"` run the built-in
34
+ guided flows; a declarative `WizardSpec` (`steps` + `build`) defines a custom
35
+ multi-step flow (e.g. tag → operator → threshold) with no editor changes.
36
+ Templates without a wizard insert-then-refine: the editor auto-opens the
37
+ first unfilled slot of the inserted clause.
38
+ - `onEditingChange(editing)` — fires as popover micro-editors open/close, so the
39
+ host can suppress its own validation display mid-edit.
40
+ - `messages: false` — hide the editor's internal validation list when the host
41
+ renders its own.
42
+ - `setText(on)` — the host's raw-text toggle (`</>`); unparseable input falls
43
+ back to raw text automatically.
44
+
45
+ ### Effects (outcome) editor
46
+
47
+ `mountEffectsEditor` edits an ordered **list** of effects — the write-side companion to
48
+ the read-only condition. Each effect is a `set` (assign a property a value) or an `emit`
49
+ (raise a host event with argument expressions); every value/argument is itself a full
50
+ pill/tree expression, edited by an embedded `mountExpressionEditor`. Modelled on the
51
+ storylets outcome editor.
52
+
53
+ ```ts
54
+ import { mountEffectsEditor } from "@wildwinter/expr-editor";
55
+
56
+ const fx = mountEffectsEditor(hostEl, {
57
+ effects: [{ kind: "set", target: "@gold", value: "@gold - 5" }],
58
+ schema, dialect, catalogue, functions, // same injected config as the condition editor
59
+ events: ["fanfare", "questComplete"], // known host events to suggest (optional)
60
+ onChange: (effects) => persist(effects), // the whole new list on every edit
61
+ });
62
+ // fx.setValue(effects); fx.destroy();
63
+ ```
64
+
65
+ The pure list operations (`addSet`, `addEmit`, `removeAt`, `moveAt`, `updateAt`,
66
+ `addArg`, `setArgAt`, `removeArgAt`, `seedValueSrc`) are exported and node-testable.
67
+
68
+ ## Layers
69
+
70
+ - **Pure logic** (`ast.ts`, `tree.ts`, `ops.ts`, `schema.ts`, `validate.ts`) — AST path
71
+ mutation, the AND/OR tree model, operator metadata, the property catalogue, and a
72
+ validation wrapper. Node-testable, no DOM.
73
+ - **UI** (`mount.ts`, `ui/*`) — pills, popover micro-editors, the property picker, clause
74
+ wizards, the tree chrome, and the raw-text fallback. Verified in a host's browser preview.
75
+
76
+ ## Status
77
+
78
+ Ported from the storylets authoring tool's React condition editor (same `ExprNode`
79
+ language). MIT, `@wildwinter` scope, published alongside `@wildwinter/expr`.