Components · Forms
Checkbox
Let a user turn one or more independent options on or off.
Examples
State
Indeterminate
Disabled
Checkbox · the playground drives this one element (State · Indeterminate · Disabled)
States · rest · checked · indeterminate · disabled
Group · a select-all that drives indeterminate
<!-- Paste-and-run: save as .html and open in a browser. No build step.
<aha-checkbox> is the SAME shared custom element React and Vue consume.
Initial state is declarative (`checked`); it emits a composed `change` event. -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/tokens.css">
<script type="module">
import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/aha-checkbox.js'; // registers <aha-checkbox>
</script>
<aha-checkbox id="anon" checked>Let participants join anonymously</aha-checkbox>
<script>
// Plain DOM — no framework. Read e.detail.checked off the composed CustomEvent.
document.getElementById('anon').addEventListener('change', (e) => {
console.log('anonymous:', e.detail.checked);
});
</script>
import '@ahaslides-product/design/aha-checkbox'; // registers <aha-checkbox>
import { useRef, useEffect } from 'react';
// React 18 needs a thin wrapper; React 19 can use <aha-checkbox> directly.
function AhaCheckbox({ checked, indeterminate, disabled, onChange, children }) {
const ref = useRef();
useEffect(() => {
const el = ref.current;
el.checked = !!checked;
el.indeterminate = !!indeterminate;
el.disabled = !!disabled;
const h = (e) => onChange?.(e.detail.checked); // composed CustomEvent
el.addEventListener('change', h);
return () => el.removeEventListener('change', h);
});
return <aha-checkbox ref={ref}>{children}</aha-checkbox>;
}
// usage
<AhaCheckbox checked={anon} onChange={setAnon}>
Let participants join anonymously
</AhaCheckbox>
// main.ts — register the element + mark aha-* as custom elements
import '@ahaslides-product/design/aha-checkbox';
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');
// Component.vue
<script setup>
import { ref } from 'vue';
const anon = ref(false);
</script>
<template>
<aha-checkbox
:checked.prop="anon"
@change="anon = $event.detail.checked"
>
Let participants join anonymously
</aha-checkbox>
</template>
API
| Prop | Type | Default | Notes |
|---|---|---|---|
checked | boolean | false | Controlled selection |
indeterminate | boolean | false | Mixed state for check-all |
disabled | boolean | false | Disables the control |
change | CustomEvent<{checked}> | — | Composed event; read e.detail.checked |
Install
# .npmrc — once: point the @ahaslides-product scope at GitHub Packages
@ahaslides-product:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} # a GitHub token with read:packages
npm i @ahaslides-product/design
import '@ahaslides-product/design/tokens.css'; // once, at the app root
import '@ahaslides-product/design/aha-checkbox'; // registers <aha-checkbox>
Agent feed for this component (absolute, fetchable anywhere): checkbox.agent.json · checkbox.md · checkbox.llms.txt
When to use
When to use
- Checkbox — one or more independent options; applies on submit
- Radio — exactly one from a small mutually-exclusive set
- Switch — a single setting that takes effect immediately
Labels are sentence case and state what the control does — 'Let participants join anonymously', not 'Join Anonymously'. Keep product nouns: Q&A, Word cloud.
Surfaces
editor dashboard settings audience
Spec
Box 14×14 r4 · Rest border #B4BCCF · Hover border #D3B4FF · Checked fill #6A1EBB + white 12px tick · Label Plus Jakarta 14/21