From 8f2d85ec20a9359abe8c53a15e9a06b7b19f29a5 Mon Sep 17 00:00:00 2001 From: farid Date: Wed, 12 Apr 2023 19:42:33 +0200 Subject: [PATCH 1/3] feat(#342): migrate stack component --- .../HelloInternet/HelloInternetTheme.ts | 2 + .../molecules/Stacks/Stack.stories.tsx | 156 ++++++++++++++++++ .../molecules/Stacks/Stack.theme.tsx | 79 +++++++++ src/lib/components/molecules/Stacks/Stack.tsx | 18 ++ .../molecules/Stacks/StackImage.tsx | 23 +++ .../components/molecules/Stacks/StackItem.tsx | 23 +++ .../molecules/Stacks/StackItemGroup.tsx | 27 +++ .../molecules/Stacks/StackTitle.tsx | 17 ++ src/lib/components/molecules/Stacks/index.ts | 18 ++ src/lib/theme/default.ts | 2 + 10 files changed, 365 insertions(+) create mode 100644 src/lib/components/molecules/Stacks/Stack.stories.tsx create mode 100644 src/lib/components/molecules/Stacks/Stack.theme.tsx create mode 100644 src/lib/components/molecules/Stacks/Stack.tsx create mode 100644 src/lib/components/molecules/Stacks/StackImage.tsx create mode 100644 src/lib/components/molecules/Stacks/StackItem.tsx create mode 100644 src/lib/components/molecules/Stacks/StackItemGroup.tsx create mode 100644 src/lib/components/molecules/Stacks/StackTitle.tsx create mode 100644 src/lib/components/molecules/Stacks/index.ts diff --git a/src/lib/components/bosons/HelloInternet/HelloInternetTheme.ts b/src/lib/components/bosons/HelloInternet/HelloInternetTheme.ts index 76dde86..ebcb58f 100644 --- a/src/lib/components/bosons/HelloInternet/HelloInternetTheme.ts +++ b/src/lib/components/bosons/HelloInternet/HelloInternetTheme.ts @@ -21,6 +21,7 @@ import type { ListGroupTheme } from '../../molecules/ListGroup/ListGroup.theme'; import type { ModalTheme } from '../../molecules/Modal/Modal.theme'; import type { PaginationTheme } from '../../molecules/Pagination/Pagination.theme'; import type { PresentationTheme } from '../../molecules/Presentational/Presentational.theme'; +import type { StacksTheme } from '../../molecules/Stacks/Stack.theme'; import type { TabsTheme } from '../../molecules/Tab/Tabs.theme'; import type { CarouselTheme } from '../../organisms/Carousel/Carousel.theme'; import type { FooterTheme } from '../../organisms/Footer/Footer.theme'; @@ -56,6 +57,7 @@ export interface HelloInternetTheme extends Record { progress: ProgressTheme; mainContainer: MainContainerTheme; spinner: SpinnerTheme; + stacks: StacksTheme; tab: TabsTheme; toast: ToastTheme; tooltip: TooltipTheme; diff --git a/src/lib/components/molecules/Stacks/Stack.stories.tsx b/src/lib/components/molecules/Stacks/Stack.stories.tsx new file mode 100644 index 0000000..fc88402 --- /dev/null +++ b/src/lib/components/molecules/Stacks/Stack.stories.tsx @@ -0,0 +1,156 @@ +import type { Meta, Story } from '@storybook/react/types-6-0'; +import { Stack } from '.'; +import type { StackProps } from './Stack'; + +export default { + title: 'Components/molecules/Stack', + component: Stack +} as Meta; + +const Template: Story = (args) => ; + +const STACKS_DATA = [ + { + stackTitle: 'Category 1', + items: [ + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'No link' + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link (gray)', + link: 'https://snowpact.com/techno/gatsby', + grayscale: true + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link', + link: 'https://snowpact.com/techno/gatsby' + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link', + link: 'https://snowpact.com/techno/gatsby' + } + ] + }, + { + stackTitle: 'Category 2', + items: [ + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link', + link: 'https://snowpact.com/techno/gatsby' + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'No link (gray)', + grayscale: true + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'No link' + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link', + link: 'https://snowpact.com/techno/gatsby' + } + ] + }, + { + stackTitle: 'Category 3', + items: [ + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link', + link: 'https://snowpact.com/techno/gatsby' + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link', + link: 'https://snowpact.com/techno/gatsby' + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'Has link (gray)', + link: 'https://snowpact.com/techno/gatsby', + grayscale: true + }, + { + image: 'https://snowpact.com/static/bbfc78f3a6a4c94f955ebc166ba7a4d6/59649/stack-gatsby.png', + alt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a.', + title: 'No link' + } + ] + } +]; + +export const DefaultStack = Template.bind({}); +DefaultStack.storyName = 'Default'; +DefaultStack.args = { + children: ( + + {STACKS_DATA.map((stack, index) => ( + + {stack.stackTitle} + {stack.items.map((item, index) => ( + + + + ))} + + ))} + + ) +}; + +export const HorizontalStack = Template.bind({}); +HorizontalStack.storyName = 'With Horizontal Item Group'; +HorizontalStack.args = { + children: ( + + {STACKS_DATA.map((stack, index) => ( + + {stack.stackTitle} + {stack.items.map((item, index) => ( + + + + ))} + + ))} + + ) +}; + +export const WithLinks = Template.bind({}); +WithLinks.storyName = 'With horizontal stack'; +WithLinks.args = { + children: ( + + {STACKS_DATA.map((stack, index) => ( + + {stack.stackTitle} + {stack.items.map((item, index) => ( + + + + ))} + + ))} + + ) +}; diff --git a/src/lib/components/molecules/Stacks/Stack.theme.tsx b/src/lib/components/molecules/Stacks/Stack.theme.tsx new file mode 100644 index 0000000..2a8ee5a --- /dev/null +++ b/src/lib/components/molecules/Stacks/Stack.theme.tsx @@ -0,0 +1,79 @@ +export type StacksTheme = { + base: string; + horizontal: { + on: string; + off: string; + }; + stacksList: { + base: string; + horizontal: string; + }; + stackList: { + base: string; + horizontal: { + on: string; + off: string; + }; + }; + title: { + base: string; + horizontal: string; + text: string; + }; + stackItem: { + base: string; + horizontal: { + on: string; + off: string; + }; + text: string; + link: { + base: string; + withLink: string; + }; + }; + stackImage: { + base: string; + withGrayscale: string; + }; +}; + +export const STACKS_THEME: StacksTheme = { + base: 'mt-2 flex gap-4', + horizontal: { + on: 'flex-row', + off: 'max-w-[150px] flex-col text-center gap-4' + }, + stacksList: { + base: 'flex flex-wrap place-content-center gap-6 p-2', + horizontal: 'flex-col gap-6 items-center' + }, + stackList: { + base: 'flex p-2', + horizontal: { + on: 'flex-row items-center gap-4', + off: 'flex-col justify-center gap-4' + } + }, + title: { + base: 'my-2', + horizontal: 'sm:rotate-360 w-36 self-center', + text: 'text-sm font-semibold text-gray-500' + }, + stackItem: { + base: 'mt-2 flex gap-4', + horizontal: { + on: 'flex-row', + off: 'flex-col' + }, + text: 'flex-1 text-sm font-bold text-gray-500', + link: { + base: 'inline-block min-w-[120px] rounded-xl px-2 py-6 text-center shadow-lg', + withLink: 'duration-300 ease-in hover:shadow-xl' + } + }, + stackImage: { + base: 'mb-2 inline-block h-10 w-10 object-contain', + withGrayscale: 'opacity-50 grayscale' + } +}; diff --git a/src/lib/components/molecules/Stacks/Stack.tsx b/src/lib/components/molecules/Stacks/Stack.tsx new file mode 100644 index 0000000..6924d6f --- /dev/null +++ b/src/lib/components/molecules/Stacks/Stack.tsx @@ -0,0 +1,18 @@ +import classNames from 'classnames'; +import type { ComponentProps, FC, PropsWithChildren } from 'react'; +import { excludeClassName } from '../../../helpers/exclude'; +import { useTheme } from '../../bosons/HelloInternet/ThemeContext'; + +export interface StackProps extends PropsWithChildren, 'className'>> { + horizontal?: boolean; +} + +export const Stack: FC = ({ horizontal, children, ...props }): JSX.Element => { + const theirProps = excludeClassName(props); + const theme = useTheme().theme.stacks.stacksList; + return ( +
+ {children} +
+ ); +}; diff --git a/src/lib/components/molecules/Stacks/StackImage.tsx b/src/lib/components/molecules/Stacks/StackImage.tsx new file mode 100644 index 0000000..53b23e9 --- /dev/null +++ b/src/lib/components/molecules/Stacks/StackImage.tsx @@ -0,0 +1,23 @@ +import classNames from 'classnames'; +import type { ComponentProps, FC, PropsWithChildren } from 'react'; +import { useTheme } from '../../bosons/HelloInternet/ThemeContext'; + +export interface StackImageProps + extends PropsWithChildren, 'className'>> { + image: string; + alt: string; + grayscale?: boolean; +} + +export const StackImage: FC = ({ alt, image, grayscale }): JSX.Element => { + const theme = useTheme().theme.stacks.stackImage; + return ( + {alt} + ); +}; diff --git a/src/lib/components/molecules/Stacks/StackItem.tsx b/src/lib/components/molecules/Stacks/StackItem.tsx new file mode 100644 index 0000000..d31960a --- /dev/null +++ b/src/lib/components/molecules/Stacks/StackItem.tsx @@ -0,0 +1,23 @@ +import classNames from 'classnames'; +import type { ComponentProps, FC, PropsWithChildren } from 'react'; +import { useTheme } from '../../bosons/HelloInternet/ThemeContext'; + +export interface StackItemProps + extends PropsWithChildren, 'className'>> { + title: string; + link?: string; +} + +export const StackItem: FC = ({ link, children, title }): JSX.Element => { + const theme = useTheme().theme.stacks.stackItem; + return ( + +
+ {children} +

+ {title} +

+
+
+ ); +}; diff --git a/src/lib/components/molecules/Stacks/StackItemGroup.tsx b/src/lib/components/molecules/Stacks/StackItemGroup.tsx new file mode 100644 index 0000000..3574314 --- /dev/null +++ b/src/lib/components/molecules/Stacks/StackItemGroup.tsx @@ -0,0 +1,27 @@ +import classNames from 'classnames'; +import type { ComponentProps, FC, PropsWithChildren } from 'react'; + +import { excludeClassName } from '../../../helpers/exclude'; +import { useTheme } from '../../bosons/HelloInternet/ThemeContext'; +import { StackTitle } from './StackTitle'; + +export interface StackItemGroupProps extends PropsWithChildren, 'className'>> { + horizontal?: boolean; +} + +export const StackItemGroup: FC = ({ horizontal, children, ...props }): JSX.Element => { + const theirProps = excludeClassName(props); + + const theme = useTheme().theme.stacks; + return ( +
+ +
+ {children} +
+
+ ); +}; diff --git a/src/lib/components/molecules/Stacks/StackTitle.tsx b/src/lib/components/molecules/Stacks/StackTitle.tsx new file mode 100644 index 0000000..9c09554 --- /dev/null +++ b/src/lib/components/molecules/Stacks/StackTitle.tsx @@ -0,0 +1,17 @@ +import classNames from 'classnames'; +import type { ComponentProps, FC, PropsWithChildren } from 'react'; + +import { useTheme } from '../../bosons/HelloInternet/ThemeContext'; + +export interface StackTitleProps extends PropsWithChildren, 'className'>> { + horizontal?: boolean; +} + +export const StackTitle: FC = ({ horizontal, children }): JSX.Element => { + const theme = useTheme().theme.stacks.title; + return ( +
+

{children}

+
+ ); +}; diff --git a/src/lib/components/molecules/Stacks/index.ts b/src/lib/components/molecules/Stacks/index.ts new file mode 100644 index 0000000..7e189dd --- /dev/null +++ b/src/lib/components/molecules/Stacks/index.ts @@ -0,0 +1,18 @@ +import { Stack as StackComponent } from './Stack'; +import { StackImage as StackImageComponent } from './StackImage'; +import { StackItem as StackItemComponent } from './StackItem'; +import { StackItemGroup as StackItemGroupComponent } from './StackItemGroup'; +import { StackTitle as StackTitleComponent } from './StackTitle'; + +StackComponent.displayName = 'Stacks'; +StackItemComponent.displayName = 'Stacks.Item'; +StackItemGroupComponent.displayName = 'Stack.ItemGroup'; +StackTitleComponent.displayName = 'Stacks.Title'; +StackImageComponent.displayName = 'Stacks.Image'; + +export const Stack = Object.assign(StackComponent, { + Item: StackItemComponent, + ItemGroup: StackItemGroupComponent, + Title: StackTitleComponent, + Image: StackImageComponent +}); diff --git a/src/lib/theme/default.ts b/src/lib/theme/default.ts index fe9a5d0..93d65aa 100644 --- a/src/lib/theme/default.ts +++ b/src/lib/theme/default.ts @@ -21,6 +21,7 @@ import { LIST_GROUP_THEME } from '../components/molecules/ListGroup/ListGroup.th import { MODAL_THEME } from '../components/molecules/Modal/Modal.theme'; import { PAGINATION_THEME } from '../components/molecules/Pagination/Pagination.theme'; import { PRESENTATIONAL_THEME } from '../components/molecules/Presentational/Presentational.theme'; +import { STACKS_THEME } from '../components/molecules/Stacks/Stack.theme'; import { TABS_THEME } from '../components/molecules/Tab/Tabs.theme'; import { CAROUSEL_THEME } from '../components/organisms/Carousel/Carousel.theme'; import { FOOTER_THEME } from '../components/organisms/Footer/Footer.theme'; @@ -50,6 +51,7 @@ const theme: HelloInternetTheme = { pagination: PAGINATION_THEME, progressBar: PROGRESS_BAR_THEME, sidebar: SIDEBAR_THEME, + stacks: STACKS_THEME, progress: PROGRESS_THEME, presentational: PRESENTATIONAL_THEME, mainContainer: MAIN_CONTAINER_THEME, From a64f5d906eba8490f475fd34dfb24453734c42d2 Mon Sep 17 00:00:00 2001 From: farid Date: Thu, 13 Apr 2023 15:43:58 +0200 Subject: [PATCH 2/3] feat(#342): migrate stack component --- .../components/molecules/Stacks/Stack.theme.tsx | 4 ++-- .../components/molecules/Stacks/StackItem.tsx | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/lib/components/molecules/Stacks/Stack.theme.tsx b/src/lib/components/molecules/Stacks/Stack.theme.tsx index 2a8ee5a..a27e621 100644 --- a/src/lib/components/molecules/Stacks/Stack.theme.tsx +++ b/src/lib/components/molecules/Stacks/Stack.theme.tsx @@ -58,7 +58,7 @@ export const STACKS_THEME: StacksTheme = { title: { base: 'my-2', horizontal: 'sm:rotate-360 w-36 self-center', - text: 'text-sm font-semibold text-gray-500' + text: 'text-xl text-black' }, stackItem: { base: 'mt-2 flex gap-4', @@ -66,7 +66,7 @@ export const STACKS_THEME: StacksTheme = { on: 'flex-row', off: 'flex-col' }, - text: 'flex-1 text-sm font-bold text-gray-500', + text: 'flex-1 text-sm font-[520] text-black', link: { base: 'inline-block min-w-[120px] rounded-xl px-2 py-6 text-center shadow-lg', withLink: 'duration-300 ease-in hover:shadow-xl' diff --git a/src/lib/components/molecules/Stacks/StackItem.tsx b/src/lib/components/molecules/Stacks/StackItem.tsx index d31960a..94fba92 100644 --- a/src/lib/components/molecules/Stacks/StackItem.tsx +++ b/src/lib/components/molecules/Stacks/StackItem.tsx @@ -10,14 +10,15 @@ export interface StackItemProps export const StackItem: FC = ({ link, children, title }): JSX.Element => { const theme = useTheme().theme.stacks.stackItem; + + const Component = typeof link === 'undefined' ? 'div' : 'a'; + return ( - -
- {children} -

