Appearance
Checkbox
FTCheckbox supports two visual modes: Classic (default, pink box) and Tick (FTDNA design-system, ink fill with check/minus glyph). Pass the tick prop to opt in; existing usage renders unchanged.
Usage
vue
<script lang="ts" setup>
import { FTCheckbox } from '@fasttrack-solutions/vue-components-lib';
</script><script lang="ts" setup>
import { FTCheckbox } from '@fasttrack-solutions/vue-components-lib';
</script>Playground
Properties
Boolean (v-model)
Prop
Medium
Value: false
<script setup lang="ts">
import { ref } from 'vue';
const checked = ref(false);
</script>
<template>
<FTCheckbox
v-model="checked"
label="Checkbox Label"
/>
</template>
Binding modes
Single boolean
Bind a boolean ref directly — the checkbox toggles between true and false.
vue
<script lang="ts" setup>
import { ref } from 'vue';
const checked = ref(false);
</script>
<template>
<FTCheckbox v-model="checked" label="Accept terms" />
</template><script lang="ts" setup>
import { ref } from 'vue';
const checked = ref(false);
</script>
<template>
<FTCheckbox v-model="checked" label="Accept terms" />
</template>Array (multi-select)
When modelValue is an array, set value on each checkbox — checked items are added/removed from the array.
vue
<script lang="ts" setup>
import { ref } from 'vue';
const checkedGenres = ref(['Drama', 'Horror']);
</script>
<template>
<FTCheckbox v-model="checkedGenres" value="Drama">Drama</FTCheckbox>
<FTCheckbox v-model="checkedGenres" value="Horror">Horror</FTCheckbox>
<FTCheckbox v-model="checkedGenres" value="Comedy">Comedy</FTCheckbox>
</template><script lang="ts" setup>
import { ref } from 'vue';
const checkedGenres = ref(['Drama', 'Horror']);
</script>
<template>
<FTCheckbox v-model="checkedGenres" value="Drama">Drama</FTCheckbox>
<FTCheckbox v-model="checkedGenres" value="Horror">Horror</FTCheckbox>
<FTCheckbox v-model="checkedGenres" value="Comedy">Comedy</FTCheckbox>
</template>Custom true/false values
Use trueValue / falseValue to bind non-boolean scalars instead of true/false.
vue
<script lang="ts" setup>
import { ref } from 'vue';
const answer = ref<'yes' | 'no'>('no');
</script>
<template>
<FTCheckbox v-model="answer" trueValue="yes" falseValue="no" label="Opt in" />
</template><script lang="ts" setup>
import { ref } from 'vue';
const answer = ref<'yes' | 'no'>('no');
</script>
<template>
<FTCheckbox v-model="answer" trueValue="yes" falseValue="no" label="Opt in" />
</template>Visual-only (checked prop)
checked doesn't bind data — use it for read-only displays where you only need to show state.
vue
<template>
<FTCheckbox checked label="Read-only checked state" />
</template><template>
<FTCheckbox checked label="Read-only checked state" />
</template>Label sources
There are three ways to provide a label: the label prop, the default slot, or neither (checkbox only). All three work identically across classic and tick modes.
vue
<template>
<FTCheckbox label="Via prop" />
<FTCheckbox>Via slot</FTCheckbox>
<FTCheckbox />
</template><template>
<FTCheckbox label="Via prop" />
<FTCheckbox>Via slot</FTCheckbox>
<FTCheckbox />
</template>Tick mode
Opt in with the tick prop — feature set is identical to classic (supports indeterminate, size, justified, flipped, all binding modes); only the visual changes. To recolor the checked fill, override --ft-tickbox-ink at the call site — it also drives hover, so idle/hover/checked stay consistent.
Statuses
- Unchecked — white fill, gray border
- Checked — ink fill, white check glyph
- Indeterminate — white fill, ink border, ink minus glyph
- Disabled — muted fill, no pointer
- Disabled · checked — faint-on-faint with a dim glyph
Props
| Name | Type | Default | Description |
|---|---|---|---|
modelValue | boolean | string | number | Array<any> | false | v-model binding; supports array mode for multi-select |
value | boolean | string | number | '' | Value added to array when modelValue is an array |
label | string | '' | Label text (or use default slot) |
trueValue | boolean | string | number | true | Value emitted when checked |
falseValue | boolean | string | number | false | Value emitted when unchecked |
flipped | boolean | false | Swap label and control positions |
disabled | boolean | false | Disable interaction |
checked | boolean | false | Visual-only checked override |
tick | boolean | false | Use the FTDNA tick visual instead of the legacy pink box |
justified | boolean | false | Fill width; label takes remaining space |
indeterminate | boolean | false | Third visual state (mixed/partial); minus glyph in both modes |
size | 'small' | 'medium' | 'large' | 'medium' | Control size: 14 / 18 / 22 px |
CSS (tick mode)
| CSS Variable | Default Value | Description |
|---|---|---|
--ft-tickbox-size | 18px | Box edge length (overridden by size modifier) |
--ft-tickbox-radius | 4px | Corner radius |
--ft-tickbox-glyph-size | 10px | Glyph (check / minus) size |
--ft-tickbox-ink | var(--color-mono-700, #2c2c2c) | Default fill + border when checked |
--ft-tickbox-surface | var(--color-mono-white) | Box background when unchecked/indeterminate |
--ft-tickbox-border-idle | var(--color-mono-400, #cacaca) | Border when unchecked |
--ft-tickbox-disabled-bg | var(--color-mono-200, #f0f0f0) | Background when disabled |
--ft-tickbox-disabled-border | var(--color-mono-300, #e0e0e0) | Border when disabled |
--ft-tickbox-disabled-glyph | var(--color-mono-100, #fafafa) | Glyph color when disabled-checked |
--ft-tickbox-ink-hover | var(--color-mono-900, #000) | Fill/border on hover when checked |
--ft-tickbox-focus-ring | var(--color-secondary-denim-600, #88b3dc) | Focus-visible outline color |
--ft-tickbox-focus-halo | color-mix(in srgb, var(--ft-tickbox-focus-ring) 25%, transparent) | Focus-visible outer halo color |