Skip to content

Commit 4bf1a97

Browse files
committed
chore: refactor Pill styles
1 parent 9e1e365 commit 4bf1a97

File tree

2 files changed

+100
-61
lines changed

2 files changed

+100
-61
lines changed

site/src/components/Pill/Pill.tsx

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,104 @@
1-
import { PaletteColor, Theme } from "@mui/material/styles";
2-
import { makeStyles } from "@mui/styles";
3-
import { FC } from "react";
4-
import { PaletteIndex } from "theme/theme";
5-
import { combineClasses } from "utils/combineClasses";
1+
import { type PaletteColor } from "@mui/material/styles";
2+
import { type FC, type ReactNode, useMemo } from "react";
3+
import { css, type Interpolation, type Theme, useTheme } from "@emotion/react";
4+
import { colors } from "theme/colors";
5+
6+
export type PillType =
7+
| "primary"
8+
| "secondary"
9+
| "error"
10+
| "warning"
11+
| "info"
12+
| "success"
13+
| "neutral";
614

715
export interface PillProps {
816
className?: string;
9-
icon?: React.ReactNode;
10-
text: string;
11-
type?: PaletteIndex;
17+
icon?: ReactNode;
18+
text: ReactNode;
19+
type?: PillType;
1220
lightBorder?: boolean;
1321
title?: string;
1422
}
1523

24+
const themeOverrides = {
25+
primary: (lightBorder) => ({
26+
backgroundColor: colors.blue[13],
27+
borderColor: lightBorder ? colors.blue[5] : colors.blue[7],
28+
}),
29+
secondary: (lightBorder) => ({
30+
backgroundColor: colors.indigo[13],
31+
borderColor: lightBorder ? colors.indigo[6] : colors.indigo[8],
32+
}),
33+
neutral: (lightBorder) => ({
34+
backgroundColor: colors.gray[13],
35+
borderColor: lightBorder ? colors.gray[6] : colors.gray[8],
36+
}),
37+
} satisfies Record<string, (lightBorder?: boolean) => Interpolation<Theme>>;
38+
39+
const themeStyles =
40+
(type: PillType, lightBorder?: boolean) => (theme: Theme) => {
41+
const palette = theme.palette[type] as PaletteColor;
42+
return {
43+
backgroundColor: palette.dark,
44+
borderColor: lightBorder ? palette.light : palette.main,
45+
};
46+
};
47+
1648
export const Pill: FC<PillProps> = (props) => {
17-
const { className, icon, text = false, title } = props;
18-
const styles = useStyles(props);
49+
const { lightBorder, icon, text = null, type = "neutral", ...attrs } = props;
50+
const theme = useTheme();
51+
52+
const typeStyles = useMemo(() => {
53+
if (type in themeOverrides) {
54+
return themeOverrides[type as keyof typeof themeOverrides](lightBorder);
55+
}
56+
return themeStyles(type, lightBorder);
57+
}, [type, lightBorder]);
58+
1959
return (
2060
<div
21-
className={combineClasses([styles.wrapper, styles.pillColor, className])}
61+
css={[
62+
{
63+
display: "inline-flex",
64+
alignItems: "center",
65+
borderWidth: 1,
66+
borderStyle: "solid",
67+
borderRadius: 99999,
68+
fontSize: 12,
69+
color: "#FFF",
70+
height: theme.spacing(3),
71+
paddingLeft: icon ? theme.spacing(0.75) : theme.spacing(1.5),
72+
paddingRight: theme.spacing(1.5),
73+
whiteSpace: "nowrap",
74+
fontWeight: 400,
75+
},
76+
typeStyles,
77+
]}
2278
role="status"
23-
title={title}
79+
{...attrs}
2480
>
25-
{icon && <div className={styles.iconWrapper}>{icon}</div>}
81+
{icon && (
82+
<div
83+
css={css`
84+
margin-right: ${theme.spacing(0.5)};
85+
width: ${theme.spacing(1.75)};
86+
height: ${theme.spacing(1.75)};
87+
line-height: 0;
88+
display: flex;
89+
align-items: center;
90+
justify-content: center;
91+
92+
& > * {
93+
width: ${theme.spacing(1.75)};
94+
height: ${theme.spacing(1.75)};
95+
}
96+
`}
97+
>
98+
{icon}
99+
</div>
100+
)}
26101
{text}
27102
</div>
28103
);
29104
};
30-
31-
const useStyles = makeStyles<Theme, PillProps>((theme) => ({
32-
wrapper: {
33-
display: "inline-flex",
34-
alignItems: "center",
35-
borderWidth: 1,
36-
borderStyle: "solid",
37-
borderRadius: 99999,
38-
fontSize: 12,
39-
color: "#FFF",
40-
height: theme.spacing(3),
41-
paddingLeft: ({ icon }) =>
42-
icon ? theme.spacing(0.75) : theme.spacing(1.5),
43-
paddingRight: theme.spacing(1.5),
44-
whiteSpace: "nowrap",
45-
fontWeight: 400,
46-
},
47-
48-
pillColor: {
49-
backgroundColor: ({ type }) =>
50-
type
51-
? (theme.palette[type] as PaletteColor).dark
52-
: theme.palette.text.secondary,
53-
borderColor: ({ type, lightBorder }) =>
54-
type
55-
? lightBorder
56-
? (theme.palette[type] as PaletteColor).light
57-
: (theme.palette[type] as PaletteColor).main
58-
: theme.palette.text.secondary,
59-
},
60-
61-
iconWrapper: {
62-
marginRight: theme.spacing(0.5),
63-
width: theme.spacing(1.75),
64-
height: theme.spacing(1.75),
65-
lineHeight: 0,
66-
display: "flex",
67-
alignItems: "center",
68-
justifyContent: "center",
69-
70-
"& > svg": {
71-
width: theme.spacing(1.75),
72-
height: theme.spacing(1.75),
73-
},
74-
},
75-
}));

site/src/theme/theme.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@ export const BUTTON_LG_HEIGHT = 40;
77
export const BUTTON_MD_HEIGHT = 36;
88
export const BUTTON_SM_HEIGHT = 32;
99

10-
export type PaletteIndex = keyof Theme["palette"];
10+
export type PaletteIndex =
11+
| "primary"
12+
| "secondary"
13+
| "background"
14+
| "text"
15+
| "error"
16+
| "warning"
17+
| "info"
18+
| "success"
19+
| "action"
20+
| "neutral";
1121

1222
export let dark = createTheme({
1323
palette: {
@@ -46,7 +56,7 @@ export let dark = createTheme({
4656
info: {
4757
light: colors.blue[7],
4858
main: colors.blue[9],
49-
dark: colors.blue[15],
59+
dark: colors.blue[14],
5060
contrastText: colors.gray[4],
5161
},
5262
error: {

0 commit comments

Comments
 (0)