This commit is contained in:
mulan xia 2024-01-26 17:06:14 -05:00
parent 8187e3615b
commit eee19b3b93
No known key found for this signature in database
GPG Key ID: C6CE526613568D73
8 changed files with 232 additions and 6 deletions

View File

@ -0,0 +1,19 @@
<svg width="120" height="97" viewBox="0 0 120 97" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="8" width="120" height="1" fill="currentColor"/>
<rect y="18" width="120" height="1" fill="currentColor"/>
<rect y="28" width="120" height="1" fill="currentColor"/>
<rect y="38" width="120" height="1" fill="currentColor"/>
<rect y="48" width="120" height="1" fill="currentColor"/>
<rect y="58" width="120" height="1" fill="currentColor"/>
<rect y="68" width="120" height="1" fill="currentColor"/>
<rect y="78" width="120" height="1" fill="currentColor"/>
<rect y="88" width="120" height="1" fill="currentColor"/>
<rect x="18" width="1" height="97" fill="currentColor"/>
<rect x="32" width="1" height="97" fill="currentColor"/>
<rect x="46" width="1" height="97" fill="currentColor"/>
<rect x="60" width="1" height="97" fill="currentColor"/>
<rect x="74" width="1" height="97" fill="currentColor"/>
<rect x="88" width="1" height="97" fill="currentColor"/>
<rect x="102" width="1" height="97" fill="currentColor"/>
<path d="M0 0H120V97H0V0Z" fill="url(#paint0_radial_314_37586)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

20
public/chart-bars.svg Normal file
View File

