Card

Display a card.

Usage

The card can be composed in a multitude of ways utilising the CCard, CCardText, CCardBody, CCardTitle, CCardFooter, CCardMedia, CCardFooter & CCardAction components.

Example title

Subtitle content can go here

Go to example
<template>
  <CCard>
    <CCardText>
      <CCardTitle
        title="Example title"
        subtitle="Subtitle content can go here"
      />
      <CCardBody>
        <CTextInput placeholder="example" />
      </CCardBody>
    </CCardText>
    <CCardFooter to="/components/card">
      <CCardAction label="Go to example" />
    </CCardFooter>
  </CCard>
</template>

The CCardFooter component will take a to prop that allows the style footer to become a link. Use in conjunction with CCardAction.

Example title

Subtitle content can go here

Go to example
<template>
  <CCard>
    <CCardText>
      <CCardTitle
        title="Example title"
        subtitle="Subtitle content can go here"
      />
      <CCardBody>
        <CTextInput placeholder="example" />
      </CCardBody>
    </CCardText>
    <CCardFooter to="/components/card">
      <CCardAction label="Go to example" />
    </CCardFooter>
  </CCard>
</template>

The CCard component will take a to prop that allows the card to be rendered as a click target.

<template>
  <CCard to="/">
    <CCardText>
      <CCardTitle
        title="Example title"
        subtitle="Subtitle content can go here"
      />
      <CCardBody>
        Example body content
      </CCardBody>
    </CCardText>
  </CCard>
</template>

Large

Apply the large prop to the compositional components to utilise a large card.

<template>
  <CCard to="/">
    <CCardText large>
      <CCardTitle
        large
        title="Example title"
        subtitle="Subtitle content can go here"
      />
      <CCardBody large>
        Example body content
      </CCardBody>
    </CCardText>
    <CCardFooter large>
      <CCardAction
        size="lg"
        label="Go to example"
      />
    </CCardFooter>
  </CCard>
</template>

Media

The CCardMedia component will apply the needed padding, positioning and overflow styles to allow you to utilise images inside the Card component.

It takes top, left, right, bottom props to apply padding to the given position, or all to apply the every side. The position prop will apply flex alignment.

Example title

Subtitle content can go here

Example body content
A terminal using a curl command to interact with the Cudo Compute API
Go to example
<template>
  <CCard>
    <CCardText>
      <CCardTitle
        title="Example title"
        subtitle="Subtitle content can go here"
      />
      <CCardBody>
        Example body content
      </CCardBody>
    </CCardText>
    <CCardMedia left>
      <img
        src="/api-light.webp"
        alt="A terminal using a curl command to interact with the Cudo Compute API"
        class="inline-block rounded-tl-lg shadow-lg dark:hidden"
      >
      <img
        src="/api-dark.webp"
        alt="A terminal using a curl command to interact with the Cudo Compute API"
        class="hidden dark:inline-block"
      >
    </CCardMedia>
    <CCardFooter to="/">
      <CCardAction label="Go to example" />
    </CCardFooter>
  </CCard>
</template>

Large

Example of CCardMedia usage with large compositional card components.

Example title

Subtitle content can go here

Example body content
A terminal using a curl command to interact with the Cudo Compute API
Go to example
<template>
  <CCard>
    <CCardText large>
      <CCardTitle
        large
        title="Example title"
        subtitle="Subtitle content can go here"
      />
      <CCardBody large>
        Example body content
      </CCardBody>
    </CCardText>
    <CCardMedia
      large
      left
    >
      <img
        src="/api-light.webp"
        alt="A terminal using a curl command to interact with the Cudo Compute API"
        class="inline-block rounded-tl-lg shadow-lg dark:hidden"
      >
      <img
        src="/api-dark.webp"
        alt="A terminal using a curl command to interact with the Cudo Compute API"
        class="hidden dark:inline-block"
      >
    </CCardMedia>
    <CCardFooter
      large
      to="/components/card"
    >
      <CCardAction
        size="lg"
        label="Go to example"
      />
    </CCardFooter>
  </CCard>
