Chce stworzyc Modal ktory po kliknieciu poza jego obszar zamyka sie ale jego zawartosc zostaje jedynie ukryta oraz po kliknieciu esc
znika on calkowicie z kodu.
Zrobilem tak:
export const DialogModalTester = ({ editor }: ImageButtonProps) => {
const [isOpened, setIsOpened] = useState(false);
const [isVisible, setIsVisible] = useState(false);
let onClick = () => {
setIsOpened(true);
setIsVisible(true);
};
return (
<div>
<button onClick={onClick}>Open "dialog" modal</button>
{isOpened && (
<ImageModal
editor={editor}
isOpened={isOpened}
setIsOpened={setIsOpened}
isVisible={isVisible}
setIsVisible={setIsVisible}
uploadOptions={{ handler: defaultImageUploadHandler }}
/>
)}
</div>
);
};
Powyzej mam state isOpened
ktory poczatkowo jest false
czyli nie ma modala, a po kliknieciu w button zminia sie na true
i pojawia sie modal oraz state isVisible
ktory ma kontrolowac czy modal jest widoczny czy nie. Przekazuje oba state i settery do ImageModal
ktory wyglada tak:
return (
<div>
<DialogModal
isVisible={isVisible}
onOutsideClick={() => setIsVisible(false)}
onClose={() => setIsOpened(false)}
>
<div id="image-modal">
<div className="upload-container">
<div className="header">
<h1>Image</h1>
<button className="close-btn" onClick={() => setIsOpened(false)}>
<img src={CloseIcon}></img>
</button>
</div>
{uploadStatus !== "uploadSuccess" && uploadStatus !== "goodLink" ? (
<div
className={
`drag-area` + `${isDragActive ? " drag-active" : ""}`
}
onDragOver={onDragOver}
onDragLeave={onDragLeave}
onDrop={onDrop}
>
<div className="icon">
<ImagesIcon />
</div>
<span className="drag-and-drop">
{isDragActive ? "Release to Upload," : "Drag & Drop,"}
</span>
<span className="paste-image">paste an image, </span>
<button onClick={onClickPasteUrl} className="paste-url">
paste link,{" "}
</button>
<span className="browse">
or{" "}
<span
onClick={() => browseInputRef.current.click()}
className="browse-btn"
>
browse
</span>
</span>
<input
ref={browseInputRef}
type="file"
onChange={onFileSelection}
hidden
></input>
<span className="support">Supports: JPEG, JPG, PNG</span>
</div>
) : (
<div className="image-preview">
<img src={imageUrl} alt="Image not found"></img>
</div>
)}
</div>
{uploadStatus && <UploadNotice />}
<div>
<label htmlFor="link-editor-href-input" className="s-label mb4">
{_t("link_editor.href_label")}
</label>
<input
ref={linkInputRef}
value={imageUrl}
placeholder="Paste image URL here"
onInput={(e) =>
setAndValidateUrl((e.target as HTMLInputElement).value)
}
id="link-editor-href-input"
className="s-input"
type="text"
name="href"
aria-describedby="link-editor-href-error"
/>
<p
id="link-editor-href-error"
className="s-input-message mt4 d-none js-link-editor-href-error"
></p>
</div>
<div className="d-flex py8 jc-space-between ai-center sm:fd-column sm:ai-start sm:g16">
<div>
<button
className="s-btn s-btn__primary ws-nowrap mr8 js-add-image"
type="button"
onClick={onSubmit}
disabled={isDisabled}
>
Add image
</button>
<button
className="s-btn ws-nowrap js-cancel-button"
type="button"
onClick={onClose}
>
Cancel
</button>
</div>
</div>
</div>
</DialogModal>
</div>
);
I co wazniejsze tak wyglada moj podstawowy modal DialogModal
:
const DialogModal = ({
isVisible,
onClose,
children,
onOutsideClick,
}: Props) => {
const ref = useRef<HTMLDialogElement>(null);
useEffect(() => {
if (isVisible) {
ref.current?.showModal();
document.body.classList.add("modal-open"); // prevent bg scroll
} else {
ref.current?.close();
document.body.classList.remove("modal-open");
}
}, [isVisible]);
return (
<div
className="modal-overlay"
onClick={(e) => {
ref.current &&
!isClickInsideRectangle(e, ref.current) &&
onOutsideClick();
}}
>
<dialog className="modal-dialog" ref={ref} onCancel={onClose}>
{children}
</dialog>
</div>
);
};
Uzywam useEffect
zeby w momencie w ktorym wartosc isVisible
sie zmieni moc pokazac/ukryc modal
Problem:
- Po kliknieciu naprzycisk do pokazania modala, akcja
useEffect
wykonywana jest dwukrtonie i przy pierwszym wykonaniu jest OK i pokazuje sie modal ale przy drugim modal jest juz widoczny wiecshowModal
zwraca blad. Dlaczego dwa razy wywolywany jest ten efekt? - Nawet jak uda sie rozwiazac 1, wydaje mi sie ze dalej nie bedzie to dzialalo jak nalezy bo jesli klikne na zewnatrz modala i
setVisible
sie ustawi na false, to modal sie schowa ale chyba strace tez jego zawartosc bo wygeneruje sie on od nowa wewnatrzDialogModalTester
.