Skip to content

Commit 50c50bc

Browse files
committed
feat(v3-uplift): restyle alerts & refresh the data-viz palette
- alerts: rebuild the MuiAlert surface per the new spec — a 2.5rem icon box (inset border-0 ring + 20% severity tint), new two-tone severity icons (AlertIcons), fg-max Paragraph text, and a per-severity gradient fading from the colour at 3% to bg-2. Add the `danger` (#DC2626) token; severity map is info=purple-1 / warning=favourite-star / success=data-green / error=danger. Warning stays a thin Alert wrapper, so all ~100 alerts inherit the restyle. - colors: replace the data-* categorical scale with the new 17-hue palette (light + dark); drop the unused data-lime. - showcase: multi-line lorem in the alert demo to exercise the layout.
1 parent 316bef4 commit 50c50bc

4 files changed

Lines changed: 156 additions & 109 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { SvgIcon, SvgIconProps } from '@mui/material';
2+
3+
// Two-tone alert severity icons: a filled shape in `currentColor` (the severity color, set by the
4+
// Alert's icon box) with a fixed-white glyph on top. Rendered at 20×20 inside the alert icon box.
5+
6+
export const AlertInfoIcon = (props: SvgIconProps) => (
7+
<SvgIcon viewBox="0 0 20 20" {...props}>
8+
<path
9+
d="M10 18C5.58172 18 2 14.4183 2 10C2 5.58172 5.58172 2 10 2C14.4183 2 18 5.58172 18 10C18 14.4183 14.4183 18 10 18Z"
10+
fill="currentColor"
11+
/>
12+
<circle cx="10" cy="6.5" r="1.5" fill="#fff" />
13+
<path d="M10 10V14" stroke="#fff" strokeWidth="2" strokeLinecap="round" fill="none" />
14+
</SvgIcon>
15+
);
16+
17+
export const AlertWarningIcon = (props: SvgIconProps) => (
18+
<SvgIcon viewBox="0 0 20 20" {...props}>
19+
<path
20+
d="M8.26813 3.68164C9.03793 2.34831 10.9622 2.34831 11.732 3.68164L17.7945 14.1816C18.5641 15.5149 17.6016 17.1816 16.0621 17.1816H3.93805C2.3985 17.1816 1.43597 15.5149 2.20563 14.1816L8.26813 3.68164Z"
21+
fill="currentColor"
22+
/>
23+
<path d="M10 6V10" stroke="#fff" strokeWidth="2" strokeLinecap="round" fill="none" />
24+
<circle cx="10" cy="13.5" r="1.5" fill="#fff" />
25+
</SvgIcon>
26+
);
27+
28+
export const AlertSuccessIcon = (props: SvgIconProps) => (
29+
<SvgIcon viewBox="0 0 20 20" {...props}>
30+
<path
31+
d="M10 18C5.58172 18 2 14.4183 2 10C2 5.58172 5.58172 2 10 2C14.4183 2 18 5.58172 18 10C18 14.4183 14.4183 18 10 18Z"
32+
fill="currentColor"
33+
/>
34+
<path
35+
d="M6.5 10.25L8.75 12.5L13.5 7.5"
36+
stroke="#fff"
37+
strokeWidth="2"
38+
strokeLinecap="round"
39+
strokeLinejoin="round"
40+
fill="none"
41+
/>
42+
</SvgIcon>
43+
);
44+
45+
export const AlertErrorIcon = (props: SvgIconProps) => (
46+
<SvgIcon viewBox="0 0 20 20" {...props}>
47+
<path
48+
d="M10 18C5.58172 18 2 14.4183 2 10C2 5.58172 5.58172 2 10 2C14.4183 2 18 5.58172 18 10C18 14.4183 14.4183 18 10 18Z"
49+
fill="currentColor"
50+
/>
51+
<path
52+
d="M7.5 7.5L12.5 12.5M12.5 7.5L7.5 12.5"
53+
stroke="#fff"
54+
strokeWidth="2"
55+
strokeLinecap="round"
56+
fill="none"
57+
/>
58+
</SvgIcon>
59+
);

src/modules/dev/ComponentShowcase/components/FeedbackSection/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ export const FeedbackSection = () => (
1414
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, width: '100%' }}>
1515
{SEVERITIES.map((severity) => (
1616
<Alert key={severity} severity={severity}>
17-
This is a {severity} alert.
17+
This is a {severity} alert. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
18+
do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
19+
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo.
1820
</Alert>
1921
))}
2022
</Box>

