chore(ui-patterns): reset command menu after selection (#42389)

This commit is contained in:
Francesco Sansalvadore authored and GitHub committed 2026-02-02 21:56:35 +01:00
1 parent efd3f77dd8
commit 6e2842dc86
5 files changed
+48 -18

No files matched your search

@@ -1,27 +1,29 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { Key } from 'lucide-react'
import { useMemo } from 'react'
import { getKeys, useAPIKeysQuery } from 'data/api-keys/api-keys-query'
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { Key } from 'lucide-react'
import { useMemo } from 'react'
import { toast } from 'sonner'
import { Badge, copyToClipboard } from 'ui'
import type { ICommand } from 'ui-patterns/CommandMenu'
import {
PageType,
useRegisterCommands,
useRegisterPage,
useResetCommandMenu,
useSetCommandMenuOpen,
useSetPage,
} from 'ui-patterns/CommandMenu'
import { COMMAND_MENU_SECTIONS } from './CommandMenu.utils'
import { orderCommandSectionsByPriority } from './ordering'
import { toast } from 'sonner'
const API_KEYS_PAGE_NAME = 'API Keys'
export function useApiKeysCommands() {
const setIsOpen = useSetCommandMenuOpen()
const resetCommandMenu = useResetCommandMenu()
const setPage = useSetPage()
const { data: project } = useSelectedProjectQuery()
@@ -51,6 +53,7 @@ export function useApiKeysCommands() {
toast.success('Publishable key copied to clipboard')
})
setIsOpen(false)
resetCommandMenu()
},
badge: () => (
<span className="flex items-center gap-x-1">
@@ -69,6 +72,7 @@ export function useApiKeysCommands() {
toast.success('Secret key copied to clipboard')
})
setIsOpen(false)
resetCommandMenu()
},
badge: () => (
<span className="flex items-center gap-x-1">
@@ -88,6 +92,7 @@ export function useApiKeysCommands() {
toast.success('Anonymous API key copied to clipboard')
})
setIsOpen(false)
resetCommandMenu()
},
badge: () => (
<span className="flex items-center gap-x-1">
@@ -107,6 +112,7 @@ export function useApiKeysCommands() {
toast.success('Service key copied to clipboard')
})
setIsOpen(false)
resetCommandMenu()
},
badge: () => (
<span className="flex items-center gap-x-1">
@@ -124,7 +130,7 @@ export function useApiKeysCommands() {
icon: () => <Key />,
},
].filter(Boolean) as ICommand[]
}, [apiKeys, canReadAPIKeys, project, ref, setIsOpen])
}, [apiKeys, canReadAPIKeys, project, ref, resetCommandMenu, setIsOpen])
useRegisterPage(
API_KEYS_PAGE_NAME,
@@ -1,15 +1,20 @@
import { Link } from 'lucide-react'
import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { Link } from 'lucide-react'
import { toast } from 'sonner'
import { Badge, copyToClipboard } from 'ui'
import { useRegisterCommands, useSetCommandMenuOpen } from 'ui-patterns/CommandMenu'
import {
useRegisterCommands,
useResetCommandMenu,
useSetCommandMenuOpen,
} from 'ui-patterns/CommandMenu'
import { COMMAND_MENU_SECTIONS } from './CommandMenu.utils'
import { orderCommandSectionsByPriority } from './ordering'
import { toast } from 'sonner'
export function useApiUrlCommand() {
const setIsOpen = useSetCommandMenuOpen()
const resetCommandMenu = useResetCommandMenu()
const { data: project } = useSelectedProjectQuery()
const { data: settings } = useProjectSettingsV2Query(
@@ -32,6 +37,7 @@ export function useApiUrlCommand() {
toast.success('API URL copied to clipboard')
})
setIsOpen(false)
resetCommandMenu()
},
icon: () => <Link />,
badge: () => <Badge>Project: {project?.name}</Badge>,
@@ -1,22 +1,26 @@
'use client'
import { useRouter as useLegacyRouter } from 'next/compat/router'
import { type PropsWithChildren, useEffect, useMemo, useCallback } from 'react'
import { useConstant } from 'common'
import { useRouter as useLegacyRouter } from 'next/compat/router'
import { type PropsWithChildren, useCallback, useEffect, useMemo } from 'react'
import { CommandContext } from '../internal/Context'
import { initCommandsState } from '../internal/state/commandsState'
import { initPagesState } from '../internal/state/pagesState'
import { initQueryState } from '../internal/state/queryState'
import { initViewState } from '../internal/state/viewState'
import { CrossCompatRouterContext } from './hooks/useCrossCompatRouter'
import {
useCommandMenuTelemetry,
type CommandMenuTelemetryCallback,
useCommandMenuTelemetry,
} from './hooks/useCommandMenuTelemetry'
import { CommandMenuTelemetryContext } from './hooks/useCommandMenuTelemetryContext'
import { useCommandMenuOpen, useSetCommandMenuOpen, useToggleCommandMenu } from './hooks/viewHooks'
import { CrossCompatRouterContext } from './hooks/useCrossCompatRouter'
import {
useCommandMenuOpen,
useResetCommandMenu,
useSetCommandMenuOpen,
useToggleCommandMenu,
} from './hooks/viewHooks'
const CommandProviderInternal = ({ children }: PropsWithChildren) => {
const combinedState = useConstant(() => ({
@@ -69,13 +73,15 @@ const CommandShortcut = ({
function CloseOnNavigation({ children }: PropsWithChildren) {
const setIsOpen = useSetCommandMenuOpen()
const resetCommandMenu = useResetCommandMenu()
const legacyRouter = useLegacyRouter()
const isUsingLegacyRouting = !!legacyRouter
const completeNavigation = useCallback(() => {
setIsOpen(false)
}, [setIsOpen])
resetCommandMenu()
}, [resetCommandMenu, setIsOpen])
const ctx = useMemo(
() => ({
@@ -1,7 +1,8 @@
'use client'
import { useLayoutEffect, useRef } from 'react'
import { useCallback, useLayoutEffect, useRef } from 'react'
import { useSnapshot } from 'valtio'
import { useCommandContext } from '../../internal/Context'
import { type DialogSize, type ITouchHandlers } from '../../internal/state/viewState.types'
@@ -23,6 +24,14 @@ const useSetCommandMenuOpen = () => {
return setOpen
}
const useResetCommandMenu = () => {
const { queryState, pagesState } = useCommandContext()
return useCallback(() => {
queryState.setQuery('')
pagesState.pageStack.length = 0
}, [queryState, pagesState])
}
const useToggleCommandMenu = () => {
const { viewState } = useCommandContext()
const { toggleOpen } = useSnapshot(viewState)
@@ -64,6 +73,7 @@ const useCommandMenuTouchGestures = () => {
export {
useCommandMenuInitiated,
useCommandMenuOpen,
useResetCommandMenu,
useSetCommandMenuOpen,
useToggleCommandMenu,
useCommandMenuSize,
@@ -4,7 +4,7 @@ import { type PropsWithChildren, forwardRef } from 'react'
import { CommandItem_Shadcn_, cn } from 'ui'
import { useCrossCompatRouter } from '../api/hooks/useCrossCompatRouter'
import { useCommandMenuTelemetryContext } from '../api/hooks/useCommandMenuTelemetryContext'
import { useSetCommandMenuOpen } from '../api/hooks/viewHooks'
import { useResetCommandMenu, useSetCommandMenuOpen } from '../api/hooks/viewHooks'
import type { ICommand, IActionCommand, IRouteCommand } from './types'
const isActionCommand = (command: ICommand): command is IActionCommand => 'action' in command
@@ -53,6 +53,7 @@ const CommandItem = forwardRef<
>(({ children, className, command: _command, ...props }, ref) => {
const router = useCrossCompatRouter()
const setIsOpen = useSetCommandMenuOpen()
const resetCommandMenu = useResetCommandMenu()
const telemetryContext = useCommandMenuTelemetryContext()
const command = _command as ICommand // strip the readonly applied from the proxy
@@ -81,6 +82,7 @@ const CommandItem = forwardRef<
if (command.route.startsWith('http')) {
setIsOpen(false)
window.open(command.route, '_blank', 'noreferrer,noopener')
resetCommandMenu()
} else {
router.push(command.route)
}