mirror of
https://github.com/supabase/supabase.git
synced 2026-07-06 09:44:25 +08:00
Replace docs command menu with Command Menu V2 from ui-patterns/CommandMenu. This introduces the prepackaged folder for the shared Command Menu, which contains commands that are shared across the sites (for example, docs search, theme switcher). Commands that are only applicable to a single site are now defined within that site's own app folder (put them wherever makes sense for your app folder organization, as long as you use the hooks within a global CommandProvider it will work...) Tested navigating around, using search and AI on laptop and mobile.
73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
'use client'
|
|
|
|
import React, { forwardRef, useEffect, useRef } from 'react'
|
|
|
|
import { useBreakpoint } from 'common'
|
|
import { CommandInput_Shadcn_, cn } from 'ui'
|
|
|
|
import { useQuery, useSetQuery } from './hooks/queryHooks'
|
|
|
|
function useFocusInputOnWiderScreens(ref: React.ForwardedRef<HTMLInputElement>) {
|
|
const isBelowSm = useBreakpoint('sm')
|
|
const isBelowSmSynchronous = useRef(isBelowSm)
|
|
isBelowSmSynchronous.current = isBelowSm
|
|
|
|
const internalRef = useRef<HTMLInputElement>()
|
|
const combinedRef = (element: HTMLInputElement) => {
|
|
if (ref instanceof Function) {
|
|
ref(element)
|
|
} else if (!!ref) {
|
|
ref.current = element
|
|
}
|
|
internalRef.current = element
|
|
}
|
|
|
|
useEffect(() => {
|
|
// This will always be false in the first iteration (since isBelowSm
|
|
// switches from false -> true on narrow screens). To avoid a preemptive
|
|
// focus, we need to delay this. But then we need to access the current
|
|
// value of isBelowSm, not the stale value, which explains the business
|
|
// with syncing state into a ref above.
|
|
setTimeout(() => {
|
|
if (!isBelowSmSynchronous.current) {
|
|
internalRef.current?.focus()
|
|
}
|
|
})
|
|
}, [])
|
|
|
|
return combinedRef
|
|
}
|
|
|
|
const CommandInput = forwardRef<
|
|
React.ElementRef<typeof CommandInput_Shadcn_>,
|
|
React.ComponentPropsWithoutRef<typeof CommandInput_Shadcn_>
|
|
>(({ className, ...props }, ref) => {
|
|
const inputRef = useFocusInputOnWiderScreens(ref)
|
|
|
|
const query = useQuery()
|
|
const setQuery = useSetQuery()
|
|
|
|
return (
|
|
<CommandInput_Shadcn_
|
|
// Focus needs to be manually handled to check breakpoint first, due to
|
|
// delays from useEffect
|
|
autoFocus={false}
|
|
ref={inputRef}
|
|
value={query}
|
|
onValueChange={setQuery}
|
|
placeholder="Type a command or search..."
|
|
className={cn(
|
|
'flex h-11 w-full rounded-md bg-transparent px-4 py-7 outline-none',
|
|
'focus:shadow-none focus:ring-transparent',
|
|
'text-base text-foreground-light placeholder:text-foreground-muted disabled:cursor-not-allowed disabled:opacity-50 border-0',
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
})
|
|
|
|
CommandInput.displayName = CommandInput_Shadcn_.displayName
|
|
|
|
export { CommandInput }
|