Skip to content

Commit bdbf933

Browse files
committed
adds ReviewCard
1 parent 6a076f5 commit bdbf933

File tree

14 files changed

+391
-6
lines changed

14 files changed

+391
-6
lines changed

packages/delete-wizard/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,14 @@
3333
"@leafygreen-ui/form-footer": "workspace:^",
3434
"@leafygreen-ui/icon": "workspace:^",
3535
"@leafygreen-ui/lib": "workspace:^",
36+
"@leafygreen-ui/loading-indicator": "workspace:^",
3637
"@leafygreen-ui/tokens": "workspace:^",
3738
"@leafygreen-ui/wizard": "workspace:^",
3839
"@lg-tools/test-harnesses": "workspace:^"
3940
},
41+
"peerDependencies": {
42+
"@leafygreen-ui/leafygreen-provider": "workspace:^5.0.0 || ^4.0.0 || ^3.2.0"
43+
},
4044
"homepage": "https://github.com/mongodb/leafygreen-ui/tree/main/packages/delete-wizard",
4145
"repository": {
4246
"type": "git",

packages/delete-wizard/src/RecommendationCard/RecommendationCard.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Link } from '@leafygreen-ui/typography';
66
import { RecommendationCard } from './RecommendationCard';
77

88
export default {
9-
title: 'Templates/DeleteWizard/RecommendedActionCard',
9+
title: 'Templates/DeleteWizard/RecommendationCard',
1010
component: RecommendationCard,
1111
args: {
1212
category: 'Things',
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import React from 'react';
2+
import { faker } from '@faker-js/faker';
3+
import { StoryMetaType } from '@lg-tools/storybook-utils';
4+
import { StoryObj } from '@storybook/react';
5+
6+
import { css } from '@leafygreen-ui/emotion';
7+
8+
import { defaultLoadingDescription } from './constants';
9+
import { ReviewCard } from './ReviewCard';
10+
import { ReviewState } from './ReviewCard.types';
11+
import { ReviewCardTitleWithCountEmphasis } from './utils';
12+
13+
faker.seed(0);
14+
15+
export default {
16+
title: 'Templates/DeleteWizard/ReviewCard',
17+
component: ReviewCard,
18+
parameters: {
19+
default: 'LiveExample',
20+
},
21+
argTypes: {
22+
title: {
23+
control: 'text',
24+
},
25+
loadingTitle: {
26+
control: 'text',
27+
},
28+
state: {
29+
control: 'select',
30+
options: Object.values(ReviewState),
31+
},
32+
},
33+
args: {
34+
state: ReviewState.Review,
35+
title: (
36+
<ReviewCardTitleWithCountEmphasis
37+
verb="Terminate"
38+
count={6}
39+
resource="clusters"
40+
/>
41+
),
42+
description: 'Completing this action will terminate all clusters',
43+
errorTitle: 'Error loading clusters',
44+
errorDescription: 'Could not fetch clusters. Please try again later',
45+
loadingTitle: 'Loading cluster data',
46+
loadingDescription: defaultLoadingDescription,
47+
completedTitle: 'No clusters detected',
48+
completedDescription: 'Required action complete',
49+
children: faker.lorem.paragraphs(4),
50+
},
51+
} satisfies StoryMetaType<typeof ReviewCard>;
52+
53+
export const LiveExample: StoryObj<typeof ReviewCard> = {
54+
render: ({ children, ...args }) => (
55+
<ReviewCard {...args}>
56+
<div
57+
className={css`
58+
padding: 16px 24px;
59+
`}
60+
>
61+
{children}
62+
</div>
63+
</ReviewCard>
64+
),
65+
};
66+
67+
export const Review: StoryObj<typeof ReviewCard> = {
68+
parameters: {
69+
controls: {
70+
exclude: [
71+
'state',
72+
'errorTitle',
73+
'errorDescription',
74+
'loadingTitle',
75+
'loadingDescription',
76+
'completedTitle',
77+
'completedDescription',
78+
],
79+
},
80+
},
81+
args: {
82+
state: ReviewState.Review,
83+
},
84+
render: LiveExample.render,
85+
};
86+
87+
export const Loading: StoryObj<typeof ReviewCard> = {
88+
parameters: {
89+
controls: {
90+
exclude: [
91+
'state',
92+
'title',
93+
'description',
94+
'errorTitle',
95+
'errorDescription',
96+
'completedTitle',
97+
'completedDescription',
98+
],
99+
},
100+
},
101+
args: {
102+
state: ReviewState.Loading,
103+
},
104+
render: LiveExample.render,
105+
};
106+
107+
export const Complete: StoryObj<typeof ReviewCard> = {
108+
parameters: {
109+
controls: {
110+
exclude: [
111+
'state',
112+
'title',
113+
'description',
114+
'errorTitle',
115+
'errorDescription',
116+
'loadingTitle',
117+
'loadingDescription',
118+
],
119+
},
120+
},
121+
args: {
122+
state: ReviewState.Complete,
123+
},
124+
render: LiveExample.render,
125+
};
126+
127+
export const Error: StoryObj<typeof ReviewCard> = {
128+
parameters: {
129+
controls: {
130+
exclude: [
131+
'state',
132+
'title',
133+
'description',
134+
'completedTitle',
135+
'completedDescription',
136+
'loadingTitle',
137+
'loadingDescription',
138+
],
139+
},
140+
},
141+
args: {
142+
state: ReviewState.Error,
143+
},
144+
render: LiveExample.render,
145+
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { css } from '@leafygreen-ui/emotion';
2+
import { spacing } from '@leafygreen-ui/tokens';
3+
4+
export const reviewCardStyles = css`
5+
& h6 {
6+
display: block;
7+
}
8+
`;
9+
10+
export const expandableCardContentStyles = css`
11+
padding: unset;
12+
`;
13+
14+
export const cardContentWrapperStyles = css`
15+
padding-bottom: ${spacing[400]}px;
16+
overflow: hidden;
17+
`;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import React from 'react';
2+
3+
import { ExpandableCard } from '@leafygreen-ui/expandable-card';
4+
5+
import {
6+
defaultCompleteDescription,
7+
defaultCompleteTitle,
8+
defaultErrorDescription,
9+
defaultErrorTitle,
10+
defaultLoadingDescription,
11+
defaultLoadingTitle,
12+
} from './constants';
13+
import {
14+
cardContentWrapperStyles,
15+
expandableCardContentStyles,
16+
reviewCardStyles,
17+
} from './ReviewCard.styles';
18+
import { type ReviewCardProps, ReviewState } from './ReviewCard.types';
19+
import { ReviewCardDescription, ReviewCardTitleElement } from './utils';
20+
21+
export const ReviewCard = ({
22+
state,
23+
title,
24+
description,
25+
errorTitle = defaultErrorTitle,
26+
errorDescription = defaultErrorDescription,
27+
loadingTitle = defaultLoadingTitle,
28+
loadingDescription = defaultLoadingDescription,
29+
completedTitle = defaultCompleteTitle,
30+
completedDescription = defaultCompleteDescription,
31+
children,
32+
...rest
33+
}: ReviewCardProps) => {
34+
return (
35+
<ExpandableCard
36+
title={
37+
<ReviewCardTitleElement
38+
state={state}
39+
title={title}
40+
completedTitle={completedTitle}
41+
loadingTitle={loadingTitle}
42+
errorTitle={errorTitle}
43+
/>
44+
}
45+
description={
46+
<ReviewCardDescription
47+
state={state}
48+
description={description}
49+
completedDescription={completedDescription}
50+
loadingDescription={loadingDescription}
51+
errorDescription={errorDescription}
52+
/>
53+
}
54+
className={reviewCardStyles}
55+
contentClassName={expandableCardContentStyles}
56+
defaultOpen={false}
57+
{...rest}
58+
>
59+
{state === ReviewState.Review && (
60+
<div className={cardContentWrapperStyles}>{children}</div>
61+
)}
62+
</ExpandableCard>
63+
);
64+
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { ReactNode } from 'react';
2+
3+
import type { ExpandableCardProps } from '@leafygreen-ui/expandable-card';
4+
5+
export enum ReviewState {
6+
Loading = 'loading',
7+
Review = 'review',
8+
Error = 'error',
9+
Complete = 'complete',
10+
}
11+
export interface ReviewCardProps extends ExpandableCardProps {
12+
/**
13+
* @required
14+
* Determines which title and description are rendered
15+
*/
16+
state: ReviewState;
17+
18+
/**
19+
* Title displayed when state === 'error'
20+
* @default 'Error loading data'
21+
*/
22+
errorTitle?: ReactNode;
23+
24+
/**
25+
* Description displayed when state === 'error'
26+
* @default 'Could not retrieve data'
27+
*/
28+
errorDescription?: ReactNode;
29+
30+
/**
31+
* Title displayed when state === 'loading'
32+
* @default Skeleton loader
33+
*/
34+
loadingTitle?: ReactNode;
35+
36+
/**
37+
* Description displayed when state === 'loading'
38+
* @default 'This may take a few moments'
39+
*/
40+
loadingDescription?: string;
41+
42+
/**
43+
* Title displayed when state === 'complete'
44+
* @default 'None detected'
45+
*/
46+
completedTitle?: ReactNode;
47+
/**
48+
* Description displaced when state === 'complete'
49+
* @default 'Review complete'
50+
*/
51+
completedDescription?: ReactNode;
52+
}
53+
export interface InheritedReviewCardProps
54+
extends Omit<ExpandableCardProps, 'title' | 'description'> {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from 'react';
2+
3+
import { css } from '@leafygreen-ui/emotion';
4+
import { Skeleton } from '@leafygreen-ui/skeleton-loader';
5+
6+
export const defaultErrorTitle = 'Error loading data';
7+
export const defaultErrorDescription = 'Could not retrieve data';
8+
export const defaultLoadingTitle = (
9+
<Skeleton
10+
size="small"
11+
className={css`
12+
width: 50%;
13+
`}
14+
/>
15+
);
16+
export const defaultLoadingDescription = 'This may take a few moments';
17+
export const defaultCompleteTitle = 'None detected';
18+
export const defaultCompleteDescription = 'Required action complete';
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export { ReviewCard } from './ReviewCard';
2+
export { type ReviewCardProps } from './ReviewCard.types';
3+
export { ReviewState } from './ReviewCard.types';
4+
export { ReviewCardTitleWithCountEmphasis } from './utils';

packages/delete-wizard/src/ReviewCard/utils/ReviewCardDescription.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,14 @@ export const ReviewCardDescription = ({
4444
);
4545
case ReviewState.Loading:
4646
return (
47-
<Spinner
48-
size={Size.XSmall}
49-
direction={'horizontal'}
50-
description={loadingDescription}
51-
/>
47+
<>
48+
<Spinner
49+
size={Size.Small}
50+
// direction={'horizontal'}
51+
// description={loadingDescription}
52+
/>
53+
{loadingDescription}
54+
</>
5255
);
5356
case ReviewState.Complete:
5457
return (
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { ReactNode } from 'react';
2+
3+
import { type ReviewCardProps, ReviewState } from '../ReviewCard.types';
4+
5+
export const ReviewCardTitleElement = ({
6+
state,
7+
title,
8+
errorTitle,
9+
loadingTitle,
10+
completedTitle,
11+
}: Pick<
12+
ReviewCardProps,
13+
'state' | 'title' | 'completedTitle' | 'loadingTitle' | 'errorTitle'
14+
>): ReactNode => {
15+
switch (state) {
16+
case ReviewState.Error:
17+
return errorTitle;
18+
case ReviewState.Loading:
19+
return loadingTitle;
20+
case ReviewState.Complete:
21+
return completedTitle;
22+
case ReviewState.Review:
23+
default:
24+
return title;
25+
}
26+
};

0 commit comments

Comments
 (0)