From 74ef6574a0c50bb3e5b08e68f8739f14238ba78e Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 28 Nov 2024 12:22:47 +0100 Subject: [PATCH] feat: Service catalog card and icon (#666) --- src/components/AppIcon.tsx | 4 +- src/components/CatalogCard.tsx | 145 +++++++++++++++++++++++++++ src/components/ChipList.tsx | 6 +- src/components/icons/CatalogIcon.tsx | 44 ++++++++ src/icons.ts | 1 + src/index.ts | 1 + src/stories/CatlogCard.stories.tsx | 64 ++++++++++++ 7 files changed, 261 insertions(+), 4 deletions(-) create mode 100644 src/components/CatalogCard.tsx create mode 100644 src/components/icons/CatalogIcon.tsx create mode 100644 src/stories/CatlogCard.stories.tsx diff --git a/src/components/AppIcon.tsx b/src/components/AppIcon.tsx index e7e86aee..f1d279f3 100644 --- a/src/components/AppIcon.tsx +++ b/src/components/AppIcon.tsx @@ -52,7 +52,7 @@ const parentFillLevelToHue = { } as const satisfies Record const sizeToWidth = { - xxsmall: 32, + xxsmall: 36, xsmall: 48, small: 64, medium: 96, @@ -61,7 +61,7 @@ const sizeToWidth = { } as const satisfies Record const sizeToIconWidth = { - xxsmall: 16, + xxsmall: 20, xsmall: 32, small: 48, medium: 64, diff --git a/src/components/CatalogCard.tsx b/src/components/CatalogCard.tsx new file mode 100644 index 00000000..9cdf70b8 --- /dev/null +++ b/src/components/CatalogCard.tsx @@ -0,0 +1,145 @@ +import { type Ref, forwardRef } from 'react' +import { useTheme } from 'styled-components' + +import { PrQueueIcon } from '../icons' + +import Chip from './Chip' +import Card, { type CardProps } from './Card' +import AppIcon from './AppIcon' +import ChipList from './ChipList' +import Flex from './Flex' + +type CatalogCardProps = CardProps & { + name?: string + author?: string + category?: string + description?: string + imageUrl?: string + tags?: string[] +} + +function CatalogCardRef( + { + name, + author, + category, + description, + imageUrl, + tags = [], + ...props + }: CatalogCardProps, + ref: Ref +) { + const theme = useTheme() + + return ( + + + + + } + /> + + +
+ {name} +
+
+ by {author} +
+
+
+
+ {description && ( +

+ {description} +

+ )} +
+ {(category || tags?.length > 0) && ( + + {!!category && ( + + {category} + + )} + + + )} + + + + ) +} + +const CatalogCard = forwardRef(CatalogCardRef) + +export default CatalogCard diff --git a/src/components/ChipList.tsx b/src/components/ChipList.tsx index e4e8defc..7a19e34e 100644 --- a/src/components/ChipList.tsx +++ b/src/components/ChipList.tsx @@ -1,4 +1,4 @@ -import { Flex, Span } from 'honorable' +import { Flex, type FlexBaseProps, Span } from 'honorable' import isEmpty from 'lodash-es/isEmpty' import { type ComponentProps, @@ -19,6 +19,7 @@ export type ChipListProps = { values: TValue[] transformValue?: TransformFn limit: number + wrap?: Pick emptyState?: JSX.Element | null onClickCondition?: (value: TValue) => boolean onClick?: Dispatch @@ -28,6 +29,7 @@ function ChipList({ values = [], transformValue, limit = 4, + wrap = 'wrap', emptyState, onClickCondition, onClick, @@ -38,7 +40,7 @@ function ChipList({ return ( {isEmpty(values) && (emptyState !== undefined ? ( diff --git a/src/components/icons/CatalogIcon.tsx b/src/components/icons/CatalogIcon.tsx new file mode 100644 index 00000000..57f3239a --- /dev/null +++ b/src/components/icons/CatalogIcon.tsx @@ -0,0 +1,44 @@ +import createIcon from './createIcon' + +export default createIcon(({ size, color }) => ( + + + + + + + +)) diff --git a/src/icons.ts b/src/icons.ts index 42b392dd..1dcc7758 100644 --- a/src/icons.ts +++ b/src/icons.ts @@ -9,6 +9,7 @@ export { default as ArchitectureIcon } from './components/icons/ArchitectureIcon export { default as ArrowLeftIcon } from './components/icons/ArrowLeftIcon' export { default as ArrowRightIcon } from './components/icons/ArrowRightIcon' export { default as ArrowRightLeftIcon } from './components/icons/ArrowRightLeftIcon' +export { default as CatalogIcon } from './components/icons/CatalogIcon' export { default as ArrowTopRightIcon } from './components/icons/ArrowTopRightIcon' export { default as AwsLogoIcon } from './components/icons/AwsLogoIcon' export { default as AzureLogoIcon } from './components/icons/AzureLogoIcon' diff --git a/src/index.ts b/src/index.ts index 6900eec1..fd61fb75 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,6 +17,7 @@ export type { CardProps } from './components/Card' export { default as Card } from './components/Card' export type { CalloutProps } from './components/Callout' export { default as Callout } from './components/Callout' +export { default as CatalogCard } from './components/CatalogCard' export { default as Checkbox } from './components/Checkbox' export { default as Chip, type ChipProps } from './components/Chip' export { default as ChipList } from './components/ChipList' diff --git a/src/stories/CatlogCard.stories.tsx b/src/stories/CatlogCard.stories.tsx new file mode 100644 index 00000000..158d1eae --- /dev/null +++ b/src/stories/CatlogCard.stories.tsx @@ -0,0 +1,64 @@ +import { Div } from 'honorable' + +import CatalogCard from '../components/CatalogCard' + +export default { + title: 'CatalogCard', + component: CatalogCard, +} + +function Template(args: any) { + return ( +
+ + + + + + +
+ ) +} + +export const Default = Template.bind({}) + +Default.args = { + name: 'Base catalog', + author: 'Plural', + category: 'Messaging', + description: + 'The new open-source standard to sync data from applications, APIs & databases. One click deploys for data scientists and developers.', + tags: [ + 'Devops', + 'Deployment', + 'Fun', + 'Turkey', + 'Chickens', + 'Handball', + 'Cricket', + 'Support', + ], +}