Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Expose descriptions for currently-bound hotkeys. #972

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/parseHotkeys.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Hotkey, KeyboardModifiers, Keys } from './types'
import { Hotkey, KeyboardModifiers, Keys, Options } from './types'

const reservedModifierKeywords = ['shift', 'alt', 'meta', 'mod', 'ctrl']

Expand Down Expand Up @@ -39,7 +39,7 @@ export function parseKeysHookInput(keys: string, splitKey: string = ','): string
return keys.split(splitKey)
}

export function parseHotkey(hotkey: string, combinationKey = '+'): Hotkey {
export function parseHotkey(hotkey: string, combinationKey = '+', description?: string): Hotkey {
const keys = hotkey
.toLocaleLowerCase()
.split(combinationKey)
Expand All @@ -58,5 +58,6 @@ export function parseHotkey(hotkey: string, combinationKey = '+'): Hotkey {
return {
...modifiers,
keys: singleCharKeys,
description,
}
}
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type KeyboardModifiers = {
export type Hotkey = KeyboardModifiers & {
keys?: string[]
scopes?: Scopes
description?: string
}

export type HotkeysEvent = Hotkey
Expand Down
4 changes: 2 additions & 2 deletions src/useHotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export default function useHotkeys<T extends HTMLElement>(

if (proxy) {
parseKeysHookInput(_keys, memoisedOptions?.splitKey).forEach((key) =>
proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey))
proxy.addHotkey(parseHotkey(key, memoisedOptions?.combinationKey, memoisedOptions?.description))
)
}

Expand All @@ -155,7 +155,7 @@ export default function useHotkeys<T extends HTMLElement>(

if (proxy) {
parseKeysHookInput(_keys, memoisedOptions?.splitKey).forEach((key) =>
proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey))
proxy.removeHotkey(parseHotkey(key, memoisedOptions?.combinationKey, memoisedOptions?.description))
)
}
}
Expand Down
59 changes: 39 additions & 20 deletions tests/HotkeysProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ test('should render children', () => {
const { getByText } = render(
<HotkeysProvider>
<div>Hello</div>
</HotkeysProvider>,
</HotkeysProvider>
)

expect(getByText('Hello')).toBeInTheDocument()
Expand All @@ -23,8 +23,9 @@ test('should default to wildcard scope', () => {
})

test('should default to wildcard scope if empty array is provided as initialActiveScopes', () => {
const wrapper = ({ children }: { children: ReactNode }) => <HotkeysProvider
initiallyActiveScopes={[]}>{children}</HotkeysProvider>
const wrapper = ({ children }: { children: ReactNode }) => (
<HotkeysProvider initiallyActiveScopes={[]}>{children}</HotkeysProvider>
)
const { result } = renderHook(() => useHotkeysContext(), {
wrapper,
})
Expand Down Expand Up @@ -150,8 +151,9 @@ test('should keep wildcard scope active when all is the only active scope and ge
})

test('should return initially set scopes', () => {
const wrapper = ({ children }: { children: ReactNode }) => <HotkeysProvider
initiallyActiveScopes={['foo', 'bar']}>{children}</HotkeysProvider>
const wrapper = ({ children }: { children: ReactNode }) => (
<HotkeysProvider initiallyActiveScopes={['foo', 'bar']}>{children}</HotkeysProvider>
)
const { result } = renderHook(() => useHotkeysContext(), {
wrapper,
})
Expand All @@ -166,8 +168,9 @@ test('should return all bound hotkeys', () => {
return useHotkeysContext()
}

const wrapper = ({ children }: { children: ReactNode }) => <HotkeysProvider
initiallyActiveScopes={['foo']}>{children}</HotkeysProvider>
const wrapper = ({ children }: { children: ReactNode }) => (
<HotkeysProvider initiallyActiveScopes={['foo']}>{children}</HotkeysProvider>
)
const { result } = renderHook(useIntegratedHotkeys, {
wrapper,
})
Expand All @@ -183,20 +186,19 @@ test('should update bound hotkeys when useHotkeys changes its scopes', () => {
}

const wrapper = ({ children }: { children: ReactNode }) => {
return (
<HotkeysProvider initiallyActiveScopes={['foo']}>
{children}
</HotkeysProvider>
)
return <HotkeysProvider initiallyActiveScopes={['foo']}>{children}</HotkeysProvider>
}

const { result, rerender } = renderHook<{ scopes: string[] }, HotkeysContextType>(({ scopes }) => useIntegratedHotkeys(scopes), {
// @ts-ignore
wrapper,
initialProps: {
scopes: ['foo'],
},
})
const { result, rerender } = renderHook<{ scopes: string[] }, HotkeysContextType>(
({ scopes }) => useIntegratedHotkeys(scopes),
{
// @ts-ignore
wrapper,
initialProps: {
scopes: ['foo'],
},
}
)

expect(result.current.hotkeys).toHaveLength(1)

Expand All @@ -220,4 +222,21 @@ test('should return bound hotkeys when defined as a string array', () => {
})
expect(result.current.hotkeys[0].keys).toEqual(['a', 'c'])
expect(result.current.hotkeys[1].keys).toEqual(['b'])
})
})

test('should return descriptions for bound hotkeys', () => {
zenzen-sol marked this conversation as resolved.
Show resolved Hide resolved
const useIntegratedHotkeys = () => {
useHotkeys('a', () => null, { scopes: ['foo'], description: 'bar' })

return useHotkeysContext()
}

const wrapper = ({ children }: { children: ReactNode }) => (
<HotkeysProvider initiallyActiveScopes={['foo']}>{children}</HotkeysProvider>
)
const { result } = renderHook(useIntegratedHotkeys, {
wrapper,
})

expect(result.current.hotkeys[0].description).toEqual('bar')
})