@wildwinter/expr-editor 0.5.0 → 0.6.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/dist/index.d.cts CHANGED
@@ -279,11 +279,12 @@ interface ExpressionEditorOptions {
279
279
  /** Flat compact editor for a `set_flags(@target, +a, -b)` value whose target is
280
280
  * implied by context (an outcome row's target column). Renders only the
281
281
  * flag-delta pills plus an "+ flag" chip, hiding the function name and target
282
- * arg. `target` is the name-form ref of the flags property (e.g. "@quests");
283
- * it seeds the call on the first flag add. Pairs with mode:"flat", and set
284
- * requireNonEmpty so the last flag can't be removed. */
282
+ * arg. `target` is the name-form ref of the flags property (e.g. "@quests"),
283
+ * `flags` its declared flag names (offered by the "+ flag" picker). Pairs
284
+ * with mode:"flat"; set requireNonEmpty so the last flag can't be removed. */
285
285
  flagValue?: {
286
286
  target: string;
287
+ flags: string[];
287
288
  };
288
289
  /** Emitted on every edit (name-form; "" when cleared). */
289
290
  onChange: (src: string) => void;
package/dist/index.d.ts CHANGED
@@ -279,11 +279,12 @@ interface ExpressionEditorOptions {
279
279
  /** Flat compact editor for a `set_flags(@target, +a, -b)` value whose target is
280
280
  * implied by context (an outcome row's target column). Renders only the
281
281
  * flag-delta pills plus an "+ flag" chip, hiding the function name and target
282
- * arg. `target` is the name-form ref of the flags property (e.g. "@quests");
283
- * it seeds the call on the first flag add. Pairs with mode:"flat", and set
284
- * requireNonEmpty so the last flag can't be removed. */
282
+ * arg. `target` is the name-form ref of the flags property (e.g. "@quests"),
283
+ * `flags` its declared flag names (offered by the "+ flag" picker). Pairs
284
+ * with mode:"flat"; set requireNonEmpty so the last flag can't be removed. */
285
285
  flagValue?: {
286
286
  target: string;
287
+ flags: string[];
287
288
  };
288
289
  /** Emitted on every edit (name-form; "" when cleared). */
289
290
  onChange: (src: string) => void;
package/dist/index.js CHANGED
@@ -1143,27 +1143,52 @@ function mountExpressionEditor(host, opts) {
1143
1143
  }
1144
1144
  function flagValueBody(call) {
1145
1145
  const wrap = el("div", "exed-flat exed-flagvalue");
1146
+ const ctx = buildCtx(call ?? boolLit(true));
1146
1147
  if (call) {
1147
- const ctx = buildCtx(call);
1148
1148
  call.args.forEach((arg, i) => {
1149
1149
  if (arg.kind === "flagdelta") wrap.append(renderNode(arg, ["args", i], ctx));
1150
1150
  });
1151
- wrap.append(addFlagChip(call));
1152
- } else {
1153
- wrap.append(addFlagChip(null));
1154
1151
  }
1152
+ wrap.append(addFlagChip(ctx, call));
1155
1153
  return wrap;
1156
1154
  }
1157
- function addFlagChip(call) {
1158
- return button("exed-add exed-addflag", "+ flag", () => {
1159
- if (call) {
1160
- pendingFocus = ["args", call.args.length];
1161
- emit(toSrc({ ...call, args: [...call.args, flagDelta("+", "")] }));
1162
- } else {
1163
- const seeded = callNode("set_flags", [parseRef(opts.flagValue.target), flagDelta("+", "")]);
1164
- pendingFocus = ["args", 1];
1165
- emit(toSrc(seeded));
1166
- }
1155
+ function addFlagChip(ctx, call) {
1156
+ const flags = opts.flagValue?.flags ?? [];
1157
+ const used = call ? call.args.filter((a) => a.kind === "flagdelta").map((a) => a.name) : [];
1158
+ const available = flags.filter((f) => !used.includes(f));
1159
+ return button("exed-add exed-addflag", "+ flag", (e) => {
1160
+ const anchor = e.currentTarget;
1161
+ ctx.openPopover(anchor, (close) => {
1162
+ let sign = "+";
1163
+ const wrap = el("div", "exed-menu");
1164
+ wrap.append(el("div", "exed-menu-head", ["Add flag"]));
1165
+ const signRow = el("div", "exed-field-row");
1166
+ const drawSign = () => {
1167
+ signRow.replaceChildren(
1168
+ button(`exed-opt${sign === "+" ? " sel" : ""}`, "+ set", () => {
1169
+ sign = "+";
1170
+ drawSign();
1171
+ }),
1172
+ button(`exed-opt${sign === "-" ? " sel" : ""}`, "\u2212 unset", () => {
1173
+ sign = "-";
1174
+ drawSign();
1175
+ })
1176
+ );
1177
+ };
1178
+ drawSign();
1179
+ wrap.append(signRow);
1180
+ const commit = (name) => {
1181
+ const delta = flagDelta(sign, name);
1182
+ emit(toSrc(call ? { ...call, args: [...call.args, delta] } : callNode("set_flags", [parseRef(opts.flagValue.target), delta])));
1183
+ close();
1184
+ };
1185
+ if (available.length) {
1186
+ for (const n of available) wrap.append(button("exed-opt", n, () => commit(n)));
1187
+ } else {
1188
+ wrap.append(el("div", "exed-hint", [flags.length === 0 ? "This flags property declares no flag values yet." : "All declared flags are already used."]));
1189
+ }
1190
+ return wrap;
1191
+ });
1167
1192
  }, "add a flag");
1168
1193
  }
1169
1194
  function addTermControl(ctx) {