Introduction
Let us continue building our chakra components using styled-components & styled-system. In this tutorial we will be cloning the Chakra UI IconButton & component.
- I would like you to first check the chakra docs for icon-button.
- We will use our
Buttoncomponent to create theIconButtoncomponent. - All the code for this tutorial can be found here under the atom-form-button branch.
Prerequisite
Please check the previous post where we have completed the Button Component. Also please check the Chakra IconButton Component code here.
In this tutorial we will -
- Create a IconButton component.
- Create story for the IconButton component.
Setup
We will continue to work in the atom-form-button from the previous tutorial.
Under the
components/form/buttonfolder create a new fileicon-button.tsx.So our folder structure stands like - src/components/atoms/form/button.
IconButton Component
- Let me first paste the code -
import * as React from "react";
import { Button, ButtonProps } from "./button";
type Omitted =
| "leftIcon"
| "isFullWidth"
| "rightIcon"
| "loadingText"
| "iconSpacing";
export interface IconButtonProps extends Omit<ButtonProps, Omitted> {
icon?: React.ReactElement;
isRound?: boolean;
"aria-label": string;
}
export const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
(props, ref) => {
const {
icon,
children,
isRound,
"aria-label": ariaLabel,
...delegated
} = props;
const element = icon || children;
const buttonChildren = React.isValidElement(element)
? React.cloneElement(element as any, {
"aria-hidden": true,
focusable: false,
})
: null;
return (
<Button
ref={ref}
aria-label={ariaLabel}
padding="0"
borderRadius={isRound ? "9999px" : "0.375rem"}
{...delegated}
>
{buttonChildren}
</Button>
);
}
);
The above code is self-explanatory. We have removed all the rightIcon, leftIcon, iconSpacing props from the type, instead we are just allowing the icon prop which will be our icon element.
We added
isRoundprop, for circle shaped buttons.Because
IconButtonusesButtonall the props are inherited and we can continue to passcolorScheme,variantands(size).
Story
- With the above our
IconButtoncomponent is completed, let us create a story. - Under the
src/components/atoms/form/button/button.stories.tsxfile we add the below story code.
export const ButtonIcon = {
render: () => (
<Stack>
<IconButton aria-label="Search database" icon={<SearchIcon />} />
<IconButton
colorScheme="blue"
aria-label="Search database"
icon={<SearchIcon />}
/>
<IconButton
variant="outline"
colorScheme="teal"
aria-label="Send email"
icon={<EmailIcon />}
/>
<IconButton
colorScheme="teal"
aria-label="Call Segun"
s="lg"
icon={<PhoneIcon />}
/>
</Stack>
),
};
- Now run
npm run storybookcheck the stories. Under the Playground stories check the controls section play with the props, add more controls if you like.
Build the Library
- Under the
/button/index.tsfile and paste the following -
export * from "./button";
export * from "./icon-button";
Now
npm run build.Under the folder
example/src/App.tsxwe can test ourWrapcomponent. Copy paste the following code and runnpm run startfrom theexampledirectory.
<Stack m="md">
<IconButton aria-label="Search database" icon={<SearchIcon />} />
<IconButton
colorScheme="blue"
aria-label="Search database"
icon={<SearchIcon />}
/>
<IconButton
variant="outline"
colorScheme="teal"
aria-label="Send email"
icon={<EmailIcon />}
/>
<IconButton
colorScheme="teal"
aria-label="Call Segun"
s="xs"
icon={<PhoneIcon />}
/>
<IconButton
colorScheme="teal"
aria-label="Call Segun"
s="sm"
icon={<PhoneIcon />}
/>
<IconButton
colorScheme="teal"
aria-label="Call Segun"
s="md"
icon={<PhoneIcon />}
/>
<IconButton
colorScheme="teal"
aria-label="Call Segun"
s="lg"
icon={<PhoneIcon />}
/>
</Stack>
Summary
There you go guys in this tutorial we created IconButton component just like chakra ui. You can find the code for this tutorial under the atom-form-button branch here. In the next tutorial we will create Image component. Until next time PEACE.
Top comments (0)