@wildwinter/expr-editor 0.11.0 → 0.12.1
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 +8 -2
- package/dist/index.cjs +26 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +26 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -407,6 +407,23 @@ declare function updateAt(list: EditorEffect[], i: number, patch: Partial<Editor
|
|
|
407
407
|
declare function setArgAt(list: EditorEffect[], i: number, argIdx: number, value: string): EditorEffect[];
|
|
408
408
|
declare function addArg(list: EditorEffect[], i: number, value?: string): EditorEffect[];
|
|
409
409
|
declare function removeArgAt(list: EditorEffect[], i: number, argIdx: number): EditorEffect[];
|
|
410
|
+
/**
|
|
411
|
+
* What a freshly targeted property's value should be, and whether the guided value wizard still has a
|
|
412
|
+
* question worth asking.
|
|
413
|
+
*
|
|
414
|
+
* BOTH paths that target a property go through this - "+ set property" (add) and re-picking an
|
|
415
|
+
* existing effect's target - because when they answered separately they drifted: 0.11.0 seeded a
|
|
416
|
+
* quality with `advance(...)` on re-pick while the add path opened a wizard that did not know what a
|
|
417
|
+
* quality was, so the same job offered two different affordances depending on how you arrived.
|
|
418
|
+
*
|
|
419
|
+
* `ask: false` means the type has a canonical outcome and the wizard would be ceremony: a QUALITY
|
|
420
|
+
* moves to its next stage, which is the insertion-safe form the type exists for, and an author who
|
|
421
|
+
* meant a specific stage clicks the pill.
|
|
422
|
+
*/
|
|
423
|
+
declare function initialValueFor(entry: CatalogueEntry, defaultScope: string): {
|
|
424
|
+
src: string;
|
|
425
|
+
ask: boolean;
|
|
426
|
+
};
|
|
410
427
|
/** A sensible starting value-expression for a freshly targeted property. Literals
|
|
411
428
|
* are seeded so the value editor opens on an editable pill, never the empty state.
|
|
412
429
|
*
|
|
@@ -450,6 +467,11 @@ interface ValueWizardOptions {
|
|
|
450
467
|
defaultScope: string;
|
|
451
468
|
/** When known (a `set` target's declared type), the picker leads straight to that input. */
|
|
452
469
|
expectedType?: PropertyType;
|
|
470
|
+
/** The target's closed set of values, when it has one: an enum's values, or a QUALITY's stages in
|
|
471
|
+
* ladder order. Callers should fill this with `choicesOf(entry)` rather than reading a single
|
|
472
|
+
* field, so a quality is never handed a wizard that knows its type but not its ladder. */
|
|
473
|
+
expectedChoices?: string[];
|
|
474
|
+
/** @deprecated Use `expectedChoices`. Kept so a 0.11.x caller keeps working. */
|
|
453
475
|
expectedEnumValues?: string[];
|
|
454
476
|
/** Receives the chosen value as name-form source. */
|
|
455
477
|
onCommit: (src: string) => void;
|
|
@@ -459,4 +481,4 @@ interface ValueWizardOptions {
|
|
|
459
481
|
/** Build the wizard UI into a fresh element (drive it via the host's popover). */
|
|
460
482
|
declare function valueWizard(opts: ValueWizardOptions): HTMLElement;
|
|
461
483
|
|
|
462
|
-
export { ARITHMETIC_OPS, BINARY_LABEL, COMPARABLE_TYPES, COMPARISON_OPS, type CatalogueEntry, EQUALITY_OPS, type EditCtx, type EditorEffect, type EffectsEditorHandle, type EffectsEditorOptions, type ExpressionEditorHandle, type ExpressionEditorOptions, type Filter, type FunctionTemplateSpec, type PreviewOptions, type TreeRow, UNARY_LABEL, type Validation, type ValueWizardOptions, type WizardSpec, type WizardStepSpec, type WizardValue, addArg, addChildToContainer, addEmit, addSet, astToTree, binary, boolLit, buildSubGroupClause, callNode, choicesOf, comparisonOpsFor, deleteAt, displayName, filterCatalogue, findEnumPeer, firstEmptyLeafPath, flagDelta, flipContainerOp, formatNumber, getNodeAt, groupByScope, insertSiblingClauseAt, isComparisonOp, isPlaceholderForOp, isWrappedInNot, issuesAt, lookup, mountEffectsEditor, mountExpressionEditor, moveAt, moveChildInContainer, needsParens, notNode, numLit, opSwapGroup, pathKey, placeholderForOp, redirectDeleteForPlaceholderSibling, refOf, removeArgAt, removeAt, renderConditionPreview, renderEffectsPreview, rhsTypesFor, scopedVar, searchCatalogue, seedValueSrc, setArgAt, setNodeAt, strLit, toggleContainerNot, toggleNotAt, updateAt, validateSource, valueWizard, wrapInNotAt };
|
|
484
|
+
export { ARITHMETIC_OPS, BINARY_LABEL, COMPARABLE_TYPES, COMPARISON_OPS, type CatalogueEntry, EQUALITY_OPS, type EditCtx, type EditorEffect, type EffectsEditorHandle, type EffectsEditorOptions, type ExpressionEditorHandle, type ExpressionEditorOptions, type Filter, type FunctionTemplateSpec, type PreviewOptions, type TreeRow, UNARY_LABEL, type Validation, type ValueWizardOptions, type WizardSpec, type WizardStepSpec, type WizardValue, addArg, addChildToContainer, addEmit, addSet, astToTree, binary, boolLit, buildSubGroupClause, callNode, choicesOf, comparisonOpsFor, deleteAt, displayName, filterCatalogue, findEnumPeer, firstEmptyLeafPath, flagDelta, flipContainerOp, formatNumber, getNodeAt, groupByScope, initialValueFor, insertSiblingClauseAt, isComparisonOp, isPlaceholderForOp, isWrappedInNot, issuesAt, lookup, mountEffectsEditor, mountExpressionEditor, moveAt, moveChildInContainer, needsParens, notNode, numLit, opSwapGroup, pathKey, placeholderForOp, redirectDeleteForPlaceholderSibling, refOf, removeArgAt, removeAt, renderConditionPreview, renderEffectsPreview, rhsTypesFor, scopedVar, searchCatalogue, seedValueSrc, setArgAt, setNodeAt, strLit, toggleContainerNot, toggleNotAt, updateAt, validateSource, valueWizard, wrapInNotAt };
|
package/dist/index.d.ts
CHANGED
|
@@ -407,6 +407,23 @@ declare function updateAt(list: EditorEffect[], i: number, patch: Partial<Editor
|
|
|
407
407
|
declare function setArgAt(list: EditorEffect[], i: number, argIdx: number, value: string): EditorEffect[];
|
|
408
408
|
declare function addArg(list: EditorEffect[], i: number, value?: string): EditorEffect[];
|
|
409
409
|
declare function removeArgAt(list: EditorEffect[], i: number, argIdx: number): EditorEffect[];
|
|
410
|
+
/**
|
|
411
|
+
* What a freshly targeted property's value should be, and whether the guided value wizard still has a
|
|
412
|
+
* question worth asking.
|
|
413
|
+
*
|
|
414
|
+
* BOTH paths that target a property go through this - "+ set property" (add) and re-picking an
|
|
415
|
+
* existing effect's target - because when they answered separately they drifted: 0.11.0 seeded a
|
|
416
|
+
* quality with `advance(...)` on re-pick while the add path opened a wizard that did not know what a
|
|
417
|
+
* quality was, so the same job offered two different affordances depending on how you arrived.
|
|
418
|
+
*
|
|
419
|
+
* `ask: false` means the type has a canonical outcome and the wizard would be ceremony: a QUALITY
|
|
420
|
+
* moves to its next stage, which is the insertion-safe form the type exists for, and an author who
|
|
421
|
+
* meant a specific stage clicks the pill.
|
|
422
|
+
*/
|
|
423
|
+
declare function initialValueFor(entry: CatalogueEntry, defaultScope: string): {
|
|
424
|
+
src: string;
|
|
425
|
+
ask: boolean;
|
|
426
|
+
};
|
|
410
427
|
/** A sensible starting value-expression for a freshly targeted property. Literals
|
|
411
428
|
* are seeded so the value editor opens on an editable pill, never the empty state.
|
|
412
429
|
*
|
|
@@ -450,6 +467,11 @@ interface ValueWizardOptions {
|
|
|
450
467
|
defaultScope: string;
|
|
451
468
|
/** When known (a `set` target's declared type), the picker leads straight to that input. */
|
|
452
469
|
expectedType?: PropertyType;
|
|
470
|
+
/** The target's closed set of values, when it has one: an enum's values, or a QUALITY's stages in
|
|
471
|
+
* ladder order. Callers should fill this with `choicesOf(entry)` rather than reading a single
|
|
472
|
+
* field, so a quality is never handed a wizard that knows its type but not its ladder. */
|
|
473
|
+
expectedChoices?: string[];
|
|
474
|
+
/** @deprecated Use `expectedChoices`. Kept so a 0.11.x caller keeps working. */
|
|
453
475
|
expectedEnumValues?: string[];
|
|
454
476
|
/** Receives the chosen value as name-form source. */
|
|
455
477
|
onCommit: (src: string) => void;
|
|
@@ -459,4 +481,4 @@ interface ValueWizardOptions {
|
|
|
459
481
|
/** Build the wizard UI into a fresh element (drive it via the host's popover). */
|
|
460
482
|
declare function valueWizard(opts: ValueWizardOptions): HTMLElement;
|
|
461
483
|
|
|
462
|
-
export { ARITHMETIC_OPS, BINARY_LABEL, COMPARABLE_TYPES, COMPARISON_OPS, type CatalogueEntry, EQUALITY_OPS, type EditCtx, type EditorEffect, type EffectsEditorHandle, type EffectsEditorOptions, type ExpressionEditorHandle, type ExpressionEditorOptions, type Filter, type FunctionTemplateSpec, type PreviewOptions, type TreeRow, UNARY_LABEL, type Validation, type ValueWizardOptions, type WizardSpec, type WizardStepSpec, type WizardValue, addArg, addChildToContainer, addEmit, addSet, astToTree, binary, boolLit, buildSubGroupClause, callNode, choicesOf, comparisonOpsFor, deleteAt, displayName, filterCatalogue, findEnumPeer, firstEmptyLeafPath, flagDelta, flipContainerOp, formatNumber, getNodeAt, groupByScope, insertSiblingClauseAt, isComparisonOp, isPlaceholderForOp, isWrappedInNot, issuesAt, lookup, mountEffectsEditor, mountExpressionEditor, moveAt, moveChildInContainer, needsParens, notNode, numLit, opSwapGroup, pathKey, placeholderForOp, redirectDeleteForPlaceholderSibling, refOf, removeArgAt, removeAt, renderConditionPreview, renderEffectsPreview, rhsTypesFor, scopedVar, searchCatalogue, seedValueSrc, setArgAt, setNodeAt, strLit, toggleContainerNot, toggleNotAt, updateAt, validateSource, valueWizard, wrapInNotAt };
|
|
484
|
+
export { ARITHMETIC_OPS, BINARY_LABEL, COMPARABLE_TYPES, COMPARISON_OPS, type CatalogueEntry, EQUALITY_OPS, type EditCtx, type EditorEffect, type EffectsEditorHandle, type EffectsEditorOptions, type ExpressionEditorHandle, type ExpressionEditorOptions, type Filter, type FunctionTemplateSpec, type PreviewOptions, type TreeRow, UNARY_LABEL, type Validation, type ValueWizardOptions, type WizardSpec, type WizardStepSpec, type WizardValue, addArg, addChildToContainer, addEmit, addSet, astToTree, binary, boolLit, buildSubGroupClause, callNode, choicesOf, comparisonOpsFor, deleteAt, displayName, filterCatalogue, findEnumPeer, firstEmptyLeafPath, flagDelta, flipContainerOp, formatNumber, getNodeAt, groupByScope, initialValueFor, insertSiblingClauseAt, isComparisonOp, isPlaceholderForOp, isWrappedInNot, issuesAt, lookup, mountEffectsEditor, mountExpressionEditor, moveAt, moveChildInContainer, needsParens, notNode, numLit, opSwapGroup, pathKey, placeholderForOp, redirectDeleteForPlaceholderSibling, refOf, removeArgAt, removeAt, renderConditionPreview, renderEffectsPreview, rhsTypesFor, scopedVar, searchCatalogue, seedValueSrc, setArgAt, setNodeAt, strLit, toggleContainerNot, toggleNotAt, updateAt, validateSource, valueWizard, wrapInNotAt };
|
package/dist/index.js
CHANGED
|
@@ -1348,7 +1348,9 @@ function valueWizard(opts) {
|
|
|
1348
1348
|
host.append(head("Pick a value"));
|
|
1349
1349
|
const body = el("div", "exed-vwiz-body");
|
|
1350
1350
|
host.append(body);
|
|
1351
|
-
|
|
1351
|
+
const choices = opts.expectedChoices?.length ? opts.expectedChoices : opts.expectedEnumValues;
|
|
1352
|
+
const isStage = opts.expectedType === "quality";
|
|
1353
|
+
let kind = opts.expectedType === "number" ? "number" : opts.expectedType === "string" ? "text" : opts.expectedType === "boolean" ? "bool" : (opts.expectedType === "enum" || opts.expectedType === "quality") && choices?.length ? "enum" : "menu";
|
|
1352
1354
|
const draw = () => {
|
|
1353
1355
|
body.replaceChildren();
|
|
1354
1356
|
const other = () => button("exed-vwiz-other", "\u21A9 a different kind", () => {
|
|
@@ -1373,7 +1375,7 @@ function valueWizard(opts) {
|
|
|
1373
1375
|
kind = "bool";
|
|
1374
1376
|
draw();
|
|
1375
1377
|
}));
|
|
1376
|
-
if (
|
|
1378
|
+
if (choices?.length) body.append(optBtn(isStage ? "A stage" : "A listed value", () => {
|
|
1377
1379
|
kind = "enum";
|
|
1378
1380
|
draw();
|
|
1379
1381
|
}));
|
|
@@ -1397,7 +1399,8 @@ function valueWizard(opts) {
|
|
|
1397
1399
|
break;
|
|
1398
1400
|
}
|
|
1399
1401
|
case "enum":
|
|
1400
|
-
|
|
1402
|
+
body.append(el("div", "exed-vwiz-note", [isStage ? "Stages, in ladder order:" : ""]));
|
|
1403
|
+
for (const v of choices ?? []) body.append(optBtn(v, () => opts.onCommit(enumSrc(v))));
|
|
1401
1404
|
body.append(other());
|
|
1402
1405
|
break;
|
|
1403
1406
|
}
|
|
@@ -1446,6 +1449,13 @@ function removeArgAt(list, i, argIdx) {
|
|
|
1446
1449
|
cur.args.splice(argIdx, 1);
|
|
1447
1450
|
return next;
|
|
1448
1451
|
}
|
|
1452
|
+
function initialValueFor(entry, defaultScope) {
|
|
1453
|
+
const ref = refOf(entry, defaultScope);
|
|
1454
|
+
return {
|
|
1455
|
+
src: seedValueSrc(entry.type, choicesOf(entry), ref),
|
|
1456
|
+
ask: entry.type !== "quality"
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1449
1459
|
function seedValueSrc(type, values, ref) {
|
|
1450
1460
|
switch (type) {
|
|
1451
1461
|
case "boolean":
|
|
@@ -1485,7 +1495,9 @@ function mountEffectsEditor(host, opts) {
|
|
|
1485
1495
|
scopeOrder: opts.scopeOrder ?? [],
|
|
1486
1496
|
defaultScope,
|
|
1487
1497
|
...expected?.type ? { expectedType: expected.type } : {},
|
|
1488
|
-
|
|
1498
|
+
// choicesOf, never a raw field: a quality's ladder lives in `stages`, and reading `enumValues`
|
|
1499
|
+
// here told the wizard the type and withheld the values.
|
|
1500
|
+
...choicesOf(expected) ? { expectedChoices: choicesOf(expected) } : {},
|
|
1489
1501
|
onCommit: (src) => {
|
|
1490
1502
|
onCommit(src);
|
|
1491
1503
|
close();
|
|
@@ -1553,8 +1565,7 @@ function mountEffectsEditor(host, opts) {
|
|
|
1553
1565
|
const row = el("div", "exed-effect exed-effect-set");
|
|
1554
1566
|
const targetBtn = button("exed-pill exed-pill-prop", eff.target || "(pick property)", (e) => {
|
|
1555
1567
|
pickTarget(e.currentTarget, void 0, (entry) => {
|
|
1556
|
-
|
|
1557
|
-
commit(updateAt(effects, i, { target: ref, value: seedValueSrc(entry.type, choicesOf(entry), ref) }));
|
|
1568
|
+
commit(updateAt(effects, i, { target: refOf(entry, defaultScope), value: initialValueFor(entry, defaultScope).src }));
|
|
1558
1569
|
});
|
|
1559
1570
|
}, "change the target property");
|
|
1560
1571
|
row.append(targetBtn, el("span", "exed-effect-eq", ["="]));
|
|
@@ -1640,7 +1651,14 @@ function mountEffectsEditor(host, opts) {
|
|
|
1640
1651
|
const bar = el("div", "exed-effect-addbar");
|
|
1641
1652
|
bar.append(button("exed-eff-add", "+ set property", (e) => {
|
|
1642
1653
|
const anchor = e.currentTarget;
|
|
1643
|
-
pickTarget(anchor, void 0, (entry) =>
|
|
1654
|
+
pickTarget(anchor, void 0, (entry) => {
|
|
1655
|
+
const { src, ask } = initialValueFor(entry, defaultScope);
|
|
1656
|
+
if (!ask) {
|
|
1657
|
+
commit(addSet(effects, refOf(entry, defaultScope), src));
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
openValueWizard(anchor, entry, (chosen) => commit(addSet(effects, refOf(entry, defaultScope), chosen)));
|
|
1661
|
+
});
|
|
1644
1662
|
}));
|
|
1645
1663
|
if (opts.allowEmit !== false) {
|
|
1646
1664
|
bar.append(button("exed-eff-add", "+ emit event", (e) => editEvent(e.currentTarget, "", (name) => commit(addEmit(effects, name)))));
|
|
@@ -1728,6 +1746,6 @@ function renderEffectsPreview(effects, o) {
|
|
|
1728
1746
|
return wrap;
|
|
1729
1747
|
}
|
|
1730
1748
|
|
|
1731
|
-
export { ARITHMETIC_OPS, BINARY_LABEL, COMPARABLE_TYPES, COMPARISON_OPS, EQUALITY_OPS, UNARY_LABEL, addArg, addChildToContainer, addEmit, addSet, astToTree, binary, boolLit, buildSubGroupClause, callNode, choicesOf, comparisonOpsFor, deleteAt, displayName, filterCatalogue, findEnumPeer, firstEmptyLeafPath, flagDelta, flipContainerOp, formatNumber, getNodeAt, groupByScope, insertSiblingClauseAt, isComparisonOp, isPlaceholderForOp, isWrappedInNot, issuesAt, lookup, mountEffectsEditor, mountExpressionEditor, moveAt, moveChildInContainer, needsParens, notNode, numLit, opSwapGroup, pathKey, placeholderForOp, redirectDeleteForPlaceholderSibling, refOf, removeArgAt, removeAt, renderConditionPreview, renderEffectsPreview, rhsTypesFor, scopedVar, searchCatalogue, seedValueSrc, setArgAt, setNodeAt, strLit, toggleContainerNot, toggleNotAt, updateAt, validateSource, valueWizard, wrapInNotAt };
|
|
1749
|
+
export { ARITHMETIC_OPS, BINARY_LABEL, COMPARABLE_TYPES, COMPARISON_OPS, EQUALITY_OPS, UNARY_LABEL, addArg, addChildToContainer, addEmit, addSet, astToTree, binary, boolLit, buildSubGroupClause, callNode, choicesOf, comparisonOpsFor, deleteAt, displayName, filterCatalogue, findEnumPeer, firstEmptyLeafPath, flagDelta, flipContainerOp, formatNumber, getNodeAt, groupByScope, initialValueFor, insertSiblingClauseAt, isComparisonOp, isPlaceholderForOp, isWrappedInNot, issuesAt, lookup, mountEffectsEditor, mountExpressionEditor, moveAt, moveChildInContainer, needsParens, notNode, numLit, opSwapGroup, pathKey, placeholderForOp, redirectDeleteForPlaceholderSibling, refOf, removeArgAt, removeAt, renderConditionPreview, renderEffectsPreview, rhsTypesFor, scopedVar, searchCatalogue, seedValueSrc, setArgAt, setNodeAt, strLit, toggleContainerNot, toggleNotAt, updateAt, validateSource, valueWizard, wrapInNotAt };
|
|
1732
1750
|
//# sourceMappingURL=index.js.map
|
|
1733
1751
|
//# sourceMappingURL=index.js.map
|