From 0114409d7efb8e5146d2b17b5fc5500ceb16b7bf Mon Sep 17 00:00:00 2001 From: Igor Brasileiro Date: Thu, 26 Aug 2021 11:04:00 -0300 Subject: [PATCH] feat(store-ui): Add IconButton Molecule (#900) * Add IconButton molecule component * Use IconButton on Carousel * Fix stories and doc * Fix default story and remove children from props * Use css hover instead of tailwind hover * Export IconButton * Trigger CI * Change story css * Change Preview to Default * Fix css * Add css selectors on docs --- packages/store-ui/src/deprecated/index.ts | 4 +-- packages/store-ui/src/index.ts | 3 ++ .../src/molecules/Carousel/Carousel.tsx | 17 +++++------ .../molecules/IconButton/IconButton.test.tsx | 27 +++++++++++++++++ .../src/molecules/IconButton/IconButton.tsx | 30 +++++++++++++++++++ .../src/molecules/IconButton/index.tsx | 2 ++ .../IconButton/stories/IconButton.mdx | 25 ++++++++++++++++ .../IconButton/stories/IconButton.stories.tsx | 30 +++++++++++++++++++ .../src/molecules/icon-button.css | 11 +++++++ .../src/molecules/index.css | 1 + 10 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 packages/store-ui/src/molecules/IconButton/IconButton.test.tsx create mode 100644 packages/store-ui/src/molecules/IconButton/IconButton.tsx create mode 100644 packages/store-ui/src/molecules/IconButton/index.tsx create mode 100644 packages/store-ui/src/molecules/IconButton/stories/IconButton.mdx create mode 100644 packages/store-ui/src/molecules/IconButton/stories/IconButton.stories.tsx create mode 100644 themes/theme-b2c-tailwind/src/molecules/icon-button.css diff --git a/packages/store-ui/src/deprecated/index.ts b/packages/store-ui/src/deprecated/index.ts index 967f35d4cd..e9ac835193 100644 --- a/packages/store-ui/src/deprecated/index.ts +++ b/packages/store-ui/src/deprecated/index.ts @@ -35,7 +35,7 @@ export { Container, NavLink, Message, - IconButton, + IconButton as UIIconButton, MenuButton, jsx, useThemeUI, @@ -70,7 +70,7 @@ export type { ContainerProps, NavLinkProps, MessageProps, - IconButtonProps, + IconButtonProps as UIIconButtonProps, MenuButtonProps, } from 'theme-ui' diff --git a/packages/store-ui/src/index.ts b/packages/store-ui/src/index.ts index 16e06ee712..1f9d7cde6c 100644 --- a/packages/store-ui/src/index.ts +++ b/packages/store-ui/src/index.ts @@ -42,6 +42,9 @@ export type { SearchInputProps } from './molecules/SearchInput' export { default as Carousel } from './molecules/Carousel' export type { CarouselProps } from './molecules/Carousel' +export { default as IconButton } from './molecules/IconButton' +export type { IconButtonProps } from './molecules/IconButton' + // Hooks export { default as useSlider } from './hooks/useSlider' export type { diff --git a/packages/store-ui/src/molecules/Carousel/Carousel.tsx b/packages/store-ui/src/molecules/Carousel/Carousel.tsx index fe323f975c..c7c254c128 100644 --- a/packages/store-ui/src/molecules/Carousel/Carousel.tsx +++ b/packages/store-ui/src/molecules/Carousel/Carousel.tsx @@ -2,12 +2,11 @@ import type { PropsWithChildren } from 'react' import React, { useMemo } from 'react' import type { SwipeableProps } from 'react-swipeable' -import Button from '../../atoms/Button' -import Icon from '../../atoms/Icon' import { RightArrowIcon, LeftArrowIcon } from './Arrows' import useSlider from '../../hooks/useSlider/useSlider' import useSlideVisibility from './hooks/useSlideVisibility' import Bullets from '../Bullets' +import IconButton from '../IconButton' const createTransformValues = (infinite: boolean, totalItems: number) => { const transformMap: Record = {} @@ -155,7 +154,7 @@ function Carousel({ {showNavigationArrows && (
- - + icon={} + />
)} diff --git a/packages/store-ui/src/molecules/IconButton/IconButton.test.tsx b/packages/store-ui/src/molecules/IconButton/IconButton.test.tsx new file mode 100644 index 0000000000..a86f1fffa2 --- /dev/null +++ b/packages/store-ui/src/molecules/IconButton/IconButton.test.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import { render } from '@testing-library/react' + +import IconButton from './IconButton' + +describe('IconButton', () => { + const testId = 'store-icon-button' + + it('data-store-icon-button is present', () => { + const { getByTestId } = render( + foo} /> + ) + + const iconButton = getByTestId(testId) + + expect(iconButton).toBeInTheDocument() + expect(iconButton).toHaveAttribute('data-store-icon-button') + }) + + it('icon is present', () => { + const { getByTestId } = render( + foo} /> + ) + + expect(getByTestId('icon')).toBeInTheDocument() + }) +}) diff --git a/packages/store-ui/src/molecules/IconButton/IconButton.tsx b/packages/store-ui/src/molecules/IconButton/IconButton.tsx new file mode 100644 index 0000000000..80a429e9d7 --- /dev/null +++ b/packages/store-ui/src/molecules/IconButton/IconButton.tsx @@ -0,0 +1,30 @@ +import type { ReactNode } from 'react' +import React, { forwardRef } from 'react' + +import Button from '../../atoms/Button' +import type { ButtonProps } from '../../atoms/Button' +import Icon from '../../atoms/Icon' + +export interface Props extends Omit { + /** + * ID to find this component in testing tools (e.g.: cypress, testing library, and jest). + */ + testId?: string + /** + * A React component that will be rendered as an icon. + */ + icon: ReactNode +} + +const IconButton = forwardRef(function IconButton( + { icon, testId = 'store-icon-button', ...buttonProps }, + ref +) { + return ( + + ) +}) + +export default IconButton diff --git a/packages/store-ui/src/molecules/IconButton/index.tsx b/packages/store-ui/src/molecules/IconButton/index.tsx new file mode 100644 index 0000000000..d58b68359e --- /dev/null +++ b/packages/store-ui/src/molecules/IconButton/index.tsx @@ -0,0 +1,2 @@ +export { default } from './IconButton' +export type { Props as IconButtonProps } from './IconButton' diff --git a/packages/store-ui/src/molecules/IconButton/stories/IconButton.mdx b/packages/store-ui/src/molecules/IconButton/stories/IconButton.mdx new file mode 100644 index 0000000000..65ca83933e --- /dev/null +++ b/packages/store-ui/src/molecules/IconButton/stories/IconButton.mdx @@ -0,0 +1,25 @@ +import { Story, Canvas, ArgsTable } from '@storybook/addon-docs' +import IconButton from '../IconButton' + +# Default + + + + + +# Custom Style + + + + + +# Props + + + +# CSS Selectors +```css +[data-store-icon-button] {} +``` + +This component inherits [Button](?path=/docs/atoms-button--button) component css selectors. diff --git a/packages/store-ui/src/molecules/IconButton/stories/IconButton.stories.tsx b/packages/store-ui/src/molecules/IconButton/stories/IconButton.stories.tsx new file mode 100644 index 0000000000..24b5e8d160 --- /dev/null +++ b/packages/store-ui/src/molecules/IconButton/stories/IconButton.stories.tsx @@ -0,0 +1,30 @@ +import type { Story, Meta } from '@storybook/react' +import React from 'react' + +import type { Props as IconButtonProps } from '../IconButton' +import Component from '../IconButton' +import ShoppingCartIcon from '../../../atoms/Icon/stories/assets/ShoppingCart' +import mdx from './IconButton.mdx' + +const IconButtonTemplate: Story = (props) => ( + } /> +) + +export const Default = IconButtonTemplate.bind({}) + +const IconButtonCustomTemplate: Story = (props) => { + return ( + } /> + ) +} + +export const CustomStyle = IconButtonCustomTemplate.bind({}) + +export default { + title: 'Molecules/IconButton', + parameters: { + docs: { + page: mdx, + }, + }, +} as Meta diff --git a/themes/theme-b2c-tailwind/src/molecules/icon-button.css b/themes/theme-b2c-tailwind/src/molecules/icon-button.css new file mode 100644 index 0000000000..d5aa3272da --- /dev/null +++ b/themes/theme-b2c-tailwind/src/molecules/icon-button.css @@ -0,0 +1,11 @@ +[data-store-icon-button] { + @apply inline-flex; +} + +.iconButton { + @apply text-black inline-flex bg-transparent cursor-pointer rounded-full p-2 transition-colors duration-150 ease-in; +} + +.iconButton:hover { + @apply bg-gray-400 bg-opacity-40; +} diff --git a/themes/theme-b2c-tailwind/src/molecules/index.css b/themes/theme-b2c-tailwind/src/molecules/index.css index 7b70eb26f1..0415f53fdc 100644 --- a/themes/theme-b2c-tailwind/src/molecules/index.css +++ b/themes/theme-b2c-tailwind/src/molecules/index.css @@ -1,2 +1,3 @@ @import "./bullets.css"; @import "./search-input.css"; +@import "./icon-button.css"