ultisuite-client/lib/drive/docs-keyboard-shortcuts-runtime.ts
R3D347HR4Y 79bb6193fc
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
menus1
2026-06-09 18:27:10 +02:00

96 lines
3.2 KiB
TypeScript

import {
formatDocsShortcutBinding,
matchesDocsShortcutBinding,
normalizeDocsShortcutBinding,
} from "@/lib/drive/docs-keyboard-shortcut"
import {
DOCS_KEYBOARD_SHORTCUT_DEFINITIONS,
DOCS_KEYBOARD_SHORTCUTS_BY_ID,
type DocsKeyboardShortcutsUserConfig,
type DocsShortcutBinding,
type DocsShortcutDefinition,
type DocsShortcutId,
} from "@/lib/drive/docs-keyboard-shortcuts-config"
export function getDocsShortcutDefinition(id: DocsShortcutId): DocsShortcutDefinition {
return DOCS_KEYBOARD_SHORTCUTS_BY_ID[id]
}
export function resolveDocsShortcutBinding(
id: DocsShortcutId,
overrides: DocsKeyboardShortcutsUserConfig = {}
): DocsShortcutBinding {
return overrides[id] ?? DOCS_KEYBOARD_SHORTCUTS_BY_ID[id].defaultBinding
}
export function resolveDocsShortcutBindings(
id: DocsShortcutId,
overrides: DocsKeyboardShortcutsUserConfig = {}
): DocsShortcutBinding[] {
const definition = DOCS_KEYBOARD_SHORTCUTS_BY_ID[id]
const primary = resolveDocsShortcutBinding(id, overrides)
const alt = overrides[id] ? [] : (definition.altBindings ?? [])
return [primary, ...alt]
}
export function formatDocsShortcutId(
id: DocsShortcutId,
overrides: DocsKeyboardShortcutsUserConfig = {}
): string {
return formatDocsShortcutBinding(resolveDocsShortcutBinding(id, overrides))
}
export function matchDocsShortcutEvent(
event: KeyboardEvent,
overrides: DocsKeyboardShortcutsUserConfig = {},
filter?: (definition: DocsShortcutDefinition) => boolean
): DocsShortcutId | null {
for (const definition of DOCS_KEYBOARD_SHORTCUT_DEFINITIONS) {
if (filter && !filter(definition)) continue
const bindings = resolveDocsShortcutBindings(definition.id, overrides)
if (bindings.some((binding) => matchesDocsShortcutBinding(event, binding))) {
return definition.id
}
}
return null
}
export function isValidDocsShortcutBinding(value: unknown): value is DocsShortcutBinding {
if (!value || typeof value !== "object") return false
const binding = value as DocsShortcutBinding
if (typeof binding.key !== "string" || binding.key.length === 0) return false
if (binding.mod != null && typeof binding.mod !== "boolean") return false
if (binding.shift != null && typeof binding.shift !== "boolean") return false
if (binding.alt != null && typeof binding.alt !== "boolean") return false
return true
}
export function sanitizeDocsKeyboardShortcutsUserConfig(
raw: unknown
): DocsKeyboardShortcutsUserConfig {
if (!raw || typeof raw !== "object") return {}
const input = raw as Record<string, unknown>
const output: DocsKeyboardShortcutsUserConfig = {}
for (const definition of DOCS_KEYBOARD_SHORTCUT_DEFINITIONS) {
const candidate = input[definition.id]
if (isValidDocsShortcutBinding(candidate)) {
output[definition.id] = normalizeDocsShortcutBinding(candidate)
}
}
return output
}
/** Catalog for a future keyboard-shortcuts settings screen. */
export function listDocsKeyboardShortcutCatalog(
overrides: DocsKeyboardShortcutsUserConfig = {}
) {
return DOCS_KEYBOARD_SHORTCUT_DEFINITIONS.map((definition) => ({
...definition,
binding: resolveDocsShortcutBinding(definition.id, overrides),
display: formatDocsShortcutId(definition.id, overrides),
isCustomized: Boolean(overrides[definition.id]),
}))
}