src/utils/figmaColors.ts

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,30 @@ export const figmaLight = {
6161
ethereum: '#25292e',
6262
focus: 'rgba(26, 136, 248, 0.2)',
6363
scrim: 'rgba(247, 246, 246, 0.8)',
64-
'data-red': '#ff383c',
65-
'data-orange': '#e2a48d',
66-
'data-yellow': '#e3da8d',
67-
'data-lime': '#c1e38d',
68-
'data-green': '#32C958',
69-
'data-teal': '#8de3cc',
70-
'data-blue': '#8dcfe3',
71-
'data-purple': '#bcbbff',
72-
'data-pink': '#e1a4d9',
64+
// Data-viz categorical palette (17 hues, red → pink).
65+
'data-red': '#FF4760',
66+
'data-coral': '#FF513D',
67+
'data-orange': '#FF7029',
68+
'data-honey': '#FF8C00',
69+
'data-yellow': '#DBA400',
70+
'data-pear': '#CCAB00',
71+
'data-light-green': '#22CE80',
72+
'data-green': '#00BD68',
73+
'data-matcha': '#89BE2D',
74+
'data-seafoam': '#00B89F',
75+
'data-teal': '#05B4C7',
76+
'data-lagoon': '#12B4D9',
77+
'data-blue': '#38B0F5',
78+
'data-azure': '#4797FF',
79+
'data-purple': '#837AFF',
80+
'data-lavender': '#C061FF',
81+
'data-pink': '#EB47CF',
7382
'button-hover': 'rgba(0, 0, 0, 0.025)',
7483
'data-green-gho': '#5dff93',
7584
// Gold for the favourited market star (mode-agnostic; Figma color(display-p3 1 0.7 0)).
7685
'favourite-star': '#FFB300',
86+
// Alert "danger" severity red (icon + gradient); distinct from the muted error-* palette.
87+
danger: '#DC2626',
7788
// sGHO markets-banner gradient tints — data-green / neutral washes at 6%.
7889
'sgho-banner-green': 'rgba(50, 201, 88, 0.06)',
7990
'sgho-banner-fade': 'rgba(255, 255, 255, 0.06)',
@@ -170,15 +181,23 @@ export const figmaDark = {
170181
'navy-1': '#1c4886',
171182
'navy-2': '#6188c0',
172183
'navy-3': '#b0d3ff',
173-
'data-red': '#d34d63',
174-
'data-orange': '#e68662',
175-
'data-yellow': '#fdc75a',
176-
'data-lime': '#c1e38d',
184+
'data-red': '#E05269',
185+
'data-coral': '#FF7045',
186+
'data-orange': '#E68662',
187+
'data-honey': '#F59942',
188+
'data-yellow': '#FDC75A',
189+
'data-pear': '#FFE042',
190+
'data-light-green': '#C1E38D',
177191
'data-green': '#66C399',
178-
'data-teal': '#8de3cc',
179-
'data-blue': '#88d5ed',
180-
'data-purple': '#a5a3ff',
181-
'data-pink': '#e1a4d9',
192+
'data-matcha': '#92D492',
193+
'data-seafoam': '#78D3B3',
194+
'data-teal': '#8DE3CC',
195+
'data-lagoon': '#83DDDF',
196+
'data-blue': '#88D5ED',
197+
'data-azure': '#88C0FE',
198+
'data-purple': '#A5A3FF',
199+
'data-lavender': '#C9A1EF',
200+
'data-pink': '#E1A4D9',
182201
'shadow-low': 'rgba(0, 0, 0, 0.15)',
183202
'shadow-medium': 'rgba(0, 0, 0, 0.3)',
184203
'shadow-high': 'rgba(0, 0, 0, 0.35)',
@@ -194,6 +213,8 @@ export const figmaDark = {
194213
'data-green-gho': '#5dff93',
195214
// Gold for the favourited market star (mode-agnostic; Figma color(display-p3 1 0.7 0)).
196215
'favourite-star': '#FFB300',
216+
// Alert "danger" severity red (icon + gradient); distinct from the muted error-* palette.
217+
danger: '#DC2626',
197218
// sGHO markets-banner gradient tints — dark data-green / neutral washes at 6%.
198219
'sgho-banner-green': 'rgba(102, 195, 153, 0.06)',
199220
'sgho-banner-fade': 'rgba(255, 255, 255, 0.06)',

src/utils/theme.tsx

Lines changed: 56 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
import {
2-
CheckCircleIcon,
3-
ExclamationCircleIcon,
4-
ExclamationIcon,
5-
InformationCircleIcon,
6-
} from '@heroicons/react/outline';
71
import { Box, SvgIcon, ThemeOptions } from '@mui/material';
82
import { type CSSObject, createTheme, experimental_extendTheme } from '@mui/material/styles';
93
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -13,6 +7,12 @@ import { ColorPartial } from '@mui/material/styles/createPalette';
137
// so `theme.vars.palette.*` typechecks app-wide, not only against this file's `AppTheme` param.
148
import type {} from '@mui/material/themeCssVarsAugmentation';
159
import React from 'react';
10+
import {
11+
AlertErrorIcon,
12+
AlertInfoIcon,
13+
AlertSuccessIcon,
14+
AlertWarningIcon,
15+
} from 'src/components/icons/AlertIcons';
1616
import { ChevronUpDownIcon } from 'src/components/icons/ChevronUpDownIcon';
1717
import { ScaleFade } from 'src/components/primitives/transitions/ScaleFade';
1818

@@ -100,6 +100,16 @@ const tertiaryPillStyle = {
100100
},
101101
};
102102

103+
// Alert severity surface: a gradient from the severity colour at 3% (left) fading to bg-2 (right)
104+
// over a bg-2 base, plus the full colour + a 20% tint behind/inside the icon box.
105+
const alertSeverityStyle = (color: string): CSSObject => ({
106+
background: `linear-gradient(90deg, color-mix(in srgb, ${color} 3%, transparent) 0%, ${figVars['bg-2']} 100%), ${figVars['bg-2']}`,
107+
'.MuiAlert-icon': {
108+
color,
109+
backgroundColor: `color-mix(in srgb, ${color} 20%, transparent)`,
110+
},
111+
});
112+
103113
// Shared box geometry for the custom selection-control icons (checkbox + radio).
104114
const checkboxIconBox = { width: 18, height: 18, borderRadius: '0.375rem' };
105115

@@ -1036,33 +1046,52 @@ export function getThemedComponents(theme: AppTheme) {
10361046
MuiAlert: {
10371047
styleOverrides: {
10381048
root: {
1039-
boxShadow: 'none',
1040-
borderRadius: '4px',
1041-
padding: '8px 12px',
1042-
...theme.typography.caption,
1049+
display: 'flex',
10431050
alignItems: 'flex-start',
1044-
'.MuiAlert-message': {
1045-
padding: 0,
1046-
paddingTop: '2px',
1047-
paddingBottom: '2px',
1048-
},
1051+
gap: '0.88rem',
1052+
padding: '1rem 1.25rem',
1053+
borderRadius: '0.75rem',
1054+
boxShadow: figSurfaceShadow(),
1055+
// Icon box: a 2.5rem rounded square with a border-0 hairline. Its per-severity tint
1056+
// fill + icon color are set in the severity variants below.
10491057
'.MuiAlert-icon': {
1050-
padding: 0,
1058+
margin: 0,
1059+
padding: '0.625rem',
1060+
width: '2.5rem',
1061+
height: '2.5rem',
1062+
flexShrink: 0,
1063+
display: 'flex',
1064+
alignItems: 'center',
1065+
justifyContent: 'center',
1066+
borderRadius: '0.5rem',
1067+
boxShadow: `inset 0 0 0 1px ${figVars['border-0']}`,
10511068
opacity: 1,
10521069
'.MuiSvgIcon-root': {
1053-
fontSize: pxToRem(20),
1070+
fontSize: '1.25rem',
1071+
flexShrink: 0,
10541072
},
10551073
},
1074+
// Message: Paragraph text in fg-max, centered against the icon box on a single line;
1075+
// multi-line grows and top-aligns via the container's flex-start.
1076+
'.MuiAlert-message': {
1077+
padding: 0,
1078+
alignSelf: 'center',
1079+
color: figVars['fg-max'],
1080+
fontFamily: FONT,
1081+
fontWeight: 400,
1082+
fontSize: pxToRem(14),
1083+
lineHeight: pxToRem(19),
1084+
},
10561085
a: {
1057-
...theme.typography.caption,
1086+
color: 'inherit',
10581087
fontWeight: 500,
10591088
textDecoration: 'underline',
10601089
'&:hover': {
10611090
textDecoration: 'none',
10621091
},
10631092
},
10641093
'.MuiButton-text': {
1065-
...theme.typography.caption,
1094+
color: 'inherit',
10661095
fontWeight: 500,
10671096
textDecoration: 'underline',
10681097
padding: 0,
@@ -1077,81 +1106,17 @@ export function getThemedComponents(theme: AppTheme) {
10771106
},
10781107
defaultProps: {
10791108
iconMapping: {
1080-
error: (
1081-
<SvgIcon color="error">
1082-
<ExclamationIcon />
1083-
</SvgIcon>
1084-
),
1085-
info: (
1086-
<SvgIcon color="info">
1087-
<InformationCircleIcon />
1088-
</SvgIcon>
1089-
),
1090-
success: (
1091-
<SvgIcon color="success">
1092-
<CheckCircleIcon />
1093-
</SvgIcon>
1094-
),
1095-
warning: (
1096-
<SvgIcon color="warning">
1097-
<ExclamationCircleIcon />
1098-
</SvgIcon>
1099-
),
1109+
error: <AlertErrorIcon />,
1110+
info: <AlertInfoIcon />,
1111+
success: <AlertSuccessIcon />,
1112+
warning: <AlertWarningIcon />,
11001113
},
11011114
},
11021115
variants: [
1103-
{
1104-
props: { severity: 'error' },
1105-
style: {
1106-
color: theme.vars.palette.error['100'],
1107-
background: theme.vars.palette.error['200'],
1108-
a: {
1109-
color: theme.vars.palette.error['100'],
1110-
},
1111-
'.MuiButton-text': {
1112-
color: theme.vars.palette.error['100'],
1113-
},
1114-
},
1115-
},
1116-
{
1117-
props: { severity: 'info' },
1118-
style: {
1119-
color: theme.vars.palette.info['100'],
1120-
background: theme.vars.palette.info['200'],
1121-
a: {
1122-
color: theme.vars.palette.info['100'],
1123-
},
1124-
'.MuiButton-text': {
1125-
color: theme.vars.palette.info['100'],
1126-
},
1127-
},
1128-
},
1129-
{
1130-
props: { severity: 'success' },
1131-
style: {
1132-
color: theme.vars.palette.success['100'],
1133-
background: theme.vars.palette.success['200'],
1134-
a: {
1135-
color: theme.vars.palette.success['100'],
1136-
},
1137-
'.MuiButton-text': {
1138-
color: theme.vars.palette.success['100'],
1139-
},
1140-
},
1141-
},
1142-
{
1143-
props: { severity: 'warning' },
1144-
style: {
1145-
color: theme.vars.palette.warning['100'],
1146-
background: theme.vars.palette.warning['200'],
1147-
a: {
1148-
color: theme.vars.palette.warning['100'],
1149-
},
1150-
'.MuiButton-text': {
1151-
color: theme.vars.palette.warning['100'],
1152-
},
1153-
},
1154-
},
1116+
{ props: { severity: 'error' }, style: alertSeverityStyle(figVars['danger']) },
1117+
{ props: { severity: 'info' }, style: alertSeverityStyle(figVars['purple-1']) },
1118+
{ props: { severity: 'success' }, style: alertSeverityStyle(figVars['data-green']) },
1119+
{ props: { severity: 'warning' }, style: alertSeverityStyle(figVars['favourite-star']) },
11551120
],
11561121
},
11571122
MuiCssBaseline: {

0 commit comments

Comments
 (0)