diff --git a/cashtab/extension/public/manifest.json b/cashtab/extension/public/manifest.json --- a/cashtab/extension/public/manifest.json +++ b/cashtab/extension/public/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "Cashtab", "description": "A browser-integrated eCash wallet from Bitcoin ABC", - "version": "3.27.0", + "version": "3.28.0", "content_scripts": [ { "matches": ["file://*/*", "http://*/*", "https://*/*"], diff --git a/cashtab/package-lock.json b/cashtab/package-lock.json --- a/cashtab/package-lock.json +++ b/cashtab/package-lock.json @@ -1,12 +1,12 @@ { "name": "cashtab", - "version": "2.27.1", + "version": "2.28.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cashtab", - "version": "2.27.1", + "version": "2.28.0", "dependencies": { "@bitgo/utxo-lib": "^9.33.0", "@zxing/browser": "^0.1.4", diff --git a/cashtab/package.json b/cashtab/package.json --- a/cashtab/package.json +++ b/cashtab/package.json @@ -1,6 +1,6 @@ { "name": "cashtab", - "version": "2.27.1", + "version": "2.28.0", "private": true, "scripts": { "start": "node scripts/start.js", diff --git a/cashtab/src/components/App/App.js b/cashtab/src/components/App/App.js --- a/cashtab/src/components/App/App.js +++ b/cashtab/src/components/App/App.js @@ -2,7 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { HomeIcon, SendIcon, @@ -18,7 +18,7 @@ TokensIcon, } from 'components/Common/CustomIcons'; import Spinner from 'components/Common/Spinner'; -import styled, { ThemeProvider, createGlobalStyle } from 'styled-components'; +import { ThemeProvider } from 'styled-components'; import { theme } from 'assets/styles/theme'; import Home from 'components/Home/Home'; import Receive from 'components/Receive/Receive'; @@ -56,344 +56,34 @@ import WebApp from 'components/AppModes/WebApp'; import Extension from 'components/AppModes/Extension'; import ExtensionHeader from 'components/Common/ExtensionHeader'; -import { WalletInfoCtn } from 'components/Common/Atoms'; import WalletLabel from 'components/Common/WalletLabel.js'; import BalanceHeader from 'components/Common/BalanceHeader'; import { isValidCashtabWallet } from 'validation'; -import { ToastContainer, Bounce } from 'react-toastify'; +import { Bounce } from 'react-toastify'; +import { + ExtensionFrame, + GlobalStyle, + CashtabNotification, + CustomApp, + Footer, + Header, + NavWrapper, + NavItem, + NavIcon, + NavMenu, + NavButton, + WalletBody, + ScreenWrapper, + WalletCtn, + HeaderCtn, + CashtabLogo, + EasterEgg, + NavHeader, + WalletInfoCtn, +} from 'components/App/styles'; +import WalletHeaderActions from 'components/Common/WalletHeaderActions'; import 'react-toastify/dist/ReactToastify.min.css'; -const CashtabNotification = styled(ToastContainer)` - .Toastify__progress-bar-theme--dark { - background: #00abe7; - } - .Toastify__progress-bar-theme--light { - background: #00abe7; - } -`; - -const ExtensionFrame = createGlobalStyle` - html, body { - min-width: 400px; - min-height: 600px; - } -`; - -const GlobalStyle = createGlobalStyle` - *::placeholder { - color: ${props => props.theme.forms.placeholder} !important; - } - a { - color: ${props => props.theme.eCashBlue} - &:hover { - color: ${props => props.theme.eCashPurple} - text-decoration: none; - } - } -`; - -const CustomApp = styled.div` - text-align: center; - font-family: 'Poppins', sans-serif; - background-color: ${props => props.theme.backgroundColor}; - background-size: 100px 171px; - background-image: ${props => props.theme.backgroundImage}; - background-attachment: fixed; -`; - -const Footer = styled.div` - z-index: 2; - height: 80px; - border-top: 1px solid rgba(255, 255, 255, 0.5); - background-color: ${props => props.theme.headerAndFooterBg}; - position: fixed; - bottom: 0; - width: 500px; - display: flex; - align-items: center; - justify-content: space-between; - padding: 0; - @media (max-width: 768px) { - width: 100%; - } -`; - -const Header = styled.div` - z-index: 2; - - background-color: ${props => props.theme.headerAndFooterBg}; - position: sticky; - top: 0; - width: 500px; - align-items: center; - justify-content: space-between; - - @media (max-width: 768px) { - width: 100%; - } -`; - -const NavWrapper = styled.div` - width: 100%; - height: 100%; - cursor: pointer; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 1.3rem; - margin-bottom: 5px; -`; - -const NavIcon = styled.span` - @media (hover: hover) { - ${NavWrapper}:hover & { - background-color: ${props => - props.clicked ? 'transparent' : props.theme.eCashPurple}; - ::before, - ::after { - background-color: ${props => props.theme.eCashPurple}; - } - } - } - - position: relative; - background-color: ${props => - props.clicked ? 'transparent' : props.theme.buttons.primary.color}; - width: 2rem; - height: 2px; - display: inline-block; - transition: transform 300ms, top 300ms, background-color 300ms; - &::before, - &::after { - content: ''; - background-color: ${props => props.theme.buttons.primary.color}; - width: 2rem; - height: 2px; - display: inline-block; - position: absolute; - left: 0; - transition: transform 300ms, top 300ms, background-color 300ms; - } - &::before { - top: ${props => (props.clicked ? '0' : '-0.8rem')}; - transform: ${props => (props.clicked ? 'rotate(135deg)' : 'rotate(0)')}; - } - &::after { - top: ${props => (props.clicked ? '0' : '0.8rem')}; - transform: ${props => - props.clicked ? 'rotate(-135deg)' : 'rotate(0)'}; - } -`; - -const NavMenu = styled.div` - position: fixed; - float: right; - margin-right: 30px; - bottom: 5rem; - display: flex; - width: 8.23rem; - flex-direction: column; - border: ${props => (props.open ? '1px solid' : '0px solid')}; - border-color: ${props => - props.open ? props.theme.contrast : 'transparent'}; - justify-content: center; - align-items: center; - - @media (max-width: 768px) { - right: 0; - margin-right: 0; - } - overflow: hidden; - transition: ${props => - props.open - ? 'max-height 1000ms ease-in-out , border-color 800ms ease-in-out, border-width 800ms ease-in-out' - : 'max-height 300ms cubic-bezier(0, 1, 0, 1), border-color 600ms ease-in-out, border-width 800ms ease-in-out'}; - max-height: ${props => (props.open ? '100rem' : '0')}; -`; - -const NavItem = styled.button` - display: flex; - justify-content: space-between; - margin-left: 3px; - text-align: left; - align-items: center; - width: 100%; - white-space: nowrap; - height: 3rem; - background-color: ${props => props.theme.walletBackground}; - border: none; - color: ${props => props.theme.contrast}; - gap: 6px; - cursor: pointer; - &:hover { - color: ${props => props.theme.eCashPurple}; - svg, - g, - path { - fill: ${props => props.theme.eCashPurple}; - } - } - svg { - fill: ${props => props.theme.contrast}; - max-width: 33px; - height: auto; - flex: 1; - } - g, - path { - fill: ${props => props.theme.contrast}; - } - p { - flex: 2; - margin: 0; - } - ${({ active, ...props }) => - active && - ` - color: ${props.theme.navActive}; - svg, g, path { - fill: ${props.theme.navActive}; - } - `} -`; - -export const NavButton = styled.button` - :focus, - :active { - outline: none; - } - @media (hover: hover) { - :hover { - svg, - g, - path { - fill: ${props => props.theme.eCashPurple}; - } - } - } - width: 100%; - height: 100%; - cursor: pointer; - padding: 0; - background: none; - border: none; - font-size: 10px; - svg { - fill: ${props => props.theme.contrast}; - width: 30px; - height: 30px; - } - g, - path { - fill: ${props => props.theme.contrast}; - } - ${({ active, ...props }) => - active && - ` - color: ${props.theme.navActive}; - svg, g, path { - fill: ${props.theme.navActive}; - } - `} -`; - -export const WalletBody = styled.div` - display: flex; - align-items: center; - justify-content: center; - width: 100%; - min-height: 100vh; -`; -export const ScreenWrapper = styled.div` - padding: 0px 30px; - @media (max-width: 768px) { - padding: 0px 15px; - } -`; - -export const WalletCtn = styled.div` - position: relative; - width: 500px; - min-height: 100vh; - padding: 0 0 100px; - background: ${props => props.theme.walletBackground}; - -webkit-box-shadow: 0px 0px 24px 1px ${props => props.theme.shadow}; - -moz-box-shadow: 0px 0px 24px 1px ${props => props.theme.shadow}; - box-shadow: 0px 0px 24px 1px ${props => props.theme.shadow}; - @media (max-width: 768px) { - width: 100%; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } -`; - -export const HeaderCtn = styled.div` - display: flex; - flex-direction: column; - gap: 1rem; - align-items: center; - justify-content: center; - width: 100%; - padding: 15px 0; -`; - -export const CashtabLogo = styled.img` - width: 120px; - @media (max-width: 768px) { - width: 110px; - } -`; - -// AbcLogo styled component not included in extension, replaced by open in new tab link -export const AbcLogo = styled.img` - width: 150px; - @media (max-width: 768px) { - width: 120px; - } -`; - -// Easter egg styled component not used in extension/src/components/App.js -export const EasterEgg = styled.img` - position: fixed; - bottom: -195px; - margin: 0; - right: 10%; - transition-property: bottom; - transition-duration: 1.5s; - transition-timing-function: ease-out; - - :hover { - bottom: 0; - } - - @media screen and (max-width: 1250px) { - display: none; - } -`; - -const NavHeader = styled.div` - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 1rem; - color: ${props => props.theme.navActive}; - svg { - padding: 0.2rem; - fill: ${props => props.theme.navActive}; - height: 33px; - width: 30px; - } - g { - fill: ${props => props.theme.navActive}; - } - path { - fill: ${props => props.theme.navActive}; - } -`; - const App = () => { const ContextValue = React.useContext(WalletContext); const { @@ -409,6 +99,7 @@ const { balanceSats } = walletState; const [spinner, setSpinner] = useState(false); const [navMenuClicked, setNavMenuClicked] = useState(false); + const [scrollYPosition, setScrollYPosition] = React.useState(0); const handleNavMenuClick = () => setNavMenuClicked(!navMenuClicked); // If wallet is unmigrated, do not show page until it has migrated // An invalid wallet will be validated/populated after the next API call, ETA 10s @@ -416,6 +107,24 @@ const location = useLocation(); const navigate = useNavigate(); + const handleScroll = () => { + setScrollYPosition(window.scrollY); + }; + + // To avoid content jump flickering without using overflow-anchor, + // This cannot exceed the height of the minified wallet menu + // overflow-anchor css rule is not supported across all browsers and devices + // WalletInfoCtn has max-height set to 90px in styles.js + const PIN_MINIFIED_WALLET_MENU_SCROLLY = 42; + const minifiedMenu = scrollYPosition >= PIN_MINIFIED_WALLET_MENU_SCROLLY; + + useEffect(() => { + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + const selectedKey = location && location.pathname ? location.pathname.substr(1) : ''; @@ -552,20 +261,38 @@ )} - + + {minifiedMenu && ( + + )} diff --git a/cashtab/src/components/App/styles.js b/cashtab/src/components/App/styles.js new file mode 100644 --- /dev/null +++ b/cashtab/src/components/App/styles.js @@ -0,0 +1,357 @@ +// Copyright (c) 2024 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import styled, { createGlobalStyle } from 'styled-components'; +import { ToastContainer } from 'react-toastify'; + +export const ExtensionFrame = createGlobalStyle` + html, body { + min-width: 400px; + min-height: 600px; + } +`; + +export const GlobalStyle = createGlobalStyle` + *::placeholder { + color: ${props => props.theme.forms.placeholder} !important; + } + a { + color: ${props => props.theme.eCashBlue} + &:hover { + color: ${props => props.theme.eCashPurple} + text-decoration: none; + } + } +`; + +export const CashtabNotification = styled(ToastContainer)` + .Toastify__progress-bar-theme--dark { + background: #00abe7; + } + .Toastify__progress-bar-theme--light { + background: #00abe7; + } +`; + +export const CustomApp = styled.div` + text-align: center; + font-family: 'Poppins', sans-serif; + background-color: ${props => props.theme.backgroundColor}; + background-size: 100px 171px; + background-image: ${props => props.theme.backgroundImage}; + background-attachment: fixed; +`; + +export const Footer = styled.div` + z-index: 2; + height: 80px; + border-top: 1px solid rgba(255, 255, 255, 0.5); + background-color: ${props => props.theme.headerAndFooterBg}; + position: fixed; + bottom: 0; + width: 500px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0; + @media (max-width: 768px) { + width: 100%; + } +`; + +export const Header = styled.div` + position: sticky; + z-index: 2; + background-color: ${props => props.theme.headerAndFooterBg}; + width: 500px; + align-items: center; + justify-content: space-between; + @media (max-width: 768px) { + width: 100%; + } + box-sizing: border-box; + *, + *:before, + *:after { + box-sizing: inherit; + } +`; + +export const NavWrapper = styled.div` + width: 100%; + height: 100%; + cursor: pointer; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 1.3rem; + margin-bottom: 5px; +`; + +export const NavIcon = styled.span` + @media (hover: hover) { + ${NavWrapper}:hover & { + background-color: ${props => + props.clicked ? 'transparent' : props.theme.eCashPurple}; + ::before, + ::after { + background-color: ${props => props.theme.eCashPurple}; + } + } + } + + position: relative; + background-color: ${props => + props.clicked ? 'transparent' : props.theme.buttons.primary.color}; + width: 2rem; + height: 2px; + display: inline-block; + transition: transform 300ms, top 300ms, background-color 300ms; + &::before, + &::after { + content: ''; + background-color: ${props => props.theme.buttons.primary.color}; + width: 2rem; + height: 2px; + display: inline-block; + position: absolute; + left: 0; + transition: transform 300ms, top 300ms, background-color 300ms; + } + &::before { + top: ${props => (props.clicked ? '0' : '-0.8rem')}; + transform: ${props => (props.clicked ? 'rotate(135deg)' : 'rotate(0)')}; + } + &::after { + top: ${props => (props.clicked ? '0' : '0.8rem')}; + transform: ${props => + props.clicked ? 'rotate(-135deg)' : 'rotate(0)'}; + } +`; + +export const NavMenu = styled.div` + position: fixed; + float: right; + margin-right: 30px; + bottom: 5rem; + display: flex; + width: 8.23rem; + flex-direction: column; + border: ${props => (props.open ? '1px solid' : '0px solid')}; + border-color: ${props => + props.open ? props.theme.contrast : 'transparent'}; + justify-content: center; + align-items: center; + + @media (max-width: 768px) { + right: 0; + margin-right: 0; + } + overflow: hidden; + transition: ${props => + props.open + ? 'max-height 1000ms ease-in-out , border-color 800ms ease-in-out, border-width 800ms ease-in-out' + : 'max-height 300ms cubic-bezier(0, 1, 0, 1), border-color 600ms ease-in-out, border-width 800ms ease-in-out'}; + max-height: ${props => (props.open ? '100rem' : '0')}; +`; + +export const NavItem = styled.button` + display: flex; + justify-content: space-between; + margin-left: 3px; + text-align: left; + align-items: center; + width: 100%; + white-space: nowrap; + height: 3rem; + background-color: ${props => props.theme.walletBackground}; + border: none; + color: ${props => props.theme.contrast}; + gap: 6px; + cursor: pointer; + &:hover { + color: ${props => props.theme.eCashPurple}; + svg, + g, + path { + fill: ${props => props.theme.eCashPurple}; + } + } + svg { + fill: ${props => props.theme.contrast}; + max-width: 33px; + height: auto; + flex: 1; + } + g, + path { + fill: ${props => props.theme.contrast}; + } + p { + flex: 2; + margin: 0; + } + ${({ active, ...props }) => + active && + ` + color: ${props.theme.navActive}; + svg, g, path { + fill: ${props.theme.navActive}; + } + `} +`; + +export const NavButton = styled.button` + :focus, + :active { + outline: none; + } + @media (hover: hover) { + :hover { + svg, + g, + path { + fill: ${props => props.theme.eCashPurple}; + } + } + } + width: 100%; + height: 100%; + cursor: pointer; + padding: 0; + background: none; + border: none; + font-size: 10px; + svg { + fill: ${props => props.theme.contrast}; + width: 30px; + height: 30px; + } + g, + path { + fill: ${props => props.theme.contrast}; + } + ${({ active, ...props }) => + active && + ` + color: ${props.theme.navActive}; + svg, g, path { + fill: ${props.theme.navActive}; + } + `} +`; + +export const WalletBody = styled.div` + display: flex; + align-items: center; + justify-content: center; + width: 100%; + min-height: 100vh; +`; +export const ScreenWrapper = styled.div` + padding: 0px 30px; + @media (max-width: 768px) { + padding: 0px 15px; + } +`; + +export const WalletCtn = styled.div` + position: relative; + width: 500px; + min-height: 100vh; + padding: 0 0 100px; + background: ${props => props.theme.walletBackground}; + -webkit-box-shadow: 0px 0px 24px 1px ${props => props.theme.shadow}; + -moz-box-shadow: 0px 0px 24px 1px ${props => props.theme.shadow}; + box-shadow: 0px 0px 24px 1px ${props => props.theme.shadow}; + @media (max-width: 768px) { + width: 100%; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } +`; + +export const HeaderCtn = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + padding: 15px 0; + gap: 6px; +`; + +export const CashtabLogo = styled.img` + width: 120px; + @media (max-width: 768px) { + width: 110px; + } +`; + +// Easter egg styled component not used in extension/src/components/App.js +export const EasterEgg = styled.img` + position: fixed; + bottom: -195px; + margin: 0; + right: 10%; + transition-property: bottom; + transition-duration: 1.5s; + transition-timing-function: ease-out; + + :hover { + bottom: 0; + } + + @media screen and (max-width: 1250px) { + display: none; + } +`; + +export const NavHeader = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 1rem; + color: ${props => props.theme.navActive}; + svg { + padding: 0.2rem; + fill: ${props => props.theme.navActive}; + height: 33px; + width: 30px; + } + g { + fill: ${props => props.theme.navActive}; + } + path { + fill: ${props => props.theme.navActive}; + } +`; + +export const WalletInfoCtn = styled.div` + ${props => + props.minified && + `display: flex; + align-items: center; + justify-content: space-between; + position: fixed; + top: 0; + width: 500px; + @media (max-width: 768px) { + width: 100%; + } + max-height: 90px; + overflow: hidden; + `} + background: ${props => props.theme.walletInfoContainer}; + padding: 12px 20px; + box-sizing: border-box; + *, + *:before, + *:after { + box-sizing: inherit; + } +`; diff --git a/cashtab/src/components/Common/Atoms.js b/cashtab/src/components/Common/Atoms.js --- a/cashtab/src/components/Common/Atoms.js +++ b/cashtab/src/components/Common/Atoms.js @@ -28,11 +28,6 @@ color: ${props => props.theme.primary}; `; -export const WalletInfoCtn = styled.div` - background: ${props => props.theme.walletInfoContainer}; - padding: 12px 20px; -`; - export const TokenParamLabel = styled.span` font-weight: bold; `; diff --git a/cashtab/src/components/Common/BalanceHeader.js b/cashtab/src/components/Common/BalanceHeader.js --- a/cashtab/src/components/Common/BalanceHeader.js +++ b/cashtab/src/components/Common/BalanceHeader.js @@ -12,15 +12,20 @@ import { toXec } from 'wallet'; import { CashtabLoader } from 'components/Common/Spinner'; import PropTypes from 'prop-types'; +import { toFormattedXec } from 'utils/formatting'; export const BalanceXec = styled.div` width: 100%; - font-size: 28px; + font-size: ${props => (props.minified ? '16px' : '28px')}; + ${props => + props.minified && + `text-align: center; + `} margin-bottom: 0px; font-weight: bold; line-height: 1.4em; @media (max-width: 768px) { - font-size: 24px; + font-size: ${props => (props.minified ? '16px' : '24px')}; } color: ${props => props.balanceVisible ? 'transparent' : props.theme.contrast}; @@ -51,12 +56,13 @@ settings = new CashtabSettings(), fiatPrice = null, userLocale = 'en-US', + minified = false, }) => { // If navigator.language is undefined, default to en-US userLocale = typeof userLocale === 'undefined' ? 'en-US' : userLocale; const renderBalanceHeader = Number.isInteger(balanceSats); - const renderFiatValues = typeof fiatPrice === 'number'; + const renderFiatValues = typeof fiatPrice === 'number' && !minified; let balanceXec, formattedBalanceXec, @@ -66,10 +72,12 @@ // Display XEC balance formatted for user's browser locale balanceXec = toXec(balanceSats); - formattedBalanceXec = balanceXec.toLocaleString(userLocale, { - minimumFractionDigits: appConfig.cashDecimals, - maximumFractionDigits: appConfig.cashDecimals, - }); + formattedBalanceXec = minified + ? toFormattedXec(balanceSats, userLocale) + : balanceXec.toLocaleString(userLocale, { + minimumFractionDigits: appConfig.cashDecimals, + maximumFractionDigits: appConfig.cashDecimals, + }); if (renderFiatValues) { // Display fiat balance formatted for user's browser locale @@ -97,6 +105,7 @@ {formattedBalanceXec} {appConfig.ticker}{' '} @@ -136,6 +145,7 @@ ]), fiatPrice: PropTypes.number, userLocale: PropTypes.string, + minified: PropTypes.bool, }; export default BalanceHeader; diff --git a/cashtab/src/components/Common/Buttons.js b/cashtab/src/components/Common/Buttons.js --- a/cashtab/src/components/Common/Buttons.js +++ b/cashtab/src/components/Common/Buttons.js @@ -171,7 +171,6 @@ data: PropTypes.string, showToast: PropTypes.bool, customMsg: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), - children: PropTypes.node, }; export default PrimaryButton; diff --git a/cashtab/src/components/Common/WalletHeaderActions.js b/cashtab/src/components/Common/WalletHeaderActions.js new file mode 100644 --- /dev/null +++ b/cashtab/src/components/Common/WalletHeaderActions.js @@ -0,0 +1,52 @@ +// Copyright (c) 2024 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import * as React from 'react'; +import PropTypes from 'prop-types'; +import styled from 'styled-components'; +import { CopyIconButton } from 'components/Common/Buttons'; +import HideBalanceSwitch from 'components/Common/HideBalanceSwitch'; + +export const WalletHideBalanceCopyAddress = styled.div` + display: flex; + align-items: baseline; + gap: 6px; + svg { + height: 21px; + width: 21px; + } +`; + +const WalletHeaderActions = ({ + address = '', + settings, + updateCashtabState, +}) => { + return ( + + + + + ); +}; + +WalletHeaderActions.propTypes = { + address: PropTypes.string, + settings: PropTypes.oneOfType([ + PropTypes.shape({ + fiatCurrency: PropTypes.string, + sendModal: PropTypes.bool, + autoCameraOn: PropTypes.bool, + hideMessagesFromUnknownSender: PropTypes.bool, + toggleShowHideBalance: PropTypes.bool, + }), + PropTypes.bool, + ]), + updateCashtabState: PropTypes.func, +}; + +export default WalletHeaderActions; diff --git a/cashtab/src/components/Common/WalletLabel.js b/cashtab/src/components/Common/WalletLabel.js --- a/cashtab/src/components/Common/WalletLabel.js +++ b/cashtab/src/components/Common/WalletLabel.js @@ -5,27 +5,21 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; -import CopyToClipboard from 'components/Common/CopyToClipboard'; -import HideBalanceSwitch from './HideBalanceSwitch'; -import { CopyPasteIcon } from 'components/Common/CustomIcons'; import { getWalletsForNewActiveWallet } from 'wallet'; import { Event } from 'components/Common/GoogleAnalytics'; import { getTextWidth } from 'helpers'; +import WalletHeaderActions from 'components/Common/WalletHeaderActions'; const LabelCtn = styled.div` display: flex; align-items: center; - justify-content: center; + justify-content: ${props => (props.minified ? 'space-between' : 'center')}; gap: 3%; svg { - height: 24px; - width: 24px; + height: 21px; + width: 21px; } -`; -const SwitchAndIcon = styled.div` - display: flex; - align-items: baseline; - gap: 6px; + width: 100%; `; const EXTRA_WIDTH_FOR_SELECT = 32; @@ -34,9 +28,18 @@ 'Segoe UI', 'Roboto', 'Oxygen', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; width: ${props => - getTextWidth(document, props.value, '18px Poppins') + - EXTRA_WIDTH_FOR_SELECT}px; - max-width: 90%; + props.minified + ? '100%' + : `${ + getTextWidth(document, props.value, '18px Poppins') + + EXTRA_WIDTH_FOR_SELECT + }px`}; + ${props => + !props.minified && + `max-width: 90%; + @media (max-width: 450px) { + max-width: 70%; + }`}; cursor: pointer; font-size: 18px; padding: 6px; @@ -44,6 +47,8 @@ border: none; border-radius: 9px; background-color: transparent; + transition: width 0.2s; + text-overflow: ellipsis; `; const WalletOption = styled.option` text-align: left; @@ -54,7 +59,7 @@ } `; -const WalletLabel = ({ wallets, settings, updateCashtabState }) => { +const WalletLabel = ({ wallets, settings, updateCashtabState, minified }) => { const address = wallets[0].paths.get(1899).address; const handleSelectWallet = e => { @@ -84,8 +89,9 @@ }; return ( - + handleSelectWallet(e)} @@ -97,15 +103,13 @@ ))} - - - - - - + )} ); }; @@ -136,6 +140,7 @@ PropTypes.bool, ]), updateCashtabState: PropTypes.func, + minified: PropTypes.bool, }; export default WalletLabel;