Skip to content

Commit

Permalink
chore: added storyTemplate utils (#39)
Browse files Browse the repository at this point in the history
* chore: added storyTemplate util

* chore: added createControls utility

* refactor(story): ♻️  remove console logs & added default args

* chore: move storybook utils to storybook folder

Co-authored-by: Navin <[email protected]>
  • Loading branch information
anuraghazra and navin-moorthy authored Jan 20, 2021
1 parent a6858ce commit 8933d29
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 82 deletions.
40 changes: 40 additions & 0 deletions .storybook/storybookUtils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from "react";
import { Story } from "@storybook/react";

import theme from "../src/theme/defaultTheme";

export const storyTemplate = <ComponentProps,>(
Component: React.FC,
defaultArgs?: Partial<ComponentProps>,
) => (props: ComponentProps) => {
const base: Story<ComponentProps> = args => <Component {...args} />;
base.args = { ...defaultArgs, ...props };
return base;
};

export const createUnionControl = (keys: any) => {
return {
control: { type: "inline-radio", options: Object.keys(keys) },
};
};

export const createControls = (
component: string,
options?: { unions: string[]; ignore: string[] },
) => {
const controls = options?.unions.reduce((cur, key) => {
return {
...cur,
[key]: createUnionControl((theme as Record<string, any>)[component][key]),
};
}, {});

const ignoredControls = options?.ignore.reduce((cur, key) => {
return {
...cur,
[key]: { table: { disable: true } },
};
}, {});

return { ...controls, ...ignoredControls };
};
2 changes: 2 additions & 0 deletions src/alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ export const AlertIcon = forwardRefWithAs<
</Role>
);
});

export default Alert;
168 changes: 86 additions & 82 deletions src/button/stories/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { cx } from "@renderlesskit/react";
// also exported from '@storybook/react' if you can deal with breaking changes in 6.1
import { Story, Meta } from "@storybook/react/types-6-0";
import { Meta } from "@storybook/react/types-6-0";
import { useTabState, Tab, TabList, TabPanel } from "reakit/Tab";

