Skip to main content

Overlays

Rating code

Copy the implementation or inspect every file that belongs to this component unit.

resources/views/components/ui/rating.blade.php

@props([
    'name' => null,
    'value' => 0,
    'max' => 5,
    'readonly' => false,
    'size' => 'lg',
])

@php
    /*
    | Star rating. Interactive by default (click to set, hover to preview) or set
    | `readonly` to display a static score. Submits the value via a hidden input
    | when `name` is set.
    |
    | Usage:
    |   <x-ui.rating name="score" :value="3" />
    |   <x-ui.rating :value="4" readonly size="sm" />
    */
    $max = (int) $max;
@endphp

<div
    x-data="{
        value: @js((int) $value),
        hover: 0,
        readonly: @js((bool) $readonly),
        set(n) { if (! this.readonly) { this.value = (this.value === n) ? 0 : n; } },
    }"
    {{ $attributes->merge(['class' => 'inline-flex items-center gap-0.5']) }}
    @mouseleave="hover = 0"
    role="radiogroup"
>
    @if ($name)
        <input type="hidden" name="{{ $name }}" :value="value">
    @endif

    @for ($i = 1; $i <= $max; $i++)
        <button
            type="button"
            @if ($readonly) tabindex="-1" disabled @endif
            @click="set({{ $i }})"
            @mouseenter="hover = {{ $i }}"
            :class="(hover || value) >= {{ $i }} ? 'text-amber-400' : 'text-gray-300 dark:text-gray-600'"
            class="{{ $readonly ? 'cursor-default' : 'cursor-pointer transition hover:scale-110' }} leading-none focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 rounded"
            aria-label="{{ $i }} star{{ $i > 1 ? 's' : '' }}"
        >
            <x-ui.icon name="star" weight="fill" :size="$size" />
        </button>
    @endfor
</div>