♻️(react) migrate to Storybook 7

This new release comes with breaking changes for stories and mdx docs.
This commit is contained in:
Nathan Vasse
2023-05-12 16:03:16 +02:00
committed by NathanVss
parent e7fc782b1c
commit 77721c3b6d
24 changed files with 2639 additions and 4187 deletions

View File

@@ -1,34 +0,0 @@
const viteTsconfig = require('vite-tsconfig-paths');
const tsconfigPaths = viteTsconfig.default;
const { mergeConfig } = require('vite');
module.exports = {
'stories': [
'../src/**/*.stories.mdx',
'../src/**/*.stories.@(js|jsx|ts|tsx)',
],
'addons': [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-a11y',
'@storybook/preset-scss'
],
'framework': '@storybook/react',
'core': {
'builder': '@storybook/builder-vite',
},
staticDirs: [
'../src',
],
'features': {
'storyStoreV7': true,
},
async viteFinal(config) {
const finalConfig = mergeConfig(config, {
plugins: [tsconfigPaths()],
});
finalConfig.base = 'https://openfun.github.io/cunningham';
return finalConfig;
},
};

View File

@@ -0,0 +1,33 @@
import { StorybookConfig } from "@storybook/react-vite";
import remarkGfm from "remark-gfm";
const config: StorybookConfig = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-a11y",
"@storybook/preset-scss",
{
name: "@storybook/addon-docs",
options: {
mdxPluginOptions: {
mdxCompileOptions: {
remarkPlugins: [remarkGfm],
},
},
},
},
],
framework: {
name: "@storybook/react-vite",
options: {},
},
staticDirs: ["../src"],
features: {
storyStoreV7: true,
},
};
export default config;

View File

@@ -34,7 +34,7 @@
"test": "FORCE_COLOR=1 vitest run", "test": "FORCE_COLOR=1 vitest run",
"test-watch": "vitest", "test-watch": "vitest",
"coverage": "vitest run --coverage", "coverage": "vitest run --coverage",
"storybook": "start-storybook -p 6006", "storybook": "storybook dev -p 6006",
"deploy-storybook": "storybook-to-ghpages" "deploy-storybook": "storybook-to-ghpages"
}, },
"dependencies": { "dependencies": {
@@ -58,14 +58,14 @@
"@faker-js/faker": "8.0.0", "@faker-js/faker": "8.0.0",
"@openfun/cunningham-tokens": "*", "@openfun/cunningham-tokens": "*",
"@openfun/typescript-configs": "*", "@openfun/typescript-configs": "*",
"@storybook/addon-a11y": "7.0.10", "@storybook/addon-a11y": "7.0.11",
"@storybook/addon-actions": "7.0.10", "@storybook/addon-actions": "7.0.11",
"@storybook/addon-essentials": "7.0.10", "@storybook/addon-essentials": "7.0.11",
"@storybook/addon-interactions": "7.0.10", "@storybook/addon-interactions": "7.0.11",
"@storybook/addon-links": "7.0.10", "@storybook/addon-links": "7.0.11",
"@storybook/builder-vite": "0.3.0",
"@storybook/preset-scss": "1.0.3", "@storybook/preset-scss": "1.0.3",
"@storybook/react": "7.0.11", "@storybook/react": "7.0.11",
"@storybook/react-vite": "7.0.11",
"@storybook/storybook-deployer": "2.8.16", "@storybook/storybook-deployer": "2.8.16",
"@storybook/testing-library": "0.1.0", "@storybook/testing-library": "0.1.0",
"@testing-library/dom": "9.2.0", "@testing-library/dom": "9.2.0",
@@ -82,8 +82,10 @@
"css-loader": "6.7.3", "css-loader": "6.7.3",
"glob": "10.2.3", "glob": "10.2.3",
"jsdom": "22.0.0", "jsdom": "22.0.0",
"remark-gfm": "3.0.1",
"sass": "1.62.1", "sass": "1.62.1",
"sass-loader": "13.2.2", "sass-loader": "13.2.2",
"storybook": "7.0.11",
"style-loader": "3.3.2", "style-loader": "3.3.2",
"typescript": "5.0.4", "typescript": "5.0.4",
"vite": "4.3.5", "vite": "4.3.5",

View File

@@ -29,17 +29,17 @@ You can use icons within the button by passing the icon name as a prop.
> Use the attribute `iconPosition` to position the icon on the left or right side of the button. The default is `left`. > Use the attribute `iconPosition` to position the icon on the left or right side of the button. The default is `left`.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-button--icon-left"/> <Story id="components-button--icon-left"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-button--icon-right"/> <Story id="components-button--icon-right"/>
</Canvas> </Canvas>
You can also use button with only an icon. You can also use button with only an icon.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-button--icon-only"/> <Story id="components-button--icon-only"/>
</Canvas> </Canvas>
@@ -49,7 +49,7 @@ The button can be disabled. The disabled button will render the same no matter w
> Keep in the mind that a disabled button will never call `onClick` if it is provided. > Keep in the mind that a disabled button will never call `onClick` if it is provided.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-button--disabled"/> <Story id="components-button--disabled"/>
</Canvas> </Canvas>

View File

@@ -1,4 +1,4 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta } from "@storybook/react";
import React from "react"; import React from "react";
import { Button } from "./index"; import { Button } from "./index";
@@ -10,111 +10,118 @@ export default {
control: "boolean", control: "boolean",
}, },
}, },
} as ComponentMeta<typeof Button>; } as Meta<typeof Button>;
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />; export const Primary = {
args: {
export const Primary = Template.bind({}); children: "Primary",
Primary.args = { color: "primary",
children: "Primary", },
color: "primary",
}; };
export const Secondary = Template.bind({}); export const Secondary = {
Secondary.args = { args: {
children: "Secondary", children: "Secondary",
color: "secondary", color: "secondary",
},
}; };
export const Tertiary = Template.bind({}); export const Tertiary = {
Tertiary.args = { args: {
children: "Tertiary", children: "Tertiary",
color: "tertiary", color: "tertiary",
},
}; };
export const Disabled = Template.bind({}); export const Disabled = {
Disabled.args = { args: {
children: "Disabled", children: "Disabled",
color: "primary", color: "primary",
disabled: true, disabled: true,
},
}; };
export const Danger = Template.bind({}); export const Danger = {
Danger.args = { args: {
children: "Danger", children: "Danger",
color: "danger", color: "danger",
},
}; };
export const Small = Template.bind({}); export const Small = {
Small.args = { args: {
children: "Primary", children: "Primary",
color: "primary", color: "primary",
size: "small", size: "small",
},
}; };
export const IconLeft = Template.bind({}); export const IconLeft = {
IconLeft.args = { args: {
children: "Icon", children: "Icon",
icon: ( icon: (
<svg <svg
width="24" width="24"
height="24" height="24"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
fill="currentColor" fill="currentColor"
fillRule="evenodd" fillRule="evenodd"
clipRule="evenodd" clipRule="evenodd"
d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z" d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z"
/> />
</svg> </svg>
), ),
color: "primary", color: "primary",
},
}; };
export const IconRight = Template.bind({}); export const IconRight = {
IconRight.args = { args: {
children: "Icon", children: "Icon",
iconPosition: "right", iconPosition: "right",
icon: ( icon: (
<svg <svg
width="24" width="24"
height="24" height="24"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
fill="currentColor" fill="currentColor"
fillRule="evenodd" fillRule="evenodd"
clipRule="evenodd" clipRule="evenodd"
d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z" d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z"
/> />
</svg> </svg>
), ),
color: "primary", color: "primary",
},
}; };
export const IconOnly = Template.bind({}); export const IconOnly = {
IconOnly.args = { args: {
"aria-label": "Button with only an icon", "aria-label": "Button with only an icon",
icon: ( icon: (
<svg <svg
width="24" width="24"
height="24" height="24"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
fill="currentColor" fill="currentColor"
fillRule="evenodd" fillRule="evenodd"
clipRule="evenodd" clipRule="evenodd"
d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z" d="M17.8724 10.0166H13.248L16.6251 4.07749C16.9258 3.54846 16.2447 3.01176 15.8005 3.42755L6.57343 12.0655C6.22192 12.3946 6.45489 12.9838 6.93615 12.9838H11.5606L8.18353 18.9229C7.88275 19.4519 8.56335 19.9886 9.00746 19.5728L18.2352 10.9349C18.5867 10.6058 18.3537 10.0166 17.8724 10.0166Z"
/> />
</svg> </svg>
), ),
color: "primary", color: "primary",
},
}; };

