Rating

Rating allows users to rate items with stars or other shapes. Supports labels, half stars, different masks, and reactive state binding.

Basic Examples

Rating components with various configurations

const { default: Rating } = await import('/components/data-input/rating.js');
const { tags, $ } = Lightview;
const { div, p } = tags;

// 1. Basic rating
const basic = Rating({ 
    defaultValue: 3
});

// 2. Rating with label
const withLabel = Rating({ 
    label: 'Rate this product',
    defaultValue: 4,
    max: 5
});

// 3. Rating with different colors and masks
const hearts = Rating({ 
    label: 'Love it?',
    defaultValue: 3,
    mask: 'heart',
    color: 'red-500'
});

// 4. Half stars
const halfStars = Rating({ 
    label: 'Precise rating',
    half: true,
    defaultValue: 3.5,
    hidden: true
});

// Insert all examples
$('#example').content(
    div({ style: 'display: flex; flex-direction: column; gap: 1.5rem' }, basic, withLabel, hearts, halfStars)
);
const { default: Rating } = await import('/components/data-input/rating.js');
const { $ } = Lightview;

const basic = {
    tag: Rating,
    attributes: { 
        defaultValue: 3
    }
};

const withLabel = {
    tag: Rating,
    attributes: { 
        label: 'Rate this product',
        defaultValue: 4,
        max: 5
    }
};

const hearts = {
    tag: Rating,
    attributes: { 
        label: 'Love it?',
        defaultValue: 3,
        mask: 'heart',
        color: 'red-500'
    }
};

const halfStars = {
    tag: Rating,
    attributes: { 
        label: 'Precise rating',
        half: true,
        defaultValue: 3.5,
        hidden: true
    }
};

$('#example').content({
    tag: 'div',
    attributes: { style: 'display: flex; flex-direction: column; gap: 1.5rem' },
    children: [basic, withLabel, hearts, halfStars]
});
const { default: Rating } = await import('/components/data-input/rating.js');
const { tags, $ } = Lightview;
tags.Rating = Rating;

$('#example').content({
    div: {
        style: 'display: flex; flex-direction: column; gap: 1.5rem',
        children: [
            { 
                Rating: { 
                    defaultValue: 3
                } 
            },
            { 
                Rating: { 
                    label: 'Rate this product',
                    defaultValue: 4,
                    max: 5
                } 
            },
            { 
                Rating: { 
                    label: 'Love it?',
                    defaultValue: 3,
                    mask: 'heart',
                    color: 'red-500'
                } 
            },
            { 
                Rating: { 
                    label: 'Precise rating',
                    half: true,
                    defaultValue: 3.5,
                    hidden: true
                } 
            }
        ]
    }
});

Reactive Example

Two-way binding with signals

const { default: Rating } = await import('/components/data-input/rating.js');
const { signal, tags, $ } = Lightview;
const { div, p, span } = tags;

// Signal for two-way binding
const rating = signal(0);

// Reactive rating demo
const reactiveDemo = div({ style: 'display: flex; flex-direction: column; gap: 1rem' },
    Rating({ 
        label: 'How was your experience?',
        value: rating,
        max: 5,
        size: 'lg',
        hidden: true,
        helper: 'Click to rate'
    }),
    div({ class: 'divider' }),
    p({ class: 'text-lg font-semibold' }, 
        () => {
            const val = rating.value;
            if (val === 0) return span({class: 'opacity-50'}, 'No rating yet');
            if (val <= 1) return span({class: 'text-error'}, '😞 Poor');
            if (val <= 2) return span({class: 'text-warning'}, '😐 Fair');
            if (val <= 3) return span({class: 'text-info'}, '🙂 Good');
            if (val <= 4) return span({class: 'text-success'}, '😊 Great');
            return span({class: 'text-primary'}, '🤩 Excellent!');
        }
    ),
    p({ class: 'text-sm font-mono opacity-70' },
        () => `Rating value: ${rating.value} / 5`
    )
);

