/* eslint-disable @next/next/no-img-element */ import styles from "./ui-lib.module.scss"; import LoadingIcon from "../icons/three-dots.svg"; import CloseIcon from "../icons/close.svg"; import EyeIcon from "../icons/eye.svg"; import EyeOffIcon from "../icons/eye-off.svg"; import DownIcon from "../icons/down.svg"; import ConfirmIcon from "../icons/confirm.svg"; import CancelIcon from "../icons/cancel.svg"; import MaxIcon from "../icons/max.svg"; import MinIcon from "../icons/min.svg"; import Locale from "../locales"; import { createRoot } from "react-dom/client"; import React, { HTMLProps, useEffect, useState } from "react"; import { IconButton } from "./button"; export function Popover(props: { children: JSX.Element; content: JSX.Element; open?: boolean; onClose?: () => void; }) { return (
{props.children} {props.open && (
{props.content}
)}
); } export function Card(props: { children: JSX.Element[]; className?: string }) { return (
{props.children}
); } export function ListItem(props: { title: string; subTitle?: string; children?: JSX.Element | JSX.Element[]; icon?: JSX.Element; className?: string; onClick?: () => void; }) { return (
{props.icon &&
{props.icon}
}
{props.title}
{props.subTitle && (
{props.subTitle}
)}
{props.children}
); } export function List(props: { children: React.ReactNode; id?: string }) { return (
{props.children}
); } export function Loading() { return (
); } interface ModalProps { title: string; children?: any; actions?: React.ReactNode[]; defaultMax?: boolean; footer?: React.ReactNode; onClose?: () => void; } export function Modal(props: ModalProps) { useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") { props.onClose?.(); } }; window.addEventListener("keydown", onKeyDown); return () => { window.removeEventListener("keydown", onKeyDown); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const [isMax, setMax] = useState(!!props.defaultMax); return (
{props.title}
setMax(!isMax)} > {isMax ? : }
{props.children}
{props.footer}
{props.actions?.map((action, i) => (
{action}
))}
); } export function showModal(props: ModalProps) { const div = document.createElement("div"); div.className = "modal-mask"; document.body.appendChild(div); const root = createRoot(div); const closeModal = () => { props.onClose?.(); root.unmount(); div.remove(); }; div.onclick = (e) => { if (e.target === div) { closeModal(); } }; root.render(); } export type ToastProps = { content: string; action?: { text: string; onClick: () => void; }; onClose?: () => void; }; export function Toast(props: ToastProps) { return (
{props.content} {props.action && ( )}
); } export function showToast( content: string, action?: ToastProps["action"], delay = 3000, ) { const div = document.createElement("div"); div.className = styles.show; document.body.appendChild(div); const root = createRoot(div); const close = () => { div.classList.add(styles.hide); setTimeout(() => { root.unmount(); div.remove(); }, 300); }; setTimeout(() => { close(); }, delay); root.render(); } export type InputProps = React.HTMLProps & { autoHeight?: boolean; rows?: number; }; export function Input(props: InputProps) { return ( ); } export function PasswordInput(props: HTMLProps) { const [visible, setVisible] = useState(false); function changeVisibility() { setVisible(!visible); } return (
: } onClick={changeVisibility} className={"password-eye"} />
); } export function Select( props: React.DetailedHTMLProps< React.SelectHTMLAttributes, HTMLSelectElement >, ) { const { className, children, ...otherProps } = props; return (
); } export function showConfirm(content: any) { const div = document.createElement("div"); div.className = "modal-mask"; document.body.appendChild(div); const root = createRoot(div); const closeModal = () => { root.unmount(); div.remove(); }; return new Promise((resolve) => { root.render( { resolve(false); closeModal(); }} icon={} tabIndex={0} bordered shadow >, { resolve(true); closeModal(); }} icon={} tabIndex={0} autoFocus bordered shadow >, ]} onClose={closeModal} > {content} , ); }); } function PromptInput(props: { value: string; onChange: (value: string) => void; rows?: number; }) { const [input, setInput] = useState(props.value); const onInput = (value: string) => { props.onChange(value); setInput(value); }; return ( ); } export function showPrompt(content: any, value = "", rows = 3) { const div = document.createElement("div"); div.className = "modal-mask"; document.body.appendChild(div); const root = createRoot(div); const closeModal = () => { root.unmount(); div.remove(); }; return new Promise((resolve) => { let userInput = value; root.render( { closeModal(); }} icon={} bordered shadow tabIndex={0} >, { resolve(userInput); closeModal(); }} icon={} bordered shadow tabIndex={0} >, ]} onClose={closeModal} > (userInput = val)} value={value} rows={rows} > , ); }); } export function showImageModal(img: string) { showModal({ title: Locale.Export.Image.Modal, children: (
preview
), }); } export function Selector(props: { items: Array<{ title: string; subTitle?: string; value: T; }>; defaultSelectedValue?: T; onSelection?: (selection: T[]) => void; onClose?: () => void; multiple?: boolean; }) { return (
props.onClose?.()}>
{props.items.map((item, i) => { const selected = props.defaultSelectedValue === item.value; return ( { props.onSelection?.([item.value]); props.onClose?.(); }} > {selected ? (
) : ( <> )}
); })}
); }