</template>

Landscape

The CCard component takes a layout prop for usage with CCardMedia, allowing the media to be positioned in a landscape layout.

The layoutCollapse prop is available to apply responsive styles, collapsing to a portrait layout below the xl breakpoint.

<template>
  <CCard
    to="/"
    layout="landscape"
  >
    <CCardText>
      <CCardTitle
        title="Example title"
        subtitle="Subtitle content can go here"
      />
      <CCardBody>
        Example body content
      </CCardBody>
      <CCardAction label="Go to example" />
    </CCardText>
    <CCardMedia top>
      <img
        src="/api-light.webp"
        alt="A terminal using a curl command to interact with the Cudo Compute API"
        class="inline-block rounded-tl-lg shadow-lg dark:hidden"
      >
      <img
        src="/api-dark.webp"
        alt="A terminal using a curl command to interact with the Cudo Compute API"
        class="hidden dark:inline-block"
      >
    </CCardMedia>
  </CCard>
</template>

Slots

action

The #action slot is an empty unstyled slot intended for absolute positioning. For example, a hover initiated close button as seen below or a notification indicator.

<script lang="ts" setup>
import { defaultFocusClasses } from '#cudo-components/classes'

const isHovered = ref(false)
const isFocused = ref(false)
const debouncedFocus = debouncedRef(isFocused, 100)
</script>

<template>
  <CCard
    to="/"
    @mouseover="isHovered = true"
    @mouseleave="isHovered = false"
    @focus="isFocused = true"
    @focusout="isFocused = false"
  >
    <template #action>
      <div
        class="absolute right--4 top--4 z-10 border-2 border-canvas-100 rounded-full dark:border-canvas-950"
        :class="[isHovered || debouncedFocus ? 'block' : 'hidden']"
      >
        <CTooltip>
          <button
            class="group/close z-10 flex items-center justify-center gap-1 border border-lm-border-1 rounded-full bg-white px-2 py-2 text-xs text-canvas-800 dark:border-dm-border hover:border-canvas-400 dark:bg-dm-bg-1 dark:text-white hover:shadow-xl dark:hover:border-canvas-500"
            :class="{ [defaultFocusClasses]: true }"
            type="button"
            @focus="isFocused = true"
            @focusout="isFocused = false"
          >
            <CIcon
              name="i-heroicons-solid-x"
              size="sm"
            />
          </button>
          <template #content>
            Remove from recent projects
          </template>
        </CTooltip>
      </div>
    </template>
    <CCardText>
      <CCardTitle title="Example title" />
      <CCardBody>
        Example body content
      </CCardBody>
    </CCardText>
  </CCard>
</template>

Props

Card

layout
"portrait" | "landscape"
"portrait"
contain
"size" | "layout" | "none" | "paint" | "strict" | "content"
"layout"
to
string | RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric
custom
false
activeClass
string
exactActiveClass
string
ariaCurrentValue
"page" | "step" | "location" | "date" | "time" | "true" | "false"
target
"_self" | "_blank" | "_parent" | "_top" | (string & {})
href
string | RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric
rel
(string & {}) | "noopener" | "noreferrer" | "nofollow" | "sponsored" | "ugc"
"noopener""noreferrer""nofollow""sponsored""ugc"
prefetchedClass
string
prefetchOn
unknown
trailingSlash
"append" | "remove"
loading
boolean
false
disabled
boolean
false
placeholder
boolean
false
layoutCollapse
boolean
false
replace
boolean
viewTransition
boolean
external
boolean
noRel
boolean
prefetch
boolean
noPrefetch
boolean

CardText

large
boolean

CardTitle

size
"md" | "sm" | "lg"
title
string
subtitle
string
large
boolean

CardBody

large
boolean

CardAction

labelrequired
string
size
"md" | "sm" | "lg"
"sm"

CardMedia

position
"end" | "center"
large
boolean
top
boolean
left
boolean
bottom
boolean
right
boolean
all
boolean