Skip to content

Commit 4d989c6

Browse files
committed
ref(badges): Move a bunch of badge* components into one folder
1 parent 7ddbab7 commit 4d989c6

File tree

96 files changed

+464
-401
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+464
-401
lines changed

static/app/components/badge.tsx

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,8 @@
1-
import type {Theme} from '@emotion/react';
2-
import styled from '@emotion/styled';
3-
4-
import {space} from 'sentry/styles/space';
5-
6-
interface Props extends React.HTMLAttributes<HTMLSpanElement> {
7-
text?: string | number | null;
8-
type?: keyof Theme['badge'];
9-
}
10-
11-
const Badge = styled(({children, text, ...props}: Props) => (
12-
<span {...props}>{children ?? text}</span>
13-
))<Props>`
14-
display: inline-block;
15-
height: 20px;
16-
min-width: 20px;
17-
line-height: 20px;
18-
border-radius: 20px;
19-
padding: 0 5px;
20-
margin-left: ${space(0.5)};
21-
font-size: 75%;
22-
font-weight: 600;
23-
text-align: center;
24-
color: ${p => p.theme.badge[p.type ?? 'default'].color};
25-
background: ${p => p.theme.badge[p.type ?? 'default'].background};
26-
transition: background 100ms linear;
27-
28-
position: relative;
29-
`;
1+
import Badge from 'sentry/components/badge/badge';
302

3+
/**
4+
* @deprecated Import from `sentry/components/badge/badge` instead
5+
*
6+
* TODO(ryan953): remove this shim once getsentry imports are updated
7+
*/
318
export default Badge;

static/app/components/alertBadge.spec.tsx renamed to static/app/components/badge/alertBadge.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {render, screen} from 'sentry-test/reactTestingLibrary';
22

3-
import AlertBadge from 'sentry/components/alertBadge';
3+
import AlertBadge from 'sentry/components/badge/alertBadge';
44
import {IncidentStatus} from 'sentry/views/alerts/types';
55