View File

@@ -40,7 +40,7 @@ This component is a wrapper around the more complicated DataGrid component. It i
Here a quick usage example Here a quick usage example
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-datagrid--data-list-only"/> <Story id="components-datagrid--data-list-only"/>
</Canvas> </Canvas>
@@ -63,7 +63,7 @@ Sorting etc ...
Take a look at the following example that renders a table of users. Take a look at the following example that renders a table of users.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-datagrid--client-side-without-pagination"/> <Story id="components-datagrid--client-side-without-pagination"/>
</Canvas> </Canvas>
@@ -74,7 +74,7 @@ with `enableRowSelection`, `rowSelection` and `onRowSelectionChange` props.
> Please click on checkboxes to select rows to see hows the `onRowSelectionChange` prop works, selected ids are displayed > Please click on checkboxes to select rows to see hows the `onRowSelectionChange` prop works, selected ids are displayed
below the table. below the table.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-datagrid--client-side-with-pagination"/> <Story id="components-datagrid--client-side-with-pagination"/>
</Canvas> </Canvas>
@@ -94,7 +94,7 @@ pagination, sorting etc ...
Please take a look at the following example that simulates a server side data that's re-fetched on each page and sorting Please take a look at the following example that simulates a server side data that's re-fetched on each page and sorting
change. change.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-datagrid--full-server-side"/> <Story id="components-datagrid--full-server-side"/>
</Canvas> </Canvas>
@@ -152,7 +152,7 @@ outside the grid component ( for example to delete selected rows ).
The component provides out of the box a loading state that can be enabled by setting the `isLoading` props to `true`. The component provides out of the box a loading state that can be enabled by setting the `isLoading` props to `true`.
So feel free to use it between page or sorting changes when you are fetching data from a server. So feel free to use it between page or sorting changes when you are fetching data from a server.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-datagrid--loading"/> <Story id="components-datagrid--loading"/>
</Canvas> </Canvas>
@@ -160,7 +160,7 @@ So feel free to use it between page or sorting changes when you are fetching dat
The component automatically displays an empty state when there is no data to display and it is not loading. The component automatically displays an empty state when there is no data to display and it is not loading.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-datagrid--empty"/> <Story id="components-datagrid--empty"/>
</Canvas> </Canvas>

View File

