fix(ui): сохранить контекст и фокус контейнеров
This commit is contained in:
1 parent
3ceb8c038c
commit
71cc6fa3a7
12 files changed
+128
-27
No files matched your search
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect, useMemo, useState, type ReactNode } from "react"
|
||||
import { useMemo, useState, type ReactNode } from "react"
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription,
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
TriangleAlertIcon,
|
||||
} from "lucide-react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { toast } from "sonner"
|
||||
|
||||
export type CodeExportFormat = {
|
||||
id: string
|
||||
@@ -88,6 +89,7 @@ export interface CodeExportSheetProps {
|
||||
liveLabel?: string
|
||||
className?: string
|
||||
/** Extra content under format tabs (e.g. meta strip) */
|
||||
returnFocus?: () => HTMLElement | null
|
||||
beforeCode?: ReactNode
|
||||
}
|
||||
|
||||
@@ -108,20 +110,18 @@ function CodeExportSheet({
|
||||
liveLabel = "С роутера",
|
||||
className,
|
||||
beforeCode,
|
||||
returnFocus,
|
||||
}: CodeExportSheetProps) {
|
||||
const firstId = formats[0]?.id ?? "default"
|
||||
const [tab, setTab] = useState(initialFormatId ?? firstId)
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return
|
||||
setTab(
|
||||
initialFormatId && formats.some((f) => f.id === initialFormatId)
|
||||
? initialFormatId
|
||||
: firstId,
|
||||
)
|
||||
setCopied(false)
|
||||
}, [open, initialFormatId, firstId, formats])
|
||||
const initialTab = initialFormatId && formats.some(format => format.id === initialFormatId) ? initialFormatId : firstId
|
||||
const resetKey = JSON.stringify([open, initialTab])
|
||||
const [previousKey, setPreviousKey] = useState(resetKey)
|
||||
const [tab, setTab] = useState(initialTab)
|
||||
const [copiedCode, setCopiedCode] = useState<string | null>(null)
|
||||
if (previousKey !== resetKey) {
|
||||
setPreviousKey(resetKey)
|
||||
if (open) { setTab(initialTab); setCopiedCode(null) }
|
||||
}
|
||||
|
||||
const active = useMemo(
|
||||
() => formats.find((f) => f.id === tab) ?? formats[0],
|
||||
@@ -129,23 +129,26 @@ function CodeExportSheet({
|
||||
)
|
||||
|
||||
const code = active?.code ?? ""
|
||||
const copied = !!code && copiedCode === code
|
||||
const emptyMessage = active?.emptyMessage
|
||||
const filename = active?.filename ?? "export.txt"
|
||||
const canCopy = Boolean(code) && !emptyMessage
|
||||
const isLive = Boolean(active?.isLive)
|
||||
const showTabs = formats.length > 1
|
||||
|
||||
function handleCopy() {
|
||||
async function handleCopy() {
|
||||
if (!canCopy) return
|
||||
void navigator.clipboard.writeText(code).then(() => {
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 1800)
|
||||
})
|
||||
setCopiedCode(null)
|
||||
try {
|
||||
await navigator.clipboard.writeText(code)
|
||||
setCopiedCode(code)
|
||||
setTimeout(() => setCopiedCode(null), 1800)
|
||||
} catch { setCopiedCode(null); toast.error("Не удалось скопировать. Повторите действие или скачайте файл.") }
|
||||
}
|
||||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={(v) => { if (!v) onClose() }}>
|
||||
<SheetContent
|
||||
<SheetContent finalFocus={returnFocus}
|
||||
className={cn(
|
||||
"flex w-full flex-col gap-0 overflow-hidden p-0 sm:max-w-xl",
|
||||
className,
|
||||
|
||||
Reference in new issue
Block a user