# Rating Star rating component with customizable count, icons, and read-only mode. ## Tag `Rating` ## Props | Prop | Type | Default | Description | | :----------- | :--------------------------- | :--------------- | :----------------------------------------------- | | `value` | `number \| Signal` | `0` | Current rating value | | `count` | `number \| Signal` | `5` | Number of stars/items | | `mask` | `string` | `'mask-star'` | Mask shape (mask-star, mask-star-2, mask-heart) | | `readonly` | `boolean \| Signal` | `false` | Disable interaction | | `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | ## Live Examples ### Basic Rating

Live Demo

```javascript const BasicDemo = () => { const rating = $(3); return Div({ class: 'flex flex-col gap-2 items-center' }, [ Rating({ value: rating, count: 5, onchange: (value) => rating(value) }), Div({ class: 'text-sm opacity-70' }, () => `Rating: ${rating()} / 5`) ]); }; $mount(BasicDemo, '#demo-basic'); ``` ### Heart Rating

Live Demo

```javascript const HeartDemo = () => { const rating = $(4); return Div({ class: 'flex flex-col gap-2 items-center' }, [ Rating({ value: rating, count: 5, mask: 'mask-heart', onchange: (value) => rating(value) }), Div({ class: 'text-sm opacity-70' }, () => `${rating()} hearts`) ]); }; $mount(HeartDemo, '#demo-heart'); ``` ### Star with Outline

Live Demo

```javascript const Star2Demo = () => { const rating = $(2); return Div({ class: 'flex flex-col gap-2 items-center' }, [ Rating({ value: rating, count: 5, mask: 'mask-star-2', onchange: (value) => rating(value) }), Div({ class: 'text-sm opacity-70' }, () => `${rating()} stars`) ]); }; $mount(Star2Demo, '#demo-star2'); ``` ### Read-only Rating

Live Demo

```javascript const ReadonlyDemo = () => { const rating = $(4.5); return Div({ class: 'flex flex-col gap-2 items-center' }, [ Rating({ value: rating, count: 5, readonly: true }), Div({ class: 'text-sm opacity-70' }, 'Average rating: 4.5/5 (read-only)') ]); }; $mount(ReadonlyDemo, '#demo-readonly'); ``` ### Custom Count

Live Demo

```javascript const CustomDemo = () => { const rating = $(3); const count = $(10); return Div({ class: 'flex flex-col gap-4 w-full' }, [ Div({ class: 'flex items-center gap-4' }, [ Span({ class: 'text-sm' }, 'Number of stars:'), Input({ type: 'number', value: count, class: 'input input-sm w-24', oninput: (e) => count(parseInt(e.target.value) || 1) }) ]), Rating({ value: rating, count: count, onchange: (value) => rating(value) }), Div({ class: 'text-sm opacity-70' }, () => `Rating: ${rating()} / ${count()}`) ]); }; $mount(CustomDemo, '#demo-custom'); ``` ### Product Review

Live Demo

```javascript const ReviewDemo = () => { const quality = $(4); const price = $(3); const support = $(5); const average = () => Math.round(((quality() + price() + support()) / 3) * 10) / 10; return Div({ class: 'flex flex-col gap-4' }, [ Div({ class: 'text-lg font-bold' }, 'Product Review'), Div({ class: 'flex flex-col gap-2' }, [ Div({ class: 'flex justify-between items-center' }, [ Span({ class: 'text-sm w-24' }, 'Quality:'), Rating({ value: quality, count: 5, size: 'sm', onchange: (v) => quality(v) }) ]), Div({ class: 'flex justify-between items-center' }, [ Span({ class: 'text-sm w-24' }, 'Price:'), Rating({ value: price, count: 5, size: 'sm', onchange: (v) => price(v) }) ]), Div({ class: 'flex justify-between items-center' }, [ Span({ class: 'text-sm w-24' }, 'Support:'), Rating({ value: support, count: 5, size: 'sm', onchange: (v) => support(v) }) ]) ]), Div({ class: 'divider my-1' }), Div({ class: 'flex justify-between items-center' }, [ Span({ class: 'font-bold' }, 'Overall:'), Div({ class: 'text-2xl font-bold text-primary' }, () => average()) ]) ]); }; $mount(ReviewDemo, '#demo-review'); ``` ### All Variants

Live Demo

```javascript const VariantsDemo = () => { return Div({ class: 'flex flex-col gap-6' }, [ Div({ class: 'text-center' }, [ Div({ class: 'text-sm mb-2' }, 'Mask Star'), Rating({ value: $(3), count: 5, mask: 'mask-star' }) ]), Div({ class: 'text-center' }, [ Div({ class: 'text-sm mb-2' }, 'Mask Star 2 (yellow)' ), Rating({ value: $(4), count: 5, mask: 'mask-star-2', class: 'rating-warning' }) ]), Div({ class: 'text-center' }, [ Div({ class: 'text-sm mb-2' }, 'Mask Heart'), Rating({ value: $(5), count: 5, mask: 'mask-heart', class: 'rating-error' }) ]), Div({ class: 'text-center' }, [ Div({ class: 'text-sm mb-2' }, 'Half Stars (read-only)'), Rating({ value: $(3.5), count: 5, readonly: true }) ]) ]); }; $mount(VariantsDemo, '#demo-variants'); ``` ### Interactive Feedback

Live Demo

```javascript const FeedbackDemo = () => { const rating = $(0); const feedback = $(false); const messages = { 1: 'Very disappointed 😞', 2: 'Could be better 😕', 3: 'Good 👍', 4: 'Very good 😊', 5: 'Excellent! 🎉' }; return Div({ class: 'flex flex-col gap-4 items-center' }, [ Div({ class: 'text-center' }, [ Div({ class: 'text-sm mb-2' }, 'How was your experience?'), Rating({ value: rating, count: 5, onchange: (value) => { rating(value); feedback(true); if (value >= 4) { Toast('Thank you for your positive feedback!', 'alert-success', 2000); } else if (value <= 2) { Toast('We appreciate your feedback and will improve!', 'alert-warning', 2000); } else { Toast('Thanks for your rating!', 'alert-info', 2000); } } }) ]), () => rating() > 0 ? Div({ class: 'alert alert-soft text-center' }, [ messages[rating()] || `Rating: ${rating()} stars` ]) : null ]); }; $mount(FeedbackDemo, '#demo-feedback'); ```