Skip to content

Commit f6fc1c2

Browse files
committed
Increase customisability of storyies
1 parent 7c4e4ef commit f6fc1c2

File tree

3 files changed

+65
-21
lines changed

3 files changed

+65
-21
lines changed

docs/Alert.stories.tsx

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import type { Equals } from "tsafe";
88
const { meta, getStory } = getStoryFactory({
99
sectionName,
1010
"wrappedComponent": { Alert },
11+
"description": `
12+
- [See DSFR documentation](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/alerte)
13+
- [See source code](https://github.com/codegouvfr/react-dsfr/blob/main/src/Alert.tsx)`,
1114
"argTypes": {
1215
"severity": {
1316
"options": (() => {
@@ -19,19 +22,26 @@ const { meta, getStory } = getStoryFactory({
1922
})(),
2023
"control": { "type": "radio" }
2124
},
25+
"title": {
26+
"description": `Required when the \`<Alert isSmall={false} />\`
27+
(which is the default if \`isSmall\` isn't specified).
28+
`
29+
},
30+
"description": {
31+
"description": "Required when the `<Alert isSmall />`"
32+
},
2233
"isClosable": {
2334
"description": "If the modal should have a close button"
2435
},
2536
"onClose": {
2637
"description": "Called when the user clicks the close button"
2738
},
2839
"isClosed": {
29-
"description": [
30-
"If specified the `<Alert />` is in [controlled mode](https://reactjs.org/docs/forms.html#controlled-components)",
31-
"this means that when the close button is clicked",
32-
"the `onClose()` callback will be called but you are responsible",
33-
"for setting `isClosed` to `false`, the `<Alert />` wont close itself."
34-
].join(" "),
40+
"description": `If specified the \`<Alert />\` is in
41+
[controlled mode](https://reactjs.org/docs/forms.html#controlled-components)
42+
this means that when the close button is clicked
43+
the \`onClose()\` callback will be called but you are responsible
44+
for setting \`isClosed\` to \`false\`, the \`<Alert />\` wont close itself.`,
3545
"control": { "type": null }
3646
}
3747
}
@@ -41,16 +51,38 @@ export default meta;
4151

4252
export const Default = getStory({
4353
"severity": "success",
54+
"isSmall": false,
4455
"title": "Message successfully sent",
4556
"description": "Everything went well",
4657
"isClosable": true,
4758
"isClosed": undefined,
4859
...logCallbacks(["onClose"])
4960
});
5061

51-
export const Small = getStory({
52-
"severity": "info",
53-
"isSmall": true,
54-
"title": "Info: this is a small alert",
55-
"description": "This is the description"
62+
export const SmallDescriptionOnlyInfo = getStory(
63+
{
64+
"severity": "info",
65+
"isSmall": true,
66+
"description": "This is the description"
67+
},
68+
{
69+
"description": "Small info `Alert` with only a description"
70+
}
71+
);
72+
73+
export const TitleOnlyWarning = getStory(
74+
{
75+
"severity": "warning",
76+
"title": "This is the title"
77+
},
78+
{
79+
"description": "Warning `Alert` with only a title"
80+
}
81+
);
82+
83+
export const Error = getStory({
84+
"severity": "error",
85+
"title": "This is the title",
86+
"description": "This is the description",
87+
"isClosable": true
5688
});

docs/getStory.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@ startDsfrReact({ "defaultColorScheme": "system" });
1010

1111
export function getStoryFactory<Props extends Record<string, any>>(params: {
1212
sectionName: string;
13+
description?: string;
1314
wrappedComponent: Record<string, (props: Props) => JSX.Element | null>;
1415
/** https://storybook.js.org/docs/react/essentials/controls */
1516
argTypes?: Partial<Record<keyof Props, ArgType>>;
1617
defaultContainerWidth?: number;
1718
}) {
18-
const { sectionName, wrappedComponent, argTypes = {}, defaultContainerWidth } = params;
19+
const {
20+
sectionName,
21+
wrappedComponent,
22+
description,
23+
argTypes = {},
24+
defaultContainerWidth
25+
} = params;
1926

2027
const Component: any = Object.entries(wrappedComponent).map(([, component]) => component)[0];
2128

@@ -47,7 +54,9 @@ export function getStoryFactory<Props extends Record<string, any>>(params: {
4754

4855
let isFirstStory = true;
4956

50-
function getStory(props: Props): typeof Template {
57+
function getStory(props: Props, params?: { description?: string }): typeof Template {
58+
const { description } = params ?? {};
59+
5160
const out = Template.bind({});
5261

5362
out.args = {
@@ -60,9 +69,9 @@ export function getStoryFactory<Props extends Record<string, any>>(params: {
6069
isFirstStory = false;
6170

6271
out.parameters = {
63-
docs: {
64-
description: {
65-
story: "Some story **markdown**"
72+
"docs": {
73+
"description": {
74+
"story": description
6675
}
6776
}
6877
};
@@ -74,10 +83,10 @@ export function getStoryFactory<Props extends Record<string, any>>(params: {
7483
"meta": id<Meta>({
7584
"title": `${sectionName}/${symToStr(wrappedComponent)}`,
7685
"component": Component,
77-
parameters: {
78-
docs: {
79-
description: {
80-
component: "Some component _markdown_"
86+
"parameters": {
87+
"docs": {
88+
"description": {
89+
"component": description
8190
}
8291
}
8392
},

src/Alert.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ export const Alert = memo(
8888

8989
const [buttonElement, setButtonElement] = useState<HTMLButtonElement | null>(null);
9090

91-
const refShouldButtonGetFocus = useRef<boolean>(false);
91+
const refShouldButtonGetFocus = useRef(false);
92+
const refShouldSetRole = useRef(false);
9293

9394
useEffect(() => {
9495
if (props_isClosed === undefined) {
@@ -97,6 +98,7 @@ export const Alert = memo(
9798
setIsClosed(isClosed => {
9899
if (isClosed && !props_isClosed) {
99100
refShouldButtonGetFocus.current = true;
101+
refShouldSetRole.current = true;
100102
}
101103

102104
return props_isClosed;
@@ -142,6 +144,7 @@ export const Alert = memo(
142144
className
143145
)}
144146
ref={ref}
147+
{...(refShouldSetRole.current && { "role": "alert" })}
145148
{...rest}
146149
>
147150
<HtmlTitleTag className={cx(fr.cx("fr-alert__title"), classes.title)}>

0 commit comments

Comments
 (0)