Patterns · AhaSlides surfaces
Status badge
A glanceable lifecycle pill for a domain object — draft, published, closed, archived, active, inactive.
Examples
Status
Domain lifecycle · dot + label · colour never alone
<!-- Paste-and-run: save as .html and open in a browser. No build step.
<aha-status-badge> is the SAME shared custom element React and Vue consume — here in its
native form. Theming comes only from the --aha-* tokens in tokens.css. -->
<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-status-badge.js'; // registers <aha-status-badge>
</script>
<div style="display:flex; gap:12px; align-items:center; flex-wrap:wrap">
<aha-status-badge status="draft">Draft</aha-status-badge>
<aha-status-badge status="published">Published</aha-status-badge>
<aha-status-badge status="closed">Closed</aha-status-badge>
<aha-status-badge status="archived">Archived</aha-status-badge>
<aha-status-badge status="active">Active</aha-status-badge>
<aha-status-badge status="inactive">Inactive</aha-status-badge>
</div>
import '@ahaslides-product/design/aha-status-badge'; // registers <aha-status-badge>
import { t } from 'i18next'; // label comes from i18n, never a hardcoded string
// Attributes only — no events — so React 18/19 can render the element directly.
function AhaStatusBadge({ status }) {
return <aha-status-badge status={status}>{t(`survey_status.${status}`)}</aha-status-badge>;
}
// usage
<AhaStatusBadge status={survey.status} />
// main.ts — register the element + mark aha-* as custom elements
import '@ahaslides-product/design/aha-status-badge';
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');
// Component.vue
<script setup>
import { useI18n } from 'vue-i18n'; // label comes from i18n, never a hardcoded string
const { t } = useI18n();
defineProps({ status: String });
</script>
<template>
<aha-status-badge :status="status">{{ t(`survey_status.${status}`) }}</aha-status-badge>
</template>
API
| Prop | Type | Default | Notes |
|---|---|---|---|
status | draft | published | closed | archived | active | inactive | draft | The lifecycle state — drives the pill and dot colour via a CSS-only persistent node |
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-status-badge'; // registers <aha-status-badge>
Agent feed for this component (absolute, fetchable anywhere): status-badge.agent.json · status-badge.md · status-badge.llms.txt
When to use
When to use
- Status badge — reflecting a value from a known status enum (a survey/presentation/collector's lifecycle state)
- Tag — a free-form label, keyword or category chip
- Badge — a count or a bare notification dot
Use only for a value from a real status enum — not free-form labels, counts, or notification dots (those are Tag / Badge). Always keep the text label; the dot colour is decorative and never the sole signal.
Surfaces
dashboard editor settings
Spec
Shape height 22 · radius pill · dot 6 + label · Draft neutral #F7F7F7 · dot #B5B5B5 · Published positive #D8FAEF / #13A181 · dot #16C49A · Closed warning #FFF5F0 / #E65B29 · dot #FF7747 · Archived muted #F3F3F3 / #8A8A8A · dot #8A8A8A · Active positive #D8FAEF / #13A181 · dot #16C49A · Inactive neutral #F3F3F3 / #8A8A8A · dot #B5B5B5