- {title} -

-
-
+ + {children} +

+ {title} +

+
); }; From ff0d800fc0de560548071d222673f8dc4e65ced9 Mon Sep 17 00:00:00 2001 From: farid Date: Fri, 14 Apr 2023 22:40:20 +0200 Subject: [PATCH 3/3] feat(#342): migrate stack component --- .../molecules/Stacks/Stack.stories.tsx | 19 +++++++-------- .../molecules/Stacks/Stack.theme.tsx | 18 +++++++-------- .../molecules/Stacks/StackImage.tsx | 23 ------------------- .../components/molecules/Stacks/StackItem.tsx | 13 +++++++++-- src/lib/components/molecules/Stacks/index.ts | 5 +--- 5 files changed, 31 insertions(+), 47 deletions(-) delete mode 100644 src/lib/components/molecules/Stacks/StackImage.tsx diff --git a/src/lib/components/molecules/Stacks/Stack.stories.tsx b/src/lib/components/molecules/Stacks/Stack.stories.tsx index fc88402..d7dd9e8 100644 --- a/src/lib/components/molecules/Stacks/Stack.stories.tsx +++ b/src/lib/components/molecules/Stacks/Stack.stories.tsx @@ -107,9 +107,7 @@ DefaultStack.args = { {stack.stackTitle} {stack.items.map((item, index) => ( - - - + ))} ))} @@ -126,9 +124,7 @@ HorizontalStack.args = { {stack.stackTitle} {stack.items.map((item, index) => ( - - - + ))} ))} @@ -145,9 +141,14 @@ WithLinks.args = { {stack.stackTitle} {stack.items.map((item, index) => ( - - - + ))} ))} diff --git a/src/lib/components/molecules/Stacks/Stack.theme.tsx b/src/lib/components/molecules/Stacks/Stack.theme.tsx index a27e621..bcf5236 100644 --- a/src/lib/components/molecules/Stacks/Stack.theme.tsx +++ b/src/lib/components/molecules/Stacks/Stack.theme.tsx @@ -31,10 +31,10 @@ export type StacksTheme = { base: string; withLink: string; }; - }; - stackImage: { - base: string; - withGrayscale: string; + stackImage: { + base: string; + withGrayscale: string; + }; }; }; @@ -68,12 +68,12 @@ export const STACKS_THEME: StacksTheme = { }, text: 'flex-1 text-sm font-[520] text-black', link: { - base: 'inline-block min-w-[120px] rounded-xl px-2 py-6 text-center shadow-lg', + base: 'inline-block min-w-[120px] rounded-xl px-2 py-6 text-center shadow-lg margin-auto', withLink: 'duration-300 ease-in hover:shadow-xl' + }, + stackImage: { + base: 'mb-2 inline-block h-10 w-10 object-contain', + withGrayscale: 'opacity-50 grayscale' } - }, - stackImage: { - base: 'mb-2 inline-block h-10 w-10 object-contain', - withGrayscale: 'opacity-50 grayscale' } }; diff --git a/src/lib/components/molecules/Stacks/StackImage.tsx b/src/lib/components/molecules/Stacks/StackImage.tsx deleted file mode 100644 index 53b23e9..0000000 --- a/src/lib/components/molecules/Stacks/StackImage.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import classNames from 'classnames'; -import type { ComponentProps, FC, PropsWithChildren } from 'react'; -import { useTheme } from '../../bosons/HelloInternet/ThemeContext'; - -export interface StackImageProps - extends PropsWithChildren, 'className'>> { - image: string; - alt: string; - grayscale?: boolean; -} - -export const StackImage: FC = ({ alt, image, grayscale }): JSX.Element => { - const theme = useTheme().theme.stacks.stackImage; - return ( - {alt} - ); -}; diff --git a/src/lib/components/molecules/Stacks/StackItem.tsx b/src/lib/components/molecules/Stacks/StackItem.tsx index 94fba92..7533b1e 100644 --- a/src/lib/components/molecules/Stacks/StackItem.tsx +++ b/src/lib/components/molecules/Stacks/StackItem.tsx @@ -5,17 +5,26 @@ import { useTheme } from '../../bosons/HelloInternet/ThemeContext'; export interface StackItemProps extends PropsWithChildren, 'className'>> { title: string; + image: string; + alt: string; + grayscale?: boolean; link?: string; } -export const StackItem: FC = ({ link, children, title }): JSX.Element => { +export const StackItem: FC = ({ link, title, alt, grayscale, image }): JSX.Element => { const theme = useTheme().theme.stacks.stackItem; const Component = typeof link === 'undefined' ? 'div' : 'a'; return ( - {children} + {alt}

{title}

diff --git a/src/lib/components/molecules/Stacks/index.ts b/src/lib/components/molecules/Stacks/index.ts index 7e189dd..d6178a6 100644 --- a/src/lib/components/molecules/Stacks/index.ts +++ b/src/lib/components/molecules/Stacks/index.ts @@ -1,5 +1,4 @@ import { Stack as StackComponent } from './Stack'; -import { StackImage as StackImageComponent } from './StackImage'; import { StackItem as StackItemComponent } from './StackItem'; import { StackItemGroup as StackItemGroupComponent } from './StackItemGroup'; import { StackTitle as StackTitleComponent } from './StackTitle'; @@ -8,11 +7,9 @@ StackComponent.displayName = 'Stacks'; StackItemComponent.displayName = 'Stacks.Item'; StackItemGroupComponent.displayName = 'Stack.ItemGroup'; StackTitleComponent.displayName = 'Stacks.Title'; -StackImageComponent.displayName = 'Stacks.Image'; export const Stack = Object.assign(StackComponent, { Item: StackItemComponent, ItemGroup: StackItemGroupComponent, - Title: StackTitleComponent, - Image: StackImageComponent + Title: StackTitleComponent });