{"id":29287888,"url":"https://github.com/jalez/react-shortcuts-provider","last_synced_at":"2026-04-12T13:03:51.573Z","repository":{"id":302651187,"uuid":"1013175729","full_name":"Jalez/react-shortcuts-provider","owner":"Jalez","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-03T14:29:29.000Z","size":80,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-03T14:43:26.389Z","etag":null,"topics":["accessibility","eslint","hotkeys","javascript","keybindings","keyboard-events","keyboard-shortcuts","npm-package","react","react-component","react-context","react-hooks","react-library","tailwindcss","typescript","typescript-library","ui-components","vite","vitest","zustand"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jalez.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["jalez"]}},"created_at":"2025-07-03T13:26:15.000Z","updated_at":"2025-07-03T14:29:33.000Z","dependencies_parsed_at":"2025-07-03T14:54:33.263Z","dependency_job_id":null,"html_url":"https://github.com/Jalez/react-shortcuts-provider","commit_stats":null,"previous_names":["jalez/react-shortcuts-provider"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Jalez/react-shortcuts-provider","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jalez%2Freact-shortcuts-provider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jalez%2Freact-shortcuts-provider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jalez%2Freact-shortcuts-provider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jalez%2Freact-shortcuts-provider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jalez","download_url":"https://codeload.github.com/Jalez/react-shortcuts-provider/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jalez%2Freact-shortcuts-provider/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263837459,"owners_count":23517950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","eslint","hotkeys","javascript","keybindings","keyboard-events","keyboard-shortcuts","npm-package","react","react-component","react-context","react-hooks","react-library","tailwindcss","typescript","typescript-library","ui-components","vite","vitest","zustand"],"created_at":"2025-07-06T02:07:28.083Z","updated_at":"2026-04-12T13:03:51.566Z","avatar_url":"https://github.com/Jalez.png","language":"TypeScript","funding_links":["https://github.com/sponsors/jalez"],"categories":[],"sub_categories":[],"readme":"# @jalez/react-shortcuts-provider\n\n[![codecov](https://codecov.io/gh/jalez/react-shortcuts-provider/branch/main/graph/badge.svg)](https://codecov.io/gh/jalez/react-shortcuts-provider)\n[![Sponsor](https://img.shields.io/badge/Sponsor-%E2%9D%A4-red.svg)](https://github.com/sponsors/jalez)\n\nA React context/provider and utilities for managing keyboard shortcuts in your app. This library provides a decoupled, registry-based keyboard shortcuts system that allows components to register actions with specific key combinations without being tightly coupled to other components.\n\n## Installation\n\n```sh\nnpm install @jalez/react-shortcuts-provider\n```\n\n## Features\n\n- **Registry-based**: Components can register/unregister shortcuts dynamically\n- **Decoupled**: No dependencies on other contexts or systems\n- **Categorized**: Shortcuts can be organized into categories\n- **Automatic handling**: Global keyboard event handling\n- **Type-safe**: Full TypeScript support\n- **Flexible**: Support for complex key combinations\n- **Cross-platform**: Works with Ctrl (Windows/Linux) and Cmd (macOS) automatically\n- **Fast Refresh Compatible**: Optimized for React Fast Refresh development\n\n## Quick Start\n\n### 1. Wrap your app with ShortcutsProvider\n\n```tsx\nimport { ShortcutsProvider } from '@jalez/react-shortcuts-provider';\n\nfunction App() {\n  return (\n    \u003cShortcutsProvider\u003e\n      \u003cYourMainComponent /\u003e\n    \u003c/ShortcutsProvider\u003e\n  );\n}\n```\n\n### 2. Register shortcuts in any component\n\n```tsx\nimport { useEffect } from 'react';\nimport { registerShortcut, unregisterShortcut, DEFAULT_SHORTCUT_CATEGORIES } from '@jalez/react-shortcuts-provider';\n\nfunction MyComponent() {\n  useEffect(() =\u003e {\n    // Register a shortcut\n    registerShortcut(\n      DEFAULT_SHORTCUT_CATEGORIES.NAVIGATION,\n      'my-action',\n      'Ctrl+M',\n      () =\u003e console.log('My action triggered!'),\n      'My custom action'\n    );\n\n    // Cleanup\n    return () =\u003e {\n      unregisterShortcut(DEFAULT_SHORTCUT_CATEGORIES.NAVIGATION, 'my-action');\n    };\n  }, []);\n\n  return \u003cdiv\u003eMy Component\u003c/div\u003e;\n}\n```\n\n### 3. Display shortcuts (optional)\n\n```tsx\nimport { ShortcutsDisplay } from '@jalez/react-shortcuts-provider';\n\nfunction MyApp() {\n  return (\n    \u003cShortcutsProvider\u003e\n      \u003cdiv\u003e\n        \u003ch1\u003eMy App\u003c/h1\u003e\n        {/* Position the shortcuts display wherever you want */}\n        \u003cShortcutsDisplay className=\"absolute bottom-5 right-5\" /\u003e\n      \u003c/div\u003e\n    \u003c/ShortcutsProvider\u003e\n  );\n}\n```\n\n## API Reference\n\n### Registry Functions\n\n#### `registerShortcut(category, name, keyCombo, action, description, enabled?, order?)`\n\nRegister a new keyboard shortcut.\n\n- `category`: Shortcut category (string)\n- `name`: Unique name for the shortcut within its category\n- `keyCombo`: Key combination (e.g., \"Ctrl+F\", \"Shift+M\", \"Delete\")\n- `action`: Function to execute when triggered\n- `description`: Human-readable description\n- `enabled`: Whether the shortcut is enabled (default: true)\n- `order`: Display order (lower numbers appear first)\n\n#### `unregisterShortcut(category, name)`\n\nRemove a registered shortcut.\n\n#### `getAllShortcuts()`\n\nGet all registered shortcuts across all categories.\n\n### Key Combination Format\n\nThe system supports various key combination formats:\n\n- `\"Ctrl+F\"` - Control + F (or Cmd+F on macOS)\n- `\"Shift+Delete\"` - Shift + Delete\n- `\"Alt+Tab\"` - Alt + Tab\n- `\"Ctrl+Shift+Z\"` - Control + Shift + Z\n- `\"F11\"` - Function key F11\n- `\"Esc\"` - Escape key\n\n### Default Categories\n\n```tsx\nDEFAULT_SHORTCUT_CATEGORIES = {\n  NAVIGATION: \"navigation\",\n  VIEW_SETTINGS: \"viewSettings\", \n  TOOLS: \"tools\",\n  EDITING: \"editing\",\n  CUSTOM: \"custom\",\n}\n```\n\n### Hooks\n\n#### `useShortcutsRegistry()`\n\nAccess the shortcuts registry state:\n\n```tsx\nconst { shortcuts, getShortcuts, getAllShortcuts } = useShortcutsRegistry();\n```\n\n#### `useShortcuts()`\n\nAccess shortcuts display state (requires ShortcutsProvider):\n\n```tsx\nconst { showShortcuts, toggleShortcuts } = useShortcuts();\n```\n\n#### `useKeyboardShortcutHandler()`\n\nEnable automatic keyboard event handling (used internally by ShortcutsManager).\n\n## Components\n\n### `ShortcutsProvider`\n\nMain component that provides the complete shortcuts system:\n\n```tsx\n\u003cShortcutsProvider initialShow={false}\u003e\n  \u003cYourApp /\u003e\n\u003c/ShortcutsProvider\u003e\n```\n\n### `ShortcutsDisplay`\n\nComponent that displays registered shortcuts. Position it wherever you want:\n\n```tsx\n\u003cShortcutsDisplay \n  showCategories={true}\n  maxShortcuts={20}\n  className=\"absolute bottom-5 right-5 z-50\"\n/\u003e\n```\n\nProps:\n- `showCategories`: Whether to group shortcuts by category (default: true)\n- `maxShortcuts`: Maximum number of shortcuts to show initially (default: 20)\n- `className`: Additional CSS classes for positioning and styling\n\n## Examples\n\n### Basic Usage\n\n```tsx\nimport React, { useState, useEffect } from 'react';\nimport { \n  ShortcutsProvider, \n  ShortcutsDisplay, \n  registerShortcut, \n  unregisterShortcut \n} from '@jalez/react-shortcuts-provider';\n\nfunction App() {\n  const [showMessage, setShowMessage] = useState(false);\n\n  useEffect(() =\u003e {\n    registerShortcut(\n      'Examples',\n      'show-message',\n      'Ctrl+M',\n      () =\u003e setShowMessage(prev =\u003e !prev),\n      'Toggle a message',\n      true,\n      20\n    );\n\n    return () =\u003e {\n      unregisterShortcut('Examples', 'show-message');\n    };\n  }, []);\n\n  return (\n    \u003cShortcutsProvider\u003e\n      \u003cdiv className=\"min-h-screen p-8\"\u003e\n        \u003ch1\u003eReact Shortcuts Provider Demo\u003c/h1\u003e\n        \n        \u003cShortcutsDisplay className=\"absolute bottom-5 right-5\" /\u003e\n        \n        {showMessage \u0026\u0026 (\n          \u003cdiv className=\"bg-blue-500 text-white p-4 rounded-lg\"\u003e\n            Hello from keyboard shortcut!\n          \u003c/div\u003e\n        )}\n      \u003c/div\u003e\n    \u003c/ShortcutsProvider\u003e\n  );\n}\n```\n\n### Advanced Usage with Multiple Categories\n\n```tsx\nimport { useEffect } from 'react';\nimport { \n  registerShortcut, \n  unregisterShortcut, \n  DEFAULT_SHORTCUT_CATEGORIES \n} from '@jalez/react-shortcuts-provider';\n\nfunction MyComponent() {\n  useEffect(() =\u003e {\n    // Navigation shortcuts\n    registerShortcut(\n      DEFAULT_SHORTCUT_CATEGORIES.NAVIGATION,\n      'next-item',\n      'ArrowDown',\n      () =\u003e navigateNext(),\n      'Navigate to next item'\n    );\n\n    // Editing shortcuts\n    registerShortcut(\n      DEFAULT_SHORTCUT_CATEGORIES.EDITING,\n      'delete-item',\n      'Delete',\n      () =\u003e deleteCurrentItem(),\n      'Delete current item'\n    );\n\n    // Tools shortcuts\n    registerShortcut(\n      DEFAULT_SHORTCUT_CATEGORIES.TOOLS,\n      'toggle-panel',\n      'Ctrl+P',\n      () =\u003e togglePanel(),\n      'Toggle side panel'\n    );\n\n    return () =\u003e {\n      unregisterShortcut(DEFAULT_SHORTCUT_CATEGORIES.NAVIGATION, 'next-item');\n      unregisterShortcut(DEFAULT_SHORTCUT_CATEGORIES.EDITING, 'delete-item');\n      unregisterShortcut(DEFAULT_SHORTCUT_CATEGORIES.TOOLS, 'toggle-panel');\n    };\n  }, []);\n\n  return \u003cdiv\u003eMy Component\u003c/div\u003e;\n}\n```\n\n## Best Practices\n\n1. **Always clean up**: Use the return function in useEffect to unregister shortcuts\n2. **Use meaningful names**: Give shortcuts descriptive names and descriptions\n3. **Organize by category**: Use appropriate categories for different types of actions\n4. **Check for conflicts**: Be aware that multiple shortcuts with the same key combination may conflict\n5. **Consider order**: Use the order parameter to control display order in the shortcuts panel\n6. **Position ShortcutsDisplay**: The ShortcutsDisplay component is not positioned by default - you control where it appears\n7. **Cross-platform compatibility**: Use \"Ctrl\" in key combinations - it automatically works as \"Cmd\" on macOS\n\n## TypeScript Support\n\nThe library is fully typed with TypeScript. All functions and components include proper type definitions:\n\n```tsx\nimport type { \n  ShortcutEntry, \n  ShortcutCategory, \n  KeyCombination \n} from '@jalez/react-shortcuts-provider';\n```\n\n## Development\n\nThis project uses:\n\n- **React** with TypeScript\n- **Vite** for build tooling\n- **Tailwind CSS** for styling\n- **Zustand** for state management\n- **Vitest** for testing\n- **ESLint** for linting\n\n### Available Scripts\n\n```bash\n# Development\nnpm run dev          # Start development server\nnpm run build        # Build the library\nnpm run preview      # Preview the build\n\n# Testing\nnpm run test         # Run tests in watch mode\nnpm run test:run     # Run tests once\nnpm run test:ui      # Run tests with UI\nnpm run test:coverage # Run tests with coverage\n\n# Linting\nnpm run lint         # Run ESLint\n```\n\n### Project Structure\n\n```\nsrc/\n├── ShortCuts/\n│   ├── components/          # React components\n│   │   └── ShortcutsDisplay.tsx\n│   │\n│   ├── context/            # React context and hooks\n│   │   ├── ShortcutsContext.tsx\n│   │   ├── ShortcutsContextDef.ts\n│   │   └── useShortcuts.ts\n│   │\n│   ├── registry/           # Core registry system\n│   │   └── shortcutsRegistry.ts\n│   │\n│   ├── index.tsx           # Component exports\n│   └── shortcuts-exports.ts # Function and type exports\n└── index.ts               # Main library entry point\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## Sponsorship\n\nIf you find this library helpful, please consider sponsoring me on GitHub! Your support helps me maintain and improve this project.\n\n[![Sponsor](https://img.shields.io/badge/Sponsor-%E2%9D%A4-red.svg)](https://github.com/sponsors/jalez)\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjalez%2Freact-shortcuts-provider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjalez%2Freact-shortcuts-provider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjalez%2Freact-shortcuts-provider/lists"}