@wildwinter/app-shell 0.33.1 → 0.34.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.
@@ -5,6 +5,10 @@ var EDIT_MENU = {
5
5
  duplicate: { label: "Duplicate", accelerator: "CmdOrCtrl+D" },
6
6
  find: { label: "Find\u2026", accelerator: "CmdOrCtrl+F" }
7
7
  };
8
+ var GO_MENU = {
9
+ back: { label: "Back", acceleratorMac: "Ctrl+Cmd+Left", acceleratorOther: "Alt+Left" },
10
+ forward: { label: "Forward", acceleratorMac: "Ctrl+Cmd+Right", acceleratorOther: "Alt+Right" }
11
+ };
8
12
  var PANE_MENU = {
9
13
  showNav: { label: "Show Navigator", accelerator: "CmdOrCtrl+1" },
10
14
  showInspector: { label: "Show Inspector", accelerator: "CmdOrCtrl+2" },
@@ -34,6 +38,6 @@ function namedMenuItems(naming) {
34
38
  };
35
39
  }
36
40
 
37
- export { APP_MENU, EDIT_MENU, HELP_MENU, PANE_MENU, namedMenuItems };
38
- //# sourceMappingURL=chunk-YLINCOQD.js.map
39
- //# sourceMappingURL=chunk-YLINCOQD.js.map
41
+ export { APP_MENU, EDIT_MENU, GO_MENU, HELP_MENU, PANE_MENU, namedMenuItems };
42
+ //# sourceMappingURL=chunk-QDPFU4WX.js.map
43
+ //# sourceMappingURL=chunk-QDPFU4WX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu.ts"],"names":[],"mappings":";AA2BO,IAAM,SAAA,GAKT;AAAA,EACF,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,aAAa,aAAA,EAAc;AAAA,EAClD,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,aAAa,mBAAA,EAAoB;AAAA,EACxD,SAAA,EAAW,EAAE,KAAA,EAAO,WAAA,EAAa,aAAa,aAAA,EAAc;AAAA,EAC5D,IAAA,EAAM,EAAE,KAAA,EAAO,YAAA,EAAS,aAAa,aAAA;AACvC;AASO,IAAM,OAAA,GAGT;AAAA,EACF,MAAM,EAAE,KAAA,EAAO,QAAQ,cAAA,EAAgB,eAAA,EAAiB,kBAAkB,UAAA,EAAW;AAAA,EACrF,SAAS,EAAE,KAAA,EAAO,WAAW,cAAA,EAAgB,gBAAA,EAAkB,kBAAkB,WAAA;AACnF;AAGO,IAAM,SAAA,GAIT;AAAA,EACF,OAAA,EAAS,EAAE,KAAA,EAAO,gBAAA,EAAkB,aAAa,aAAA,EAAc;AAAA,EAC/D,aAAA,EAAe,EAAE,KAAA,EAAO,gBAAA,EAAkB,aAAa,aAAA,EAAc;AAAA,EACrE,SAAA,EAAW,EAAE,KAAA,EAAO,YAAA;AACtB;AAkBO,IAAM,SAAA,GAET;AAAA,EACF,eAAA,EAAiB,EAAE,KAAA,EAAO,yBAAA;AAC5B;AAGO,IAAM,QAAA,GAET;AAAA;AAAA,EAEF,QAAA,EAAU,EAAE,KAAA,EAAO,wBAAA;AACrB;AA+BO,SAAS,eAAe,MAAA,EAI7B;AACA,EAAA,MAAM,KAAA,GAAQ,OAAO,SAAA,IAAa,QAAA;AAClC,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,MAAA,EAAS,OAAO,OAAO,CAAA,CAAA,EAAI,OAAO,IAAA,EAAK;AAAA,IACvD,IAAA,EAAM;AAAA,MACJ,KAAA,EAAO,CAAA,EAAG,MAAA,CAAO,OAAO,CAAA,cAAA,CAAA;AAAA,MACxB,GAAI,OAAO,OAAA,GAAU,EAAE,KAAK,MAAA,CAAO,OAAA,KAAY,EAAC;AAAA,MAChD,KAAA,EAAO,OAAO,OAAA,KAAY;AAAA,KAC5B;AAAA,IACA,SAAA,EAAW;AAAA,MACT,KAAA,EAAO,GAAG,KAAK,CAAA,mBAAA,CAAA;AAAA,MACf,GAAI,OAAO,YAAA,GAAe,EAAE,KAAK,MAAA,CAAO,YAAA,KAAiB,EAAC;AAAA,MAC1D,KAAA,EAAO,OAAO,YAAA,KAAiB;AAAA;AACjC,GACF;AACF","file":"chunk-QDPFU4WX.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Shell-owned menu naming: the labels + accelerators for the pane-frame menu\n// items, single-sourced so every app in the family names them identically\n// (and a rename here flows to all of them). Pure data - no electron, no DOM -\n// so a main-process menu builder can import it. Each app builds its own\n// MenuItem from these and wires the click to its shell controller.\n// ---------------------------------------------------------------------------\n\nexport interface MenuLabel {\n label: string;\n /** Electron accelerator string, when the item has one. */\n accelerator?: string;\n}\n\n/**\n * The Edit menu items the family shares.\n *\n * Undo and Redo are here and the MECHANISM is not, which is the whole finding\n * about undo: Patterpad's is ProseMirror's document history, Storyletter's is a\n * replay of file bytes, and those have nothing in common but this. See\n * `design/shared-shell.md`.\n *\n * The rule both apps discovered separately, and the reason these are spelled\n * out rather than left as Electron's `role: \"undo\"`: the native role runs a DOM\n * text-field undo, which knows nothing about either app's model and will\n * silently undo the wrong thing.\n */\nexport const EDIT_MENU: {\n undo: MenuLabel;\n redo: MenuLabel;\n duplicate: MenuLabel;\n find: MenuLabel;\n} = {\n undo: { label: \"Undo\", accelerator: \"CmdOrCtrl+Z\" },\n redo: { label: \"Redo\", accelerator: \"Shift+CmdOrCtrl+Z\" },\n duplicate: { label: \"Duplicate\", accelerator: \"CmdOrCtrl+D\" },\n find: { label: \"Find…\", accelerator: \"CmdOrCtrl+F\" },\n};\n\n/**\n * Back / Forward: navigation HISTORY, the other axis from Up a Level's\n * hierarchy. One string cannot serve both platforms - the mac pair is Xcode's\n * (Cmd+[ is already Up a Level in this family, so the browser pair is taken),\n * and the Alt pair is what every Windows browser and Explorer trained - so the\n * menu builder picks by platform.\n */\nexport const GO_MENU: {\n back: { label: string; acceleratorMac: string; acceleratorOther: string };\n forward: { label: string; acceleratorMac: string; acceleratorOther: string };\n} = {\n back: { label: \"Back\", acceleratorMac: \"Ctrl+Cmd+Left\", acceleratorOther: \"Alt+Left\" },\n forward: { label: \"Forward\", acceleratorMac: \"Ctrl+Cmd+Right\", acceleratorOther: \"Alt+Right\" },\n};\n\n/** The pane-frame menu items (a View menu, conventionally). */\nexport const PANE_MENU: {\n showNav: MenuLabel;\n showInspector: MenuLabel;\n resetView: MenuLabel;\n} = {\n showNav: { label: \"Show Navigator\", accelerator: \"CmdOrCtrl+1\" },\n showInspector: { label: \"Show Inspector\", accelerator: \"CmdOrCtrl+2\" },\n resetView: { label: \"Reset View\" },\n};\n\n/**\n * The Help menu items the family shares, and the one platform rule that goes\n * with them.\n *\n * Lifted from Patterpad, which is the only app that has ever had these: a\n * second app writing its own updater or About is pure waste (`design/\n * shared-shell.md`), and a suite is recognised by finding Check for Updates\n * where you left it. Storyletter will grow both; until it does, these labels\n * are the agreement rather than a description of two implementations.\n *\n * PLACEMENT, which differs by platform and is easy to get wrong:\n * - macOS keeps About in the APP menu (the one named after the product), and\n * Help carries documentation + Check for Updates only.\n * - Windows and Linux have no app menu, so About goes at the foot of Help,\n * after a separator. That is the conventional home there.\n */\nexport const HELP_MENU: {\n checkForUpdates: MenuLabel;\n} = {\n checkForUpdates: { label: \"Check for Updates\\u2026\" },\n};\n\n/** The app-menu items the family shares (macOS; the identity item also belongs in File elsewhere). */\nexport const APP_MENU: {\n userInfo: MenuLabel;\n} = {\n /** Name + optional email, used to sign edits and comments. One label across the suite. */\n userInfo: { label: \"User Information\\u2026\" },\n};\n\n/** What an app must tell the shell to build its named menu items. */\nexport interface MenuNaming {\n /** The product, as it appears in menus: \"Patterpad\", \"Storyletter\". */\n appName: string;\n /** The product's own documentation URL. Omit while an app has no docs yet and\n * the item is rendered disabled rather than opening a broken link. */\n docsUrl?: string;\n /** The suite's documentation home, shared by every app in the family. */\n suiteDocsUrl?: string;\n /** The suite, as it appears in \"<suite> Documentation Home\". Defaults to \"Patter\". */\n suiteName?: string;\n}\n\n/** A named menu item: the label, plus the URL it opens (absent = nothing wired yet). */\nexport interface NamedMenuItem extends MenuLabel {\n url?: string;\n /** False when the app has not supplied a URL, so the builder can render it\n * disabled instead of opening nothing. A placeholder, honestly labelled. */\n ready: boolean;\n}\n\n/**\n * The menu labels that carry a product or suite name, so no app spells its own\n * About or Documentation item differently from the rest of the family.\n *\n * An app with no documentation site yet still gets the ITEM, marked\n * `ready: false`, so the menu has its family shape from day one and wiring the\n * URL later is a one-line change rather than a menu redesign.\n */\nexport function namedMenuItems(naming: MenuNaming): {\n about: NamedMenuItem;\n docs: NamedMenuItem;\n suiteDocs: NamedMenuItem;\n} {\n const suite = naming.suiteName ?? \"Patter\";\n return {\n about: { label: `About ${naming.appName}`, ready: true },\n docs: {\n label: `${naming.appName} Documentation`,\n ...(naming.docsUrl ? { url: naming.docsUrl } : {}),\n ready: naming.docsUrl !== undefined,\n },\n suiteDocs: {\n label: `${suite} Documentation Home`,\n ...(naming.suiteDocsUrl ? { url: naming.suiteDocsUrl } : {}),\n ready: naming.suiteDocsUrl !== undefined,\n },\n };\n}\n"]}
package/dist/index.cjs CHANGED
@@ -467,6 +467,10 @@ var EDIT_MENU = {
467
467
  duplicate: { label: "Duplicate", accelerator: "CmdOrCtrl+D" },
468
468
  find: { label: "Find\u2026", accelerator: "CmdOrCtrl+F" }
469
469
  };
