From f5736e90593d22817bb8f7d43b20a612f9253e1d Mon Sep 17 00:00:00 2001 From: unclebill Date: Tue, 29 Mar 2022 13:27:31 +0800 Subject: [PATCH 1/2] feat: add closes https://mask.atlassian.net/browse/MF-329 --- packages/icons/general/LeftArrow.tsx | 14 ++ packages/icons/general/RightArrow.tsx | 14 ++ packages/icons/general/index.ts | 2 + .../components/InjectedComponents/PageTab.tsx | 48 ---- .../InjectedComponents/PageTabItem.tsx | 58 ----- .../InjectedComponents/ProfileTabContent.tsx | 96 ++++---- .../mask/src/components/shared/NetworkTab.tsx | 69 +----- .../plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx | 32 +-- .../plugins/NextID/components/BindingItem.tsx | 8 +- .../NextID/components/Tip/TipDialog.tsx | 33 +-- .../Savings/SNSAdaptor/SavingsDialog.tsx | 14 +- .../SNSAdaptor/SavingsDialogStyles.tsx | 28 +-- .../Trader/SNSAdaptor/trader/TraderDialog.tsx | 45 +--- .../UI/components/ConcealableTabs/index.tsx | 212 ++++++++++++++++++ packages/shared/src/UI/components/index.ts | 21 +- 15 files changed, 355 insertions(+), 339 deletions(-) create mode 100644 packages/icons/general/LeftArrow.tsx create mode 100644 packages/icons/general/RightArrow.tsx delete mode 100644 packages/mask/src/components/InjectedComponents/PageTab.tsx delete mode 100644 packages/mask/src/components/InjectedComponents/PageTabItem.tsx create mode 100644 packages/shared/src/UI/components/ConcealableTabs/index.tsx diff --git a/packages/icons/general/LeftArrow.tsx b/packages/icons/general/LeftArrow.tsx new file mode 100644 index 000000000000..edc22960430f --- /dev/null +++ b/packages/icons/general/LeftArrow.tsx @@ -0,0 +1,14 @@ +import { createIcon } from '../utils' + +export const LeftArrowIcon = createIcon( + 'LeftArrowIcon', + + + , + '0 0 25 25', +) diff --git a/packages/icons/general/RightArrow.tsx b/packages/icons/general/RightArrow.tsx new file mode 100644 index 000000000000..de71933d6a49 --- /dev/null +++ b/packages/icons/general/RightArrow.tsx @@ -0,0 +1,14 @@ +import { createIcon } from '../utils' + +export const RightArrowIcon = createIcon( + 'RightArrowIcon', + + + , + '0 0 25 25', +) diff --git a/packages/icons/general/index.ts b/packages/icons/general/index.ts index f9e5c503e831..a21efb353db5 100644 --- a/packages/icons/general/index.ts +++ b/packages/icons/general/index.ts @@ -36,6 +36,8 @@ export * from './Copy' export * from './ArrowBack' export * from './Setting' export * from './ArrowRight' +export * from './LeftArrow' +export * from './RightArrow' export * from './Trash' export * from './BackUp' export * from './Warning' diff --git a/packages/mask/src/components/InjectedComponents/PageTab.tsx b/packages/mask/src/components/InjectedComponents/PageTab.tsx deleted file mode 100644 index 58405377ce20..000000000000 --- a/packages/mask/src/components/InjectedComponents/PageTab.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { makeStyles } from '@masknet/theme' -import type { Plugin } from '@masknet/plugin-infra' -import { PageTabItem } from './PageTabItem' -import { Typography } from '@mui/material' -import { useI18N } from '../../utils' - -const useStyles = makeStyles()((theme) => ({ - root: { - display: 'flex', - gap: '8px', - flexWrap: 'wrap', - }, -})) - -export interface PageTabProps { - tabs: ({ pluginID: string } & Plugin.SNSAdaptor.ProfileTab)[] - selectedTab?: Plugin.SNSAdaptor.ProfileTab - onChange?: (tag: Plugin.SNSAdaptor.ProfileTab) => void -} - -export function PageTab(props: PageTabProps) { - const { tabs, selectedTab, onChange } = props - const { classes } = useStyles() - const { t } = useI18N() - - if (!tabs.length) { - return ( - - {t('web3_tab_hint')} - - ) - } - return ( -
- {tabs.map((x) => ( - { - onChange?.(tab) - }} - /> - ))} -
- ) -} diff --git a/packages/mask/src/components/InjectedComponents/PageTabItem.tsx b/packages/mask/src/components/InjectedComponents/PageTabItem.tsx deleted file mode 100644 index 6340061fea0c..000000000000 --- a/packages/mask/src/components/InjectedComponents/PageTabItem.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import classNames from 'classnames' -import { makeStyles } from '@masknet/theme' -import { Button } from '@mui/material' -import { type Plugin, usePluginI18NField } from '@masknet/plugin-infra/content-script' - -const borderShadows = { - dark: '0px 0px 16px 0px #FFFFFF33', - light: '0px 0px 16px 0px #65778633', - dim: '0px 0px 16px 0px #8899A633', -} -const useStyles = makeStyles()((theme) => ({ - hidden: { - display: 'none', - }, - button: { - border: `1px solid ${theme.palette.divider} !important`, - color: `${theme.palette.text.primary} !important`, - borderRadius: 9999, - '&:hover': { - boxShadow: borderShadows?.[theme.palette.mode], - border: `1px solid ${theme.palette.primary.main} !important`, - color: `${theme.palette.primary.main} !important`, - backgroundColor: 'transparent', - }, - }, - selected: { - border: `1px solid ${theme.palette.primary.main} !important`, - color: `${theme.palette.primary.main} !important`, - borderRadius: 9999, - '&:hover': { - boxShadow: borderShadows?.[theme.palette.mode], - backgroundColor: 'transparent', - }, - }, -})) - -export interface PageTabItemProps { - pluginID: string - tab: Plugin.SNSAdaptor.ProfileTab - selected?: boolean - onClick?: (tab: Plugin.SNSAdaptor.ProfileTab) => void -} - -export function PageTabItem(props: PageTabItemProps) { - const { tab, selected, onClick } = props - const { classes } = useStyles() - const translate = usePluginI18NField() - - return ( - - ) -} diff --git a/packages/mask/src/components/InjectedComponents/ProfileTabContent.tsx b/packages/mask/src/components/InjectedComponents/ProfileTabContent.tsx index 3bee5277aeb8..cfe42258a49b 100644 --- a/packages/mask/src/components/InjectedComponents/ProfileTabContent.tsx +++ b/packages/mask/src/components/InjectedComponents/ProfileTabContent.tsx @@ -1,25 +1,25 @@ import { createInjectHooksRenderer, - Plugin, PluginId, useActivatedPluginsSNSAdaptor, + usePluginI18NField, } from '@masknet/plugin-infra/content-script' import { useAvailablePlugins } from '@masknet/plugin-infra/web3' +import { ConcealableTabs } from '@masknet/shared' import { EMPTY_LIST, NextIDPlatform } from '@masknet/shared-base' import { makeStyles, useStylesExtends } from '@masknet/theme' import { useAddressNames } from '@masknet/web3-shared-evm' -import { Box, CircularProgress } from '@mui/material' +import { Box, CircularProgress, Typography } from '@mui/material' import { first } from 'lodash-unified' import { useEffect, useMemo, useState } from 'react' import { useUpdateEffect } from 'react-use' import { activatedSocialNetworkUI } from '../../social-network' import { isTwitter } from '../../social-network-adaptor/twitter.com/base' -import { MaskMessages } from '../../utils' +import { MaskMessages, useI18N } from '../../utils' import { useLocationChange } from '../../utils/hooks/useLocationChange' import { useCurrentVisitingIdentity, useLastRecognizedIdentity } from '../DataSource/useActivatedUI' import { useNextIDBoundByPlatform } from '../DataSource/useNextID' import { usePersonaConnectStatus } from '../DataSource/usePersonaConnectStatus' -import { PageTab } from '../InjectedComponents/PageTab' function getTabContent(tabId: string) { return createInjectHooksRenderer(useActivatedPluginsSNSAdaptor.visibility.useAnyMode, (x) => { @@ -31,13 +31,9 @@ function getTabContent(tabId: string) { const useStyles = makeStyles()((theme) => ({ root: {}, - tags: { - padding: theme.spacing(2), - }, - metadata: {}, content: { position: 'relative', - padding: theme.spacing(1), + padding: theme.spacing(2, 1), }, })) @@ -46,8 +42,9 @@ export interface ProfileTabContentProps extends withClasses<'text' | 'button' | export function ProfileTabContent(props: ProfileTabContentProps) { const classes = useStylesExtends(useStyles(), props) + const { t } = useI18N() const [hidden, setHidden] = useState(true) - const [selectedTab, setSelectedTab] = useState() + const [selectedTab, setSelectedTab] = useState() const currentIdentity = useLastRecognizedIdentity() const identity = useCurrentVisitingIdentity() @@ -63,31 +60,42 @@ export function ProfileTabContent(props: ProfileTabContentProps) { currentIdentity.identifier.userId === identity.identifier.userId && personaList.findIndex((persona) => persona?.persona === currentConnectedPersona?.publicHexKey) === -1 + const translate = usePluginI18NField() const activatedPlugins = useActivatedPluginsSNSAdaptor('any') - const tabs = useAvailablePlugins(activatedPlugins) - .flatMap((x) => x.ProfileTabs?.map((y) => ({ ...y, pluginID: x.ID })) ?? []) - .filter((z) => z.Utils?.shouldDisplay?.(identity, addressNames) ?? true) - .sort((a, z) => { - // order those tabs from next id first - if (a.pluginID === PluginId.NextID) return -1 - if (z.pluginID === PluginId.NextID) return 1 - - // order those tabs from collectible first - if (a.pluginID === PluginId.Collectible) return -1 - if (z.pluginID === PluginId.Collectible) return 1 - - // place those tabs from debugger last - if (a.pluginID === PluginId.Debugger) return 1 - if (z.pluginID === PluginId.Debugger) return -1 - - // place those tabs from dao before the last - if (a.pluginID === PluginId.DAO) return 1 - if (z.pluginID === PluginId.DAO) return -1 - - return a.priority - z.priority - }) - - const selectedTabComputed = selectedTab ?? first(tabs) + const availablePlugins = useAvailablePlugins(activatedPlugins) + const displayPlugins = useMemo(() => { + return availablePlugins + .flatMap((x) => x.ProfileTabs?.map((y) => ({ ...y, pluginID: x.ID })) ?? []) + .filter((z) => z.Utils?.shouldDisplay?.(identity, addressNames) ?? true) + }, [availablePlugins, identity, addressNames]) + const tabs = useMemo(() => { + return displayPlugins + .sort((a, z) => { + // order those tabs from next id first + if (a.pluginID === PluginId.NextID) return -1 + if (z.pluginID === PluginId.NextID) return 1 + + // order those tabs from collectible first + if (a.pluginID === PluginId.Collectible) return -1 + if (z.pluginID === PluginId.Collectible) return 1 + + // place those tabs from debugger last + if (a.pluginID === PluginId.Debugger) return 1 + if (z.pluginID === PluginId.Debugger) return -1 + + // place those tabs from dao before the last + if (a.pluginID === PluginId.DAO) return 1 + if (z.pluginID === PluginId.DAO) return -1 + + return a.priority - z.priority + }) + .map((x) => ({ + id: x.ID, + label: typeof x.label === 'string' ? x.label : translate(x.pluginID, x.label), + })) + }, [displayPlugins, translate]) + + const selectedTabId = selectedTab ?? first(tabs)?.id useLocationChange(() => { setSelectedTab(undefined) @@ -110,12 +118,12 @@ export function ProfileTabContent(props: ProfileTabContentProps) { }, [identity]) const ContentComponent = useMemo(() => { - const tab = + const tabId = isTwitter(activatedSocialNetworkUI) && currentAccountNotConnectPersona - ? tabs?.find((tab) => tab?.pluginID === PluginId.NextID)?.ID - : selectedTabComputed?.ID - return getTabContent(tab ?? '') - }, [selectedTabComputed?.ID, identity.identifier.userId]) + ? displayPlugins?.find((tab) => tab?.pluginID === PluginId.NextID)?.ID + : selectedTabId + return getTabContent(tabId ?? '') + }, [selectedTabId, identity.identifier.userId, tabs]) if (hidden) return null @@ -134,8 +142,14 @@ export function ProfileTabContent(props: ProfileTabContentProps) { return (
-
- +
+ {tabs.length ? ( + tabs={tabs} selectedId={selectedTabId} onChange={setSelectedTab} /> + ) : ( + + {t('web3_tab_hint')} + + )}
()((theme, props) => ({ - tab: { - backgroundColor: !props.isDashboard - ? `${theme.palette.background.default}!important` - : `${MaskColorVar.primaryBackground2}!important`, - marginRight: 1, - '&:last-child': { - marginRight: 0, - }, - }, - tabs: { - '& .MuiTabs-flexContainer': { - backgroundColor: theme.palette.background.paper, - }, - '& .Mui-selected': { - color: '#ffffff', - backgroundColor: `${theme.palette.primary.main}!important`, - }, - '& .MuiTabs-scroller': { - margin: '0 1px', - }, - '& .MuiTabs-scrollButtons': { - width: 'unset', - backgroundColor: !props.isDashboard - ? `${theme.palette.background.default}!important` - : `${MaskColorVar.primaryBackground2}!important`, - '&.Mui-disabled': { - opacity: 1, - '& svg': { - opacity: 0.3, - }, - }, - }, - }, -})) - -interface NetworkTabProps extends withClasses<'tab' | 'tabs' | 'tabPanel' | 'indicator' | 'focusTab' | 'tabPaper'> { +interface NetworkTabProps extends Omit, 'onChange'> { chains: ChainId[] setChainId: (chainId: ChainId) => void chainId: ChainId } export function NetworkTab(props: NetworkTabProps) { - const isDashboard = isDashboardPage() - const classes = useStylesExtends(useStyles({ chainLength: props.chains.length, isDashboard }), props) - const { chainId, setChainId, chains } = props - const createTabItem = (name: string, chainId: ChainId) => ({ - label: {name}, - sx: { p: 0 }, - cb: () => setChainId(chainId), - }) + const { chainId, setChainId, chains, ...rest } = props - const tabProps: AbstractTabProps = { - tabs: chains.map((chainId) => createTabItem(getChainDetailed(chainId)?.chain ?? 'Unknown', chainId)), - index: chains.indexOf(chainId), - classes, - hasOnlyOneChild: true, - scrollable: true, - } + const tabs = chains.map((chainId) => ({ + id: chainId, + label: getChainDetailed(chainId)?.chain ?? 'Unknown', + })) - return + return } diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx index 6c575395fef0..9c05659bb143 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx @@ -132,27 +132,9 @@ const useStyles = makeStyles()((theme, props) => { fontSize: 18, fontWeight: 300, }, - tab: { - height: 36, - minHeight: 36, - fontWeight: 300, - }, - tabs: { - height: 36, - minHeight: 36, - borderRadius: 4, - backgroundColor: theme.palette.background.default, - '& .Mui-selected': { - color: theme.palette.primary.contrastText, - backgroundColor: theme.palette.primary.main, - }, - }, indicator: { display: 'none', }, - tabPanel: { - marginTop: theme.spacing(3), - }, contentWrapper: { display: 'flex', flexDirection: 'column', @@ -201,13 +183,12 @@ const useStyles = makeStyles()((theme, props) => { snackbarError: { backgroundColor: '#FF5555', }, - abstractTabWrapper: { + networkTab: { position: 'sticky', top: 0, width: '100%', zIndex: 2, - paddingTop: theme.spacing(1), - paddingBottom: theme.spacing(2), + margin: theme.spacing(1, 'auto', 2), backgroundColor: theme.palette.background.paper, }, walletStatusBox: { @@ -328,9 +309,12 @@ export function ClaimAllDialog(props: ClaimAllDialogProps) {
-
- -
+
{(showNftAirdrop || loadingAirdrop) && chainId === ChainId.Matic && diff --git a/packages/mask/src/plugins/NextID/components/BindingItem.tsx b/packages/mask/src/plugins/NextID/components/BindingItem.tsx index 942963273b58..54a0438ddd20 100644 --- a/packages/mask/src/plugins/NextID/components/BindingItem.tsx +++ b/packages/mask/src/plugins/NextID/components/BindingItem.tsx @@ -73,13 +73,7 @@ export const BindingItem = memo(({ platform, identity, tipable, deletable, if (platform === NextIDPlatform.Ethereum) { return ( - + {formatEthereumAddress(identity, 4)} diff --git a/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx b/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx index 43e733d37edc..ae74732248c7 100644 --- a/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx +++ b/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx @@ -49,24 +49,9 @@ const useStyles = makeStyles()((theme) => ({ display: 'none', }, }, - abstractTabWrapper: { + networkTab: { width: '100%', - paddingTop: theme.spacing(1), - paddingBottom: theme.spacing(2), - flexShrink: 0, - }, - tab: { - height: 36, - minHeight: 36, - }, - tabPaper: { - backgroundColor: 'inherit', - }, - tabs: { - height: 36, - minHeight: 36, - margin: '0 auto', - borderRadius: 4, + margin: theme.spacing(1, 'auto', 2), }, tipForm: { flexGrow: 1, @@ -294,14 +279,12 @@ export function TipDialog({ open = false, onClose }: TipDialogProps) { title={t.tips()} titleTail={walletChip}> -
- -
+ openAddTokenDialog(true)} />
diff --git a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx index e6e4c606c614..c957354929f2 100644 --- a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx +++ b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx @@ -133,14 +133,12 @@ export function SavingsDialog({ open, onClose }: SavingsDialogProps) { ) : ( <> -
- -
+
{protocols.length === 0 ? ( diff --git a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx index 8b13fe54e7b3..a0b2f8c1bf60 100644 --- a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx +++ b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx @@ -1,37 +1,17 @@ -import { makeStyles, MaskColorVar } from '@masknet/theme' +import { makeStyles } from '@masknet/theme' export const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard }) => ({ walletStatusBox: { width: 535, margin: '24px auto', }, - abstractTabWrapper: { - width: '100%', - paddingTop: theme.spacing(1), - paddingBottom: theme.spacing(2), + networkTab: { + width: 535, + margin: theme.spacing(1, 'auto', 2), }, tableTabWrapper: { padding: theme.spacing(2), }, - tab: { - height: 36, - minHeight: 36, - backgroundColor: isDashboard ? `${MaskColorVar.primaryBackground2}!important` : undefined, - }, - tabPaper: { - backgroundColor: 'inherit', - }, - tabs: { - width: 535, - height: 36, - minHeight: 36, - margin: '0 auto', - borderRadius: 4, - '& .Mui-selected': { - color: '#ffffff', - backgroundColor: `${theme.palette.primary.main}!important`, - }, - }, indicator: { display: 'none', }, diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx index e5417e20234d..71dac3d38f41 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx @@ -20,32 +20,7 @@ import { isDashboardPage } from '@masknet/shared-base' const useStyles = makeStyles()((theme) => ({ walletStatusBox: { width: 535, - margin: '24px auto', - }, - abstractTabWrapper: { - width: '100%', - paddingTop: theme.spacing(1), - paddingBottom: theme.spacing(2), - }, - tab: { - height: 36, - minHeight: 36, - }, - tabPaper: { - backgroundColor: 'inherit', - }, - tabs: { - width: 535, - height: 36, - minHeight: 36, - margin: '0 auto', - borderRadius: 4, - }, - indicator: { - display: 'none', - }, - tabPanel: { - marginTop: theme.spacing(3), + margin: theme.spacing(3, 'auto'), }, content: { paddingTop: 0, @@ -57,6 +32,10 @@ const useStyles = makeStyles()((theme) => ({ width: 535, margin: 'auto', }, + networkTab: { + width: 535, + margin: theme.spacing(1, 'auto', 2), + }, })) interface TraderDialogProps { @@ -110,14 +89,12 @@ export function TraderDialog({ open, onClose }: TraderDialogProps) {
) : null} -
- -
+ diff --git a/packages/shared/src/UI/components/ConcealableTabs/index.tsx b/packages/shared/src/UI/components/ConcealableTabs/index.tsx new file mode 100644 index 000000000000..6ea0aa321f2a --- /dev/null +++ b/packages/shared/src/UI/components/ConcealableTabs/index.tsx @@ -0,0 +1,212 @@ +import { LeftArrowIcon, RightArrowIcon } from '@masknet/icons' +import { makeStyles } from '@masknet/theme' +import { Button } from '@mui/material' +import classnames from 'classnames' +import { throttle } from 'lodash-unified' +import { HTMLProps, ReactNode, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react' + +const TAB_WIDTH = 126 +const useStyles = makeStyles()((theme) => ({ + container: { + display: 'flex', + position: 'relative', + backgroundColor: theme.palette.background.default, + '&::after': { + content: '""', + position: 'absolute', + left: 0, + right: 0, + bottom: 0, + height: 1, + backgroundColor: theme.palette.divider, + zIndex: 0, + }, + }, + track: { + flexGrow: 1, + display: 'flex', + overflow: 'auto', + 'scrollbar-width': 'none', + '&::-webkit-scrollbar': { + display: 'none', + }, + }, + button: { + height: 35, + minWidth: TAB_WIDTH, + padding: theme.spacing(0, 2.5), + borderRadius: 0, + flexShrink: 0, + border: '1px solid transparent', + }, + normal: { + boxSizing: 'border-box', + color: `${theme.palette.text.secondary} !important`, + backgroundColor: theme.palette.background.default, + border: '1px solid transparent', + '&:hover': { + color: `${theme.palette.text.primary} !important`, + backgroundColor: theme.palette.background.default, + }, + }, + selected: { + color: `${theme.palette.text.primary} !important`, + backgroundColor: theme.palette.background.paper, + border: '1px solid', + borderColor: theme.palette.background.paper, + borderBottomColor: theme.palette.background.paper, + '&:hover': { + borderBottomColor: theme.palette.background.paper, + backgroundColor: theme.palette.background.paper, + }, + position: 'relative', + zIndex: 10, + '&::after': { + content: '""', + position: 'absolute', + left: 0, + right: 0, + bottom: 0, + height: 1, + backgroundColor: theme.palette.background.paper, + }, + }, + controllers: { + display: 'flex', + flexGrow: 0, + alignItems: 'center', + borderLeft: `1px solid ${theme.palette.divider}`, + }, + controller: { + display: 'flex', + minWidth: 35, + color: theme.palette.text.primary, + border: 'none', + width: 35, + height: 35, + borderRadius: 0, + boxSizing: 'border-box', + alignItems: 'center', + justifyContent: 'center', + '&:hover': { + border: 'none !important', + borderBottomColor: theme.palette.divider, + color: `${theme.palette.text.primary} !important`, + backgroundColor: theme.palette.background.paper, + }, + '&[disabled]': { + backgroundColor: theme.palette.background.default, + }, + }, +})) + +interface TabOption { + id: T + label: string +} + +export interface ConcealableTabsProps extends Omit, 'onChange'> { + tabs: TabOption[] + selectedId?: T + onChange?(id: T): void + tail?: ReactNode +} + +export function ConcealableTabs({ + className, + tabs, + selectedId, + tail, + onChange, + ...rest +}: ConcealableTabsProps) { + const { classes } = useStyles() + const [overflow, setOverflow] = useState(false) + + const trackRef = useRef(null) + const [reachedLeftEdge, setReachedLeftEdge] = useState(false) + const [reachedRightEdge, setReachedRightEdge] = useState(false) + + useLayoutEffect(() => { + const tabList = trackRef.current + if (!tabList) return + const isWider = tabList.scrollWidth > tabList.offsetWidth + setOverflow(isWider) + + if (!isWider) return + const detectScrollStatus = throttle(() => { + const reachedRight = tabList.scrollWidth - tabList.offsetWidth <= tabList.scrollLeft + const reachedLeft = tabList.scrollLeft === 0 + setReachedRightEdge(reachedRight) + setReachedLeftEdge(reachedLeft) + }, 100) + + detectScrollStatus() + tabList.addEventListener('scroll', detectScrollStatus) + return () => { + tabList.removeEventListener('scroll', detectScrollStatus) + } + }, []) + + useEffect(() => { + if (selectedId === undefined && tabs.length) { + onChange?.(tabs[0].id) + } + }, [selectedId === undefined, tabs.length > 0, onChange]) + + const slide = useCallback((toLeft: boolean) => { + const tabList = trackRef.current + if (!tabList) return + const scrolled = Math.round(tabList.scrollLeft / TAB_WIDTH) + tabList.scrollTo({ left: TAB_WIDTH * (scrolled + (toLeft ? 1 : -1)), behavior: 'smooth' }) + }, []) + + return ( +
+
+ {tabs.map((tab) => ( + + ))} +
+ {overflow || tail ? ( +
+ {overflow ? ( + <> + + + + ) : null} + {tail} +
+ ) : null} +
+ ) +} diff --git a/packages/shared/src/UI/components/index.ts b/packages/shared/src/UI/components/index.ts index b32738abcf4a..31462dc86df1 100644 --- a/packages/shared/src/UI/components/index.ts +++ b/packages/shared/src/UI/components/index.ts @@ -1,16 +1,17 @@ -export * from './TokenIcon' +export * from './AddressViewer' +export * from './ApplicationEntry' +export * from './AssetPlayer' export * from './ChainIcon' -export * from './ImageIcon' -export * from './WalletIcon' +export * from './ConcealableTabs' export * from './ERC20TokenList' -export * from './QRCode' -export * from './SelectTokenChip' -export * from './TokenAmountPanel' +export * from './I18NextProviderHMR' +export * from './ImageIcon' export * from './LoadingAnimation' export * from './MiniNetworkSelector' -export * from './AddressViewer' -export * from './I18NextProviderHMR' -export * from './AssetPlayer' export * from './NFTCardStyledAssetPlayer' +export * from './QRCode' export * from './ReversedAddress' -export * from './ApplicationEntry' +export * from './SelectTokenChip' +export * from './TokenAmountPanel' +export * from './TokenIcon' +export * from './WalletIcon' From 84bd1a4ec98649bca5a929559e54131313f0d668 Mon Sep 17 00:00:00 2001 From: unclebill Date: Mon, 18 Apr 2022 13:47:17 +0800 Subject: [PATCH 2/2] fix: revert unwanted changes --- .../mask/src/components/shared/NetworkTab.tsx | 69 ++++++++++++++++--- .../plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx | 32 ++++++--- .../NextID/components/Tip/TipDialog.tsx | 33 ++++++--- .../Savings/SNSAdaptor/SavingsDialog.tsx | 14 ++-- .../SNSAdaptor/SavingsDialogStyles.tsx | 28 ++++++-- .../Trader/SNSAdaptor/trader/TraderDialog.tsx | 45 +++++++++--- 6 files changed, 175 insertions(+), 46 deletions(-) diff --git a/packages/mask/src/components/shared/NetworkTab.tsx b/packages/mask/src/components/shared/NetworkTab.tsx index 124f2cb540fa..6087c1306c27 100644 --- a/packages/mask/src/components/shared/NetworkTab.tsx +++ b/packages/mask/src/components/shared/NetworkTab.tsx @@ -1,19 +1,70 @@ -import { ConcealableTabs } from '@masknet/shared' +import { makeStyles, MaskColorVar, useStylesExtends } from '@masknet/theme' +import AbstractTab, { AbstractTabProps } from './AbstractTab' import { ChainId, getChainDetailed } from '@masknet/web3-shared-evm' -import type { HTMLProps } from 'react' +import { isDashboardPage } from '@masknet/shared-base' -interface NetworkTabProps extends Omit, 'onChange'> { +interface StyleProps { + chainLength: number + isDashboard: boolean +} +const useStyles = makeStyles()((theme, props) => ({ + tab: { + backgroundColor: !props.isDashboard + ? `${theme.palette.background.default}!important` + : `${MaskColorVar.primaryBackground2}!important`, + marginRight: 1, + '&:last-child': { + marginRight: 0, + }, + }, + tabs: { + '& .MuiTabs-flexContainer': { + backgroundColor: theme.palette.background.paper, + }, + '& .Mui-selected': { + color: '#ffffff', + backgroundColor: `${theme.palette.primary.main}!important`, + }, + '& .MuiTabs-scroller': { + margin: '0 1px', + }, + '& .MuiTabs-scrollButtons': { + width: 'unset', + backgroundColor: !props.isDashboard + ? `${theme.palette.background.default}!important` + : `${MaskColorVar.primaryBackground2}!important`, + '&.Mui-disabled': { + opacity: 1, + '& svg': { + opacity: 0.3, + }, + }, + }, + }, +})) + +interface NetworkTabProps extends withClasses<'tab' | 'tabs' | 'tabPanel' | 'indicator' | 'focusTab' | 'tabPaper'> { chains: ChainId[] setChainId: (chainId: ChainId) => void chainId: ChainId } export function NetworkTab(props: NetworkTabProps) { - const { chainId, setChainId, chains, ...rest } = props + const isDashboard = isDashboardPage() + const classes = useStylesExtends(useStyles({ chainLength: props.chains.length, isDashboard }), props) + const { chainId, setChainId, chains } = props + const createTabItem = (name: string, chainId: ChainId) => ({ + label: {name}, + sx: { p: 0 }, + cb: () => setChainId(chainId), + }) - const tabs = chains.map((chainId) => ({ - id: chainId, - label: getChainDetailed(chainId)?.chain ?? 'Unknown', - })) + const tabProps: AbstractTabProps = { + tabs: chains.map((chainId) => createTabItem(getChainDetailed(chainId)?.chain ?? 'Unknown', chainId)), + index: chains.indexOf(chainId), + classes, + hasOnlyOneChild: true, + scrollable: true, + } - return + return } diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx index 9c05659bb143..6c575395fef0 100644 --- a/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx +++ b/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx @@ -132,9 +132,27 @@ const useStyles = makeStyles()((theme, props) => { fontSize: 18, fontWeight: 300, }, + tab: { + height: 36, + minHeight: 36, + fontWeight: 300, + }, + tabs: { + height: 36, + minHeight: 36, + borderRadius: 4, + backgroundColor: theme.palette.background.default, + '& .Mui-selected': { + color: theme.palette.primary.contrastText, + backgroundColor: theme.palette.primary.main, + }, + }, indicator: { display: 'none', }, + tabPanel: { + marginTop: theme.spacing(3), + }, contentWrapper: { display: 'flex', flexDirection: 'column', @@ -183,12 +201,13 @@ const useStyles = makeStyles()((theme, props) => { snackbarError: { backgroundColor: '#FF5555', }, - networkTab: { + abstractTabWrapper: { position: 'sticky', top: 0, width: '100%', zIndex: 2, - margin: theme.spacing(1, 'auto', 2), + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(2), backgroundColor: theme.palette.background.paper, }, walletStatusBox: { @@ -309,12 +328,9 @@ export function ClaimAllDialog(props: ClaimAllDialogProps) {
- +
+ +
{(showNftAirdrop || loadingAirdrop) && chainId === ChainId.Matic && diff --git a/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx b/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx index ae74732248c7..43e733d37edc 100644 --- a/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx +++ b/packages/mask/src/plugins/NextID/components/Tip/TipDialog.tsx @@ -49,9 +49,24 @@ const useStyles = makeStyles()((theme) => ({ display: 'none', }, }, - networkTab: { + abstractTabWrapper: { width: '100%', - margin: theme.spacing(1, 'auto', 2), + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(2), + flexShrink: 0, + }, + tab: { + height: 36, + minHeight: 36, + }, + tabPaper: { + backgroundColor: 'inherit', + }, + tabs: { + height: 36, + minHeight: 36, + margin: '0 auto', + borderRadius: 4, }, tipForm: { flexGrow: 1, @@ -279,12 +294,14 @@ export function TipDialog({ open = false, onClose }: TipDialogProps) { title={t.tips()} titleTail={walletChip}> - +
+ +
openAddTokenDialog(true)} />
diff --git a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx index c957354929f2..e6e4c606c614 100644 --- a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx +++ b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialog.tsx @@ -133,12 +133,14 @@ export function SavingsDialog({ open, onClose }: SavingsDialogProps) { ) : ( <> - +
+ +
{protocols.length === 0 ? ( diff --git a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx index a0b2f8c1bf60..8b13fe54e7b3 100644 --- a/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx +++ b/packages/mask/src/plugins/Savings/SNSAdaptor/SavingsDialogStyles.tsx @@ -1,17 +1,37 @@ -import { makeStyles } from '@masknet/theme' +import { makeStyles, MaskColorVar } from '@masknet/theme' export const useStyles = makeStyles<{ isDashboard: boolean }>()((theme, { isDashboard }) => ({ walletStatusBox: { width: 535, margin: '24px auto', }, - networkTab: { - width: 535, - margin: theme.spacing(1, 'auto', 2), + abstractTabWrapper: { + width: '100%', + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(2), }, tableTabWrapper: { padding: theme.spacing(2), }, + tab: { + height: 36, + minHeight: 36, + backgroundColor: isDashboard ? `${MaskColorVar.primaryBackground2}!important` : undefined, + }, + tabPaper: { + backgroundColor: 'inherit', + }, + tabs: { + width: 535, + height: 36, + minHeight: 36, + margin: '0 auto', + borderRadius: 4, + '& .Mui-selected': { + color: '#ffffff', + backgroundColor: `${theme.palette.primary.main}!important`, + }, + }, indicator: { display: 'none', }, diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx index 71dac3d38f41..e5417e20234d 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/TraderDialog.tsx @@ -20,7 +20,32 @@ import { isDashboardPage } from '@masknet/shared-base' const useStyles = makeStyles()((theme) => ({ walletStatusBox: { width: 535, - margin: theme.spacing(3, 'auto'), + margin: '24px auto', + }, + abstractTabWrapper: { + width: '100%', + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(2), + }, + tab: { + height: 36, + minHeight: 36, + }, + tabPaper: { + backgroundColor: 'inherit', + }, + tabs: { + width: 535, + height: 36, + minHeight: 36, + margin: '0 auto', + borderRadius: 4, + }, + indicator: { + display: 'none', + }, + tabPanel: { + marginTop: theme.spacing(3), }, content: { paddingTop: 0, @@ -32,10 +57,6 @@ const useStyles = makeStyles()((theme) => ({ width: 535, margin: 'auto', }, - networkTab: { - width: 535, - margin: theme.spacing(1, 'auto', 2), - }, })) interface TraderDialogProps { @@ -89,12 +110,14 @@ export function TraderDialog({ open, onClose }: TraderDialogProps) {
) : null} - +
+ +