{# Star Rating Components ====================== Reusable star rating display and input for product reviews. Usage: {% from 'shared/macros/storefront/star-rating.html' import star_rating, rating_input, rating_summary %} #} {# Star Rating Display =================== Static star rating display. Parameters: - rating: Numeric rating value (0-5) - rating_var: Alpine.js expression for rating (dynamic) - max: Maximum stars (default: 5) - size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' (default: 'md') - show_value: Show numeric value (default: false) - show_count: Show review count (default: false) - count: Number of reviews - count_var: Alpine.js expression for count - precision: 'full' | 'half' | 'exact' (default: 'half') - color: Star color class (default: 'text-yellow-400') - empty_color: Empty star color (default: 'text-gray-300 dark:text-gray-600') Usage: {{ star_rating(rating=4.5) }} {{ star_rating(rating_var='product.rating', show_count=true, count_var='product.review_count') }} #} {% macro star_rating( rating=none, rating_var=none, max=5, size='md', show_value=false, show_count=false, count=none, count_var=none, precision='half', color='text-yellow-400', empty_color='text-gray-300 dark:text-gray-600' ) %} {% set sizes = { 'xs': 'w-3 h-3', 'sm': 'w-4 h-4', 'md': 'w-5 h-5', 'lg': 'w-6 h-6', 'xl': 'w-8 h-8' } %} {% set text_sizes = { 'xs': 'text-xs', 'sm': 'text-sm', 'md': 'text-sm', 'lg': 'text-base', 'xl': 'text-lg' } %}
{% if rating is not none %} {# Static rating #}
{% for i in range(1, max + 1) %} {% if precision == 'half' %} {% set fill = 'full' if rating >= i else ('half' if rating >= i - 0.5 else 'empty') %} {% elif precision == 'exact' %} {% set fill_percent = ((rating - (i - 1)) * 100) | int %} {% set fill_percent = [0, [fill_percent, 100] | min] | max %} {% else %} {% set fill = 'full' if rating >= i - 0.5 else 'empty' %} {% endif %} {% if precision == 'exact' %} {% elif fill == 'half' %} {% else %} {% endif %} {% endfor %}
{% if show_value %} {{ rating }} {% endif %} {% if show_count and count is not none %} ({{ count }}) {% endif %} {% elif rating_var %} {# Dynamic rating from Alpine.js #}
{% if show_value %} {% endif %} {% if show_count and count_var %} {% elif show_count and count is not none %} ({{ count }}) {% endif %} {% endif %}
{% endmacro %} {# Rating Input ============ Interactive star rating input for submitting reviews. Parameters: - model: Alpine.js model for rating value (default: 'rating') - max: Maximum stars (default: 5) - size: 'sm' | 'md' | 'lg' (default: 'md') - allow_half: Allow half-star ratings (default: false) - allow_clear: Allow clearing rating (default: true) - disabled_var: Alpine.js expression for disabled state - on_change: Callback when rating changes Usage: {{ rating_input(model='reviewRating') }} {{ rating_input(model='rating', size='lg', allow_half=true) }} #} {% macro rating_input( model='rating', max=5, size='md', allow_half=false, allow_clear=true, disabled_var=none, on_change=none ) %} {% set sizes = { 'sm': 'w-6 h-6', 'md': 'w-8 h-8', 'lg': 'w-10 h-10' } %}
{% for i in range(1, max + 1) %} {% endfor %} {# Rating label #}
{% endmacro %} {# Rating Summary ============== Rating distribution summary (typically shown on product pages). Parameters: - rating_var: Alpine.js expression for average rating - count_var: Alpine.js expression for total reviews - distribution_var: Alpine.js expression for distribution object {5: count, 4: count, ...} - show_bars: Show distribution bars (default: true) - size: 'sm' | 'md' | 'lg' (default: 'md') Usage: {{ rating_summary(rating_var='product.rating', count_var='product.review_count', distribution_var='product.rating_distribution') }} #} {% macro rating_summary( rating_var='rating', count_var='reviewCount', distribution_var='ratingDistribution', show_bars=true, size='md' ) %} {% set sizes = { 'sm': {'star': 'w-4 h-4', 'text': 'text-3xl', 'bar_h': 'h-1.5'}, 'md': {'star': 'w-5 h-5', 'text': 'text-4xl', 'bar_h': 'h-2'}, 'lg': {'star': 'w-6 h-6', 'text': 'text-5xl', 'bar_h': 'h-2.5'} } %}
{# Average Rating #}
Based on reviews
{% if show_bars %} {# Rating Distribution #}
{% for i in range(5, 0, -1) %}
{{ i }}
{% endfor %}
{% endif %}
{% endmacro %} {# Compact Rating ============== Inline compact rating for lists and cards. Parameters: - rating: Static rating value - rating_var: Alpine.js expression for rating - count: Review count - count_var: Alpine.js expression for count - size: 'xs' | 'sm' | 'md' (default: 'sm') Usage: {{ compact_rating(rating=4.5, count=127) }} {{ compact_rating(rating_var='item.rating', count_var='item.reviews') }} #} {% macro compact_rating( rating=none, rating_var=none, count=none, count_var=none, size='sm' ) %} {% set sizes = { 'xs': {'star': 'w-3 h-3', 'text': 'text-xs'}, 'sm': {'star': 'w-4 h-4', 'text': 'text-sm'}, 'md': {'star': 'w-5 h-5', 'text': 'text-base'} } %}
{% if rating is not none %} {{ rating }} {% if count is not none %} ({{ count }}) {% endif %} {% elif rating_var %} {% if count_var %} {% elif count is not none %} ({{ count }}) {% endif %} {% endif %}
{% endmacro %}