giggles 0.5.1 → 0.5.3

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.
@@ -48,7 +48,6 @@ function useKeybindingRegistry(focus) {
48
48
  return trapIndex >= 0 ? new Set(branchPath.slice(0, trapIndex + 1)) : null;
49
49
  })();
50
50
  const available = all.filter((b) => {
51
- if (b.when === "mounted") return withinTrapSet ? withinTrapSet.has(b.nodeId) : true;
52
51
  return (withinTrapSet ?? branchSet).has(b.nodeId);
53
52
  });
54
53
  const local = focus ? all.filter((b) => b.nodeId === focus.id) : [];
@@ -397,14 +396,13 @@ var FocusStore = class {
397
396
  if (typeof def === "function") {
398
397
  return [key, { handler: def }];
399
398
  }
400
- return [key, { handler: def.action, name: def.name, when: def.when }];
399
+ return [key, { handler: def.action, name: def.name }];
401
400
  });
402
401
  const registration = {
403
402
  bindings: new Map(entries),
404
403
  capture: (options == null ? void 0 : options.capture) ?? false,
405
404
  onKeypress: options == null ? void 0 : options.onKeypress,
406
- passthrough: (options == null ? void 0 : options.passthrough) ? new Set(options.passthrough) : void 0,
407
- layer: options == null ? void 0 : options.layer
405
+ passthrough: (options == null ? void 0 : options.passthrough) ? new Set(options.passthrough) : void 0
408
406
  };
409
407
  if (!this.keybindings.has(nodeId)) {
410
408
  this.keybindings.set(nodeId, /* @__PURE__ */ new Map());
@@ -427,7 +425,6 @@ var FocusStore = class {
427
425
  let finalCapture = false;
428
426
  let finalOnKeypress;
429
427
  let finalPassthrough;
430
- let finalLayer;
431
428
  for (const registration of nodeRegistrations.values()) {
432
429
  const isCaptureRegistration = registration.onKeypress !== void 0;
433
430
  const shouldIncludeBindings = !isCaptureRegistration || registration.capture;
@@ -441,16 +438,12 @@ var FocusStore = class {
441
438
  finalOnKeypress = registration.onKeypress;
442
439
  finalPassthrough = registration.passthrough;
443
440
  }
444
- if (registration.layer) {
445
- finalLayer = registration.layer;
446
- }
447
441
  }
448
442
  return {
449
443
  bindings: mergedBindings,
450
444
  capture: finalCapture,
451
445
  onKeypress: finalOnKeypress,
452
- passthrough: finalPassthrough,
453
- layer: finalLayer
446
+ passthrough: finalPassthrough
454
447
  };
455
448
  }
456
449
  getAllBindings() {
@@ -462,9 +455,7 @@ var FocusStore = class {
462
455
  nodeId,
463
456
  key,
464
457
  handler: entry.handler,
465
- name: entry.name,
466
- when: entry.when,
467
- layer: registration.layer
458
+ name: entry.name
468
459
  });
469
460
  }
470
461
  }
