Skip to content

feat(release): v2.0.0 - cascade mode, priority scopes, hooks, zero-blinking react architecture, and ci/cd workflows - #1

Merged
prassamin merged 4 commits into
mainfrom
release/v2.0.0
Aug 30, 2026
Merged

feat(release): v2.0.0 - cascade mode, priority scopes, hooks, zero-blinking react architecture, and ci/cd workflows#1
prassamin merged 4 commits into
mainfrom
release/v2.0.0

Conversation

@prassamin

Copy link
Copy Markdown
Contributor

v2.0.0 - cascade mode, priority scopes, hooks, zero-blinking react architecture, and ci/cd workflows

Copilot AI lite review requested due to automatic review settings August 30, 2026 11:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prepares the v2.0.0 release of Keybindy by introducing cascading scope mode with priority weights, input-aware shortcut suppression, and before/after shortcut hooks in @keybindy/core, while modernizing @keybindy/react around useShortcut / useShortcuts and updating docs, samples, and CI/CD workflows.

Changes:

  • Add cascade scope mode + numeric scope priorities, input target handling (ignoreInputs / enableInInput), and beforeEach/afterEach hooks to @keybindy/core.
  • Introduce useShortcut / useShortcuts and expand programmatic manager access in @keybindy/react; remove ShortcutLabel; update tests and docs.
  • Bump package versions to 2.0.0, update changelogs/READMEs, and add CI + release workflows with Changesets config updates.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/sample-react/src/App.jsx Updates the React sample to exercise new scoping/priority/input behavior.
tests/sample-project/src/main.js Extends vanilla sample registrations for sequential shortcuts, cascade mode, priority, and input handling.
tests/sample-project/index.html Adds input elements to test input-ignoring behavior.
README.md Refreshes top-level project documentation and quick examples.
packages/react/src/useShortcuts.ts Adds new React hooks (useShortcuts, useShortcut) implementing stable handler refs and lifecycle behavior.
packages/react/src/useKeybindy.tsx Expands manager hook surface (scope mode/priority/hooks) and adds deprecation aliasing.
packages/react/src/types.ts Updates React shortcut typing to use the new ShortcutBinding type.
packages/react/src/ShortcutLabel.tsx Removes the UI helper component to keep the React package headless.
packages/react/src/Keybindy.tsx Refactors <Keybindy /> to delegate registration logic to useShortcuts.
packages/react/src/Keybindy.test.tsx Updates/extends React unit tests for new APIs and behaviors.
packages/react/src/index.ts Re-exports new hooks/types and expands core type exports.
packages/react/README.md Rewrites React package docs to document the new hooks, scoping, and hooks APIs.
packages/react/package.json Bumps @keybindy/react to 2.0.0 and adjusts export typings.
packages/react/CHANGELOG.md Adds v2.0.0 changelog entry describing major React changes.
packages/core/src/utils/isInputTarget.ts Adds helper for detecting input/textarea/select/contenteditable targets.
packages/core/src/utils/expandAliases.ts Extends key alias coverage (cmd/command/option/esc/return, etc.).
packages/core/src/types.ts Adds new public types (ScopeMode, Key, ShortcutBinding, hooks, manager options).
packages/core/src/ShortcutManager.ts Implements cascade behavior, priority resolution, input ignoring, blur reset, and before/after hooks.
packages/core/src/ShortcutManager.test.ts Adds extensive tests for cascade priority, sequences, blur reset, input handling, and hooks.
packages/core/src/ScopeManager.ts Adds scope modes, priority records, sorting, and targeted popScope.
packages/core/src/index.ts Expands exports and re-exports ShortcutManager as a named export.
packages/core/README.md Overhauls core documentation to reflect new API surface and behaviors.
packages/core/package.json Bumps @keybindy/core to 2.0.0.
packages/core/CHANGELOG.md Adds v2.0.0 changelog entry describing core changes.
.github/workflows/release.yml Adds Changesets-based release/publish workflow on main.
.github/workflows/ci.yml Adds CI workflow for test/lint/build on pushes/PRs.
.changeset/config.json Updates Changesets config (schema/changelog/linking) for coordinated releases.
Suppressed comments (1)

packages/core/src/types.ts:353

  • HookOptions.keys uses the same mixed-shape type as ShortcutBinding, which allows invalid combinations and makes hook filtering ambiguous. Reusing ShortcutBinding here keeps the contract consistent with register()/unregister() and avoids mixed-array inputs.
   * Target specific key combination(s) (e.g. `['Delete']` or `[['Ctrl', 'S'], ['Meta', 'S']]`).
   * If omitted or empty, applies to all shortcuts in the scope.
   */
  keys?: (Key | Key[])[];
};

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/react/src/useShortcuts.ts
Comment thread packages/react/src/useShortcuts.ts
Comment thread packages/core/src/types.ts Outdated
Comment thread packages/core/src/ShortcutManager.ts
Comment thread packages/react/src/useKeybindy.tsx
Comment thread tests/sample-react/src/App.jsx Outdated
Copilot AI review requested due to automatic review settings August 30, 2026 11:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.

Suppressed comments (5)

Previously missed (3) — in code that hasn't changed since the last review.

packages/core/src/ShortcutManager.ts:431

  • beforeEach hooks can block hold-shortcut cleanup on keyup: if a guard returns false, activeHoldShortcuts.delete(shortcutId) is skipped, leaving the hold shortcut stuck "down" and preventing future activations.
      if (shortcut && !this.shouldIgnoreForInput(shortcut, e.target) && shortcut.keys.map(k => k.toLowerCase()).includes(key)) {
        if (this.runBeforeHooks(shortcut, e)) {
          if (shortcut.options?.preventDefault) e.preventDefault();
          (shortcut.handler as HoldShortcutHandler)(e, 'up');
          this.activeHoldShortcuts.delete(shortcutId);

packages/react/src/useShortcuts.ts:251

  • ignoreInputs is used when registering shortcuts, but it is not included in the effect dependency array. If a component toggles ignoreInputs, existing registrations won't be updated (and this also violates React hooks dependency expectations).
  }, [scope, manager, disabled, priority, scopeMode, Boolean(beforeEach), Boolean(afterEach), stableShortcuts]);

packages/core/README.md:219

  • Docs say silent defaults to true, but ShortcutManager currently defaults silent = false in the constructor. This makes the README option defaults inaccurate for core users.
  silent?: boolean;                   // Default: true (suppress debug logs)

packages/react/src/useShortcuts.ts:170

  • handlersRef.current is only ever appended/overwritten by key and is never cleared. If the shortcuts list changes over time (dynamic registrations with different key sets), this ref can grow unbounded for the lifetime of the component.
  const handlersRef = React.useRef<Record<string, ShortcutHandler>>({});
  shortcuts.forEach(({ keys, handler }) => {
    handlersRef.current[JSON.stringify(keys)] = handler;
  });

tests/sample-react/src/App.jsx:132

  • Typo in log message: "presed" → "pressed".
  return (<Keybindy scope='dialog' shortcuts={[{ keys: ["X"], handler: () => { console.log("x presed from model") } }]}>

Comment thread packages/react/vitest.config.ts
Copilot AI review requested due to automatic review settings August 30, 2026 11:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@prassamin
prassamin merged commit cd691b8 into main Aug 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants