TRCL-3535 Add green/red preference to display modal (#261)
* add functionality, without user exposure yet * fix commit history * remove unnecessary change * lint * update css * audit of pos/neg colors * fix flipping of disconnect/export keys colors * review comments * clean up naming of icon * fix icon sizing * small edit to story example
This commit is contained in:
@@ -102,13 +102,13 @@ const buttonActionVariants = {
|
||||
|
||||
[ButtonAction.Create]: css`
|
||||
--button-textColor: var(--color-text-2);
|
||||
--button-backgroundColor: var(--color-positive);
|
||||
--button-backgroundColor: var(--color-success);
|
||||
--button-border: solid var(--border-width) var(--color-border-white);
|
||||
`,
|
||||
|
||||
[ButtonAction.Destroy]: css`
|
||||
--button-textColor: var(--color-text-2);
|
||||
--button-backgroundColor: var(--color-negative);
|
||||
--button-backgroundColor: var(--color-error);
|
||||
--button-border: solid var(--border-width) var(--color-border-white);
|
||||
`,
|
||||
|
||||
@@ -119,7 +119,7 @@ const buttonActionVariants = {
|
||||
`,
|
||||
|
||||
[ButtonAction.Reset]: css`
|
||||
--button-textColor: var(--color-negative);
|
||||
--button-textColor: var(--color-error);
|
||||
--button-backgroundColor: var(--color-layer-3);
|
||||
--button-border: solid var(--border-width) var(--color-border-red);
|
||||
`,
|
||||
|
||||
@@ -87,7 +87,7 @@ Styled.Icon = styled(Icon)<{ copied: boolean }>`
|
||||
${({ copied }) =>
|
||||
copied &&
|
||||
css`
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -96,7 +96,7 @@ Styled.IconButton = styled(IconButton)<{ copied: boolean }>`
|
||||
copied &&
|
||||
css`
|
||||
svg {
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
@@ -62,6 +62,6 @@ Styled.DiffArrowContainer = styled.span<DiffArrowProps>`
|
||||
`,
|
||||
down: css`
|
||||
transform: rotate(90deg);
|
||||
`
|
||||
`,
|
||||
}[direction || 'right'])}
|
||||
`;
|
||||
|
||||
@@ -75,7 +75,7 @@ Styled.DiffValue = styled.div<{ hasInvalidNewValue?: boolean }>`
|
||||
${({ hasInvalidNewValue }) =>
|
||||
hasInvalidNewValue &&
|
||||
css`
|
||||
color: var(--color-negative);
|
||||
color: var(--color-error);
|
||||
`}
|
||||
`;
|
||||
|
||||
|
||||
@@ -6,29 +6,34 @@ import { StoryWrapper } from '.ladle/components';
|
||||
|
||||
export const DropdownMenuStory: Story<Parameters<typeof DropdownMenu>> = (args) => {
|
||||
const exampleItems = [
|
||||
{
|
||||
value: '0',
|
||||
label: 'Item 0',
|
||||
onSelect: () => alert('Item 0 action'),
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: 'Item 1',
|
||||
label: 'Item 1 (accent)',
|
||||
onSelect: () => alert('Item 1 action'),
|
||||
highlightColor: 'accent',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: 'Item 2',
|
||||
label: 'Item 2 (create)',
|
||||
onSelect: () => alert('Item 2 action'),
|
||||
highlightColor: 'create',
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: 'Item 3',
|
||||
label: 'Item 3 (destroy)',
|
||||
onSelect: () => alert('Item 3 action'),
|
||||
highlightColor: 'destroy',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<StoryWrapper>
|
||||
<DropdownMenu
|
||||
{...args}
|
||||
items={exampleItems}
|
||||
>
|
||||
<DropdownMenu {...args} items={exampleItems}>
|
||||
<span>Menu</span>
|
||||
</DropdownMenu>
|
||||
</StoryWrapper>
|
||||
|
||||
@@ -13,7 +13,7 @@ export type DropdownMenuItem<T> = {
|
||||
label: React.ReactNode;
|
||||
onSelect?: () => void;
|
||||
separator?: boolean;
|
||||
highlightColor?: 'accent' | 'positive' | 'negative';
|
||||
highlightColor?: 'accent' | 'create' | 'destroy';
|
||||
};
|
||||
|
||||
type StyleProps = {
|
||||
@@ -82,7 +82,7 @@ Styled.Separator = styled(Separator)`
|
||||
margin: 0.25rem 1rem;
|
||||
`;
|
||||
|
||||
Styled.Item = styled(Item)<{ $highlightColor: 'accent' | 'positive' | 'negative' }>`
|
||||
Styled.Item = styled(Item)<{ $highlightColor: 'accent' | 'create' | 'destroy' }>`
|
||||
${popoverMixins.item}
|
||||
--item-font-size: var(--dropdownMenu-item-font-size);
|
||||
${({ $highlightColor }) =>
|
||||
@@ -90,11 +90,11 @@ Styled.Item = styled(Item)<{ $highlightColor: 'accent' | 'positive' | 'negative'
|
||||
['accent']: `
|
||||
--item-highlighted-textColor: var(--color-accent);
|
||||
`,
|
||||
['positive']: `
|
||||
--item-highlighted-textColor: var(--color-positive);
|
||||
['create']: `
|
||||
--item-highlighted-textColor: var(--color-success);
|
||||
`,
|
||||
['negative']: `
|
||||
--item-highlighted-textColor: var(--color-negative);
|
||||
['destroy']: `
|
||||
--item-highlighted-textColor: var(--color-error);
|
||||
`,
|
||||
}[$highlightColor])}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ Styled.ConfirmButton = styled(Styled.IconButton)`
|
||||
--button-backgroundColor: hsla(203, 25%, 19%, 1);
|
||||
|
||||
svg {
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -125,7 +125,7 @@ Styled.CancelButton = styled(Styled.IconButton)`
|
||||
--button-backgroundColor: hsla(296, 16%, 18%, 1);
|
||||
|
||||
svg {
|
||||
color: var(--color-negative);
|
||||
color: var(--color-error);
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ type StatusColors = {
|
||||
success: string;
|
||||
warning: string;
|
||||
error: string;
|
||||
successFaded: string;
|
||||
warningFaded: string;
|
||||
errorFaded: string;
|
||||
};
|
||||
|
||||
/** ##InvertDirectionalColors
|
||||
|
||||
@@ -127,7 +127,7 @@ Styled.StatusDot = styled.div<{ exchangeStatus: ExchangeStatus }>`
|
||||
background-color: ${({ exchangeStatus }) =>
|
||||
({
|
||||
[ExchangeStatus.Degraded]: css`var(--color-warning)`,
|
||||
[ExchangeStatus.Operational]: css`var(--color-positive)`,
|
||||
[ExchangeStatus.Operational]: css`var(--color-success)`,
|
||||
}[exchangeStatus])};
|
||||
`;
|
||||
|
||||
|
||||
+3
-3
@@ -43,19 +43,19 @@ export const getStatusIconInfo = ({
|
||||
case AbacusOrderStatus.filled: {
|
||||
return {
|
||||
statusIcon: IconName.OrderFilled,
|
||||
statusIconColor: `var(--color-positive)`,
|
||||
statusIconColor: `var(--color-success)`,
|
||||
};
|
||||
}
|
||||
case AbacusOrderStatus.cancelled: {
|
||||
return {
|
||||
statusIcon: IconName.OrderCanceled,
|
||||
statusIconColor: `var(--color-negative)`,
|
||||
statusIconColor: `var(--color-error)`,
|
||||
};
|
||||
}
|
||||
case AbacusOrderStatus.canceling: {
|
||||
return {
|
||||
statusIcon: IconName.OrderPending,
|
||||
statusIconColor: `var(--color-negative)`,
|
||||
statusIconColor: `var(--color-error)`,
|
||||
};
|
||||
}
|
||||
case AbacusOrderStatus.untriggered: {
|
||||
|
||||
@@ -286,10 +286,10 @@ Styled.ConnectedIcon = styled.div`
|
||||
height: 0.5rem;
|
||||
width: 0.5rem;
|
||||
margin-right: 0.25rem;
|
||||
background: var(--color-positive);
|
||||
background: var(--color-success);
|
||||
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 0 0.2rem var(--color-gradient-positive);
|
||||
box-shadow: 0 0 0 0.2rem var(--color-gradient-success);
|
||||
`;
|
||||
|
||||
Styled.Address = styled.h1`
|
||||
@@ -318,7 +318,7 @@ Styled.ActionButton = styled(IconButton)<{ iconName?: IconName }>`
|
||||
${({ iconName }) =>
|
||||
iconName === IconName.Close
|
||||
? css`
|
||||
--button-textColor: var(--color-negative);
|
||||
--button-textColor: var(--color-error);
|
||||
--button-icon-size: 0.75em;
|
||||
`
|
||||
: iconName === IconName.Transfer &&
|
||||
|
||||
@@ -29,6 +29,9 @@ export const GlobalStyle = createGlobalStyle`
|
||||
--color-success: ${({ theme }) => theme.success};
|
||||
--color-warning: ${({ theme }) => theme.warning};
|
||||
--color-error: ${({ theme }) => theme.error};
|
||||
--color-gradient-success: ${({ theme }) => theme.successFaded};
|
||||
--color-gradient-warning: ${({ theme }) => theme.warningFaded};
|
||||
--color-gradient-error: ${({ theme }) => theme.errorFaded};
|
||||
|
||||
--color-positive: ${({ theme }) => theme.positive};
|
||||
--color-negative: ${({ theme }) => theme.negative};
|
||||
|
||||
@@ -31,6 +31,9 @@ const ClassicThemeBase: ThemeColorBase = {
|
||||
success: ColorToken.Green1,
|
||||
warning: ColorToken.Yellow0,
|
||||
error: ColorToken.Red2,
|
||||
successFaded: generateFadedColorVariant(ColorToken.Green1, OpacityToken.Opacity16),
|
||||
warningFaded: generateFadedColorVariant(ColorToken.Yellow0, OpacityToken.Opacity16),
|
||||
errorFaded: generateFadedColorVariant(ColorToken.Red2, OpacityToken.Opacity16),
|
||||
|
||||
positive: ColorToken.Green1,
|
||||
negative: ColorToken.Red2,
|
||||
@@ -80,6 +83,9 @@ const DarkThemeBase: ThemeColorBase = {
|
||||
success: ColorToken.Green0,
|
||||
warning: ColorToken.Yellow0,
|
||||
error: ColorToken.Red0,
|
||||
successFaded: generateFadedColorVariant(ColorToken.Green0, OpacityToken.Opacity16),
|
||||
warningFaded: generateFadedColorVariant(ColorToken.Yellow0, OpacityToken.Opacity16),
|
||||
errorFaded: generateFadedColorVariant(ColorToken.Red0, OpacityToken.Opacity16),
|
||||
|
||||
positive: ColorToken.Green0,
|
||||
negative: ColorToken.Red0,
|
||||
@@ -129,6 +135,9 @@ const LightThemeBase: ThemeColorBase = {
|
||||
success: ColorToken.Green2,
|
||||
warning: ColorToken.Yellow0,
|
||||
error: ColorToken.Red1,
|
||||
successFaded: generateFadedColorVariant(ColorToken.Green2, OpacityToken.Opacity16),
|
||||
warningFaded: generateFadedColorVariant(ColorToken.Yellow0, OpacityToken.Opacity16),
|
||||
errorFaded: generateFadedColorVariant(ColorToken.Red1, OpacityToken.Opacity16),
|
||||
|
||||
positive: ColorToken.Green2,
|
||||
negative: ColorToken.Red1,
|
||||
|
||||
@@ -231,7 +231,7 @@ Styled.CircleContainer = styled.div`
|
||||
`;
|
||||
|
||||
Styled.Icon = styled(Icon)`
|
||||
color: var(--color-negative);
|
||||
color: var(--color-error);
|
||||
`;
|
||||
|
||||
Styled.WithUsage = styled.div`
|
||||
|
||||
@@ -557,11 +557,11 @@ Styled.PositionTile = styled(PositionTile)``;
|
||||
|
||||
Styled.ClosePositionButton = styled(Button)`
|
||||
--button-border: solid var(--border-width) var(--color-border-red);
|
||||
--button-textColor: var(--color-negative);
|
||||
--button-textColor: var(--color-error);
|
||||
`;
|
||||
|
||||
Styled.ClosePositionToggleButton = styled(ToggleButton)`
|
||||
--button-border: solid var(--border-width) var(--color-border-red);
|
||||
--button-toggle-off-textColor: var(--color-negative);
|
||||
--button-toggle-on-textColor: var(--color-negative);
|
||||
--button-toggle-off-textColor: var(--color-error);
|
||||
--button-toggle-on-textColor: var(--color-error);
|
||||
`;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Root, Item, Indicator } from '@radix-ui/react-radio-group';
|
||||
|
||||
import { useStringGetter } from '@/hooks';
|
||||
|
||||
import { AppTheme, AppColorMode, setAppTheme } from '@/state/configs';
|
||||
import { AppTheme, AppColorMode, setAppTheme, setAppColorMode } from '@/state/configs';
|
||||
import { getAppTheme, getAppColorMode } from '@/state/configsSelectors';
|
||||
|
||||
import { layoutMixins } from '@/styles/layoutMixins';
|
||||
@@ -76,6 +76,48 @@ export const DisplaySettingsDialog = ({ setIsOpen }: ElementProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const colorModeOptions = () => {
|
||||
return (
|
||||
<Styled.ColorPreferenceRoot value={currentColorMode}>
|
||||
{[
|
||||
{
|
||||
colorMode: AppColorMode.GreenUp,
|
||||
label: STRING_KEYS.GREEN_IS_UP,
|
||||
},
|
||||
{
|
||||
colorMode: AppColorMode.RedUp,
|
||||
label: STRING_KEYS.RED_IS_UP,
|
||||
},
|
||||
].map(({ colorMode, label }) => (
|
||||
<Styled.ColorPreferenceItem
|
||||
key={colorMode}
|
||||
value={colorMode}
|
||||
onClick={() => {
|
||||
dispatch(setAppColorMode(colorMode));
|
||||
}}
|
||||
>
|
||||
<Styled.ColorPreferenceLabel>
|
||||
<Styled.ArrowIconContainer>
|
||||
<Styled.ArrowIcon
|
||||
iconName={IconName.Arrow}
|
||||
direction="up"
|
||||
color={colorMode === AppColorMode.GreenUp ? 'green' : 'red'}
|
||||
/>
|
||||
<Styled.ArrowIcon
|
||||
iconName={IconName.Arrow}
|
||||
direction="down"
|
||||
color={colorMode === AppColorMode.GreenUp ? 'red' : 'green'}
|
||||
/>
|
||||
</Styled.ArrowIconContainer>
|
||||
{stringGetter({ key: label })}
|
||||
</Styled.ColorPreferenceLabel>
|
||||
<Styled.DotIndicator $selected={currentColorMode === colorMode} />
|
||||
</Styled.ColorPreferenceItem>
|
||||
))}
|
||||
</Styled.ColorPreferenceRoot>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
isOpen
|
||||
@@ -86,6 +128,10 @@ export const DisplaySettingsDialog = ({ setIsOpen }: ElementProps) => {
|
||||
{sectionHeader(stringGetter({ key: STRING_KEYS.THEME }))}
|
||||
{themePanels()}
|
||||
</Styled.Section>
|
||||
<Styled.Section>
|
||||
{sectionHeader(stringGetter({ key: STRING_KEYS.DIRECTION_COLOR_PREFERENCE }))}
|
||||
{colorModeOptions()}
|
||||
</Styled.Section>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
@@ -111,6 +157,11 @@ Styled.AppThemeRoot = styled(Root)`
|
||||
grid-template-columns: 1fr 1fr;
|
||||
`;
|
||||
|
||||
Styled.ColorPreferenceRoot = styled(Root)`
|
||||
${gridStyle}
|
||||
grid-template-columns: 1fr;
|
||||
`;
|
||||
|
||||
Styled.Item = styled(Item)`
|
||||
--border-color: var(--color-border);
|
||||
--item-padding: 0.75rem;
|
||||
@@ -121,9 +172,19 @@ Styled.Item = styled(Item)`
|
||||
|
||||
border: solid var(--border-width) var(--border-color);
|
||||
border-radius: 0.875rem;
|
||||
|
||||
padding: var(--item-padding);
|
||||
`;
|
||||
|
||||
Styled.ColorPreferenceItem = styled(Styled.Item)`
|
||||
&[data-state='checked'] {
|
||||
background-color: var(--color-layer-4);
|
||||
}
|
||||
|
||||
${layoutMixins.row}
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
Styled.AppThemeItem = styled(Styled.Item)<{ backgroundcolor: string; gridcolor: string }>`
|
||||
${({ backgroundcolor, gridcolor }) => css`
|
||||
--themePanel-backgroundColor: ${backgroundcolor};
|
||||
@@ -134,6 +195,7 @@ Styled.AppThemeItem = styled(Styled.Item)<{ backgroundcolor: string; gridcolor:
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
background-color: var(--themePanel-backgroundColor);
|
||||
|
||||
&::before {
|
||||
@@ -170,6 +232,43 @@ Styled.Image = styled.img`
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
Styled.ColorPreferenceLabel = styled.div`
|
||||
${layoutMixins.inlineRow};
|
||||
gap: 1ch;
|
||||
`;
|
||||
|
||||
Styled.ArrowIconContainer = styled.div`
|
||||
${layoutMixins.column}
|
||||
gap: 0.5ch;
|
||||
|
||||
svg {
|
||||
height: 0.75em;
|
||||
width: 0.75em;
|
||||
}
|
||||
`;
|
||||
|
||||
Styled.ArrowIcon = styled(Icon)<{ direction: 'up' | 'down'; color: 'green' | 'red' }>`
|
||||
${({ direction }) =>
|
||||
({
|
||||
['up']: css`
|
||||
transform: rotate(-90deg);
|
||||
`,
|
||||
['down']: css`
|
||||
transform: rotate(90deg);
|
||||
`,
|
||||
}[direction])}
|
||||
|
||||
${({ color }) =>
|
||||
({
|
||||
['green']: css`
|
||||
color: var(--color-success);
|
||||
`,
|
||||
['red']: css`
|
||||
color: var(--color-error);
|
||||
`,
|
||||
}[color])}
|
||||
`;
|
||||
|
||||
const indicatorStyle = css`
|
||||
--indicator-size: 1.25rem;
|
||||
--icon-size: 0.5rem;
|
||||
@@ -183,9 +282,33 @@ const indicatorStyle = css`
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
Styled.DotIndicator = styled.div<{ $selected: boolean }>`
|
||||
${indicatorStyle}
|
||||
--background-color: var(--color-layer-2);
|
||||
--border-color: var(--color-border);
|
||||
|
||||
${({ $selected }) =>
|
||||
$selected &&
|
||||
css`
|
||||
--background-color: var(--color-accent);
|
||||
--border-color: var(--color-accent);
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: var(--icon-size);
|
||||
height: var(--icon-size);
|
||||
background-color: var(--color-layer-2);
|
||||
border-radius: 50%;
|
||||
}
|
||||
`}
|
||||
|
||||
background-color: var(--background-color);
|
||||
border: solid var(--border-width) var(--border-color);
|
||||
`;
|
||||
|
||||
Styled.CheckIndicator = styled(Indicator)`
|
||||
${indicatorStyle}
|
||||
|
||||
position: absolute;
|
||||
bottom: var(--item-padding);
|
||||
right: var(--item-padding);
|
||||
|
||||
@@ -323,7 +323,7 @@ Styled.ReceiptArea = styled.div`
|
||||
`;
|
||||
|
||||
Styled.Green = styled.span`
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
`;
|
||||
|
||||
Styled.GreenCheckCircle = styled(GreenCheckCircle)`
|
||||
|
||||
@@ -453,6 +453,6 @@ Styled.FormInputButton = styled(Button)`
|
||||
Styled.CheckIcon = styled(Icon)`
|
||||
margin: 0 1ch;
|
||||
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
font-size: 0.625rem;
|
||||
`;
|
||||
|
||||
@@ -441,7 +441,7 @@ Styled.DestinationInputLabel = styled.span`
|
||||
${layoutMixins.inlineRow}
|
||||
|
||||
svg {
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ export const AccountMenu = () => {
|
||||
value: 'MnemonicExport',
|
||||
icon: <Icon iconName={IconName.ExportKeys} />,
|
||||
label: <span>{stringGetter({ key: STRING_KEYS.EXPORT_SECRET_PHRASE })}</span>,
|
||||
highlightColor: 'negative',
|
||||
highlightColor: 'destroy',
|
||||
onSelect: () => dispatch(openDialog({ type: DialogTypes.MnemonicExport })),
|
||||
},
|
||||
].filter(isTruthy)
|
||||
@@ -212,7 +212,7 @@ export const AccountMenu = () => {
|
||||
value: 'Disconnect',
|
||||
icon: <Icon iconName={IconName.BoxClose} />,
|
||||
label: stringGetter({ key: STRING_KEYS.DISCONNECT }),
|
||||
highlightColor: 'negative',
|
||||
highlightColor: 'destroy',
|
||||
onSelect: () => dispatch(openDialog({ type: DialogTypes.DisconnectWallet })),
|
||||
},
|
||||
].filter(isTruthy)}
|
||||
|
||||
@@ -72,7 +72,7 @@ Styled.Notification = styled(Notification)`
|
||||
Styled.Output = styled(Output)`
|
||||
&:before {
|
||||
content: '+';
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
margin-right: 0.5ch;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -179,7 +179,7 @@ Styled.Icon = styled.div<{ state: 'complete' | 'default' }>`
|
||||
${({ state }) =>
|
||||
({
|
||||
['complete']: css`
|
||||
color: var(--color-positive);
|
||||
color: var(--color-success);
|
||||
`,
|
||||
['default']: css`
|
||||
color: var(--color-text-0);
|
||||
|
||||
@@ -82,6 +82,6 @@ Styled.ActionButton = styled(IconButton)`
|
||||
|
||||
Styled.CancelButton = styled(Styled.ActionButton)`
|
||||
&:not(:disabled) {
|
||||
--button-textColor: var(--color-negative);
|
||||
--button-textColor: var(--color-error);
|
||||
}
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user