@alephium/web3-react
Version:
React components for Alephium Web3.
1,397 lines (1,338 loc) • 261 kB
JavaScript
'use client';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import React, { createContext, useContext, useRef, useState, useEffect, useCallback, useLayoutEffect, useMemo } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { createPortal } from 'react-dom';
import { detect } from 'detect-browser';
import styled$1, { keyframes, css, ThemeProvider } from 'styled-components';
import { useTransition } from 'react-transition-state';
import ResizeObserver from 'resize-observer-polyfill';
import useMeasure from 'react-use-measure';
import { useSyncExternalStore } from 'use-sync-external-store/shim';
import { getDefaultAlephiumWallet, isWalletObj, getWalletObject, alephiumProvider, providerInitializedEvent } from '@alephium/get-extension-wallet';
import { isBalanceEqual, subscribeToTxStatus, web3 } from '@alephium/web3';
import { WalletConnectProvider, isCompatibleAddressGroup } from '@alephium/walletconnect-provider';
import QRCodeModal from '@alephium/walletconnect-qrcode-modal';
const defaultLightTheme = {
font: {
family: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, 'Apple Color Emoji', Arial, sans-serif, 'Segoe UI Emoji'`
},
text: {
primary: {
color: '#373737'
},
secondary: {
color: '#999999',
hover: {
color: '#111111'
}
},
error: '#FC6464',
valid: '#32D74B'
},
buttons: {
primary: {
borderRadius: 16,
color: '#000373737000',
background: '#FFFFFF',
border: '#F0F0F0',
hover: {
color: '#000000',
border: '#1A88F8'
}
},
secondary: {
borderRadius: 16,
background: '#F6F7F9',
color: '#000000'
}
},
navigation: {
color: '#999999'
},
modal: {
background: '#ffffff', // need to generate an rgba transparent version of this for Safari
divider: '#f7f6f8'
},
tooltips: {
color: '#999999',
background: '#ffffff',
hover: {
background: '#f6f7f9'
}
},
overlay: {
background: 'rgba(0, 0, 0, 0.06)'
},
qrCode: {
accentColor: '#F7F6F8'
}
};
// parse into css variables so we can use p3 colors
const parseTheme = (theme) => {
return theme;
};
const userPrefersDarkMode = () => {
if (typeof window === 'undefined')
return false;
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
/*
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (event) => {
userPrefersDarkMode = event.matches;
});
*/
};
userPrefersDarkMode();
const defaultTheme$1 = {
connectKit: {
options: {
iconStyle: 'light'
},
//theme: parseTheme(defaultLightTheme),
theme: {
preferred: 'dark',
light: parseTheme(defaultLightTheme),
dark: parseTheme(defaultLightTheme)
}
}
};
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
const ConnectSettingContext = createContext(null);
const useConnectSettingContext = () => {
const context = useContext(ConnectSettingContext);
if (!context)
throw Error('ConnectSetting Hook must be inside a Provider.');
return context;
};
const AlephiumConnectContext = createContext(null);
// Use hooks `useWallet` and `useWalletConfig` instead
const useAlephiumConnectContext = () => {
const context = useContext(AlephiumConnectContext);
if (!context)
throw Error('AlephiumConnect Hook must be inside a Provider.');
return context;
};
const AlephiumBalanceContext = createContext(null);
// Use hook `useBalance` instead
const useAlephiumBalanceContext = () => {
const context = useContext(AlephiumBalanceContext);
if (!context)
throw Error('AlephiumBalance Hook must be inside a Provider.');
return context;
};
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
const Portal = (props) => {
props = {
selector: '__ALEPHIUMCONNECT__',
...props
};
const { selector, children } = props;
const ref = useRef(null);
const [mounted, setMounted] = useState(false);
useEffect(() => {
const selectorPrefixed = '#' + selector.replace(/^#/, '');
ref.current = document.querySelector(selectorPrefixed);
if (!ref.current) {
const div = document.createElement('div');
div.setAttribute('id', selector);
document.body.appendChild(div);
ref.current = div;
}
setMounted(true);
}, [selector]);
if (!ref.current)
return null;
return mounted ? createPortal(children, ref.current) : null;
};
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
const detectBrowser = () => {
var _a;
const browser = detect();
return (_a = browser === null || browser === void 0 ? void 0 : browser.name) !== null && _a !== void 0 ? _a : '';
};
const detectOS = () => {
var _a;
const browser = detect();
return (_a = browser === null || browser === void 0 ? void 0 : browser.os) !== null && _a !== void 0 ? _a : '';
};
const isIOS = () => {
const os = detectOS();
return os.toLowerCase().includes('ios');
};
const isAndroid = () => {
const os = detectOS();
return os.toLowerCase().includes('android');
};
const isMobile = () => {
return isAndroid() || isIOS();
};
function flattenChildren(children) {
const childrenArray = React.Children.toArray(children);
return childrenArray.reduce((flatChildren, child) => {
if (child.type === React.Fragment) {
return flatChildren.concat(flattenChildren(child.props.children));
}
flatChildren.push(child);
return flatChildren;
}, []);
}
const truncatedAddress = (address) => {
const start = address.slice(0, 6);
const end = address.slice(-6);
return `${start} ... ${end}`;
};
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
var styled = typeof styled$1.div === 'function' ? styled$1 : styled$1['default'];
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
var defaultTheme = {
mobileWidth: 560
};
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
const ErrorMessage = styled(motion.div) `
z-index: -1;
pointer-events: auto;
position: absolute;
left: 50%;
transform: translateX(-50%);
width: var(--width);
top: 64px;
color: #fff;
font-size: 14px;
line-height: 20px;
font-weight: 500;
background: var(--ck-body-color-danger);
border-radius: 20px;
padding: 24px 46px 82px 24px;
transition: width var(--duration) var(--ease);
a {
font-weight: 700;
text-decoration: underline;
}
code {
font-size: 0.9em;
display: inline-block;
font-family: monospace;
margin: 1px;
padding: 0 4px;
border-radius: 8px;
font-weight: bold;
background: rgba(255, 255, 255, 0.1);
}
`;
const FadeIn = keyframes `
from { opacity: 0; }
to { opacity: 1; }
`;
const FadeInScaleUp = keyframes `
from { opacity: 0; transform: scale(0.85); }
to { opacity: 1; transform: scale(1); }
`;
const FadeInScaleDown = keyframes `
from { opacity: 0; transform: scale(1.1); }
to { opacity: 1; transform: scale(1); }
`;
const FadeOut = keyframes `
from { opacity: 1; }
to { opacity: 0; }
`;
const FadeOutScaleUp = keyframes `
from { opacity: 1; transform: scale(1); }
to { opacity: 0; transform: scale(1.1); }
`;
const FadeOutScaleDown = keyframes `
from { opacity: 1; transform: scale(1); }
to { opacity: 0; transform: scale(0.85); }
`;
const PageContent = styled(motion.div) `
max-width: 100%;
width: 295px;
padding-top: 48px;
`;
const TextWithHr = styled(motion.div) `
user-select: none;
position: relative;
display: block;
text-align: center;
color: var(--ck-body-color-muted);
font-size: 15px;
font-weight: 400;
line-height: 21px;
span {
z-index: 2;
position: relative;
display: inline-block;
user-select: none;
pointer-events: none;
padding: 0 14px;
background: var(--ck-body-background);
transition: background-color 200ms ease;
}
&:before {
z-index: 2;
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 1px;
transform: translateY(-1px);
background: var(--ck-body-divider);
box-shadow: var(--ck-body-divider-box-shadow);
}
`;
const ModalHeading = styled(motion.div) `
z-index: 3;
pointer-events: none;
user-select: none;
position: absolute;
top: 25px;
left: 50%;
display: flex;
align-items: center;
justify-content: center;
height: 26px;
transform: translateX(-50%);
width: var(--width);
text-align: center;
font-size: 17px;
line-height: 20px;
font-weight: var(--ck-modal-heading-font-weight, 600);
color: var(--ck-body-color);
span {
display: inline-block;
}
`;
const ModalContentContainer = styled(motion.div) `
position: relative;
padding: 0;
`;
const ModalContent = styled(motion.div) `
left: 0;
right: 0;
text-align: center;
display: flex;
flex-direction: column;
gap: 12px;
padding: 0 0 16px;
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
display: block;
}
`;
const ModalH1 = styled(motion.h1) `
margin: 0;
padding: 0;
line-height: ${(props) => (props.$small ? 20 : 22)}px;
font-size: ${(props) => (props.$small ? 17 : 19)}px;
font-weight: var(--ck-modal-h1-font-weight, 600);
color: ${(props) => {
if (props.$error)
return 'var(--ck-body-color-danger)';
if (props.$valid)
return 'var(--ck-body-color-valid)';
return 'var(--ck-body-color)';
}};
> svg {
position: relative;
top: -2px;
display: inline-block;
vertical-align: middle;
margin-right: 6px;
}
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
margin-bottom: 6px;
font-size: 17px;
}
`;
const ModalBody = styled.div `
font-size: 16px;
font-weight: 400;
line-height: 21px;
color: var(--ck-body-color-muted);
strong {
font-weight: 500;
color: var(--ck-body-color);
}
`;
const BackgroundOverlay = styled(motion.div) `
z-index: 1;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--ck-overlay-background, rgba(71, 88, 107, 0.24));
backdrop-filter: var(--ck-overlay-backdrop-filter, none);
opacity: 0;
animation: ${(props) => (props.$active ? FadeIn : FadeOut)} 150ms ease-out both;
`;
const BoxIn = keyframes `
from{ opacity: 0; transform: scale(0.97); }
to{ opacity: 1; transform: scale(1); }
`;
const BoxOut = keyframes `
from{ opacity: 1; transform: scale(1); }
to{ opacity: 0; transform: scale(0.97); }
`;
const MobileBoxIn = keyframes `
from { transform: translate3d(0, 100%, 0); }
to { transform: translate3d(0, 0%, 0); }
`;
const MobileBoxOut = keyframes `
from { opacity: 1; }
to { opacity: 0; }
`;
const BoxContainer = styled(motion.div) `
z-index: 2;
position: relative;
color: var(--ck-body-color);
animation: 150ms ease both;
animation-name: ${BoxOut};
&.active {
animation-name: ${BoxIn};
}
&:before {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: var(--width);
height: var(--height);
transform: translateX(-50%);
backface-visibility: hidden;
transition: all 200ms ease;
border-radius: var(--ck-border-radius, 20px);
background: var(--ck-body-background);
box-shadow: var(--ck-modal-box-shadow);
}
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
animation-name: ${MobileBoxOut};
animation-duration: 130ms;
animation-timing-function: ease;
&.active {
animation-name: ${MobileBoxIn};
animation-duration: 300ms;
animation-delay: 32ms;
animation-timing-function: cubic-bezier(0.15, 1.15, 0.6, 1);
}
&:before {
width: 100%;
transition: 0ms height cubic-bezier(0.15, 1.15, 0.6, 1);
will-change: height;
}
}
`;
const ControllerContainer = styled(motion.div) `
z-index: 3;
position: absolute;
top: 0;
left: 50%;
height: 64px;
transform: translateX(-50%);
backface-visibility: hidden;
width: var(--width);
transition: 0.2s ease width;
pointer-events: auto;
//border-bottom: 1px solid var(--ck-body-divider);
`;
const InnerContainer$1 = styled(motion.div) `
position: relative;
overflow: hidden;
height: var(--height);
transition: 0.2s ease height;
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
transition: 0ms height cubic-bezier(0.15, 1.15, 0.6, 1);
/* animation-delay: 34ms; */
}
`;
const PageContainer = styled(motion.div) `
z-index: 2;
position: relative;
top: 0;
left: 50%;
margin-left: calc(var(--width) / -2);
width: var(--width);
/* left: 0; */
/* width: 100%; */
display: flex;
justify-content: center;
align-items: center;
transform-origin: center center;
animation: 200ms ease both;
&.active {
animation-name: ${FadeInScaleDown};
}
&.active-scale-up {
animation-name: ${FadeInScaleUp};
}
&.exit-scale-down {
z-index: 1;
pointer-events: none;
position: absolute;
/* top: 0; */
/* left: 0; */
animation-name: ${FadeOutScaleDown};
}
&.exit {
z-index: 1;
pointer-events: none;
position: absolute;
/* top: 0; */
/* left: 0; */
/* left: 50%; */
/* transform: translateX(-50%); */
animation-name: ${FadeOutScaleUp};
animation-delay: 16.6667ms;
}
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
/* animation: 0ms ease both; */
/* animation-delay: 35ms; */
animation: 0ms cubic-bezier(0.15, 1.15, 0.6, 1) both;
&.active {
animation-name: ${FadeIn};
}
&.active-scale-up {
animation-name: ${FadeIn};
}
&.exit-scale-down {
z-index: 3;
animation-name: ${FadeOut};
}
&.exit {
z-index: 3;
animation-name: ${FadeOut};
animation-delay: 0ms;
}
}
`;
const PageContents = styled(motion.div) `
margin: 0 auto;
width: fit-content;
padding: 29px 24px 24px;
backface-visibility: hidden;
`;
const ModalContainer = styled.div `
z-index: 2147483646; // z-index set one below max (2147483647) for if we wish to layer things ontop of the modal in a seperate Portal
position: fixed;
inset: 0;
`;
const CloseButton = styled(motion.button) `
z-index: 3;
cursor: pointer;
position: absolute;
top: 22px;
right: 17px;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 16px;
padding: 0;
margin: 0;
color: var(--ck-body-action-color);
background: var(--ck-body-background);
transition: background-color 200ms ease, transform 100ms ease;
/* will-change: transform; */
svg {
display: block;
}
&:hover {
background: var(--ck-body-background-secondary);
}
&:active {
transform: scale(0.9);
}
`;
const BackButton = styled(motion.button) `
z-index: 3;
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 16px;
padding: 0;
margin: 0;
color: var(--ck-body-action-color);
background: var(--ck-body-background);
transition: background-color 200ms ease, transform 100ms ease;
/* will-change: transform; */
svg {
display: block;
position: relative;
left: -1px;
}
&:enabled {
cursor: pointer;
&:hover {
background: var(--ck-body-background-secondary);
}
&:active {
transform: scale(0.9);
}
}
`;
const InfoButton = styled(motion.button) `
z-index: 3;
position: absolute;
inset: 0;
transform: translateX(-1px);
display: flex;
align-items: center;
justify-content: center;
border-radius: 16px;
padding: 0;
margin: 0;
color: var(--ck-body-action-color);
background: var(--ck-body-background);
transition: background-color 200ms ease, transform 100ms ease;
/* will-change: transform; */
svg {
display: block;
position: relative;
}
&:enabled {
cursor: pointer;
&:hover {
background: var(--ck-body-background-secondary);
}
&:active {
transform: scale(0.9);
}
}
`;
const Container$3 = styled(motion.div) `
--ease: cubic-bezier(0.25, 0.1, 0.25, 1);
--duration: 200ms;
--transition: height var(--duration) var(--ease), width var(--duration) var(--ease);
z-index: 3;
display: block;
pointer-events: none;
position: absolute;
left: 50%;
top: 50%;
width: 100%;
transform: translate3d(-50%, -50%, 0);
backface-visibility: hidden;
@media only screen and (max-width: ${defaultTheme.mobileWidth}px) {
pointer-events: auto;
left: 0;
top: auto;
bottom: -5px;
transform: none;
${BoxContainer} {
max-width: 448px;
margin: 0 auto;
&:before {
width: 100%;
border-radius: var(--ck-border-radius, 30px) var(--ck-border-radius, 30px) 0 0;
}
}
${PageContainer} {
left: 0;
right: 0;
margin: 0 auto;
width: auto;
}
${PageContent} {
margin: 0 auto;
width: 100% !important;
}
${ModalHeading} {
top: 29px;
}
${ModalContent} {
gap: 12px;
}
${ModalBody} {
margin: 0 auto;
max-width: 295px;
}
${PageContents} {
width: 100%;
padding: 31px 24px;
}
${ControllerContainer} {
width: 100%;
top: 4px;
border-bottom: 0;
}
${CloseButton} {
right: 22px;
}
${BackButton} {
top: -1px;
left: -3px;
}
${InfoButton} {
top: -1px;
left: -3px;
svg {
width: 65%;
height: auto;
}
}
${CloseButton},
${BackButton},
${InfoButton} {
// Quick hack for bigger tappable area on mobile
transform: scale(1.4) !important;
background: transparent !important;
svg {
transform: scale(0.8) !important;
}
}
}
`;
const KEYCODE_TAB = 9;
function useFocusTrap() {
const elRef = useRef(null);
function handleFocus(e) {
if (!elRef.current)
return;
const focusableEls = elRef.current.querySelectorAll(`
a[href]:not(:disabled),
button:not(:disabled),
textarea:not(:disabled),
input[type="text"]:not(:disabled),
input[type="radio"]:not(:disabled),
input[type="checkbox"]:not(:disabled),
select:not(:disabled)
`), firstFocusableEl = focusableEls[0], lastFocusableEl = focusableEls[focusableEls.length - 1];
const isTabPressed = e.key === 'Tab' || e.keyCode === KEYCODE_TAB;
if (!isTabPressed) {
return;
}
if (e.shiftKey) {
/* shift + tab */ if (document.activeElement === firstFocusableEl) {
lastFocusableEl.focus();
e.preventDefault();
}
} /* tab */
else {
if (document.activeElement === lastFocusableEl) {
firstFocusableEl.focus();
e.preventDefault();
}
}
}
useEffect(() => {
if (elRef.current) {
elRef.current.addEventListener('keydown', handleFocus);
elRef.current.focus({ preventScroll: true });
}
const current = elRef.current;
return () => {
if (current) {
current.removeEventListener('keydown', handleFocus);
}
};
}, [elRef]);
return elRef;
}
function FocusTrap(props) {
const elRef = useFocusTrap();
useEffect(() => {
if (!elRef.current)
return;
elRef.current.focus({ preventScroll: true });
}, [elRef]);
return (jsx("div", { ref: elRef, tabIndex: 0, children: props.children }));
}
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
function usePrevious(value, initial) {
const ref = useRef({ target: value, previous: initial });
if (ref.current.target !== value) {
// The value changed.
ref.current.previous = ref.current.target;
ref.current.target = value;
}
return ref.current.previous;
}
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
const LOG_LEVEL = {
debug: 10,
info: 20,
warn: 30,
error: 40,
none: 100
};
// Suppress `useLayoutEffect` warning when rendering on the server
// https://gist.github.com/gaearon/e7d97cdf38a2907924ea12e4ebdf3c85
const useIsoLayoutEffect = typeof window !== 'undefined' && window.document && window.document.createElement !== undefined
? useLayoutEffect
: useEffect;
const useFitText = ({ logLevel: logLevelOption = 'info', maxFontSize = 100, minFontSize = 20, onFinish, onStart, resolution = 5 } = {}) => {
const logLevel = LOG_LEVEL[logLevelOption];
const initState = useCallback(() => {
return {
calcKey: 0,
fontSize: maxFontSize,
fontSizePrev: minFontSize,
fontSizeMax: maxFontSize,
fontSizeMin: minFontSize
};
}, [maxFontSize, minFontSize]);
const ref = useRef(null);
const innerHtmlPrevRef = useRef();
const isCalculatingRef = useRef(false);
const [state, setState] = useState(initState);
const { calcKey, fontSize, fontSizeMax, fontSizeMin, fontSizePrev } = state;
// Montior div size changes and recalculate on resize
let animationFrameId = null;
const [ro] = useState(() => new ResizeObserver(() => {
animationFrameId = window.requestAnimationFrame(() => {
if (isCalculatingRef.current) {
return;
}
onStart && onStart();
isCalculatingRef.current = true;
// `calcKey` is used in the dependencies array of
// `useIsoLayoutEffect` below. It is incremented so that the font size
// will be recalculated even if the previous state didn't change (e.g.
// when the text fit initially).
setState({
...initState(),
calcKey: calcKey + 1
});
});
}));
useEffect(() => {
if (ref.current) {
ro.observe(ref.current);
}
return () => {
animationFrameId && window.cancelAnimationFrame(animationFrameId);
ro.disconnect();
};
}, [animationFrameId, ro]);
// Recalculate when the div contents change
const innerHtml = ref.current && ref.current.innerHTML;
useEffect(() => {
if (calcKey === 0 || isCalculatingRef.current)
return;
if (innerHtml !== innerHtmlPrevRef.current) {
onStart && onStart();
setState({
...initState(),
calcKey: calcKey + 1
});
}
innerHtmlPrevRef.current = innerHtml;
}, [calcKey, initState, innerHtml, onStart]);
// Check overflow and resize font
useIsoLayoutEffect(() => {
// Don't start calculating font size until the `resizeKey` is incremented
// above in the `ResizeObserver` callback. This avoids an extra resize
// on initialization.
if (calcKey === 0) {
return;
}
const isWithinResolution = Math.abs(fontSize - fontSizePrev) <= resolution;
const isOverflow = !!ref.current &&
(ref.current.scrollHeight > ref.current.offsetHeight || ref.current.scrollWidth > ref.current.offsetWidth);
const isFailed = isOverflow && fontSize === fontSizePrev;
const isAsc = fontSize > fontSizePrev;
// Return if the font size has been adjusted "enough" (change within `resolution`)
// reduce font size by one increment if it's overflowing.
if (isWithinResolution) {
if (isFailed) {
isCalculatingRef.current = false;
if (logLevel <= LOG_LEVEL.info) {
console.info(`[use-fit-text] reached \`minFontSize = ${minFontSize}\` without fitting text`);
}
}
else if (isOverflow) {
setState({
fontSize: isAsc ? fontSizePrev : fontSizeMin,
fontSizeMax,
fontSizeMin,
fontSizePrev,
calcKey
});
}
else {
isCalculatingRef.current = false;
onFinish && onFinish(fontSize);
}
return;
}
// Binary search to adjust font size
let delta;
let newMax = fontSizeMax;
let newMin = fontSizeMin;
if (isOverflow) {
delta = isAsc ? fontSizePrev - fontSize : fontSizeMin - fontSize;
newMax = Math.min(fontSizeMax, fontSize);
}
else {
delta = isAsc ? fontSizeMax - fontSize : fontSizePrev - fontSize;
newMin = Math.max(fontSizeMin, fontSize);
}
setState({
calcKey,
fontSize: fontSize + delta / 2,
fontSizeMax: newMax,
fontSizeMin: newMin,
fontSizePrev: fontSize
});
}, [calcKey, fontSize, fontSizeMax, fontSizeMin, fontSizePrev, onFinish, ref, resolution]);
return { fontSize, ref };
};
const FitText = React.forwardRef(({ children }, ref) => {
const [ready, setReady] = React.useState(false);
const { fontSize, ref: textRef } = useFitText({
logLevel: 'none',
maxFontSize: 100,
minFontSize: 70,
onStart: () => setReady(true),
onFinish: () => setReady(true)
});
return (jsx("div", { ref: textRef, style: {
visibility: ready ? 'visible' : 'hidden', // avoid flash of unstyled text
fontSize: `${fontSize}%`,
maxHeight: '100%',
maxWidth: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
//lineHeight: `${21 * (fontSize / 100)}px`,
//background: fontSize !== '100%' ? 'red' : undefined, // debug
}, children: children }));
});
FitText.displayName = 'FitText';
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
var base = {
light: {
/** Connect Wallet Button */
'--ck-connectbutton-font-size': '15px',
'--ck-connectbutton-color': '#373737',
'--ck-connectbutton-background': '#F6F7F9',
'--ck-connectbutton-background-secondary': '#FFFFFF',
'--ck-connectbutton-hover-color': '#373737',
'--ck-connectbutton-hover-background': '#F0F2F5',
'--ck-connectbutton-active-color': '#373737',
'--ck-connectbutton-active-background': '#EAECF1',
'--ck-connectbutton-balance-color': '#373737',
'--ck-connectbutton-balance-background': '#fff',
'--ck-connectbutton-balance-box-shadow': 'inset 0 0 0 1px var(--ck-connectbutton-background)',
'--ck-connectbutton-balance-hover-background': '#F6F7F9',
'--ck-connectbutton-balance-hover-box-shadow': 'inset 0 0 0 1px var(--ck-connectbutton-hover-background)',
'--ck-connectbutton-balance-active-background': '#F0F2F5',
'--ck-connectbutton-balance-active-box-shadow': 'inset 0 0 0 1px var(--ck-connectbutton-active-background)',
/** Primary Button */
'--ck-primary-button-border-radius': '16px',
'--ck-primary-button-color': '#373737',
'--ck-primary-button-background': '#F6F7F9',
//'--ck-primary-button-box-shadow': 'inset 0 0 0 1px #F0F0F0',
'--ck-primary-button-font-weight': '600',
'--ck-primary-button-hover-color': '#373737',
'--ck-primary-button-hover-background': '#F0F2F5',
//'--ck-primary-button-hover-box-shadow': 'inset 0 0 0 2px var(--ck-focus-color)',
//'--ck-primary-button-active-background': '#EAECF1',
/** Secondary Button */
'--ck-secondary-button-border-radius': '16px',
'--ck-secondary-button-color': '#373737',
'--ck-secondary-button-background': '#F6F7F9',
//'--ck-secondary-button-box-shadow': '',
//'--ck-secondary-button-font-weight': '',
/** Tertiary Button */
'--ck-tertiary-button-background': '#FFFFFF',
'--ck-secondary-button-hover-background': '#e0e4eb',
/** Modal */
'--ck-modal-box-shadow': '0px 2px 4px rgba(0, 0, 0, 0.02)',
'--ck-overlay-background': 'rgba(71, 88, 107, 0.24)',
'--ck-body-color': '#373737',
'--ck-body-color-muted': '#999999',
'--ck-body-color-muted-hover': '#111111',
'--ck-body-background': '#ffffff',
'--ck-body-background-transparent': 'rgba(255,255,255,0)',
'--ck-body-background-secondary': '#f6f7f9',
'--ck-body-background-secondary-hover-background': '#e0e4eb',
'--ck-body-background-secondary-hover-outline': '#4282FF',
'--ck-body-background-tertiary': '#F3F4F7',
'--ck-body-action-color': '#999999',
'--ck-body-divider': '#f7f6f8',
'--ck-body-color-danger': '#FF4E4E',
'--ck-body-color-valid': '#32D74B',
'--ck-siwe-border': '#F0F0F0',
/** Disclaimer */
//'--ck-body-disclaimer-background': '#E3D6C9',
//'--ck-body-disclaimer-box-shadow': 'none',
'--ck-body-disclaimer-color': '#AAAAAB',
'--ck-body-disclaimer-link-color': '#838485',
'--ck-body-disclaimer-link-hover-color': '#000000',
/** Tooltips */
'--ck-tooltip-background': '#ffffff',
'--ck-tooltip-background-secondary': '#ffffff',
'--ck-tooltip-color': '#999999',
'--ck-tooltip-shadow': '0px 2px 10px rgba(0, 0, 0, 0.08)',
/** Network dropdown */
'--ck-dropdown-button-color': '#999999',
'--ck-dropdown-button-box-shadow': '0 0 0 1px rgba(0,0,0,0.01), 0px 0px 7px rgba(0, 0, 0, 0.05)',
'--ck-dropdown-button-background': '#fff',
'--ck-dropdown-button-hover-color': '#8B8B8B',
'--ck-dropdown-button-hover-background': '#F5F7F9',
/** QR Code */
'--ck-qr-dot-color': '#000000',
'--ck-qr-border-color': '#f7f6f8',
/** Misc. */
'--ck-focus-color': '#1A88F8',
'--ck-spinner-color': 'var(--ck-focus-color)',
'--ck-copytoclipboard-stroke': '#CCCCCC'
},
dark: {
'--ck-connectbutton-font-size': '15px',
'--ck-connectbutton-color': '#ffffff',
'--ck-connectbutton-background': '#383838',
'--ck-connectbutton-background-secondary': '#282828',
'--ck-connectbutton-hover-background': '#404040',
'--ck-connectbutton-active-background': '#4D4D4D',
'--ck-connectbutton-balance-color': '#fff',
'--ck-connectbutton-balance-background': '#282828',
'--ck-connectbutton-balance-box-shadow': 'inset 0 0 0 1px var(--ck-connectbutton-background)',
'--ck-connectbutton-balance-hover-background': '#383838',
'--ck-connectbutton-balance-hover-box-shadow': 'inset 0 0 0 1px var(--ck-connectbutton-hover-background)',
'--ck-connectbutton-balance-active-background': '#404040',
'--ck-connectbutton-balance-active-box-shadow': 'inset 0 0 0 1px var(--ck-connectbutton-active-background)',
'--ck-primary-button-color': '#ffffff',
'--ck-primary-button-background': '#383838',
//'--ck-primary-button-box-shadow': 'inset 0 0 0 1px #3D3D3D',
'--ck-primary-button-border-radius': '16px',
'--ck-primary-button-font-weight': '600',
'--ck-primary-button-hover-background': '#404040',
//'--ck-primary-button-hover-box-shadow': 'inset 0 0 0 2px rgba(255, 255, 255, 0.4)',
//'--ck-primary-button-active-background': '#4D4D4D',
'--ck-primary-button-active-border-radius': '16px',
'--ck-secondary-button-color': '#ffffff',
'--ck-secondary-button-background': '#333333',
'--ck-secondary-button-hover-background': '#4D4D4D',
/** Tertiary Button */
'--ck-tertiary-button-background': '#424242',
'--ck-focus-color': '#1A88F8',
'--ck-overlay-background': 'rgba(0,0,0,0.4)',
'--ck-body-color': '#ffffff',
'--ck-body-color-muted': 'rgba(255, 255, 255, 0.4)',
'--ck-body-color-muted-hover': 'rgba(255, 255, 255, 0.8)',
'--ck-body-background': '#2B2B2B',
'--ck-body-background-transparent': 'rgba(0,0,0,0)',
'--ck-body-background-secondary': '#333333',
'--ck-body-background-secondary-hover-background': '#4D4D4D',
'--ck-body-background-secondary-hover-outline': '#ffffff',
'--ck-body-background-tertiary': '#333333',
'--ck-body-action-color': '#808080',
'--ck-body-divider': '#383838',
'--ck-body-color-danger': '#FF4E4E',
'--ck-body-disclaimer-color': '#858585',
'--ck-body-disclaimer-link-color': '#ADADAD',
'--ck-body-disclaimer-link-hover-color': '#FFFFFF',
'--ck-modal-box-shadow': '0px 2px 4px rgba(0, 0, 0, 0.02)',
'--ck-copytoclipboard-stroke': '#555555',
'--ck-tooltip-background': '#2B2B2B',
'--ck-tooltip-background-secondary': '#333333',
'--ck-tooltip-color': '#999999',
'--ck-tooltip-shadow': '0px 2px 10px rgba(0, 0, 0, 0.08)',
/** Network dropdown */
'--ck-dropdown-button-color': '#6C7381',
'--ck-spinner-color': 'var(--ck-focus-color)',
'--ck-qr-dot-color': '#ffffff',
'--ck-qr-border-color': '#3d3d3d'
}
};
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
var web95 = {
'--ck-font-family': 'Lato',
'--ck-border-radius': '0px',
'--ck-connectbutton-color': '#373737',
'--ck-connectbutton-background': 'linear-gradient(180deg, #F0F0EA 0%, #FFFFFF 50%, #F0F0EA 100%) 100% 100% / 200% 200%, #F5F5F1',
'--ck-connectbutton-box-shadow': ' 0 0 0 1px #003C74, 2px 2px 0px rgba(255, 255, 255, 0.75), -2px -2px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 0px #97B9EC, inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-connectbutton-border-radius': '4.5px',
'--ck-connectbutton-hover-color': '#373737',
'--ck-connectbutton-hover-background': 'linear-gradient(180deg, #F0F0EA 0%, #FFFFFF 50%, #F0F0EA 100%) 100% 0% / 200% 200%, #F5F5F1',
'--ck-connectbutton-active-background': 'linear-gradient(180deg, #F0F0EA 0%, #FFFFFF 50%, #F0F0EA 100%) 100% 100% / 200% 200%, #F5F5F1',
'--ck-connectbutton-balance-color': '#373737',
'--ck-connectbutton-balance-background': '#fff',
'--ck-connectbutton-balance-box-shadow': '0 0 0 1px #E4E7E7',
'--ck-connectbutton-balance-hover-box-shadow': '0 0 0 1px #d7dbdb',
'--ck-connectbutton-balance-active-box-shadow': '0 0 0 1px #bbc0c0',
'--ck-focus-color': '#1A88F8',
'--ck-overlay-background': 'rgba(0, 127, 128, 0.8)',
'--ck-body-color': '#373737',
'--ck-body-color-muted': '#808080',
'--ck-body-color-muted-hover': '#111111',
'--ck-body-background': '#F0EDE2',
'--ck-body-background-transparent': 'rgba(255,255,255,0)',
'--ck-body-background-secondary-hover-background': '#FAFAFA',
'--ck-body-background-secondary-hover-outline': '#4282FF',
'--ck-body-action-color': '#373737',
'--ck-body-color-danger': '#FC6464',
'--ck-body-color-valid': '#32D74B',
'--ck-body-divider': '#919B9C',
'--ck-body-divider-box-shadow': '0px 1px 0px #FBFBF8',
// Primary button
'--ck-primary-button-background': 'linear-gradient(180deg, #FFFFFF 0%, #F0F0EA 100%), #F5F5F1',
'--ck-primary-button-box-shadow': 'inset 0 0 0 1px #003C74, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 0px #97B9EC, inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-primary-button-border-radius': '6px',
// Primary button hover
'--ck-primary-button-hover-box-shadow': 'inset 0 0 0 1px #003C74, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 5px #97B9EC, inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-primary-button-hover-border-radius': '6px',
// Modal
'--ck-modal-heading-font-weight': 400,
'--ck-modal-box-shadow': `
inset 0px -3px 0px #0F37A9,
inset -2px 0px 0px #0F37A9,
inset 0px -4px 0px #0D5DDF,
inset -4px 0px 0px #0D5DDF,
inset 2px 0px 0px #0453DD,
inset 0px 2px 0px #044FD1,
inset 4px 0px 0px #4283EB,
inset 0px 4px 0px #4283EB
`,
'--ck-modal-h1-font-weight': 400,
// Secondary button
'--ck-secondary-button-color': '#373737',
'--ck-secondary-button-border-radius': '6px',
'--ck-secondary-button-box-shadow': 'inset 0 0 0 1px #003C74, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 0px #97B9EC, inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-secondary-button-background': 'linear-gradient(180deg, #FFFFFF 0%, #F0F0EA 100%), #F5F5F1',
// Secondary button hover
'--ck-secondary-button-hover-box-shadow': 'inset 0 0 0 1px #003C74, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 4px #97B9EC, inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-body-background-secondary': 'rgba(0, 0, 0, 0.1)',
'--ck-body-background-tertiary': 'linear-gradient(180deg, #FBFBFB 0%, #EFEFEE 100%)',
'--ck-tertiary-border-radius': '0px',
'--ck-tertiary-box-shadow': 'inset 0 0 0 1px #919B9C, 1px 1px 2px rgba(0, 0, 0, 0.15), inset -2px -2px 0px #FFFFFF',
'--ck-body-button-text-align': 'left',
'--ck-body-button-box-shadow': '0 2px 4px rgba(0, 0, 0, 0.05 )',
'--ck-body-disclaimer-background': 'linear-gradient(180deg, #FBFBFB 0%, #EFEFEE 100%)',
'--ck-body-disclaimer-box-shadow': `
inset 0px -3px 0px #0F37A9,
inset -2px 0px 0px #0F37A9,
inset 0px -4px 0px #0D5DDF,
inset -4px 0px 0px #0D5DDF,
inset 2px 0px 0px #0453DD,
inset 4px 0px 0px #4283EB,
inset 0 1px 0 0 #919B9C`,
'--ck-body-disclaimer-font-size': '14px',
'--ck-body-disclaimer-color': '#959594',
'--ck-body-disclaimer-link-color': '#626262',
'--ck-body-disclaimer-link-hover-color': '#000000',
'--ck-qr-dot-color': '#000000',
'--ck-qr-border-color': '#919B9C',
'--ck-qr-border-radius': '0',
'--ck-qr-background': '#FFFFFF',
'--ck-copytoclipboard-stroke': 'rgba(55, 55, 55, 0.4)',
'--ck-tooltip-background': 'linear-gradient(270deg, #F7F3E6 7.69%, #F5F7DA 100%)',
'--ck-tooltip-background-secondary': '#f6f7f9',
'--ck-tooltip-color': '#000000',
'--ck-tooltip-shadow': ' 0 0 0 1.5px #2b2622, 0px 2px 10px rgba(0, 0, 0, 0.08)',
'--ck-spinner-color': 'var(--ck-focus-color)',
'--ck-dropdown-button-color': '#999999',
'--ck-dropdown-button-box-shadow': '0 0 0 1px #A0A0A0, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-dropdown-button-background': 'linear-gradient(180deg, #FFFFFF 0%, #F0F0EA 100%), #F5F5F1',
'--ck-dropdown-button-hover-background': 'linear-gradient(0deg, #FFFFFF 0%, #F0F0EA 100%), #F5F5F1',
'--ck-dropdown-pending-color': '#ACA899',
'--ck-dropdown-active-color': '#FFFFFF',
'--ck-dropdown-active-static-color': '#ACA899',
'--ck-dropdown-active-background': '#3F69BF',
'--ck-dropdown-active-border-radius': '0',
'--ck-dropdown-active-inset': '-12px',
'--ck-dropdown-color': '#ACA899',
'--ck-dropdown-background': '#FFFFFF',
'--ck-dropdown-box-shadow': 'inset 0 0 0 1px #ACA899, 2px 2px 7px rgba(0, 0, 0, 0.15)',
'--ck-dropdown-border-radius': '0',
'--ck-alert-color': '#ACA899',
'--ck-alert-background': 'linear-gradient(180deg, #FBFBFB 0%, #EFEFEE 100%)',
'--ck-alert-box-shadow': 'inset 0 0 0 1px #919B9C, 1px 1px 2px rgba(0, 0, 0, 0.15), inset -2px -2px 0px #FFFFFF',
'--ck-alert-border-radius': '0',
/** Graphics options for our themes, not to be exposed to devs */
'--ck-graphic-primary-color': '#333333',
'--ck-graphic-primary-background': '#FFFFFF',
/*
'--ck-graphic-secondary-color': '#7D7D7D',
'--ck-graphic-secondary-background':
'linear-gradient(180deg, #FFFFFF 0%, #F0F0EA 100%), #F5F5F1',
'--ck-graphic-secondary-box-shadow':
'inset 0 0 0 1px #003C74, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 0px #97B9EC, inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-graphic-compass-color': '#7D7D7D',
*/
'--ck-graphic-compass-background': '#FFFFFF',
/*
'--ck-graphic-compass-box-shadow':
'inset 0 0 0 1px #003C74, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 0px #97B9EC, inset -1px -2px 2px rgba(0, 0, 0, 0.2)',
'--ck-graphic-globe-background': '#ffffff',
'--ck-graphic-globe-lines': '#808080',
'--ck-graphic-globe-box-shadow':
' 0 0 0 1px #999A9E, 1px 1px 0px rgba(255, 255, 255, 0.75), -1px -1px 0px rgba(0, 0, 0, 0.05), inset 0px 0px 0px 0px #97B9EC',
*/
'--ck-siwe-border': '#919B9C'
};
/*
Copyright 2018 - 2022 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/
var retro = {
'--ck-font-family': '"SF Pro Rounded",ui-rounded,"Nunito",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,"Apple Color Emoji",Arial,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"',
'--ck-border-radius': '8px',
'--ck-connectbutton-font-size': '17px',
'--ck-connectbutton-color': '#000000',
'--ck-connectbutton-background': '#ffffff',
'--ck-connectbutton-box-shadow': '-4px 4px 0px #000000, inset 0 0 0 2px #000000',
'--ck-connectbutton-border-radius': '8px',
'--ck-connectbutton-hover-background': '#F3EDE8',
'--ck-connectbutton-active-box-shadow': '0 0 0 0 #000000, inset 0 0 0 2px #000000',
'--ck-connectbutton-balance-color': '#000000',
'--ck-connectbutton-balance-background': '#F3EDE8',
'--ck-connectbutton-balance-box-shadow': '-4px 4px 0px #000000, inset 0 0 0 2px #000000',
'--ck-connectbutton-balance-hover-background': '#eee5dd',
'--ck-connectbutton-balance-connectbutton-box-shadow': '-4px 8px 0px -4px #000000, inset 0 0 0 2px #000000',
'--ck-connectbutton-balance-connectbutton-border-radius': '0px 8px 8px 0',
'--ck-primary-button-color': '#373737',
'--ck-primary-button-background': '#ffffff',
'--ck-primary-button-box-shadow': 'inset 0 0 0 2px #000000, -4px 4px 0 0 #000000',
'--ck-primary-button-border-radius': '8px',
'--ck-primary-button-hover-background': '#F3EDE8',
'--ck-primary-button-hover-box-shadow': 'inset 0 0 0 2px #000000, -0px 0px 0 0 #000000',
'--ck-secondary-button-border-radius': '8px',
'