$('#example').content(reactiveDemo);
const { default: Rating } = await import('/components/data-input/rating.js');
const { signal, $ } = Lightview;

const rating = signal(0);

const reactiveDemo = {
    tag: 'div',
    attributes: { style: 'display: flex; flex-direction: column; gap: 1rem' },
    children: [
        {
            tag: Rating,
            attributes: {
                label: 'How was your experience?',
                value: rating,
                max: 5,
                size: 'lg',
                hidden: true,
                helper: 'Click to rate'
            }
        },
        { tag: 'div', attributes: { class: 'divider' } },
        {
            tag: 'p',
            attributes: { class: 'text-lg font-semibold' },
            children: [
                () => {
                    const val = rating.value;
                    if (val === 0) return { tag: 'span', attributes: { class: 'opacity-50' }, children: ['No rating yet'] };
                    if (val <= 1) return { tag: 'span', attributes: { class: 'text-error' }, children: ['😞 Poor'] };
                    if (val <= 2) return { tag: 'span', attributes: { class: 'text-warning' }, children: ['😐 Fair'] };
                    if (val <= 3) return { tag: 'span', attributes: { class: 'text-info' }, children: ['🙂 Good'] };
                    if (val <= 4) return { tag: 'span', attributes: { class: 'text-success' }, children: ['😊 Great'] };
                    return { tag: 'span', attributes: { class: 'text-primary' }, children: ['🤩 Excellent!'] };
                }
            ]
        },
        {
            tag: 'p',
            attributes: { class: 'text-sm font-mono opacity-70' },
            children: [
                () => `Rating value: ${rating.value} / 5`
            ]
        }
    ]
};

$('#example').content(reactiveDemo);
const { default: Rating } = await import('/components/data-input/rating.js');
const { signal, tags, $ } = Lightview;
tags.Rating = Rating;

const rating = signal(0);

const reactiveDemo = {
    div: {
        style: 'display: flex; flex-direction: column; gap: 1rem',
        children: [
            {
                Rating: {
                    label: 'How was your experience?',
                    value: rating,
                    max: 5,
                    size: 'lg',
                    hidden: true,
                    helper: 'Click to rate'
                }
            },
            { div: { class: 'divider' } },
            {
                p: {
                    class: 'text-lg font-semibold',
                    children: [
                        () => {
                            const val = rating.value;
                            if (val === 0) return { span: { class: 'opacity-50', children: ['No rating yet'] } };
                            if (val <= 1) return { span: { class: 'text-error', children: ['😞 Poor'] } };
                            if (val <= 2) return { span: { class: 'text-warning', children: ['😐 Fair'] } };
                            if (val <= 3) return { span: { class: 'text-info', children: ['🙂 Good'] } };
                            if (val <= 4) return { span: { class: 'text-success', children: ['😊 Great'] } };
                            return { span: { class: 'text-primary', children: ['🤩 Excellent!'] } };
                        }
                    ]
                }
            },
            {
                p: {
                    class: 'text-sm font-mono opacity-70',
                    children: [
                        () => `Rating value: ${rating.value} / 5`
                    ]
                }
            }
        ]
    }
};

$('#example').content(reactiveDemo);

Props

Prop Type Default Description
value number | signal - Current rating value (reactive with signals)
defaultValue number 0 Default value for uncontrolled mode
max number 5 Maximum rating (number of stars)
label string - Label text displayed above the rating
helper string - Helper text displayed below the rating
half boolean false Allow half-star ratings
hidden boolean false Include hidden 0-star option for clearing
mask string 'star-2' 'star' | 'star-2' | 'heart' | 'circle' | 'square' | 'diamond'
color string 'orange-400' Tailwind color class for the rating icons
size string - 'xs' | 'sm' | 'md' | 'lg'
disabled boolean false Disable the rating
readOnly boolean false Make rating read-only (display only)
onChange function - Callback when rating changes: (rating) => void
useShadow boolean * Render in Shadow DOM

Sizes

Half Stars

Different Shapes

Hearts

Circles

Diamonds