66
describe('AlertBadge', () => {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {Fragment} from 'react';
2+
3+
import AlertBadge from 'sentry/components/badge/alertBadge';
4+
import Matrix from 'sentry/components/stories/matrix';
5+
import storyBook from 'sentry/stories/storyBook';
6+
import {IncidentStatus} from 'sentry/views/alerts/types';
7+
8+
export default storyBook(AlertBadge, story => {
9+
story('Default', () => <AlertBadge />);
10+
11+
const props = {
12+
status: [
13+
IncidentStatus.CLOSED,
14+
IncidentStatus.CRITICAL,
15+
IncidentStatus.OPENED,
16+
IncidentStatus.WARNING,
17+
],
18+
withText: [false, true],
19+
isIssue: [false, true],
20+
};
21+
story('Props', () => (
22+
<Fragment>
23+
<Matrix
24+
render={AlertBadge}
25+
selectedProps={['withText', 'status']}
26+
propMatrix={props}
27+
/>
28+
<Matrix
29+
render={AlertBadge}
30+
selectedProps={['isIssue', 'withText']}
31+
propMatrix={props}
32+
/>
33+
<Matrix
34+
render={AlertBadge}
35+
selectedProps={['isIssue', 'status']}
36+
propMatrix={props}
37+
/>
38+
</Fragment>
39+
));
40+
});

static/app/components/badge.stories.tsx renamed to static/app/components/badge/badge.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Badge from 'sentry/components/badge';
1+
import Badge from 'sentry/components/badge/badge';
22
import JSXProperty from 'sentry/components/stories/jsxProperty';
33
import SideBySide from 'sentry/components/stories/sideBySide';
44
import storyBook from 'sentry/stories/storyBook';

static/app/components/badge/badge.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type {Theme} from '@emotion/react';
2+
import styled from '@emotion/styled';
3+
4+
import {space} from 'sentry/styles/space';
5+
6+
interface Props extends React.HTMLAttributes<HTMLSpanElement> {
7+
text?: string | number | null;
8+
type?: keyof Theme['badge'];
9+
}
10+
11+
const Badge = styled(({children, text, ...props}: Props) => (
12+
<span {...props}>{children ?? text}</span>
13+
))<Props>`
14+
display: inline-block;
15+
height: 20px;
16+
min-width: 20px;
17+
line-height: 20px;
18+
border-radius: 20px;
19+
padding: 0 5px;
20+
margin-left: ${space(0.5)};
21+
font-size: 75%;
22+
font-weight: 600;
23+
text-align: center;
24+
color: ${p => p.theme.badge[p.type ?? 'default'].color};
25+
background: ${p => p.theme.badge[p.type ?? 'default'].background};
26+
transition: background 100ms linear;
27+
28+
position: relative;
29+
`;
30+
31+
export default Badge;

static/app/components/featureBadge.spec.tsx renamed to static/app/components/badge/featureBadge.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {render, screen} from 'sentry-test/reactTestingLibrary';
22

3-
import FeatureBadge from 'sentry/components/featureBadge';
3+
import FeatureBadge from 'sentry/components/badge/featureBadge';
44

55
describe('FeatureBadge', function () {
66
it('auto-hides when expired', function () {

static/app/components/featureBadge.stories.tsx renamed to static/app/components/badge/featureBadge.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type {ComponentProps} from 'react';
22
import {Fragment} from 'react';
33

4-
import FeatureBadge from 'sentry/components/featureBadge';
4+
import FeatureBadge from 'sentry/components/badge/featureBadge';
55
import Matrix from 'sentry/components/stories/matrix';
66
import SideBySide from 'sentry/components/stories/sideBySide';
77
import storyBook from 'sentry/stories/storyBook';
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import {Fragment} from 'react';
2+
import {useTheme} from '@emotion/react';
3+
import styled from '@emotion/styled';
4+
import {captureException, withScope} from '@sentry/react';
5+
import type {SeverityLevel} from '@sentry/types';
6+
7+
import Badge from 'sentry/components/badge/badge';
8+
import CircleIndicator from 'sentry/components/circleIndicator';
9+
import type {TooltipProps} from 'sentry/components/tooltip';
10+
import {Tooltip} from 'sentry/components/tooltip';
11+
import {t} from 'sentry/locale';
12+
import type {ValidSize} from 'sentry/styles/space';
13+
import {space} from 'sentry/styles/space';
14+
15+
export type BadgeType = 'alpha' | 'beta' | 'new' | 'experimental';
16+
17+
type BadgeProps = {
18+
type: BadgeType;
19+
condensed?: boolean;
20+
expiresAt?: Date;
21+
title?: string;
22+
tooltipProps?: Partial<TooltipProps>;
23+
variant?: 'badge' | 'indicator' | 'short';
24+
};
25+
26+
type Props = Omit<React.HTMLAttributes<HTMLDivElement>, keyof BadgeProps> & BadgeProps;
27+
28+
const defaultTitles: Record<BadgeType, string> = {
29+
alpha: t('This feature is internal and available for QA purposes'),
30+
beta: t('This feature is available for early adopters and may change'),
31+
new: t('This feature is new! Try it out and let us know what you think'),
32+
experimental: t(
33+
'This feature is experimental! Try it out and let us know what you think. No promises!'
34+
),
35+
};
36+
37+
const labels: Record<BadgeType, string> = {
38+
alpha: t('alpha'),
39+
beta: t('beta'),
40+
new: t('new'),
41+
experimental: t('experimental'),
42+
};
43+
44+
const shortLabels: Record<BadgeType, string> = {
45+
alpha: 'A',
46+
beta: 'B',
47+
new: 'N',
48+
experimental: 'E',
49+
};
50+
51+
function BaseFeatureBadge({
52+
type,
53+
variant = 'badge',
54+
title,
55+
tooltipProps,
56+
expiresAt,
57+
...props
58+
}: Props) {
59+
const theme = useTheme();
60+
if (expiresAt && expiresAt.valueOf() < Date.now()) {
61+
// Only get 1% of events as we don't need many to know that a badge needs to be cleaned up.
62+
if (Math.random() < 0.01) {
63+
withScope(scope => {
64+
scope.setTag('title', title);
65+
scope.setTag('type', type);
66+
scope.setLevel('warning' as SeverityLevel);
67+
captureException(new Error('Expired Feature Badge'));
68+
});
69+
}
70+
return null;
71+
}
72+
73+
return (
74+
<div {...props}>
75+
<Tooltip title={title ?? defaultTitles[type]} position="right" {...tooltipProps}>
76+
<Fragment>
77+
{variant === 'badge' && <StyledBadge type={type} text={labels[type]} />}
78+
{variant === 'short' && <StyledBadge type={type} text={shortLabels[type]} />}
79+
{variant === 'indicator' && (
80+
<CircleIndicator color={theme.badge[type].indicatorColor} size={8} />
81+
)}
82+
</Fragment>
83+
</Tooltip>
84+
</div>
85+
);
86+
}
87+
88+
const StyledBadge = styled(Badge)`
89+
margin: 0;
90+
padding: 0 ${space(0.75)};
91+
line-height: ${space(2)};
92+
height: ${space(2)};
93+
font-weight: normal;
94+
font-size: ${p => p.theme.fontSizeExtraSmall};
95+
vertical-align: middle;
96+
`;
97+
98+
const FeatureBadge = styled(BaseFeatureBadge)<{space?: ValidSize}>`
99+
display: inline-flex;
100+
align-items: center;
101+
margin-left: ${p => space(p.space ?? 0.75)};
102+
`;
103+
104+
export default FeatureBadge;

static/app/components/group/groupPriority.spec.tsx renamed to static/app/components/badge/groupPriority.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {UserFixture} from 'sentry-fixture/user';
44
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
55
import {textWithMarkupMatcher} from 'sentry-test/utils';
66

7-
import {GroupPriorityDropdown} from 'sentry/components/group/groupPriority';
7+
import {GroupPriorityDropdown} from 'sentry/components/badge/groupPriority';
88
import {GroupActivityType, PriorityLevel} from 'sentry/types';
99

1010
describe('GroupPriority', () => {

static/app/components/group/groupPriority.stories.tsx renamed to static/app/components/badge/groupPriority.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {useState} from 'react';
33
import {
44
GroupPriorityBadge,
55
GroupPriorityDropdown,
6-
} from 'sentry/components/group/groupPriority';
6+
} from 'sentry/components/badge/groupPriority';
77
import SideBySide from 'sentry/components/stories/sideBySide';
88
import storyBook from 'sentry/stories/storyBook';
99
import {PriorityLevel} from 'sentry/types';

static/app/components/group/groupPriority.tsx renamed to static/app/components/badge/groupPriority.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import styled from '@emotion/styled';
55
import bannerStar from 'sentry-images/spot/banner-star.svg';
66

77
import {usePrompt} from 'sentry/actionCreators/prompts';
8+
import Tag from 'sentry/components/badge/tag';
89
import {Button, LinkButton} from 'sentry/components/button';
910
import {Chevron} from 'sentry/components/chevron';
1011
import type {MenuItemProps} from 'sentry/components/dropdownMenu';
@@ -13,7 +14,6 @@ import {DropdownMenuFooter} from 'sentry/components/dropdownMenu/footer';
1314
import useFeedbackWidget from 'sentry/components/feedback/widget/useFeedbackWidget';
1415
import HookOrDefault from 'sentry/components/hookOrDefault';
1516
import Placeholder from 'sentry/components/placeholder';
16-
import {Tag} from 'sentry/components/tag';
1717
import {Tooltip} from 'sentry/components/tooltip';
1818
import {IconClose} from 'sentry/icons';
1919
import {t, tct} from 'sentry/locale';

static/app/components/tag.spec.tsx renamed to static/app/components/badge/tag.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {RouterContextFixture} from 'sentry-fixture/routerContextFixture';
22

33
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
44

5-
import {Tag} from 'sentry/components/tag';
5+
import Tag from 'sentry/components/badge/tag';
66
import {IconFire} from 'sentry/icons';
77

88
describe('Tag', () => {

static/app/components/tag.stories.tsx renamed to static/app/components/badge/tag.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {Fragment, useState} from 'react';
22

3+
import Tag from 'sentry/components/badge/tag';
34
import {Button} from 'sentry/components/button';
45
import JSXNode from 'sentry/components/stories/jsxNode';
56
import JSXProperty from 'sentry/components/stories/jsxProperty';
67
import SizingWindow from 'sentry/components/stories/sizingWindow';
7-
import {Tag} from 'sentry/components/tag';
88
import {IconCheckmark, IconFire, IconSentry, IconStar} from 'sentry/icons';
99
import storyBook from 'sentry/stories/storyBook';
1010
import useDismissAlert from 'sentry/utils/useDismissAlert';

0 commit comments

Comments
 (0)