Deck
Browse the catalog

Build / Organisms

FeaturedEventsHeaderCard

  • organism
  • play-fn

The event at the top of the calendar — the one happening next, as a card.

Distinct from EventHeaderCard, which heads an event's own page and carries the things you do there: an RSVP, a share control, who else is going. This one heads a list of events. It answers "what is next" and then, on the strip along its foot, "and after that" — so the top of the calendar says the same thing the calendar does.

The photograph is sharp here rather than blurred. A hero is read; this is looked at, and its facts are two short lines rather than a paragraph.

import { FeaturedEventsHeaderCard } from '@meetcard/deck'

Example

<FeaturedEventsHeaderCard name="RevOps Summit" coverSrc={cover} badges={<Badge tone="success">Attending</Badge>} facts={[{ icon: <Clock />, text: 'Tuesday, May 18, 2027 · 9:00 AM' }]} upNext={{ label: 'Up next · Jun 16', name: 'Boulder Climate Happy Hour' }} />

Stories

Every preview below is the real component, rendered in this page from the same story Storybook runs. The width control resizes each preview's container; CSS media queries still follow the browser window, so breakpoint behaviour is worth checking in Storybook.

The top of the calendar: what is happening next, and — on the strip along the foot — what is after that.

Default
Source
const Default = () => <FeaturedEventsHeaderCard
    name="RevOps Summit"
    coverSrc={'data:image/svg+xml;utf8,' +
    encodeURIComponent(
      `<svg xmlns="http://www.w3.org/2000/svg" width="560" height="320">
         <rect width="560" height="320" fill="#fdfbf7"/>
         <circle cx="150" cy="90" r="130" fill="#ffe9c7"/>
         <circle cx="430" cy="240" r="170" fill="#dbeee4"/>
         <rect x="240" y="40" width="120" height="240" fill="#fff6e0"/>
       </svg>`,
    )}
    badges={(<>
      <Badge size="sm">Happening next</Badge>
      <Badge tone="success" size="sm">
        Attending
      </Badge>
    </>)}
    facts={[
      { icon: <ClockIcon />, text: 'Tuesday, May 18, 2027 · 9:00 AM' },
      { icon: <PinIcon />, text: 'Austin Convention Center, Austin, Texas' },
    ]}
    upNext={{
      label: 'Up next · Jun 16',
      name: 'Boulder Climate Happy Hour',
      detail: '5:30 PM · Rayback Collective',
      trailing: <Avatar name="Hannah Davis" size="sm" decorative />,
    }} />;

Without the strip — a calendar with nothing after this one. The card ends on its facts rather than leaving an empty shelf.

Nothing After This
Source
const NothingAfterThis = () => <FeaturedEventsHeaderCard
    name="RevOps Summit"
    coverSrc={'data:image/svg+xml;utf8,' +
    encodeURIComponent(
      `<svg xmlns="http://www.w3.org/2000/svg" width="560" height="320">
         <rect width="560" height="320" fill="#fdfbf7"/>
         <circle cx="150" cy="90" r="130" fill="#ffe9c7"/>
         <circle cx="430" cy="240" r="170" fill="#dbeee4"/>
         <rect x="240" y="40" width="120" height="240" fill="#fff6e0"/>
       </svg>`,
    )}
    badges={(<>
      <Badge size="sm">Happening next</Badge>
      <Badge tone="success" size="sm">
        Attending
      </Badge>
    </>)}
    facts={[
      { icon: <ClockIcon />, text: 'Tuesday, May 18, 2027 · 9:00 AM' },
      { icon: <PinIcon />, text: 'Austin Convention Center, Austin, Texas' },
    ]}
    upNext={undefined} />;

Linked, so the name leads to the event's own page.

