From a5fd7a7ef702bc01d29d9607a6286d946db6b7e2 Mon Sep 17 00:00:00 2001 From: Thibault Barske Date: Thu, 16 Jan 2025 14:44:05 +0100 Subject: [PATCH] feat(manager-react-component): add manager tile component It's a duplicated of dashboard tile but with a Compound components pattern Signed-off-by: Thibault Barske --- .../manager-tile-item.component.tsx | 28 +++++ .../ManagerTile/manager-tile.component.tsx | 37 ++++++ .../ManagerTile/manager-tile.stories.tsx | 110 ++++++++++++++++++ .../content/ManagerTile/tile.spec.tsx | 40 +++++++ 4 files changed, 215 insertions(+) create mode 100644 packages/manager-react-components/src/components/content/ManagerTile/manager-tile-item.component.tsx create mode 100644 packages/manager-react-components/src/components/content/ManagerTile/manager-tile.component.tsx create mode 100644 packages/manager-react-components/src/components/content/ManagerTile/manager-tile.stories.tsx create mode 100644 packages/manager-react-components/src/components/content/ManagerTile/tile.spec.tsx diff --git a/packages/manager-react-components/src/components/content/ManagerTile/manager-tile-item.component.tsx b/packages/manager-react-components/src/components/content/ManagerTile/manager-tile-item.component.tsx new file mode 100644 index 000000000000..6fe9e0345718 --- /dev/null +++ b/packages/manager-react-components/src/components/content/ManagerTile/manager-tile-item.component.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +export type TileBlockProps = React.PropsWithChildren<{ + label?: string; +}>; + +export const ManagerTileItem = ({ children }: React.PropsWithChildren) => { + return
{children}
; +}; + +const ManagerTileItemLabel = ({ children }: React.PropsWithChildren) => { + return ( +
+ {children} +
+ ); +}; + +const ManagerTileItemDescription = ({ children }: React.PropsWithChildren) => { + return ( +
+ {children} +
+ ); +}; + +ManagerTileItem.Label = ManagerTileItemLabel; +ManagerTileItem.Description = ManagerTileItemDescription; diff --git a/packages/manager-react-components/src/components/content/ManagerTile/manager-tile.component.tsx b/packages/manager-react-components/src/components/content/ManagerTile/manager-tile.component.tsx new file mode 100644 index 000000000000..899ebd54f208 --- /dev/null +++ b/packages/manager-react-components/src/components/content/ManagerTile/manager-tile.component.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { OdsDivider, OdsCard } from '@ovhcloud/ods-components/react'; +import { ODS_CARD_COLOR } from '@ovhcloud/ods-components'; +import { ManagerTileItem } from './manager-tile-item.component'; + +export type ManagerTileProps = React.ComponentProps; + +export const ManagerTile = ({ + className, + children, + ...props +}: ManagerTileProps) => { + return ( + +
{children}
+
+ ); +}; + +type ManagerTileTitleProps = React.PropsWithChildren; +const ManagerTileTitle = ({ children }: ManagerTileTitleProps) => { + return ( +

+ {children} +

+ ); +}; + +const ManagerTileDivider = () => ; + +ManagerTile.Title = ManagerTileTitle; +ManagerTile.Item = ManagerTileItem; +ManagerTile.Divider = ManagerTileDivider; diff --git a/packages/manager-react-components/src/components/content/ManagerTile/manager-tile.stories.tsx b/packages/manager-react-components/src/components/content/ManagerTile/manager-tile.stories.tsx new file mode 100644 index 000000000000..63976ee487d2 --- /dev/null +++ b/packages/manager-react-components/src/components/content/ManagerTile/manager-tile.stories.tsx @@ -0,0 +1,110 @@ +import React, { useId } from 'react'; +import { Meta } from '@storybook/react'; +import { OdsSkeleton } from '@ovhcloud/ods-components/react'; +import { ManagerTile } from './manager-tile.component'; +import ActionMenu from '../../navigation/menus/action/action.component'; + +const actionItems = [ + { + id: 1, + href: 'https://ovhcloud.com', + label: 'Action 1', + }, + { + id: 2, + onClick: () => window.open('https://ovhcloud.com', '_blank', 'noopener'), + label: 'Action 2', + }, +]; + +export const CompleteExample = () => { + const id = useId(); + return ( + + Complete example + + + Component Example + + Test + + + + + Loading + + + + + + + Text Directly + + Text example + + + + + Menu Example + + +
+
Test value
+ +
+
+
+
+ + + Component Example + + Test + + +
+ ); +}; + +export const SimpleExampleWithTitle = () => ( + + Sample example with title + + + Component Example + Test + + + + Loading + + + + + +); + +export const NoTitle = () => ( + + + Component Example + Test + + + + Loading + + + + + +); + +const meta: Meta = { + title: 'Content/Manager Tile', + component: ManagerTile, + argTypes: {}, + args: {}, +}; + +export default meta; diff --git a/packages/manager-react-components/src/components/content/ManagerTile/tile.spec.tsx b/packages/manager-react-components/src/components/content/ManagerTile/tile.spec.tsx new file mode 100644 index 000000000000..e5b39751f62b --- /dev/null +++ b/packages/manager-react-components/src/components/content/ManagerTile/tile.spec.tsx @@ -0,0 +1,40 @@ +import { waitFor, screen } from '@testing-library/react'; + +const testItem = { + id: 'id', + label: 'label', + value: 'value', +}; + +describe.skip('Dashboard Tile component', () => { + it('renders correctly', async () => { + await waitFor(() => { + expect(screen.getByText('Title')).toBeInTheDocument(); + expect(screen.getByText(testItem.value)).toBeInTheDocument(); + expect(screen.getByText(testItem.label)).toBeInTheDocument(); + expect(screen.queryByText(testItem.id)).not.toBeInTheDocument(); + }); + }); + + it('renders correctly without items', async () => { + await waitFor(() => { + expect(screen.getByText('Title 2')).toBeInTheDocument(); + }); + }); + + it('renders correctly without title', async () => { + await waitFor(() => { + expect(screen.getByText(testItem.value)).toBeInTheDocument(); + expect(screen.getByText(testItem.label)).toBeInTheDocument(); + expect(screen.queryByText(testItem.id)).not.toBeInTheDocument(); + }); + }); + + it('renders correctly without label', async () => { + await waitFor(() => { + expect(screen.getByText(testItem.value)).toBeInTheDocument(); + expect(screen.queryByText(testItem.label)).not.toBeInTheDocument(); + expect(screen.queryByText(testItem.id)).not.toBeInTheDocument(); + }); + }); +});