mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
feat: add modals
This commit is contained in:
parent
c82bc48aab
commit
cddaff4f7e
55
frontend/app/element/modal.less
Normal file
55
frontend/app/element/modal.less
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
80
frontend/app/element/modal.tsx
Normal file
80
frontend/app/element/modal.tsx
Normal file
@ -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>
|
||||
);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
:root {
|
||||
--main-text-color: #f7f7f7;
|
||||
--title-font-size: 18px;
|
||||
--secondary-text-color: rgb(195, 200, 194);
|
||||
--main-bg-color: #000000;
|
||||
--border-color: #333333;
|
||||
@ -16,4 +17,27 @@
|
||||
--error-color: rgb(229, 77, 46);
|
||||
--warning-color: rgb(224, 185, 86);
|
||||
--success-color: rgb(78, 154, 6);
|
||||
|
||||
/* global colors */
|
||||
--app-bg-color: black;
|
||||
--app-accent-color: rgb(88, 193, 66);
|
||||
--app-accent-bg-color: rgba(88, 193, 66, 0.25);
|
||||
--app-accent-bg-darker-color: rgba(88, 193, 66, 0.5);
|
||||
--app-text-color: rgb(211, 215, 207);
|
||||
--app-text-primary-color: rgb(255, 255, 255);
|
||||
--app-text-secondary-color: rgb(195, 200, 194);
|
||||
--app-text-disabled-color: rgb(173, 173, 173);
|
||||
--app-text-bg-color: rgb(23, 23, 23);
|
||||
--app-text-bg-disabled-color: rgb(51, 51, 51);
|
||||
--app-border-color: rgb(51, 51, 51);
|
||||
--app-maincontent-bg-color: rgb(51, 51, 51);
|
||||
--app-panel-bg-color: rgba(21, 23, 21, 1);
|
||||
--app-panel-bg-color-dev: rgb(21, 23, 48);
|
||||
--app-icon-color: rgb(139, 145, 138);
|
||||
--app-icon-hover-color: rgb(255, 255, 255);
|
||||
--app-selected-mask-color: rgba(255, 255, 255, 0.06);
|
||||
|
||||
/* modals colors */
|
||||
--modal-bg-color: var(--app-bg-color);
|
||||
--modal-header-bottom-border-color: rgba(241, 246, 243, 0.15);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user