Linked
Source
const Linked = () => <FeaturedEventsHeaderCard
    name="RevOps Summit"
    coverSrc={'data:image/svg+xml;utf8,' +
    encodeURIComponent(
      `<svg xmlns="http://www.w3.org/2000/svg" width="560" height="320">
         <rect width="560" height="320" fill="#fdfbf7"/>
         <circle cx="150" cy="90" r="130" fill="#ffe9c7"/>
         <circle cx="430" cy="240" r="170" fill="#dbeee4"/>
         <rect x="240" y="40" width="120" height="240" fill="#fff6e0"/>
       </svg>`,
    )}
    badges={(<>
      <Badge size="sm">Happening next</Badge>
      <Badge tone="success" size="sm">
        Attending
      </Badge>
    </>)}
    facts={[
      { icon: <ClockIcon />, text: 'Tuesday, May 18, 2027 · 9:00 AM' },
      { icon: <PinIcon />, text: 'Austin Convention Center, Austin, Texas' },
    ]}
    upNext={{
      label: 'Up next · Jun 16',
      name: 'Boulder Climate Happy Hour',
      detail: '5:30 PM · Rayback Collective',
      trailing: <Avatar name="Hannah Davis" size="sm" decorative />,
    }}
    href="/events/revops-summit" />;

On a phone. Stood up, and the strip still holds the foot — everything above it takes the squeeze instead.

On A Phone
Source
const OnAPhone = () => <FeaturedEventsHeaderCard
    name="RevOps Summit"
    coverSrc={'data:image/svg+xml;utf8,' +
    encodeURIComponent(
      `<svg xmlns="http://www.w3.org/2000/svg" width="560" height="320">
         <rect width="560" height="320" fill="#fdfbf7"/>
         <circle cx="150" cy="90" r="130" fill="#ffe9c7"/>
         <circle cx="430" cy="240" r="170" fill="#dbeee4"/>
         <rect x="240" y="40" width="120" height="240" fill="#fff6e0"/>
       </svg>`,
    )}
    badges={(<>
      <Badge size="sm">Happening next</Badge>
      <Badge tone="success" size="sm">
        Attending
      </Badge>
    </>)}
    facts={[
      { icon: <ClockIcon />, text: 'Tuesday, May 18, 2027 · 9:00 AM' },
      { icon: <PinIcon />, text: 'Austin Convention Center, Austin, Texas' },
    ]}
    upNext={{
      label: 'Up next · Jun 16',
      name: 'Boulder Climate Happy Hour',
      detail: '5:30 PM · Rayback Collective',
      trailing: <Avatar name="Hannah Davis" size="sm" decorative />,
    }} />;

A name long enough to need the room. It clamps at two lines rather than pushing the facts off the card.

A Long Name
Source
const ALongName = () => <FeaturedEventsHeaderCard
    name="The Annual RevOps, Partnerships and Community Leaders Summit"
    coverSrc={'data:image/svg+xml;utf8,' +
    encodeURIComponent(
      `<svg xmlns="http://www.w3.org/2000/svg" width="560" height="320">
         <rect width="560" height="320" fill="#fdfbf7"/>
         <circle cx="150" cy="90" r="130" fill="#ffe9c7"/>
         <circle cx="430" cy="240" r="170" fill="#dbeee4"/>
         <rect x="240" y="40" width="120" height="240" fill="#fff6e0"/>
       </svg>`,
    )}
    badges={(<>
      <Badge size="sm">Happening next</Badge>
      <Badge tone="success" size="sm">
        Attending
      </Badge>
    </>)}
    facts={[
      { icon: <ClockIcon />, text: 'Tuesday, May 18, 2027 · 9:00 AM' },
      { icon: <PinIcon />, text: 'Austin Convention Center, Austin, Texas' },
    ]}
    upNext={{
      label: 'Up next · Jun 16',
      name: 'Boulder Climate Happy Hour',
      detail: '5:30 PM · Rayback Collective',
      trailing: <Avatar name="Hannah Davis" size="sm" decorative />,
    }} />;

Props

PropTypeDefaultDescription
namerequiredstring——
badgesReactNode—Pills above the name: "Happening next", "Attending".
factsFeaturedEventsHeaderCardFact[]—When and where, one line each.
hrefstring—Makes the name a link to the event.
level1 | 2 | 3 | 4 | 5 | 62Heading level. 2 by default — this heads a section, not a page.
upNextFeaturedEventsHeaderCardUpNext—The event after this one, on a strip along the foot of the card. It is what makes this the calendar's header rather than an event's own: the question on a calendar is what is next, and the answer is worth more than the empty half of a photograph.

Also accepts everything from Omit, so id, data-* and event handlers pass straight through.

Open in Storybookfor controls, the a11y panel and the interaction runner.