Skip to content

@carrot/design-vue — Developer Reference

Overview

@carrot/design-vue is the umbrella package for all Carrot Vue 3 UI components, composables, types, and constants. It re-exports every individual @carrot/design-vue-* package from a single entry point so consumers do not need to manage multiple package imports.

The umbrella covers:

  • 29 Vue component packages
  • All associated composables
  • Shared TypeScript types and prop interfaces
  • Re-exported constants from component-level packages

CSS is not bundled. You must load @carrot/design-components (or individual @carrot/design-components-* packages) separately. See the CSS section below.

Design System demo


Installation

bash
npm install @carrot/design-vue @carrot/design-components

Import everything from one place:

ts
import { CarrotButton, CarrotModal, useModal } from '@carrot/design-vue'

Individual packages (tree-shaking / micro-frontends)

Install only what you need:

bash
npm install @carrot/design-vue-buttons @carrot/design-vue-modals
npm install @carrot/design-components-buttons @carrot/design-components-modals

Import directly from the individual package:

ts
import { CarrotButton } from '@carrot/design-vue-buttons'
import { CarrotModal, useModal } from '@carrot/design-vue-modals'

CSS

This package does not bundle any CSS. Class names are generated and shipped by @carrot/design-components. Load styles before your app mounts:

ts
// main.ts — umbrella CSS
import '@carrot/design-components/dist/style.css'

Or per-feature if you installed individual packages:

ts
import '@carrot/design-components-buttons/dist/style.css'
import '@carrot/design-components-modals/dist/style.css'

Package Table

All 29 Vue packages, their exported components, and composables.

PackageComponentsComposables
@carrot/design-vue-avatarsCarrotAvatar, CarrotAvatarGroupgetInitials
@carrot/design-vue-coreCarrotPanel, CarrotLink, CarrotLabel, CarrotDivider, CarrotHidden, CarrotOverflowRow, CarrotShortcut
@carrot/design-vue-badgesCarrotBadge, CarrotBadgeCount, CarrotDot
@carrot/design-vue-buttonsCarrotButton, CarrotButtonGroup
@carrot/design-vue-calendarCarrotCalendar, CarrotCalendarHeader, CarrotCalendarDayView, CarrotCalendarWeekView, CarrotCalendarMonthView, CarrotCalendarYearView, CarrotCalendarEvent, CarrotCalendarMonthEvent, CarrotCalendarNowIndicator, CarrotCalendarEventPopoveruseCalendarNavigation, useCalendarEvents, useCalendarGrid, useCalendarDrag, useNowIndicator
@carrot/design-vue-cardsCarrotCard, CarrotCardHeader, CarrotCardBody, CarrotCardFooter, CarrotCardMedia
@carrot/design-vue-chartsCarrotChartHeatmap, CarrotChartLegend, CarrotChartLegendGradientuseHeatmapIntensity
@carrot/design-vue-dropdownsCarrotDropdown, CarrotDropdownTrigger, CarrotDropdownMenu, CarrotDropdownItem, CarrotDropdownGroup, CarrotDropdownDivideruseClickOutside, useDropdownKeyboard
@carrot/design-vue-formsCarrotFormuseCarrotForm, useFormField, createFormValidator, toFormData, dirtyValues + rule builders
@carrot/design-vue-graphsCarrotGraphBar, CarrotGraphLine, CarrotGraphPie, CarrotGraphRadar, CarrotGraphSparkline, CarrotGraphLegend, CarrotGraphTooltip, CarrotGraphEmptyuseSeriesColors, useGraphDimensions, useTooltip, useRadarGeometry
@carrot/design-vue-hotspotsCarrotHotspot, CarrotHotspotOverlay, CarrotHotspotOverlayItem, CarrotHotspotInfoPaneluseHotspots, useHotspotsContext
@carrot/design-vue-imagesCarrotImage, CarrotBgImage, CarrotPicture, CarrotSvguseImageLoad, useLazyLoad, useImageQueue, useRadius
@carrot/design-vue-inputsCarrotInput, CarrotInputNumber, CarrotInputNumberPin, CarrotInputGroup, CarrotTextArea, CarrotCheckbox, CarrotCheckboxGroup, CarrotRadio, CarrotRadioGroupuseInputField, useAutoResize
@carrot/design-vue-listsCarrotList, CarrotListItem, CarrotListGroup, CarrotListDivider, CarrotListEmpty, CarrotTransferList, CarrotTransferPanel
@carrot/design-vue-menusCarrotMenu, CarrotMenuItem, CarrotMenuGroup, CarrotMenuDivider, CarrotMenuFlyoutuseMenuKeyboard
@carrot/design-vue-modalsCarrotModal, CarrotModalHeader, CarrotModalBody, CarrotModalFooteruseModal, useFocusTrap, useScrollLock
@carrot/design-vue-paginationCarrotPaginationusePagination
@carrot/design-vue-progressCarrotProgressBar, CarrotProgressRinguseProgress, useProgressTimer
@carrot/design-vue-responsiveCarrotResponsiveContainer, CarrotResponsiveGrid, CarrotResponsiveStackuseContainerBreakpoint
@carrot/design-vue-slidersCarrotSlideruseSliderDrag
@carrot/design-vue-spinnersCarrotSpinner, CarrotSpinnerOverlay, CarrotSkeleton
@carrot/design-vue-tabsCarrotTabs, CarrotTabList, CarrotTab, CarrotTabPanels, CarrotTabPanel
@carrot/design-vue-tablesCarrotTableuseTableSort, useTableSelection
@carrot/design-vue-timelineCarrotTimeline + 9 sub-componentsuseTimeline, useTimelinePlayback, useTimelineDrag, useTimelineSelection, useTimelineKeyboard, useTimelineZoom
@carrot/design-vue-toastsCarrotToast, CarrotToastContainertoast (imperative), useToast
@carrot/design-vue-togglesCarrotToggle
@carrot/design-vue-uploadsCarrotUploadZone, CarrotUploadList, CarrotUploadItem, CarrotUploadIndicatoruseUploadQueue