@@ -476,38 +467,41 @@ var FocusStore = class {
476
467
  // ---------------------------------------------------------------------------
477
468
  // Bridge target for InputRouter. Walks the active branch path with passive-scope
478
469
  // skipping, capture mode, and trap boundary — the full dispatch algorithm.
470
+ //
471
+ // Priority order (per node, walking focused → root):
472
+ // 1. Named bindings — always checked first
473
+ // 2. Capture mode (onKeypress) — deferred until after the full path walk,
474
+ // so named bindings at any ancestor still fire before capture kicks in.
475
+ // Keys in `passthrough` skip capture and bubble to the next ancestor.
476
+ // 3. Trap boundary — stops the walk; capture inside the trap still fires.
479
477
  dispatch(input, key) {
480
478
  var _a;
481
479
  const keyName = normalizeKey(input, key);
482
480
  if (!keyName) return;
483
481
  const path = this.getActiveBranchPath();
484
482
  const trapNodeId = this.trapNodeId;
483
+ let pendingCapture;
485
484
  for (const nodeId of path) {
486
485
  if (this.passiveSet.has(nodeId)) continue;
487
486
  const nodeBindings = this.getNodeBindings(nodeId);
488
487
  if (nodeBindings) {
489
- if (nodeBindings.capture && nodeBindings.onKeypress) {
490
- if (!((_a = nodeBindings.passthrough) == null ? void 0 : _a.has(keyName))) {
491
- nodeBindings.onKeypress(input, key);
492
- return;
493
- }
494
- }
495
488
  const entry = nodeBindings.bindings.get(keyName);
496
- if (entry && entry.when !== "mounted") {
489
+ if (entry) {
497
490
  entry.handler(input, key);
498
491
  return;
499
492
  }
493
+ if (!pendingCapture && nodeBindings.capture && nodeBindings.onKeypress) {
494
+ if ((_a = nodeBindings.passthrough) == null ? void 0 : _a.has(keyName)) {
495
+ continue;
496
+ }
497
+ pendingCapture = nodeBindings.onKeypress;
498
+ }
500
499
  }
501
500
  if (nodeId === trapNodeId) {
502
- return;
503
- }
504
- }
505
- for (const binding of this.getAllBindings()) {
506
- if (binding.key === keyName && binding.when === "mounted") {
507
- binding.handler(input, key);
508
- return;
501
+ break;
509
502
  }
510
503
  }
504
+ pendingCapture == null ? void 0 : pendingCapture(input, key);
511
505
  }
512
506
  // ---------------------------------------------------------------------------
513
507
  // Private helpers
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
3
  import { BoxProps } from 'ink';
4
4
  export { Key } from 'ink';
5
- import { K as Keybindings, a as KeybindingOptions, R as RegisteredKeybinding } from './types-Dmw9TKt4.js';
6
- export { b as KeyHandler } from './types-Dmw9TKt4.js';
5
+ import { K as Keybindings, a as KeybindingOptions, R as RegisteredKeybinding } from './types-BODf7e7U.js';
6
+ export { b as KeyHandler } from './types-BODf7e7U.js';
7
7
 
8
8
  declare class GigglesError extends Error {
9
9
  constructor(message: string);
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  useKeybindingRegistry,
15
15
  useKeybindings,
16
16
  useStore
17
- } from "./chunk-LXNKSYJT.js";
17
+ } from "./chunk-RO3ZD423.js";
18
18
  import {
19
19
  ThemeProvider,
20
20
  useTheme
@@ -6,22 +6,18 @@ type KeyName = SpecialKey | (string & {});
6
6
  type KeybindingDefinition = KeyHandler | {
7
7
  action: KeyHandler;
8
8
  name: string;
9
- when?: 'focused' | 'mounted';
10
9
  };
11
10
  type Keybindings = Partial<Record<KeyName, KeybindingDefinition>>;
12
11
  type KeybindingOptions = {
13
12
  capture?: boolean;
14
13
  onKeypress?: (input: string, key: Key) => void;
15
14
  passthrough?: string[];
16
- layer?: string;
17
15
  };
18
16
  type RegisteredKeybinding = {
19
17
  nodeId: string;
20
18
  key: string;
21
19
  handler: KeyHandler;
22
20
  name?: string;
23
- when?: 'focused' | 'mounted';
24
- layer?: string;
25
21
  };
26
22
 
27
23
  export type { Keybindings as K, RegisteredKeybinding as R, KeybindingOptions as a, KeyHandler as b };
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { R as RegisteredKeybinding } from '../types-Dmw9TKt4.js';
2
+ import { R as RegisteredKeybinding } from '../types-BODf7e7U.js';
3
3
  import React$1 from 'react';
4
4
  import { BoxProps } from 'ink';
5
5
 
package/dist/ui/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  useFocusNode,
5
5
  useKeybindingRegistry,
6
6
  useKeybindings
7
- } from "../chunk-LXNKSYJT.js";
7
+ } from "../chunk-RO3ZD423.js";
8
8
  import {
9
9
  CodeBlock
10
10
  } from "../chunk-SKSDNDQF.js";
@@ -78,7 +78,6 @@ function Inner({ onClose, render }) {
78
78
  },
79
79
  {
80
80
  capture: true,
81
- passthrough: ["escape", "enter", "left", "right", "backspace"],
82
81
  onKeypress: (input, key) => {
83
82
  if (input.length === 1 && !key.ctrl) {
84
83
  setQuery((q) => q + input);
@@ -644,20 +643,7 @@ function Autocomplete({
644
643
  },
645
644
  {
646
645
  capture: true,
647
- passthrough: [
648
- "tab",
649
- "shift+tab",
650
- "escape",
651
- "backspace",
652
- "delete",
653
- "left",
654
- "right",
655
- "home",
656
- "end",
657
- "up",
658
- "down",
659
- "enter"
660
- ],
646
+ passthrough: ["tab", "shift+tab", "escape"],
661
647
  onKeypress: (input, key) => {
662
648
  if (input.length === 1 && !key.ctrl && !key.return && !key.escape && !key.tab) {
663
649
  const c = cursorRef.current;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "giggles",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",