You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.4 KiB
104 lines
2.4 KiB
import React, {PropsWithChildren, useCallback, useEffect} from "react";
|
|
import ReactModal from "react-modal";
|
|
import "./Layout.sass";
|
|
import {LuciferIcon} from "../models/Icons";
|
|
import {IconBlock} from "./Elements";
|
|
|
|
interface TabsProps {
|
|
tabNames: string[]
|
|
index: number
|
|
onChange: (newIndex: number) => void
|
|
boldIndex?: number
|
|
large?: boolean
|
|
}
|
|
|
|
export function Tabs({tabNames, index, onChange, large, boldIndex}: TabsProps) {
|
|
useEffect(() => {
|
|
if (index < 0) {
|
|
onChange(0);
|
|
} else if (tabNames.length > 0 && index >= tabNames.length) {
|
|
onChange(tabNames.length - 1);
|
|
}
|
|
}, [tabNames, index, onChange]);
|
|
|
|
const tabClass = useCallback((i: number) => {
|
|
const classes = ['Tabs-element'];
|
|
|
|
if (i === index) {
|
|
classes.push("Tabs-active");
|
|
}
|
|
|
|
if (i === boldIndex) {
|
|
classes.push("Tabs-bold");
|
|
}
|
|
|
|
return classes.join(" ");
|
|
}, [index, boldIndex])
|
|
|
|
return (
|
|
<div className={`Tabs-container ${large ? "Tabs-large" : ""}`}>
|
|
<div className="Tabs-inner">
|
|
{tabNames.map((name, i) => (
|
|
<div className={tabClass(i)}
|
|
onClick={() => onChange(i)}
|
|
>
|
|
{name}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface PageProps {
|
|
title?: string
|
|
}
|
|
|
|
export function Page({title, children}: PropsWithChildren<PageProps>) {
|
|
useEffect(() => {
|
|
window.document.title = title ? `${title} - Lucifer` : "Lucifer";
|
|
}, [title]);
|
|
|
|
return (
|
|
<div className="Page">
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface DialogProps {
|
|
title: string
|
|
buttons?: {
|
|
text: string
|
|
icon: LuciferIcon
|
|
onClick?: (() => void)
|
|
}[]
|
|
loading?: boolean
|
|
}
|
|
|
|
export function Dialog({title, buttons, children}: PropsWithChildren<DialogProps>) {
|
|
|
|
|
|
return (
|
|
<ReactModal isOpen={true}
|
|
className="Dialog-main"
|
|
overlayClassName="Dialog-overlay"
|
|
>
|
|
<div className="Dialog-container">
|
|
<div className="Dialog-header">
|
|
{title}
|
|
</div>
|
|
{children}
|
|
<div className="Dialog-footer">
|
|
{buttons?.map(b => (
|
|
<button key={b.text}>
|
|
<IconBlock icon={b.icon}/>
|
|
{" "}
|
|
{b.text}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</ReactModal>
|
|
);
|
|
}
|