Build System

All Vue packages use Vite in library mode with vite-plugin-dts for TypeScript declaration generation.

  • Output format: ES module (es)
  • All @carrot/* packages are externalized
  • vue is externalized as a peer dependency
  • Declaration files (.d.ts) are emitted alongside the bundle

Building a New Vue Package

Package anatomy

@carrot/design-vue-{name}/
  package.json
  tsconfig.json
  vite.config.ts
  src/
    index.ts            ← barrel export
    types.ts            ← prop interfaces + re-exported style types
    components/
      Carrot{Name}.vue
    composables/
      use{Name}.ts

package.json template

json
{
  "name": "@carrot/design-vue-{name}",
  "version": "0.9.0",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    }
  },
  "peerDependencies": {
    "vue": "^3.4.0"
  },
  "dependencies": {
    "@carrot/core": "workspace:*",
    "@carrot/design-components-{name}": "workspace:*"
  },
  "devDependencies": {
    "vue": "^3.4.0"
  },
  "scripts": {
    "build": "vite build && vue-tsc --declaration --emitDeclarationOnly"
  }
}

vite.config.ts template

ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import dts from 'vite-plugin-dts'

export default defineConfig({
  plugins: [
    vue(),
    dts({ insertTypesEntry: true }),
  ],
  build: {
    lib: {
      entry: 'src/index.ts',
      formats: ['es'],
      fileName: 'index',
    },
    rollupOptions: {
      external: ['vue', /^@carrot\//],
      output: {
        globals: { vue: 'Vue' },
      },
    },
  },
})

tsconfig.json template

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "lib": ["ES2020", "DOM"],
    "strict": true,
    "skipLibCheck": true,
    "paths": {
      "@carrot/core": ["../../core/src/index.ts"],
      "@carrot/design-components-{name}": ["../design-components-{name}/src/index.ts"]
    }
  },
  "include": ["src"]
}

src/types.ts pattern

Re-export component-level style types from @carrot/design-components-{name}, then define Vue prop interfaces on top:

ts
// Re-export style types from the CSS/component layer
export type { {Name}Variant, {Name}Size } from '@carrot/design-components-{name}'

// Vue prop interfaces
export interface Carrot{Name}Props {
  variant?: {Name}Variant
  size?: {Name}Size
  disabled?: boolean
  // ... additional Vue-level props
}

SFC authoring conventions

Class names come from the design-components package. Do not write <style> blocks in Vue SFCs — class names are provided by the CSS layer.

Enum props use data-variant and data-size HTML attributes:

vue
<template>
  <button
    v-bind="$attrs"
    :class="classes"
    :data-variant="variant"
    :data-size="size"
    :data-loading="loading || undefined"
    :disabled="disabled || undefined"
  >
    <slot />
  </button>
</template>

Boolean data attributes use :data-flag="flag || undefined". Passing undefined removes the attribute from the DOM entirely, avoiding data-flag="false" pollution.

Attribute inheritance must be disabled and manually applied to the root element:

vue
<script setup lang="ts">
defineOptions({ inheritAttrs: false })
</script>

<template>
  <div v-bind="$attrs" :class="rootClass">
    <slot />
  </div>
</template>

Optional props should always use withDefaults:

vue
<script setup lang="ts">
import type { Carrot{Name}Props } from '../types'

const props = withDefaults(defineProps<Carrot{Name}Props>(), {
  variant: 'primary',
  size: 'md',
  disabled: false,
})
</script>

Prefer semantic HTML and ARIA over custom data attributes for conveying state. Use aria-disabled, aria-expanded, role, aria-label, etc., rather than data attributes for accessibility-relevant information.

Barrel (src/index.ts)

Export components, then re-export all types and constants:

ts
// Components
export { default as Carrot{Name} } from './components/Carrot{Name}.vue'

// Types
export type { Carrot{Name}Props, {Name}Variant, {Name}Size } from './types'

// Constants (re-export from design-components layer)
export { {NAME}_VARIANTS, {NAME}_SIZES } from '@carrot/design-components-{name}'

Provide / Inject Pattern

Compound components (tabs, dropdown, form, menu, list) share state via Vue's provide/inject rather than prop drilling or a global store.

ts
// types.ts
export interface TabsContext {
  activeTab: Ref<string>
  setActiveTab: (id: string) => void
}

export const TABS_INJECTION_KEY: InjectionKey<TabsContext> = Symbol('CarrotTabs')
vue
<!-- CarrotTabs.vue (parent) -->
<script setup lang="ts">
import { provide, ref } from 'vue'
import { TABS_INJECTION_KEY } from '../types'

const activeTab = ref(props.modelValue ?? '')
provide(TABS_INJECTION_KEY, {
  activeTab,
  setActiveTab: (id) => { activeTab.value = id },
})
</script>
vue
<!-- CarrotTab.vue (child) -->
<script setup lang="ts">
import { inject } from 'vue'
import { TABS_INJECTION_KEY } from '../types'

const tabs = inject(TABS_INJECTION_KEY)
</script>

Composable Conventions

  • Name with use prefix: useModal, usePagination, useSliderDrag
  • Return reactive refs or computed values, not raw values
  • Register cleanup in onUnmounted (remove event listeners, cancel timers, abort fetch)
  • Accept options as a single typed options object for forward compatibility
  • Do not call composables conditionally
ts
// Example pattern
export function useProgressTimer(options: ProgressTimerOptions) {
  const elapsed = ref(0)
  let timer: ReturnType<typeof setInterval> | null = null

  function start() {
    timer = setInterval(() => { elapsed.value += options.step ?? 100 }, options.step ?? 100)
  }

  function stop() {
    if (timer !== null) clearInterval(timer)
  }

  onUnmounted(stop)

  return { elapsed: readonly(elapsed), start, stop }
}

Accessibility Baseline

Every component must meet these requirements:

  • Semantic HTML: use <button>, <nav>, <ul>, <dialog>, etc., not <div> everywhere
  • ARIA attributes: aria-label / aria-labelledby, aria-expanded, aria-selected, aria-disabled, role where native semantics are insufficient
  • Keyboard navigation: interactive components must be fully operable via keyboard
  • Focus management: modals and dropdowns must trap / restore focus
  • No CSS-only state: do not rely solely on data-* attributes for state that screen readers need to understand

Checklist for New Vue Packages

  • [ ] package.json has version 0.9.0, Vue as peerDependency, and the correct @carrot/design-components-{name} dependency
  • [ ] vite.config.ts externalizes vue and all /^@carrot\//
  • [ ] No <style> blocks in SFCs
  • [ ] defineOptions({ inheritAttrs: false }) + v-bind="$attrs" on root element
  • [ ] All optional props use withDefaults
  • [ ] Boolean data-* attributes use || undefined to avoid false-valued attributes
  • [ ] Compound components use provide/inject with a typed InjectionKey
  • [ ] Composables clean up in onUnmounted
  • [ ] Barrel (src/index.ts) exports components, types, and constants
  • [ ] Semantic HTML and ARIA requirements met
  • [ ] Package added to @carrot/design-vue umbrella re-exports

@carrot/design-vue — Usage Guide

AI-optimized reference. Each section is self-contained and copy-paste ready.


Quick Start

1. Install

bash
npm install @carrot/design-vue @carrot/design-components

2. Load CSS

CSS is not bundled in @carrot/design-vue. You must import it separately before your app mounts:

ts
// main.ts
import { createApp } from 'vue'
import '@carrot/design-components/dist/style.css'
import App from './App.vue'

createApp(App).mount('#app')

3. Import components

ts
import {
  CarrotButton,
  CarrotModal,
  CarrotInput,
  useModal,
} from '@carrot/design-vue'

Component Usage Patterns

CarrotButton

vue
<template>
  <!-- Variants -->
  <CarrotButton variant="primary">Save</CarrotButton>
  <CarrotButton variant="secondary">Cancel</CarrotButton>
  <CarrotButton variant="ghost">Learn more</CarrotButton>
  <CarrotButton variant="danger">Delete</CarrotButton>

  <!-- Sizes -->
  <CarrotButton size="sm">Small</CarrotButton>
  <CarrotButton size="md">Medium</CarrotButton>
  <CarrotButton size="lg">Large</CarrotButton>

  <!-- Loading state -->
  <CarrotButton :loading="isSaving" variant="primary">
    {{ isSaving ? 'Saving…' : 'Save' }}
  </CarrotButton>

  <!-- Disabled -->
  <CarrotButton :disabled="!isValid" variant="primary">Submit</CarrotButton>

  <!-- Custom color (cascades --color-accent) -->
  <CarrotButton color="#e85d04">Custom</CarrotButton>

  <!-- Polymorphic: render as <a> -->
  <CarrotButton as="a" href="/docs" target="_blank">View docs</CarrotButton>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { CarrotButton } from '@carrot/design-vue'

const isSaving = ref(false)
const isValid = ref(true)
</script>

CarrotBadge

vue
<template>
  <!-- Variants -->
  <CarrotBadge variant="success">Active</CarrotBadge>
  <CarrotBadge variant="warning">Pending</CarrotBadge>
  <CarrotBadge variant="danger">Error</CarrotBadge>
  <CarrotBadge variant="neutral">Draft</CarrotBadge>

  <!-- Auto-color from value string -->
  <CarrotBadge :autoColor="true">marine</CarrotBadge>

  <!-- Dismissible -->
  <CarrotBadge
    v-for="tag in tags"
    :key="tag"
    dismissible
    @dismiss="removeTag(tag)"
  >
    {{ tag }}
  </CarrotBadge>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { CarrotBadge } from '@carrot/design-vue'

const tags = ref(['ocean', 'reef', 'survey'])

function removeTag(tag: string) {
  tags.value = tags.value.filter(t => t !== tag)
}
</script>

CarrotCard with sections

vue
<template>
  <CarrotCard>
    <CarrotCardMedia>
      <img src="/survey-photo.jpg" alt="Survey site aerial view" />
    </CarrotCardMedia>
    <CarrotCardHeader>
      <h3>Reef Survey — Site A</h3>
    </CarrotCardHeader>
    <CarrotCardBody>
      <p>Coral coverage recorded at 68% across 12 transects.</p>
    </CarrotCardBody>
    <CarrotCardFooter>
      <CarrotButton variant="primary" size="sm">View Report</CarrotButton>
      <CarrotButton variant="ghost" size="sm">Share</CarrotButton>
    </CarrotCardFooter>
  </CarrotCard>
</template>

<script setup lang="ts">
import { CarrotCard, CarrotCardHeader, CarrotCardBody, CarrotCardFooter, CarrotCardMedia, CarrotButton } from '@carrot/design-vue'
</script>

CarrotInput with label and validation

vue
<template>
  <CarrotInput
    v-model="email"
    label="Email address"
    type="email"
    placeholder="you@example.com"
    :error="emailError"
    :required="true"
  />
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { CarrotInput } from '@carrot/design-vue'

const email = ref('')

const emailError = computed(() => {
  if (!email.value) return 'Email is required'
  if (!email.value.includes('@')) return 'Enter a valid email address'
  return ''
})
</script>

CarrotModal with useModal

vue
<template>
  <CarrotButton variant="primary" @click="modal.open()">
    Open Modal
  </CarrotButton>

  <CarrotModal :open="modal.isOpen.value" @close="modal.close()">
    <CarrotModalHeader>Confirm deletion</CarrotModalHeader>
    <CarrotModalBody>
      <p>This action cannot be undone. Are you sure you want to delete this survey?</p>
    </CarrotModalBody>
    <CarrotModalFooter>
      <CarrotButton variant="ghost" @click="modal.close()">Cancel</CarrotButton>
      <CarrotButton variant="danger" @click="handleDelete">Delete</CarrotButton>
    </CarrotModalFooter>
  </CarrotModal>
</template>

<script setup lang="ts">
import {
  CarrotButton,
  CarrotModal,
  CarrotModalHeader,
  CarrotModalBody,
  CarrotModalFooter,
  useModal,
} from '@carrot/design-vue'

const modal = useModal()

function handleDelete() {
  // perform delete
  modal.close()
}
</script>

CarrotTable with useTableSort

vue
<template>
  <CarrotTable
    :columns="columns"
    :rows="sortedRows"
    :sort="sort"
    @sort="setSort"
  />
</template>

<script setup lang="ts">
import { CarrotTable, useTableSort } from '@carrot/design-vue'

const rows = [
  { id: 1, site: 'Site A', coverage: 68, date: '2025-03-01' },
  { id: 2, site: 'Site B', coverage: 42, date: '2025-03-04' },
  { id: 3, site: 'Site C', coverage: 81, date: '2025-02-28' },
]

const columns = [
  { key: 'site',     label: 'Site',          sortable: true },
  { key: 'coverage', label: 'Coverage (%)',   sortable: true },
  { key: 'date',     label: 'Survey Date',    sortable: true },
]

const { sort, sortedRows, setSort } = useTableSort(rows, { key: 'date', direction: 'desc' })
</script>

CarrotToast with toast() imperative API

vue
<template>
  <!-- Mount once at app root -->
  <CarrotToastContainer />

  <CarrotButton variant="primary" @click="handleSave">Save changes</CarrotButton>
</template>

<script setup lang="ts">
import { CarrotToastContainer, CarrotButton, toast } from '@carrot/design-vue'

async function handleSave() {
  try {
    await saveData()
    toast.success('Changes saved successfully.')
  } catch (err) {
    toast.error('Save failed. Please try again.')
  }
}
</script>

All toast variants:

ts
toast.success('Done!')
toast.error('Something went wrong.')
toast.warning('Low disk space.')
toast.info('New version available.')
toast('Custom message', { duration: 8000, dismissible: true })

CarrotForm with useCarrotForm

vue
<template>
  <CarrotForm :form="form" @submit="handleSubmit">
    <CarrotInput
      v-model="form.fields.name.value"
      label="Full name"
      :error="form.fields.name.error"
    />
    <CarrotInput
      v-model="form.fields.email.value"
      label="Email"
      type="email"
      :error="form.fields.email.error"
    />
    <CarrotButton
      type="submit"
      variant="primary"
      :loading="form.isSubmitting.value"
      :disabled="!form.isValid.value"
    >
      Submit
    </CarrotButton>
  </CarrotForm>
</template>

<script setup lang="ts">
import {
  CarrotForm,
  CarrotInput,
  CarrotButton,
  useCarrotForm,
  createFormValidator,
} from '@carrot/design-vue'

const form = useCarrotForm({
  name: {
    initial: '',
    rules: [createFormValidator.required('Name is required')],
  },
  email: {
    initial: '',
    rules: [
      createFormValidator.required('Email is required'),
      createFormValidator.email('Enter a valid email'),
    ],
  },
})

async function handleSubmit() {
  if (!form.validate()) return
  await submitToApi(form.values())
}
</script>

CarrotPagination with usePagination

vue
<template>
  <ul>
    <li v-for="item in pageItems" :key="item.id">{{ item.name }}</li>
  </ul>

  <CarrotPagination
    :current="pagination.currentPage.value"
    :total="pagination.totalPages.value"
    @change="pagination.goTo"
  />
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { CarrotPagination, usePagination } from '@carrot/design-vue'

const allItems = Array.from({ length: 87 }, (_, i) => ({ id: i + 1, name: `Survey ${i + 1}` }))

const pagination = usePagination({ total: allItems.length, pageSize: 10 })

const pageItems = computed(() =>
  allItems.slice(pagination.offset.value, pagination.offset.value + 10)
)
</script>

Loading CSS

@carrot/design-vue ships no CSS. Class names are defined in @carrot/design-components. You must load styles separately.

Option A — Umbrella CSS (simplest)

ts
import '@carrot/design-components/dist/style.css'

Option B — Individual CSS packages (smaller bundles)

ts
import '@carrot/design-components-buttons/dist/style.css'
import '@carrot/design-components-inputs/dist/style.css'
import '@carrot/design-components-modals/dist/style.css'

Match each @carrot/design-vue-* package you use with its corresponding @carrot/design-components-* CSS package.


Tree-Shaking

Modern bundlers (Vite, webpack 5+) tree-shake the umbrella automatically. To guarantee the smallest possible bundle or to avoid loading unneeded packages in a micro-frontend, import directly from individual packages:

ts
// Instead of:
import { CarrotButton } from '@carrot/design-vue'

// Import from the leaf package:
import { CarrotButton } from '@carrot/design-vue-buttons'

Custom Color via color Prop

Passing a color prop to most components sets the --color-accent CSS custom property on the root element. Child elements that reference --color-accent inherit the override automatically.

vue
<CarrotButton color="#0077b6">Ocean blue</CarrotButton>
<CarrotProgressBar :value="72" color="#e9c46a" />
<CarrotBadge color="#2a9d8f">Custom</CarrotBadge>

The value is applied as an inline style: style="--color-accent: #0077b6". This does not affect sibling or parent elements.


Umbrella vs Individual Packages

ScenarioUse
Standard application@carrot/design-vue umbrella
Micro-frontend with strict budgetIndividual @carrot/design-vue-* packages
Only need one or two components in a libraryIndividual packages to avoid transitive deps
Building a new Carrot Vue packageIndividual packages as peer/dev dependencies
Prototyping or internal toolsUmbrella — fastest to set up

The umbrella is the default choice. Switch to individual packages only when bundle size or dependency isolation is a hard constraint.


Package Contents

@carrot/design-vue-avatars

Import: import { CarrotAvatar, CarrotAvatarGroup, getInitials } from "@carrot/design-vue-avatars";CSS required: @import "@carrot/design-components-avatars";

Components

CarrotAvatar · CarrotAvatarGroup

Key Props

name (required) · src · thumbSrc · size (xs/sm/md/lg/xl) · status (online/offline/busy/away) · bgColor · fgColor · ring · clickable · loading

Utilities

getInitials(name, max?)

Demo: Design System demo


@carrot/design-vue-badges

Import: import { CarrotBadge, CarrotBadgeCount, CarrotDot } from "@carrot/design-vue-badges";CSS required: @import "@carrot/design-components-badges";

Components

CarrotBadge · CarrotBadgeCount · CarrotDot

Key Props

CarrotBadge: label (required) · variant · size (sm/md/lg) · pill · interactive · dismissible · autoColor · bgColor · fgColorCarrotBadgeCount: count (required) · max · hideZero · pulse · variantCarrotDot: variant · color · pulse · ariaLabel

Demo: Design System demo


@carrot/design-vue-buttons

Import: import { CarrotButton, CarrotButtonGroup } from "@carrot/design-vue-buttons";CSS required: @import "@carrot/design-components-buttons";

Components

CarrotButton · CarrotButtonGroup

Key Props

CarrotButton: variant (primary/secondary/ghost/danger/link) · size (sm/md/lg) · shape (default/circle) · loading · full · icon · disabled · color · as · typeCarrotButtonGroup: role (group/toolbar) · label

Demo: Design System demo


@carrot/design-vue-calendar

Import: import { CarrotCalendar, CarrotCalendarHeader, CarrotCalendarEvent, CarrotCalendarMonthEvent, CarrotCalendarEventPopover, CarrotCalendarDayView, CarrotCalendarWeekView, CarrotCalendarMonthView, CarrotCalendarYearView, CarrotCalendarNowIndicator } from "@carrot/design-vue-calendar";CSS required: @import "@carrot/design-components-calendar";

Components

CarrotCalendar · CarrotCalendarHeader · CarrotCalendarDayView · CarrotCalendarWeekView · CarrotCalendarMonthView · CarrotCalendarYearView · CarrotCalendarEvent · CarrotCalendarMonthEvent · CarrotCalendarNowIndicator · CarrotCalendarEventPopover

Key Props

modelValue · view · events · weekStart · slotInterval · showWeekNumbers · showAllDay · compact · timezone · editable · workingHoursStart · workingHoursEnd · workingHoursMode · weekDays · event · variant · size · selected · dragging · continued · continues · open · anchor · isRecurring

Key Events

update:modelValue · update:view · event:click · event:dblclick · event:drop · event:resize · slot:click · date:click · more:click · series:edit · event:delete · edit:this · edit:future · edit:all

Types

CalendarEventData · PositionedEvent · CalendarContext · CalendarEmits · CarrotCalendarProps · CarrotCalendarHeaderProps · CarrotCalendarEventProps · CarrotCalendarMonthEventProps · CarrotCalendarMultiDayBarProps · CarrotCalendarEventPopoverProps · CALENDAR_INJECTION_KEY

Composables

useCalendarNavigation() · useCalendarEvents() · useCalendarGrid() · useCalendarDrag() · useNowIndicator()

Demo: Design System demo


@carrot/design-vue-cards

Import: import { CarrotCard, CarrotCardHeader, CarrotCardBody, CarrotCardFooter, CarrotCardMedia } from "@carrot/design-vue-cards";CSS required: @import "@carrot/design-components-cards";

Components

CarrotCard · CarrotCardHeader · CarrotCardBody · CarrotCardFooter · CarrotCardMedia

Key Props

CarrotCard: variant (default/elevated/outlined/ghost/gradient/gradient-subtle/gradient-elevated) · size (sm/md/lg) · interactive · horizontal · seamless · flush · as · hrefCarrotCardMedia: position (top/bottom)

Demo: Design System demo


@carrot/design-vue-charts

Import: import { CarrotChartHeatmap, CarrotChartLegend, CarrotChartLegendGradient, useHeatmapIntensity } from "@carrot/design-vue-charts";CSS required: @import "@carrot/design-components-charts";

Components

CarrotChartHeatmap · CarrotChartLegend · CarrotChartLegendGradient

Key Props

CarrotChartHeatmap: rows (required) · xLabels · yLabels · min · max · size (sm/md/lg) · colorScale · rounded · seamless · interactive · ariaLabelCarrotChartLegend: items (required) · layout (horizontal/vertical) CarrotChartLegendGradient: minLabel · maxLabel

Composables

useHeatmapIntensity()

Demo: Design System demo


@carrot/design-vue-core

Import: import { CarrotPanel, CarrotLink, CarrotLabel, CarrotDivider, CarrotHidden, CarrotOverflowRow, CarrotShortcut } from "@carrot/design-vue-core";CSS required: @import "@carrot/design-components-core";

Components

CarrotPanel · CarrotLink · CarrotLabel · CarrotDivider · CarrotHidden · CarrotOverflowRow · CarrotShortcut

Key Props

CarrotPanel: variant (default/outlined/raised/ghost) · size (sm/md/lg/xl) · flush · as · sectionCarrotLink: href · to · variant (accent/muted/inherit) · external · active · disabled · asCarrotLabel: for · size (sm/md/lg) · required · disabledCarrotDivider: orientation (horizontal/vertical) · ariaLabelCarrotOverflowRow: items (requires id) · gapCarrotHidden: focusable · asCarrotShortcut: keys · ctrl · shift · alt · meta · size (sm/md) · listen · preventDefault

Demo: Design System demo


@carrot/design-vue-dropdowns

Import: import { CarrotDropdown, CarrotDropdownTrigger, CarrotDropdownMenu, CarrotDropdownItem, CarrotDropdownGroup, CarrotDropdownDivider } from "@carrot/design-vue-dropdowns";CSS required: @import "@carrot/design-components-dropdowns";

Components

CarrotDropdown · CarrotDropdownTrigger · CarrotDropdownMenu · CarrotDropdownItem · CarrotDropdownGroup · CarrotDropdownDivider

Key Props

CarrotDropdown: open (v-model) · closeOnSelect · closeOnClickOutside · closeOnEscapeCarrotDropdownMenu: align · fullCarrotDropdownItem: value · variant · href · disabled · selected

Composables

useClickOutside() · useMenuKeyboard()

Demo: Design System demo


@carrot/design-vue-forms

Import: import { CarrotForm, useCarrotForm, useFormField, required, email, minLength, maxLength, pattern, url, min, max, matches, custom, createFormValidator, toFormData, dirtyValues } from "@carrot/design-vue-forms";CSS required: none (pure logic package)

Components

CarrotForm

Key Props

CarrotForm: initial-values (required) · validate · validate-on (change/blur/submit) · no-form-error · id · autocomplete

Composables

useCarrotForm() · useFormField()

Validation Rules

required() · email() · minLength() · maxLength() · pattern() · url() · min() · max() · matches() · custom() · createFormValidator()

Utilities

toFormData() · dirtyValues()

Demo: Design System demo


@carrot/design-vue-graphs

Import: import { CarrotGraphBar, CarrotGraphLine, CarrotGraphPie, CarrotGraphSparkline, CarrotGraphRadar, CarrotGraphLegend, CarrotGraphTooltip, CarrotGraphEmpty } from "@carrot/design-vue-graphs";CSS required: @import "@carrot/design-components-graphs";

Components

CarrotGraphBar · CarrotGraphLine · CarrotGraphPie · CarrotGraphSparkline · CarrotGraphRadar · CarrotGraphLegend · CarrotGraphTooltip · CarrotGraphEmpty

Key Props

All charts: width · height · ratio · legend · legendPosition · tooltip · animate · ariaLabelCarrotGraphBar: series · horizontal · stacked · barRadiusCarrotGraphLine: series · curve · points · areaCarrotGraphPie: data · innerRadius · labelsCarrotGraphRadar: axes · series · gridStyle · gridLevels · max · fillCarrotGraphSparkline: data · color · area · showExtremes

Composables

useSeriesColors() · resolveSeriesColor() · useGraphDimensions() · useTooltip() · useRadarGeometry()

Demo: Design System demo


@carrot/design-vue-hotspots

Import: import { CarrotHotspot, CarrotHotspotOverlay, CarrotHotspotOverlayItem, CarrotHotspotInfoPanel, useHotspots, useHotspotsContext } from "@carrot/design-vue-hotspots";CSS optional: @carrot/design-vue-hotspots/overlay.css (overlay + info panel styles)

Components

CarrotHotspot · CarrotHotspotOverlay · CarrotHotspotOverlayItem · CarrotHotspotInfoPanel

Key Props

CarrotHotspot: id (required) · meta · tagCarrotHotspotOverlay: defs (required) · active · colorCarrotHotspotOverlayItem: def (required) · entry (required) · selected · colorCarrotHotspotInfoPanel: open · placement · anchor · margin · autoFlip

Composables

useHotspots() · useHotspotsContext()Demo: Design System demo


@carrot/design-vue-images

Import: import { CarrotImage, CarrotBgImage, CarrotPicture, CarrotSvg, useImageLoad, useLazyLoad, useImageQueue, useRadius, useSvgFetch } from "@carrot/design-vue-images";CSS required: none (styles are inline/scoped)

Components

CarrotImage · CarrotBgImage · CarrotPicture · CarrotSvg

Key Props

CarrotImage: src · thumbSrc · alt · srcset · sizes · width · height · fit · loading · crossfade · duration · radius · asCarrotBgImage: src · thumbSrc · fit · position · fixed · overlay · ariaLabelCarrotPicture: all CarrotImage props (except as, srcset, sizes) · sourcesCarrotSvg: src · alt · width · height · radius · colors

Composables

useImageLoad() · useLazyLoad() · useImageQueue() · useRadius() · useSvgFetch()

Demo: Design System demo


@carrot/design-vue-inputs

Import: import { CarrotInput, CarrotInputNumber, CarrotInputNumberPin, CarrotInputGroup, CarrotTextArea, CarrotCheckbox, CarrotCheckboxGroup, CarrotRadio, CarrotRadioGroup } from "@carrot/design-vue-inputs";CSS required: @import "@carrot/design-components-inputs";

Components

CarrotInput · CarrotInputNumber · CarrotInputNumberPin · CarrotInputGroup · CarrotTextArea · CarrotCheckbox · CarrotCheckboxGroup · CarrotRadio · CarrotRadioGroup

Key Props

CarrotInput: modelValue · type · size (sm/md/lg) · label · error · success · required · rules · validateOn · debounce · showCount · maxlengthCarrotInputNumber: modelValue · min · max · step · precision · controls · nullableCarrotInputNumberPin: modelValue · digits (default 6) · size (sm/md/lg) · masked · disabled · error · autofocus · ariaLabelCarrotInputGroup: label · direction (vertical/horizontal) · seamless · errorCarrotTextArea: modelValue · rows · autoResize · maxRows · showCount · resizableCarrotCheckbox: modelValue · value · label · indeterminateCarrotRadio / CarrotRadioGroup: modelValue · value · name · horizontal

Composables

useInputField() · useAutoResize()

Demo: Design System demo


@carrot/design-vue-lists

Import: import { CarrotList, CarrotListItem, CarrotListGroup, CarrotListDivider, CarrotListEmpty, CarrotTransferList, CarrotTransferPanel } from "@carrot/design-vue-lists";CSS required: @import "@carrot/design-components-lists";

Components

CarrotList · CarrotListItem · CarrotListGroup · CarrotListDivider · CarrotListEmpty · CarrotTransferList · CarrotTransferPanel

Key Props

CarrotList: variant · size (sm/md/lg) · divided · striped · hoverable · interactive · flush · reorderable · selectionMode (none/single/multi) · selected (v-model) CarrotListItem: value · label · description · disabledCarrotListGroup: labelCarrotListEmpty: messageCarrotTransferList: items · modelValue (v-model) · sourceTitle · targetTitle · reorderable · filterable · crossDrag · variant · sizeCarrotTransferPanel: panelId · items · title · showCount · checkable · draggable · accepts · reorderable · filterable · emptyText · variant · size

Types

DragPosition ("above" | "below")

Demo: Design System demo


@carrot/design-vue-menus

Import: import { CarrotMenu, CarrotMenuItem, CarrotMenuGroup, CarrotMenuDivider, CarrotMenuFlyout } from "@carrot/design-vue-menus";CSS required: @import "@carrot/design-components-menus";

Components

CarrotMenu · CarrotMenuItem · CarrotMenuGroup · CarrotMenuFlyout · CarrotMenuDivider

Key Props

nav · horizontal · compact · label · active · disabled · href · to · as · chevron · expanded · trail · collapsible · trigger · align · open

Composables

useMenuKeyboard()

Demo: Design System demo


@carrot/design-vue-modals

Import: import { CarrotModal, CarrotModalHeader, CarrotModalBody, CarrotModalFooter, useModal, useFocusTrap, useScrollLock } from "@carrot/design-vue-modals";CSS required: @import "@carrot/design-components-modals";

Components

CarrotModal · CarrotModalHeader · CarrotModalBody · CarrotModalFooter

Key Props

CarrotModal: open (v-model) · size (sm/md/lg/xl/full) · variant · drawer · drawerSide (left/right) · noBackdrop · beforeClose · centered · seamless · closeOnBackdrop · closeOnEscape · trapFocus · lockScroll · teleport · noClose · initialFocusCarrotModalHeader: srOnlyCarrotModalFooter: split

Composables

useModal() · useFocusTrap() · useScrollLock()

Demo: Design System demo


@carrot/design-vue-pagination

Import: import { CarrotPagination } from "@carrot/design-vue-pagination";CSS required: @import "@carrot/design-components-pagination";

Components

CarrotPagination

Key Props

page · totalPages · siblings · showPrevNext · prevLabel · nextLabel · disabled · ariaLabel

Composables

usePagination()

Demo: Design System demo


@carrot/design-vue-progress

Import: import { CarrotProgressBar, CarrotProgressRing } from "@carrot/design-vue-progress";CSS required: @import "@carrot/design-components-progress";

Components

CarrotProgressBar · CarrotProgressRing

Key Props

value · min · max · size · variant · color · autoThresholds · label · formatLabel · indeterminate · striped · animated · shimmer · strokeWidth · showLabel

Composables

useProgress() · useProgressTimer()

Demo: Design System demo


@carrot/design-vue-responsive

Import: import { CarrotResponsiveContainer, CarrotResponsiveGrid, CarrotResponsiveStack, useContainerBreakpoint } from "@carrot/design-vue-responsive";CSS required: @import "@carrot/design-components-responsive";

Components

CarrotResponsiveContainer · CarrotResponsiveGrid · CarrotResponsiveStack

Key Props

tag · type · name · cols · colsXs · colsSm · colsMd · colsLg · colsXl · cols2xl · breakpoint

Composables

useContainerBreakpoint()

Demo: Design System demo


@carrot/design-vue-sliders

Import: import { CarrotSlider } from "@carrot/design-vue-sliders";CSS required: @import "@carrot/design-components-sliders";

Components

CarrotSlider

Key Props

modelValue · min · max · step · range · size · orientation · thumbShape · color · tooltip · marks · formatValue · disabled

Composables

useSliderDrag()

Demo: Design System demo


@carrot/design-vue-spinners

Import: import { CarrotSpinner, CarrotSpinnerOverlay, CarrotSkeleton } from "@carrot/design-vue-spinners";CSS required: @import "@carrot/design-components-spinners";

Components

CarrotSpinner · CarrotSpinnerOverlay · CarrotSkeleton

Key Props

size · color · label · stacked · ariaLabel · visible · shape · lines · width · height · static

Demo: Design System demo


@carrot/design-vue-tables

Import: import { CarrotTable, useTableSort, useTableSelection } from "@carrot/design-vue-tables";CSS required: @import "@carrot/design-components-tables";

Components

CarrotTable

Key Props

columns · items · rowKey · sort · variant · size · striped · hoverable · interactive · fixedHeader · emptyText · rowSelected · rowDisabled

Composables

useTableSort() · useTableSelection()

Demo: Design System demo


@carrot/design-vue-tabs

Import: import { CarrotTabs, CarrotTabList, CarrotTab, CarrotTabPanels, CarrotTabPanel } from "@carrot/design-vue-tabs";CSS required: @import "@carrot/design-components-tabs";

Components

CarrotTabs · CarrotTabList · CarrotTab · CarrotTabPanels · CarrotTabPanel

Key Props

modelValue · defaultValue · mountStrategy · variant · scrollable · full · name · disabled · badge

Demo: Design System demo


@carrot/design-vue-timeline

Import: import { CarrotTimeline, CarrotTimelineRuler, CarrotTimelineTrack, CarrotTimelineTrackGroup, CarrotTimelineBlock, CarrotTimelineMarker, CarrotTimelinePlayhead, CarrotTimelineGrid, CarrotTimelineWaveform, CarrotTimelineSelection } from "@carrot/design-vue-timeline";CSS required: @import "@carrot/design-components-timeline";

Components

CarrotTimeline · CarrotTimelineRuler · CarrotTimelineTrackGroup · CarrotTimelineTrack · CarrotTimelineBlock · CarrotTimelineMarker · CarrotTimelinePlayhead · CarrotTimelineGrid · CarrotTimelineWaveform · CarrotTimelineSelection

Key Props

duration · currentTime · playing · density · snap · snapping · looping · pixelsPerUnit · start · label · variant · selected · resizable · draggable · kind · muted · solo · locked

Composables

useTimeline() · useTimelinePlayback() · useTimelineDrag() · useTimelineSelection() · useTimelineKeyboard() · useTimelineZoom()

Demo: Design System demo


@carrot/design-vue-toasts

Import: import { toast, CarrotToastContainer, useToast } from "@carrot/design-vue-toasts";CSS required: @import "@carrot/design-components-toasts";

Components

CarrotToastContainer · CarrotToast

Key Props

position · limit · mode · pauseOnHover · defaultDuration

Composables

useToast()

Imperative API

toast() · toast.success() · toast.warning() · toast.danger() · toast.info() · toast.promise() · toast.dismiss() · toast.dismissAll() · toast.update()

Demo: Design System demo


@carrot/design-vue-toggles

Import: import { CarrotToggle } from "@carrot/design-vue-toggles";CSS required: @import "@carrot/design-components-toggles";

Components

CarrotToggle

Key Props

modelValue · size · disabled · label · labelPosition · name · value · required · ariaLabel · ariaLabelledby · ariaDescribedby

Demo: Design System demo


@carrot/design-vue-uploads

Import: import { CarrotUploadZone, CarrotUploadList, CarrotUploadItem, CarrotUploadIndicator, useUploadQueue } from "@carrot/design-vue-uploads";CSS required: @import "@carrot/design-components-uploads";

Components

CarrotUploadZone · CarrotUploadList · CarrotUploadItem · CarrotUploadIndicator

Key Props

accept · multiple · disabled · compact · directory · file · showPreview · removable · progress · active · total · complete · error

Composables

useUploadQueue()

Demo: Design System demo

Carrot