@ -0,0 +1,20 @@
<svg width="90" height="39" viewBox="0 0 90 39" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="31.2344" width="2.57142" height="7.71427" fill="#3ED9A4"/>
<rect x="5.14258" y="28.6648" width="2.57142" height="5.14284" fill="#E45555"/>
<rect x="25.7139" y="26.0923" width="2.57142" height="10.2857" fill="#E45555"/>
<rect x="51.4283" y="28.6648" width="2.57142" height="5.14284" fill="#E45555"/>
<rect x="56.5712" y="31.2344" width="2.57142" height="5.14284" fill="#E45555"/>
<rect x="77.1426" y="18.3767" width="2.57142" height="5.14284" fill="#E45555"/>
<rect x="41.1427" y="23.5198" width="2.57142" height="5.14284" fill="#E45555"/>
<rect x="10.2856" y="28.6648" width="2.57142" height="10.2857" fill="#3ED9A4"/>
<rect x="61.7143" y="23.5198" width="2.57142" height="10.2857" fill="#3ED9A4"/>
<rect x="66.8569" y="20.9492" width="2.57142" height="5.14284" fill="#3ED9A4"/>
<rect x="71.9997" y="13.2346" width="2.57142" height="7.71427" fill="#3ED9A4"/>
<rect x="82.2856" y="10.6631" width="2.57142" height="10.2857" fill="#3ED9A4"/>
<rect x="87.4287" y="0.37793" width="2.57142" height="15.4285" fill="#3ED9A4"/>
<rect x="15.4284" y="26.0923" width="2.57142" height="5.14284" fill="#3ED9A4"/>
<rect x="20.5714" y="23.5198" width="2.57142" height="5.14284" fill="#3ED9A4"/>
<rect x="30.857" y="31.2344" width="2.57142" height="5.14284" fill="#3ED9A4"/>
<rect x="35.9999" y="26.0923" width="2.57142" height="5.14284" fill="#3ED9A4"/>
<rect x="46.2853" y="26.0923" width="2.57142" height="2.57142" fill="#3ED9A4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,10 +1,10 @@
import type { Story } from '@ladle/react';
import { Panel } from '@/components/Panel';
import { Panel, PanelProps } from '@/components/Panel';
import { StoryWrapper } from '.ladle/components';
export const PanelStory: Story<{ slotHeader: React.ReactNode, children?: React.ReactNode }> = (args) => {
export const PanelStory: Story<PanelProps> = (args) => {
return (
<StoryWrapper>
<Panel {...args} />
@ -13,6 +13,8 @@ export const PanelStory: Story<{ slotHeader: React.ReactNode, children?: React.R
};
PanelStory.args = {
slotHeader: 'Header',
slotHeaderContent: 'Header',
children: 'Content',
slotRight: '1⃣',
hasSeparator: true,
};

View File

@ -6,7 +6,7 @@ import { Icon, IconName } from '@/components/Icon';
import { layoutMixins } from '@/styles/layoutMixins';
import { breakpoints } from '@/styles';
type PanelProps = {
type ElementProps = {
slotHeaderContent?: React.ReactNode;
slotHeader?: React.ReactNode;
slotRight?: React.ReactNode;
@ -16,11 +16,13 @@ type PanelProps = {
onClick?: () => void;
};
type PanelStyleProps = {
type StyleProps = {
className?: string;
hasSeparator?: boolean;
};
export type PanelProps = ElementProps & StyleProps;
export const Panel = ({
slotHeaderContent,
slotHeader,
@ -31,7 +33,7 @@ export const Panel = ({
onClick,
hasSeparator,
className,
}: PanelProps & PanelStyleProps) => (
}: PanelProps) => (
<Styled.Panel onClick={onClick} className={className}>
<Styled.Left>
{href ? (

View File

@ -2,6 +2,7 @@ export enum DialogTypes {
ClosePosition = 'ClosePosition',
Deposit = 'Deposit',
DisconnectWallet = 'DisconnectWallet',
DisplaySettings = 'DisplaySettings',
ExchangeOffline = 'ExchangeOffline',
ExternalLink = 'ExternalLink',
FillDetails = 'FillDetails',

View File

@ -9,6 +9,7 @@ import { getActiveDialog } from '@/state/dialogsSelectors';
import { ClosePositionDialog } from '@/views/dialogs/ClosePositionDialog';
import { DepositDialog } from '@/views/dialogs/DepositDialog';
import { DisconnectDialog } from '@/views/dialogs/DisconnectDialog';
import { DisplaySettingsDialog } from '@/views/dialogs/DisplaySettingsDialog';
import { ExchangeOfflineDialog } from '@/views/dialogs/ExchangeOfflineDialog';
import { HelpDialog } from '@/views/dialogs/HelpDialog';
import { ExternalLinkDialog } from '@/views/dialogs/ExternalLinkDialog';
@ -51,6 +52,7 @@ export const DialogManager = () => {
return {
[DialogTypes.ClosePosition]: <ClosePositionDialog {...modalProps} />,
[DialogTypes.Deposit]: <DepositDialog {...modalProps} />,
[DialogTypes.DisplaySettings]: <DisplaySettingsDialog {...modalProps} />,
[DialogTypes.DisconnectWallet]: <DisconnectDialog {...modalProps} />,
[DialogTypes.ExchangeOffline]: <ExchangeOfflineDialog {...modalProps} />,
[DialogTypes.FillDetails]: <FillDetailsDialog {...modalProps} />,

View File

@ -0,0 +1,171 @@
import { useDispatch, useSelector } from 'react-redux';
import styled, { AnyStyledComponent, css } from 'styled-components';
import { Root, Item, Indicator } from '@radix-ui/react-radio-group';
import { AppTheme, setAppTheme } from '@/state/configs';
import { getAppTheme } from '@/state/configsSelectors';
import { layoutMixins } from '@/styles/layoutMixins';
import { Themes } from '@/styles/themes';
import { STRING_KEYS } from '@/constants/localization';
import { Icon, IconName } from '@/components/Icon';
import { Panel } from '@/components/Panel';
import {
useStringGetter,
} from '@/hooks';
import { Dialog } from '@/components/Dialog';
import { HorizontalSeparatorFiller } from '@/components/Separator';
type ElementProps = {
setIsOpen: (open: boolean) => void;
};
export const DisplaySettingsDialog = ({ setIsOpen }: ElementProps) => {
const dispatch = useDispatch();
const stringGetter = useStringGetter();
const currentTheme: AppTheme = useSelector(getAppTheme);
const sectionHeader = (heading: string) => {
return (
<Styled.Header>
{ heading }
<HorizontalSeparatorFiller />
</Styled.Header>
);
};
const themePanels = () => {
return (
<Styled.Root value={currentTheme}>
{[{
theme: AppTheme.Classic,
label: STRING_KEYS.CLASSIC_DARK
}, {
theme: AppTheme.Dark,
label: STRING_KEYS.DARK
}, {
theme: AppTheme.Light,
label: STRING_KEYS.LIGHT
}].map(({theme, label}) => (
<Item value={theme}>
<Styled.Panel
backgroundColor={Themes[theme].layer2}
gridColor={Themes[theme].borderDefault}
onClick={() => {
dispatch(setAppTheme(theme));
}}
slotHeader={<Styled.PanelHeader textColor={Themes[theme].textPrimary}>{stringGetter({ key: label })}</Styled.PanelHeader>}
>
<Styled.Image src="/chart-bars.svg" />
<Styled.Indicator>
<Styled.CheckIcon iconName={IconName.Check} />
</Styled.Indicator>
</Styled.Panel>
</Item>
))}
</Styled.Root>
)
}
return (
<Dialog isOpen setIsOpen={setIsOpen} title={stringGetter({ key: STRING_KEYS.DISPLAY_SETTINGS })}>
<Styled.Section>
{sectionHeader(stringGetter({ key: STRING_KEYS.THEME }))}
{themePanels()}
</Styled.Section>
</Dialog>
);
};
const Styled: Record<string, AnyStyledComponent> = {};
Styled.Section = styled.div`
display: grid;
gap: 1.5rem;
`;
Styled.Header = styled.header`
${layoutMixins.inlineRow}
`;
Styled.Root = styled(Root)`
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
`;
Styled.Panel = styled(Panel)<{ backgroundColor: string, gridColor: string }>`
--panel-content-paddingY: 0.25rem;
--panel-content-paddingX: 0.25rem;
${({ backgroundColor, gridColor }) => css`
--themePanel-backgroundColor: ${backgroundColor};
--themePanel-gridColor: ${gridColor};
`}
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: radial-gradient(55% 35% at 50% 65%, transparent, var(--themePanel-backgroundColor) 100%);
background-color: var(--themePanel-gridColor);
mask-image: url('/chart-bars-background.svg');
mask-size: cover;
}
position: relative;
padding: 0.75rem;
background-color: var(--themePanel-backgroundColor);
border: solid var(--border-width) var(--color-border);
`;
Styled.PanelHeader = styled.h3<{ textColor: string }>`
${({ textColor }) => css`
color: ${textColor};
`}
align-self: flex-start;
`;
Styled.Image = styled.img`
width: 100%;
height: auto;
`
Styled.Indicator = styled(Indicator)`
--indicator-size: 1.25rem;
height: var(--indicator-size);
width: var(--indicator-size);
position: absolute;
bottom: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--color-accent);
border-radius: 50%;
color: var(--color-text-2);
`
Styled.CheckIcon = styled(Icon)`
--icon-size: 0.625rem;
width: var(--icon-size);
height: var(--icon-size);
`;

View File

@ -32,9 +32,11 @@ import { Icon, IconName } from '@/components/Icon';
import { IconButton } from '@/components/IconButton';
import { WithTooltip } from '@/components/WithTooltip';
import { AppTheme } from '@/state/configs';
import { openDialog } from '@/state/dialogs';
import { getOnboardingState, getSubaccount } from '@/state/accountSelectors';
import { getAppTheme } from '@/state/configsSelectors';
import { isTruthy } from '@/lib/isTruthy';
import { truncateAddress } from '@/lib/wallet';
@ -50,6 +52,7 @@ export const AccountMenu = () => {
const { freeCollateral } = useSelector(getSubaccount, shallowEqual) || {};
const { nativeTokenBalance } = useAccountBalance();
const { usdcLabel, chainTokenLabel } = useTokenConfigs();
const theme = useSelector(getAppTheme);
const { evmAddress, walletType, dydxAddress, hdKey } = useAccounts();
@ -177,6 +180,12 @@ export const AccountMenu = () => {
label: stringGetter({ key: STRING_KEYS.PREFERENCES }),
onSelect: () => dispatch(openDialog({ type: DialogTypes.Preferences })),
},
{
value: 'Display Settings',
icon: theme === AppTheme.Light ? <Icon iconName={IconName.Sun} /> : <Icon iconName={IconName.Moon} />,
label: stringGetter({ key: STRING_KEYS.DISPLAY_SETTINGS }),
onSelect: () => dispatch(openDialog({ type: DialogTypes.DisplaySettings })),
},
...(onboardingState === OnboardingState.AccountConnected && hdKey
? [
(!isMainnet || testFlags.showMobileSignInOption) && {