From d34ca787ca109fd578053a98939da429eafa2604 Mon Sep 17 00:00:00 2001 From: PRASSamin Date: Sun, 30 Aug 2026 17:31:20 +0600 Subject: [PATCH 1/4] feat(release): v2.0.0 - cascade mode, priority scopes, hooks, zero- blinking react architecture, and ci/cd workflows --- .changeset/config.json | 10 +- .github/workflows/ci.yml | 42 ++ .github/workflows/release.yml | 57 +++ README.md | 131 +++--- packages/core/CHANGELOG.md | 18 + packages/core/README.md | 546 +++++++--------------- packages/core/package.json | 2 +- packages/core/src/ScopeManager.ts | 212 ++++++++- packages/core/src/ShortcutManager.test.ts | 465 +++++++++++++++++- packages/core/src/ShortcutManager.ts | 418 ++++++++++++++--- packages/core/src/index.ts | 13 +- packages/core/src/types.ts | 90 +++- packages/core/src/utils/expandAliases.ts | 10 +- packages/core/src/utils/isInputTarget.ts | 13 + packages/react/CHANGELOG.md | 21 + packages/react/README.md | 385 ++++++++++----- packages/react/package.json | 3 +- packages/react/src/Keybindy.test.tsx | 136 +++++- packages/react/src/Keybindy.tsx | 110 +---- packages/react/src/ShortcutLabel.tsx | 134 ------ packages/react/src/index.ts | 34 +- packages/react/src/types.ts | 4 +- packages/react/src/useKeybindy.tsx | 211 ++++++++- packages/react/src/useShortcuts.ts | 311 ++++++++++++ tests/sample-project/index.html | 5 +- tests/sample-project/src/main.js | 34 +- tests/sample-react/src/App.jsx | 46 +- 27 files changed, 2488 insertions(+), 973 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 packages/core/src/utils/isInputTarget.ts delete mode 100644 packages/react/src/ShortcutLabel.tsx create mode 100644 packages/react/src/useShortcuts.ts diff --git a/.changeset/config.json b/.changeset/config.json index 8bc7e8a..06d82f8 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,11 +1,13 @@ { - "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": "@changesets/cli/changelog", "commit": false, "fixed": [], - "linked": [], + "linked": [ + ["@keybindy/core", "@keybindy/react"] + ], "access": "public", "baseBranch": "main", - "changelog": false, "updateInternalDependencies": "patch", - "ignore": ["@tests/*"] + "ignore": [] } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0fa1b84 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + validate: + name: Test & Build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10.16.1 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run Tests + run: pnpm test + + - name: Run Lint + run: pnpm lint + + - name: Build Packages + run: pnpm build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c088622 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,57 @@ +name: Release + +on: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +jobs: + release: + name: Release & Publish + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10.16.1 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'pnpm' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run Tests & Build + run: | + pnpm test + pnpm build + + - name: Create Release PR or Publish to NPM + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm release + version: pnpm version + title: 'chore(release): Version Packages' + commit: 'chore(release): Version Packages' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/README.md b/README.md index 007e7ee..bcb6cda 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,102 @@ # Keybindy -**A lightweight, fast, and framework-agnostic TypeScript library for managing keyboard shortcuts in modern web applications.** +

+ The lightweight, framework-agnostic keyboard shortcut engine for modern web apps.
+ Fast, tiny, type-safe, and zero dependencies. +

-Keybindy provides a simple yet powerful API to register, manage, and scope keyboard shortcuts with a tiny footprint and zero dependencies. It is designed to be flexible, tree-shakeable, and easy to integrate into any project, from vanilla JavaScript to React. - -[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) +

+ MIT License + TypeScript + pnpm +

