@wildwinter/app-shell 0.28.0 → 0.30.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.cjs CHANGED
@@ -872,6 +872,73 @@ function isValidGameId(gameId) {
872
872
  return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(gameId);
873
873
  }
874
874
 
875
+ // src/property-names.ts
876
+ var RESERVED_PROPERTY_NAMES = ["true", "false", "and", "or", "not"];
877
+ var PROPERTY_NAME_HINT = "Lower case letters, digits and underscores. Cannot start with a digit. No hyphens or spaces.";
878
+ function propertyNameify(text) {
879
+ const trimmed = text.trim();
880
+ const deliberateLeading = trimmed.startsWith("_");
881
+ let out = trimmed.toLowerCase().replace(/['’]/g, "").replace(/[^a-z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
882
+ if (out === "") return "";
883
+ if (deliberateLeading || /^[0-9]/.test(out)) out = `_${out}`;
884
+ if (RESERVED_PROPERTY_NAMES.includes(out)) out = `${out}_`;
885
+ return out;
886
+ }
887
+ function isValidPropertyName(name) {
888
+ return /^[a-z_][a-z0-9_]*$/.test(name) && !RESERVED_PROPERTY_NAMES.includes(name);
889
+ }
890
+ function isCaseOnlyPropertyName(name) {
891
+ return !isValidPropertyName(name) && isValidPropertyName(name.toLowerCase());
892
+ }
893
+
894
+ // src/property-name-field.ts
895
+ function propertyNameProblem(name) {
896
+ if (isValidPropertyName(name)) return void 0;
897
+ const suggestion = propertyNameify(name);
898
+ const tail = suggestion ? ` Try "${suggestion}", or press Tab.` : "";
899
+ if (RESERVED_PROPERTY_NAMES.includes(name.toLowerCase())) {
900
+ return `Cannot be used: "${name.toLowerCase()}" is a keyword in expressions.${tail}`;
901
+ }
902
+ if (name.includes("-")) return `Cannot be used: a hyphen reads as subtraction in an expression.${tail}`;
903
+ if (/^[0-9]/.test(name)) return `Cannot be used: a name cannot start with a digit.${tail}`;
904
+ if (name !== name.toLowerCase()) {
905
+ return `Cannot be used: expressions fold names, so this would look for "${name.toLowerCase()}".${tail}`;
906
+ }
907
+ return `Cannot be used: only lower case letters, digits and underscores.${tail}`;
908
+ }
909
+ function bindPropertyName(input, onCommit, opts = {}) {
910
+ const hint = opts.hint;
911
+ const sync = () => {
912
+ const v = input.value.trim();
913
+ const problem = v === "" ? void 0 : propertyNameProblem(v);
914
+ input.classList.toggle("illegal", !!problem);
915
+ if (problem) input.title = problem;
916
+ else if (input.title.startsWith("Cannot be used")) {
917
+ if (hint) input.title = hint;
918
+ else input.removeAttribute("title");
919
+ }
920
+ };
921
+ input.addEventListener("input", () => {
922
+ onCommit(input.value);
923
+ sync();
924
+ });
925
+ input.addEventListener("keydown", (e) => {
926
+ if (e.key !== "Tab" || e.shiftKey) return;
927
+ const typed = input.value.trim();
928
+ if (typed === "" || isValidPropertyName(typed)) return;
929
+ const coerced = propertyNameify(typed);
930
+ if (!coerced || coerced === input.value) return;
931
+ e.preventDefault();
932
+ input.value = coerced;
933
+ onCommit(coerced);
934
+ sync();
935
+ });
936
+ sync();
937
+ }
938
+ function firstIllegalPropertyName(host) {
939
+ return host.querySelector("input.illegal");
940
+ }
941
+
875
942
  // src/id-editor.ts
876
943
  function openGameIdEditor(opts) {
877
944
  const slugify = opts.slugify ?? gameIdify;
@@ -1540,7 +1607,10 @@ exports.JOB_PROGRESS = JOB_PROGRESS;
1540
1607
  exports.PALETTE = PALETTE;
1541
1608
  exports.PALETTE_SIZE = PALETTE_SIZE;
1542
1609
  exports.PANE_MENU = PANE_MENU;
1610
+ exports.PROPERTY_NAME_HINT = PROPERTY_NAME_HINT;
1611
+ exports.RESERVED_PROPERTY_NAMES = RESERVED_PROPERTY_NAMES;
1543
1612
  exports.askIdentity = askIdentity;
1613
+ exports.bindPropertyName = bindPropertyName;
1544
1614
  exports.closeAnchoredPanel = closeAnchoredPanel;
1545
1615
  exports.closeWithExit = closeWithExit;
1546
1616
  exports.colourFor = colourFor;
@@ -1550,6 +1620,7 @@ exports.createSaveController = createSaveController;
1550
1620
  exports.dupGuard = dupGuard;
1551
1621
  exports.el = el;
1552
1622
  exports.expandableRow = expandableRow;
1623
+ exports.firstIllegalPropertyName = firstIllegalPropertyName;
1553
1624
  exports.focusNewRow = focusNewRow;
1554
1625
  exports.foldVc = foldVc;
1555
1626
  exports.gameIdify = gameIdify;
@@ -1558,7 +1629,9 @@ exports.icon = icon;
1558
1629
  exports.iconBtn = iconBtn;
1559
1630
  exports.iconSvg = iconSvg;
1560
1631
  exports.initTooltips = initTooltips;
1632
+ exports.isCaseOnlyPropertyName = isCaseOnlyPropertyName;
1561
1633
  exports.isValidGameId = isValidGameId;
1634
+ exports.isValidPropertyName = isValidPropertyName;
1562
1635
  exports.labelled = labelled;
1563
1636
  exports.lockControls = lockControls;
1564
1637
  exports.lockNotice = lockNotice;
@@ -1573,6 +1646,8 @@ exports.openNotesEditor = openNotesEditor;
1573
1646
  exports.paintVcBadges = paintVcBadges;
1574
1647
  exports.pinButton = pinButton;
1575
1648
  exports.placeAnchored = placeAnchored;
1649
+ exports.propertyNameProblem = propertyNameProblem;
1650
+ exports.propertyNameify = propertyNameify;
1576
1651
  exports.renderStepperBar = renderStepperBar;
1577
1652
  exports.saveIndicator = saveIndicator;
1578
1653
  exports.showAbout = showAbout;