summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/components')
-rw-r--r--packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx57
-rw-r--r--packages/taler-wallet-webextension/src/components/ExchangeToS.tsx51
-rw-r--r--packages/taler-wallet-webextension/src/components/styled/index.tsx198
3 files changed, 305 insertions, 1 deletions
diff --git a/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx
new file mode 100644
index 000000000..e596797cc
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/components/CheckboxOutlined.tsx
@@ -0,0 +1,57 @@
+/*
+ This file is part of GNU Taler
+ (C) 2019 Taler Systems SA
+
+ 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 { JSX } from "preact/jsx-runtime";
+import { Outlined, StyledCheckboxLabel } from "./styled/index";
+
+interface Props {
+ enabled: boolean;
+ onToggle: () => void;
+ label: string;
+ name: string;
+}
+
+
+const Tick = () => <svg
+ xmlns="http://www.w3.org/2000/svg"
+ viewBox="0 0 24 24"
+ aria-hidden="true"
+ focusable="false"
+ style={{ backgroundColor: 'green' }}
+>
+ <path
+ fill="none"
+ stroke="white"
+ stroke-width="3"
+ d="M1.73 12.91l6.37 6.37L22.79 4.59"
+ />
+</svg>
+
+export function CheckboxOutlined({ name, enabled, onToggle, label }: Props): JSX.Element {
+ return (
+ <Outlined>
+ <StyledCheckboxLabel onClick={onToggle}>
+ <span>
+ <input type="checkbox" name={name} checked={enabled} disabled={false} />
+ <div>
+ <Tick />
+ </div>
+ <label for={name}>{label}</label>
+ </span>
+ </StyledCheckboxLabel>
+ </Outlined>
+ );
+}
diff --git a/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx b/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx
new file mode 100644
index 000000000..7e029d474
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/components/ExchangeToS.tsx
@@ -0,0 +1,51 @@
+import { Fragment, VNode } from "preact"
+import { useState } from "preact/hooks"
+import { JSXInternal } from "preact/src/jsx"
+
+export function ExchangeXmlTos({ doc }: { doc: Document }) {
+ const termsNode = doc.querySelector('[ids=terms-of-service]')
+ if (!termsNode) {
+ return <div>not found</div>
+ }
+ return <Fragment>
+ {Array.from(termsNode.children).map(renderChild)}
+ </Fragment>
+}
+
+function renderChild(child: Element): VNode {
+ const children = Array.from(child.children)
+ switch (child.nodeName) {
+ case 'title': return <header>{child.textContent}</header>
+ case '#text': return <Fragment />
+ case 'paragraph': return <p>{child.textContent}</p>
+ case 'section': {
+ return <AnchorWithOpenState href={`#terms-${child.getAttribute('ids')}`}>
+ {children.map(renderChild)}
+ </AnchorWithOpenState>
+ }
+ case 'bullet_list': {
+ return <ul>{children.map(renderChild)}</ul>
+ }
+ case 'enumerated_list': {
+ return <ol>{children.map(renderChild)}</ol>
+ }
+ case 'list_item': {
+ return <li>{children.map(renderChild)}</li>
+ }
+ case 'block_quote': {
+ return <div>{children.map(renderChild)}</div>
+ }
+ default: return <div style={{ color: 'red', display: 'hidden' }}>unknown tag {child.nodeName} <a></a></div>
+ }
+}
+
+function AnchorWithOpenState(props: JSXInternal.HTMLAttributes<HTMLAnchorElement>) {
+ const [open, setOpen] = useState<boolean>(false)
+ function doClick(e: JSXInternal.TargetedMouseEvent<HTMLAnchorElement>) {
+ setOpen(!open);
+ e.stopPropagation();
+ e.preventDefault();
+ }
+ return <a data-open={JSON.stringify(open)} onClick={doClick} {...props} />
+}
+
diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx
index 553726de4..f4b8c088a 100644
--- a/packages/taler-wallet-webextension/src/components/styled/index.tsx
+++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx
@@ -12,6 +12,10 @@ export const PaymentStatus = styled.div<{ color: string }>`
`
export const WalletAction = styled.section`
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: center;
max-width: 50%;
margin: auto;
@@ -20,6 +24,9 @@ export const WalletAction = styled.section`
& h1:first-child {
margin-top: 0;
}
+ section {
+ margin-bottom: 2em;
+ }
`
export const WalletActionOld = styled.section`
border: solid 5px black;
@@ -211,6 +218,51 @@ export const Button = styled.button<{ upperCased?: boolean }>`
}
`;
+export const Link = styled.a<{ upperCased?: boolean }>`
+ display: inline-block;
+ zoom: 1;
+ line-height: normal;
+ white-space: nowrap;
+ vertical-align: middle;
+ text-align: center;
+ cursor: pointer;
+ user-select: none;
+ box-sizing: border-box;
+ text-transform: ${({ upperCased }) => upperCased ? 'uppercase' : 'none'};
+
+ font-family: inherit;
+ font-size: 100%;
+ padding: 0.5em 1em;
+ background-color: transparent;
+ text-decoration: none;
+
+ :focus {
+ outline: 0;
+ }
+
+ &:disabled {
+ border: none;
+ background-image: none;
+ /* csslint ignore:start */
+ filter: alpha(opacity=40);
+ /* csslint ignore:end */
+ opacity: 0.4;
+ cursor: not-allowed;
+ box-shadow: none;
+ pointer-events: none;
+ }
+
+ :hover {
+ text-decoration: underline;
+ /* filter: alpha(opacity=90);
+ background-image: linear-gradient(
+ transparent,
+ rgba(0, 0, 0, 0.05) 40%,
+ rgba(0, 0, 0, 0.1)
+ ); */
+ }
+`;
+
export const FontIcon = styled.div`
font-family: monospace;
font-size: x-large;
@@ -220,7 +272,7 @@ export const FontIcon = styled.div`
`
export const ButtonBox = styled(Button)`
padding: .5em;
- width: 2em;
+ width: fit-content;
height: 2em;
& > ${FontIcon} {
@@ -255,6 +307,9 @@ export const ButtonBoxPrimary = styled(ButtonBox)`
export const ButtonSuccess = styled(ButtonVariant)`
background-color: #388e3c;
`
+export const LinkSuccess = styled(Link)`
+ color: #388e3c;
+`
export const ButtonBoxSuccess = styled(ButtonBox)`
color: #388e3c;
border-color: #388e3c;
@@ -504,3 +559,144 @@ export const NiceSelect = styled.div`
display: none;
}
`
+
+export const Outlined = styled.div`
+ border: 2px solid #388e3c;
+ padding: 0.5em 1em;
+ width: fit-content;
+ border-radius: 2px;
+ color: #388e3c;
+`
+
+/* { width: "1.5em", height: "1.5em", verticalAlign: "middle" } */
+export const CheckboxSuccess = styled.input`
+ vertical-align: center;
+
+`
+
+export const TermsSection = styled.a`
+ border: 1px solid black;
+ border-radius: 5px;
+ padding: 1em;
+ margin-top: 2px;
+ margin-bottom: 2px;
+ text-decoration: none;
+ color: inherit;
+ flex-direction: column;
+
+ display: flex;
+ &[data-open="true"] {
+ display: flex;
+ }
+ &[data-open="false"] > *:not(:first-child) {
+ display: none;
+ }
+
+ header {
+ display: flex;
+ flex-direction: row;
+ font-weight: bold;
+ justify-content: space-between;
+ height: auto;
+ }
+
+ &[data-open="true"] header:after {
+ content: '\\2227';
+ }
+ &[data-open="false"] header:after {
+ content: '\\2228';
+ }
+`;
+
+export const TermsOfService = styled.div`
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+
+ & > header {
+ text-align: center;
+ font-size: 2em;
+ }
+
+ a {
+ border: 1px solid black;
+ border-radius: 5px;
+ padding: 1em;
+ margin-top: 2px;
+ margin-bottom: 2px;
+ text-decoration: none;
+ color: inherit;
+ flex-direction: column;
+
+ display: flex;
+ &[data-open="true"] {
+ display: flex;
+ }
+ &[data-open="false"] > *:not(:first-child) {
+ display: none;
+ }
+
+ header {
+ display: flex;
+ flex-direction: row;
+ font-weight: bold;
+ justify-content: space-between;
+ height: auto;
+ }
+
+ &[data-open="true"] header:after {
+ content: '\\2227';
+ }
+ &[data-open="false"] header:after {
+ content: '\\2228';
+ }
+ }
+
+`
+export const StyledCheckboxLabel = styled.div`
+ color: green;
+ text-transform: uppercase;
+ /* font-weight: bold; */
+ text-align: center;
+ span {
+
+ input {
+ display: none;
+ opacity: 0;
+ width: 1em;
+ height: 1em;
+ }
+ div {
+ display: inline-grid;
+ width: 1em;
+ height: 1em;
+ margin-right: 1em;
+ border-radius: 2px;
+ border: 2px solid currentColor;
+
+ svg {
+ transition: transform 0.1s ease-in 25ms;
+ transform: scale(0);
+ transform-origin: bottom left;
+ }
+ }
+ label {
+ padding: 0px;
+ font-size: small;
+ }
+ }
+
+ input:checked + div svg {
+ transform: scale(1);
+ }
+ input:disabled + div {
+ color: #959495;
+ };
+ input:disabled + div + label {
+ color: #959495;
+ };
+ input:focus + div + label {
+ box-shadow: 0 0 0 0.05em #fff, 0 0 0.15em 0.1em currentColor;
+ }
+
+` \ No newline at end of file