Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
section: extensions
subsection: Component groups
id: Service card
source: react
propComponents: ['ServiceCard']
sourceLink: https://github.com/patternfly/react-component-groups/blob/main/packages/module/patternfly-docs/content/extensions/component-groups/examples/ServiceCard/ServiceCard.md
---

import ServiceCard from "@patternfly/react-component-groups/dist/dynamic/ServiceCard";
import { EllipsisVIcon } from '@patternfly/react-icons';
import contentHeaderIcon from '../../assets/icons/content-header-icon.svg'

A **Service Card** component allows

## Examples

### Service Card

```js file="./ServiceCardExample.tsx"

```

### Service Card with Gallery example

```js file="./ServiceCardGalleryExample.tsx"

```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@InsaneZein can you please add some texts to the docs? It would also be nice to create an example with the custom footer. Let me know if you need help with the texts.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import ServiceCard from "@patternfly/react-component-groups/dist/dynamic/ServiceCard";
import contentHeaderIcon from '../../assets/icons/content-header-icon.svg';

export const BasicExample: React.FunctionComponent = () => (
<ServiceCard
title='Example'
subtitle='A basic example'
description='This is a basic ServiceCard Example'
icon={<img src={contentHeaderIcon} alt="content-header-icon" />}
showDisabledButton={false}
helperText=''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would either provide some text or remove the prop from this example

learnMoreUrl='/'
launchUrl='/'
/>
);
Copy link
Contributor

@fhlavac fhlavac Jul 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add icons to these cards and show a helper text in one of the cards? Just to show the features.

For the footers we could hardcode the default one in the example and another with something like this

<Button variant="link" isInline>
            Learn more  
          <Icon className="pf-u-ml-sm" isInline>
            <ArrowRightIcon />
          </Icon>
</Button>

(another already known use case of this component)

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import ServiceCard from "@patternfly/react-component-groups/dist/dynamic/ServiceCard";
import { Gallery } from '@patternfly/react-core/dist/dynamic/layouts/Gallery';
import { GalleryItem } from '@patternfly/react-core/dist/dynamic/layouts/Gallery';


export const ServiceCardGalleryExample: React.FunctionComponent = () => (
<Gallery hasGutter minWidths={{ default: '330px' }}>
<GalleryItem>
<ServiceCard
title='Example2'
subtitle='A basic example'
description='This is a basic ServiceCard Example'
iconUrl='/'
showDisabledButton={false}
helperText=''
learnMoreUrl='/'
launchUrl='/'
/>
</GalleryItem>
<GalleryItem>
<ServiceCard
title='Example2'
subtitle='A second example'
description='This is another basic ServiceCard Example'
iconUrl='/'
showDisabledButton={false}
helperText=''
learnMoreUrl='/'
launchUrl='/'
/>
</GalleryItem>
</Gallery>
)
18 changes: 18 additions & 0 deletions packages/module/src/ServiceCard/ServiceCard.test.tsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should preferably use cypress

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { render } from '@testing-library/react';
import ServiceCard from './ServiceCard';

describe('LogSnippet component', () => {
it('should render LogSnippet component', () => {
expect(render(<ServiceCard
title='Example'
subtitle='A basic example'
description='This is a basic ServiceCard Example'
icon='/'
showDisabledButton={false}
helperText=''
learnMoreUrl='/'
launchUrl='/'
/>)).toMatchSnapshot();
});
});
102 changes: 102 additions & 0 deletions packages/module/src/ServiceCard/ServiceCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from 'react';
import { Button, ButtonVariant, Card, CardBody, CardFooter, CardHeader, Text, TextContent, TextVariants } from '@patternfly/react-core';
import { HelperText } from '@patternfly/react-core/dist/dynamic/components/HelperText';
import { HelperTextItem } from '@patternfly/react-core/dist/dynamic/components/HelperText';
import { createUseStyles } from 'react-jss';

export interface ServiceCardProps {
/** Title for card */
title: string;
/** Subtitle for card */
subtitle: string;
/** Custom description */
description: string;
/** icon for service card */
icon: React.ReactNode;
/** Whether to show if button is disabled */
showDisabledButton?: boolean;
/** Helper text for card */
helperText?: string;
/** learn more button url*/
learnMoreUrl: string;
/** Optional launch button url*/
launchUrl?: string;
/** Optional foot to override default Learn More and Launch buttons */
footer?: React.ReactElement
/** Optional custom OUIA ID */
ouiaId?: string | number;
}

const useStyles = createUseStyles({
card: {
height: ('var(--pf-v5-u-h-100)')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
height: ('var(--pf-v5-u-h-100)')
height: 'var(--pf-v5-u-h-100)'

},
image: {
marginRight: ('var(--pf-v5-global--spacer--md)'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
marginRight: ('var(--pf-v5-global--spacer--md)'),
marginRight: 'var(--pf-v5-global--spacer--md)',

width: 48
},
launchButton: {
marginRight: ('var(--pf-v5-global--spacer--sm)')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
marginRight: ('var(--pf-v5-global--spacer--sm)')
marginRight: 'var(--pf-v5-global--spacer--md)'

I think this one should be md

}
});

const ServiceCard: React.FunctionComponent<ServiceCardProps> = ({
title,
subtitle,
description,
icon,
helperText,
learnMoreUrl,
launchUrl,
footer,
ouiaId='ServiceCard'
}: ServiceCardProps) => {
const classes = useStyles();

return (
<Card className={classes.card} ouiaId={`${ouiaId}-card`}>
<CardHeader>
<div className={classes.image}>
{icon}
</div>
<TextContent>
<Text component={TextVariants.h2}>{title}</Text>
{subtitle}
</TextContent>
</CardHeader>
<CardBody>{description}</CardBody>
<CardFooter>
<HelperText>
<HelperTextItem variant="indeterminate" className="pf-v5-u-mb-lg">
{helperText}
</HelperTextItem>
</HelperText>
{
footer ?
( footer ) :
( <>
{ launchUrl &&
<Button
variant={ButtonVariant.secondary}
isInline
className={classes.launchButton}
component="a"
href={launchUrl}>
Launch
</Button> }
<Button
variant={ButtonVariant.link}
component="a"
isInline
href={learnMoreUrl}
>
Learn More
</Button>
</> )
}
</CardFooter>
</Card>
)
}

export default ServiceCard;
Loading