Components · Data Entry
Rate
Capture or display a score as a row of stars.
Examples
Half-step
Count
Character
Disabled
Interactive · click or hover to rate
States · value 3 (probe) · half-step 3.5 · custom heart character · readonly · disabled
<!-- Paste-and-run: save as .html and open in a browser. No build step.
<aha-rate> is the SAME shared custom element React and Vue consume.
Initial score is declarative (`value`); 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-rate.js'; // registers <aha-rate>
</script>
<aha-rate id="score" value="3" count="5"></aha-rate>
<!-- half-step selection: <aha-rate value="3.5" count="5" allow-half></aha-rate> -->
<!-- custom DS character: <aha-rate value="4" icon="system-heart-straight"></aha-rate> -->
<!-- read-only display: <aha-rate value="4" readonly></aha-rate> -->
<script>
// Plain DOM — no framework. Read e.detail.value off the composed CustomEvent.
document.getElementById('score').addEventListener('change', (e) => {
console.log('rating:', e.detail.value);
});
</script>
import '@ahaslides-product/design/aha-rate'; // registers <aha-rate>
import { useRef, useEffect } from 'react';
// React 18 needs a thin wrapper; React 19 can use <aha-rate> directly.
function AhaRate({ value, count = 5, allowHalf, icon, readonly, disabled, onChange }) {
const ref = useRef();
useEffect(() => {
const el = ref.current;
el.value = value ?? 0;
const h = (e) => onChange?.(e.detail.value); // composed CustomEvent
el.addEventListener('change', h);
return () => el.removeEventListener('change', h);
});
return <aha-rate ref={ref} count={count} icon={icon || undefined}
allow-half={allowHalf || undefined} readonly={readonly || undefined} disabled={disabled || undefined} />;
}
// usage — whole-star, half-step, and a custom DS character
<AhaRate value={score} onChange={setScore} />
<AhaRate value={3.5} allowHalf onChange={setScore} />
<AhaRate value={4} icon="system-heart-straight" onChange={setScore} />
// main.ts — register the element + mark aha-* as custom elements
import '@ahaslides-product/design/aha-rate';
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');
// Component.vue
<script setup>
import { ref } from 'vue';
const score = ref(3);
</script>
<template>
<aha-rate
:value.prop="score"
:count="5"
@change="score = $event.detail.value"
/>
<!-- half-step + a custom DS character -->
<aha-rate :value.prop="score" :count="5" allow-half @change="score = $event.detail.value" />
<aha-rate :value.prop="score" icon="system-heart-straight" @change="score = $event.detail.value" />
</template>
API
| Prop | Type | Default | Notes |
|---|---|---|---|
value | number | 0 | Current score (0…count; .5 steps with allow-half) |
count | number | 5 | Number of stars (DS V3 name; `max` is an alias) |
allow-half | boolean | false | Half-star selection — the left half of a star scores n−0.5 |
allow-clear | boolean | false | Click the current value again to clear to 0 |
icon | string | — | Custom character: a DS icon name (e.g. system-heart-straight) drawn instead of the star |
readonly | boolean | false | Display only — no interaction |
disabled | boolean | false | Dims and disables the control |
change | CustomEvent<{value}> | — | Composed event; read e.detail.value |
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-rate'; // registers <aha-rate>
Agent feed for this component (absolute, fetchable anywhere): rate.agent.json · rate.md · rate.llms.txt
When to use
When to use
- Rate — a subjective score on a small fixed scale — a review, a difficulty, satisfaction
- Segmented — picking one labelled option from a few, not a magnitude
- Slider — a continuous value across a wide range
Keep the scale small (5 is the norm). Pair with a short label — 'Rate this session' — and show the chosen value nearby for confirmation.
Surfaces
editor dashboard audience
Spec
Star 24×24, gap 4 · Filled yellow-50 #FFE32C · Empty gray-40 #E3E3E3 · Half filled overlay clipped to 50% (allow-half) · Character any DS icon by name via `icon` (outline, brand-tinted) · Hover scale 1.12, fill preview to cursor (half-precise)