@chuvenger/devdock 0.7.0 → 0.9.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 (38) hide show
  1. package/README.md +7 -7
  2. package/dist/{chunk-2IQRWZ7T.js → chunk-RO4CY6GJ.js} +3 -3
  3. package/dist/{chunk-2IQRWZ7T.js.map → chunk-RO4CY6GJ.js.map} +1 -1
  4. package/dist/{chunk-2YX4DI2D.js → chunk-V47DEXPS.js} +120 -29
  5. package/dist/chunk-V47DEXPS.js.map +1 -0
  6. package/dist/{dock-C7wZ8pQb.d.cts → dock-ClU_Wn2a.d.cts} +1 -1
  7. package/dist/{dock-DJZuGmih.d.ts → dock-DKknJBIF.d.ts} +1 -1
  8. package/dist/index.cjs +119 -26
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +19 -3
  11. package/dist/index.d.ts +19 -3
  12. package/dist/index.js +1 -1
  13. package/dist/{match-C8MsaP6h.d.ts → match-gTnXtOUP.d.ts} +1 -1
  14. package/dist/{match-Dw1CSS0G.d.cts → match-zABwk1Ai.d.cts} +1 -1
  15. package/dist/react-router.cjs +117 -26
  16. package/dist/react-router.cjs.map +1 -1
  17. package/dist/react-router.d.cts +2 -2
  18. package/dist/react-router.d.ts +2 -2
  19. package/dist/react-router.js +2 -2
  20. package/dist/react.cjs +117 -26
  21. package/dist/react.cjs.map +1 -1
  22. package/dist/react.d.cts +2 -2
  23. package/dist/react.d.ts +2 -2
  24. package/dist/react.js +2 -2
  25. package/dist/svelte.cjs +117 -26
  26. package/dist/svelte.cjs.map +1 -1
  27. package/dist/svelte.d.cts +3 -3
  28. package/dist/svelte.d.ts +3 -3
  29. package/dist/svelte.js +2 -2
  30. package/dist/sveltekit.cjs +117 -26
  31. package/dist/sveltekit.cjs.map +1 -1
  32. package/dist/sveltekit.d.cts +4 -4
  33. package/dist/sveltekit.d.ts +4 -4
  34. package/dist/sveltekit.js +2 -2
  35. package/dist/{types-B8WgSe7o.d.cts → types-D9BBBI7v.d.cts} +16 -4
  36. package/dist/{types-B8WgSe7o.d.ts → types-D9BBBI7v.d.ts} +16 -4
  37. package/package.json +1 -1
  38. package/dist/chunk-2YX4DI2D.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { d as DevRoute } from './types-B8WgSe7o.js';
1
+ import { d as DevRoute } from './types-D9BBBI7v.js';
2
2
 