@@ -1,4 +1,4 @@
import { ComponentMeta } from "@storybook/react"; import { Meta } from "@storybook/react";
import React, { useEffect, useMemo, useState } from "react"; import React, { useEffect, useMemo, useState } from "react";
import { faker } from "@faker-js/faker"; import { faker } from "@faker-js/faker";
import { DataGrid, SortModel } from ":/components/DataGrid/index"; import { DataGrid, SortModel } from ":/components/DataGrid/index";
@@ -11,7 +11,7 @@ import { DataList } from ":/components/DataGrid/DataList";
export default { export default {
title: "Components/DataGrid", title: "Components/DataGrid",
component: DataGrid, component: DataGrid,
} as ComponentMeta<typeof DataGrid>; } as Meta<typeof DataGrid>;
export const Empty = () => { export const Empty = () => {
return ( return (

View File

@@ -17,13 +17,13 @@ The `label` props is optional, but you can use it to provide a description of th
**Without label** **Without label**
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--default"/> <Story id="components-forms-checkbox--default"/>
</Canvas> </Canvas>
**With label** **With label**
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--with-label"/> <Story id="components-forms-checkbox--with-label"/>
</Canvas> </Canvas>
@@ -31,7 +31,7 @@ The `label` props is optional, but you can use it to provide a description of th
You can set the value of the checkbox in 3 different ways. You can set the value of the checkbox in 3 different ways.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--default"/> <Story id="components-forms-checkbox--default"/>
<Story id="components-forms-checkbox--indeterminate"/> <Story id="components-forms-checkbox--indeterminate"/>
<Story id="components-forms-checkbox--checked"/> <Story id="components-forms-checkbox--checked"/>
@@ -41,7 +41,7 @@ You can set the value of the checkbox in 3 different ways.
As the component uses [Field](?path=/story/components-forms-field-doc--page), you can use the `text` props to provide a description of the checkbox. As the component uses [Field](?path=/story/components-forms-field-doc--page), you can use the `text` props to provide a description of the checkbox.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--with-texts"/> <Story id="components-forms-checkbox--with-texts"/>
</Canvas> </Canvas>
@@ -49,7 +49,7 @@ As the component uses [Field](?path=/story/components-forms-field-doc--page), yo
As a regular checkbox, you can disable it by using the `disabled` props. As a regular checkbox, you can disable it by using the `disabled` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--disabled"/> <Story id="components-forms-checkbox--disabled"/>
</Canvas> </Canvas>
@@ -57,15 +57,15 @@ As a regular checkbox, you can disable it by using the `disabled` props.
You can use the following props to change the state of the Input component by using the `state` props. You can use the following props to change the state of the Input component by using the `state` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--with-texts"/> <Story id="components-forms-checkbox--with-texts"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--success"/> <Story id="components-forms-checkbox--success"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--error"/> <Story id="components-forms-checkbox--error"/>
</Canvas> </Canvas>
@@ -73,13 +73,13 @@ You can use the following props to change the state of the Input component by us
It will happen often that you will need to use multiple grouped checkboxes. You can use the `CheckboxGroup` component to do so. It will happen often that you will need to use multiple grouped checkboxes. You can use the `CheckboxGroup` component to do so.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--group"/> <Story id="components-forms-checkbox--group"/>
</Canvas> </Canvas>
You can also define `state`, `text` props on the group component You can also define `state`, `text` props on the group component
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-checkbox--group-error"/> <Story id="components-forms-checkbox--group-error"/>
<Story id="components-forms-checkbox--group-success"/> <Story id="components-forms-checkbox--group-success"/>
</Canvas> </Canvas>

View File

@@ -1,74 +1,103 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta, StoryFn } from "@storybook/react";
import React from "react"; import React from "react";
import { Checkbox, CheckboxGroup } from ":/components/Forms/Checkbox/index"; import { Checkbox, CheckboxGroup } from ":/components/Forms/Checkbox/index";
export default { export default {
title: "Components/Forms/Checkbox", title: "Components/Forms/Checkbox",
component: Checkbox, component: Checkbox,
} as ComponentMeta<typeof Checkbox>; } as Meta<typeof Checkbox>;
const Template: ComponentStory<typeof Checkbox> = (args) => ( const Template: StoryFn<typeof Checkbox> = (args) => (
<Checkbox {...args} aria-label="Checkbox" /> <Checkbox {...args} aria-label="Checkbox" />
); );
export const Default = Template.bind({}); export const Default = {
Default.args = {}; render: Template,
args: {},
export const Checked = Template.bind({});
Checked.args = {
checked: true,
}; };
export const Indeterminate = Template.bind({}); export const Checked = {
Indeterminate.args = { render: Template,
indeterminate: true,
args: {
checked: true,
},
}; };
export const WithLabel = Template.bind({}); export const Indeterminate = {
WithLabel.args = { render: Template,
label: "Label",
args: {
indeterminate: true,
},
}; };
export const LabelChecked = Template.bind({}); export const WithLabel = {
LabelChecked.args = { render: Template,
checked: true,
label: "Label", args: {
label: "Label",
},
}; };
export const WithTexts = Template.bind({}); export const LabelChecked = {
WithTexts.args = { render: Template,
checked: true,
label: "Label", args: {
text: "This is an optional text", checked: true,
label: "Label",
},
}; };
export const Disabled = Template.bind({}); export const WithTexts = {
Disabled.args = { render: Template,
disabled: true,
label: "Label", args: {
checked: true,
label: "Label",
text: "This is an optional text",
},
}; };
export const DisabledChecked = Template.bind({}); export const Disabled = {
DisabledChecked.args = { render: Template,
checked: true,
disabled: true, args: {
label: "Label", disabled: true,
label: "Label",
},
}; };
export const Error = Template.bind({}); export const DisabledChecked = {
Error.args = { render: Template,
checked: true,
label: "Label", args: {
text: "This is an optional text", checked: true,
state: "error", disabled: true,
label: "Label",
},
}; };
export const Success = Template.bind({}); export const Error = {
Success.args = { render: Template,
checked: true,
label: "Label", args: {
text: "This is an optional text", checked: true,
state: "success", label: "Label",
text: "This is an optional text",
state: "error",
},
};
export const Success = {
render: Template,
args: {
checked: true,
label: "Label",
text: "This is an optional text",
state: "success",
},
}; };
export const Group = () => ( export const Group = () => (

View File

@@ -1,34 +1,43 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta, StoryFn } from "@storybook/react";
import React from "react"; import React from "react";
import { Field } from ":/components/Forms/Field/index"; import { Field } from ":/components/Forms/Field/index";
export default { export default {
title: "Components/Forms/Field", title: "Components/Forms/Field",
component: Field, component: Field,
} as ComponentMeta<typeof Field>; } as Meta<typeof Field>;
const Template: ComponentStory<typeof Field> = (args) => ( const Template: StoryFn<typeof Field> = (args) => (
<Field {...args}> <Field {...args}>
<strong>Any children</strong> <strong>Any children</strong>
</Field> </Field>
); );
export const Default = Template.bind({}); export const Default = {
Default.args = { render: Template,
text: "This is an optional text",
rightText: "Right text", args: {
text: "This is an optional text",
rightText: "Right text",
},
}; };
export const Success = Template.bind({}); export const Success = {
Success.args = { render: Template,
state: "success",
text: "This is an optional success message", args: {
rightText: "Right text", state: "success",
text: "This is an optional success message",
rightText: "Right text",
},
}; };
export const Error = Template.bind({}); export const Error = {
Error.args = { render: Template,
state: "error",
text: "This is an optional error message", args: {
rightText: "Right text", state: "error",
text: "This is an optional error message",
rightText: "Right text",
},
}; };

View File

@@ -24,15 +24,15 @@ Cunningham provides a versatile Input component that you can use in your forms.
You can use the following props to change the state of the Input component by using the `state` props. You can use the following props to change the state of the Input component by using the `state` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--default"/> <Story id="components-forms-input--default"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--success"/> <Story id="components-forms-input--success"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--error"/> <Story id="components-forms-input--error"/>
</Canvas> </Canvas>
@@ -40,7 +40,7 @@ You can use the following props to change the state of the Input component by us
As a regular input, you can disable it by using the `disabled` props. As a regular input, you can disable it by using the `disabled` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--disabled-empty"/> <Story id="components-forms-input--disabled-empty"/>
<Story id="components-forms-input--disabled-filled"/> <Story id="components-forms-input--disabled-filled"/>
</Canvas> </Canvas>
@@ -49,13 +49,13 @@ As a regular input, you can disable it by using the `disabled` props.
You can define an icon that will appear on the left side of the input by using the `icon` props. You can define an icon that will appear on the left side of the input by using the `icon` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--icon"/> <Story id="components-forms-input--icon"/>
</Canvas> </Canvas>
You can also independently add an icon on the right side by using the `rightIcon` props. You can also independently add an icon on the right side by using the `rightIcon` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--icon-right"/> <Story id="components-forms-input--icon-right"/>
</Canvas> </Canvas>
@@ -63,13 +63,13 @@ You can also independently add an icon on the right side by using the `rightIcon
You can define a text that will appear below the input by using the `text` props. You can define a text that will appear below the input by using the `text` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--with-text"/> <Story id="components-forms-input--with-text"/>
</Canvas> </Canvas>
You can also independently add a text on the right side by using the `rightText` props. You can also independently add a text on the right side by using the `rightText` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--with-both-texts"/> <Story id="components-forms-input--with-both-texts"/>
</Canvas> </Canvas>
@@ -77,7 +77,7 @@ You can also independently add a text on the right side by using the `rightText`
By default, the input has a default width, like all inputs. But you can force it to take the full width of its container by using the `fullWidth` props. By default, the input has a default width, like all inputs. But you can force it to take the full width of its container by using the `fullWidth` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--full-width"/> <Story id="components-forms-input--full-width"/>
</Canvas> </Canvas>
@@ -86,7 +86,7 @@ By default, the input has a default width, like all inputs. But you can force it
You can display a counter of the number of characters entered in the input by using the `charsCounter` props. Please bare You can display a counter of the number of characters entered in the input by using the `charsCounter` props. Please bare
in mind to also define `charCounterMax`. in mind to also define `charCounterMax`.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--char-counter"/> <Story id="components-forms-input--char-counter"/>
</Canvas> </Canvas>
@@ -95,7 +95,7 @@ in mind to also define `charCounterMax`.
Like a native input, you can use the Input component in a controlled or non controlled way. You can see the example below Like a native input, you can use the Input component in a controlled or non controlled way. You can see the example below
using the component in a controlled way. using the component in a controlled way.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--controlled"/> <Story id="components-forms-input--controlled"/>
</Canvas> </Canvas>
@@ -103,7 +103,7 @@ using the component in a controlled way.
You can use the `ref` props to get a reference to the input element. The ref to the native input is nested inside the `input` attribute. You can use the `ref` props to get a reference to the input element. The ref to the native input is nested inside the `input` attribute.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-input--with-ref"/> <Story id="components-forms-input--with-ref"/>
</Canvas> </Canvas>

View File

@@ -1,4 +1,4 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta } from "@storybook/react";
import React, { useRef } from "react"; import React, { useRef } from "react";
import { Input, InputRefType } from ":/components/Forms/Input/index"; import { Input, InputRefType } from ":/components/Forms/Input/index";
import { Button } from ":/components/Button"; import { Button } from ":/components/Button";
@@ -6,121 +6,134 @@ import { Button } from ":/components/Button";
export default { export default {
title: "Components/Forms/Input", title: "Components/Forms/Input",
component: Input, component: Input,
} as ComponentMeta<typeof Input>; } as Meta<typeof Input>;
const Template: ComponentStory<typeof Input> = (args) => <Input {...args} />; export const Default = {
args: {
export const Default = Template.bind({}); defaultValue: "Hello world",
Default.args = { label: "Your name",
defaultValue: "Hello world", },
label: "Your name",
}; };
export const Success = Template.bind({}); export const Success = {
Success.args = { args: {
defaultValue: "Hello world", defaultValue: "Hello world",
label: "Your name", label: "Your name",
state: "success", state: "success",
icon: <span className="material-icons">person</span>, icon: <span className="material-icons">person</span>,
text: "This is an optional success message", text: "This is an optional success message",
},
}; };
export const Error = Template.bind({}); export const Error = {
Error.args = { args: {
defaultValue: "Hello world", defaultValue: "Hello world",
label: "Your name", label: "Your name",
state: "error", state: "error",
icon: <span className="material-icons">person</span>, icon: <span className="material-icons">person</span>,
text: "This is an optional error message", text: "This is an optional error message",
},
}; };
export const DisabledEmpty = Template.bind({}); export const DisabledEmpty = {
DisabledEmpty.args = { args: {
label: "Your name", label: "Your name",
icon: <span className="material-icons">person</span>, icon: <span className="material-icons">person</span>,
disabled: true, disabled: true,
},
}; };
export const DisabledFilled = Template.bind({}); export const DisabledFilled = {
DisabledFilled.args = { args: {
label: "Your name", label: "Your name",
defaultValue: "John Doe", defaultValue: "John Doe",
icon: <span className="material-icons">person</span>, icon: <span className="material-icons">person</span>,
disabled: true, disabled: true,
},
}; };
export const Empty = Template.bind({}); export const Empty = {
Empty.args = { args: {
label: "Your email", label: "Your email",
},
}; };
export const Icon = Template.bind({}); export const Icon = {
Icon.args = { args: {
label: "Account balance", label: "Account balance",
icon: <span className="material-icons">attach_money</span>, icon: <span className="material-icons">attach_money</span>,
defaultValue: "1000", defaultValue: "1000",
},
}; };
export const IconRight = Template.bind({}); export const IconRight = {
IconRight.args = { args: {
label: "Account balance", label: "Account balance",
rightIcon: <span className="material-icons">attach_money</span>, rightIcon: <span className="material-icons">attach_money</span>,
defaultValue: "1000", defaultValue: "1000",
},
}; };
export const IconBoth = Template.bind({}); export const IconBoth = {
IconBoth.args = { args: {
label: "Not a recommended use", label: "Not a recommended use",
icon: <span className="material-icons">attach_money</span>, icon: <span className="material-icons">attach_money</span>,
rightIcon: <span className="material-icons">attach_money</span>, rightIcon: <span className="material-icons">attach_money</span>,
defaultValue: "Is isn't recommended to use both icons", defaultValue: "Is isn't recommended to use both icons",
},
}; };
export const OverflowingText = Template.bind({}); export const OverflowingText = {
OverflowingText.args = { args: {
label: "Your name", label: "Your name",
icon: <span className="material-icons">attach_money</span>, icon: <span className="material-icons">attach_money</span>,
defaultValue: "John Dave Mike Smith Doe Junior Senior Yoda Skywalker", defaultValue: "John Dave Mike Smith Doe Junior Senior Yoda Skywalker",
},
}; };
export const WithText = Template.bind({}); export const WithText = {
WithText.args = { args: {
defaultValue: "Hello world", defaultValue: "Hello world",
label: "Your name", label: "Your name",
text: "This is a text, you can display anything you want here like warnings, informations or errors.", text: "This is a text, you can display anything you want here like warnings, informations or errors.",
},
}; };
export const WithTextRight = Template.bind({}); export const WithTextRight = {
WithTextRight.args = { args: {
defaultValue: "Hello world", defaultValue: "Hello world",
label: "Your name", label: "Your name",
rightText: "0/300", rightText: "0/300",
},
}; };
export const WithBothTexts = Template.bind({}); export const WithBothTexts = {
WithBothTexts.args = { args: {
defaultValue: "Hello world", defaultValue: "Hello world",
label: "Your name", label: "Your name",
text: "This is a text, you can display anything you want here like warnings, informations or errors.", text: "This is a text, you can display anything you want here like warnings, informations or errors.",
rightText: "0/300", rightText: "0/300",
},
}; };
export const FullWidth = Template.bind({}); export const FullWidth = {
FullWidth.args = { args: {
defaultValue: "Hello world", defaultValue: "Hello world",
label: "Your name", label: "Your name",
fullWidth: true, fullWidth: true,
text: "This is a text, you can display anything you want here like warnings, informations or errors.", text: "This is a text, you can display anything you want here like warnings, informations or errors.",
rightText: "0/300", rightText: "0/300",
},
}; };
export const CharCounter = Template.bind({}); export const CharCounter = {
CharCounter.args = { args: {
defaultValue: "CEO", defaultValue: "CEO",
label: "Job title", label: "Job title",
text: "This is a text, you can display anything you want here like warnings, informations or errors.", text: "This is a text, you can display anything you want here like warnings, informations or errors.",
charCounter: true, charCounter: true,
charCounterMax: 30, charCounterMax: 30,
},
}; };
export const Controlled = () => { export const Controlled = () => {

View File

@@ -1,20 +1,23 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta, StoryFn } from "@storybook/react";
import React from "react"; import React from "react";
import { LabelledBox } from ":/components/Forms/LabelledBox/index"; import { LabelledBox } from ":/components/Forms/LabelledBox/index";
export default { export default {
title: "Components/Forms/LabelledBox", title: "Components/Forms/LabelledBox",
component: LabelledBox, component: LabelledBox,
} as ComponentMeta<typeof LabelledBox>; } as Meta<typeof LabelledBox>;
const Template: ComponentStory<typeof LabelledBox> = (args) => ( const Template: StoryFn<typeof LabelledBox> = (args) => (
<div style={{ height: "3.5rem" }}> <div style={{ height: "3.5rem" }}>
<LabelledBox {...args} /> <LabelledBox {...args} />
</div> </div>
); );
export const Default = Template.bind({}); export const Default = {
Default.args = { render: Template,
label: "Your label here",
children: <span className="clr-greyscale-800">Hello world</span>, args: {
label: "Your label here",
children: <span className="clr-greyscale-800">Hello world</span>,
},
}; };

View File

@@ -17,13 +17,13 @@ The `label` props is optional, but you can use it to provide a description of th
**Without label** **Without label**
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--default"/> <Story id="components-forms-radio--default"/>
</Canvas> </Canvas>
**With label** **With label**
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--with-label"/> <Story id="components-forms-radio--with-label"/>
</Canvas> </Canvas>
@@ -31,7 +31,7 @@ The `label` props is optional, but you can use it to provide a description of th
You can set the value of the radio with the `checked` attribute. You can set the value of the radio with the `checked` attribute.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--default"/> <Story id="components-forms-radio--default"/>
<Story id="components-forms-radio--checked"/> <Story id="components-forms-radio--checked"/>
</Canvas> </Canvas>
@@ -40,7 +40,7 @@ You can set the value of the radio with the `checked` attribute.
As the component uses [Field](?path=/story/components-forms-field-doc--page), you can use the `text` props to provide a description of the radio. As the component uses [Field](?path=/story/components-forms-field-doc--page), you can use the `text` props to provide a description of the radio.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--with-text"/> <Story id="components-forms-radio--with-text"/>
</Canvas> </Canvas>
@@ -48,7 +48,7 @@ As the component uses [Field](?path=/story/components-forms-field-doc--page), yo
As a regular radio, you can disable it by using the `disabled` props. As a regular radio, you can disable it by using the `disabled` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--disabled"/> <Story id="components-forms-radio--disabled"/>
</Canvas> </Canvas>
@@ -56,15 +56,15 @@ As a regular radio, you can disable it by using the `disabled` props.
You can use the following props to change the state of the Input component by using the `state` props. You can use the following props to change the state of the Input component by using the `state` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--with-text"/> <Story id="components-forms-radio--with-text"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--success"/> <Story id="components-forms-radio--success"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--error"/> <Story id="components-forms-radio--error"/>
</Canvas> </Canvas>
@@ -72,13 +72,13 @@ You can use the following props to change the state of the Input component by us
Here is how you can leverage the `RadioGroup` component to create a group of radio buttons. Here is how you can leverage the `RadioGroup` component to create a group of radio buttons.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--group"/> <Story id="components-forms-radio--group"/>
</Canvas> </Canvas>
You can also define `state`, `text` props on the group component You can also define `state`, `text` props on the group component
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-radio--group-error"/> <Story id="components-forms-radio--group-error"/>
<Story id="components-forms-radio--group-success"/> <Story id="components-forms-radio--group-success"/>
</Canvas> </Canvas>

View File

@@ -1,69 +1,95 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta, StoryFn } from "@storybook/react";
import React from "react"; import React from "react";
import { Radio, RadioGroup } from ":/components/Forms/Radio/index"; import { Radio, RadioGroup } from ":/components/Forms/Radio/index";
export default { export default {
title: "Components/Forms/Radio", title: "Components/Forms/Radio",
component: Radio, component: Radio,
} as ComponentMeta<typeof Radio>; } as Meta<typeof Radio>;
const Template: ComponentStory<typeof Radio> = (args) => ( const Template: StoryFn<typeof Radio> = (args) => (
<Radio {...args} aria-label="Radio" /> <Radio {...args} aria-label="Radio" />
); );
export const Default = Template.bind({}); export const Default = {
Default.args = {}; render: Template,
args: {},
export const Checked = Template.bind({});
Checked.args = {
checked: true,
}; };
export const WithLabel = Template.bind({}); export const Checked = {
WithLabel.args = { render: Template,
label: "Label",
args: {
checked: true,
},
}; };
export const WithLabelChecked = Template.bind({}); export const WithLabel = {
WithLabelChecked.args = { render: Template,
label: "Label",
checked: true, args: {
label: "Label",
},
}; };
export const WithText = Template.bind({}); export const WithLabelChecked = {
WithText.args = { render: Template,
label: "Label",
text: "Some optional text", args: {
label: "Label",
checked: true,
},
}; };
export const Disabled = Template.bind({}); export const WithText = {
Disabled.args = { render: Template,
label: "Label",
disabled: true, args: {
label: "Label",
text: "Some optional text",
},
}; };
export const DisabledChecked = Template.bind({}); export const Disabled = {
DisabledChecked.args = { render: Template,
label: "Label",
disabled: true, args: {
checked: true, label: "Label",
text: "Some optional text", disabled: true,
},
}; };
export const Error = Template.bind({}); export const DisabledChecked = {
Error.args = { render: Template,
checked: true,
label: "Label", args: {
text: "This is an optional text", label: "Label",
state: "error", disabled: true,
checked: true,
text: "Some optional text",
},
}; };
export const Success = Template.bind({}); export const Error = {
Success.args = { render: Template,
checked: true,
label: "Label", args: {
text: "This is an optional text", checked: true,
state: "success", label: "Label",
text: "This is an optional text",
state: "error",
},
};
export const Success = {
render: Template,
args: {
checked: true,
label: "Label",
text: "This is an optional text",
state: "success",
},
}; };
export const Group = () => { export const Group = () => {

View File

@@ -36,7 +36,7 @@ As you can see the `value` is optional, if not provided, the `label` will be use
You can enable the text live filtering simply by using the `searchable` props. You can enable the text live filtering simply by using the `searchable` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-select-mono--searchable-uncontrolled"/> <Story id="components-forms-select-mono--searchable-uncontrolled"/>
</Canvas> </Canvas>
@@ -44,11 +44,11 @@ You can enable the text live filtering simply by using the `searchable` props.
You can use the following props to change the state of the Select component by using the `state` props. You can use the following props to change the state of the Select component by using the `state` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-select-mono--success"/> <Story id="components-forms-select-mono--success"/>
</Canvas> </Canvas>
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-select-mono--error"/> <Story id="components-forms-select-mono--error"/>
</Canvas> </Canvas>
@@ -56,7 +56,7 @@ You can use the following props to change the state of the Select component by u
As a regular select, you can disable it by using the `disabled` props. As a regular select, you can disable it by using the `disabled` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-select-mono--disabled"/> <Story id="components-forms-select-mono--disabled"/>
</Canvas> </Canvas>
@@ -64,7 +64,7 @@ As a regular select, you can disable it by using the `disabled` props.
As the component uses [Field](?path=/story/components-forms-field-doc--page), you can use the `text` props to provide a description of the checkbox. As the component uses [Field](?path=/story/components-forms-field-doc--page), you can use the `text` props to provide a description of the checkbox.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-select-mono--with-text"/> <Story id="components-forms-select-mono--with-text"/>
</Canvas> </Canvas>
@@ -72,7 +72,7 @@ As the component uses [Field](?path=/story/components-forms-field-doc--page), yo
By default, the select has a default width, like all inputs. But you can force it to take the full width of its container by using the `fullWidth` props. By default, the select has a default width, like all inputs. But you can force it to take the full width of its container by using the `fullWidth` props.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-select-mono--full-width"/> <Story id="components-forms-select-mono--full-width"/>
</Canvas> </Canvas>
@@ -81,7 +81,7 @@ By default, the select has a default width, like all inputs. But you can force i
Like a native select, you can use the Select component in a controlled or non controlled way. You can see the example below Like a native select, you can use the Select component in a controlled or non controlled way. You can see the example below
using the component in a controlled way. using the component in a controlled way.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-forms-select-mono--controlled"/> <Story id="components-forms-select-mono--controlled"/>
</Canvas> </Canvas>

View File

@@ -1,4 +1,4 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta, StoryFn } from "@storybook/react";
import React, { useState } from "react"; import React, { useState } from "react";
import { faker } from "@faker-js/faker"; import { faker } from "@faker-js/faker";
import { Select } from ":/components/Forms/Select"; import { Select } from ":/components/Forms/Select";
@@ -8,9 +8,9 @@ import { CunninghamProvider } from ":/components/Provider";
export default { export default {
title: "Components/Forms/Select/Mono", title: "Components/Forms/Select/Mono",
component: Select, component: Select,
} as ComponentMeta<typeof Select>; } as Meta<typeof Select>;
const Template: ComponentStory<typeof Select> = (args) => ( const Template: StoryFn<typeof Select> = (args) => (
<div style={{ paddingBottom: "200px" }}> <div style={{ paddingBottom: "200px" }}>
<CunninghamProvider> <CunninghamProvider>
<Select {...args} /> <Select {...args} />
@@ -24,28 +24,38 @@ const OPTIONS = CITIES.map((city) => ({
value: city.toLowerCase(), value: city.toLowerCase(),
})); }));
export const Uncontrolled = Template.bind({}); export const Uncontrolled = {
Uncontrolled.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
defaultValue: OPTIONS[4].value, label: "Select a city",
options: OPTIONS,
defaultValue: OPTIONS[4].value,
},
}; };
export const Disabled = Template.bind({}); export const Disabled = {
Disabled.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
defaultValue: OPTIONS[4].value, label: "Select a city",
disabled: true, options: OPTIONS,
defaultValue: OPTIONS[4].value,
disabled: true,
},
}; };
export const WithText = Template.bind({}); export const WithText = {
WithText.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
defaultValue: OPTIONS[4].value, label: "Select a city",
text: "This is a text, you can display anything you want here like warnings, information or errors.", options: OPTIONS,
defaultValue: OPTIONS[4].value,
text: "This is a text, you can display anything you want here like warnings, information or errors.",
},
}; };
export const Controlled = () => { export const Controlled = () => {
const [value, setValue] = useState(OPTIONS[8].value); const [value, setValue] = useState(OPTIONS[8].value);
return ( return (
@@ -66,40 +76,52 @@ export const Controlled = () => {
); );
}; };
export const Overflow = Template.bind({}); export const Overflow = {
Overflow.args = { render: Template,
label: "Select a city",
options: [ args: {
{ label: "Select a city",
value: "1", options: [
label: "Very long long long long long long long city name", {
}, value: "1",
], label: "Very long long long long long long long city name",
defaultValue: "1", },
],
defaultValue: "1",
},
}; };
export const SearchableEmpty = Template.bind({}); export const SearchableEmpty = {
SearchableEmpty.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
searchable: true, label: "Select a city",
options: OPTIONS,
searchable: true,
},
}; };
export const SearchableUncontrolled = Template.bind({}); export const SearchableUncontrolled = {
SearchableUncontrolled.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
defaultValue: OPTIONS[4].value, label: "Select a city",
searchable: true, options: OPTIONS,
defaultValue: OPTIONS[4].value,
searchable: true,
},
}; };
export const SearchableDisabled = Template.bind({}); export const SearchableDisabled = {
SearchableDisabled.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
defaultValue: OPTIONS[4].value, label: "Select a city",
searchable: true, options: OPTIONS,
disabled: true, defaultValue: OPTIONS[4].value,
searchable: true,
disabled: true,
},
}; };
export const SearchableControlled = () => { export const SearchableControlled = () => {
@@ -123,27 +145,36 @@ export const SearchableControlled = () => {
); );
}; };
export const FullWidth = Template.bind({}); export const FullWidth = {
FullWidth.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
fullWidth: true, label: "Select a city",
options: OPTIONS,
fullWidth: true,
},
}; };
export const Success = Template.bind({}); export const Success = {
Success.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
state: "success", label: "Select a city",
text: "Well done", options: OPTIONS,
state: "success",
text: "Well done",
},
}; };
export const Error = Template.bind({}); export const Error = {
Error.args = { render: Template,
label: "Select a city",
options: OPTIONS, args: {
state: "error", label: "Select a city",
text: "Something went wrong", options: OPTIONS,
state: "error",
text: "Something went wrong",
},
}; };
export const FormExample = () => { export const FormExample = () => {

View File

@@ -1,13 +1,15 @@
import { ComponentMeta, ComponentStory } from "@storybook/react"; import { Meta, StoryFn } from "@storybook/react";
import React from "react"; import React from "react";
import { Loader } from ":/components/Loader/index"; import { Loader } from ":/components/Loader/index";
export default { export default {
title: "Components/Loader (WIP)", title: "Components/Loader (WIP)",
component: Loader, component: Loader,
} as ComponentMeta<typeof Loader>; } as Meta<typeof Loader>;
const Template: ComponentStory<typeof Loader> = () => <Loader />; const Template: StoryFn<typeof Loader> = () => <Loader />;
export const Default = Template.bind({}); export const Default = {
Default.args = {}; render: Template,
args: {},
};

View File

@@ -10,7 +10,7 @@ for synchronous loading as well as asynchronous loading. You can paginate your a
fetch it from a server, the component is really versatile. fetch it from a server, the component is really versatile.
<Canvas withSource={"none"}> <Canvas sourceState="none">
<Story id="components-pagination--basic"/> <Story id="components-pagination--basic"/>
</Canvas> </Canvas>
@@ -30,7 +30,7 @@ The most basic usage you can make of it is this one, defining a pagination with
### Basic ### Basic
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-pagination--basic"/> <Story id="components-pagination--basic"/>
</Canvas> </Canvas>
@@ -40,7 +40,7 @@ The most basic usage you can make of it is this one, defining a pagination with
But this won't make you really happy if you want to paginate your list of items, so you can wire things a bit better. But this won't make you really happy if you want to paginate your list of items, so you can wire things a bit better.
Let's make a component that paginate a list of random number. Let's make a component that paginate a list of random number.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-pagination--list"/> <Story id="components-pagination--list"/>
</Canvas> </Canvas>
@@ -48,7 +48,7 @@ Let's make a component that paginate a list of random number.
You can also set the page programmatically, for example, if you want to use a query parameter to set the page. You can also set the page programmatically, for example, if you want to use a query parameter to set the page.
<Canvas withSource="open"> <Canvas sourceState="shown">
<Story id="components-pagination--force-page"/> <Story id="components-pagination--force-page"/>
</Canvas> </Canvas>

View File

@@ -1,4 +1,4 @@
import { ComponentMeta } from "@storybook/react"; import { Meta } from "@storybook/react";
import React, { useEffect, useMemo, useState } from "react"; import React, { useEffect, useMemo, useState } from "react";
import { Pagination, usePagination } from ":/components/Pagination/index"; import { Pagination, usePagination } from ":/components/Pagination/index";
import { CunninghamProvider } from ":/components/Provider"; import { CunninghamProvider } from ":/components/Provider";
@@ -6,7 +6,7 @@ import { CunninghamProvider } from ":/components/Provider";
export default { export default {
title: "Components/Pagination", title: "Components/Pagination",
component: Pagination, component: Pagination,
} as ComponentMeta<typeof Pagination>; } as Meta<typeof Pagination>;
export const Basic = () => { export const Basic = () => {
const pagination = usePagination({ const pagination = usePagination({

View File

@@ -26,13 +26,13 @@ You can use custom utility classes to set the background color of an element. Th
You can find all existing classes below. You can find all existing classes below.
<Canvas isColumn={true} withSource="none"> <Canvas sourceState="none">
{colors.map(color => ( {colors.map(color => (
<div key={color} style={{display: 'flex', gap: '5px'}}> <div key={color} style={{display: 'flex', gap: '5px'}}>
{tints.map(tint => ( {tints.map(tint => (
<div key={color + tint} style={{display: 'flex', flexDirection: 'column', flexShrink: 0,flexBasis: '120px', alignItems: 'center', flexGrow: 1}}> <div key={color + tint} style={{display: 'flex', flexDirection: 'column', flexShrink: 0,flexBasis: '120px', alignItems: 'center', flexGrow: 1}}>
<div style={{width: '72px', height: '48px'}} className={"bg-" + color + "-" + tint}></div> <div style={{width: '72px', height: '48px'}} className={"bg-" + color + "-" + tint}></div>
<code className="fs-s mt-st">bg-{color}-{tint}</code> <pre className="fs-s mt-st">bg-{color}-{tint}</pre>
</div> </div>
))} ))}
</div> </div>
@@ -54,7 +54,7 @@ You can use custom utility classes to set the color attribute of an element. The
You can find all existing classes below. You can find all existing classes below.
<Canvas isColumn={true} withSource="none"> <Canvas sourceState="none">
{colors.map(color => ( {colors.map(color => (
<div key={color} style={{display: 'flex', gap: '10px'}}> <div key={color} style={{display: 'flex', gap: '10px'}}>
{['text', ...tints].map(tint => { {['text', ...tints].map(tint => {
@@ -70,7 +70,7 @@ You can find all existing classes below.
alignItems: 'center', alignItems: 'center',
flexGrow: 1 flexGrow: 1
}}> }}>
<code className={classes.join(' ')}>clr-{color}-{tint}</code> <pre className={classes.join(' ')}>clr-{color}-{tint}</pre>
</div> </div>
})} })}
</div> </div>
@@ -80,16 +80,10 @@ You can find all existing classes below.
Pay attention the special `{color}-text` variation. Each color must have a text color variation, which is supposed to Pay attention the special `{color}-text` variation. Each color must have a text color variation, which is supposed to
render readable text on top of a -500 background of its own color variation. Please check out the following examples: render readable text on top of a -500 background of its own color variation. Please check out the following examples:
<Canvas withSource="open"> <Canvas sourceState="none">
<span className="bg-primary-500 clr-primary-text fw-medium p-t"> <div className="bg-primary-500 clr-primary-text fw-medium p-t">I'm a text on top of a primary-500 background 👋</div>
I'm a text on top of a primary-500 background 👋 <div className="bg-secondary-500 clr-secondary-text fw-medium p-t">I'm a text on top of a secondary-500 background 👋</div>
</span> <div className="bg-danger-500 clr-danger-text fw-medium p-t">I'm a text on top of a danger-500 background 👋</div>
<span className="bg-secondary-500 clr-secondary-text fw-medium p-t">
I'm a text on top of a secondary-500 background 👋
</span>
<span className="bg-danger-500 clr-danger-text fw-medium p-t">
I'm a text on top of a danger-500 background 👋
</span>
</Canvas> </Canvas>
## Customize ## Customize

View File

@@ -9,7 +9,7 @@ Cunningham comes with an existing toolkit to deal with spacings. 📏
Here are the existing spacings: Here are the existing spacings:
<Canvas isColumn={true} withSource="none"> <Canvas sourceState="none">
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
{Object.keys(tokens.theme.spacings).map(key => ( {Object.keys(tokens.theme.spacings).map(key => (
<div key={key} style={{ display: 'flex', alignItems: 'center', gap: '10px' }}> <div key={key} style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
@@ -29,11 +29,11 @@ You can use the following classes to add margins to your elements:
| Class | Equivalent | | Class | Equivalent |
|--------------|----------------------------| |--------------|----------------------------|
| m-{spacing} | `margin: {spacing}` | | m-[spacing] | `margin: [spacing]` |
| mt-{spacing} | `margin-top: {spacing}` | | mt-[spacing] | `margin-top: [spacing]` |
| mr-{spacing} | `margin-right: {spacing}` | | mr-[spacing] | `margin-right: [spacing]` |
| mb-{spacing} | `margin-bottom: {spacing}` | | mb-[spacing] | `margin-bottom: [spacing]` |
| ml-{spacing} | `margin-left: {spacing}` | | ml-[spacing] | `margin-left: [spacing]` |
## Paddings ## Paddings
@@ -41,22 +41,18 @@ You can use the following classes to add paddings to your elements:
| Class | Equivalent | | Class | Equivalent |
|--------------|----------------------------| |--------------|----------------------------|
| p-{spacing} | `padding: {spacing}` | | p-[spacing] | `padding: [spacing]` |
| pt-{spacing} | `padding-top: {spacing}` | | pt-[spacing] | `padding-top: [spacing]` |
| pr-{spacing} | `padding-right: {spacing}` | | pr-[spacing] | `padding-right: [spacing]` |
| pb-{spacing} | `padding-bottom: {spacing}` | | pb-[spacing] | `padding-bottom: [spacing]` |
| pl-{spacing} | `padding-left: {spacing}` | | pl-[spacing] | `padding-left: [spacing]` |
## Example ## Example
<Canvas isColumn={true} withSource="open"> <Canvas sourceState="shown">
<div className="bg-danger-100"> <div className="bg-danger-100">
<div className="bg-primary-500 clr-primary-text fw-medium p-t mb-l"> <div className="bg-primary-500 clr-primary-text fw-medium p-t mb-l">Tiny padding + Large margin bottom</div>
Tiny padding + Large margin bottom <div className="bg-secondary-500 clr-secondary-text fw-medium p-l ml-b">Large padding + Base margin left</div>
</div> </div>
<div className="bg-secondary-500 clr-secondary-text fw-medium p-l ml-b">
Large padding + Base margin left
</div>
</div>
</Canvas> </Canvas>

View File

@@ -20,10 +20,12 @@ You can use custom utility classes to set the font size of an element. These cla
`} `}
/> />
<Canvas isColumn={true} withSource="none"> <Canvas sourceState="none">
{Object.keys(tokens.theme.font.sizes).map(key => ( <div style={{display: "flex", flexDirection: "column", gap: "20px"}}>
<div key={key} className={"fs-" + key}>Using the <code>fs-{key}</code> class</div> {Object.keys(tokens.theme.font.sizes).map(key => (
))} <div key={key} className={"fs-" + key}>Using the <code>fs-{key}</code> class</div>
))}
</div>
</Canvas> </Canvas>
You can customize the values of the font size design tokens with the configuration file this way: You can customize the values of the font size design tokens with the configuration file this way:
@@ -61,10 +63,12 @@ You can use custom utility classes to set the font weight of an element. These c
`} `}
/> />
<Canvas isColumn={true} withSource="none"> <Canvas sourceState="none">
{Object.keys(tokens.theme.font.weights).map(key => ( <div style={{display: "flex", flexDirection: "column", gap: "20px"}}>
<div key={key} className={"fs-l fw-" + key}>Using the <code>fw-{key}</code> class</div> {Object.keys(tokens.theme.font.weights).map(key => (
))} <div key={key} className={"fs-l fw-" + key}>Using the <code>fw-{key}</code> class</div>
))}
</div>
</Canvas> </Canvas>
You can customize the values of the font weight design tokens with the configuration file this way: You can customize the values of the font weight design tokens with the configuration file this way:
@@ -106,10 +110,12 @@ class on every dom element.
`} `}
/> />
<Canvas isColumn={true} withSource="none"> <Canvas sourceState="none">
{Object.keys(tokens.theme.font.families).map(key => ( <div style={{display: "flex", flexDirection: "column", gap: "20px"}}>
<div key={key} className={"f-" + key}>Using the <code>f-{key}</code> class</div> {Object.keys(tokens.theme.font.families).map(key => (
))} <div key={key} className={"f-" + key}>Using the <code>f-{key}</code> class</div>
))}
</div>
</Canvas> </Canvas>
You can customize the values of the font family design tokens with the configuration file this way: You can customize the values of the font family design tokens with the configuration file this way:

5705
yarn.lock

File diff suppressed because it is too large Load Diff