Skip to content

Commit 7c18b3d

Browse files
author
MargeBot
committed
Merge branch 'MAILWEB-6593' into 'main'
MAILWEB-6593: Migrate Atom Button story to SB v8 with visual test See merge request web/clients!16797
2 parents 14986be + f45468f commit 7c18b3d

File tree

8 files changed

+163
-7
lines changed

8 files changed

+163
-7
lines changed

packages/atoms/Button/ButtonLike.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { ElementType, ForwardedRef } from 'react';
22
import { forwardRef } from 'react';
33

4+
import { ThemeColor } from '@proton/colors';
45
import type { ThemeColorUnion } from '@proton/colors';
56
import type { PolymorphicForwardRefExoticComponent, PolymorphicPropsWithRef } from '@proton/react-polymorphic-types';
67
import clsx from '@proton/utils/clsx';
@@ -9,9 +10,22 @@ import CircleLoader from '../CircleLoader/CircleLoader';
910

1011
import './ButtonLike.scss';
1112

12-
export type ButtonLikeShape = 'solid' | 'outline' | 'ghost' | 'underline';
13+
export enum ButtonLikeShapeEnum {
14+
Solid = 'solid',
15+
Outline = 'outline',
16+
Ghost = 'ghost',
17+
Underline = 'underline',
18+
}
19+
20+
export type ButtonLikeShape = `${ButtonLikeShapeEnum}`;
21+
22+
export enum ButtonLikeSizeEnum {
23+
Small = 'small',
24+
Medium = 'medium',
25+
Large = 'large',
26+
}
1327

14-
export type ButtonLikeSize = 'small' | 'medium' | 'large';
28+
export type ButtonLikeSize = `${ButtonLikeSizeEnum}`;
1529

