mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
167 lines
4.2 KiB
JavaScript
167 lines
4.2 KiB
JavaScript
import React from "react"
|
|
import { Modal as AntdModal } from "antd"
|
|
import classnames from "classnames"
|
|
|
|
import { Icons } from "components/Icons"
|
|
|
|
import useLayoutInterface from "hooks/useLayoutInterface"
|
|
import { DOMWindow } from "components/RenderWindow"
|
|
|
|
import "./index.less"
|
|
|
|
class Modal extends React.Component {
|
|
state = {
|
|
visible: false,
|
|
}
|
|
|
|
contentRef = React.createRef()
|
|
|
|
escTimeout = null
|
|
|
|
componentDidMount() {
|
|
setTimeout(() => {
|
|
this.setState({
|
|
visible: true,
|
|
})
|
|
}, 10)
|
|
|
|
document.addEventListener("keydown", this.handleEsc, false)
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
document.removeEventListener("keydown", this.handleEsc, false)
|
|
}
|
|
|
|
close = () => {
|
|
this.setState({
|
|
visible: false,
|
|
})
|
|
|
|
setTimeout(() => {
|
|
if (typeof this.props.onClose === "function") {
|
|
this.props.onClose()
|
|
}
|
|
}, 250)
|
|
}
|
|
|
|
handleEsc = (e) => {
|
|
if (e.key === "Escape") {
|
|
if (this.escTimeout !== null) {
|
|
clearTimeout(this.escTimeout)
|
|
return this.close()
|
|
}
|
|
|
|
this.escTimeout = setTimeout(() => {
|
|
this.escTimeout = null
|
|
}, 250)
|
|
}
|
|
}
|
|
|
|
handleClickOutside = (e) => {
|
|
if (this.contentRef.current && !this.contentRef.current.contains(e.target)) {
|
|
if (this.props.confirmOnOutsideClick) {
|
|
return AntdModal.confirm({
|
|
title: this.props.confirmOnClickTitle ?? "Are you sure?",
|
|
content: this.props.confirmOnClickContent ?? "Are you sure you want to close this window?",
|
|
onOk: () => {
|
|
this.close()
|
|
}
|
|
})
|
|
}
|
|
|
|
return this.close()
|
|
}
|
|
}
|
|
|
|
render() {
|
|
return <div
|
|
className={classnames(
|
|
"app_modal_wrapper",
|
|
{
|
|
["active"]: this.state.visible,
|
|
["framed"]: this.props.framed,
|
|
}
|
|
)}
|
|
onTouchEnd={this.handleClickOutside}
|
|
onMouseDown={this.handleClickOutside}
|
|
>
|
|
<div
|
|
className="app_modal_content"
|
|
ref={this.contentRef}
|
|
onTouchEnd={this.handleClickOutside}
|
|
onMouseDown={this.handleClickOutside}
|
|
style={this.props.frameContentStyle}
|
|
>
|
|
{
|
|
this.props.includeCloseButton && <div
|
|
className="app_modal_close"
|
|
onClick={this.close}
|
|
>
|
|
<Icons.MdClose />
|
|
</div>
|
|
}
|
|
|
|
{
|
|
React.cloneElement(this.props.children, {
|
|
close: this.close
|
|
})
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
export default () => {
|
|
const modalRef = React.useRef()
|
|
|
|
function openModal(
|
|
id,
|
|
render,
|
|
{
|
|
framed = true,
|
|
frameContentStyle = null,
|
|
includeCloseButton = false,
|
|
|
|
confirmOnOutsideClick = false,
|
|
confirmOnClickTitle,
|
|
confirmOnClickContent,
|
|
|
|
className,
|
|
props,
|
|
} = {}
|
|
) {
|
|
const win = new DOMWindow({
|
|
id: id,
|
|
className: className,
|
|
})
|
|
|
|
win.render(<Modal
|
|
ref={modalRef}
|
|
win={win}
|
|
onClose={() => {
|
|
win.destroy()
|
|
}}
|
|
includeCloseButton={includeCloseButton}
|
|
framed={framed}
|
|
frameContentStyle={frameContentStyle}
|
|
confirmOnOutsideClick={confirmOnOutsideClick}
|
|
confirmOnClickTitle={confirmOnClickTitle}
|
|
confirmOnClickContent={confirmOnClickContent}
|
|
>
|
|
{
|
|
React.createElement(render, props)
|
|
}
|
|
</Modal>)
|
|
}
|
|
|
|
function closeModal() {
|
|
modalRef.current.close()
|
|
}
|
|
|
|
useLayoutInterface("modal", {
|
|
open: openModal,
|
|
close: closeModal,
|
|
})
|
|
|
|
return null
|
|
} |