Skip to content

Commit 136b8b6

Browse files
authored
feat(feature-showcase): Redesign and rewrite FeatureTourModal as FeatureShowcase (#112532)
e need to use a multi-step modal to demo the new Monitors/Alerts product, and we do already have `FeatureTourModal` which does that and is used in a few hard-to-find places. However, that modal is a bit outdated design-wise and doesn't have the most flexible API (and is a class component). I decided to rewrite it, and to rename it `FeatureShowcase` (so that it will not be confused with the existing `Tour` compoent).
1 parent 6853983 commit 136b8b6

File tree

5 files changed

+609
-0
lines changed

5 files changed

+609
-0
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ tests/sentry/api/endpoints/test_organization_attribute_mappings.py @get
439439
/static/app/components/loading/ @getsentry/app-frontend
440440
/static/app/components/events/interfaces/ @getsentry/app-frontend
441441
/static/app/components/forms/ @getsentry/app-frontend
442+
/static/app/components/featureShowcase.mdx @getsentry/app-frontend
443+
/static/app/components/featureShowcase.spec.tsx @getsentry/app-frontend
444+
/static/app/components/featureShowcase.tsx @getsentry/app-frontend
442445
/static/app/components/markdownTextArea.tsx @getsentry/app-frontend
443446
/static/app/locale.tsx @getsentry/app-frontend
444447
## End of Frontend

knip.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const productionEntryPoints = [
2525
'static/app/components/pipeline/**/*.{js,ts,tsx}',
2626
// TODO: Remove when used
2727
'static/app/views/seerExplorer/contexts/**/*.{js,ts,tsx}',
28+
// TODO: Remove when used
29+
'static/app/components/featureShowcase.tsx',
2830
];
2931

3032
const testingEntryPoints = [
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
title: FeatureShowcase
3+
description: A multi-step modal tour for showcasing features.
4+
category: overlay
5+
source: sentry/components/featureShowcase
6+
---
7+
8+
import {Fragment} from 'react';
9+
10+
import tourAlertImage from 'sentry-images/spot/performance-tour-alert.svg';
11+
import tourCorrelateImage from 'sentry-images/spot/performance-tour-correlate.svg';
12+
import tourTraceImage from 'sentry-images/spot/performance-tour-trace.svg';
13+
14+
import {Button, LinkButton} from '@sentry/scraps/button';
15+
import {Flex} from '@sentry/scraps/layout';
16+
17+
import {openModal} from 'sentry/actionCreators/modal';
18+
import {FeatureShowcase, useShowcaseContext} from 'sentry/components/featureShowcase';
19+
import {GlobalModal} from 'sentry/components/globalModal';
20+
import * as Storybook from 'sentry/stories';
21+
22+
export function ReadTheDocsFooter() {
23+
const {close} = useShowcaseContext();
24+
return (
25+
<Flex justify="end">
26+
<LinkButton
27+
external
28+
href="https://docs.sentry.io"
29+
onClick={close}
30+
priority="primary"
31+
>
32+
Read the Docs
33+
</LinkButton>
34+
</Flex>
35+
);
36+
}
37+
38+
Render `<FeatureShowcase>` inside `openModal` with `<FeatureShowcase.Step>` children to create a multi-step modal tour.
39+
40+
```jsx
41+
openModal(deps => (
42+
<FeatureShowcase {...deps}>
43+
<FeatureShowcase.Step>
44+
<FeatureShowcase.Image src={image} alt="Step title" />
45+
<FeatureShowcase.StepTitle>Step title</FeatureShowcase.StepTitle>
46+
<FeatureShowcase.StepContent>Step description</FeatureShowcase.StepContent>
47+
<FeatureShowcase.StepActions />
48+
</FeatureShowcase.Step>
49+
</FeatureShowcase>
50+
));
51+
```
52+
53+
## Basic
54+
55+
Each step can include an image, title, content, and navigation actions. The default `<FeatureShowcase.StepActions />` renders Back/Next/Done buttons automatically.
56+
57+
<Storybook.Demo>
58+
<Fragment>
59+
<GlobalModal />
60+
<Button
61+
priority="primary"
62+
onClick={() => {
63+
openModal(deps => (
64+
<FeatureShowcase {...deps}>
65+
<FeatureShowcase.Step>
66+
<FeatureShowcase.Image src={tourTraceImage} alt="Trace Errors" />
67+
<FeatureShowcase.StepTitle>Trace Errors</FeatureShowcase.StepTitle>
68+
<FeatureShowcase.StepContent>
69+
Trace errors across your services to find the root cause.
70+
</FeatureShowcase.StepContent>
71+
<FeatureShowcase.StepActions />
72+
</FeatureShowcase.Step>
73+
<FeatureShowcase.Step>
74+
<FeatureShowcase.Image src={tourAlertImage} alt="Set Alerts" />
75+
<FeatureShowcase.StepTitle>Set Alerts</FeatureShowcase.StepTitle>
76+
<FeatureShowcase.StepContent>
77+
Get notified when things break before your users do.
78+
</FeatureShowcase.StepContent>
79+
<FeatureShowcase.StepActions />
80+
</FeatureShowcase.Step>
81+
<FeatureShowcase.Step>
82+
<FeatureShowcase.Image src={tourCorrelateImage} alt="Correlate Data" />
83+
<FeatureShowcase.StepTitle>Correlate Data</FeatureShowcase.StepTitle>
84+
<FeatureShowcase.StepContent>
85+
Correlate errors, transactions, and releases to find patterns.
86+
</FeatureShowcase.StepContent>
87+
<FeatureShowcase.StepActions />
88+
</FeatureShowcase.Step>
89+
</FeatureShowcase>
90+
));
91+
}}
92+
>
93+
Open Tour
94+
</Button>
95+
</Fragment>
96+
</Storybook.Demo>
97+
```jsx
98+
openModal(deps => (
99+
<FeatureShowcase {...deps}>
100+
<FeatureShowcase.Step>
101+
<FeatureShowcase.Image src={tourTraceImage} alt="Trace Errors" />
102+
<FeatureShowcase.StepTitle>Trace Errors</FeatureShowcase.StepTitle>
103+
<FeatureShowcase.StepContent>
104+
Trace errors across your services to find the root cause.
105+
</FeatureShowcase.StepContent>
106+
<FeatureShowcase.StepActions />
107+
</FeatureShowcase.Step>
108+
<FeatureShowcase.Step>
109+
<FeatureShowcase.Image src={tourAlertImage} alt="Set Alerts" />
110+
<FeatureShowcase.StepTitle>Set Alerts</FeatureShowcase.StepTitle>
111+
<FeatureShowcase.StepContent>
112+
Get notified when things break before your users do.
113+
</FeatureShowcase.StepContent>
114+
<FeatureShowcase.StepActions />
115+
</FeatureShowcase.Step>
116+
<FeatureShowcase.Step>
117+
<FeatureShowcase.Image src={tourCorrelateImage} alt="Correlate Data" />
118+
<FeatureShowcase.StepTitle>Correlate Data</FeatureShowcase.StepTitle>
119+
<FeatureShowcase.StepContent>
120+
Correlate errors, transactions, and releases to find patterns.
121+
</FeatureShowcase.StepContent>
122+
<FeatureShowcase.StepActions />
123+
</FeatureShowcase.Step>
124+
</FeatureShowcase>
125+
));
126+
```
127+
128+
## Custom Footer Buttons
129+
130+
Pass custom children alongside `<FeatureShowcase.StepActions />`, or replace it entirely with your own footer. Use `useShowcaseContext()` to access `close` and `advance` from custom components.
131+
132+
<Storybook.Demo>
133+
<Fragment>
134+
<GlobalModal />
135+
<Button
136+
priority="primary"
137+
onClick={() => {
138+
openModal(deps => (
139+
<FeatureShowcase {...deps}>
140+
<FeatureShowcase.Step>
141+
<FeatureShowcase.Image src={tourTraceImage} alt="Trace Errors" />
142+
<FeatureShowcase.StepTitle>Trace Errors</FeatureShowcase.StepTitle>
143+
<FeatureShowcase.StepContent>
144+
Trace errors across your services to find the root cause.
145+
</FeatureShowcase.StepContent>
146+
<FeatureShowcase.StepActions />
147+
</FeatureShowcase.Step>
148+
<FeatureShowcase.Step>
149+
<FeatureShowcase.Image src={tourCorrelateImage} alt="Correlate Data" />
150+
<FeatureShowcase.StepTitle>Correlate Data</FeatureShowcase.StepTitle>
151+
<FeatureShowcase.StepContent>
152+
Correlate errors, transactions, and releases to find patterns.
153+
</FeatureShowcase.StepContent>
154+
<ReadTheDocsFooter />
155+
</FeatureShowcase.Step>
156+
</FeatureShowcase>
157+
));
158+
}}
159+
>
160+
Open Tour
161+
</Button>
162+
</Fragment>
163+
</Storybook.Demo>
164+
```jsx
165+
function ReadTheDocsFooter() {
166+
const {close} = useShowcaseContext();
167+
return (
168+
<Flex justify="end">
169+
<LinkButton external href="https://docs.sentry.io" onClick={close} priority="primary">
170+
Read the Docs
171+
</LinkButton>
172+
</Flex>
173+
);
174+
}
175+
176+
openModal(deps => (
177+
178+
<FeatureShowcase {...deps}>
179+
<FeatureShowcase.Step>
180+
<FeatureShowcase.Image src={tourTraceImage} alt="Trace Errors" />
181+
<FeatureShowcase.StepTitle>Trace Errors</FeatureShowcase.StepTitle>
182+
<FeatureShowcase.StepContent>
183+
Trace errors across your services to find the root cause.
184+
</FeatureShowcase.StepContent>
185+
<FeatureShowcase.StepActions />
186+
</FeatureShowcase.Step>
187+
<FeatureShowcase.Step>
188+
<FeatureShowcase.Image src={tourCorrelateImage} alt="Correlate Data" />
189+
<FeatureShowcase.StepTitle>Correlate Data</FeatureShowcase.StepTitle>
190+
<FeatureShowcase.StepContent>
191+
Correlate errors, transactions, and releases to find patterns.
192+
</FeatureShowcase.StepContent>
193+
<ReadTheDocsFooter />
194+
</FeatureShowcase.Step>
195+
</FeatureShowcase>
196+
)); ```

0 commit comments

Comments
 (0)