176 lines
4.5 KiB
TypeScript
176 lines
4.5 KiB
TypeScript
/*
|
|
This file is part of GNU Taler
|
|
(C) 2022 Taler Systems S.A.
|
|
|
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
|
terms of the GNU General Public License as published by the Free Software
|
|
Foundation; either version 3, or (at your option) any later version.
|
|
|
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
import { css } from "@linaria/core";
|
|
import { ComponentChildren, h, VNode } from "preact";
|
|
// eslint-disable-next-line import/extensions
|
|
import CloseIcon from "../svg/close_24px.svg";
|
|
import ErrorOutlineIcon from "../svg/error_outline_outlined_24px.svg";
|
|
import InfoOutlinedIcon from "../svg/info_outlined_24px.svg";
|
|
import ReportProblemOutlinedIcon from "../svg/report_problem_outlined_24px.svg";
|
|
import SuccessOutlinedIcon from "../svg/success_outlined_24px.svg";
|
|
import { IconButton } from "./Button.js";
|
|
// eslint-disable-next-line import/extensions
|
|
import { darken, lighten } from "./colors/manipulation";
|
|
import { Paper } from "./Paper.js";
|
|
// eslint-disable-next-line import/extensions
|
|
import { theme } from "./style";
|
|
import { Typography } from "./Typography.js";
|
|
|
|
const defaultIconMapping = {
|
|
success: SuccessOutlinedIcon,
|
|
warning: ReportProblemOutlinedIcon,
|
|
error: ErrorOutlineIcon,
|
|
info: InfoOutlinedIcon,
|
|
};
|
|
|
|
const baseStyle = css`
|
|
background-color: transparent;
|
|
display: flex;
|
|
padding: 6px 16px;
|
|
`;
|
|
|
|
const colorVariant = {
|
|
standard: css`
|
|
color: var(--color-light-06);
|
|
background-color: var(--color-background-light-09);
|
|
`,
|
|
outlined: css`
|
|
color: var(--color-light-06);
|
|
border-width: 1px;
|
|
border-style: solid;
|
|
border-color: var(--color-light);
|
|
`,
|
|
filled: css`
|
|
color: "#fff";
|
|
font-weight: ${theme.typography.fontWeightMedium};
|
|
background-color: var(--color-main);
|
|
`,
|
|
};
|
|
|
|
interface Props {
|
|
title?: string;
|
|
variant?: "filled" | "outlined" | "standard";
|
|
role?: string;
|
|
onClose?: () => Promise<void>;
|
|
// icon: VNode;
|
|
severity?: "info" | "warning" | "success" | "error";
|
|
children: ComponentChildren;
|
|
icon?: boolean;
|
|
}
|
|
|
|
const getColor = theme.palette.mode === "light" ? darken : lighten;
|
|
const getBackgroundColor = theme.palette.mode === "light" ? lighten : darken;
|
|
|
|
function Icon({ svg }: { svg: VNode }): VNode {
|
|
return (
|
|
<div
|
|
class={css`
|
|
margin-right: 12px;
|
|
padding: 7px 0px;
|
|
display: flex;
|
|
font-size: 22px;
|
|
opacity: 0.9;
|
|
fill: currentColor;
|
|
`}
|
|
dangerouslySetInnerHTML={{ __html: svg as any }}
|
|
></div>
|
|
);
|
|
}
|
|
|
|
function Action({ children }: { children: ComponentChildren }): VNode {
|
|
return (
|
|
<div
|
|
class={css`
|
|
display: flex;
|
|
align-items: flex-start;
|
|
padding: 4px 0px 0px 16px;
|
|
margin-left: auto;
|
|
margin-right: -8px;
|
|
`}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Message({
|
|
title,
|
|
children,
|
|
}: {
|
|
title?: string;
|
|
children: ComponentChildren;
|
|
}): VNode {
|
|
return (
|
|
<div
|
|
class={css`
|
|
padding: 8px 0px;
|
|
width: 100%;
|
|
`}
|
|
>
|
|
{title && (
|
|
<Typography
|
|
class={css`
|
|
font-weight: ${theme.typography.fontWeightMedium};
|
|
`}
|
|
gutterBottom
|
|
>
|
|
{title}
|
|
</Typography>
|
|
)}
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function Alert({
|
|
variant = "standard",
|
|
severity = "success",
|
|
title,
|
|
children,
|
|
icon,
|
|
onClose,
|
|
...rest
|
|
}: Props): VNode {
|
|
return (
|
|
<Paper
|
|
class={[
|
|
theme.typography.body2,
|
|
baseStyle,
|
|
severity && colorVariant[variant],
|
|
].join(" ")}
|
|
style={{
|
|
"--color-light-06": getColor(theme.palette[severity].light, 0.6),
|
|
"--color-background-light-09": getBackgroundColor(
|
|
theme.palette[severity].light,
|
|
0.9,
|
|
),
|
|
"--color-main": theme.palette[severity].main,
|
|
"--color-light": theme.palette[severity].light,
|
|
// ...(style as any),
|
|
}}
|
|
elevation={1}
|
|
>
|
|
{icon != false ? <Icon svg={defaultIconMapping[severity]} /> : null}
|
|
<Message title={title}>{children}</Message>
|
|
{onClose && (
|
|
<Action>
|
|
<IconButton svg={CloseIcon} onClick={onClose} />
|
|
</Action>
|
|
)}
|
|
</Paper>
|
|
);
|
|
}
|