--- -## About Keybindy - -Keyboard shortcuts are essential for a productive user experience, but managing them across different components, contexts, and frameworks can be complex. Keybindy solves this by providing a robust, centralized, and framework-agnostic solution. +## 🎯 About Keybindy -- **Tiny & Dependency-Free**: Approximately 2KB gzipped, with no external dependencies. -- **Framework-Agnostic**: Works with Vanilla JS, React, Vue, Svelte, and any other framework. -- **Simple yet Powerful API**: Clean and intuitive methods to register, scope, and manage shortcuts. -- **Type-Safe**: Written entirely in TypeScript for a great developer experience. -- **SSR-Safe**: Designed to work flawlessly in server-side rendering environments like Next.js. +Handling keyboard shortcuts in modern web applications shouldn't require messy event listeners, broken modal state, or bulky dependencies. -## Packages +**Keybindy** is a centralized, high-performance keyboard shortcut engine (~2KB gzipped) designed to handle everything from simple hotkeys to complex Figma/Vim-style layered tools with ease: -This repository is a monorepo managed by [pnpm](https://pnpm.io/). It contains the following packages: +- **Simultaneous, Hold, & Sequential Chains**: Support for chords (`Ctrl+Shift+P`), holdable push-to-talk keys, and Vim sequences (`G` then `D`). +- **Modal Isolation & Cascading Tools**: Strict scope isolation (`default` mode) or layered priority overrides (`cascade` mode). +- **Smart Input Detection**: Automatically ignores keystrokes when typing in inputs, textareas, and contenteditables (with per-shortcut overrides). +- **Lifecycle Safety in React**: Stable ref architecture that completely eliminates hook "blinking" and stale closures. +- **Zero Dependencies & 100% Type-Safe**: Written in TypeScript with rich autocomplete. -| Package | Version | Description | Docs | -| ------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------- | -| [`@keybindy/core`](./packages/core) | [![npm version](https://badge.fury.io/js/@keybindy%2Fcore.svg)](https://www.npmjs.com/package/@keybindy/core) | The core, framework-agnostic shortcut management library. | [Docs](./packages/core/README.md) | -| [`@keybindy/react`](./packages/react) | [![npm version](https://badge.fury.io/js/@keybindy%2Freact.svg)](https://www.npmjs.com/package/@keybindy/react) | React components and hooks for seamless integration with React applications. | [Docs](./packages/react/README.md) | +--- -## Installation +## πŸ“¦ Packages -Install the package you need using your preferred package manager: +| Package | Version | Description | Docs | +| :--- | :--- | :--- | :--- | +| [`@keybindy/core`](./packages/core) | [![npm version](https://img.shields.io/npm/v/@keybindy/core.svg?style=flat&colorA=18181B&colorB=3B82F6)](https://www.npmjs.com/package/@keybindy/core) | Core framework-agnostic shortcut engine. | [Core Docs](./packages/core/README.md) | +| [`@keybindy/react`](./packages/react) | [![npm version](https://img.shields.io/npm/v/@keybindy/react.svg?style=flat&colorA=18181B&colorB=3B82F6)](https://www.npmjs.com/package/@keybindy/react) | Modern React hooks & components (`useShortcut`, `useShortcuts`, ``). | [React Docs](./packages/react/README.md) | -```bash -# For the core library -pnpm add @keybindy/core - -# For the React integration -pnpm add @keybindy/react -``` +--- -## Getting Started +## πŸš€ Quick Look -Here is a quick example of how to use `@keybindy/core` in a vanilla JavaScript project. +### Vanilla JS / Framework-Agnostic (`@keybindy/core`) ```ts import ShortcutManager from '@keybindy/core'; -// 1. Initialize the manager -const manager = new ShortcutManager(); +const shortcuts = new ShortcutManager({ ignoreInputs: true }); -// 2. Define a handler -const saveDocument = () => { - console.log('Document saved!'); -}; +// Register shortcut +shortcuts.register(['Ctrl', 'S'], () => { + saveDocument(); +}, { preventDefault: true }); -// 3. Register the shortcut -manager.register(['Ctrl', 'S'], saveDocument, { - // Optional: prevent the browser's default save action - preventDefault: true, -}); +// Sequential Vim-style shortcut (G then D) +shortcuts.register(['G', 'D'], () => { + navigateToDashboard(); +}, { sequential: true }); ``` -For framework-specific usage, please see the `README.md` file in the corresponding package directory. +### React (`@keybindy/react`) -## Development and Contributing +```tsx +import { useShortcut, useShortcuts } from '@keybindy/react'; -This project is a monorepo, and we welcome contributions! To get started with local development, follow these steps: +function Canvas() { + const [scale, setScale] = useState(1); -1. **Clone the repository:** + // ⚑️ Always accesses latest state with ZERO re-registration flickering + useShortcut(['Ctrl', '+'], () => setScale(s => s + 0.1), { + preventDefault: true, + }); - ```bash - git clone https://github.com/keybindyjs/keybindy.git - cd keybindy - ``` - -2. **Install dependencies:** + useShortcuts([ + { keys: ['Space'], handler: (e, state) => setPanning(state === 'down'), options: { hold: true } }, + { keys: ['Esc'], handler: deselectAll, options: { enableInInput: true } }, + ]); +} +``` - This project uses `pnpm` for workspace management. Install it if you haven't already (`npm install -g pnpm`), then run: +--- - ```bash - pnpm install - ``` +## πŸ›  Local Development & Testing -3. **Run tests:** +```bash +# 1. Clone repo +git clone https://github.com/keybindyjs/keybindy.git +cd keybindy - You can run tests for all packages or for a specific one. +# 2. Install dependencies +pnpm install - ```bash - # Run all tests - pnpm test +# 3. Run all unit tests +pnpm test - # Run tests for a specific package (e.g., @keybindy/react) - pnpm --filter @keybindy/react test - ``` +# 4. Build packages +pnpm build +``` -We encourage you to open an issue or a pull request if you have ideas for improvement or have found a bug. +--- -## License +## πŸ“„ License -This project is licensed under the MIT License. See the [LICENSE](./LICENSE.md) file for details. +MIT Β© [Keybindy Contributors](https://github.com/keybindyjs/keybindy) diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 10358fe..32f904c 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,23 @@ # @keybindy/core +## [2.0.0] - 2026-08-30 + +### Major Features & Improvements + +- **Cascading Scope Mode & Priority Weights**: + - Added `scopeMode: 'default' | 'cascade'`. In `'default'` mode, only the topmost active scope is enabled (ideal for strict modal isolation). In `'cascade'` mode, all active scopes work together. + - Added dynamic numeric priority weighting (`setScopePriority(scope, priority)`, `removeScopePriority(scope)`). Common key collisions are resolved by priority weight (e.g. `100 > 10 > 0`) or stack order, while non-colliding parent shortcuts continue executing. +- **Guard & Interceptor Middlewares**: + - Added `beforeEach((shortcut, event) => boolean | void, options?)` guard hook. Returning `false` safely cancels shortcut execution. + - Added `afterEach((shortcut, event) => void, options?)` interceptor hook for analytics, telemetry, and side-effects. +- **Smart Input Target Handling**: + - Added automatic ignoring of keystrokes when typing inside ``, ` + diff --git a/tests/sample-project/src/main.js b/tests/sample-project/src/main.js index 5b3c16a..0cb320d 100644 --- a/tests/sample-project/src/main.js +++ b/tests/sample-project/src/main.js @@ -17,7 +17,7 @@ manager.register( manager.register( ['D'], - e => { + () => { console.log('D key released!'); }, { @@ -27,7 +27,7 @@ manager.register( manager.register( ['D'], - e => { + () => { console.log('D key pressed!'); }, { @@ -82,7 +82,35 @@ manager.register( scope: 'lg', } ); +manager.register( + ['l', 'g'], + () => { + console.log('Sequential LG shortcut triggered from default!'); + }, + { + sequential: true, + sequenceDelay: 3000, + } +); + +manager.register( + ['Ctrl', 'C'], + () => { + console.log('CTRL+C shortcut triggered!'); + }, + { + ignoreInputs: true, + } +); + +// manager.setActiveScope('nono'); -manager.setActiveScope('global'); // manager.disableAll(); // Get all methods (including inherited ones) +manager.setScopeMode('cascade'); +manager.setScopePriority(scope => ({ ...scope, global: 10 })); +// manager.setScopePriority(scope => ({ ...scope, global: 10 })); +// console.log(manager.getScopesInfo()); +// console.log(manager.getScopePriority()); + +console.log(manager.getScopePriority()); diff --git a/tests/sample-react/src/App.jsx b/tests/sample-react/src/App.jsx index ffd9a03..939ff9b 100644 --- a/tests/sample-react/src/App.jsx +++ b/tests/sample-react/src/App.jsx @@ -1,16 +1,14 @@ import { useEffect, useState } from 'react'; -import { Keybindy, ShortcutLabel, useKeybindy } from '@keybindy/react'; +import { Keybindy, useKeybindy } from '@keybindy/react'; function App() { const [isOpen, setIsOpen] = useState(false); + const [isModelOpen, setIsModelOpen] = useState(false); const s = useKeybindy(); useEffect(() => { - s.register(['Enter'], () => { - console.log('Enter key pressed!'); - }); - console.log(s.getCheatSheet()) - }, [s]); + console.log(s.getScopePriority()) + }, [s]) return ( @@ -63,6 +61,11 @@ function App() { variable++; console.log('Z pressed:', variable); }, + options: { + repeat: true, + // ignoreInputs: true + + } }, { keys: ['X'], @@ -74,22 +77,6 @@ function App() { ]; }}> -
- { - // console.log(keys) - // return keys.map((key) => ( - // - // {key} - // - // )); - // }} - /> -

Vite + React

{isOpen && ( @@ -128,9 +115,24 @@ function App() { Edit src/App.jsx and save to test HMR

Click on the Vite and React logos to learn more

+ + + + {isModelOpen && } + +
); } export default App; + +const Model = ({ setIsModelOpen }) => { + return ( { console.log("x presed from model") } }]}> +
+

Open

+ +
+
) +} \ No newline at end of file From 2ce32311c58566401ca2d515a1bde0aa16ee5894 Mon Sep 17 00:00:00 2001 From: PRASSamin Date: Sun, 30 Aug 2026 17:33:28 +0600 Subject: [PATCH 2/4] chore: add tests folder to changeset ignore list --- .changeset/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/config.json b/.changeset/config.json index 06d82f8..24b29b5 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -9,5 +9,5 @@ "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": [] + "ignore": ["@tests/*"] } From 611d077a13904f2e9bfc8c91b99e753260f3d671 Mon Sep 17 00:00:00 2001 From: PRASSamin Date: Sun, 30 Aug 2026 17:38:22 +0600 Subject: [PATCH 3/4] fix(ci): add vitest source alias and update build order in ci workflow --- .github/workflows/ci.yml | 6 +++--- packages/react/vitest.config.ts | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fa1b84..1786004 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,11 +32,11 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Build Packages + run: pnpm build + - name: Run Tests run: pnpm test - name: Run Lint run: pnpm lint - - - name: Build Packages - run: pnpm build diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index 3510c74..b512fa0 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -1,6 +1,12 @@ import { defineConfig } from 'vitest/config'; +import path from 'path'; export default defineConfig({ + resolve: { + alias: { + '@keybindy/core': path.resolve(__dirname, '../core/src/index.ts'), + }, + }, test: { globals: true, environment: 'happy-dom', From f8f8fa4d653e22a9d23fb2173f4939beff9ab36a Mon Sep 17 00:00:00 2001 From: PRASSamin Date: Sun, 30 Aug 2026 17:55:52 +0600 Subject: [PATCH 4/4] fix: improve binding types, scope cleanup checks, and sequential hook filtering --- packages/core/src/ShortcutManager.test.ts | 21 +++++++++++++++++++++ packages/core/src/ShortcutManager.ts | 11 ++++++++--- packages/core/src/types.ts | 4 ++-- packages/react/src/Keybindy.test.tsx | 10 ++++++++++ packages/react/src/useShortcuts.ts | 6 +++++- packages/react/vitest.config.ts | 4 ++++ tests/sample-react/src/App.jsx | 12 ++++++------ 7 files changed, 56 insertions(+), 12 deletions(-) diff --git a/packages/core/src/ShortcutManager.test.ts b/packages/core/src/ShortcutManager.test.ts index 880fd51..89a5b46 100644 --- a/packages/core/src/ShortcutManager.test.ts +++ b/packages/core/src/ShortcutManager.test.ts @@ -675,6 +675,27 @@ describe('ShortcutManager', () => { expect(beforeHook).toHaveBeenCalledOnce(); // Still 1, not called again expect(handler).toHaveBeenCalledTimes(2); }); + + it('should preserve key order when filtering hooks on sequential shortcuts', () => { + const gdBeforeHook = vi.fn(); + const dgBeforeHook = vi.fn(); + + manager.beforeEach(gdBeforeHook, { keys: ['G', 'D'] }); + manager.beforeEach(dgBeforeHook, { keys: ['D', 'G'] }); + + const gdHandler = vi.fn(); + manager.register(['G', 'D'], gdHandler, { sequential: true }); + + // Trigger G then D sequence + dispatchKeyEvent('keydown', 'KeyG'); + dispatchKeyEvent('keyup', 'KeyG'); + dispatchKeyEvent('keydown', 'KeyD'); + dispatchKeyEvent('keyup', 'KeyD'); + + expect(gdHandler).toHaveBeenCalledOnce(); + expect(gdBeforeHook).toHaveBeenCalledOnce(); + expect(dgBeforeHook).not.toHaveBeenCalled(); + }); }); }); diff --git a/packages/core/src/ShortcutManager.ts b/packages/core/src/ShortcutManager.ts index 8b4092b..35e9091 100644 --- a/packages/core/src/ShortcutManager.ts +++ b/packages/core/src/ShortcutManager.ts @@ -114,16 +114,21 @@ export class ShortcutManager extends ScopeManager { Array.isArray(options.keys[0]) ? options.keys : [options.keys] ) as unknown as Keys[][]; + const isSequential = Boolean(shortcut.options?.sequential); + const normalizeCombo = (combo: Keys[]): string => { + const ordered = isSequential ? combo : [...combo].sort(); + return ordered.map(k => k.toLowerCase()).join(isSequential ? '>' : '+'); + }; + const expandedCombos: string[] = []; for (const binding of targetBindings) { const combos = expandAliases(binding); for (const combo of combos) { - const normalized = combo.map(k => k.toLowerCase()).sort().join('+'); - expandedCombos.push(normalized); + expandedCombos.push(normalizeCombo(combo)); } } - const shortcutCombo = [...shortcut.keys].map(k => k.toLowerCase()).sort().join('+'); + const shortcutCombo = normalizeCombo([...shortcut.keys] as Keys[]); if (!expandedCombos.includes(shortcutCombo)) { return false; } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index a271673..d6867fb 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -318,7 +318,7 @@ export type Key = Keys | (string & {}); * It can be a single combination (e.g., `['Ctrl', 'S']`) or multiple * combinations for the same shortcut (e.g., `[['Ctrl', 'K'], ['Meta', 'K']]`). */ -export type ShortcutBinding = (Key | Key[])[]; +export type ShortcutBinding = Key[] | Key[][]; /** * Hook function executed before a shortcut handler runs. @@ -349,7 +349,7 @@ export type HookOptions = { * 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[])[]; + keys?: Key[] | Key[][]; }; diff --git a/packages/react/src/Keybindy.test.tsx b/packages/react/src/Keybindy.test.tsx index 4017b84..83d702b 100644 --- a/packages/react/src/Keybindy.test.tsx +++ b/packages/react/src/Keybindy.test.tsx @@ -22,6 +22,7 @@ const mockManagerInstance = { clearScopePriority: vi.fn(), setScopeMode: vi.fn(), getScopeMode: vi.fn(() => 'default'), + getCheatSheet: vi.fn((): any[] => []), beforeEach: vi.fn(() => vi.fn()), afterEach: vi.fn(() => vi.fn()), }; @@ -114,6 +115,15 @@ describe(' Component', () => { expect(mockManagerInstance.popScope).toHaveBeenCalledOnce(); }); + it('should not popScope if other shortcuts still remain in the same scope', async () => { + mockManagerInstance.getCheatSheet.mockReturnValueOnce([{ keys: ['Ctrl', 'Z'] }]); + const { unmount } = render(); + + unmount(); + + expect(mockManagerInstance.popScope).not.toHaveBeenCalled(); + }); + it('should handle priority prop by setting and removing numeric scope priority', async () => { const { unmount } = render(); diff --git a/packages/react/src/useShortcuts.ts b/packages/react/src/useShortcuts.ts index b7d19a8..e2414df 100644 --- a/packages/react/src/useShortcuts.ts +++ b/packages/react/src/useShortcuts.ts @@ -165,6 +165,7 @@ export const useShortcuts = ( // Keep a ref of current handlers so our stable handler closures never go stale. const handlersRef = React.useRef>({}); + handlersRef.current = {}; shortcuts.forEach(({ keys, handler }) => { handlersRef.current[JSON.stringify(keys)] = handler; }); @@ -242,7 +243,10 @@ export const useShortcuts = ( removeScopePriority(scope); } if (scope !== 'global') { - popScope(scope); + const remaining = manager.getCheatSheet(scope); + if (!remaining || remaining.length === 0) { + popScope(scope); + } } if (scopeMode && prevScopeMode !== undefined) { setScopeMode(prevScopeMode); diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index b512fa0..2e151b5 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -1,5 +1,9 @@ import { defineConfig } from 'vitest/config'; import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); export default defineConfig({ resolve: { diff --git a/tests/sample-react/src/App.jsx b/tests/sample-react/src/App.jsx index 939ff9b..461d537 100644 --- a/tests/sample-react/src/App.jsx +++ b/tests/sample-react/src/App.jsx @@ -3,7 +3,7 @@ import { Keybindy, useKeybindy } from '@keybindy/react'; function App() { const [isOpen, setIsOpen] = useState(false); - const [isModelOpen, setIsModelOpen] = useState(false); + const [isModalOpen, setIsModalOpen] = useState(false); const s = useKeybindy(); useEffect(() => { @@ -116,9 +116,9 @@ function App() {

Click on the Vite and React logos to learn more

- + - {isModelOpen && } + {isModalOpen && }
@@ -128,11 +128,11 @@ function App() { export default App; -const Model = ({ setIsModelOpen }) => { - return ( { console.log("x presed from model") } }]}> +const Modal = ({ setIsModalOpen }) => { + return ( { console.log("x pressed from Modal") } }]}>

Open

- +
) } \ No newline at end of file