Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8717fdf

Browse files
refactor(site): refactor pill component API (coder#11329)
Refactor the Pill API to make it easier to extend and reuse.
1 parent c9b7d61 commit 8717fdf

File tree

13 files changed

+112
-84
lines changed

13 files changed

+112
-84
lines changed

site/src/components/Dashboard/LicenseBanner/LicenseBannerView.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const LicenseBannerView: FC<LicenseBannerViewProps> = ({
5555
if (messages.length === 1) {
5656
return (
5757
<div css={containerStyles}>
58-
<Pill text={Language.licenseIssue} type={type} />
58+
<Pill type={type}>{Language.licenseIssue}</Pill>
5959
<div css={styles.leftContent}>
6060
<span>{messages[0]}</span>
6161
&nbsp;
@@ -73,7 +73,7 @@ export const LicenseBannerView: FC<LicenseBannerViewProps> = ({
7373

7474
return (
7575
<div css={containerStyles}>
76-
<Pill text={Language.licenseIssues(messages.length)} type={type} />
76+
<Pill type={type}>{Language.licenseIssues(messages.length)}</Pill>
7777
<div css={styles.leftContent}>
7878
<div>
7979
{Language.exceeded}

site/src/components/Dashboard/ServiceBanner/ServiceBannerView.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const ServiceBannerView: FC<ServiceBannerViewProps> = ({
1717
}) => {
1818
return (
1919
<div css={[styles.banner, { backgroundColor }]}>
20-
{isPreview && <Pill text="Preview" type="info" />}
20+
{isPreview && <Pill type="info">Preview</Pill>}
2121
<div
2222
css={[
2323
styles.wrapper,
+17-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Pill } from "./Pill";
22
import type { Meta, StoryObj } from "@storybook/react";
3+
import InfoOutlined from "@mui/icons-material/InfoOutlined";
34

45
const meta: Meta<typeof Pill> = {
56
title: "components/Pill",
@@ -11,55 +12,63 @@ type Story = StoryObj<typeof Pill>;
1112

1213
export const Default: Story = {
1314
args: {
14-
text: "Default",
15+
children: "Default",
1516
},
1617
};
1718

1819
export const Danger: Story = {
1920
args: {
20-
text: "Danger",
21+
children: "Danger",
2122
type: "danger",
2223
},
2324
};
2425

2526
export const Error: Story = {
2627
args: {
27-
text: "Error",
28+
children: "Error",
2829
type: "error",
2930
},
3031
};
3132

3233
export const Warning: Story = {
3334
args: {
34-
text: "Warning",
35+
children: "Warning",
3536
type: "warning",
3637
},
3738
};
3839

3940
export const Notice: Story = {
4041
args: {
41-
text: "Notice",
42+
children: "Notice",
4243
type: "notice",
4344
},
4445
};
4546

4647
export const Info: Story = {
4748
args: {
48-
text: "Information",
49+
children: "Information",
4950
type: "info",
5051
},
5152
};
5253

5354
export const Success: Story = {
5455
args: {
55-
text: "Success",
56+
children: "Success",
5657
type: "success",
5758
},
5859
};
5960

6061
export const Active: Story = {
6162
args: {
62-
text: "Active",
63+
children: "Active",
6364
type: "active",
6465
},
6566
};
67+
68+
export const WithIcon: Story = {
69+
args: {
70+
children: "Information",
71+
type: "info",
72+
icon: <InfoOutlined />,
73+
},
74+
};

site/src/components/Pill/Pill.tsx

+31-39
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
import { type FC, type ReactNode, useMemo, forwardRef } from "react";
2-
import { css, useTheme, type Interpolation, type Theme } from "@emotion/react";
1+
import {
2+
type FC,
3+
type ReactNode,
4+
useMemo,
5+
forwardRef,
6+
HTMLAttributes,
7+
} from "react";
8+
import { useTheme, type Interpolation, type Theme } from "@emotion/react";
39
import type { ThemeRole } from "theme/experimental";
410

511
export type PillType = ThemeRole | keyof typeof themeOverrides;
612

7-
export interface PillProps {
8-
className?: string;
13+
export type PillProps = HTMLAttributes<HTMLDivElement> & {
914
icon?: ReactNode;
10-
text: ReactNode;
1115
type?: PillType;
12-
title?: string;
13-
}
16+
};
1417

1518
const themeOverrides = {
1619
neutral: (theme) => ({
@@ -27,11 +30,14 @@ const themeStyles = (type: ThemeRole) => (theme: Theme) => {
2730
};
2831
};
2932

33+
const PILL_HEIGHT = 24;
34+
const PILL_ICON_SIZE = 14;
35+
const PILL_ICON_SPACING = (PILL_HEIGHT - PILL_ICON_SIZE) / 2;
36+
3037
export const Pill: FC<PillProps> = forwardRef<HTMLDivElement, PillProps>(
3138
(props, ref) => {
32-
const { icon, text = null, type = "neutral", ...attrs } = props;
39+
const { icon, type = "neutral", children, ...divProps } = props;
3340
const theme = useTheme();
34-
3541
const typeStyles = useMemo(() => {
3642
if (type in themeOverrides) {
3743
return themeOverrides[type as keyof typeof themeOverrides];
@@ -44,47 +50,33 @@ export const Pill: FC<PillProps> = forwardRef<HTMLDivElement, PillProps>(
4450
ref={ref}
4551
css={[
4652
{
53+
fontSize: 12,
54+
color: theme.experimental.l1.text,
4755
cursor: "default",
4856
display: "inline-flex",
4957
alignItems: "center",
58+
whiteSpace: "nowrap",
59+
fontWeight: 400,
5060
borderWidth: 1,
5161
borderStyle: "solid",
5262
borderRadius: 99999,
53-
fontSize: 12,
54-
color: theme.experimental.l1.text,
55-
height: 24,
56-
paddingLeft: icon ? 6 : 12,
63+
lineHeight: 1,
64+
height: PILL_HEIGHT,
65+
gap: PILL_ICON_SPACING,
5766
paddingRight: 12,
58-
whiteSpace: "nowrap",
59-
fontWeight: 400,
67+
paddingLeft: icon ? PILL_ICON_SPACING : 12,
68+
69+
"& svg": {
70+
width: PILL_ICON_SIZE,
71+
height: PILL_ICON_SIZE,
72+
},
6073
},
6174
typeStyles,
6275
]}
63-
role="status"
64-
{...attrs}
76+
{...divProps}
6577
>
66-
{icon && (
67-
<div
68-
css={css`
69-
margin-right: 4px;
70-
width: 14px;
71-
height: 14px;
72-
line-height: 0;
73-
display: flex;
74-
align-items: center;
75-
justify-content: center;
76-
77-
& > img,
78-
& > svg {
79-
width: 14px;
80-
height: 14px;
81-
}
82-
`}
83-
>
84-
{icon}
85-
</div>
86-
)}
87-
{text}
78+
{icon}
79+
{children}
8880
</div>
8981
);
9082
},

site/src/components/TemplateExampleCard/TemplateExampleCard.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ export const TemplateExampleCard = (props: TemplateExampleCardProps) => {
5757
return (
5858
<RouterLink key={tag} to={`/starter-templates?tag=${tag}`}>
5959
<Pill
60-
text={tag}
6160
css={(theme) => ({
6261
borderColor: isActive
6362
? theme.palette.primary.main
@@ -70,7 +69,9 @@ export const TemplateExampleCard = (props: TemplateExampleCardProps) => {
7069
borderColor: theme.palette.primary.main,
7170
},
7271
})}
73-
/>
72+
>
73+
{tag}
74+
</Pill>
7475
</RouterLink>
7576
);
7677
})}

site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx

+14-8
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ export const WorkspaceStatusBadge: FC<WorkspaceStatusBadgeProps> = ({
4747
}
4848
placement="top"
4949
>
50-
<div>
51-
<Pill className={className} icon={icon} text={text} type={type} />
52-
</div>
50+
<Pill role="status" className={className} icon={icon} type={type}>
51+
{text}
52+
</Pill>
5353
</FailureTooltip>
5454
</Cond>
5555
<Cond>
56-
<Pill className={className} icon={icon} text={text} type={type} />
56+
<Pill role="status" className={className} icon={icon} type={type}>
57+
{text}
58+
</Pill>
5759
</Cond>
5860
</ChooseOne>
5961
);
@@ -95,11 +97,13 @@ export const DormantStatusBadge: FC<DormantStatusBadgeProps> = ({
9597
}
9698
>
9799
<Pill
100+
role="status"
98101
className={className}
99102
icon={<AutoDeleteIcon />}
100-
text="Deletion Pending"
101103
type="error"
102-
/>
104+
>
105+
Deletion Pending
106+
</Pill>
103107
</Tooltip>
104108
) : (
105109
<Tooltip
@@ -113,11 +117,13 @@ export const DormantStatusBadge: FC<DormantStatusBadgeProps> = ({
113117
}
114118
>
115119
<Pill
120+
role="status"
116121
className={className}
117122
icon={<RecyclingIcon />}
118-
text="Dormant"
119123
type="warning"
120-
/>
124+
>
125+
Dormant
126+
</Pill>
121127
</Tooltip>
122128
);
123129
};

site/src/pages/AuditPage/AuditLogRow/AuditLogRow.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ export const AuditLogRow: React.FC<AuditLogRowProps> = ({
138138
<Pill
139139
css={styles.httpStatusPill}
140140
type={httpStatusColor(auditLog.status_code)}
141-
text={auditLog.status_code.toString()}
142-
/>
141+
>
142+
{auditLog.status_code.toString()}
143+
</Pill>
143144
</Stack>
144145
</Stack>
145146
</Stack>

site/src/pages/DeploySettingsPage/LicensesSettingsPage/LicenseCard.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ export const LicenseCard = ({
8686
new Date(license.claims.license_expires * 1000),
8787
new Date(),
8888
) < 1 ? (
89-
<Pill css={styles.expiredBadge} text="Expired" type="error" />
89+
<Pill css={styles.expiredBadge} type="error">
90+
Expired
91+
</Pill>
9092
) : (
9193
<span css={styles.secondaryMaincolor}>Valid Until</span>
9294
)}

site/src/pages/TemplatePage/TemplatePageHeader.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
216216
)}
217217
</div>
218218

219-
{template.deprecated && <Pill text="Deprecated" type="warning" />}
219+
{template.deprecated && <Pill type="warning">Deprecated</Pill>}
220220
</Stack>
221221
</PageHeader>
222222
</Margins>

site/src/pages/TemplatePage/TemplateVersionsPage/VersionRow.tsx

+24-7
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,36 @@ export const VersionRow: FC<VersionRowProps> = ({
7575
</Stack>
7676

7777
<Stack direction="row" alignItems="center" spacing={2}>
78-
{isActive && <Pill text="Active" type="success" />}
79-
{isLatest && <Pill text="Newest" type="info" />}
80-
78+
{isActive && (
79+
<Pill role="status" type="success">
80+
Active
81+
</Pill>
82+
)}
83+
{isLatest && (
84+
<Pill role="status" type="info">
85+
Newest
86+
</Pill>
87+
)}
8188
{jobStatus === "pending" && (
82-
<Pill text={<>Pending&hellip;</>} type="warning" />
89+
<Pill role="status" type="warning">
90+
Pending&hellip;
91+
</Pill>
8392
)}
8493
{jobStatus === "running" && (
85-
<Pill text={<>Building&hellip;</>} type="warning" />
94+
<Pill role="status" type="warning">
95+
Building&hellip;
96+
</Pill>
8697
)}
8798
{(jobStatus === "canceling" || jobStatus === "canceled") && (
88-
<Pill text="Canceled" type="neutral" />
99+
<Pill role="status" type="neutral">
100+
Canceled
101+
</Pill>
102+
)}
103+
{jobStatus === "failed" && (
104+
<Pill role="status" type="error">
105+
Failed
106+
</Pill>
89107
)}
90-
{jobStatus === "failed" && <Pill text="Failed" type="error" />}
91108

92109
{showActions && (
93110
<>

site/src/pages/TemplateVersionEditorPage/TemplateVersionStatusBadge.tsx

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@ export const TemplateVersionStatusBadge: FC<{
1010
}> = ({ version }) => {
1111
const { text, icon, type } = getStatus(version);
1212
return (
13-
<Pill
14-
icon={icon}
15-
text={text}
16-
type={type}
17-
title={`Build status is ${text}`}
18-
/>
13+
<Pill icon={icon} type={type} title={`Build status is ${text}`}>
14+
{text}
15+
</Pill>
1916
);
2017
};
2118

0 commit comments

Comments
 (0)