mui alert and not enough blanance ported to material
35
packages/taler-wallet-webextension/dev-html/static/font/import.css
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-italic-400.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-300.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-400.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-500.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-700.ttf) format('truetype');
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Stories</title>
|
<title>Stories</title>
|
||||||
<link rel="stylesheet" type="text/css" href="/dist/stories.css" />
|
<link rel="stylesheet" type="text/css" href="/dist/stories.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/font/import.css" />
|
||||||
<script src="/dist/stories.js"></script>
|
<script src="/dist/stories.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
|
||||||
import linaria from '@linaria/esbuild'
|
import linaria from '@linaria/esbuild'
|
||||||
import esbuild from 'esbuild'
|
import esbuild from 'esbuild'
|
||||||
|
@ -106,9 +106,13 @@ export const PendingOperation = (): VNode => (
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
),
|
),
|
||||||
description: (
|
description: (
|
||||||
<Typography>
|
<Fragment>
|
||||||
<b>EUR 37.95</b> - 5 feb 2022
|
<Typography inline bold>
|
||||||
</Typography>
|
EUR 37.95
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography inline>- 5 feb 2022</Typography>
|
||||||
|
</Fragment>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
@ -70,16 +70,16 @@ export function PendingTransactionsView({
|
|||||||
),
|
),
|
||||||
action: () => goToTransaction(t.transactionId),
|
action: () => goToTransaction(t.transactionId),
|
||||||
description: (
|
description: (
|
||||||
<Typography>
|
<Fragment>
|
||||||
<b>
|
<Typography inline bold>
|
||||||
{amount.currency} {Amounts.stringifyValue(amount)}
|
{amount.currency} {Amounts.stringifyValue(amount)}
|
||||||
</b>{" "}
|
</Typography>
|
||||||
-{" "}
|
-
|
||||||
<Time
|
<Time
|
||||||
timestamp={AbsoluteTime.fromTimestamp(t.timestamp)}
|
timestamp={AbsoluteTime.fromTimestamp(t.timestamp)}
|
||||||
format="dd MMMM yyyy"
|
format="dd MMMM yyyy"
|
||||||
/>
|
/>
|
||||||
</Typography>
|
</Fragment>
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
})}
|
})}
|
||||||
|
86
packages/taler-wallet-webextension/src/mui/Alert.stories.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
This file is part of GNU Taler
|
||||||
|
(C) 2021 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/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Javier Marchano (sebasjm)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { css } from "@linaria/core";
|
||||||
|
import { ComponentChildren, Fragment, h, VNode } from "preact";
|
||||||
|
import { Alert } from "./Alert.jsx";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "mui/alert",
|
||||||
|
component: Alert,
|
||||||
|
};
|
||||||
|
|
||||||
|
function Wrapper({ children }: { children: ComponentChildren }): VNode {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={css`
|
||||||
|
& > * {
|
||||||
|
margin: 2em;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BasicExample = (): VNode => (
|
||||||
|
<Wrapper>
|
||||||
|
<Alert severity="warning">this is an warning</Alert>
|
||||||
|
<Alert severity="error">this is an error</Alert>
|
||||||
|
<Alert severity="success">this is an success</Alert>
|
||||||
|
<Alert severity="info">this is an info</Alert>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const WithTitle = (): VNode => (
|
||||||
|
<Wrapper>
|
||||||
|
<Alert title="Warning" severity="warning">
|
||||||
|
this is an warning
|
||||||
|
</Alert>
|
||||||
|
<Alert title="Error" severity="error">
|
||||||
|
this is an error
|
||||||
|
</Alert>
|
||||||
|
<Alert title="Success" severity="success">
|
||||||
|
this is an success
|
||||||
|
</Alert>
|
||||||
|
<Alert title="Info" severity="info">
|
||||||
|
this is an info
|
||||||
|
</Alert>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const WithAction = (): VNode => (
|
||||||
|
<Wrapper>
|
||||||
|
<Alert title="Warning" severity="warning" onClose={() => alert("closed")}>
|
||||||
|
this is an warning
|
||||||
|
</Alert>
|
||||||
|
<Alert title="Error" severity="error" onClose={() => alert("closed")}>
|
||||||
|
this is an error
|
||||||
|
</Alert>
|
||||||
|
<Alert title="Success" severity="success" onClose={() => alert("closed")}>
|
||||||
|
this is an success
|
||||||
|
</Alert>
|
||||||
|
<Alert title="Info" severity="info" onClose={() => alert("closed")}>
|
||||||
|
this is an info
|
||||||
|
</Alert>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
160
packages/taler-wallet-webextension/src/mui/Alert.tsx
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
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?: () => 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>
|
||||||
|
);
|
||||||
|
}
|
@ -1,26 +1,11 @@
|
|||||||
import { ComponentChildren, h, VNode } from "preact";
|
import { ComponentChildren, h, VNode, JSX } from "preact";
|
||||||
import { css } from "@linaria/core";
|
import { css } from "@linaria/core";
|
||||||
// eslint-disable-next-line import/extensions
|
// eslint-disable-next-line import/extensions
|
||||||
import { theme, ripple, Colors } from "./style";
|
import { theme, ripple, Colors } from "./style";
|
||||||
// eslint-disable-next-line import/extensions
|
// eslint-disable-next-line import/extensions
|
||||||
import { alpha } from "./colors/manipulation";
|
import { alpha } from "./colors/manipulation";
|
||||||
|
|
||||||
interface Props {
|
const buttonBaseStyle = css`
|
||||||
children?: ComponentChildren;
|
|
||||||
disabled?: boolean;
|
|
||||||
disableElevation?: boolean;
|
|
||||||
disableFocusRipple?: boolean;
|
|
||||||
endIcon?: VNode;
|
|
||||||
fullWidth?: boolean;
|
|
||||||
href?: string;
|
|
||||||
size?: "small" | "medium" | "large";
|
|
||||||
startIcon?: VNode | string;
|
|
||||||
variant?: "contained" | "outlined" | "text";
|
|
||||||
color?: Colors;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseStyle = css`
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -30,7 +15,7 @@ const baseStyle = css`
|
|||||||
outline: 0;
|
outline: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
/* border-radius: 0; */
|
border-radius: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -39,6 +24,21 @@ const baseStyle = css`
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children?: ComponentChildren;
|
||||||
|
disabled?: boolean;
|
||||||
|
disableElevation?: boolean;
|
||||||
|
disableFocusRipple?: boolean;
|
||||||
|
endIcon?: string | VNode;
|
||||||
|
fullWidth?: boolean;
|
||||||
|
href?: string;
|
||||||
|
size?: "small" | "medium" | "large";
|
||||||
|
startIcon?: VNode | string;
|
||||||
|
variant?: "contained" | "outlined" | "text";
|
||||||
|
color?: Colors;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
const button = css`
|
const button = css`
|
||||||
min-width: 64px;
|
min-width: 64px;
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -54,13 +54,13 @@ const button = css`
|
|||||||
`;
|
`;
|
||||||
const colorIconVariant = {
|
const colorIconVariant = {
|
||||||
outlined: css`
|
outlined: css`
|
||||||
background-color: var(--color-main);
|
fill: var(--color-main);
|
||||||
`,
|
`,
|
||||||
contained: css`
|
contained: css`
|
||||||
background-color: var(--color-contrastText);
|
fill: var(--color-contrastText);
|
||||||
`,
|
`,
|
||||||
text: css`
|
text: css`
|
||||||
background-color: var(--color-main);
|
fill: var(--color-main);
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,6 +68,7 @@ const colorVariant = {
|
|||||||
outlined: css`
|
outlined: css`
|
||||||
color: var(--color-main);
|
color: var(--color-main);
|
||||||
border: 1px solid var(--color-main-alpha-half);
|
border: 1px solid var(--color-main-alpha-half);
|
||||||
|
background-color: var(--color-contrastText);
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 1px solid var(--color-main);
|
border: 1px solid var(--color-main);
|
||||||
background-color: var(--color-main-alpha-opacity);
|
background-color: var(--color-main-alpha-opacity);
|
||||||
@ -81,7 +82,7 @@ const colorVariant = {
|
|||||||
background-color: var(--color-main);
|
background-color: var(--color-main);
|
||||||
box-shadow: ${theme.shadows[2]};
|
box-shadow: ${theme.shadows[2]};
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--color-dark);
|
background-color: var(--color-grey-or-dark);
|
||||||
}
|
}
|
||||||
&:active {
|
&:active {
|
||||||
box-shadow: ${theme.shadows[8]};
|
box-shadow: ${theme.shadows[8]};
|
||||||
@ -186,11 +187,16 @@ const sizeVariant = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fullWidthStyle = css`
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
export function Button({
|
export function Button({
|
||||||
children,
|
children,
|
||||||
disabled,
|
disabled,
|
||||||
startIcon: sip,
|
startIcon: sip,
|
||||||
endIcon: eip,
|
endIcon: eip,
|
||||||
|
fullWidth,
|
||||||
variant = "text",
|
variant = "text",
|
||||||
size = "medium",
|
size = "medium",
|
||||||
color = "primary",
|
color = "primary",
|
||||||
@ -198,8 +204,8 @@ export function Button({
|
|||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
const style = css`
|
const style = css`
|
||||||
user-select: none;
|
user-select: none;
|
||||||
width: 1em;
|
width: 24px;
|
||||||
height: 1em;
|
height: 24px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@ -222,8 +228,9 @@ export function Button({
|
|||||||
sizeIconVariant[variant][size],
|
sizeIconVariant[variant][size],
|
||||||
style,
|
style,
|
||||||
].join(" ")}
|
].join(" ")}
|
||||||
|
//FIXME: check when sip can be a vnode
|
||||||
|
dangerouslySetInnerHTML={{ __html: sip as string }}
|
||||||
style={{
|
style={{
|
||||||
"--image": `url("${sip}")`,
|
|
||||||
"--color-main": theme.palette[color].main,
|
"--color-main": theme.palette[color].main,
|
||||||
"--color-contrastText": theme.palette[color].contrastText,
|
"--color-contrastText": theme.palette[color].contrastText,
|
||||||
}}
|
}}
|
||||||
@ -241,8 +248,8 @@ export function Button({
|
|||||||
sizeIconVariant[variant][size],
|
sizeIconVariant[variant][size],
|
||||||
style,
|
style,
|
||||||
].join(" ")}
|
].join(" ")}
|
||||||
|
dangerouslySetInnerHTML={{ __html: eip as string }}
|
||||||
style={{
|
style={{
|
||||||
"--image": `url("${eip}")`,
|
|
||||||
"--color-main": theme.palette[color].main,
|
"--color-main": theme.palette[color].main,
|
||||||
"--color-contrastText": theme.palette[color].contrastText,
|
"--color-contrastText": theme.palette[color].contrastText,
|
||||||
"--color-dark": theme.palette[color].dark,
|
"--color-dark": theme.palette[color].dark,
|
||||||
@ -250,17 +257,17 @@ export function Button({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<button
|
<ButtonBase
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
class={[
|
class={[
|
||||||
theme.typography.button,
|
theme.typography.button,
|
||||||
theme.shape.roundBorder,
|
theme.shape.roundBorder,
|
||||||
ripple,
|
|
||||||
baseStyle,
|
|
||||||
button,
|
button,
|
||||||
|
fullWidth && fullWidthStyle,
|
||||||
colorVariant[variant],
|
colorVariant[variant],
|
||||||
sizeVariant[variant][size],
|
sizeVariant[variant][size],
|
||||||
].join(" ")}
|
].join(" ")}
|
||||||
|
onClick={onClick}
|
||||||
style={{
|
style={{
|
||||||
"--color-main": theme.palette[color].main,
|
"--color-main": theme.palette[color].main,
|
||||||
"--color-contrastText": theme.palette[color].contrastText,
|
"--color-contrastText": theme.palette[color].contrastText,
|
||||||
@ -274,11 +281,75 @@ export function Button({
|
|||||||
theme.palette.text.primary,
|
theme.palette.text.primary,
|
||||||
theme.palette.action.hoverOpacity,
|
theme.palette.action.hoverOpacity,
|
||||||
),
|
),
|
||||||
|
"--color-grey-or-dark": !color
|
||||||
|
? theme.palette.grey.A100
|
||||||
|
: theme.palette[color].dark,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{startIcon}
|
{startIcon}
|
||||||
{children}
|
{children}
|
||||||
{endIcon}
|
{endIcon}
|
||||||
|
</ButtonBase>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BaseProps extends JSX.HTMLAttributes<HTMLButtonElement> {
|
||||||
|
class: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
children?: ComponentChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ButtonBase({
|
||||||
|
class: _class,
|
||||||
|
children,
|
||||||
|
onClick,
|
||||||
|
dangerouslySetInnerHTML,
|
||||||
|
...rest
|
||||||
|
}: BaseProps): VNode {
|
||||||
|
function doClick(): void {
|
||||||
|
if (onClick) onClick();
|
||||||
|
}
|
||||||
|
const classNames = [buttonBaseStyle, _class, ripple].join(" ");
|
||||||
|
if (dangerouslySetInnerHTML) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={doClick}
|
||||||
|
class={classNames}
|
||||||
|
dangerouslySetInnerHTML={dangerouslySetInnerHTML}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<button onClick={doClick} class={classNames} {...rest}>
|
||||||
|
{children}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function IconButton({
|
||||||
|
svg,
|
||||||
|
onClick,
|
||||||
|
}: {
|
||||||
|
svg: any;
|
||||||
|
onClick?: () => void;
|
||||||
|
}): VNode {
|
||||||
|
return (
|
||||||
|
<ButtonBase
|
||||||
|
onClick={onClick}
|
||||||
|
class={[
|
||||||
|
css`
|
||||||
|
text-align: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
font-size: ${theme.typography.pxToRem(24)};
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: visible;
|
||||||
|
color: "inherit";
|
||||||
|
fill: currentColor;
|
||||||
|
`,
|
||||||
|
].join(" ")}
|
||||||
|
dangerouslySetInnerHTML={{ __html: svg }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -34,11 +34,14 @@ export function Paper({
|
|||||||
square,
|
square,
|
||||||
variant = "elevation",
|
variant = "elevation",
|
||||||
children,
|
children,
|
||||||
|
class: _class,
|
||||||
|
style,
|
||||||
...rest
|
...rest
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
|
_class,
|
||||||
baseStyle,
|
baseStyle,
|
||||||
!square && theme.shape.roundBorder,
|
!square && theme.shape.roundBorder,
|
||||||
borderVariant[variant],
|
borderVariant[variant],
|
||||||
@ -49,6 +52,7 @@ export function Paper({
|
|||||||
"#fff",
|
"#fff",
|
||||||
getOverlayAlpha(elevation),
|
getOverlayAlpha(elevation),
|
||||||
)}, ${alpha("#fff", getOverlayAlpha(elevation))})`,
|
)}, ${alpha("#fff", getOverlayAlpha(elevation))})`,
|
||||||
|
...(style as any),
|
||||||
}}
|
}}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { css } from "@linaria/core";
|
import { css } from "@linaria/core";
|
||||||
import { ComponentChildren, h, VNode } from "preact";
|
import { ComponentChildren, h, VNode } from "preact";
|
||||||
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
// eslint-disable-next-line import/extensions
|
// eslint-disable-next-line import/extensions
|
||||||
import { theme } from "./style";
|
import { theme } from "./style";
|
||||||
|
|
||||||
@ -22,10 +23,13 @@ type VariantEnum =
|
|||||||
interface Props {
|
interface Props {
|
||||||
align?: "center" | "inherit" | "justify" | "left" | "right";
|
align?: "center" | "inherit" | "justify" | "left" | "right";
|
||||||
gutterBottom?: boolean;
|
gutterBottom?: boolean;
|
||||||
|
bold?: boolean;
|
||||||
|
inline?: boolean;
|
||||||
noWrap?: boolean;
|
noWrap?: boolean;
|
||||||
paragraph?: boolean;
|
paragraph?: boolean;
|
||||||
variant?: VariantEnum;
|
variant?: VariantEnum;
|
||||||
children?: ComponentChildren;
|
children: string[] | string;
|
||||||
|
class?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultVariantMapping = {
|
const defaultVariantMapping = {
|
||||||
@ -57,6 +61,9 @@ const gutterBottomStyle = css`
|
|||||||
const paragraphStyle = css`
|
const paragraphStyle = css`
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
`;
|
`;
|
||||||
|
const boldStyle = css`
|
||||||
|
font-weight: bold;
|
||||||
|
`;
|
||||||
|
|
||||||
export function Typography({
|
export function Typography({
|
||||||
align,
|
align,
|
||||||
@ -64,9 +71,16 @@ export function Typography({
|
|||||||
noWrap = false,
|
noWrap = false,
|
||||||
paragraph = false,
|
paragraph = false,
|
||||||
variant = "body1",
|
variant = "body1",
|
||||||
|
bold,
|
||||||
|
inline,
|
||||||
children,
|
children,
|
||||||
|
class: _class,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
const cmp = paragraph
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
|
const Component = inline
|
||||||
|
? "span"
|
||||||
|
: paragraph === true
|
||||||
? "p"
|
? "p"
|
||||||
: defaultVariantMapping[variant as "h1"] || "span";
|
: defaultVariantMapping[variant as "h1"] || "span";
|
||||||
|
|
||||||
@ -76,20 +90,21 @@ export function Typography({
|
|||||||
: {
|
: {
|
||||||
textAlign: align,
|
textAlign: align,
|
||||||
};
|
};
|
||||||
|
|
||||||
return h(
|
return h(
|
||||||
cmp,
|
Component,
|
||||||
{
|
{
|
||||||
class: [
|
class: [
|
||||||
|
_class,
|
||||||
root,
|
root,
|
||||||
noWrap && noWrapStyle,
|
noWrap && noWrapStyle,
|
||||||
gutterBottom && gutterBottomStyle,
|
gutterBottom && gutterBottomStyle,
|
||||||
paragraph && paragraphStyle,
|
paragraph && paragraphStyle,
|
||||||
|
bold && boldStyle,
|
||||||
theme.typography[variant as "button"], //FIXME: implement the rest of the typography and remove the casting
|
theme.typography[variant as "button"], //FIXME: implement the rest of the typography and remove the casting
|
||||||
].join(" "),
|
].join(" "),
|
||||||
style: {
|
style: alignStyle,
|
||||||
...alignStyle,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
children,
|
<i18n.Translate>{children}</i18n.Translate>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,5 +23,6 @@ import * as a1 from "./Button.stories.js";
|
|||||||
import * as a3 from "./Grid.stories.js";
|
import * as a3 from "./Grid.stories.js";
|
||||||
import * as a4 from "./Paper.stories.js";
|
import * as a4 from "./Paper.stories.js";
|
||||||
import * as a5 from "./TextField.stories.js";
|
import * as a5 from "./TextField.stories.js";
|
||||||
|
import * as a6 from "./Alert.stories.js";
|
||||||
|
|
||||||
export default [a1, a3, a4, a5];
|
export default [a1, a3, a4, a5, a6];
|
||||||
|
@ -48,11 +48,11 @@ export const ripple = css`
|
|||||||
|
|
||||||
transition: background 0.5s;
|
transition: background 0.5s;
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #47a7f5 radial-gradient(circle, transparent 1%, #47a7f5 1%)
|
background: #eeeeee radial-gradient(circle, transparent 1%, #eeeeee 1%)
|
||||||
center/15000%;
|
center/15000%;
|
||||||
}
|
}
|
||||||
&:active {
|
&:active {
|
||||||
background-color: #6eb9f7;
|
background-color: currentColor;
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
transition: background 0s;
|
transition: background 0s;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,32 @@
|
|||||||
import { h, VNode } from "preact";
|
import { css } from "@linaria/core";
|
||||||
import { ButtonBoxWarning, WarningBox } from "../components/styled/index.js";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { Alert } from "../mui/Alert.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
import { Paper } from "../mui/Paper.js";
|
||||||
|
import { Typography } from "../mui/Typography.js";
|
||||||
|
|
||||||
export function NoBalanceHelp({
|
export function NoBalanceHelp({
|
||||||
goToWalletManualWithdraw,
|
goToWalletManualWithdraw,
|
||||||
}: {
|
}: {
|
||||||
goToWalletManualWithdraw: () => void;
|
goToWalletManualWithdraw: () => void;
|
||||||
}): VNode {
|
}): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
|
||||||
return (
|
return (
|
||||||
<WarningBox>
|
<Paper
|
||||||
<p>
|
class={css`
|
||||||
<b>
|
margin: 1em;
|
||||||
<i18n.Translate>You have no balance.</i18n.Translate>
|
`}
|
||||||
</b>{" "}
|
>
|
||||||
<i18n.Translate>Withdraw some funds into your wallet.</i18n.Translate>
|
<Alert title="You have no balance." severity="warning">
|
||||||
</p>
|
<Typography>Withdraw some funds into your wallet.</Typography>
|
||||||
<ButtonBoxWarning onClick={() => goToWalletManualWithdraw()}>
|
<Button
|
||||||
<i18n.Translate>Withdraw</i18n.Translate>
|
fullWidth
|
||||||
</ButtonBoxWarning>
|
color="warning"
|
||||||
</WarningBox>
|
variant="outlined"
|
||||||
|
onClick={goToWalletManualWithdraw}
|
||||||
|
>
|
||||||
|
<Typography>Withdraw</Typography>
|
||||||
|
</Button>
|
||||||
|
</Alert>
|
||||||
|
</Paper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -286,12 +286,19 @@ function Application(): VNode {
|
|||||||
initialSelection,
|
initialSelection,
|
||||||
);
|
);
|
||||||
|
|
||||||
function updateSelectedFromHashChange({ newURL, oldURL }: any): void {
|
function updateSelectedFromHashChange(): void {
|
||||||
const selected = getSelectionFromLocationHash();
|
const selected = getSelectionFromLocationHash();
|
||||||
updateSelected(selected);
|
updateSelected(selected);
|
||||||
}
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener("hashchange", updateSelectedFromHashChange);
|
window.addEventListener("hashchange", updateSelectedFromHashChange);
|
||||||
|
if (location.hash) {
|
||||||
|
const hash = location.hash.substring(1);
|
||||||
|
const found = document.getElementById(hash);
|
||||||
|
if (found) {
|
||||||
|
found.scrollIntoView();
|
||||||
|
}
|
||||||
|
}
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("hashchange", updateSelectedFromHashChange);
|
window.removeEventListener("hashchange", updateSelectedFromHashChange);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 248 B |
@ -1 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" />
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 201 B |
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
|
||||||
|
<path d="M11 15h2v2h-2v-2zm0-8h2v6h-2V7zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 278 B |
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 297 B |
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 229 B |
@ -1 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<path d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" />
|
||||||
|
</svg>
|
Before Width: | Height: | Size: 152 B After Width: | Height: | Size: 161 B |
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path d="M20,12A8,8 0 0,1 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4C12.76,4 13.5,4.11 14.2, 4.31L15.77,2.74C14.61,2.26 13.34,2 12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0, 0 22,12M7.91,10.08L6.5,11.5L11,16L21,6L19.59,4.58L11,13.17L7.91,10.08Z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 382 B |
@ -166,7 +166,7 @@ export function CreateManualWithdraw({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (state.noExchangeFound) {
|
if (state.noExchangeFound) {
|
||||||
if (initialCurrency !== undefined) {
|
if (initialCurrency) {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<SubTitle>
|
<SubTitle>
|
||||||
|
35
packages/taler-wallet-webextension/static/font/import.css
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-italic-400.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-300.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-400.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-500.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(/static/font/roboto-normal-700.ttf) format('truetype');
|
||||||
|
}
|
@ -9,8 +9,8 @@
|
|||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
html {
|
html {
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
@ -27,8 +27,9 @@
|
|||||||
background-color: #f8faf7;
|
background-color: #f8faf7;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" type="text/css" href="/dist/popupEntryPoint.css" />
|
<link rel="stylesheet" type="text/css" href="/dist/popupEntryPoint.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/font/import.css" />
|
||||||
<link rel="icon" href="/static/img/icon.png" />
|
<link rel="icon" href="/static/img/icon.png" />
|
||||||
<script src="/dist/popupEntryPoint.js"></script>
|
<script src="/dist/popupEntryPoint.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="stylesheet" type="text/css" href="/dist/walletEntryPoint.css" />
|
<link rel="stylesheet" type="text/css" href="/dist/walletEntryPoint.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/font/import.css" />
|
||||||
<link rel="icon" href="/static/img/icon.png" />
|
<link rel="icon" href="/static/img/icon.png" />
|
||||||
<script src="/dist/walletEntryPoint.js"></script>
|
<script src="/dist/walletEntryPoint.js"></script>
|
||||||
<style>
|
<style>
|
||||||
|