implement edit dialog mnemonics
This commit is contained in:
@@ -33,6 +33,9 @@ function AddBookmarkDialog() {
|
|||||||
{ ignore: () => false },
|
{ ignore: () => false },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// when using autoFocus, it also captures the "a" mnemonic
|
||||||
|
// which appends the "a" to the input
|
||||||
|
// this is to prevent the "a" mnemonic to be captured as input to the text box
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (linkInputRef.current) {
|
if (linkInputRef.current) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import type { Bookmark, Tag } from "@markone/core"
|
import type { Bookmark, Tag } from "@markone/core"
|
||||||
import { useId, useRef } from "react"
|
import { useEffect, useId, useImperativeHandle, useRef } from "react"
|
||||||
import { useBookmarkTags, useUpdateBookmark } from "~/bookmark/api"
|
import { useBookmarkTags, useUpdateBookmark } from "~/bookmark/api"
|
||||||
import { Button } from "~/components/button"
|
import { Button } from "~/components/button"
|
||||||
import { Dialog, DialogActionRow, DialogBody, DialogTitle } from "~/components/dialog"
|
import { Dialog, DialogActionRow, DialogBody, DialogTitle } from "~/components/dialog"
|
||||||
@@ -7,12 +7,47 @@ import { FormField } from "~/components/form-field"
|
|||||||
import { LoadingSpinner } from "~/components/loading-spinner"
|
import { LoadingSpinner } from "~/components/loading-spinner"
|
||||||
import { Message, MessageVariant } from "~/components/message.tsx"
|
import { Message, MessageVariant } from "~/components/message.tsx"
|
||||||
import { TagsInput, type TagsInputRef } from "~/components/tags-input"
|
import { TagsInput, type TagsInputRef } from "~/components/tags-input"
|
||||||
|
import { useMnemonics } from "~/hooks/use-mnemonics.ts"
|
||||||
import { useBookmarkPageStore } from "../-store"
|
import { useBookmarkPageStore } from "../-store"
|
||||||
|
|
||||||
|
interface EditFormRef {
|
||||||
|
form: HTMLFormElement | null
|
||||||
|
titleInput: HTMLInputElement | null
|
||||||
|
tagsInput: TagsInputRef | null
|
||||||
|
}
|
||||||
|
|
||||||
function EditBookmarkDialog({ bookmark }: { bookmark: Bookmark }) {
|
function EditBookmarkDialog({ bookmark }: { bookmark: Bookmark }) {
|
||||||
const closeDialog = useBookmarkPageStore((state) => state.closeDialog)
|
const closeDialog = useBookmarkPageStore((state) => state.closeDialog)
|
||||||
const { data: tags, status } = useBookmarkTags(bookmark)
|
const { data: tags, status } = useBookmarkTags(bookmark)
|
||||||
const editFormId = useId()
|
const editFormId = useId()
|
||||||
|
const editFormRef = useRef<EditFormRef | null>(null)
|
||||||
|
|
||||||
|
useMnemonics(
|
||||||
|
{
|
||||||
|
s: () => {
|
||||||
|
if (
|
||||||
|
editFormRef.current &&
|
||||||
|
editFormRef.current.titleInput !== document.activeElement &&
|
||||||
|
editFormRef.current.tagsInput?.input !== document.activeElement
|
||||||
|
) {
|
||||||
|
editFormRef.current.form?.requestSubmit()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
c: () => {
|
||||||
|
if (
|
||||||
|
editFormRef.current?.titleInput !== document.activeElement &&
|
||||||
|
editFormRef.current?.tagsInput?.input !== document.activeElement
|
||||||
|
) {
|
||||||
|
closeDialog()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Escape: () => {
|
||||||
|
editFormRef.current?.titleInput?.blur()
|
||||||
|
editFormRef.current?.tagsInput?.input?.blur()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ ignore: () => false },
|
||||||
|
)
|
||||||
|
|
||||||
function content() {
|
function content() {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@@ -23,7 +58,7 @@ function EditBookmarkDialog({ bookmark }: { bookmark: Bookmark }) {
|
|||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
case "success":
|
case "success":
|
||||||
return <EditForm formId={editFormId} bookmark={bookmark} tags={tags} />
|
return <EditForm ref={editFormRef} formId={editFormId} bookmark={bookmark} tags={tags} />
|
||||||
case "error":
|
case "error":
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -45,11 +80,33 @@ function EditBookmarkDialog({ bookmark }: { bookmark: Bookmark }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditForm({ formId, bookmark, tags }: { formId: string; bookmark: Bookmark; tags: Tag[] }) {
|
function EditForm({
|
||||||
|
ref,
|
||||||
|
formId,
|
||||||
|
bookmark,
|
||||||
|
tags,
|
||||||
|
}: { ref: React.Ref<EditFormRef>; formId: string; bookmark: Bookmark; tags: Tag[] }) {
|
||||||
|
const formRef = useRef<HTMLFormElement | null>(null)
|
||||||
|
const titleInputRef = useRef<HTMLInputElement | null>(null)
|
||||||
const tagsInputRef = useRef<TagsInputRef>(null)
|
const tagsInputRef = useRef<TagsInputRef>(null)
|
||||||
const updateBookmarkMutation = useUpdateBookmark(bookmark)
|
const updateBookmarkMutation = useUpdateBookmark(bookmark)
|
||||||
const closeDialog = useBookmarkPageStore((state) => state.closeDialog)
|
const closeDialog = useBookmarkPageStore((state) => state.closeDialog)
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
form: formRef.current,
|
||||||
|
titleInput: titleInputRef.current,
|
||||||
|
tagsInput: tagsInputRef.current,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// when using autoFocus, it also captures the "e" mnemonic
|
||||||
|
// which appends the "e" to the input
|
||||||
|
// this is to prevent the "e" mnemonic to be captured as input to the text box
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
titleInputRef.current?.focus()
|
||||||
|
}, 0)
|
||||||
|
}, [])
|
||||||
|
|
||||||
async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
|
async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
|
||||||
if (tagsInputRef.current) {
|
if (tagsInputRef.current) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
@@ -86,8 +143,9 @@ function EditForm({ formId, bookmark, tags }: { formId: string; bookmark: Bookma
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{message()}
|
{message()}
|
||||||
<form id={formId} onSubmit={onSubmit}>
|
<form ref={formRef} id={formId} onSubmit={onSubmit}>
|
||||||
<FormField
|
<FormField
|
||||||
|
ref={titleInputRef}
|
||||||
type="text"
|
type="text"
|
||||||
name="title"
|
name="title"
|
||||||
label="TITLE"
|
label="TITLE"
|
||||||
|
Reference in New Issue
Block a user