Skip to content
RTL Support: Full
Accessibility: Full
Translations: Not Needed
Migration Guide: Work in progress

Checkbox Card

A selectable card component that combines a checkbox with rich content. Perfect for selection interfaces requiring visual hierarchy with titles, descriptions, and optional icons.

Basic Checkbox Card

A simple checkbox card with title and description.

vue
<template>
  <HLCheckboxCard
    id="basic-card"
    v-model:checked="singleChecked"
    title="Business Plan"
    description="Perfect for growing teams with up to 20 users"
  />
</template>

<script setup lang="ts">
  import { HLCheckboxCard } from '@platform-ui/highrise'
  import { ref } from 'vue'

  const singleChecked = ref(false)
</script>

Basic Checkbox Card Group

A group of checkbox cards.

vue
<template>
  <HLCheckboxGroup v-model:value="selectedPlans">
    <HLSpace vertical size="md">
      <HLCheckboxCard id="basic-plan" value="basic" title="Basic Plan" description="Perfect for small teams starting their journey">
        <template #icon>
          <LayersThree01Icon />
        </template>
      </HLCheckboxCard>
      <HLCheckboxCard id="pro-plan" value="pro" title="Pro Plan" description="Advanced features for growing teams">
        <template #icon>
          <LayersThree01Icon />
        </template>
      </HLCheckboxCard>
      <HLCheckboxCard
        id="enterprise-plan"
        value="enterprise"
        title="Enterprise Plan"
        description="Full suite of features for large organizations"
      >
        <template #icon>
          <LayersThree01Icon />
        </template>
      </HLCheckboxCard>
    </HLSpace>
  </HLCheckboxGroup>
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import { HLCheckboxCard, HLCheckboxGroup, HLSpace } from '@platform-ui/highrise'
  import { LayersThree01Icon } from '@gohighlevel/ghl-icons/24/outline'

  const selectedPlans = ref(['basic']) // Pre-selected value
</script>

Dynamic Cards with a Manual Handler

When you render cards from a list and manage selection yourself, bind :checked per item and update your own state in an @update:checked handler. This is the common pattern when the cards aren't wrapped in an HLCheckboxGroup.

vue
<template>
  <HLSpace horizontal size="md">
    <HLCheckboxCard
      v-for="day in days"
      :key="day.value"
      :id="`day-${day.value}`"
      :title="day.label"
      :value="day.value"
      :checked="selectedDays.includes(day.value)"
      @update:checked="checked => toggleDay(day.value, checked)"
    />
  </HLSpace>
</template>

<script setup lang="ts">
  import { HLCheckboxCard, HLSpace } from '@platform-ui/highrise'
  import { ref } from 'vue'

  const days = [
    { label: 'Monday', value: 'mon' },
    { label: 'Tuesday', value: 'tue' },
    { label: 'Wednesday', value: 'wed' },
  ]
  const selectedDays = ref(['mon'])

  const toggleDay = (value: string, checked: boolean) => {
    if (checked) {
      if (!selectedDays.value.includes(value)) selectedDays.value.push(value)
    } else {
      selectedDays.value = selectedDays.value.filter(v => v !== value)
    }
  }
</script>

With Icon

Checkbox card with a custom icon for enhanced visual hierarchy.

vue
<template>
  <HLCheckboxCard
    id="icon-card"
    v-model:checked="singleChecked"
    title="Enterprise Plan"
    description="Unlimited users and advanced features"
  >
    <template #icon>
      <LayersThree01Icon />
    </template>
  </HLCheckboxCard>
</template>

<script setup lang="ts">
  import { HLCheckboxCard } from '@platform-ui/highrise'
  import { LayersThree01Icon } from '@gohighlevel/ghl-icons/24/outline'
  import { ref } from 'vue'

  const singleChecked = ref(false)
</script>

Compact Mode

A more condensed version without the checkbox visible.

vue
<template>
  <HLCheckboxCard
    id="compact-card"
    v-model:checked="singleChecked"
    title="Enterprise Plan"
    description="Unlimited users and advanced features"
    :compact="true"
  >
    <template #icon>
      <LayersThree01Icon />
    </template>
  </HLCheckboxCard>
</template>

<script setup lang="ts">
  import { HLCheckboxCard } from '@platform-ui/highrise'
  import { LayersThree01Icon } from '@gohighlevel/ghl-icons/24/outline'
  import { ref } from 'vue'

  const singleChecked = ref(false)
</script>

Disabled State

Checkbox card in a disabled state.

vue
<template>
  <HLCheckboxCard id="disabled-card" title="Premium Plan" description="Currently unavailable" :disabled="true" />
</template>

<script setup lang="ts">
  import { HLCheckboxCard } from '@platform-ui/highrise'
</script>

Form Validation

Wrap the card in an HLFormItem and drive validation from there — its validation-status and feedback render the error state and message. The card itself has no validation prop.

vue
<template>
  <HLFormItem label="Select a plan" required feedback="Please select a plan to continue" validation-status="error">
    <HLCheckboxCard
      id="validation-card"
      v-model:checked="checked"
      value="required-plan"
      title="Required Plan"
      description="This plan must be selected"
    />
  </HLFormItem>
</template>

<script setup lang="ts">
  import { HLFormItem, HLCheckboxCard } from '@platform-ui/highrise'
  import { ref } from 'vue'

  const checked = ref(false)
</script>

Horizontal Card Group

A group of checkbox cards arranged horizontally.

