Card component for React

July 31, 2019 ยท View on GitHub

Back to Polythene Card main page

Card component for React

Options

Card options

Usage

import React from "react"
import { Card } from "polythene-react"

The card can contain various elements. The content parameter accepts any String, hyperscript or component:

import { Card, List } from "polythene-react"

<Card content={<List ... />} />

To generated Material Design elements, pass an array of element options, where each item is an object with on of the keys:

  • primary
  • text
  • media
  • header
  • actions
  • any (for any other content)

Element primary contains the sub-options title and subtitle:

<Card
  content={[
    {
      primary: {
        title: "Primary title",
        subtitle: "Subtitle"
      }
    }
  ]}
/>

Content parts are processed in the order as they are written. Of course this makes it possible to wildly deviate from the design specs.

To show in order:

  1. header with portrait image
  2. media item
  3. title and subtitle
  4. action row
  5. text

these are passed in this order to content:

import { Card, Button } from "polythene-react"

<Card
  content={[
    {
      header: {
        title: "Name",
        subtitle: "date",
        icon: {
          size: "large",
          avatar: true,
          src: "img/avatar.png"
        }
      }
    },
    {
      media: {
        content: <img src="img/large.jpg" />
      }
    },
    {
      primary: {
        title: "Primary title",
        subtitle: "Subtitle"
      }
    },
    {
      actions: {
        content: <div>
          <Button label="Action 1" />
          <Button label="Action 2" />
        </div>
      }
    },
    {
      text: {
        content: "More text"
      }
    }
  ]}
/>

For further control over the primary content, you can pass an array to primary.content:

import { Card, IconButton } from "polythene-react"
import { addLayoutStyles } from "polythene-css"

addLayoutStyles() // to use className="flex"

<Card
  content={[
    {
      primary: {
        content: [
          {
            media: {
              ratio: ratio,
              size: "large",
              content: <img src="img/large.jpg" />
            }
          },
          <div className="flex" />
          {
            actions: {
              layout: "vertical",
              content: <div>
                <IconButton icon={{ svg: { content: iconHeart } }} />
                <IconButton icon={{ svg: { content: iconBookmark } }} />
                <IconButton icon={{ svg: { content: iconShare } }} />
              </div>
            }
          }
        ]
      }
    }
  ]}
/>

Images

By specification, the media element has an image ratio of 16:9, but 1:1 images can be used too, as well as "title images" (an image placed next to the title). Images can additionally have with overlay text. Both ratio ("square" or "landscape") and size ("small", "medium", "large", "extra-large") can be set.

Cropping / origin

An image that does not fit the ratio is cropped by CSS. An additional parameter origin can be passed to determine from which side cropping should be done. Default value is "center", optional values are "start" and "end". The end result depends if the image is landscape or portrait format.

To show the left side of a landscape image:

<Card
  content={[
    {
      media: {
        origin: "start",
        content: <img src="img/large.jpg" />
      }
    }
  ]}
/>

Overlay

Images with an overlay (text, actions) can be created with media.overlay:

<Card
  content={[
    {
      media: {
        ratio: "square",
        content: <img src="img/large.jpg" />,
        overlay: {
          sheet: true,
          className: "pe-dark-tone",
          content: [
            {
              primary: {
                title: "Primary title",
                subtitle: "Subtitle"
              }
            },
            {
              actions: {
                content: <div>
                  <Button label="Action 1" />
                  <Button label="Action 2" />
                </div>
              }
            }
          ]
        }
      }
    }
  ]}
/>

An additional HTML element to control the image is "card__media__dimmer". First enable the dimmer:

{
  media: {
    showDimmer: true,
    ...
  }
},

To create a fuzzy dark border all around use an inset box shadow

.pe-card__media__dimmer {
  box-shadow: inset 0px 0px 40px rgba(0,0,0,.6);
}
.pe-card__overlay__content {
  /* something else */
}

Title image

To create a square image at the right side of the title, use primary.media:

<Card
  content={[
    {
      primary: {
        title: title,
        subtitle: "Subtitle",
        media: {
          ratio: "square",
          size,
          content: <img src="img/large.jpg" />
        }
      }
    }
  ]}
/>

Embedded videos

To show an embedded video, pass an iframe element:

content: [{
  media: {
    content: (
      <iframe
        id="ytplayer"
        type="text/html"
        width="100%"
        height="100%"
        src="https://www.youtube.com/embed/Fe7lxMJTgZ4"
        frameborder="0"
      />
    )
  }
}]

Appearance

Styling

Below are examples how to change the Card appearance, either with a theme or with CSS.

You can find more information about theming in Theming.

Themed component

import { CardCSS } from "polythene-css"

CardCSS.addStyle(".themed-card", {
  color_light_main_background: "#0097a7",
  color_light_title_text:      "#fff",
  color_light_subtitle_text:   "#fff"
});

<Card className="themed-card" />

CSS

Change CSS using the Card CSS classes.

Class names can be imported with:

import classes from "polythene-css-classes/card"

Style

Some style attributes can be set using option style. For example:

<Card
  style={{
    maxWidth: "360px",
    backgroundColor: "#B89E58"
  }}
/>

RTL (right-to-left) support

The direction of Card content is reversed when the Card is contained within an element that either:

  • has attribute dir="rtl"
  • has className pe-rtl

Dark or light tone

If the component - or a component's parent - has option tone set to "dark", the component will be rendered with light colors on dark.

  • Use tone: "dark" to render light on dark
  • Use tone: "light" to locally render normally when dark tone is set