added option to disable globally

This commit is contained in:
Ali Waseem committed 2026-05-01 08:43:53 -06:00
1 parent ab611008c6
commit eddfb062f1
7 files changed
+101 -3

No files matched your search

@@ -5,18 +5,24 @@ import { Card, Form } from 'ui'
import * as z from 'zod'
import { DashboardToggle } from './DashboardToggle'
import { useIsInlineEditorSetting, useIsQueueOperationsSetting } from './useDashboardSettings'
import {
useIsInlineEditorSetting,
useIsQueueOperationsSetting,
useIsShortcutChordHudSetting,
} from './useDashboardSettings'
import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
const DashboardSettingsSchema = z.object({
inlineEditorEnabled: z.boolean(),
queueOperationsEnabled: z.boolean(),
shortcutChordHudEnabled: z.boolean(),
})
export const DashboardSettingsToggles = () => {
const { inlineEditorEnabled, setInlineEditorEnabled } = useIsInlineEditorSetting()
const { isQueueOperationsEnabled, setIsQueueOperationsEnabled } = useIsQueueOperationsSetting()
const { isShortcutChordHudEnabled, setIsShortcutChordHudEnabled } = useIsShortcutChordHudSetting()
const { data: org } = useSelectedOrganizationQuery()
@@ -27,6 +33,7 @@ export const DashboardSettingsToggles = () => {
values: {
inlineEditorEnabled: inlineEditorEnabled ?? false,
queueOperationsEnabled: isQueueOperationsEnabled ?? false,
shortcutChordHudEnabled: isShortcutChordHudEnabled ?? true,
},
})
@@ -60,6 +67,21 @@ export const DashboardSettingsToggles = () => {
)
}
const handleShortcutChordHudToggle = (value: boolean) => {
setIsShortcutChordHudEnabled(value)
form.setValue('shortcutChordHudEnabled', value)
sendEvent({
action: 'shortcut_chord_hud_setting_clicked',
properties: { enabled: value },
groups: { organization: org?.slug },
})
toast(
`${value ? 'Keyboard shortcut hints will now appear while typing chords' : 'Keyboard shortcut hints are now hidden'}`
)
}
return (
<Form {...form}>
<Card>
@@ -76,6 +98,13 @@ export const DashboardSettingsToggles = () => {
label="Queue table operations"
description="Review and batch table edits in Table Editor before saving them to your database."
onToggle={handleQueueOperationsToggle}
/>
<DashboardToggle
form={form}
name="shortcutChordHudEnabled"
label="Show keyboard shortcut hints"
description="Show an on-screen hint while typing multi-key keyboard shortcuts."
onToggle={handleShortcutChordHudToggle}
isLast
/>
</Card>
@@ -25,6 +25,17 @@ export const useIsQueueOperationsSetting = () => {
}
}
export const useIsShortcutChordHudSetting = () => {
const [isShortcutChordHudEnabled, setIsShortcutChordHudEnabled] = useLocalStorageQuery(
LOCAL_STORAGE_KEYS.UI_SHORTCUT_CHORD_HUD,
true
)
return {
isShortcutChordHudEnabled: isShortcutChordHudEnabled ?? true,
setIsShortcutChordHudEnabled,
}
}
export const useIsInlineEditorEnabled = () => {
const { inlineEditorEnabled } = useIsInlineEditorSetting()
return inlineEditorEnabled ?? false
@@ -34,3 +45,8 @@ export const useIsQueueOperationsEnabled = () => {
const { isQueueOperationsEnabled } = useIsQueueOperationsSetting()
return isQueueOperationsEnabled ?? false
}
export const useIsShortcutChordHudEnabled = () => {
const { isShortcutChordHudEnabled } = useIsShortcutChordHudSetting()
return isShortcutChordHudEnabled ?? true
}
@@ -4,14 +4,19 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ShortcutChordHud } from './ShortcutChordHud'
import type { ShortcutSequenceRegistration } from './ShortcutChordHud.utils'
const { mockUseHotkeyRegistrations } = vi.hoisted(() => ({
const { mockUseHotkeyRegistrations, mockUseIsShortcutChordHudEnabled } = vi.hoisted(() => ({
mockUseHotkeyRegistrations: vi.fn(),
mockUseIsShortcutChordHudEnabled: vi.fn(() => true),
}))
vi.mock('@tanstack/react-hotkeys', () => ({
useHotkeyRegistrations: mockUseHotkeyRegistrations,
}))
vi.mock('@/components/interfaces/Account/Preferences/useDashboardSettings', () => ({
useIsShortcutChordHudEnabled: mockUseIsShortcutChordHudEnabled,
}))
const makeSequence = (
overrides: Partial<ShortcutSequenceRegistration> &
Pick<ShortcutSequenceRegistration, 'id' | 'sequence'>
@@ -30,6 +35,7 @@ describe('ShortcutChordHud', () => {
vi.useFakeTimers()
vi.setSystemTime(new Date('2026-05-01T10:00:00.000Z'))
mockUseHotkeyRegistrations.mockReturnValue({ hotkeys: [], sequences: [] })
mockUseIsShortcutChordHudEnabled.mockReturnValue(true)
})
it('stays hidden when no chord is in progress', () => {
@@ -38,6 +44,29 @@ describe('ShortcutChordHud', () => {
expect(screen.queryByTestId('shortcut-chord-hud')).not.toBeInTheDocument()
})
it('stays hidden when the user has disabled the chord HUD preference', () => {
mockUseIsShortcutChordHudEnabled.mockReturnValue(false)
const now = Date.now()
mockUseHotkeyRegistrations.mockReturnValue({
hotkeys: [],
sequences: [
makeSequence({
id: 'nav.table',
sequence: ['G', 'T'],
matchedStepCount: 1,
partialMatchLastKeyTime: now - 200,
}),
],
})
render(<ShortcutChordHud />)
act(() => {
vi.advanceTimersByTime(20)
})
expect(screen.queryByTestId('shortcut-chord-hud')).not.toBeInTheDocument()
})
it('renders the active chord at the bottom centre while a sequence is in progress', () => {
const now = Date.now()
mockUseHotkeyRegistrations.mockReturnValue({
@@ -3,6 +3,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'
import { cn, KeyboardShortcut } from 'ui'
import { getVisibleShortcutChord, isInputLikeElement } from './ShortcutChordHud.utils'
import { useIsShortcutChordHudEnabled } from '@/components/interfaces/Account/Preferences/useDashboardSettings'
import { useInterval } from '@/hooks/misc/useInterval'
import { hotkeyToKeys } from '@/state/shortcuts/formatShortcut'
@@ -23,6 +24,7 @@ interface RenderedShortcutChord {
}
export function ShortcutChordHud() {
const isEnabled = useIsShortcutChordHudEnabled()
const { sequences } = useHotkeyRegistrations()
const [, setTick] = useState(0)
const [focusVersion, setFocusVersion] = useState(0)
@@ -167,7 +169,7 @@ export function ShortcutChordHud() {
const displayedHud = targetHud ?? exitingHud
if (!displayedHud) {
if (!displayedHud || !isEnabled) {
return null
}
+1
View File
@@ -26,6 +26,7 @@ export const test = base.extend<TestOptions>({
`table-editor-queue-operations-banner-dismissed-${ref}`,
JSON.stringify(true)
)
localStorage.setItem('supabase-ui-shortcut-chord-hud', JSON.stringify(false))
}, ref)
await use(page)
},
@@ -25,6 +25,7 @@ export const LOCAL_STORAGE_KEYS = {
UI_PREVIEW_PLATFORM_WEBHOOKS: 'supabase-ui-platform-webhooks',
UI_PREVIEW_JIT_DB_ACCESS: 'supabase-ui-jit-db-access',
UI_PREVIEW_RLS_TESTER: 'supabase-ui-rls-tester',
UI_SHORTCUT_CHORD_HUD: 'supabase-ui-shortcut-chord-hud',
NEW_LAYOUT_NOTICE_ACKNOWLEDGED: 'new-layout-notice-acknowledge',
TABS_INTERFACE_ACKNOWLEDGED: 'tabs-interface-acknowledge',
@@ -155,6 +156,7 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [
LOCAL_STORAGE_KEYS.UI_PREVIEW_UNIFIED_LOGS,
LOCAL_STORAGE_KEYS.UI_PREVIEW_PLATFORM_WEBHOOKS,
LOCAL_STORAGE_KEYS.UI_PREVIEW_JIT_DB_ACCESS,
LOCAL_STORAGE_KEYS.UI_SHORTCUT_CHORD_HUD,
LOCAL_STORAGE_KEYS.LAST_SIGN_IN_METHOD,
LOCAL_STORAGE_KEYS.HIDE_PROMO_TOAST,
LOCAL_STORAGE_KEYS.BLOG_VIEW,
+19
View File
@@ -2545,6 +2545,24 @@ export interface QueueOperationsSettingClickedEvent {
groups: Partial<TelemetryGroups>
}
/**
* User toggled the keyboard shortcut hint HUD setting in account preferences.
*
* @group Events
* @source studio
* @page /dashboard/account/preferences
*/
export interface ShortcutChordHudSettingClickedEvent {
action: 'shortcut_chord_hud_setting_clicked'
properties: {
/**
* Whether the keyboard shortcut hint HUD was enabled or disabled
*/
enabled: boolean
}
groups: Partial<TelemetryGroups>
}
/**
* User clicked the save destination button in add log drains sheet.
*
@@ -3349,6 +3367,7 @@ export type TelemetryEvent =
| CommandMenuCommandClickedEvent
| InlineEditorSettingClickedEvent
| QueueOperationsSettingClickedEvent
| ShortcutChordHudSettingClickedEvent
| SidebarOpenedEvent
| LogDrainSaveButtonClickedEvent
| LogDrainConfirmButtonSubmittedEvent