vue
<template>
  <HLCheckboxGroup v-model:value="selectedPlans" direction="horizontal">
    <HLSpace horizontal size="md">
      <HLCheckboxCard id="monthly-plan" value="monthly" title="Monthly" description="Please select a plan to continue" :width="250">
        <template #icon>
          <LayersThree01Icon />
        </template>
      </HLCheckboxCard>
      <HLCheckboxCard id="quarterly-plan" value="quarterly" title="Quarterly" description="Please select a plan to continue" :width="250">
        <template #icon>
          <LayersThree01Icon />
        </template>
      </HLCheckboxCard>
      <HLCheckboxCard id="yearly-plan" value="yearly" title="Yearly" description="Please select a plan to continue" :width="250">
        <template #icon>
          <LayersThree01Icon />
        </template>
      </HLCheckboxCard>
    </HLSpace>
  </HLCheckboxGroup>
</template>

<script setup lang="ts">
  import { HLCheckboxGroup, HLCheckboxCard, HLSpace } from '@platform-ui/highrise'
  import { LayersThree01Icon } from '@gohighlevel/ghl-icons/24/outline'
  import { ref } from 'vue'

  const selectedPlans = ref(['monthly'])
</script>

Custom Content

The checkbox card supports custom content through its default slot, allowing you to create rich, customized layouts beyond the standard title and description.

vue
<template>
  <HLCheckboxGroup v-model:value="selectedPlans">
    <HLSpace vertical size="md">
      <!-- Custom layout with image -->
      <HLCheckboxCard id="custom-card-1" value="custom1" :width="323">
        <div style="display: flex; align-items: center; gap: 16px;">
          <img src="https://picsum.photos/60" style="border-radius: 4px;" alt="Plan thumbnail" />
          <div>
            <div style="font-weight: 600; margin-bottom: 4px;">Custom Layout Plan</div>
            <div style="color: var(--n-description-color); font-size: 14px;">$29/month</div>
          </div>
        </div>
      </HLCheckboxCard>

      <!-- Feature grid layout -->
      <HLCheckboxCard id="custom-card-2" value="custom2" :width="323">
        <div style="display: flex; flex-direction: column; gap: 8px;">
          <div style="font-weight: 600;">Advanced Features</div>
          <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; font-size: 14px;">
            <div>✓ Custom Domains</div>
            <div>✓ API Access</div>
            <div>✓ 24/7 Support</div>
            <div>✓ Analytics</div>
          </div>
        </div>
      </HLCheckboxCard>
    </HLSpace>
  </HLCheckboxGroup>
</template>

<script setup lang="ts">
  import { HLCheckboxGroup, HLCheckboxCard, HLSpace } from '@platform-ui/highrise'
  import { ref } from 'vue'

  const selectedPlans = ref(['custom1'])
</script>

The default slot allows you to:

  • Create custom layouts using flexbox or grid
  • Include images and custom icons
  • Use different text styles and sizes
  • Implement feature lists or pricing displays
  • Maintain the checkbox card's core functionality while customizing its content

Overflowing Content

A checkbox card with long content that demonstrates text wrapping and overflow handling. Currently, the title is restricted to 2 lines and the description is restricted to 4 lines.

vue
<template>
  <HLCheckboxCard
    id="overflow-card"
    v-model:checked="singleChecked"
    title="Enterprise Plan with Very Long Title That Might Wrap to Multiple Lines"
    description="This is a very long description that demonstrates how the card handles overflow content. It includes multiple sentences and should wrap naturally within the card's boundaries while maintaining readability and proper spacing."
    :width="300"
  >
    <template #icon>
      <LayersThree01Icon />
    </template>
  </HLCheckboxCard>
</template>

<script setup lang="ts">
  import { HLCheckboxCard } from '@platform-ui/highrise'
  import { LayersThree01Icon } from '@gohighlevel/ghl-icons/24/outline'
  import { ref } from 'vue'

  const singleChecked = ref(false)
</script>

Accessibility

  • The card root renders with role="checkbox", a tabindex (0 when enabled, -1 when disabled), and aria-checked / aria-disabled wired to the current state — so the card is keyboard-focusable and toggles on Enter / Space automatically.
  • Give every HLCheckboxCard a unique id. The card auto-links its label region via aria-labelledby (pointing at its title/description content), so the visible text is announced without extra wiring.

Imports

ts
import { HLCheckboxCard } from '@platform-ui/highrise'

Props

NameTypeDefaultDescription
id*string-Required unique identifier for the checkbox card
titlestringundefinedTitle text displayed in the card
descriptionstringundefinedDescription text displayed below the title
valuestring | number''Value associated with the checkbox (used to identify the card within an HLCheckboxGroup)
checkedbooleanfalseWhether the checkbox is checked
disabledbooleanfalseWhether the checkbox card is disabled, if disabled is passed to the HLCheckboxGroup this will be taken priority
compactbooleanfalseWhether to show the card in compact mode (without checkbox)
widthnumberundefinedCustom width for the card

Emits

NameParametersDescription
@update:checked(value: boolean)Two-way binding for checked state

Slots

NameDescription
iconCustom icon content displayed at the start of the card
defaultDefault slot for custom content

Best Practices

  1. Always provide a unique id for each checkbox card
  2. Group related checkbox cards using HLCheckboxGroup
  3. Use compact mode when checkbox visibility isn't necessary
  4. Encompass the checkbox card in a HLFormItem for form validation