1630
export interface ButtonLikeOwnProps {
1731
/**
@@ -82,8 +96,8 @@ const ButtonLikeBase = <E extends ElementType = typeof defaultElement>(
8296
tabIndex,
8397
children,
8498
shape: shapeProp,
85-
color = 'weak',
86-
size = 'medium',
99+
color = ThemeColor.Weak,
100+
size = ButtonLikeSizeEnum.Medium,
87101
fullWidth,
88102
pill,
89103
icon,
@@ -98,9 +112,9 @@ const ButtonLikeBase = <E extends ElementType = typeof defaultElement>(
98112
) => {
99113
const isDisabled = loading || disabled;
100114

101-
const shape = shapeProp || (color === 'weak' ? 'outline' : 'solid');
115+
const shape = shapeProp || (color === ThemeColor.Weak ? 'outline' : 'solid');
102116

103-
const isUnderlineShape = shape === 'underline';
117+
const isUnderlineShape = shape === ButtonLikeShapeEnum.Underline;
104118
const Element: ElementType = as || defaultElement;
105119

106120
const buttonClassName = clsx(

packages/atoms/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export type { AvatarProps } from './Avatar/Avatar';
33
export { default as Banner, BannerVariants } from './Banner/Banner';
44
export { Button } from './Button/Button';
55
export type { ButtonProps } from './Button/Button';
6-
export { default as ButtonLike } from './Button/ButtonLike';
6+
export { default as ButtonLike, ButtonLikeShapeEnum, ButtonLikeSizeEnum } from './Button/ButtonLike';
77
export type { ButtonLikeOwnProps, ButtonLikeProps, ButtonLikeShape, ButtonLikeSize } from './Button/ButtonLike';
88
export { default as Card, type CardProps } from './Card/Card';
99
export {
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import type { Meta, StoryObj } from '@storybook/react';
2+
3+
import { Button, ButtonLikeShapeEnum, ButtonLikeSizeEnum } from '@proton/atoms';
4+
import type { ButtonLikeOwnProps } from '@proton/atoms';
5+
import { ThemeColor } from '@proton/colors';
6+
7+
const meta: Meta<typeof Button> = {
8+
args: {
9+
color: ThemeColor.Norm,
10+
children: 'I am a button',
11+
'data-testid': '',
12+
disabled: false,
13+
fullWidth: false,
14+
group: false,
15+
icon: false,
16+
loading: false,
17+
noDisabledStyles: false,
18+
pill: false,
19+
selected: false,
20+
shape: ButtonLikeShapeEnum.Solid,
21+
size: ButtonLikeSizeEnum.Medium,
22+
},
23+
component: Button,
24+
parameters: {
25+
docs: {
26+
description: {
27+
component: 'Button component.',
28+
},
29+
},
30+
},
31+
tags: ['autodocs'],
32+
};
33+
34+
export default meta;
35+
36+
type Story = StoryObj<typeof Button>;
37+
38+
export const Default: Story = {};
39+
40+
// Colors
41+
const AllColorsSorted = Object.values(ThemeColor).sort();
42+
const AllColorsWithProps = (props: ButtonLikeOwnProps = {}) => (
43+
<>
44+
{AllColorsSorted.map((color: ThemeColor) => (
45+
<Button key={color} {...props} children={color} color={color} />
46+
))}
47+
</>
48+
);
49+
50+
export const AllColors: Story = {
51+
render: () => AllColorsWithProps(),
52+
};
53+
export const AllColorsDisabled: Story = {
54+
render: () => AllColorsWithProps({ disabled: true }),
55+
};
56+
export const AllColorsFullWidth: Story = {
57+
render: () => AllColorsWithProps({ fullWidth: true }),
58+
};
59+
export const AllColorsAsIcon: Story = {
60+
render: () => AllColorsWithProps({ icon: true }),
61+
};
62+
export const AllColorsLoading: Story = {
63+
render: () => AllColorsWithProps({ loading: true }),
64+
};
65+
export const AllColorsPill: Story = {
66+
render: () => AllColorsWithProps({ pill: true }),
67+
};
68+
69+
// Shapes
70+
const AllShapesSorted = Object.values(ButtonLikeShapeEnum).sort();
71+
const AllShapesWithProps = (props: ButtonLikeOwnProps = {}) => (
72+
<>
73+
{AllShapesSorted.map((shape: ButtonLikeShapeEnum) => (
74+
<Button key={shape} {...props} children={shape} color={ThemeColor.Norm} shape={shape} />
75+
))}
76+
</>
77+
);
78+
79+
export const AllShapes: Story = {
80+
render: () => AllShapesWithProps(),
81+
};
82+
export const AllShapesDisabled: Story = {
83+
render: () => AllShapesWithProps({ disabled: true }),
84+
};
85+
export const AllShapesFullWidth: Story = {
86+
render: () => AllShapesWithProps({ fullWidth: true }),
87+
};
88+
export const AllShapesAsIcon: Story = {
89+
render: () => AllShapesWithProps({ icon: true }),
90+
};
91+
export const AllShapesLoading: Story = {
92+
render: () => AllShapesWithProps({ loading: true }),
93+
};
94+
export const AllShapesPill: Story = {
95+
render: () => AllShapesWithProps({ pill: true }),
96+
};
97+
98+
// Sizes
99+
const AllSizesSorted = Object.values(ButtonLikeSizeEnum).sort();
100+
const AllSizesWithProps = (props: ButtonLikeOwnProps = {}) => (
101+
<>
102+
{AllSizesSorted.map((size: ButtonLikeSizeEnum) => (
103+
<Button key={size} {...props} children={size} color={ThemeColor.Norm} size={size} />
104+
))}
105+
</>
106+
);
107+
108+
export const AllSizes: Story = {
109+
render: () => AllSizesWithProps(),
110+
};
111+
export const AllSizesDisabled: Story = {
112+
render: () => AllSizesWithProps({ disabled: true }),
113+
};
114+
export const AllSizesFullWidth: Story = {
115+
render: () => AllSizesWithProps({ fullWidth: true }),
116+
};
117+
export const AllSizesAsIcon: Story = {
118+
render: () => AllSizesWithProps({ icon: true }),
119+
};
120+
export const AllSizesLoading: Story = {
121+
render: () => AllSizesWithProps({ loading: true }),
122+
};
123+
export const AllSizesPill: Story = {
124+
render: () => AllSizesWithProps({ pill: true }),
125+
};

packages/storybook/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
},
1818
"dependencies": {
1919
"@proton/atoms": "workspace:^",
20+
"@proton/colors": "workspace:^",
2021
"@proton/i18n": "workspace:^",
2122
"@proton/icons": "workspace:^",
2223
"@proton/pack": "workspace:^",

packages/storybook/tests/atoms-visual.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,24 @@ test.describe('visual tests', () => {
3333
test(testName, async ({ page }) => {
3434
await page.goto(`/iframe.html?viewMode=docs&id=${id}`);
3535

36+
await page.waitForLoadState('domcontentloaded');
37+
3638
await expect(page).toHaveScreenshot({
39+
animations: 'disabled',
3740
fullPage: true,
3841
});
3942
});
4043
}
44+
45+
// TODO: remove this once done with the migration (it's used to take screenshots of the old stories)
46+
// const id = 'components-NAME--basic';
47+
// test(id.replaceAll('-', '_'), async ({ page }) => {
48+
// await page.goto(`http://localhost:6006/iframe.html?viewMode=docs&id=${id}`);
49+
50+
// await page.waitForLoadState('domcontentloaded');
51+
52+
// await expect(page).toHaveScreenshot({
53+
// fullPage: true,
54+
// });
55+
// });
4156
});
331 KB
Loading
346 KB
Loading

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8291,6 +8291,7 @@ __metadata:
82918291
"@babel/preset-typescript": "npm:^7.27.0"
82928292
"@playwright/test": "npm:^1.52.0"
82938293
"@proton/atoms": "workspace:^"
8294+
"@proton/colors": "workspace:^"
82948295
"@proton/i18n": "workspace:^"
82958296
"@proton/icons": "workspace:^"
82968297
"@proton/pack": "workspace:^"

0 commit comments

Comments
 (0)