0.4.0 Release (#67)
* full width divider
* fix icon size and alignment
* remove size tokens in svgs
* fix width of qr code and button on anchor screen
* add list item hover state
* fix padding
* fix divider color
* fix for keyboard navigation
* clean up
* fix: allowing countdown timer to be used more than once
* update list item hover state
* add buttongroup component
* new generic styled body title and text components
* update title and subtitle in login flow
* add dark mode and fix typography font family
* fix list item columns to account for no icon lists
* fix clicking backdrop to dismiss
* Revert "fix clicking backdrop to dismiss"
This reverts commit ea14ded5b9.
* fix for dismissing dialog by clicking backdrop
* Passing new `getLogo` call to list for blockchains
* Containing variable size logos
* refactor listitem leading logo
* Added light/dark mode to wallets
* Updated to 0.4.0-RC2
* Upgraded to Session Kit + Wallet Plugins 0.4.0
* Renaming to `web-renderer`
* fix for tall chain icons
* update styles
* Updating Anchor plugin
* Better placeholder text
* Updating cleos plugin
* add check for valid image url
* add theme writable store with toggle component
* handle logo via method or property
* hide toggle in header
* fix default theme when no value in localstorage
---------
Co-authored-by: Dean Sallinen <dean@greymass.com>
Co-authored-by: dafuga <danielfugere28@gmail.com>
@@ -34,7 +34,7 @@ docs: $(SRC_FILES) node_modules
|
||||
./node_modules/.bin/typedoc \
|
||||
--excludeInternal \
|
||||
--excludePrivate --excludeProtected \
|
||||
--name "@wharfkit/web-ui-renderer" --includeVersion --readme none \
|
||||
--name "@wharfkit/web-renderer" --includeVersion --readme none \
|
||||
--out docs \
|
||||
src/index-module.ts
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "@wharfkit/web-ui-renderer",
|
||||
"name": "@wharfkit/web-renderer",
|
||||
"type": "module",
|
||||
"version": "0.3.7",
|
||||
"description": "",
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "lib/web-ui-renderer.js",
|
||||
"module": "lib/web-ui-renderer.m.js",
|
||||
"types": "lib/web-ui-renderer.d.ts",
|
||||
"unpkg": "lib/web-ui-renderer.bundle.js",
|
||||
"main": "lib/web-renderer.js",
|
||||
"module": "lib/web-renderer.m.js",
|
||||
"types": "lib/web-renderer.d.ts",
|
||||
"unpkg": "lib/web-renderer.bundle.js",
|
||||
"scripts": {
|
||||
"build": "rollup -c --bundleConfigAsCjs",
|
||||
"build-test": "rollup -c test/rollup.config.js --bundleConfigAsCjs",
|
||||
@@ -21,15 +21,15 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/@wharfkit/web-ui-renderer.git"
|
||||
"url": "git+https://github.com/@wharfkit/web-renderer.git"
|
||||
},
|
||||
"authors": [
|
||||
"Aaron Cox <aaron@greymass.com>"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/@wharfkit/web-ui-renderer/issues"
|
||||
"url": "https://github.com/@wharfkit/web-renderer/issues"
|
||||
},
|
||||
"homepage": "https://github.com/@wharfkit/web-ui-renderer",
|
||||
"homepage": "https://github.com/@wharfkit/web-renderer",
|
||||
"files": [
|
||||
"lib/*",
|
||||
"src/*"
|
||||
@@ -39,7 +39,7 @@
|
||||
"crypto": false
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@wharfkit/session": "^0.3.2"
|
||||
"@wharfkit/session": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
@@ -63,17 +63,17 @@
|
||||
"@tsconfig/svelte": "^3.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
||||
"@typescript-eslint/parser": "^5.49.0",
|
||||
"@wharfkit/session": "^0.3.3",
|
||||
"@wharfkit/session": "^0.4.0",
|
||||
"@wharfkit/transact-plugin-autocorrect": "^0.3.4",
|
||||
"@wharfkit/transact-plugin-cosigner": "^0.3.4",
|
||||
"@wharfkit/transact-plugin-explorerlink": "^0.3.0",
|
||||
"@wharfkit/transact-plugin-mock": "^0.3.0",
|
||||
"@wharfkit/transact-plugin-resource-provider": "^0.3.0",
|
||||
"@wharfkit/wallet-plugin-anchor": "^0.3.4",
|
||||
"@wharfkit/wallet-plugin-cleos": "^0.3.1",
|
||||
"@wharfkit/wallet-plugin-cloudwallet": "^0.3.2",
|
||||
"@wharfkit/wallet-plugin-mock": "^0.3.0",
|
||||
"@wharfkit/wallet-plugin-privatekey": "^0.3.0",
|
||||
"@wharfkit/wallet-plugin-anchor": "^0.4.1",
|
||||
"@wharfkit/wallet-plugin-cleos": "^0.4.1",
|
||||
"@wharfkit/wallet-plugin-cloudwallet": "^0.4.0",
|
||||
"@wharfkit/wallet-plugin-mock": "^0.4.0",
|
||||
"@wharfkit/wallet-plugin-privatekey": "^0.4.0",
|
||||
"core-js": "^3.27.2",
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
},
|
||||
"title": "Login",
|
||||
"subtitle": "Please login to continue",
|
||||
"title-app": "Login to {{appName}}"
|
||||
"title-app": "{{appName}}"
|
||||
},
|
||||
"transact": {
|
||||
"title": "Transact",
|
||||
"subtitle": " ",
|
||||
"processing": "Doing transact stuffs - cool animation!",
|
||||
"processing": "Processing transaction...",
|
||||
"signing": "Signing transaction",
|
||||
"signed": "Transaction signed",
|
||||
"broadcasting": "Broadcasting transaction",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"transact": {
|
||||
"title": "거래하다",
|
||||
"subtitle": " ",
|
||||
"processing": "물건을 거래하는 것 - 멋진 애니메이션!",
|
||||
"processing": "Processing transaction...",
|
||||
"signing": "서명 트랜잭션",
|
||||
"signed": "트랜잭션 서명",
|
||||
"broadcasting": "방송 거래",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"transact": {
|
||||
"title": "办理",
|
||||
"subtitle": " ",
|
||||
"processing": "做交易的东西 - 很酷的动画!",
|
||||
"processing": "Processing transaction...",
|
||||
"signing": "签署交易",
|
||||
"signed": "交易已签署",
|
||||
"broadcasting": "广播交易",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"transact": {
|
||||
"title": "辦理",
|
||||
"subtitle": "",
|
||||
"processing": "做交易的東西 - 很酷的動畫!",
|
||||
"processing": "Processing transaction...",
|
||||
"signing": "簽署交易",
|
||||
"signed": "交易已簽署",
|
||||
"broadcasting": "廣播交易",
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
export function isBase64Image(str: string | undefined): boolean {
|
||||
if (!str) return false
|
||||
const regex = /^data:image\/(jpeg|png|gif|bmp|svg\+xml);base64,([^\s]*)$/
|
||||
return regex.test(str)
|
||||
import type {ChainDefinition, WalletPluginMetadata} from '@wharfkit/session'
|
||||
import type {ColorScheme} from '../types'
|
||||
import {colorScheme} from '../ui/state'
|
||||
import {get} from 'svelte/store'
|
||||
|
||||
export function isUrlImage(str: string) {
|
||||
return str.startsWith('http://') || str.startsWith('https://')
|
||||
}
|
||||
|
||||
export function isBase64Image(str: string) {
|
||||
return str.startsWith('data:image/')
|
||||
}
|
||||
|
||||
// Returns a themed logo based on the wallet metadata and the current color scheme preference
|
||||
export function getThemedLogo(
|
||||
metadata: WalletPluginMetadata | ChainDefinition
|
||||
): string | undefined {
|
||||
const {name, logo} = metadata
|
||||
const theme = get(colorScheme) as ColorScheme
|
||||
const oppositeColorScheme = theme === 'light' ? 'dark' : 'light'
|
||||
|
||||
if (!logo) {
|
||||
if ('getLogo' in metadata) {
|
||||
return metadata.getLogo()?.[theme] ?? metadata.getLogo()?.[oppositeColorScheme]
|
||||
}
|
||||
console.warn(`${name} does not have a logo.`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!isUrlImage(logo.toString()) && !isBase64Image(logo.toString())) {
|
||||
console.warn(`${name} ${theme} logo is not a supported image format.`)
|
||||
return
|
||||
}
|
||||
|
||||
return logo[theme] ?? logo[oppositeColorScheme]
|
||||
}
|
||||
|
||||
export function getStoredColorScheme(): ColorScheme | null {
|
||||
return localStorage.getItem('colorScheme') as ColorScheme
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<script lang="ts">
|
||||
import {Meta, Story} from '@storybook/addon-svelte-csf'
|
||||
import Asset from '../ui/components/Asset.svelte'
|
||||
</script>
|
||||
|
||||
<Meta title="Components/Asset" component={Asset} />
|
||||
|
||||
<Story name="Default">
|
||||
<Asset data={{label: 'cost of CPU/NET', value: '0.03 EOS'}} />
|
||||
</Story>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
import {Meta, Story} from '@storybook/addon-svelte-csf'
|
||||
import ButtonGroup from '../ui/components/ButtonGroup.svelte'
|
||||
import Button from '../ui/components/Button.svelte'
|
||||
</script>
|
||||
|
||||
<Meta title="Components/ButtonGroup" component={ButtonGroup} />
|
||||
|
||||
<Story name="Default">
|
||||
<div>
|
||||
<ButtonGroup>
|
||||
<Button data={{variant: 'outlined', label: 'Decline', icon: 'close'}} />
|
||||
<Button data={{variant: 'primary', label: 'Accept', icon: 'check'}} />
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<style>
|
||||
div {
|
||||
max-width: 400px;
|
||||
margin-inline: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -6,11 +6,11 @@ Globals and custom properties
|
||||
*/
|
||||
|
||||
/******************
|
||||
Default Theme
|
||||
Light Theme
|
||||
******************/
|
||||
|
||||
:host dialog,
|
||||
:root {
|
||||
@mixin light-theme {
|
||||
color-scheme: light;
|
||||
--body-background-color: white;
|
||||
--body-text-color: var(--color-primary-700);
|
||||
--body-text-color-variant: var(--color-neutral-700);
|
||||
@@ -54,54 +54,86 @@ Globals and custom properties
|
||||
--checkbox-fill: var(--reef-turquoise);
|
||||
|
||||
--error-color: var(--color-error-1);
|
||||
|
||||
--list-item-background-color-hover: var(--color-custom-9);
|
||||
--list-item-text-color-hover: var(--color-secondary-500);
|
||||
--list-divider-color: #00000010;
|
||||
|
||||
--text-area-background: var(--swell-mist);
|
||||
--text-area-text-color: #242424;
|
||||
}
|
||||
|
||||
/******************
|
||||
Dark Theme
|
||||
******************/
|
||||
@mixin dark-theme {
|
||||
color-scheme: dark;
|
||||
--body-background-color: var(--color-primary-700);
|
||||
--body-text-color: white;
|
||||
--body-text-color-variant: var(--color-neutral-300);
|
||||
|
||||
--header-background-color: white;
|
||||
--header-text-color: var(--color-primary-700);
|
||||
--header-button-background: var(--header-background-color);
|
||||
--header-button-outline: var(--seafoam-mint);
|
||||
|
||||
--button-text-color: var(--body-text-color);
|
||||
--button-text-color-active: var(--reef-turquoise);
|
||||
--button-outline-active: inset 0 0 0 2px var(--reef-turquoise);
|
||||
|
||||
--button-primary-background: var(--color-secondary-500);
|
||||
--button-primary-background-hover: var(--color-secondary-500);
|
||||
--button-primary-background-active: var(--color-custom-2);
|
||||
--button-primary-outline-hover: inset 0 0 0 1px white;
|
||||
|
||||
--button-secondary-background: var(--color-primary-800);
|
||||
--button-secondary-background-hover: var(--color-primary-800);
|
||||
--button-secondary-background-active: var(--color-primary-900);
|
||||
--button-secondary-outline-hover: inset 0 0 0 1px #ffffff30;
|
||||
|
||||
--button-outlined-background-active: var(--color-primary-900);
|
||||
--button-outlined-outline: inset 0 0 0 1px #00000030;
|
||||
--button-outlined-outline-hover: inset 0 0 0 1px #ffffff30;
|
||||
|
||||
--input-placeholder-color: #ffffff75;
|
||||
--input-background-focus: var(--color-custom-4);
|
||||
--input-border-color: #ffffff30;
|
||||
--input-border-color-hover: var(--color-custom-6);
|
||||
--input-border-color-focus: var(--reef-turquoise);
|
||||
|
||||
--qr-border-color: rgba(0 0 0 / 0.2);
|
||||
|
||||
--checkbox-stroke: var(--reef-turquoise);
|
||||
--checkbox-fill: var(--color-custom-3);
|
||||
|
||||
--error-color: var(--color-error-3);
|
||||
|
||||
--list-item-background-color-hover: var(--color-custom-8);
|
||||
--list-item-text-color-hover: var(--color-secondary-400);
|
||||
--list-divider-color: #ffffff10;
|
||||
|
||||
--text-area-background: var(--color-primary-900);
|
||||
--text-area-text-color: #ffffff;
|
||||
}
|
||||
|
||||
// Default theme, no user or system preference
|
||||
:host dialog,
|
||||
:root {
|
||||
@include light-theme;
|
||||
}
|
||||
|
||||
// No system preference, User prefers dark theme
|
||||
:host dialog[data-theme='dark'] {
|
||||
@include dark-theme;
|
||||
}
|
||||
|
||||
// System dark mode enables dark theme
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:host dialog,
|
||||
:root {
|
||||
--body-background-color: var(--color-primary-700);
|
||||
--body-text-color: white;
|
||||
--body-text-color-variant: var(--color-neutral-300);
|
||||
@include dark-theme;
|
||||
}
|
||||
|
||||
--header-background-color: white;
|
||||
--header-text-color: var(--color-primary-700);
|
||||
--header-button-background: var(--header-background-color);
|
||||
--header-button-outline: var(--seafoam-mint);
|
||||
|
||||
--button-text-color: var(--body-text-color);
|
||||
--button-text-color-active: var(--reef-turquoise);
|
||||
--button-outline-active: inset 0 0 0 2px var(--reef-turquoise);
|
||||
|
||||
--button-primary-background: var(--color-secondary-500);
|
||||
--button-primary-background-hover: var(--color-secondary-500);
|
||||
--button-primary-background-active: var(--color-custom-2);
|
||||
--button-primary-outline-hover: inset 0 0 0 1px white;
|
||||
|
||||
--button-secondary-background: var(--color-primary-800);
|
||||
--button-secondary-background-hover: var(--color-primary-800);
|
||||
--button-secondary-background-active: var(--color-primary-900);
|
||||
--button-secondary-outline-hover: inset 0 0 0 1px #ffffff30;
|
||||
|
||||
--button-outlined-background-active: var(--color-primary-900);
|
||||
--button-outlined-outline: inset 0 0 0 1px #00000030;
|
||||
--button-outlined-outline-hover: inset 0 0 0 1px #ffffff30;
|
||||
|
||||
--input-placeholder-color: #ffffff75;
|
||||
--input-background-focus: var(--color-custom-4);
|
||||
--input-border-color: #ffffff30;
|
||||
--input-border-color-hover: var(--color-custom-6);
|
||||
--input-border-color-focus: var(--reef-turquoise);
|
||||
|
||||
--qr-border-color: rgba(0 0 0 / 0.2);
|
||||
|
||||
--checkbox-stroke: var(--reef-turquoise);
|
||||
--checkbox-fill: var(--color-custom-3);
|
||||
|
||||
--error-color: var(--color-error-3);
|
||||
// User prefers light theme in system dark mode
|
||||
:host dialog[data-theme='light'] {
|
||||
@include light-theme;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +204,9 @@ Globals and custom properties
|
||||
--color-custom-4: #3d435a;
|
||||
--color-custom-5: #8ec2b4;
|
||||
--color-custom-6: #777b8b;
|
||||
--color-custom-7: #35ccae10;
|
||||
--color-custom-8: #575c6e;
|
||||
--color-custom-9: #f4f5f7;
|
||||
--color-error-1: #cd3939;
|
||||
--color-error-2: #ff5454;
|
||||
--color-error-3: #ffacac;
|
||||
@@ -179,7 +214,8 @@ Globals and custom properties
|
||||
/******************
|
||||
Typography
|
||||
******************/
|
||||
font-family: system-ui, ui-sans-serif;
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
|
||||
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
--measure: 35ch;
|
||||
|
||||
/* Font Sizing - Fixed */
|
||||
@@ -192,11 +228,6 @@ Globals and custom properties
|
||||
/* Font Sizing - Fluid */
|
||||
/* @link https://utopia.fyi/type/calculator?c=320,12,1.125,1240,16,1.25,3,0,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
|
||||
|
||||
/* --fs-0: clamp(0.75rem, calc(0.66rem + 0.43vw), 1rem);
|
||||
--fs-1: clamp(0.84rem, calc(0.7rem + 0.71vw), 1.25rem);
|
||||
--fs-2: clamp(0.95rem, calc(0.74rem + 1.07vw), 1.56rem);
|
||||
--fs-3: clamp(1.07rem, calc(0.76rem + 1.54vw), 1.95rem); */
|
||||
|
||||
/******************
|
||||
Size and Spacing
|
||||
******************/
|
||||
@@ -223,92 +254,6 @@ Globals and custom properties
|
||||
/* Spacing Scale - Fluid */
|
||||
/* @link https://utopia.fyi/space/calculator?c=320,12,1.2,1240,16,1.25,3,0,&s=0.75|0.5|0.25,1.5|2|3|4|6|10|16|25|30|40,s-l&g=s,l,xl,12 */
|
||||
|
||||
/* Space 3xs: 3px → 4px */
|
||||
/* --space-3xs: clamp(0.19rem, calc(0.17rem + 0.11vw), 0.25rem); */
|
||||
|
||||
/* Space 2xs: 6px → 8px */
|
||||
/* --space-2xs: clamp(0.38rem, calc(0.33rem + 0.22vw), 0.5rem); */
|
||||
|
||||
/* Space xs: 9px → 12px */
|
||||
/* --space-xs: clamp(0.56rem, calc(0.5rem + 0.33vw), 0.75rem); */
|
||||
|
||||
/* Space s: 12px → 16px */
|
||||
/* --space-s: clamp(0.75rem, calc(0.66rem + 0.43vw), 1rem); */
|
||||
|
||||
/* Space m: 18px → 24px */
|
||||
/* --space-m: clamp(1.13rem, calc(0.99rem + 0.65vw), 1.5rem); */
|
||||
|
||||
/* Space l: 24px → 32px */
|
||||
/* --space-l: clamp(1.5rem, calc(1.33rem + 0.87vw), 2rem); */
|
||||
|
||||
/* Space xl: 36px → 48px */
|
||||
/* --space-xl: clamp(2.25rem, calc(1.99rem + 1.3vw), 3rem); */
|
||||
|
||||
/* Space 2xl: 48px → 64px */
|
||||
/* --space-2xl: clamp(3rem, calc(2.65rem + 1.74vw), 4rem); */
|
||||
|
||||
/* Space 3xl: 72px → 96px */
|
||||
/* --space-3xl: clamp(4.5rem, calc(3.98rem + 2.61vw), 6rem); */
|
||||
|
||||
/* Space 4xl: 120px → 160px */
|
||||
/* --space-4xl: clamp(7.5rem, calc(6.63rem + 4.35vw), 10rem); */
|
||||
|
||||
/* Space 5xl: 192px → 256px */
|
||||
/* --space-5xl: clamp(12rem, calc(10.61rem + 6.96vw), 16rem); */
|
||||
|
||||
/* Space 6xl: 300px → 400px */
|
||||
/* --space-6xl: clamp(18.75rem, calc(16.58rem + 10.87vw), 25rem); */
|
||||
|
||||
/* Space 7xl: 360px → 480px */
|
||||
/* --space-7xl: clamp(22.5rem, calc(19.89rem + 13.04vw), 30rem); */
|
||||
|
||||
/* Space 8xl: 480px → 640px */
|
||||
/* --space-8xl: clamp(30rem, calc(26.52rem + 17.39vw), 40rem); */
|
||||
|
||||
/* One-up pairs */
|
||||
/* Space 3xs-2xs: 3px → 8px */
|
||||
/* --space-3xs-2xs: clamp(0.19rem, calc(0.08rem + 0.54vw), 0.5rem); */
|
||||
|
||||
/* Space 2xs-xs: 6px → 12px */
|
||||
/* --space-2xs-xs: clamp(0.38rem, calc(0.24rem + 0.65vw), 0.75rem); */
|
||||
|
||||
/* Space xs-s: 9px → 16px */
|
||||
/* --space-xs-s: clamp(0.56rem, calc(0.41rem + 0.76vw), 1rem); */
|
||||
|
||||
/* Space s-m: 12px → 24px */
|
||||
/* --space-s-m: clamp(0.75rem, calc(0.49rem + 1.3vw), 1.5rem); */
|
||||
|
||||
/* Space m-l: 18px → 32px */
|
||||
/* --space-m-l: clamp(1.13rem, calc(0.82rem + 1.52vw), 2rem); */
|
||||
|
||||
/* Space l-xl: 24px → 48px */
|
||||
/* --space-l-xl: clamp(1.5rem, calc(0.98rem + 2.61vw), 3rem); */
|
||||
|
||||
/* Space xl-2xl: 36px → 64px */
|
||||
/* --space-xl-2xl: clamp(2.25rem, calc(1.64rem + 3.04vw), 4rem); */
|
||||
|
||||
/* Space 2xl-3xl: 48px → 96px */
|
||||
/* --space-2xl-3xl: clamp(3rem, calc(1.96rem + 5.22vw), 6rem); */
|
||||
|
||||
/* Space 3xl-4xl: 72px → 160px */
|
||||
/* --space-3xl-4xl: clamp(4.5rem, calc(2.59rem + 9.57vw), 10rem); */
|
||||
|
||||
/* Space 4xl-5xl: 120px → 256px */
|
||||
/* --space-4xl-5xl: clamp(7.5rem, calc(4.54rem + 14.78vw), 16rem); */
|
||||
|
||||
/* Space 5xl-6xl: 192px → 400px */
|
||||
/* --space-5xl-6xl: clamp(12rem, calc(7.48rem + 22.61vw), 25rem); */
|
||||
|
||||
/* Space 6xl-7xl: 300px → 480px */
|
||||
/* --space-6xl-7xl: clamp(18.75rem, calc(14.84rem + 19.57vw), 30rem); */
|
||||
|
||||
/* Space 7xl-8xl: 360px → 640px */
|
||||
/* --space-7xl-8xl: clamp(22.5rem, calc(16.41rem + 30.43vw), 40rem); */
|
||||
|
||||
/* Custom pairs */
|
||||
/* Space s-l: 12px → 32px */
|
||||
/* --space-s-l: clamp(0.75rem, calc(0.32rem + 2.17vw), 2rem); */
|
||||
|
||||
/* Other sizes */
|
||||
--border-radius-outer: 24px;
|
||||
--border-radius-inner: 12px;
|
||||
@@ -1,3 +1,5 @@
|
||||
export type ColorScheme = 'light' | 'dark'
|
||||
|
||||
export type Space =
|
||||
| '--space-3xs'
|
||||
| '--space-2xs'
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
const loginContextUnsubscribe = loginContext.subscribe((currentContext) => {
|
||||
if (currentContext) {
|
||||
// If an appName is specified, set the title to it.
|
||||
$props.title = $t('login.title-app', {
|
||||
$props.subtitle = $t('login.title-app', {
|
||||
appName: currentContext.appName,
|
||||
default: 'Login to {{appName}}',
|
||||
})
|
||||
@@ -116,7 +116,6 @@
|
||||
[loginResponse, walletPlugin],
|
||||
([$currentResponse, $currentWalletPlugin]) => {
|
||||
if (!$currentWalletPlugin) {
|
||||
$props.subtitle = $t('login.select.wallet', {default: 'Select a Wallet'})
|
||||
return Steps.selectWallet
|
||||
}
|
||||
|
||||
@@ -134,13 +133,10 @@
|
||||
$loginResponse.chainId = $loginContext?.chain.id
|
||||
return Steps.selectPermission
|
||||
} else if (!$currentResponse.chainId && requiresChainSelect) {
|
||||
$props.subtitle = $t('login.select.blockchain', {default: 'Select a Blockchain'})
|
||||
return Steps.selectChain
|
||||
} else if (!$currentResponse.permissionLevel && requiresPermissionSelect) {
|
||||
$props.subtitle = $t('login.select.account', {default: 'Select an Account'})
|
||||
return Steps.selectPermission
|
||||
} else if (!$currentResponse.permissionLevel && requiresPermissionEntry) {
|
||||
$props.subtitle = $t('login.enter.account', {default: 'Enter account name'})
|
||||
return Steps.enterPermission
|
||||
}
|
||||
|
||||
@@ -205,11 +201,17 @@
|
||||
on:select={selectWallet}
|
||||
on:cancel={cancel}
|
||||
wallets={$loginContext.walletPlugins}
|
||||
title={$t('login.select.wallet', {default: 'Select a Wallet'})}
|
||||
/>
|
||||
</Transition>
|
||||
{:else if $step === Steps.selectChain && $chains}
|
||||
<Transition direction={transitionDirection}>
|
||||
<Blockchain on:select={selectChain} on:cancel={unselectWallet} chains={$chains} />
|
||||
<Blockchain
|
||||
on:select={selectChain}
|
||||
on:cancel={unselectWallet}
|
||||
chains={$chains}
|
||||
title={$t('login.select.blockchain', {default: 'Select a Blockchain'})}
|
||||
/>
|
||||
</Transition>
|
||||
{:else if $step === Steps.enterPermission && $client && $walletPlugin}
|
||||
<Transition direction={transitionDirection}>
|
||||
@@ -218,6 +220,7 @@
|
||||
on:cancel={unselectChain}
|
||||
client={$client}
|
||||
walletPlugin={$walletPlugin}
|
||||
title={$t('login.enter.account', {default: 'Enter account name'})}
|
||||
/>
|
||||
</Transition>
|
||||
{:else if $step === Steps.selectPermission && $client && $walletPlugin}
|
||||
@@ -227,6 +230,7 @@
|
||||
on:cancel={unselectChain}
|
||||
client={$client}
|
||||
walletPlugin={$walletPlugin}
|
||||
title={$t('login.select.account', {default: 'Select an Account'})}
|
||||
/>
|
||||
</Transition>
|
||||
{:else}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
import Textarea from './components/Textarea.svelte'
|
||||
|
||||
import {prompt} from './state'
|
||||
import BodyTitle from './components/BodyTitle.svelte'
|
||||
import BodyText from './components/BodyText.svelte'
|
||||
|
||||
interface UIComponent {
|
||||
component: ComponentType<SvelteComponentTyped>
|
||||
@@ -112,47 +114,28 @@
|
||||
|
||||
<div>
|
||||
<div class="text">
|
||||
<h3>{$prompt?.args.title}</h3>
|
||||
<p>{$prompt?.args.body}</p>
|
||||
<BodyTitle>{$prompt?.args.title}</BodyTitle>
|
||||
<BodyText>{$prompt?.args.body}</BodyText>
|
||||
</div>
|
||||
{#each $elements as component}
|
||||
<div>
|
||||
<svelte:component
|
||||
this={component.component}
|
||||
on:complete={() => dispatch('complete')}
|
||||
on:cancel={() => dispatch('cancel')}
|
||||
{...component.props}
|
||||
/>
|
||||
</div>
|
||||
<svelte:component
|
||||
this={component.component}
|
||||
on:complete={() => dispatch('complete')}
|
||||
on:cancel={() => dispatch('cancel')}
|
||||
{...component.props}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:is(h3, p) {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: var(--body-text-color);
|
||||
font-size: var(--fs-2);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
p {
|
||||
color: var(--body-text-color-variant);
|
||||
font-size: var(--fs-1);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--space-m);
|
||||
gap: var(--space-l);
|
||||
}
|
||||
|
||||
.text {
|
||||
gap: var(--space-2xs);
|
||||
gap: var(--space-s);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script lang="ts">
|
||||
import {createEventDispatcher, getContext} from 'svelte'
|
||||
import {i18nType} from 'src/lib/translations'
|
||||
import type {i18nType} from 'src/lib/translations'
|
||||
import Button from './Button.svelte'
|
||||
import ButtonGroup from './ButtonGroup.svelte'
|
||||
|
||||
const {t} = getContext<i18nType>('i18n')
|
||||
|
||||
@@ -11,18 +12,22 @@
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<Button
|
||||
data={{
|
||||
variant: 'primary',
|
||||
label: $t('accept', {default: 'Accept'}),
|
||||
onClick: () => dispatch('complete'),
|
||||
}}
|
||||
/>
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
data={{
|
||||
variant: 'outlined',
|
||||
label: $t('decline', {default: 'Decline'}),
|
||||
onClick: () => dispatch('cancel'),
|
||||
icon: 'close',
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
data={{
|
||||
variant: 'secondary',
|
||||
label: $t('decline', {default: 'Decline'}),
|
||||
onClick: () => dispatch('cancel'),
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
data={{
|
||||
variant: 'primary',
|
||||
label: $t('accept', {default: 'Accept'}),
|
||||
onClick: () => dispatch('complete'),
|
||||
icon: 'check',
|
||||
}}
|
||||
/>
|
||||
</ButtonGroup>
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
<style lang="scss">
|
||||
.asset {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<p><slot /></p>
|
||||
|
||||
<style>
|
||||
p {
|
||||
color: var(--body-text-color-variant);
|
||||
font-size: var(--fs-1);
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,11 @@
|
||||
<h3><slot /></h3>
|
||||
|
||||
<style>
|
||||
h3 {
|
||||
color: var(--body-text-color);
|
||||
font-size: var(--fs-2);
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,12 @@
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
</style>
|
||||
@@ -6,15 +6,20 @@
|
||||
let remaining
|
||||
let timer
|
||||
|
||||
onMount(() => {
|
||||
$: {
|
||||
if (timer) {
|
||||
clearInterval(timer)
|
||||
}
|
||||
|
||||
deadline = new Date(data)
|
||||
timer = setInterval(() => {
|
||||
remaining = deadline - Date.now()
|
||||
|
||||
if (remaining <= 0) {
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, 200)
|
||||
})
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
if (timer) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import HeaderButton from './HeaderButton.svelte'
|
||||
import {backAction} from '../state'
|
||||
import {fade} from 'svelte/transition'
|
||||
import ThemeToggle from './ThemeToggle.svelte'
|
||||
|
||||
export let title: string
|
||||
export let subtitle: string | undefined
|
||||
@@ -24,10 +25,12 @@
|
||||
</div>
|
||||
<div class="slot center">
|
||||
<slot name="center">
|
||||
<h2>{title}</h2>
|
||||
{#if subtitle}
|
||||
<p>{subtitle}</p>
|
||||
{/if}
|
||||
<ThemeToggle>
|
||||
<h2>{title}</h2>
|
||||
{#if subtitle}
|
||||
<p>{subtitle}</p>
|
||||
{/if}
|
||||
</ThemeToggle>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="slot right">
|
||||
@@ -65,6 +68,7 @@
|
||||
}
|
||||
|
||||
:is(h2, p) {
|
||||
color: var(--header-text-color);
|
||||
margin: 0;
|
||||
line-height: 1.1em;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
import Icon from './Icon.svelte'
|
||||
export let onClick
|
||||
export let icon: ComponentProps<Icon>['name']
|
||||
const onKeydown = onClick
|
||||
</script>
|
||||
|
||||
<button on:click={onClick} on:keydown={onKeydown}>
|
||||
<button on:click={onClick}>
|
||||
<span class="background" />
|
||||
<Icon name={icon} />
|
||||
<span class="label visually-hidden">{icon}</span>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
let {button = true, href, label, icon} = data
|
||||
</script>
|
||||
|
||||
<a class:button {href} target="_blank" rel="noreferrer">
|
||||
<a class:button class="outlined" {href} target="_blank" rel="noreferrer">
|
||||
{#if icon}
|
||||
<Icon name={icon} />
|
||||
{/if}
|
||||
@@ -20,4 +20,8 @@
|
||||
|
||||
<style lang="scss">
|
||||
@use '../../styles/buttonStyles.css';
|
||||
|
||||
a {
|
||||
align-self: stretch;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,22 +6,30 @@
|
||||
export let onClick
|
||||
export let leadingIcon: ComponentProps<Icon>['name'] | undefined = undefined
|
||||
export let trailingIcon: ComponentProps<Icon>['name'] | undefined = 'chevron-right'
|
||||
export let logo: string | undefined = undefined
|
||||
</script>
|
||||
|
||||
<li>
|
||||
<button on:click={onClick}>
|
||||
{#if leadingIcon}
|
||||
<Icon name={leadingIcon} />
|
||||
{/if}
|
||||
|
||||
<slot name="logo" />
|
||||
|
||||
<div>
|
||||
<span>{label}</span>
|
||||
{#if trailingIcon}
|
||||
<Icon name={trailingIcon} />
|
||||
<div class="leading">
|
||||
{#if logo}
|
||||
<div class="logo">
|
||||
<img src={logo} alt={`${label} logo`} />
|
||||
</div>
|
||||
{:else if leadingIcon}
|
||||
<div class="icon">
|
||||
<Icon name={leadingIcon} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<span>{label}</span>
|
||||
|
||||
{#if trailingIcon}
|
||||
<div class="trailing">
|
||||
<Icon name={trailingIcon} />
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
</li>
|
||||
|
||||
@@ -30,34 +38,53 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
li:not(:last-child) button div {
|
||||
border-bottom: 1px solid var(--color-neutral-200);
|
||||
li:not(:last-child) button {
|
||||
border-bottom: 1px solid var(--list-divider-color);
|
||||
}
|
||||
|
||||
li button {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: var(--space-l);
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--body-text-color);
|
||||
font-size: var(--fs-1);
|
||||
font-weight: 500;
|
||||
padding-block: var(--space-s);
|
||||
}
|
||||
|
||||
div {
|
||||
padding-block: var(--space-s);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.leading > * {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
inline-size: var(--space-xl);
|
||||
}
|
||||
|
||||
.leading img {
|
||||
max-inline-size: 30px;
|
||||
max-block-size: 30px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.trailing {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
li button:hover {
|
||||
background: var(--list-item-background-color-hover);
|
||||
|
||||
& .trailing {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
flex: 1;
|
||||
text-align: start;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding-inline-start: var(--space-xs);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Header from './Header.svelte'
|
||||
import {active, cancelablePromises, resetState, props} from '../state'
|
||||
import {active, cancelablePromises, resetState, props, colorScheme} from '../state'
|
||||
import {onDestroy} from 'svelte'
|
||||
|
||||
let dialog: HTMLDialogElement
|
||||
@@ -35,7 +35,7 @@
|
||||
event.clientY <= rect.top + rect.height &&
|
||||
rect.left <= event.clientX &&
|
||||
event.clientX <= rect.left + rect.width
|
||||
if (!isInDialog) {
|
||||
if (event.target === dialog && !isInDialog) {
|
||||
cancelRequest()
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,7 @@
|
||||
bind:this={dialog}
|
||||
on:click|capture|nonpassive={backgroundClose}
|
||||
on:keyup|preventDefault|capture|nonpassive={escapeClose}
|
||||
data-theme={$colorScheme}
|
||||
>
|
||||
<Header title={$props.title} subtitle={$props.subtitle} on:cancel={cancelRequest} />
|
||||
<div class="modal-content">
|
||||
@@ -60,11 +61,10 @@
|
||||
</dialog>
|
||||
|
||||
<style lang="scss">
|
||||
@use '../../styles/variables.css';
|
||||
@import '../../styles/variables';
|
||||
|
||||
dialog {
|
||||
--margin-top: var(--space-xl);
|
||||
// font-family: system-ui, ui-sans-serif;
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
margin-bottom: 0;
|
||||
|
||||
@@ -30,25 +30,29 @@
|
||||
<style>
|
||||
div {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: grid;
|
||||
background: var(--body-background-color);
|
||||
border-radius: var(--space-s);
|
||||
padding: var(--space-s);
|
||||
border: 2px solid var(--qr-border-color);
|
||||
border: 1px solid var(--qr-border-color);
|
||||
aspect-ratio: 1;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
span {
|
||||
background: white;
|
||||
padding: var(--space-xs);
|
||||
padding-bottom: var(--space-2xs);
|
||||
border-radius: var(--space-2xs);
|
||||
transition: scale 200ms ease;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
button {
|
||||
span :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* button {
|
||||
position: absolute;
|
||||
bottom: calc(var(--space-m) * -1);
|
||||
border: none;
|
||||
@@ -67,5 +71,5 @@
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
} */
|
||||
</style>
|
||||
|
||||
@@ -13,16 +13,19 @@
|
||||
<style lang="scss">
|
||||
div {
|
||||
display: flex;
|
||||
background-color: var(--swell-mist);
|
||||
background-color: var(--text-area-background);
|
||||
padding: var(--space-m);
|
||||
border-radius: var(--border-radius-inner);
|
||||
}
|
||||
textarea {
|
||||
flex: 1;
|
||||
color: var(--wharf-blue);
|
||||
background-color: var(--swell-mist);
|
||||
color: var(--text-area-text-color);
|
||||
background-color: var(--text-area-background);
|
||||
border: none;
|
||||
font-size: var(--fs-0);
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
resize: none;
|
||||
opacity: 0.75;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<script>
|
||||
import {onMount} from 'svelte'
|
||||
import {colorScheme} from '../state'
|
||||
import {getStoredColorScheme} from '../../lib/utils'
|
||||
|
||||
function toggleColorScheme() {
|
||||
colorScheme.update((current) => (current === 'light' ? 'dark' : 'light'))
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
// initialize the color scheme based on existing user preference otherwise system default
|
||||
if (window.matchMedia) {
|
||||
const mql = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
colorScheme.set(getStoredColorScheme() ?? (mql.matches ? 'dark' : 'light'))
|
||||
mql.addEventListener('change', () => {
|
||||
colorScheme.set(mql.matches ? 'dark' : 'light')
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<button on:click={toggleColorScheme}>
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
<style lang="scss">
|
||||
button {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -3,6 +3,6 @@
|
||||
export let direction: number = 0
|
||||
</script>
|
||||
|
||||
<div in:fly={{duration: 200, x: direction}}>
|
||||
<div class="transition" in:fly={{duration: 200, x: direction}}>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 261 B |
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 343 B After Width: | Height: | Size: 262 B |
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 261 B |
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 306 B |
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 367 B |
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 497 B After Width: | Height: | Size: 416 B |
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 394 B |
@@ -1,11 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let size: string = 'var(--space-l)'
|
||||
</script>
|
||||
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
|
||||
|
Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 373 B |
@@ -1,12 +1,13 @@
|
||||
<script lang="ts">
|
||||
import {createEventDispatcher, setContext} from 'svelte'
|
||||
import {ChainDefinition, Checksum256} from '@wharfkit/session'
|
||||
import Icon from '../components/Icon.svelte'
|
||||
import Button from '../components/Button.svelte'
|
||||
import List from '../components/List.svelte'
|
||||
import ListItem from '../components/ListItem.svelte'
|
||||
import BodyTitle from '../components/BodyTitle.svelte'
|
||||
import {getThemedLogo} from '../../lib/utils'
|
||||
|
||||
export let chains: ChainDefinition[]
|
||||
export let title: string
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
select: Checksum256
|
||||
@@ -14,24 +15,26 @@
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if chains}
|
||||
{#if chains}
|
||||
<section>
|
||||
<BodyTitle>{title}</BodyTitle>
|
||||
<List>
|
||||
{#each chains as chain}
|
||||
<ListItem
|
||||
label={chain.name}
|
||||
onClick={() => dispatch('select', chain.id)}
|
||||
leadingIcon="wharf"
|
||||
logo={getThemedLogo(chain)}
|
||||
/>
|
||||
{/each}
|
||||
</List>
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
div {
|
||||
section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-l);
|
||||
gap: var(--space-s);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
import ListItem from '../components/ListItem.svelte'
|
||||
import TextInput from '../components/TextInput.svelte'
|
||||
import WarningMessage from '../components/WarningMessage.svelte'
|
||||
import BodyTitle from '../components/BodyTitle.svelte'
|
||||
|
||||
const {t} = getContext<i18nType>('i18n')
|
||||
|
||||
export let client: APIClient
|
||||
export let walletPlugin: UserInterfaceWalletPlugin
|
||||
export let title: string
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
select: PermissionLevel
|
||||
@@ -75,7 +77,8 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<section>
|
||||
<BodyTitle>{title}</BodyTitle>
|
||||
{#if $busy}
|
||||
<p class="loading">{$t('loading', {default: 'Loading...'})}</p>
|
||||
{:else if permissions && permissions.length > 0}
|
||||
@@ -98,38 +101,40 @@
|
||||
})}
|
||||
/>
|
||||
{:else if !accountName}
|
||||
<TextInput
|
||||
onKeyup={handleKeyup}
|
||||
bind:value={input}
|
||||
placeholder="Account name"
|
||||
autofocus={!input}
|
||||
error={accountNotFound && input === prevInput}
|
||||
/>
|
||||
{#if accountNotFound}
|
||||
<p class="error">
|
||||
{$t('login.enter.not_found', {
|
||||
default: 'Unable to find account',
|
||||
})}
|
||||
{prevInput}
|
||||
</p>
|
||||
{/if}
|
||||
<Button
|
||||
data={{
|
||||
variant: 'primary',
|
||||
onClick: lookup,
|
||||
label: $t('login.enter.lookup', {
|
||||
default: 'Lookup Account',
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
<div class="input-group">
|
||||
<TextInput
|
||||
onKeyup={handleKeyup}
|
||||
bind:value={input}
|
||||
placeholder="Account name"
|
||||
autofocus={!input}
|
||||
error={accountNotFound && input === prevInput}
|
||||
/>
|
||||
{#if accountNotFound}
|
||||
<p class="error">
|
||||
{$t('login.enter.not_found', {
|
||||
default: 'Unable to find account',
|
||||
})}
|
||||
{prevInput}
|
||||
</p>
|
||||
{/if}
|
||||
<Button
|
||||
data={{
|
||||
variant: 'primary',
|
||||
onClick: lookup,
|
||||
label: $t('login.enter.lookup', {
|
||||
default: 'Lookup Account',
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style lang="scss">
|
||||
div {
|
||||
section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-m);
|
||||
gap: var(--space-s);
|
||||
}
|
||||
|
||||
p.loading {
|
||||
@@ -143,4 +148,11 @@
|
||||
text-align: center;
|
||||
color: var(--error-color);
|
||||
}
|
||||
|
||||
.input-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-m);
|
||||
margin-top: var(--space-s);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,50 +1,42 @@
|
||||
<script lang="ts">
|
||||
import {createEventDispatcher} from 'svelte'
|
||||
import {UserInterfaceWalletPlugin} from '@wharfkit/session'
|
||||
import Icon from '../components/Icon.svelte'
|
||||
import List from '../components/List.svelte'
|
||||
import ListItem from '../components/ListItem.svelte'
|
||||
import {isBase64Image} from '../../lib/utils'
|
||||
|
||||
import BodyTitle from '../components/BodyTitle.svelte'
|
||||
import {getThemedLogo} from '../../lib/utils'
|
||||
export let wallets: UserInterfaceWalletPlugin[]
|
||||
export let title: string
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
select: number
|
||||
cancel: void
|
||||
}>()
|
||||
|
||||
const hasValidLogo = ({metadata: {logo, name}}: UserInterfaceWalletPlugin) => {
|
||||
if (isBase64Image(logo)) {
|
||||
return true
|
||||
} else {
|
||||
console.warn(`${name} logo is not a valid base64 image`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if wallets}
|
||||
<List>
|
||||
{#each wallets as wallet, index}
|
||||
<ListItem label={wallet.metadata.name} onClick={() => dispatch('select', index)}>
|
||||
<div class="logo" slot="logo">
|
||||
{#if hasValidLogo(wallet)}
|
||||
<img
|
||||
src={wallet.metadata.logo}
|
||||
alt={wallet.metadata.name}
|
||||
width="32"
|
||||
height="32"
|
||||
/>
|
||||
{:else}
|
||||
<Icon name="wallet" />
|
||||
{/if}
|
||||
</div>
|
||||
</ListItem>
|
||||
{/each}
|
||||
</List>
|
||||
<section>
|
||||
<BodyTitle>{title}</BodyTitle>
|
||||
<List>
|
||||
{#each wallets as wallet, index}
|
||||
<ListItem
|
||||
label={wallet.metadata.name}
|
||||
onClick={() => dispatch('select', index)}
|
||||
leadingIcon="wallet"
|
||||
logo={getThemedLogo(wallet.metadata)}
|
||||
/>
|
||||
{/each}
|
||||
</List>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-s);
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
@@ -6,7 +6,9 @@ import {
|
||||
TransactContext,
|
||||
UserInterfaceLoginResponse,
|
||||
} from '@wharfkit/session'
|
||||
import type {ColorScheme} from '../types'
|
||||
import {Writable, writable} from 'svelte/store'
|
||||
import {getStoredColorScheme} from '../lib/utils'
|
||||
|
||||
// Reset data in all stores
|
||||
export function resetState() {
|
||||
@@ -139,3 +141,10 @@ export const loginResponse = writable<UserInterfaceLoginData>({...defaultLoginRe
|
||||
export const errorDetails = writable<string | undefined>(undefined)
|
||||
|
||||
export const backAction = writable<Function | undefined>(undefined)
|
||||
|
||||
// define a writable store to hold the color scheme preference and set the initial color scheme preference based on localStorage
|
||||
export const colorScheme = writable<ColorScheme | null>(getStoredColorScheme())
|
||||
// listen for changes to the color scheme preference and update localStorage
|
||||
colorScheme.subscribe((value) => {
|
||||
if (value) localStorage.setItem('colorScheme', value)
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html data-color-mode="dark" data-dark-theme="dark_dimmed" lang="en">
|
||||
<head>
|
||||
<title>@wharfkit/web-ui-renderer</title>
|
||||
<title>@wharfkit/web-renderer</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<script src="./bundle.js"></script>
|
||||
<script>
|
||||
@@ -323,8 +323,8 @@
|
||||
<h2 class="Subhead-heading">Web Renderer Test</h2>
|
||||
<div class="Subhead-description">
|
||||
A suite of testing tools for the
|
||||
<a href="https://github.com/@wharfkit/web-ui-renderer" target="_blank">
|
||||
@wharfkit/web-ui-renderer
|
||||
<a href="https://github.com/@wharfkit/web-renderer" target="_blank">
|
||||
@wharfkit/web-renderer
|
||||
</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2995,10 +2995,10 @@
|
||||
"@typescript-eslint/types" "5.49.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@wharfkit/session@^0.3.3":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/session/-/session-0.3.3.tgz#fc09975a6065fb2173706318ef496cf3b38413d0"
|
||||
integrity sha512-RMJEIXHlvS5jTqPjCARIBSwOFxyPib0KjEHehTkEzYxwFgfBUTs4yjYnrqFYxYMqLWNKYwtCoKsvgbRmg3E9dQ==
|
||||
"@wharfkit/session@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/session/-/session-0.4.0.tgz#bfb7b4800a3e373f5747fcf33ccbe759dcf328be"
|
||||
integrity sha512-mNAYF2DG5g1yJsI3AYUbHu0eAULmehtDg7BBEzm2FlMy2wo4z2tUD5BtjmGWo2ZmYR6tKQ5jY69kRNVnxzWARg==
|
||||
dependencies:
|
||||
"@greymass/eosio" "^0.6.10"
|
||||
eosio-signing-request "^2.5.3"
|
||||
@@ -3039,41 +3039,41 @@
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@wharfkit/wallet-plugin-anchor@^0.3.4":
|
||||
version "0.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-anchor/-/wallet-plugin-anchor-0.3.4.tgz#8c8c39dcb67f1c46f2a330df12f45f70199cf924"
|
||||
integrity sha512-lWX0NdQccgKwWv0HSQUv0RNhOIEtydqxK3XN+Yal466Z4PZutetYQ41FKTl792Nr0e3UXqf6SNT2ky8xIO+Y1w==
|
||||
"@wharfkit/wallet-plugin-anchor@^0.4.1":
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-anchor/-/wallet-plugin-anchor-0.4.1.tgz#58f4bfa37709213881ded12b69d2486e9fa72989"
|
||||
integrity sha512-i/e8llzhGfXndtCW8FE+bBLbILB3yM3N4wiizVc4BuEbYHf/GJsDzSF3CBNVgYaflq1wIt/niOddOJ3GVMGxPw==
|
||||
dependencies:
|
||||
"@greymass/buoy" "^1.0.3"
|
||||
"@greymass/miniaes" "^1.0.0"
|
||||
isomorphic-ws "^5.0.0"
|
||||
ws "^8.13.0"
|
||||
|
||||
"@wharfkit/wallet-plugin-cleos@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-cleos/-/wallet-plugin-cleos-0.3.1.tgz#aed1793fff22e67d397172d5fa078d126b533dae"
|
||||
integrity sha512-ISfh1WMXpveGC9pAHebsmuC5tappa0TYXSi5EjbfWcutNOz3WptPcNLkQnjGBrt1ZiWTn7YWrhtr+ZNpQ8ZUHA==
|
||||
"@wharfkit/wallet-plugin-cleos@^0.4.1":
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-cleos/-/wallet-plugin-cleos-0.4.1.tgz#aaad9f32254cf43023d142de07ea5bc8309da6fe"
|
||||
integrity sha512-scxhjuLEJr7c79ROFYGSGCRmqaCyKVtp8oRkksicY/ZR6HIrtGLMFxL8Ws+uRis8KKvCOu3Vc88q47CCnHZTnQ==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@wharfkit/wallet-plugin-cloudwallet@^0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-cloudwallet/-/wallet-plugin-cloudwallet-0.3.2.tgz#7fc3e8ad062687f4f483691a3dbe6e076b7f0155"
|
||||
integrity sha512-sc4Sg02hCNjVclBIiZ7f/zFNigpk52AZB+EiOQfrwfqwi+Uqa5ZT2EvE7ESWl8FVTVi0kTPs+qdlS4hY0Nq5Gg==
|
||||
"@wharfkit/wallet-plugin-cloudwallet@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-cloudwallet/-/wallet-plugin-cloudwallet-0.4.0.tgz#61908a33be384ce7090d4d1f954db09b71483049"
|
||||
integrity sha512-hW489WJjDfhJhmSeuyjQTIdM7kEyeS/6qmA7yzK4ReqiACEoyofw1oyVieVu3bfdm+rnKwHb8DFBG/h4aVSa1w==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@wharfkit/wallet-plugin-mock@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-mock/-/wallet-plugin-mock-0.3.0.tgz#1d96ad466766cfc8eed3757eb910ecb56937df97"
|
||||
integrity sha512-EmunrKyH9BVTUB+eXCepo0rBzh19dLRRveqfawSYg+FTIlInnaDIHS2S6J9jpJ0xqBEpnIpar/vEWJChUT97mg==
|
||||
"@wharfkit/wallet-plugin-mock@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-mock/-/wallet-plugin-mock-0.4.0.tgz#b317e2f21ccb3a4df11338ecba60854a2e493901"
|
||||
integrity sha512-g06eO+mlpltqanb60xzLRNGR+XhWFQYNMj6BoMT5XTNcWfmE8mjoGnUf5ApjLXcv+mVgN8BrJHpV5XxTwvVa7g==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@wharfkit/wallet-plugin-privatekey@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-privatekey/-/wallet-plugin-privatekey-0.3.0.tgz#a54b03c9b71cbdb132a33eceaf6afec5066be101"
|
||||
integrity sha512-ysEqenJ5CrL4Aja0qVtr3ya4Ah2ADuA4e+16mPMtBGcdDpmFkK/rF8006icLuHNQRXYh5QQTRiVrkQN04V+mZQ==
|
||||
"@wharfkit/wallet-plugin-privatekey@^0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@wharfkit/wallet-plugin-privatekey/-/wallet-plugin-privatekey-0.4.0.tgz#1f7050850b161699cf854f7898e2a081743008a7"
|
||||
integrity sha512-mUpHssEEqbCiOhwI2xTbo+rLfTUx86E+82EBVaWmb43U+OV1Pg/FnYcNkMaI8U5pYgbKVphBBWVymfaQ8uDTcw==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
|
||||