470
+ var GO_MENU = {
471
+ back: { label: "Back", acceleratorMac: "Ctrl+Cmd+Left", acceleratorOther: "Alt+Left" },
472
+ forward: { label: "Forward", acceleratorMac: "Ctrl+Cmd+Right", acceleratorOther: "Alt+Right" }
473
+ };
470
474
  var PANE_MENU = {
471
475
  showNav: { label: "Show Navigator", accelerator: "CmdOrCtrl+1" },
472
476
  showInspector: { label: "Show Inspector", accelerator: "CmdOrCtrl+2" },
@@ -1698,7 +1702,71 @@ function renderStepperBar(host, opts) {
1698
1702
  );
1699
1703
  }
1700
1704
 
1705
+ // src/nav-history.ts
1706
+ function createNavHistory(opts) {
1707
+ const cap = opts.cap ?? 100;
1708
+ const usable = opts.usable ?? (() => true);
1709
+ let past = [];
1710
+ let ahead = [];
1711
+ const step = (from, to, current2) => {
1712
+ for (; ; ) {
1713
+ const p = from.pop();
1714
+ if (p === void 0) return void 0;
1715
+ if (!usable(p)) continue;
1716
+ if (opts.same(p, current2)) continue;
1717
+ to.push(current2);
1718
+ return p;
1719
+ }
1720
+ };
1721
+ return {
1722
+ visit(place2) {
1723
+ ahead = [];
1724
+ const top = past[past.length - 1];
1725
+ if (top !== void 0 && opts.same(top, place2)) past[past.length - 1] = place2;
1726
+ else past.push(place2);
1727
+ if (past.length > cap) past = past.slice(past.length - cap);
1728
+ },
1729
+ back(current2) {
1730
+ return step(past, ahead, current2);
1731
+ },
1732
+ forward(current2) {
1733
+ return step(ahead, past, current2);
1734
+ },
1735
+ canBack() {
1736
+ return past.length > 0;
1737
+ },
1738
+ canForward() {
1739
+ return ahead.length > 0;
1740
+ }
1741
+ };
1742
+ }
1743
+ function historyNav(onBack, onForward) {
1744
+ const btn = (glyph, tip2, onClick) => {
1745
+ const b = document.createElement("button");
1746
+ b.type = "button";
1747
+ b.className = "shell-histnav-btn";
1748
+ b.textContent = glyph;
1749
+ b.dataset["tip"] = tip2;
1750
+ b.setAttribute("aria-label", tip2);
1751
+ b.addEventListener("click", onClick);
1752
+ return b;
1753
+ };
1754
+ const back = btn("\u2039", "Back", onBack);
1755
+ const forward = btn("\u203A", "Forward", onForward);
1756
+ const el2 = document.createElement("span");
1757
+ el2.className = "shell-histnav";
1758
+ el2.append(back, forward);
1759
+ return {
1760
+ el: el2,
1761
+ set(canBack, canForward) {
1762
+ back.disabled = !canBack;
1763
+ forward.disabled = !canForward;
1764
+ }
1765
+ };
1766
+ }
1767
+
1701
1768
  exports.EDIT_MENU = EDIT_MENU;
1769
+ exports.GO_MENU = GO_MENU;
1702
1770
  exports.JOB_PROGRESS = JOB_PROGRESS;
1703
1771
  exports.PALETTE = PALETTE;
1704
1772
  exports.PALETTE_SIZE = PALETTE_SIZE;
@@ -1713,6 +1781,7 @@ exports.closeWithExit = closeWithExit;
1713
1781
  exports.colourFor = colourFor;
1714
1782
  exports.colourIndex = colourIndex;
1715
1783
  exports.confirmDialog = confirmDialog;
1784
+ exports.createNavHistory = createNavHistory;
1716
1785
  exports.createSaveController = createSaveController;
1717
1786
  exports.dupGuard = dupGuard;
1718
1787
  exports.el = el;
@@ -1722,6 +1791,7 @@ exports.focusNewRow = focusNewRow;
1722
1791
  exports.foldVc = foldVc;
1723
1792
  exports.gameIdify = gameIdify;
1724
1793
  exports.hideTip = hideTip;
1794
+ exports.historyNav = historyNav;
1725
1795
  exports.icon = icon;
1726
1796
  exports.iconBtn = iconBtn;
1727
1797
  exports.iconSvg = iconSvg;