mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
feat: add modals
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
.modal-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 100;
|
||||
background-color: rgba(21, 23, 21, 0.7);
|
||||
|
||||
.modal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 10px;
|
||||
padding: 0;
|
||||
width: 450px;
|
||||
max-height: 80vh;
|
||||
margin-top: 25vh;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background: var(--modal-bg-color);
|
||||
border: 1px solid var(--app-border-color);
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 20px 20px 10px;
|
||||
border-bottom: 1px solid var(--modal-header-bottom-border-color);
|
||||
|
||||
.modal-title {
|
||||
margin: 0 0 5px;
|
||||
color: var(--app-text-primary-color);
|
||||
font-size: var(--title-font-size);
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 0.8rem;
|
||||
color: var(--app-text-secondary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
padding: 15px 20px;
|
||||
gap: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import React from "react";
|
||||
import { Button } from "@/element/button";
|
||||
|
||||
import "./modal.less";
|
||||
|
||||
interface ModalProps {
|
||||
id?: string;
|
||||
children: React.ReactNode;
|
||||
onClickOut: () => void;
|
||||
}
|
||||
|
||||
function Modal({ children, onClickOut, id = "modal", ...otherProps }: ModalProps) {
|
||||
const handleOutsideClick = (e: React.SyntheticEvent<HTMLDivElement>) => {
|
||||
if (typeof onClickOut === "function" && (e.target as Element).className === "modal-container") {
|
||||
onClickOut();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="modal-container" onClick={handleOutsideClick}>
|
||||
<dialog {...otherProps} id={id} className="modal">
|
||||
{children}
|
||||
</dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface ModalContentProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function ModalContent({ children }: ModalContentProps) {
|
||||
return <div className="modal-content">{children}</div>;
|
||||
}
|
||||
|
||||
interface ModalHeaderProps {
|
||||
title: React.ReactNode;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
function ModalHeader({ title, description }: ModalHeaderProps) {
|
||||
return (
|
||||
<header className="modal-header">
|
||||
{typeof title === "string" ? <h3 className="modal-title">{title}</h3> : title}
|
||||
{description && <p>{description}</p>}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
interface ModalFooterProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function ModalFooter({ children }: ModalFooterProps) {
|
||||
return <footer className="modal-footer">{children}</footer>;
|
||||
}
|
||||
|
||||
interface WaveModalProps {
|
||||
title: string;
|
||||
description?: string;
|
||||
id?: string;
|
||||
onSubmit: () => void;
|
||||
onCancel: () => void;
|
||||
buttonLabel?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function WaveModal({ title, description, onSubmit, onCancel, buttonLabel = "Ok", children }: WaveModalProps) {
|
||||
return (
|
||||
<Modal id="text-box-modal" onClickOut={onCancel}>
|
||||
<ModalHeader title={title} description={description} />
|
||||
<ModalContent>{children}</ModalContent>
|
||||
<ModalFooter>
|
||||
<Button onClick={onSubmit}>{buttonLabel}</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export { WaveModal };
|
||||
@@ -11,7 +11,6 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
max-height: 40%;
|
||||
height: auto;
|
||||
background-color: var(--panel-bg-color);
|
||||
color: var(--main-text-color);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import * as React from "react";
|
||||
import * as Plot from "@observablehq/plot";
|
||||
import * as d3 from "d3";
|
||||
import { Button } from "@/element/button";
|
||||
import { WaveModal } from "@/element/modal";
|
||||
|
||||
import "./plotview.less";
|
||||
|
||||
@@ -29,6 +31,9 @@ function evalAsync(Plot: any, d3: any, funcText: string): Promise<unknown> {
|
||||
function PlotView() {
|
||||
const containerRef = React.useRef<HTMLInputElement>();
|
||||
const [plotDef, setPlotDef] = React.useState<string>();
|
||||
const [tempDef, setTempDef] = React.useState<string>();
|
||||
const [savedDef, setSavedDef] = React.useState<string>();
|
||||
const [modalUp, setModalUp] = React.useState(false);
|
||||
/*
|
||||
const [data, setData] = React.useState();
|
||||
|
||||
@@ -94,13 +99,23 @@ function PlotView() {
|
||||
|
||||
return (
|
||||
<div className="plot-view">
|
||||
<Button onClick={() => setModalUp(true)}>Edit</Button>
|
||||
<div className="plot-window" ref={containerRef} />
|
||||
<textarea
|
||||
className="plot-config"
|
||||
rows={5}
|
||||
onChange={(e) => setPlotDef(e.target.value)}
|
||||
spellCheck={false}
|
||||
/>
|
||||
{modalUp && (
|
||||
<WaveModal
|
||||
title="Plot Definition"
|
||||
onCancel={() => setModalUp(false)}
|
||||
onSubmit={() => setModalUp(false)}
|
||||
>
|
||||
<textarea
|
||||
className="plot-config"
|
||||
rows={5}
|
||||
onChange={(e) => setPlotDef(e.target.value)}
|
||||
spellCheck={false}
|
||||
defaultValue={plotDef}
|
||||
/>
|
||||
</WaveModal>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user