staffa 0.15.0 → 0.17.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.
Files changed (82) hide show
  1. package/README.md +99 -271
  2. package/dist/components/autocomplete.js +4 -5
  3. package/dist/components/box.js +11 -21
  4. package/dist/components/button.d.ts +20 -5
  5. package/dist/components/button.js +55 -47
  6. package/dist/components/buttonChooser.js +1 -3
  7. package/dist/components/checkbox.js +1 -2
  8. package/dist/components/dialog.d.ts +9 -2
  9. package/dist/components/dialog.js +28 -32
  10. package/dist/components/field.d.ts +5 -8
  11. package/dist/components/field.js +4 -6
  12. package/dist/components/form.d.ts +5 -7
  13. package/dist/components/form.js +6 -9
  14. package/dist/components/keyhelp.d.ts +22 -0
  15. package/dist/components/keyhelp.js +91 -0
  16. package/dist/components/main.js +188 -271
  17. package/dist/components/menu.d.ts +48 -10
  18. package/dist/components/menu.js +228 -147
  19. package/dist/components/panels.d.ts +151 -239
  20. package/dist/components/panels.js +331 -558
  21. package/dist/components/select.js +1 -3
  22. package/dist/components/tabs.d.ts +10 -13
  23. package/dist/components/tabs.js +38 -58
  24. package/dist/components/textline.d.ts +3 -5
  25. package/dist/components/textline.js +3 -5
  26. package/dist/components/toast.d.ts +1 -3
  27. package/dist/components/toast.js +2 -3
  28. package/dist/components/tooltip.d.ts +4 -5
  29. package/dist/components/tooltip.js +13 -11
  30. package/dist/core.d.ts +17 -24
  31. package/dist/core.js +13 -18
  32. package/dist/icons-helpers.d.ts +3 -3
  33. package/dist/icons-helpers.js +6 -11
  34. package/dist/index.d.ts +3 -1
  35. package/dist/index.js +5 -4
  36. package/dist/keys.d.ts +92 -0
  37. package/dist/keys.js +279 -0
  38. package/dist/staffa.esm.js +1 -1
  39. package/dist/theme.d.ts +4 -10
  40. package/dist/theme.js +58 -123
  41. package/package.json +2 -2
  42. package/skill/ButtonOptions.md +12 -0
  43. package/skill/DialogOptions.md +11 -2
  44. package/skill/FieldOptions.md +3 -5
  45. package/skill/IconButtonOptions.md +8 -0
  46. package/skill/MenuItem.md +32 -3
  47. package/skill/Panel.md +11 -3
  48. package/skill/SKILL.md +161 -294
  49. package/skill/addTooltip.md +4 -5
  50. package/skill/bindKey.md +51 -0
  51. package/skill/box.md +1 -1
  52. package/skill/form.md +5 -7
  53. package/skill/formatKey.md +21 -0
  54. package/skill/iconButton.md +4 -5
  55. package/skill/scrollStrip.md +7 -9
  56. package/skill/showFloatingMenu.md +2 -2
  57. package/skill/showKeyHelp.md +17 -0
  58. package/skill/tabs.md +3 -4
  59. package/skill/textline.md +3 -5
  60. package/src/components/autocomplete.ts +4 -5
  61. package/src/components/box.ts +11 -21
  62. package/src/components/button.ts +70 -47
  63. package/src/components/buttonChooser.ts +1 -3
  64. package/src/components/checkbox.ts +1 -2
  65. package/src/components/dialog.ts +38 -34
  66. package/src/components/field.ts +7 -11
  67. package/src/components/form.ts +6 -9
  68. package/src/components/keyhelp.ts +96 -0
  69. package/src/components/main.ts +191 -270
  70. package/src/components/menu.ts +258 -150
  71. package/src/components/panels.ts +378 -623
  72. package/src/components/select.ts +1 -3
  73. package/src/components/tabs.ts +38 -58
  74. package/src/components/textline.ts +3 -5
  75. package/src/components/toast.ts +3 -6
  76. package/src/components/tooltip.ts +12 -11
  77. package/src/core.ts +17 -24
  78. package/src/icons-helpers.ts +6 -11
  79. package/src/index.ts +5 -4
  80. package/src/keys.ts +300 -0
  81. package/src/theme.ts +58 -123
  82. package/skill/Attributes.md +0 -10
