Organisms

TsNuxtCard

Overview

The TsNuxtCard component is a reusable card wrapper tailored for Nuxt applications. It provides a structured container to display content consistently

Component Code

<template>
  <div
    :id="props.id || 'card-' + randomId"
    :data-testid="
      props.dataTestid
        ? props.dataTestid + '-card-container'
        : '-card-container'
    "
    :class="
      twMerge(
        'shadow-md border rounded-xl overflow-hidden p-4 bg-natural-soft-white',
        props.heightFull && 'h-full',
        props.noShadow && 'shadow-none',
        props.noBorder && 'border-0',
        props.appendClass
      )
    "
  >
    <slot>
      <div
        v-if="props.title || $slots.header"
        :class="
            twMerge(
              'pb-2',
              props.headerClass
            )
          "
        :data-testid="
            props.dataTestid
              ? props.dataTestid + '-card-header'
              : '-card-header'
          "
      >
        <slot name="header">
          <TsTypography as="h3" append-class="mb-0">
            {{ props.title }}
          </TsTypography>
        </slot>
      </div>
      <div
        v-if="props.content || $slots.content"
        :class="twMerge('py-2', props.bodyClass)"
        :data-testid="
            props.dataTestid
              ? props.dataTestid + '-card-content'
              : '-card-content'
          "
      >
        <slot name="content">
          <TsTypography
            as="p"
            append-class="mb-0"
          >
            {{ props.content }}
          </TsTypography>
        </slot>
      </div>
      <div
        v-if="props.footer || $slots.footer"
        :class="
            twMerge(
              'pt-2',
              props.footerClass
            )
          "
        :data-testid="
            props.dataTestid
              ? props.dataTestid + '-card-footer'
              : '-card-footer'
          "
      >
        <slot name="footer">
          {{ props.footer }}
        </slot>
      </div>
    </slot>
  </div>
</template>

<script setup lang="ts">
import {ref, onMounted} from "vue";
import {useRandomUUID} from "../../composables/useRandomUUID";
import {twMerge} from "tailwind-merge";

type Props = {
  id?: string;
  title?: string;
  content?: string;
  footer?: string;
  appendClass?: string;
  headerClass?: string;
  bodyClass?: string;
  footerClass?: string;
  noShadow?: boolean;
  noBorder?: boolean;
  heightFull?: boolean;
  dataTestid?: string;
};

const props = defineProps<Props>();

const randomId = ref<string>("");
onMounted(() => {
  if (import.meta.client)
    randomId.value = useRandomUUID();
});
</script>

Usage

<TsNuxtCard>
  <!-- Add code here to use default slot -->
</TsNuxtCard>

<!-- OR -->

<!-- Pass data through props for default layout -->
<TsNuxtCard
  title="Title of Card"
  content="Content of Card"
  footer="Footer of Card"
/>

Props

NameTypeDefaultDescription
idstring""It is used to add id to the component.
titlestring""It is used to add title to the component.
contentstring""It is used to add content to the component.
footerstring""It is used to add footer to the component.
appendClassstring""It is used to add classes to the root element of the component.
headerClassstring""It is used to add classes to the heading element of the component.
bodyClassstring""It is used to add classes to the body element of the component.
footerClassstring""It is used to add classes to the footer element of the component.
noShadowboolean""It is used to toggle shadow of the Card.
noBorderboolean""It is used to toggle border of the Card.
heightFullboolean""It is used to toggle height of the Card whether it keeps the height to max-content or obtain the height of parent element.
dataTestidstring""It is used to add data-testid for testing purpose it should be unique.

Slots

NameSlot propsDescription
Default_It is used to replace the default content with our Custom content.
header_It is used to replace the header of component.
content_It is used to replace the content of component.
footer_It is used to replace the footer of component.

Copyright © 2026