From a4a406463d69f6901919d273e831dff22a838caf Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Tue, 19 Apr 2022 12:07:21 +0200 Subject: chore: add a Gallery component --- .../organisms/images/gallery.module.scss | 26 ++++++++ .../organisms/images/gallery.stories.tsx | 75 ++++++++++++++++++++++ src/components/organisms/images/gallery.test.tsx | 38 +++++++++++ src/components/organisms/images/gallery.tsx | 35 ++++++++++ 4 files changed, 174 insertions(+) create mode 100644 src/components/organisms/images/gallery.module.scss create mode 100644 src/components/organisms/images/gallery.stories.tsx create mode 100644 src/components/organisms/images/gallery.test.tsx create mode 100644 src/components/organisms/images/gallery.tsx (limited to 'src/components') diff --git a/src/components/organisms/images/gallery.module.scss b/src/components/organisms/images/gallery.module.scss new file mode 100644 index 0000000..a057ed9 --- /dev/null +++ b/src/components/organisms/images/gallery.module.scss @@ -0,0 +1,26 @@ +@use "@styles/abstracts/mixins" as mix; +@use "@styles/abstracts/placeholders"; + +.wrapper { + @extend %reset-list; + + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--spacing-sm); + max-width: 100%; + margin: var(--spacing-sm) 0; + + @for $i from 0 to 6 { + &--#{$i}-columns { + @include mix.media("screen") { + @include mix.dimensions("xs") { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + @include mix.dimensions("sm") { + grid-template-columns: repeat(#{$i}, minmax(0, 1fr)); + } + } + } + } +} diff --git a/src/components/organisms/images/gallery.stories.tsx b/src/components/organisms/images/gallery.stories.tsx new file mode 100644 index 0000000..786cfff --- /dev/null +++ b/src/components/organisms/images/gallery.stories.tsx @@ -0,0 +1,75 @@ +import ResponsiveImage from '@components/molecules/images/responsive-image'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import Gallery from './gallery'; + +/** + * Gallery - Storybook Meta + */ +export default { + title: 'Organisms/Images/Gallery', + component: Gallery, + argTypes: { + children: { + control: { + type: null, + }, + description: 'Two or more ResponsiveImage component.', + type: { + name: 'function', + required: true, + }, + }, + columns: { + control: { + type: 'number', + min: 2, + max: 4, + }, + description: 'The columns count.', + type: { + name: 'number', + required: true, + }, + }, + }, +} as ComponentMeta; + +const image = { + alt: 'Modi provident omnis', + height: 480, + src: 'http://placeimg.com/640/480/fashion', + width: 640, +}; + +const Template: ComponentStory = (args) => ( + + + + + + +); + +/** + * Gallery Stories - Two columns + */ +export const TwoColumns = Template.bind({}); +TwoColumns.args = { + columns: 2, +}; + +/** + * Gallery Stories - Three columns + */ +export const ThreeColumns = Template.bind({}); +ThreeColumns.args = { + columns: 3, +}; + +/** + * Gallery Stories - Four columns + */ +export const FourColumns = Template.bind({}); +FourColumns.args = { + columns: 4, +}; diff --git a/src/components/organisms/images/gallery.test.tsx b/src/components/organisms/images/gallery.test.tsx new file mode 100644 index 0000000..5f35f0a --- /dev/null +++ b/src/components/organisms/images/gallery.test.tsx @@ -0,0 +1,38 @@ +import ResponsiveImage from '@components/molecules/images/responsive-image'; +import { render, screen } from '@test-utils'; +import Gallery from './gallery'; + +const columns = 3; + +const image = { + alt: 'Modi provident omnis', + height: 480, + src: 'http://placeimg.com/640/480/fashion', + width: 640, +}; + +describe('Gallery', () => { + it('renders the correct number of items', () => { + render( + + + + + + + ); + expect(screen.getAllByRole('listitem')).toHaveLength(4); + }); + + it('renders the right number of columns', () => { + render( + + + + + + + ); + expect(screen.getByRole('list')).toHaveClass(`wrapper--${columns}-columns`); + }); +}); diff --git a/src/components/organisms/images/gallery.tsx b/src/components/organisms/images/gallery.tsx new file mode 100644 index 0000000..6c4a271 --- /dev/null +++ b/src/components/organisms/images/gallery.tsx @@ -0,0 +1,35 @@ +import { type ResponsiveImageProps } from '@components/molecules/images/responsive-image'; +import { Children, FC, ReactElement } from 'react'; +import styles from './gallery.module.scss'; + +export type GalleryColumn = 2 | 3 | 4; + +export type GalleryProps = { + /** + * The images using ResponsiveImage component. + */ + children: ReactElement[]; + /** + * The columns count. + */ + columns: GalleryColumn; +}; + +/** + * Gallery component + * + * Render a gallery of images. + */ +const Gallery: FC = ({ children, columns }) => { + const columnsClass = `wrapper--${columns}-columns`; + + return ( +
    + {Children.map(children, (child) => { + return
  • {child}
  • ; + })} +
+ ); +}; + +export default Gallery; -- cgit v1.2.3