@@ -0,0 +1,91 @@
1
+ import A from "aberdeen";
2
+ import { drawSlot } from "../core.js";
3
+ import { bindKey, formatKey, getActiveKeyBindings } from "../keys.js";
4
+ import { dialog } from "./dialog.js";
5
+ A.insertGlobalCss({
6
+ ".s-keyhelp": {
7
+ "&": "display:flex flex-direction:column gap:$1 min-width:14rem",
8
+ "> div": "display:flex align-items:baseline justify-content:space-between gap:$4",
9
+ "kbd": "font-family:inherit font-size:0.85em fg:$s-muted white-space:nowrap border: 1px solid $s-faint; r:$s-radius-sm padding: 0 0.4em;",
10
+ },
11
+ });
12
+ /** Non-null while the overview is up; calling it closes the dialog. */
13
+ let closeHelp = null;
14
+ /**
15
+ * The shortcut overview: a dialog listing what a keypress could do *right now*
16
+ * — every described binding the keyboard focus and any open modal leave in
17
+ * effect: buttons under their label, menu items under theirs, {@link bindKey}
18
+ * bindings under the description they were given.
19
+ *
20
+ * It's a cheat-sheet, not a modal: the shortcuts it lists keep working, and any
21
+ * keypress closes it *and* still lands — so the key you just looked up can be
22
+ * pressed right there. That is also what keeps the listing honest: focus cannot
23
+ * move while it is up (a click lands on the backdrop, a key closes it), so what
24
+ * was true when it opened stays true. Bound to `?` (and `mod+?`, which also
25
+ * works while typing in a field) by default — see {@link setKeyHelp}. Calling
26
+ * this while the overview is already up closes it, which is what lets that `?`
27
+ * toggle.
28
+ */
29
+ export function showKeyHelp() {
30
+ if (closeHelp) {
31
+ closeHelp();
32
+ return;
33
+ }
34
+ // What a keypress could do at the moment of asking, snapshotted before the
35
+ // overview's own dialog (whose Esc shadows the Esc row shown here) exists.
36
+ // Focus cannot move while the overview is up, so the listing stays true —
37
+ // except for Esc itself, which dismisses the overview first.
38
+ const entries = getActiveKeyBindings(document.activeElement);
39
+ void dialog({
40
+ header: "Keyboard shortcuts",
41
+ // Usually pressed into being from the global `?` handler, where there is
42
+ // no scope to tie the dialog's life to.
43
+ cancelWithScope: false,
44
+ // The whole point: the keys it lists stay pressable while it is up.
45
+ keyboardTransparent: true,
46
+ onClose: () => { closeHelp = null; },
47
+ content: (close) => {
48
+ closeHelp = close;
49
+ // Any keypress closes the overview, in the capture phase so the key
50
+ // then travels on to whoever handles it. Except: bare modifiers (the
51
+ // combination they start still needs reading), Esc (the dialog's own
52
+ // close, handled there) and `?` (the toggle binding's).
53
+ const closer = (e) => {
54
+ if (e.repeat || ["Control", "Shift", "Alt", "Meta", "Escape", "?"].includes(e.key))
55
+ return;
56
+ close();
57
+ };
58
+ document.addEventListener("keydown", closer, true);
59
+ A.clean(() => document.removeEventListener("keydown", closer, true));
60
+ A("div.s-keyhelp", () => {
61
+ for (const [keyStr, binding] of entries) {
62
+ if (binding.description === undefined)
63
+ continue;
64
+ A("div", () => {
65
+ A("span", () => drawSlot(binding.description));
66
+ A("kbd text=", formatKey(keyStr));
67
+ });
68
+ }
69
+ });
70
+ },
71
+ });
72
+ }
73
+ /** Whether the default `?` / `mod+?` bindings are on. */
74
+ const $enabled = A.proxy(true);
75
+ /**
76
+ * Turn the default overview shortcuts off (or back on): `?` — free, like any
77
+ * unmodified key, whenever nothing is being typed into — and `mod+?`, which
78
+ * reaches the overview even from inside a text field. On by default.
79
+ */
80
+ export function setKeyHelp(enabled) {
81
+ $enabled.value = enabled;
82
+ }
83
+ // Global bindings, so they keep working while a dialog is up — the overview
84
+ // should answer anywhere. It lists itself under the `mod+?` spelling, the one
85
+ // that is true everywhere, a text field included; the bare `?` stays quiet.
86
+ A(() => {
87
+ if (!$enabled.value)
88
+ return;
89
+ bindKey("?", undefined, showKeyHelp, "global");
90
+ bindKey("mod+?", "This overview", showKeyHelp, "global");
91
+ });