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
Button
component to create theIconButton
component. - 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/button
folder 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
isRound
prop, for circle shaped buttons.Because
IconButton
usesButton
all the props are inherited and we can continue to passcolorScheme
,variant
ands
(size).
Story
- With the above our
IconButton
component is completed, let us create a story. - Under the
src/components/atoms/form/button/button.stories.tsx
file 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 storybook
check 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.ts
file and paste the following -
export * from "./button";
export * from "./icon-button";
Now
npm run build
.Under the folder
example/src/App.tsx
we can test ourWrap
component. Copy paste the following code and runnpm run start
from theexample
directory.
<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)