Skip to content

Commit

Permalink
Merge pull request #420 from indiana-university/feature/372/Card
Browse files Browse the repository at this point in the history
feat: Implemented Card component (#372)
  • Loading branch information
johglove committed Mar 29, 2024
2 parents 6aa1fc4 + abf4011 commit 2bb4927
Show file tree
Hide file tree
Showing 5 changed files with 528 additions and 0 deletions.
119 changes: 119 additions & 0 deletions src/components/PageContent/Card/Card.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
Copyright (C) 2018 The Trustees of Indiana University
SPDX-License-Identifier: BSD-3-Clause
*/
import classNames from "classnames";
import * as PropTypes from "prop-types";
import * as React from "react";
import * as Rivet from "../../util/Rivet";
import { TestUtils } from "../../util/TestUtils";

const Card = ({
children,
className,
clickable = false,
Component = 'div',
eyebrow,
horizontal = false,
image,
meta,
raised = false,
testMode = false,
title,
titleUrl,
...attrs
}) => {
const classNameArr = [
"rvt-card",
clickable ? "rvt-card--clickable" : "",
horizontal ? "rvt-card--horizontal" : "",
raised ? "rvt-card--raised " : "",
className
]

return (
<Component
className={classNames(classNameArr)}
{...(testMode && { "data-testid": TestUtils.Card.container })}
{...attrs}
>
{image && <Image testMode={testMode}>{image}</Image>}
<div className="rvt-card__body">
{eyebrow && <Eyebrow testMode={testMode}>{eyebrow}</Eyebrow>}
<h2
className="rvt-card__title"
{...(testMode && { "data-testid": TestUtils.Card.title })}
>
{titleUrl && <a href={titleUrl}>{title}</a>}
{!titleUrl && <span>{title}</span>}
</h2>
<div
className="rvt-card__content"
{...(testMode && { "data-testid": TestUtils.Card.content })}
>
{children}
</div>
{meta && <Meta testMode={testMode}>{meta}</Meta>}
</div>
</Component>
)
}

Card.displayName = "Card";
Card.propTypes = {
/** Full card will trigger link to tiitle's url (requires titleUrl set) */
clickable: PropTypes.bool,
/** Allows setting of container element */
Component: PropTypes.string,
/** Optional eyebrow to display */
eyebrow: PropTypes.oneOfType(PropTypes.element),
/** Display card in horizontal format */
horizontal: PropTypes.bool,
/** Optional image to display */
image: PropTypes.oneOfType(PropTypes.element),
/** Optional meta information */
meta: PropTypes.oneOfType(PropTypes.element),
/** Add a box shadow to the card */
raised: PropTypes.bool,
/** [Developer] Adds data-testId attributes for component testing */
testMode: PropTypes.bool,
/** The title of the Card */
title: PropTypes.string.isRequired,
/** Url for the title */
titleUrl: PropTypes.string
};

const Eyebrow = ({ children, testMode }) => {
return (
<div
className="rvt-card__eyebrow"
{...(testMode && { "data-testid": TestUtils.Card.eyebrow })}
>
{children}
</div>
)
}

const Image = ({ children, testMode }) => {
return (
<div
className="rvt-card__image"
{...(testMode && { "data-testid": TestUtils.Card.image })}
>
{children}
</div>
)
}

const Meta = ({ children, testMode }) => {
return (
<div
className="rvt-card__meta"
{...(testMode && { "data-testid": TestUtils.Card.meta })}
>
{children}
</div>
)
}

export default Rivet.rivetize(Card);
145 changes: 145 additions & 0 deletions src/components/PageContent/Card/Card.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
Use the card component to group related content, including an image, headline, summary text, and link.

Cards are often used to present lists or grids of content such as featured news articles or resources related to a specific topic.

View the [Rivet documentation for Card](https://rivet.uits.iu.edu/components/card/).

### Card Example

<!-- prettier-ignore-start -->
```jsx
<Card
className="rvt-container-sm"
title="Basic Card"
titleUrl="#"
>
<p>This is a basic card with just a title (with link) and some text</p>
</Card>
```
<!-- prettier-ignore-end -->

<!-- prettier-ignore-start -->
```jsx
<Card
className="rvt-container-sm"
eyebrow="Card Examples"
raised
title="Basic Card"
titleUrl="#"
>
<p>This is a basic card but text added above and a box shadow</p>
</Card>
```
<!-- prettier-ignore-end -->
<!-- prettier-ignore-start -->
```jsx
const image = <img class="rvt-width-sm" src="https://rivet.iu.edu/img/placeholder/list-card-3.webp" alt="Smiling students sitting outside on a bench" />;
const meta = <time>November 5, 1955</time>;
<Card
className="rvt-container-sm"
image={image}
title="Card with image and metadata"
meta={meta}
>
<p>In this card there is no link for the title.</p>
<p>A image has been placed above and metadata has been added to the bottom</p>
</Card>
```
<!-- prettier-ignore-end -->
<!-- prettier-ignore-start -->
```jsx
const image = <img class="rvt-width-sm" src="https://rivet.iu.edu/img/placeholder/list-card-3.webp" alt="Smiling students sitting outside on a bench" />;
const meta = <time>November 5, 1955</time>;
<Card
className="rvt-container-sm"
image={image}
horizontal
title="Card with image and metadata"
meta={meta}
>
<p>This is the same as the example above </p>
<p>However the format is horizontal instead of vertical.</p>
</Card>
```
<!-- prettier-ignore-end -->
<!-- prettier-ignore-start -->
```jsx
const image = <img class="rvt-width-sm" src="https://rivet.iu.edu/img/placeholder/list-card-3.webp" alt="Smiling students sitting outside on a bench" />;
const meta = <time>November 5, 1955</time>;
<Card
clickable
image={image}
title="Card with image and metadata"
titleUrl="#"
meta={meta}
>
<p>The link has been added back in and made clickable on the full card</p>
</Card>
```
<!-- prettier-ignore-end -->
<!-- prettier-ignore-start -->
```jsx
<ul class="rvt-list-plain rvt-flow">
<Card
Component="li"
horizontal
image={<img class="rvt-width-sm" src="https://rivet.iu.edu/img/placeholder/list-card-1.webp" alt="example 1" />}
title="Card 1"
meta={<time>November 1, 1955</time>}
>
<p>The first card in a list</p>
</Card>
<Card
Component="li"
horizontal
image={<img class="rvt-width-sm" src="https://rivet.iu.edu/img/placeholder/list-card-2.webp" alt="example 2" />}
title="Card 2"
meta={<time>December 1, 1975</time>}
>
<p>The second card in the list</p>
</Card>
<Card
Component="li"
horizontal
image={<img class="rvt-width-sm" src="https://rivet.iu.edu/img/placeholder/list-card-3.webp" alt="example 3" />}
title="Card 3"
meta={<time>Apirl 1, 2020</time>}
>
<p>Last Card</p>
</Card>
</ul>
```
<!-- prettier-ignore-end -->
<!-- prettier-ignore-start -->
```jsx
<div class="rvt-row">
<div class="rvt-cols-4-md">
<Card
image={<img class="rvt-width-md" src="https://rivet.iu.edu/img/placeholder/list-card-1.webp" alt="example 1" />}
title="Card 1"
meta={<time>November 1, 1955</time>}
>
<p>The first card in a grid</p>
</Card>
</div>
<div class="rvt-cols-4-md">
<Card
image={<img class="rvt-width-md" src="https://rivet.iu.edu/img/placeholder/list-card-2.webp" alt="example 2" />}
title="Card 2"
meta={<time>December 1, 1975</time>}
>
<p>The second card in the grid</p>
</Card>
</div>
<div class="rvt-cols-4-md">
<Card
image={<img class="rvt-width-md" src="https://rivet.iu.edu/img/placeholder/list-card-3.webp" alt="example 3" />}
title="Card 3"
meta={<time>Apirl 1, 2020</time>}
>
<p>Last Card</p>
</Card>
</div>
</div>
```
<!-- prettier-ignore-end -->
Loading

0 comments on commit 2bb4927

Please sign in to comment.