import {
Expand All @@ -12,7 +12,6 @@ import {
CloseButton as CloseButtonDefault,
IconButtonProps,
ButtonGroupProps,
CloseButtonProps,
} from "../index";
import {
SearchIcon,
Expand All @@ -22,65 +21,58 @@ import {
} from "../../icons";
import { useTheme } from "../../theme";
import { Spinner } from "../../spinner";
import {
createControls,
storyTemplate,
} from "../../../.storybook/storybookUtils";

export default {
title: "Button",
component: Button,
argTypes: createControls("button", {
unions: ["size", "variant"],
ignore: [
"unstable_system",
"unstable_clickOnEnter",
"unstable_clickOnSpace",
"wrapElement",
],
}),
} as Meta;

const Base: Story<ButtonProps> = args => <Button {...args}>Button</Button>;

export const Default = Base.bind({});
Default.args = { size: "lg", variant: "primary" };

export const ExtendedVariant = Default.bind({});
ExtendedVariant.args = { size: "xxl", variant: "tertiary" };

const LeftIconButton: Story<ButtonProps> = args => (
<Button prefix={<SearchIcon />} {...args}>
Button
</Button>
);

export const LeftIcon = LeftIconButton.bind({});
LeftIcon.args = { size: "lg", variant: "primary" };

const RightIconButton: Story<ButtonProps> = args => (
<Button suffix={<CaretDownIcon />} {...args}>
Button
</Button>
);

export const RightIcon = RightIconButton.bind({});
RightIcon.args = { size: "lg", variant: "primary" };
const base = storyTemplate<ButtonProps>(Button, {
children: "Button",
size: "lg",
variant: "primary",
});

const BothSideIconButton: Story<ButtonProps> = args => (
<Button prefix={<SearchIcon />} suffix={<CaretDownIcon />} {...args}>
Button
</Button>
);
export const Default = base({});

export const BothSideIcon = BothSideIconButton.bind({});
BothSideIcon.args = { size: "lg", variant: "primary" };
export const ExtendedVariant = base({
// @ts-ignore
size: "xxl",
// @ts-ignore
variant: "tertiary",
});

const IconButtonBase: Story<IconButtonProps> = args => (
<IconButton aria-label="picture" {...args}>
<SearchIcon />
</IconButton>
);
export const LeftIcon = base({
prefix: <SearchIcon />,
});

export const OnlyIcon = IconButtonBase.bind({});
OnlyIcon.args = { size: "lg", variant: "primary" };
export const RightIcon = base({
suffix: <CaretDownIcon />,
});

const CloseButtonBase: Story<CloseButtonProps> = args => (
<CloseButtonDefault {...args} />
);
export const BothIcon = base({
suffix: <CaretDownIcon />,
prefix: <SearchIcon />,
});

export const CloseButton = CloseButtonBase.bind({});
CloseButton.args = { size: "lg", variant: "primary" };

export const LoadingIcon = BothSideIconButton.bind({});
LoadingIcon.args = { size: "lg", variant: "primary", isLoading: true };
export const LoadingIcon = base({
suffix: <CaretDownIcon />,
prefix: <SearchIcon />,
isLoading: true,
});

const CustomSpinner = () => {
const theme = useTheme();
Expand All @@ -93,23 +85,26 @@ const CustomSpinner = () => {
);
};

export const CustomLaodingElement = BothSideIconButton.bind({});
CustomLaodingElement.args = {
size: "lg",
variant: "primary",
export const CustomLoadingElement = base({
suffix: <CaretDownIcon />,
prefix: <SearchIcon />,
isLoading: true,
spinner: <CustomSpinner />,
};

const ButtonGroupBase: Story<ButtonGroupProps> = args => (
<ButtonGroup {...args}>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</ButtonGroup>
});

const iconButtonBase = storyTemplate<IconButtonProps>(
args => {
return (
<IconButton aria-label="picture" {...args}>
<SearchIcon />
</IconButton>
);
},
{ size: "lg", variant: "primary" },
);

const IconButtonGroupBase: Story<ButtonGroupProps> = args => (
export const OnlyIcon = iconButtonBase({});
const IconButtonGroupBase = storyTemplate<ButtonGroupProps>(args => (
<ButtonGroup {...args}>
<IconButton aria-label="search" {...args}>
<SearchIcon />
Expand All @@ -121,34 +116,44 @@ const IconButtonGroupBase: Story<ButtonGroupProps> = args => (
<WheelIcon />
</IconButton>
</ButtonGroup>
);
));

export const GroupDefault = ButtonGroupBase.bind({});
GroupDefault.args = { className: "space-x-4" };

export const GroupCollapsed = ButtonGroupBase.bind({});
GroupCollapsed.args = {
isAttached: true,
const closeButtonBase = storyTemplate<IconButtonProps>(CloseButtonDefault, {
size: "lg",
variant: "primary",
};
});

export const CloseButton = closeButtonBase({});

const buttonGroupBase = storyTemplate<ButtonGroupProps>(
args => (
<ButtonGroup {...args}>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</ButtonGroup>
),
{ size: "lg", variant: "primary" },
);

export const IconButtonGroupCollapsed = IconButtonGroupBase.bind({});
IconButtonGroupCollapsed.args = {
export const GroupDefault = buttonGroupBase({ className: "space-x-4" });

export const GroupCollapsed = buttonGroupBase({ isAttached: true });

export const IconButtonGroupCollapsed = IconButtonGroupBase({
isAttached: true,
size: "lg",
variant: "primary",
};
});

export const GroupSecondary = ButtonGroupBase.bind({});
GroupSecondary.args = {
export const GroupSecondary = buttonGroupBase({
isAttached: true,
size: "lg",
variant: "secondary",
};
});

const ButtonGroupExample: Story<ButtonGroupProps> = args => {
const buttonGroupExample = storyTemplate<ButtonGroupProps>(args => {
const tab = useTabState();

return (
<>
<TabList as={ButtonGroup} {...args} {...tab} aria-label="My tabs">
Expand All @@ -167,11 +172,10 @@ const ButtonGroupExample: Story<ButtonGroupProps> = args => {
<TabPanel {...tab}>Tab 3</TabPanel>
</>
);
};
});

export const TabListAsGroup = ButtonGroupExample.bind({});
TabListAsGroup.args = {
export const TabListAsGroup = buttonGroupExample({
isAttached: true,
size: "lg",
variant: "secondary",
};
});

1 comment on commit 8933d29

@vercel
Copy link

@vercel vercel bot commented on 8933d29 Jan 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.