@wildwinter/expr-editor 0.11.0 → 0.12.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 CHANGED
@@ -41,8 +41,14 @@ Notable options beyond the basics:
41
41
  ladder exists for "at or past a stage"), lists its stages wherever a value is
42
42
  picked, labels that list "stage", and seeds an outcome on it with
43
43
  `advance(@ref)` — the form that keeps a story insertion-safe, because it names
44
- no destination. A host still passing a ladder through `enumValues` keeps its
45
- value picker, but not the ordering affordances.
44
+ no destination. That seed is the same on both paths (adding an effect and
45
+ re-pointing one), via `initialValueFor`, and a quality skips the value wizard
46
+ entirely: there is no question left worth asking. A host still passing a
47
+ ladder through `enumValues` keeps its value picker, but not the ordering
48
+ affordances.
49
+ - `valueWizard`'s `expectedChoices` supersedes `expectedEnumValues` — one
50
+ channel for "the target's closed set of values", filled with `choicesOf(entry)`
51
+ so a quality's ladder arrives with its type. The old name still works.
46
52
  - `onEditingChange(editing)` — fires as popover micro-editors open/close, so the
47
53
  host can suppress its own validation display mid-edit.
48
54
  - `messages: false` — hide the editor's internal validation list when the host
package/dist/index.cjs CHANGED
@@ -1350,7 +1350,9 @@ function valueWizard(opts) {
1350
1350
  host.append(head("Pick a value"));
1351
1351
  const body = el("div", "exed-vwiz-body");
1352
1352
  host.append(body);
1353
- let kind = opts.expectedType === "number" ? "number" : opts.expectedType === "string" ? "text" : opts.expectedType === "boolean" ? "bool" : opts.expectedType === "enum" && opts.expectedEnumValues?.length ? "enum" : "menu";
1353
+ const choices = opts.expectedChoices?.length ? opts.expectedChoices : opts.expectedEnumValues;
1354
+ const isStage = opts.expectedType === "quality";
1355
+ let kind = opts.expectedType === "number" ? "number" : opts.expectedType === "string" ? "text" : opts.expectedType === "boolean" ? "bool" : (opts.expectedType === "enum" || opts.expectedType === "quality") && choices?.length ? "enum" : "menu";
1354
1356
  const draw = () => {
1355
1357
  body.replaceChildren();
1356
1358
  const other = () => button("exed-vwiz-other", "\u21A9 a different kind", () => {
@@ -1375,7 +1377,7 @@ function valueWizard(opts) {
1375
1377
  kind = "bool";
1376
1378
  draw();
1377
1379
  }));
1378
- if (opts.expectedEnumValues?.length) body.append(optBtn("A listed value", () => {
1380
+ if (choices?.length) body.append(optBtn(isStage ? "A stage" : "A listed value", () => {
1379
1381
  kind = "enum";
1380
1382
  draw();
1381
1383
  }));
@@ -1399,7 +1401,8 @@ function valueWizard(opts) {
1399
1401
  break;
1400
1402
  }
1401
1403
  case "enum":
1402
- for (const v of opts.expectedEnumValues ?? []) body.append(optBtn(v, () => opts.onCommit(enumSrc(v))));
1404
+ body.append(el("div", "exed-vwiz-note", [isStage ? "Stages, in ladder order:" : ""]));
1405
+ for (const v of choices ?? []) body.append(optBtn(v, () => opts.onCommit(enumSrc(v))));
1403
1406
  body.append(other());
1404
1407
  break;
1405
1408
  }
@@ -1448,6 +1451,13 @@ function removeArgAt(list, i, argIdx) {
1448
1451
  cur.args.splice(argIdx, 1);
1449
1452
  return next;
1450
1453
  }
1454
+ function initialValueFor(entry, defaultScope) {
1455
+ const ref = refOf(entry, defaultScope);
1456
+ return {
1457
+ src: seedValueSrc(entry.type, choicesOf(entry), ref),
1458
+ ask: entry.type !== "quality"
1459
+ };
1460
+ }
1451
1461
  function seedValueSrc(type, values, ref) {
1452
1462
  switch (type) {
1453
1463
  case "boolean":
@@ -1487,7 +1497,9 @@ function mountEffectsEditor(host, opts) {
1487
1497
  scopeOrder: opts.scopeOrder ?? [],
1488
1498
  defaultScope,
1489
1499
  ...expected?.type ? { expectedType: expected.type } : {},
1490
- ...expected?.enumValues ? { expectedEnumValues: expected.enumValues } : {},
1500
+ // choicesOf, never a raw field: a quality's ladder lives in `stages`, and reading `enumValues`
1501
+ // here told the wizard the type and withheld the values.
1502
+ ...choicesOf(expected) ? { expectedChoices: choicesOf(expected) } : {},
1491
1503
  onCommit: (src) => {
1492
1504
  onCommit(src);
1493
1505
  close();
@@ -1555,8 +1567,7 @@ function mountEffectsEditor(host, opts) {
1555
1567
  const row = el("div", "exed-effect exed-effect-set");
1556
1568
  const targetBtn = button("exed-pill exed-pill-prop", eff.target || "(pick property)", (e) => {
1557
1569
  pickTarget(e.currentTarget, void 0, (entry) => {
1558
- const ref = refOf(entry, defaultScope);
1559
- commit(updateAt(effects, i, { target: ref, value: seedValueSrc(entry.type, choicesOf(entry), ref) }));
1570
+ commit(updateAt(effects, i, { target: refOf(entry, defaultScope), value: initialValueFor(entry, defaultScope).src }));
1560
1571
  });
1561
1572
  }, "change the target property");
1562
1573
  row.append(targetBtn, el("span", "exed-effect-eq", ["="]));
@@ -1642,7 +1653,14 @@ function mountEffectsEditor(host, opts) {
1642
1653
  const bar = el("div", "exed-effect-addbar");
1643
1654
  bar.append(button("exed-eff-add", "+ set property", (e) => {
1644
1655
  const anchor = e.currentTarget;
1645
- pickTarget(anchor, void 0, (entry) => openValueWizard(anchor, entry, (src) => commit(addSet(effects, refOf(entry, defaultScope), src))));
1656
+ pickTarget(anchor, void 0, (entry) => {
1657
+ const { src, ask } = initialValueFor(entry, defaultScope);
1658
+ if (!ask) {
1659
+ commit(addSet(effects, refOf(entry, defaultScope), src));
1660
+ return;
1661
+ }
1662
+ openValueWizard(anchor, entry, (chosen) => commit(addSet(effects, refOf(entry, defaultScope), chosen)));
1663
+ });
1646
1664
  }));
1647
1665
  if (opts.allowEmit !== false) {
1648
1666
  bar.append(button("exed-eff-add", "+ emit event", (e) => editEvent(e.currentTarget, "", (name) => commit(addEmit(effects, name)))));