feat: lower memory dedupe threshold for more aggressive cleaning
This commit is contained in:
@@ -1,82 +1,82 @@
|
||||
import { useRef } from "react"
|
||||
import { X } from "lucide-react"
|
||||
|
||||
export interface CustomDialogProps {
|
||||
type: "alert" | "confirm" | "prompt"
|
||||
title: string
|
||||
message: string
|
||||
defaultValue?: string
|
||||
autoValue?: string
|
||||
autoLabel?: string
|
||||
onConfirm: (val?: string) => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export function CustomDialog({ type, title, message, defaultValue, autoValue, autoLabel, onConfirm, onCancel }: CustomDialogProps) {
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
return (
|
||||
<div className="fixed inset-0 z-[99] bg-black/60 backdrop-blur-sm flex items-center justify-center p-4 overscroll-contain" role="dialog" aria-modal="true" aria-label={title}>
|
||||
<div className="w-full max-w-sm rounded-2xl border border-border/80 bg-card p-6 shadow-2xl space-y-4 animate-in fade-in zoom-in-95 duration-200">
|
||||
<div className="flex items-center justify-between border-b border-border/20 pb-2">
|
||||
<h3 className="text-xs font-bold uppercase tracking-wider text-primary">{title}</h3>
|
||||
<button
|
||||
onClick={onCancel || (() => onConfirm())}
|
||||
aria-label="Schließen"
|
||||
className="p-1 rounded hover:bg-accent text-muted-foreground hover:text-foreground cursor-pointer"
|
||||
>
|
||||
<X className="h-4 w-4" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground leading-relaxed">{message}</p>
|
||||
|
||||
{type === "prompt" && (
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
defaultValue={defaultValue}
|
||||
aria-label={title}
|
||||
className="flex-1 h-9 px-3 text-xs bg-background/40 border border-border/60 rounded-lg outline-none focus:border-primary transition-colors text-foreground"
|
||||
autoFocus
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
onConfirm(inputRef.current?.value)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{autoValue !== undefined && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { if (inputRef.current) inputRef.current.value = autoValue }}
|
||||
title="Setup-bewussten Optimalwert eintragen"
|
||||
className="h-9 px-3 shrink-0 text-xs font-semibold text-primary border border-primary/50 bg-primary/10 hover:bg-primary/20 rounded-lg transition-colors cursor-pointer"
|
||||
>
|
||||
{autoLabel || "Auto"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end gap-3 pt-2">
|
||||
{(type === "confirm" || type === "prompt") && (
|
||||
<button
|
||||
onClick={onCancel}
|
||||
className="h-8 px-4 flex items-center justify-center text-xs font-semibold text-muted-foreground border border-border/60 bg-background/20 hover:bg-accent rounded-lg transition-colors cursor-pointer"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => {
|
||||
const val = type === "prompt" ? inputRef.current?.value : undefined
|
||||
onConfirm(val)
|
||||
}}
|
||||
className="h-8 px-4 flex items-center justify-center text-xs font-semibold text-primary-foreground bg-primary hover:bg-primary/95 rounded-lg transition-colors cursor-pointer"
|
||||
>
|
||||
{type === "confirm" ? "Ja, fortfahren" : type === "prompt" ? "Übernehmen" : "OK"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
import { useRef } from "react"
|
||||
import { X } from "lucide-react"
|
||||
|
||||
export interface CustomDialogProps {
|
||||
type: "alert" | "confirm" | "prompt"
|
||||
title: string
|
||||
message: string
|
||||
defaultValue?: string
|
||||
autoValue?: string
|
||||
autoLabel?: string
|
||||
onConfirm: (val?: string) => void
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export function CustomDialog({ type, title, message, defaultValue, autoValue, autoLabel, onConfirm, onCancel }: CustomDialogProps) {
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
return (
|
||||
<div className="fixed inset-0 z-[99] bg-black/60 backdrop-blur-sm flex items-center justify-center p-4 overscroll-contain" role="dialog" aria-modal="true" aria-label={title}>
|
||||
<div className="w-full max-w-sm rounded-2xl border border-border/80 bg-card p-6 shadow-2xl space-y-4 animate-in fade-in zoom-in-95 duration-200">
|
||||
<div className="flex items-center justify-between border-b border-border/20 pb-2">
|
||||
<h3 className="text-xs font-bold uppercase tracking-wider text-primary">{title}</h3>
|
||||
<button
|
||||
onClick={onCancel || (() => onConfirm())}
|
||||
aria-label="Schließen"
|
||||
className="p-1 rounded hover:bg-accent text-muted-foreground hover:text-foreground cursor-pointer"
|
||||
>
|
||||
<X className="h-4 w-4" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground leading-relaxed">{message}</p>
|
||||
|
||||
{type === "prompt" && (
|
||||
<div className="flex gap-2">
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
defaultValue={defaultValue}
|
||||
aria-label={title}
|
||||
className="flex-1 h-9 px-3 text-xs bg-background/40 border border-border/60 rounded-lg outline-none focus:border-primary transition-colors text-foreground"
|
||||
autoFocus
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
onConfirm(inputRef.current?.value)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{autoValue !== undefined && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { if (inputRef.current) inputRef.current.value = autoValue }}
|
||||
title="Setup-bewussten Optimalwert eintragen"
|
||||
className="h-9 px-3 shrink-0 text-xs font-semibold text-primary border border-primary/50 bg-primary/10 hover:bg-primary/20 rounded-lg transition-colors cursor-pointer"
|
||||
>
|
||||
{autoLabel || "Auto"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end gap-3 pt-2">
|
||||
{(type === "confirm" || type === "prompt") && (
|
||||
<button
|
||||
onClick={onCancel}
|
||||
className="h-8 px-4 flex items-center justify-center text-xs font-semibold text-muted-foreground border border-border/60 bg-background/20 hover:bg-accent rounded-lg transition-colors cursor-pointer"
|
||||
>
|
||||
Abbrechen
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => {
|
||||
const val = type === "prompt" ? inputRef.current?.value : undefined
|
||||
onConfirm(val)
|
||||
}}
|
||||
className="h-8 px-4 flex items-center justify-center text-xs font-semibold text-primary-foreground bg-primary hover:bg-primary/95 rounded-lg transition-colors cursor-pointer"
|
||||
>
|
||||
{type === "confirm" ? "Ja, fortfahren" : type === "prompt" ? "Übernehmen" : "OK"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user