From 293f311ef9094d5af8791c6f82d715c7a7b048ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20V=C3=A1clav=C3=ADk?= Date: Thu, 4 Jul 2024 20:41:13 +0200 Subject: [PATCH] style(suite): Container query in Sidebar --- .../ResizableBox/ResizableBox.stories.tsx | 2 + .../components/ResizableBox/ResizableBox.tsx | 2 + .../DeviceSelector/DeviceSelector.tsx | 13 +- .../DeviceSelector/DeviceStatus.tsx | 21 ++- .../Sidebar/CollapsedSidebarOnly.tsx | 17 ++ .../Sidebar/ExpandedSidebarOnly.tsx | 17 ++ .../SuiteLayout/Sidebar/HelperIcons.tsx | 39 ++-- .../SuiteLayout/Sidebar/NavigationItem.tsx | 24 ++- .../SuiteLayout/Sidebar/QuickActions.tsx | 5 +- .../layouts/SuiteLayout/Sidebar/Sidebar.tsx | 5 +- .../layouts/SuiteLayout/Sidebar/consts.ts | 4 + .../WalletLayout/AccountsMenu/AccountItem.tsx | 175 ++++++++++-------- .../AccountsMenu/AccountsList.tsx | 33 +++- .../AccountsMenu/AccountsMenu.tsx | 3 +- 14 files changed, 237 insertions(+), 123 deletions(-) create mode 100644 packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/CollapsedSidebarOnly.tsx create mode 100644 packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/ExpandedSidebarOnly.tsx create mode 100644 packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/consts.ts diff --git a/packages/components/src/components/ResizableBox/ResizableBox.stories.tsx b/packages/components/src/components/ResizableBox/ResizableBox.stories.tsx index dfa7261f8df7..cbe2798886e9 100644 --- a/packages/components/src/components/ResizableBox/ResizableBox.stories.tsx +++ b/packages/components/src/components/ResizableBox/ResizableBox.stories.tsx @@ -38,6 +38,8 @@ export const ResizableBox: StoryObj = { height: 100, minHeight: 50, maxHeight: 300, + disabledWidthIntervals: [[51, 100]], + disabledHeightIntervals: undefined, updateWidthOnWindowResize: false, updateHeightOnWindowResize: false, }, diff --git a/packages/components/src/components/ResizableBox/ResizableBox.tsx b/packages/components/src/components/ResizableBox/ResizableBox.tsx index 9ac247278ddd..e80db450a45f 100644 --- a/packages/components/src/components/ResizableBox/ResizableBox.tsx +++ b/packages/components/src/components/ResizableBox/ResizableBox.tsx @@ -19,6 +19,8 @@ export type ResizableBoxProps = { updateWidthOnWindowResize?: boolean; updateHeightOnWindowResize?: boolean; zIndex?: ZIndexValues; + disabledWidthIntervals?: Array>; + disabledHeightIntervals?: Array>; }; type ResizerHandlersProps = { diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceSelector.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceSelector.tsx index 50f0e19f5979..3b774e2e4c8e 100644 --- a/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceSelector.tsx +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceSelector.tsx @@ -10,6 +10,7 @@ import { borders, spacingsPx } from '@trezor/theme'; import { focusStyleTransition, getFocusShadowStyle } from '@trezor/components/src/utils/utils'; import { SidebarDeviceStatus } from './SidebarDeviceStatus'; import { ViewOnlyTooltip } from 'src/views/view-only/ViewOnlyTooltip'; +import { ExpandedSidebarOnly } from '../Sidebar/ExpandedSidebarOnly'; const CaretContainer = styled.div` background: transparent; @@ -111,11 +112,13 @@ export const DeviceSelector = () => { > - {selectedDevice && selectedDevice.state && ( - - - - )} + + {selectedDevice && selectedDevice.state && ( + + + + )} + diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceStatus.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceStatus.tsx index 61a16632cd7c..f733ebc87dd6 100644 --- a/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceStatus.tsx +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/DeviceSelector/DeviceStatus.tsx @@ -7,6 +7,7 @@ import { TrezorDevice } from 'src/types/suite'; import { spacingsPx } from '@trezor/theme'; import { RotateDeviceImage } from '@trezor/components'; import { DeviceStatusText } from 'src/views/suite/SwitchDevice/DeviceItem/DeviceStatusText'; +import { ExpandedSidebarOnly } from '../Sidebar/ExpandedSidebarOnly'; type DeviceStatusProps = { deviceModel: DeviceModelInternal; @@ -53,15 +54,17 @@ export const DeviceStatus = ({ /> - {device && ( - - - - )} + + {device && ( + + + + )} + ); }; diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/CollapsedSidebarOnly.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/CollapsedSidebarOnly.tsx new file mode 100644 index 000000000000..269836a349f2 --- /dev/null +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/CollapsedSidebarOnly.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import styled from 'styled-components'; +import { isExpandedSidebar } from './consts'; + +const Container = styled.div` + @container ${isExpandedSidebar} { + display: none; + } +`; + +type Props = { + children: React.ReactNode; +}; + +export const CollapsedSidebarOnly = ({ children }: Props) => { + return {children}; +}; diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/ExpandedSidebarOnly.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/ExpandedSidebarOnly.tsx new file mode 100644 index 000000000000..dc2f889d38f6 --- /dev/null +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/ExpandedSidebarOnly.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import styled from 'styled-components'; +import { isCollapsedSidebar } from './consts'; + +const Container = styled.div` + @container ${isCollapsedSidebar} { + display: none; + } +`; + +type Props = { + children: React.ReactNode; +}; + +export const ExpandedSidebarOnly = ({ children }: Props) => { + return {children}; +}; diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/HelperIcons.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/HelperIcons.tsx index bed916515339..81c808f8ff85 100644 --- a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/HelperIcons.tsx +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/HelperIcons.tsx @@ -4,6 +4,7 @@ import { borders, spacingsPx } from '@trezor/theme'; import { useDispatch, useSelector, useTranslation } from 'src/hooks/suite'; import { goto } from 'src/actions/suite/routerActions'; import { SettingsAnchor } from 'src/constants/suite/anchors'; +import { ExpandedSidebarOnly } from './ExpandedSidebarOnly'; const Container = styled.div` display: flex; @@ -68,24 +69,26 @@ export const HelperIcons = () => { return ( - {showExperimental && ( - - - - - - )} - {showDebugMode && ( - - - - - - )} + + {showExperimental && ( + + + + + + )} + {showDebugMode && ( + + + + + + )} + ); }; diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/NavigationItem.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/NavigationItem.tsx index 9d67449f0030..e212ca8e11b9 100644 --- a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/NavigationItem.tsx +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/NavigationItem.tsx @@ -10,7 +10,9 @@ import { useDispatch, useSelector } from 'src/hooks/suite'; import { goto } from 'src/actions/suite/routerActions'; import { MouseEvent } from 'react'; import { selectRouteName } from 'src/reducers/suite/routerReducer'; -import { useElevation } from '@trezor/components'; +import { Tooltip, useElevation } from '@trezor/components'; +import { ExpandedSidebarOnly } from './ExpandedSidebarOnly'; +import { CollapsedSidebarOnly } from './CollapsedSidebarOnly'; const StyledIcon = styled(Icon)` pointer-events: none; @@ -104,7 +106,8 @@ export const NavigationItem = ({ const isActiveRoute = routes?.some(route => route === activeRoute); - return ( + const Title = () => ; + const NavItem = () => ( - + + + </ExpandedSidebarOnly> {itemsCount && <Count>{itemsCount}</Count>} </Container> ); + + return ( + <> + <ExpandedSidebarOnly> + <NavItem /> + </ExpandedSidebarOnly> + <CollapsedSidebarOnly> + <Tooltip content={<Title />} placement="right" hasArrow> + <NavItem /> + </Tooltip> + </CollapsedSidebarOnly> + </> + ); }; diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/QuickActions.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/QuickActions.tsx index 46201463cb44..ec2ac5fd28b0 100644 --- a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/QuickActions.tsx +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/QuickActions.tsx @@ -13,6 +13,7 @@ import { ActionButton } from './ActionButton'; import { NavBackends } from './NavBackends'; import { HelperIcons } from './HelperIcons'; import { useEnabledBackends } from '../utils'; +import { ExpandedSidebarOnly } from './ExpandedSidebarOnly'; const Container = styled.div` display: flex; @@ -88,7 +89,9 @@ export const QuickActions = () => { {!isCustomBackendIconVisible && !isTorIconVisible ? ( <DescreetContainer onClick={handleDiscreetModeClick}> <Icon size={16} icon={isDiscreetModeActive ? 'HIDE' : 'SHOW'} /> - <Label>{translationString(translationLabel)} </Label> + <ExpandedSidebarOnly> + <Label>{translationString(translationLabel)} </Label> + </ExpandedSidebarOnly> </DescreetContainer> ) : ( <> diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/Sidebar.tsx b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/Sidebar.tsx index e4f72e379c80..0508e2a92fbf 100644 --- a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/Sidebar.tsx +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/Sidebar.tsx @@ -10,6 +10,7 @@ import { Elevation, mapElevationToBackground, mapElevationToBorder, zIndices } f const Container = styled.nav<{ $elevation: Elevation }>` display: flex; + container-type: inline-size; flex-direction: column; flex: 0 0 auto; height: 100%; @@ -29,8 +30,8 @@ export const Sidebar = () => { <ResizableBox directions={['right']} width={SIDEBAR_WIDTH_NUMERIC} - minWidth={230} - maxWidth={400} + minWidth={84} + maxWidth={600} zIndex={zIndices.draggableComponent} updateHeightOnWindowResize > diff --git a/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/consts.ts b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/consts.ts new file mode 100644 index 000000000000..0eb2019fc78d --- /dev/null +++ b/packages/suite/src/components/suite/layouts/SuiteLayout/Sidebar/consts.ts @@ -0,0 +1,4 @@ +export const SIDEBAR_COLLAPSED_WIDTH = 200; + +export const isCollapsedSidebar = `(max-width: ${SIDEBAR_COLLAPSED_WIDTH}px)`; +export const isExpandedSidebar = `(min-width: ${SIDEBAR_COLLAPSED_WIDTH + 1}px)`; diff --git a/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountItem.tsx b/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountItem.tsx index 581f4395d663..801bd8bc8c01 100644 --- a/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountItem.tsx +++ b/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountItem.tsx @@ -8,6 +8,7 @@ import { Icon, SkeletonRectangle, SkeletonStack, + Tooltip, TOOLTIP_DELAY_LONG, TruncateWithTooltip, } from '@trezor/components'; @@ -25,6 +26,8 @@ import { goto } from 'src/actions/suite/routerActions'; import { NavigationItemBase } from 'src/components/suite/layouts/SuiteLayout/Sidebar/NavigationItem'; import { useFormatters } from '@suite-common/formatters'; import { selectLocalCurrency } from 'src/reducers/wallet/settingsReducer'; +import { ExpandedSidebarOnly } from '../../../suite/layouts/SuiteLayout/Sidebar/ExpandedSidebarOnly'; +import { CollapsedSidebarOnly } from '../../../suite/layouts/SuiteLayout/Sidebar/CollapsedSidebarOnly'; const Wrapper = styled(NavigationItemBase)<{ $isSelected: boolean; @@ -219,7 +222,22 @@ export const AccountItem = forwardRef( // Show skeleton instead of zero balance during coinjoin initial discovery const isBalanceShown = account.backendType !== 'coinjoin' || account.status !== 'initial'; - return ( + const Name = () => ( + <AccountLabelContainer> + {type === 'coin' && ( + <AccountLabel + accountLabel={accountLabel} + accountType={accountType} + symbol={symbol} + index={index} + /> + )} + {type === 'staking' && <Translation id="TR_NAV_STAKING" />} + {type === 'tokens' && <Translation id="TR_NAV_TOKENS" />} + </AccountLabelContainer> + ); + + const AccountRow = () => ( <Wrapper $isSelected={isSelected} $isGroup={isGroup} @@ -231,87 +249,94 @@ export const AccountItem = forwardRef( > <Left>{getLeftComponent()}</Left> <Right> - <Row> - <AccountName $isSelected={isSelected} data-test={`${dataTestKey}/label`}> - <AccountLabelContainer> - {type === 'coin' && ( - <AccountLabel - accountLabel={accountLabel} - accountType={accountType} - symbol={symbol} - index={index} - /> - )} - {type === 'staking' && <Translation id="TR_NAV_STAKING" />} - {type === 'tokens' && <Translation id="TR_NAV_TOKENS" />} - </AccountLabelContainer> - <FiatAmount> - {customFiatValue && !isTestnet(symbol) ? ( - <HiddenPlaceholder> - <FiatAmountFormatter - value={customFiatValue} - currency={localCurrency} - minimumFractionDigits={0} - maximumFractionDigits={0} - /> - </HiddenPlaceholder> - ) : ( - <FiatValue - amount={formattedBalance} - symbol={symbol} - fiatAmountFormatterOptions={{ - minimumFractionDigits: 0, - maximumFractionDigits: 0, - }} - > - {({ value }) => - value ? ( - <FiatValueWrapper> - <TruncateWithTooltip - delayShow={TOOLTIP_DELAY_LONG} - > - {value} - </TruncateWithTooltip> - </FiatValueWrapper> - ) : null - } - </FiatValue> - )} - </FiatAmount> - </AccountName> - </Row> - {isBalanceShown && type !== 'tokens' && ( - <> - <Row> - <Balance> - <CoinBalance value={formattedBalance} symbol={symbol} /> - </Balance> - </Row> - </> - )} - {!isBalanceShown && ( - <SkeletonStack - $col - $margin="6px 0px 0px 0px" - $childMargin="0px 0px 8px 0px" - > - <SkeletonRectangle - width="100px" - height="16px" - animate={shouldAnimate} - /> - - {!isTestnet(account.symbol) && ( + <ExpandedSidebarOnly> + <Row> + <AccountName + $isSelected={isSelected} + data-test={`${dataTestKey}/label`} + > + <Name /> + <FiatAmount> + {customFiatValue && !isTestnet(symbol) ? ( + <HiddenPlaceholder> + <FiatAmountFormatter + value={customFiatValue} + currency={localCurrency} + minimumFractionDigits={0} + maximumFractionDigits={0} + /> + </HiddenPlaceholder> + ) : ( + <FiatValue + amount={formattedBalance} + symbol={symbol} + fiatAmountFormatterOptions={{ + minimumFractionDigits: 0, + maximumFractionDigits: 0, + }} + > + {({ value }) => + value ? ( + <FiatValueWrapper> + <TruncateWithTooltip + delayShow={TOOLTIP_DELAY_LONG} + > + {value} + </TruncateWithTooltip> + </FiatValueWrapper> + ) : null + } + </FiatValue> + )} + </FiatAmount> + </AccountName> + </Row> + {isBalanceShown && type !== 'tokens' && ( + <> + <Row> + <Balance> + <CoinBalance value={formattedBalance} symbol={symbol} /> + </Balance> + </Row> + </> + )} + {!isBalanceShown && ( + <SkeletonStack + $col + $margin="6px 0px 0px 0px" + $childMargin="0px 0px 8px 0px" + > <SkeletonRectangle width="100px" height="16px" animate={shouldAnimate} /> - )} - </SkeletonStack> - )} + + {!isTestnet(account.symbol) && ( + <SkeletonRectangle + width="100px" + height="16px" + animate={shouldAnimate} + /> + )} + </SkeletonStack> + )} + </ExpandedSidebarOnly> </Right> </Wrapper> ); + + return ( + <> + <ExpandedSidebarOnly> + <AccountRow /> + </ExpandedSidebarOnly> + <CollapsedSidebarOnly> + <Tooltip content={<Name />} placement="right" hasArrow> + <AccountRow /> + </Tooltip> + </CollapsedSidebarOnly> + </> + ); }, ); diff --git a/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsList.tsx b/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsList.tsx index 99ceaa991db5..2830d44f6847 100644 --- a/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsList.tsx +++ b/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsList.tsx @@ -10,6 +10,8 @@ import { AccountsMenuNotice } from './AccountsMenuNotice'; import styled from 'styled-components'; import { spacingsPx } from '@trezor/theme'; import { AccountSection } from './AcccountSection'; +import { ExpandedSidebarOnly } from '../../../suite/layouts/SuiteLayout/Sidebar/ExpandedSidebarOnly'; +import { CollapsedSidebarOnly } from '../../../suite/layouts/SuiteLayout/Sidebar/CollapsedSidebarOnly'; const SkeletonContainer = styled.div` margin: ${spacingsPx.xs}; @@ -86,14 +88,8 @@ export const AccountsList = ({ onItemClick }: AccountListProps) => { const isSkeletonShown = discoveryInProgress || (type === 'coinjoin' && coinjoinIsPreloading); - return ( - <AccountGroup - key={`${device.state}-${type}`} - type={type} - hideLabel={hideLabel} - hasBalance={groupHasBalance} - keepOpen={keepOpen(type)} - > + const Accounts = () => ( + <> {accounts.map(account => { const selected = !!isSelected(account); @@ -108,7 +104,26 @@ export const AccountsList = ({ onItemClick }: AccountListProps) => { ); })} {isSkeletonShown && <AccountItemSkeleton />} - </AccountGroup> + </> + ); + + return ( + <> + <ExpandedSidebarOnly> + <AccountGroup + key={`${device.state}-${type}`} + type={type} + hideLabel={hideLabel} + hasBalance={groupHasBalance} + keepOpen={keepOpen(type)} + > + <Accounts /> + </AccountGroup> + </ExpandedSidebarOnly> + <CollapsedSidebarOnly> + <Accounts /> + </CollapsedSidebarOnly> + </> ); }; diff --git a/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsMenu.tsx b/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsMenu.tsx index f8bb85f6f794..4376b1833e0b 100644 --- a/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsMenu.tsx +++ b/packages/suite/src/components/wallet/WalletLayout/AccountsMenu/AccountsMenu.tsx @@ -14,6 +14,7 @@ import { AccountsMenuNotice } from './AccountsMenuNotice'; import { getFailedAccounts, sortByCoin } from '@suite-common/wallet-utils'; import { RefreshAfterDiscoveryNeeded } from './RefreshAfterDiscoveryNeeded'; import { useScrollShadow } from '@trezor/components'; +import { ExpandedSidebarOnly } from '../../../suite/layouts/SuiteLayout/Sidebar/ExpandedSidebarOnly'; const Wrapper = styled.div` display: flex; @@ -69,7 +70,7 @@ export const AccountsMenu = () => { <Wrapper> <MenuHeader> <Row> - {!isEmpty && <AccountSearchBox />} + <ExpandedSidebarOnly>{!isEmpty && <AccountSearchBox />}</ExpandedSidebarOnly> <AddAccountButton isFullWidth={isEmpty} data-test="@account-menu/add-account"