diff options
| author | MohamedBassem <me@mbassem.com> | 2024-03-31 19:04:44 +0100 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-03-31 19:27:25 +0100 |
| commit | 23bc97528882e293883fff896b4ac1c5d8030371 (patch) | |
| tree | 59dc32710df163dd52e90d3c2dce9b6a35eed983 | |
| parent | cb8754bc09bf8495fb7f5ee744f61e06ac6af5d4 (diff) | |
| download | karakeep-23bc97528882e293883fff896b4ac1c5d8030371.tar.zst | |
feature(web): Add ⌘ + E shortcut for quickly focusing on the editor
card. Fixes #58
| -rw-r--r-- | apps/web/components/dashboard/bookmarks/EditorCard.tsx | 97 |
1 files changed, 67 insertions, 30 deletions
diff --git a/apps/web/components/dashboard/bookmarks/EditorCard.tsx b/apps/web/components/dashboard/bookmarks/EditorCard.tsx index adada927..28686e6c 100644 --- a/apps/web/components/dashboard/bookmarks/EditorCard.tsx +++ b/apps/web/components/dashboard/bookmarks/EditorCard.tsx @@ -1,17 +1,44 @@ import type { SubmitErrorHandler, SubmitHandler } from "react-hook-form"; +import { useEffect, useImperativeHandle, useRef } from "react"; import { ActionButton } from "@/components/ui/action-button"; -import { Form, FormControl, FormField, FormItem } from "@/components/ui/form"; +import { Form, FormControl, FormItem } from "@/components/ui/form"; import { Separator } from "@/components/ui/separator"; import { Textarea } from "@/components/ui/textarea"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { toast } from "@/components/ui/use-toast"; import { useClientConfig } from "@/lib/clientConfig"; import { api } from "@/lib/trpc"; import { cn } from "@/lib/utils"; import { zodResolver } from "@hookform/resolvers/zod"; +import { Info } from "lucide-react"; import { useForm } from "react-hook-form"; import { z } from "zod"; +function useFocusOnKeyPress(inputRef: React.RefObject<HTMLTextAreaElement>) { + useEffect(() => { + function handleKeyPress(e: KeyboardEvent) { + if (!inputRef.current) { + return; + } + if ((e.metaKey || e.ctrlKey) && e.code === "KeyE") { + inputRef.current.focus(); + } + } + document.addEventListener("keydown", handleKeyPress); + return () => { + document.removeEventListener("keydown", handleKeyPress); + }; + }, [inputRef]); +} + export default function EditorCard({ className }: { className?: string }) { + const inputRef = useRef<HTMLTextAreaElement>(null); + const demoMode = !!useClientConfig().demoMode; const formSchema = z.object({ text: z.string(), @@ -22,6 +49,9 @@ export default function EditorCard({ className }: { className?: string }) { text: "", }, }); + const { ref, ...textFieldProps } = form.register("text"); + useImperativeHandle(ref, () => inputRef.current); + useFocusOnKeyPress(inputRef); const invalidateBookmarksCache = api.useUtils().bookmarks.invalidate; const { mutate, isPending } = api.bookmarks.createBookmark.useMutation({ @@ -62,36 +92,43 @@ export default function EditorCard({ className }: { className?: string }) { )} onSubmit={form.handleSubmit(onSubmit, onError)} > - <p className="text-sm">NEW ITEM</p> + <div className="flex justify-between"> + <p className="text-sm">NEW ITEM</p> + <TooltipProvider delayDuration={0}> + <Tooltip> + <TooltipTrigger asChild> + <Info size={15} /> + </TooltipTrigger> + <TooltipContent className="w-52"> + <p className="text-center"> + You can quickly focus on this field by pressing ⌘ + E + </p> + </TooltipContent> + </Tooltip> + </TooltipProvider> + </div> <Separator /> - <FormField - control={form.control} - name="text" - render={({ field }) => { - return ( - <FormItem className="flex-1"> - <FormControl> - <Textarea - disabled={isPending} - className="h-full w-full resize-none border-none text-lg focus-visible:ring-0" - placeholder={ - "Paste a link, write a note or drag and drop an image in here ..." - } - onKeyDown={(e) => { - if (demoMode) { - return; - } - if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { - form.handleSubmit(onSubmit, onError)(); - } - }} - {...field} - /> - </FormControl> - </FormItem> - ); - }} - /> + <FormItem className="flex-1"> + <FormControl> + <Textarea + ref={inputRef} + disabled={isPending} + className="h-full w-full resize-none border-none text-lg focus-visible:ring-0" + placeholder={ + "Paste a link, write a note or drag and drop an image in here ..." + } + onKeyDown={(e) => { + if (demoMode) { + return; + } + if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { + form.handleSubmit(onSubmit, onError)(); + } + }} + {...textFieldProps} + /> + </FormControl> + </FormItem> <ActionButton loading={isPending} type="submit" variant="default"> {form.formState.dirtyFields.text ? demoMode |
