Tom Butcher 42d6ac6422 Add Dashboard Object Tools Context and Chevron Icons
- Introduced DashboardObjectToolsContext and DashboardObjectToolsProvider for managing object tools state within the dashboard.
- Added ChevronLeftIcon and ChevronRightIcon components for navigation buttons, enhancing user interface consistency.
- Updated ObjectTableNavigationButtons to utilize new chevron icons and improved layout for better user experience.
- Refactored KeyboardShortcut and Tooltip components for cleaner code and improved functionality.
2026-08-21 21:11:15 +01:00

120 lines
2.7 KiB
JavaScript

import { useEffect, useRef, useMemo } from 'react'
import PropTypes from 'prop-types'
import loglevel from 'loglevel'
import config from '../../../config'
import Tooltip from './Tooltip'
import KeyboardKey from './KeyboardKey'
const logger = loglevel.getLogger('ApiServerContext')
logger.setLevel(config.logLevel)
const MODIFIER_ALIASES = {
cmd: 'meta',
meta: 'meta',
ctrl: 'control',
control: 'control',
alt: 'alt',
option: 'alt',
shift: 'shift'
}
function parseShortcut(shortcut) {
return shortcut
.toLowerCase()
.split('+')
.map((part) => MODIFIER_ALIASES[part] ?? part)
}
function getPressedKey(event) {
if (
event.key === 'Meta' ||
event.key === 'Control' ||
event.key === 'Alt' ||
event.key === 'Shift'
) {
return event.key.toLowerCase()
}
if (event.code) {
const code = event.code.toLowerCase()
if (code.startsWith('key')) {
return code.slice(3)
}
return code
}
return null
}
const KeyboardShortcut = ({
shortcut,
children,
hint,
onTrigger,
log = false
}) => {
const pressedKeysRef = useRef(new Set())
const shortcutKeys = useMemo(() => parseShortcut(shortcut), [shortcut])
useEffect(() => {
const handleKeyDown = (event) => {
const key = getPressedKey(event)
if (key) {
pressedKeysRef.current.add(key)
}
if (log) {
logger.info('Key Down:', key, 'Pressed Keys:', [
...pressedKeysRef.current
])
}
if (
shortcutKeys.length &&
shortcutKeys.every((k) => pressedKeysRef.current.has(k))
) {
if (typeof onTrigger === 'function') {
onTrigger(event)
}
event.preventDefault()
}
}
const handleKeyUp = (event) => {
const key = getPressedKey(event)
if (key) {
pressedKeysRef.current.delete(key)
}
}
window.addEventListener('keydown', handleKeyDown)
window.addEventListener('keyup', handleKeyUp)
return () => {
window.removeEventListener('keydown', handleKeyDown)
window.removeEventListener('keyup', handleKeyUp)
}
}, [shortcutKeys, onTrigger, log])
if (hint) {
var osSpecificHint = hint.replaceAll('ALT', '⌥')
return (
<Tooltip
hideBorder
title={<KeyboardKey size='md'>{osSpecificHint}</KeyboardKey>}
>
{children}
</Tooltip>
)
}
return children
}
KeyboardShortcut.propTypes = {
shortcut: PropTypes.string.isRequired, // e.g. 'cmd+shift+p'
onTrigger: PropTypes.func.isRequired,
children: PropTypes.element.isRequired,
hint: PropTypes.string, // Optional, e.g. '⌘ ⇧ P'
log: PropTypes.bool // Optional, e.g. true
}
export default KeyboardShortcut