3
3
  /**
4
4
  * Restricts which auto-detected routes appear. A string is treated as a glob
@@ -1,4 +1,4 @@
1
- import { d as DevRoute } from './types-B8WgSe7o.cjs';
1
+ import { d as DevRoute } from './types-D9BBBI7v.cjs';
2
2
 
3
3
  /**
4
4
  * Restricts which auto-detected routes appear. A string is treated as a glob
@@ -9,21 +9,74 @@ var jsxRuntime = require('react/jsx-runtime');
9
9
  // src/react/react-router.tsx
10
10
 
11
11
  // src/core/hotkey.ts
12
+ var isMac = () => typeof navigator !== "undefined" && /mac/i.test(navigator.platform);
13
+ var KEY_CODES = {
14
+ ".": "Period",
15
+ ",": "Comma",
16
+ "/": "Slash",
17
+ "\\": "Backslash",
18
+ ";": "Semicolon",
19
+ "'": "Quote",
20
+ "[": "BracketLeft",
21
+ "]": "BracketRight",
22
+ "-": "Minus",
23
+ "=": "Equal",
24
+ "`": "Backquote",
25
+ " ": "Space",
26
+ space: "Space"
27
+ };
28
+ var codeFor = (key) => {
29
+ if (/^[a-z]$/.test(key)) return `Key${key.toUpperCase()}`;
30
+ if (/^[0-9]$/.test(key)) return `Digit${key}`;
31
+ return KEY_CODES[key];
32
+ };
12
33
  function matchHotkey(spec, e) {
13
34
  const parts = spec.toLowerCase().split("+").map((p) => p.trim()).filter(Boolean);
14
35
  if (parts.length === 0) return false;
15
36
  const key = parts[parts.length - 1];
16
37
  const mods = new Set(parts.slice(0, -1));
17
- const isMac = typeof navigator !== "undefined" && /mac/i.test(navigator.platform);
18
- const wantMeta = mods.has("meta") || mods.has("cmd") || mods.has("mod") && isMac;
19
- const wantCtrl = mods.has("ctrl") || mods.has("control") || mods.has("mod") && !isMac;
38
+ const mac = isMac();
39
+ const wantMeta = mods.has("meta") || mods.has("cmd") || mods.has("mod") && mac;
40
+ const wantCtrl = mods.has("ctrl") || mods.has("control") || mods.has("mod") && !mac;
20
41
  const wantShift = mods.has("shift");
21
42
  const wantAlt = mods.has("alt") || mods.has("option");
22
43
  if (e.metaKey !== wantMeta) return false;
23
44
  if (e.ctrlKey !== wantCtrl) return false;
24
45
  if (e.shiftKey !== wantShift) return false;
25
46
  if (e.altKey !== wantAlt) return false;
26
- return e.key.toLowerCase() === key;
47
+ if (e.key.toLowerCase() === key) return true;
48
+ return wantAlt && e.code === codeFor(key);
49
+ }
50
+ var DEFAULT_HOTKEY = "alt+shift+d";
51
+ var MAC_SYMBOL = {
52
+ meta: "\u2318",
53
+ cmd: "\u2318",
54
+ ctrl: "\u2303",
55
+ control: "\u2303",
56
+ shift: "\u21E7",
57
+ alt: "\u2325",
58
+ option: "\u2325"
59
+ };
60
+ var PC_NAME = {
61
+ meta: "Win",
62
+ cmd: "Win",
63
+ ctrl: "Ctrl",
64
+ control: "Ctrl",
65
+ shift: "Shift",
66
+ alt: "Alt",
67
+ option: "Alt"
68
+ };
69
+ function formatHotkey(spec) {
70
+ const parts = spec.toLowerCase().split("+").map((p) => p.trim()).filter(Boolean);
71
+ if (parts.length === 0) return "";
72
+ const key = parts[parts.length - 1];
73
+ const mods = parts.slice(0, -1);
74
+ const mac = isMac();
75
+ const label = key.length === 1 ? key.toUpperCase() : key;
76
+ const shown = mods.map(
77
+ (m) => mac ? MAC_SYMBOL[m] ?? (m === "mod" ? "\u2318" : m) : PC_NAME[m] ?? (m === "mod" ? "Ctrl" : m)
78
+ );
79
+ return mac ? [...shown, label].join("") : [...shown, label].join("+");
27
80
  }
28
81
 
29
82
  // src/core/theme.ts
@@ -34,6 +87,7 @@ var partClass = {
34
87
  buttonLabel: "devdock-button-label",
35
88
  panel: "devdock-panel",
36
89
  title: "devdock-title",
90
+ hotkeyHint: "devdock-hotkey-hint",
37
91
  inputWrap: "devdock-input-wrap",
38
92
  input: "devdock-input",
39
93
  body: "devdock-body",
@@ -95,6 +149,10 @@ var BASE_CSS = `
95
149
  }
96
150
 
97
151
  .devdock-title {
152
+ display: flex;
153
+ align-items: center;
154
+ justify-content: space-between;
155
+ gap: 8px;
98
156
  padding: 10px 12px;
99
157
  border-bottom: 1px solid var(--devdock-border, #2a2e37);
100
158
  font-size: 12px;
@@ -104,6 +162,20 @@ var BASE_CSS = `
104
162
  color: var(--devdock-muted, #8b909c);
105
163
  }
106
164
 
165
+ .devdock-hotkey-hint {
166
+ flex-shrink: 0;
167
+ padding: 1px 5px;
168
+ font-family: inherit;
169
+ font-size: 10px;
170
+ font-weight: 600;
171
+ /* The heading's tracking and casing are for words, not for a key cap. */
172
+ letter-spacing: 0;
173
+ text-transform: none;
174
+ color: var(--devdock-subtle, #6b7280);
175
+ border: 1px solid var(--devdock-border, #2a2e37);
176
+ border-radius: var(--devdock-radius-xs, 4px);
177
+ }
178
+
107
179
  .devdock-input-wrap { padding: 8px; }
108
180
 
109
181
  .devdock-input {
@@ -244,27 +316,37 @@ function el(tag, props) {
244
316
  return node;
245
317
  }
246
318
  var PARTS = Object.keys(partClass);
319
+ function edgesOf(position) {
320
+ return position.split("-");
321
+ }
322
+ var CENTER_ALONG = {
323
+ top: { left: "50%", transform: "translateX(-50%)" },
324
+ bottom: { left: "50%", transform: "translateX(-50%)" },
325
+ left: { top: "50%", transform: "translateY(-50%)" },
326
+ right: { top: "50%", transform: "translateY(-50%)" }
327
+ };
328
+ var CLEAR = { top: "", bottom: "", left: "", right: "", transform: "" };
247
329
  function cornerStyle(position) {
248
330
  const gap = "16px";
249
- switch (position) {
250
- case "bottom-left":
251
- return { bottom: gap, left: gap };
252
- case "top-left":
253
- return { top: gap, left: gap };
254
- case "top-right":
255
- return { top: gap, right: gap };
256
- default:
257
- return { bottom: gap, right: gap };
258
- }
331
+ const edges = edgesOf(position);
332
+ const styles = { ...CLEAR };
333
+ for (const edge of edges) styles[edge] = gap;
334
+ if (edges.length === 1) Object.assign(styles, CENTER_ALONG[edges[0]]);
335
+ return styles;
259
336
  }
260
337
  function panelAnchor(position) {
261
- const isTop = position.startsWith("top");
262
- const isRight = position.endsWith("right");
263
- return {
264
- position: "absolute",
265
- [isTop ? "top" : "bottom"]: "calc(100% + 8px)",
266
- [isRight ? "right" : "left"]: "0"
267
- };
338
+ const edges = edgesOf(position);
339
+ const styles = { ...CLEAR, position: "absolute" };
340
+ if (edges.length === 2) {
341
+ const [vertical, horizontal] = edges;
342
+ styles[vertical] = "calc(100% + 8px)";
343
+ styles[horizontal] = "0";
344
+ return styles;
345
+ }
346
+ const edge = edges[0];
347
+ styles[edge] = "calc(100% + 8px)";
348
+ Object.assign(styles, CENTER_ALONG[edge]);
349
+ return styles;
268
350
  }
269
351
  function keyViews(views) {
270
352
  const used = /* @__PURE__ */ new Set();
@@ -309,6 +391,9 @@ function createDevDock(initial = {}) {
309
391
  const panel = el("div");
310
392
  panel.setAttribute("role", "dialog");
311
393
  const heading = el("div");
394
+ const headingText = el("span");
395
+ const hotkeyHint = el("kbd");
396
+ heading.append(headingText, hotkeyHint);
312
397
  const inputWrap = el("div");
313
398
  const input = el("input");
314
399
  input.placeholder = "Filter\u2026";
@@ -338,11 +423,13 @@ function createDevDock(initial = {}) {
338
423
  buttonLabel.className = cls("buttonLabel");
339
424
  panel.className = cls("panel");
340
425
  heading.className = cls("title");
426
+ hotkeyHint.className = cls("hotkeyHint");
341
427
  inputWrap.className = cls("inputWrap");
342
428
  input.className = cls("input");
343
429
  body.className = cls("body");
344
430
  list.className = cls("list");
345
431
  };
432
+ const hotkey = () => opts.hotkey === void 0 ? DEFAULT_HOTKEY : opts.hotkey;
346
433
  const enabled = () => {
347
434
  const e = opts.enabled;
348
435
  if (typeof e === "function") return e();
@@ -626,15 +713,18 @@ function createDevDock(initial = {}) {
626
713
  position: "fixed",
627
714
  zIndex: String(zIndex),
628
715
  top: "",
629
- bottom: "",
630
- left: "",
631
- right: ""
716
+ bottom: ""
632
717
  });
633
718
  Object.assign(root.style, cornerStyle(position));
634
- heading.textContent = opts.title ?? "Dev Menu";
719
+ headingText.textContent = opts.title ?? "Dev Menu";
635
720
  panel.setAttribute("aria-label", opts.title ?? "Dev Menu");
636
721
  Object.assign(panel.style, panelAnchor(position));
637
722
  buttonLabel.textContent = opts.label ?? "DEV";
723
+ const spec = hotkey();
724
+ const chord = spec ? formatHotkey(spec) : "";
725
+ hotkeyHint.textContent = chord;
726
+ hotkeyHint.hidden = !chord;
727
+ button.title = chord ? `${opts.title ?? "Dev Menu"} (${chord})` : opts.title ?? "Dev Menu";
638
728
  button.setAttribute("aria-expanded", String(open));
639
729
  paintClasses();
640
730
  };
@@ -683,7 +773,8 @@ function createDevDock(initial = {}) {
683
773
  if (open && !e.composedPath().includes(root)) setOpen(false);
684
774
  };
685
775
  const onKeyDown = (e) => {
686
- if (opts.hotkey && matchHotkey(opts.hotkey, e)) {
776
+ const spec = hotkey();
777
+ if (spec && matchHotkey(spec, e)) {
687
778
  e.preventDefault();
688
779
  setOpen(!open);
689
780
  }