From 64ec6f5db804319cad54a57ace18ba7ca4df1a6c Mon Sep 17 00:00:00 2001 From: joannasikora Date: Tue, 21 Jan 2025 12:21:12 +0100 Subject: [PATCH 01/13] feat(EmptyState): add base EmptyState component --- .../src/components/EmptyState/EmptyState.mdx | 33 ++++ .../EmptyState/EmptyState.stories.tsx | 141 ++++++++++++++++++ .../src/components/EmptyState/EmptyState.tsx | 40 +++++ .../src/components/EmptyState/index.ts | 2 + .../src/components/EmptyState/types.ts | 17 +++ packages/react-components/src/index.ts | 1 + 6 files changed, 234 insertions(+) create mode 100644 packages/react-components/src/components/EmptyState/EmptyState.mdx create mode 100644 packages/react-components/src/components/EmptyState/EmptyState.stories.tsx create mode 100644 packages/react-components/src/components/EmptyState/EmptyState.tsx create mode 100644 packages/react-components/src/components/EmptyState/index.ts create mode 100644 packages/react-components/src/components/EmptyState/types.ts diff --git a/packages/react-components/src/components/EmptyState/EmptyState.mdx b/packages/react-components/src/components/EmptyState/EmptyState.mdx new file mode 100644 index 000000000..627eed529 --- /dev/null +++ b/packages/react-components/src/components/EmptyState/EmptyState.mdx @@ -0,0 +1,33 @@ +import { Canvas, Controls, Meta, Title } from '@storybook/blocks'; + +import * as EmptyStateStories from './EmptyState.stories'; + + + +EmptyState + +[Intro](#Intro) | [Component API](#ComponentAPI) | [Content Spec](#ContentSpec) + +## Intro + + + +#### Example implementation + +```jsx + +``` + +## Component API + + + +## Content Spec + + + Go to Figma documentation + diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx new file mode 100644 index 000000000..9162a7aa6 --- /dev/null +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -0,0 +1,141 @@ +import { ReactElement } from 'react'; + +import { Info as InfoIcon } from '@livechat/design-system-icons'; + +import { Button } from '../Button'; +import { Icon } from '../Icon'; +import { Text } from '../Typography'; + +import { EmptyState } from './EmptyState'; +import { IEmptyStateProps } from './types'; + +export default { + title: 'Components/EmptyState', + component: EmptyState, +}; + +export const Default = (args: IEmptyStateProps): ReactElement => { + return ; +}; + +export const Inline = (args: IEmptyStateProps): ReactElement => { + return ( +
+ +
+ ); +}; + +export const WithIcon = (args: IEmptyStateProps): ReactElement => { + return ; +}; + +export const WithCustomContentAndNoIllustration = ( + args: IEmptyStateProps +): ReactElement => { + return ; +}; + +export const WithoutActionsOnlyDescription = ( + args: IEmptyStateProps +): ReactElement => { + return ; +}; + +Default.args = { + image: 'https://placehold.co/600x400', + title: 'No data', + description: 'There is no data to display', + actions: ( + <> + + + + + + ), + type: 'full', +}; + +WithIcon.args = { + icon: InfoIcon, + title: 'No data', + description: 'There is no data to display', + actions: ( + <> + + + + ), + type: 'full', +}; + +Inline.args = { + icon: InfoIcon, + title: 'No data', + type: 'inline', + actions: ( + <> + + + ), +}; + +WithCustomContentAndNoIllustration.args = { + title: 'No data', + description: 'There is no data to display', + type: 'full', + actions: ( +
+
+
+ Custom content +
+
+ Custom content +
+
+ + +
+ ), +}; + +WithoutActionsOnlyDescription.args = { + icon: InfoIcon, + title: 'No data', + description: ( + + There is no data to display{' '} + + + ), + type: 'full', +}; diff --git a/packages/react-components/src/components/EmptyState/EmptyState.tsx b/packages/react-components/src/components/EmptyState/EmptyState.tsx new file mode 100644 index 000000000..0a673eda8 --- /dev/null +++ b/packages/react-components/src/components/EmptyState/EmptyState.tsx @@ -0,0 +1,40 @@ +import { Icon } from '../Icon'; +import { Heading, Text } from '../Typography'; + +import { IEmptyStateProps } from './types'; + +export const EmptyState = (props: IEmptyStateProps) => { + return ( +
+ {props.image && {props.title}} + {props.type === 'inline' ? ( +
+ {props.icon && } + {props.title} +
+ ) : ( + <> + {props.icon && } + {props.title} + + )} + +
+ {props.type === 'full' && props.description && ( +
{props.description}
+ )} +
+ {props.actions && ( +
{props.actions}
+ )} +
+ ); +}; diff --git a/packages/react-components/src/components/EmptyState/index.ts b/packages/react-components/src/components/EmptyState/index.ts new file mode 100644 index 000000000..c1e6e511c --- /dev/null +++ b/packages/react-components/src/components/EmptyState/index.ts @@ -0,0 +1,2 @@ +export { EmptyState } from './EmptyState'; +export type { IEmptyStateProps } from './types'; diff --git a/packages/react-components/src/components/EmptyState/types.ts b/packages/react-components/src/components/EmptyState/types.ts new file mode 100644 index 000000000..c1d23b3b9 --- /dev/null +++ b/packages/react-components/src/components/EmptyState/types.ts @@ -0,0 +1,17 @@ +import { ReactNode } from 'react'; + +import { IconSource } from 'components/Icon'; + +export type IEmptyStateProps = ( + | { + type?: 'full' | undefined; + description?: string | ReactNode; + } + | { + type: 'inline'; + description?: never; + } +) & { + title: string; + actions?: ReactNode; +} & ({ image: string; icon?: never } | { image?: never; icon: IconSource }); diff --git a/packages/react-components/src/index.ts b/packages/react-components/src/index.ts index 5f1a659ec..d2173d4ea 100644 --- a/packages/react-components/src/index.ts +++ b/packages/react-components/src/index.ts @@ -21,6 +21,7 @@ export * from './components/DatePicker'; export * from './components/DetailsCard'; export * from './components/DetailsCardInfo'; export * from './components/FieldDescription'; +export * from './components/EmptyState'; export * from './components/FieldError'; export * from './components/FieldGroup'; export * from './components/Form'; From 91aff55a3d2360f667b51231b4064833d93c1eb7 Mon Sep 17 00:00:00 2001 From: joannasikora Date: Tue, 21 Jan 2025 12:37:36 +0100 Subject: [PATCH 02/13] feat(EmptyState): update button text --- .../src/components/EmptyState/EmptyState.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx index 9162a7aa6..df3d8c5c5 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -123,7 +123,7 @@ WithCustomContentAndNoIllustration.args = { - + ), }; From c1cb2b4e461d498599beedffe8a2cc0d1f8088bf Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 11:48:35 +0100 Subject: [PATCH 03/13] feat(EmptyState): updated component with styles and examples in stpries --- .../src/components/EmptyState/EmptyState.mdx | 11 +- .../EmptyState/EmptyState.module.scss | 66 +++++ .../components/EmptyState/EmptyState.spec.tsx | 50 ++++ .../EmptyState/EmptyState.stories.module.scss | 42 +++ .../EmptyState/EmptyState.stories.tsx | 247 ++++++++++-------- .../src/components/EmptyState/EmptyState.tsx | 76 ++++-- .../src/components/EmptyState/types.ts | 10 +- 7 files changed, 358 insertions(+), 144 deletions(-) create mode 100644 packages/react-components/src/components/EmptyState/EmptyState.module.scss create mode 100644 packages/react-components/src/components/EmptyState/EmptyState.spec.tsx create mode 100644 packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss diff --git a/packages/react-components/src/components/EmptyState/EmptyState.mdx b/packages/react-components/src/components/EmptyState/EmptyState.mdx index 627eed529..e67304a93 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.mdx +++ b/packages/react-components/src/components/EmptyState/EmptyState.mdx @@ -10,12 +10,21 @@ import * as EmptyStateStories from './EmptyState.stories'; ## Intro +The Empty State component is used to display a placeholder when there is no content to show in a container or page. +It helps communicate to users why content is missing and what actions they can take, + providing a better user experience than showing a blank space. + #### Example implementation ```jsx - +Go to settings} +/> ``` ## Component API diff --git a/packages/react-components/src/components/EmptyState/EmptyState.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.module.scss new file mode 100644 index 000000000..d107874f5 --- /dev/null +++ b/packages/react-components/src/components/EmptyState/EmptyState.module.scss @@ -0,0 +1,66 @@ +$base-class: 'empty-state'; + +.#{$base-class} { + display: flex; + align-items: center; + + &--inline { + flex-direction: row; + justify-content: space-between; + } + + &--full { + flex-direction: column; + justify-content: center; + padding: var(--spacing-6); + } + + &__image { + margin-bottom: var(--spacing-6); + width: auto; + max-width: 100%; + height: auto; + } + + &__icon { + &--full { + margin-bottom: var(--spacing-2); + } + } + + &__description { + max-width: 600px; + text-align: center; + } + + &__content-inline { + display: flex; + gap: var(--spacing-2); + align-items: center; + } + + &__title { + margin: 0; + margin-bottom: var(--spacing-2); + text-align: center; + } + + &__actions { + display: flex; + gap: var(--spacing-2); + margin-top: var(--spacing-4); + + &--inline { + margin-top: 0; + } + + @media (width <= 600px) { + flex-direction: column; + margin-top: var(--spacing-2); + + &--inline { + margin-top: 0; + } + } + } +} diff --git a/packages/react-components/src/components/EmptyState/EmptyState.spec.tsx b/packages/react-components/src/components/EmptyState/EmptyState.spec.tsx new file mode 100644 index 000000000..fc1d8403c --- /dev/null +++ b/packages/react-components/src/components/EmptyState/EmptyState.spec.tsx @@ -0,0 +1,50 @@ +import { Info as InfoIcon } from '@livechat/design-system-icons'; + +import { render } from 'test-utils'; + +import { Button } from '../Button'; +import { Icon } from '../Icon'; + +import { EmptyState } from './EmptyState'; +import { IEmptyStateProps } from './types'; + +const renderComponent = (props: IEmptyStateProps) => { + return render(); +}; + +describe(' component', () => { + it('should render with image', () => { + const { getByAltText } = renderComponent({ + title: 'Test title', + description: 'Test description', + image: 'test-image.jpg', + }); + + const image = getByAltText('Test title'); + + expect(image).toBeVisible(); + expect(image).toHaveAttribute('src', 'test-image.jpg'); + }); + + it('should render actions when provided', () => { + const { getByText } = renderComponent({ + title: 'Test title', + description: 'Test description', + actions: , + }); + + expect(getByText('Test action')).toBeVisible(); + }); + + it('should render with icon', () => { + const { getByTestId } = renderComponent({ + title: 'Test title', + description: 'Test description', + icon: , + }); + + const icon = getByTestId('icon'); + + expect(icon).toBeVisible(); + }); +}); diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss new file mode 100644 index 000000000..92e774f69 --- /dev/null +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss @@ -0,0 +1,42 @@ +.empty-state-story { + &--centered { + display: flex; + justify-content: center; + height: 100vh; + } + + &__custom-content { + display: flex; + flex-direction: column; + gap: var(--spacing-2); + align-items: center; + + &__row { + display: flex; + gap: var(--spacing-2); + } + + &__box { + border-radius: 8px; + background-color: var(--surface-secondary-default); + padding: var(--spacing-6); + width: 220px; + } + } + + &__icon { + svg { + width: 40px; + height: 40px; + color: var(--content-basic-disabled); + } + } + + &__action-menu { + width: 200px; + + &__item { + width: 400px; + } + } +} diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx index df3d8c5c5..dd2dfefeb 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -1,141 +1,160 @@ -import { ReactElement } from 'react'; - -import { Info as InfoIcon } from '@livechat/design-system-icons'; +import { + Info as InfoIcon, + FacebookColored as FacebookIcon, + GoogleLightModeColored as GoogleIcon, + MoreHoriz, +} from '@livechat/design-system-icons'; +import { Meta, StoryObj } from '@storybook/react'; +import { ActionMenu } from '../ActionMenu'; import { Button } from '../Button'; import { Icon } from '../Icon'; +import { ListItem } from '../ListItem'; import { Text } from '../Typography'; import { EmptyState } from './EmptyState'; -import { IEmptyStateProps } from './types'; + +import styles from './EmptyState.stories.module.scss'; export default { title: 'Components/EmptyState', component: EmptyState, -}; - -export const Default = (args: IEmptyStateProps): ReactElement => { - return ; -}; - -export const Inline = (args: IEmptyStateProps): ReactElement => { - return ( -
- -
- ); -}; +} as Meta; -export const WithIcon = (args: IEmptyStateProps): ReactElement => { - return ; -}; +type Story = StoryObj; -export const WithCustomContentAndNoIllustration = ( - args: IEmptyStateProps -): ReactElement => { - return ; +export const Default: Story = { + args: { + image: 'https://placehold.co/600x400', + title: 'No data', + description: 'There is no data to display', + actions: ( + <> + + + + + + ), + }, }; -export const WithoutActionsOnlyDescription = ( - args: IEmptyStateProps -): ReactElement => { - return ; +export const Inline: Story = { + decorators: [ + (Story) => ( +
+ + + + +
+ ), + }, + ]} + triggerRenderer={ + , + }, }; -Default.args = { - image: 'https://placehold.co/600x400', - title: 'No data', - description: 'There is no data to display', - actions: ( - <> - - - - - - ), - type: 'full', +export const WithIcon: Story = { + args: { + icon: ( + + ), + title: 'No data', + description: 'There is no data to display', + actions: ( + <> + + + + ), + }, }; -WithIcon.args = { - icon: InfoIcon, - title: 'No data', - description: 'There is no data to display', - actions: ( - <> - - - - ), - type: 'full', +export const Centered: Story = { + args: { + icon: ( + + ), + title: 'No data', + description: 'There is no data to display', + actions: ( + <> + + + + ), + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], }; -Inline.args = { - icon: InfoIcon, - title: 'No data', - type: 'inline', - actions: ( - <> - - - ), +export const SmallImage: Story = { + args: { + image: 'https://placehold.co/250x200', + title: 'All tickets solved', + description: 'Follow the instruction to start working with tickets', + }, }; -WithCustomContentAndNoIllustration.args = { - title: 'No data', - description: 'There is no data to display', - type: 'full', - actions: ( -
-
-
- Custom content -
-
- Custom content +export const WithCustomContentAndNoIllustration: Story = { + args: { + title: 'Title up to 50 characters', + description: + 'A description with a maximum of 100 characters. That usually means only one or two sentences.', + actions: ( +
+
+
+ + Facebook Messanger +
+
+ + Google Messages +
+
- - -
- ), + ), + }, }; -WithoutActionsOnlyDescription.args = { - icon: InfoIcon, - title: 'No data', - description: ( - - There is no data to display{' '} - - - ), - type: 'full', +export const WithoutActionsOnlyDescription: Story = { + args: { + icon: ( + + ), + title: 'No data', + description: ( + + There is no data to display{' '} + + + ), + }, }; diff --git a/packages/react-components/src/components/EmptyState/EmptyState.tsx b/packages/react-components/src/components/EmptyState/EmptyState.tsx index 0a673eda8..56ff8ee51 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.tsx @@ -1,39 +1,65 @@ -import { Icon } from '../Icon'; -import { Heading, Text } from '../Typography'; +import cx from 'clsx'; + +import { Display, Heading, Text } from '../Typography'; import { IEmptyStateProps } from './types'; -export const EmptyState = (props: IEmptyStateProps) => { +import styles from './EmptyState.module.scss'; + +const baseClass = 'empty-state'; + +export const EmptyState = ({ + type = 'full', + image, + icon, + title, + description, + actions, +}: IEmptyStateProps) => { return ( -
- {props.image && {props.title}} - {props.type === 'inline' ? ( -
- {props.icon && } - {props.title} +
+ {image && ( + {title} + )} + {type === 'inline' ? ( +
+ {icon && {icon}} + {title}
) : ( <> - {props.icon && } - {props.title} + {icon && ( + + {icon} + + )} + {title} )} -
- {props.type === 'full' && props.description && ( -
{props.description}
+ <> + {type === 'full' && description && ( + + {description} + )} -
- {props.actions && ( -
{props.actions}
+ + {actions && ( +
+ {actions} +
)}
); diff --git a/packages/react-components/src/components/EmptyState/types.ts b/packages/react-components/src/components/EmptyState/types.ts index c1d23b3b9..73a678027 100644 --- a/packages/react-components/src/components/EmptyState/types.ts +++ b/packages/react-components/src/components/EmptyState/types.ts @@ -1,10 +1,8 @@ import { ReactNode } from 'react'; -import { IconSource } from 'components/Icon'; - export type IEmptyStateProps = ( | { - type?: 'full' | undefined; + type?: 'full'; description?: string | ReactNode; } | { @@ -14,4 +12,8 @@ export type IEmptyStateProps = ( ) & { title: string; actions?: ReactNode; -} & ({ image: string; icon?: never } | { image?: never; icon: IconSource }); +} & ( + | { image?: string; icon?: never } + | { image?: never; icon?: ReactNode } + | { image?: never; icon?: never } + ); From b415bb5ae99ba0b9d685158859ce2299a1722ab9 Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 12:08:26 +0100 Subject: [PATCH 04/13] feat(EmptyState): add border-radius to styles and update placeholder image size in stories --- .../src/components/EmptyState/EmptyState.module.scss | 1 + .../src/components/EmptyState/EmptyState.stories.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.module.scss index d107874f5..205aaafa6 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.module.scss @@ -17,6 +17,7 @@ $base-class: 'empty-state'; &__image { margin-bottom: var(--spacing-6); + border-radius: var(--radius-4); width: auto; max-width: 100%; height: auto; diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx index dd2dfefeb..c2526b6e0 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -25,7 +25,7 @@ type Story = StoryObj; export const Default: Story = { args: { - image: 'https://placehold.co/600x400', + image: 'https://placehold.co/600x300', title: 'No data', description: 'There is no data to display', actions: ( From a3e8728330126822c64d58a3377ed08827800b86 Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 12:11:50 +0100 Subject: [PATCH 05/13] fix(EmptyState): adjust story styles --- .../components/EmptyState/EmptyState.stories.module.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss index 92e774f69..71739fb5d 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss @@ -14,6 +14,10 @@ &__row { display: flex; gap: var(--spacing-2); + + @media (width <= 600px) { + flex-direction: column; + } } &__box { @@ -22,6 +26,10 @@ padding: var(--spacing-6); width: 220px; } + + @media (width <= 600px) { + flex-direction: column; + } } &__icon { From 7ba6653c7146a3a593ba82806140b9ab057402f0 Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 12:36:54 +0100 Subject: [PATCH 06/13] fix(EmptyState): fix spacing --- .../src/components/EmptyState/EmptyState.module.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.module.scss index 205aaafa6..77d29b64f 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.module.scss @@ -12,7 +12,11 @@ $base-class: 'empty-state'; &--full { flex-direction: column; justify-content: center; - padding: var(--spacing-6); + padding: var(--spacing-16) var(--spacing-6); + + @media (width <= 600px) { + padding: var(--spacing-8) var(--spacing-6); + } } &__image { From 8ce8b464da39db61a4ac9bf1f27518755729480f Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 12:59:24 +0100 Subject: [PATCH 07/13] feat(EmptyState): add centered alignment option and update styles in stories --- .../src/components/EmptyState/EmptyState.module.scss | 6 ++++++ .../components/EmptyState/EmptyState.stories.module.scss | 2 -- .../src/components/EmptyState/EmptyState.stories.tsx | 1 + .../src/components/EmptyState/EmptyState.tsx | 9 ++++++++- .../react-components/src/components/EmptyState/types.ts | 2 ++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.module.scss index 77d29b64f..af34ac30f 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.module.scss @@ -4,6 +4,12 @@ $base-class: 'empty-state'; display: flex; align-items: center; + &--centered { + justify-content: center; + width: 100%; + height: 100%; + } + &--inline { flex-direction: row; justify-content: space-between; diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss index 71739fb5d..df3ecdb84 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.module.scss @@ -1,7 +1,5 @@ .empty-state-story { &--centered { - display: flex; - justify-content: center; height: 100vh; } diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx index c2526b6e0..3daebaf10 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -92,6 +92,7 @@ export const WithIcon: Story = { export const Centered: Story = { args: { + centered: true, icon: ( ), diff --git a/packages/react-components/src/components/EmptyState/EmptyState.tsx b/packages/react-components/src/components/EmptyState/EmptyState.tsx index 56ff8ee51..f6b106bd2 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.tsx @@ -15,9 +15,16 @@ export const EmptyState = ({ title, description, actions, + centered = false, }: IEmptyStateProps) => { return ( -
+
{image && ( Date: Wed, 22 Jan 2025 13:07:01 +0100 Subject: [PATCH 08/13] style(EmptyState): add max-width to improve layout responsiveness --- .../src/components/EmptyState/EmptyState.module.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.module.scss index af34ac30f..9e201494f 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.module.scss @@ -53,6 +53,7 @@ $base-class: 'empty-state'; &__title { margin: 0; margin-bottom: var(--spacing-2); + max-width: 600px; text-align: center; } From c6b6e265a6513dd7a506040dc8a360750b5b9c48 Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 13:08:44 +0100 Subject: [PATCH 09/13] feat(EmptyState): exclude 'description' and 'image' controls in story parameters --- .../src/components/EmptyState/EmptyState.stories.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx index 3daebaf10..fe3f09920 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -72,6 +72,11 @@ export const Inline: Story = { type: 'inline', actions: , }, + parameters: { + controls: { + exclude: ['description', 'image'], + }, + }, }; export const WithIcon: Story = { From 7f8d86a37dcad224ef15857b0016c757c700eaf7 Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 13:19:01 +0100 Subject: [PATCH 10/13] refactor(EmptyState): remove redundant fragment --- .../src/components/EmptyState/EmptyState.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.tsx b/packages/react-components/src/components/EmptyState/EmptyState.tsx index f6b106bd2..63b52bf03 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.tsx @@ -51,13 +51,11 @@ export const EmptyState = ({ )} - <> - {type === 'full' && description && ( - - {description} - - )} - + {type === 'full' && description && ( + + {description} + + )} {actions && (
Date: Mon, 20 Jan 2025 13:55:21 +0100 Subject: [PATCH 11/13] feat(EmptyState): fix coderabbit nitpicks --- .../EmptyState/EmptyState.stories.tsx | 2 +- .../src/components/EmptyState/types.ts | 45 +++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx index fe3f09920..00a0671f2 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -137,7 +137,7 @@ export const WithCustomContentAndNoIllustration: Story = {
- Facebook Messanger + Facebook Messenger
diff --git a/packages/react-components/src/components/EmptyState/types.ts b/packages/react-components/src/components/EmptyState/types.ts index b806eae1d..89811babe 100644 --- a/packages/react-components/src/components/EmptyState/types.ts +++ b/packages/react-components/src/components/EmptyState/types.ts @@ -2,20 +2,59 @@ import { ReactNode } from 'react'; export type IEmptyStateProps = ( | { + /** + * Specify the empty state type + */ type?: 'full'; + /** + * The empty state description text or element + */ description?: string | ReactNode; } | { + /** + * Specify the empty state type + */ type: 'inline'; + /** + * Description is not available in inline type + */ description?: never; + /** + * Image is not available in inline type + */ image?: never; } ) & { + /** + * The empty state title + */ title: string; + /** + * Optional actions to be displayed + */ actions?: ReactNode; + /** + * Set to center the content + */ centered?: boolean; } & ( - | { image?: string; icon?: never } - | { image?: never; icon?: ReactNode } - | { image?: never; icon?: never } + | { + /** + * The URL of the empty state image + */ + image?: string; + icon?: never; + } + | { + image?: never; + /** + * The icon element to be displayed + */ + icon?: ReactNode; + } + | { + image?: never; + icon?: never; + } ); From c4882fb2cf5f7ce32f7e7ad4c9f1b4f17a653470 Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 14:46:53 +0100 Subject: [PATCH 12/13] feat(EmptyState): enhance image handling with max dimensions --- .../src/components/EmptyState/EmptyState.module.scss | 4 +++- .../src/components/EmptyState/EmptyState.stories.tsx | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.module.scss index 9e201494f..d25a1c352 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.module.scss @@ -29,8 +29,10 @@ $base-class: 'empty-state'; margin-bottom: var(--spacing-6); border-radius: var(--radius-4); width: auto; - max-width: 100%; + max-width: 600px; height: auto; + max-height: 300px; + object-fit: contain; } &__icon { diff --git a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx index 00a0671f2..fa9e871c9 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx +++ b/packages/react-components/src/components/EmptyState/EmptyState.stories.tsx @@ -127,6 +127,14 @@ export const SmallImage: Story = { }, }; +export const VeryBigImage: Story = { + args: { + image: 'https://placehold.co/800x300', + title: 'All tickets solved', + description: 'Follow the instruction to start working with tickets', + }, +}; + export const WithCustomContentAndNoIllustration: Story = { args: { title: 'Title up to 50 characters', From 1e67f5c77b8c9dbe48fe2051982117ae18bcf15c Mon Sep 17 00:00:00 2001 From: joannasikora Date: Wed, 22 Jan 2025 15:28:52 +0100 Subject: [PATCH 13/13] style(EmptyState): update max-width and max-height for improved responsiveness --- .../src/components/EmptyState/EmptyState.module.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-components/src/components/EmptyState/EmptyState.module.scss b/packages/react-components/src/components/EmptyState/EmptyState.module.scss index d25a1c352..c9118185d 100644 --- a/packages/react-components/src/components/EmptyState/EmptyState.module.scss +++ b/packages/react-components/src/components/EmptyState/EmptyState.module.scss @@ -29,9 +29,9 @@ $base-class: 'empty-state'; margin-bottom: var(--spacing-6); border-radius: var(--radius-4); width: auto; - max-width: 600px; + max-width: min(100%, 600px); height: auto; - max-height: 300px; + max-height: min(100%, 300px); object-fit: contain; }