Angular Rating Component

Rating

CoreUI PRO
This component is part of CoreUI PRO – a powerful UI library with over 250 components and 25+ templates, designed to help you build modern, responsive apps faster. Fully compatible with Angular, Bootstrap, React.js, and Vue.js.

Angular star rating component allows users to rate and provide feedback on content or products by selecting a specified number of stars, typically ranging from one to five, representing their level of satisfaction or preference.

Available in Other JavaScript Frameworks

CoreUI Angular Rating Component is also available for Bootstrap, React, and Vue. Explore framework-specific implementations below:

Added in v5.1.0

Examples

Embed the Rating component in your Angular application like this:

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-example',
  standalone: true,
  imports: [RatingComponent],
  templateUrl: './rating-example.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RatingExampleComponent {}
<c-rating value="3" />

Allow clear

Enable users to clear their selected rating by clicking on the current rating again. This functionality is activated by setting allowClear boolean property.

import { Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-allow-clear',
  imports: [RatingComponent],
  templateUrl: './rating-allow-clear.component.html',
  styleUrl: './rating-allow-clear.component.scss'
})
export class RatingAllowClearComponent {}
<c-rating allowClear value="3" />

This allows the selected rating to be deselected, effectively resetting the rating to a state where no value is selected.

Resettable

Our Angular Rating component allows users to assign and reset a star rating within a user interface. In the example below, we use the a button to clear the selected value by passing null value.

import { Component, signal } from '@angular/core';
import { ButtonDirective, RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-resettable',
  imports: [RatingComponent, ButtonDirective],
  templateUrl: './rating-resettable.component.html'
})
export class RatingResettableComponent {
  readonly value = signal<number | null>(3);
}
<div class="d-flex align-items-center">
  <c-rating [(value)]="value" />
  <button cButton (click)="value.set(null)" class="ms-3">Reset</button>
</div>

Read only

Set the Angular Rating component to read-only by adding readOnly property. This disables interaction, preventing users from changing the displayed rating value.

import { Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-read-only',
  imports: [RatingComponent],
  templateUrl: './rating-read-only.component.html',
  styleUrl: './rating-read-only.component.scss'
})
export class RatingReadOnlyComponent {}
<c-rating readOnly value="3" />

Disabled

Add the disabled boolean property to give it a grayed out appearance, remove pointer events, and prevent focusing.

import { Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-disabled',
  imports: [RatingComponent],
  templateUrl: './rating-disabled.component.html',
  styleUrl: './rating-disabled.component.scss'
})
export class RatingDisabledComponent {}
<c-rating disabled value="3" />

Tooltips

Enable descriptive text on hover by adding tooltips prop. This provides immediate feedback or guidance as the user interacts with the rating items.

import { Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-tooltips',
  imports: [RatingComponent],
  templateUrl: './rating-tooltips.component.html',
  styleUrl: './rating-tooltips.component.scss'
})
export class RatingTooltipsComponent {}
<c-rating [tooltips]="true" value="3" />

For custom messages, provide an array of labels corresponding to each rating value to enhance the user’s understanding of each rating level.

import { Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-tooltips-2',
  imports: [RatingComponent],
  templateUrl: './rating-tooltips-2.component.html',
  styleUrl: './rating-tooltips-2.component.scss'
})
export class RatingTooltips2Component {}
<c-rating [tooltips]="['Very bad', 'Bad', 'Meh', 'Good', 'Very good']" value="3" />

Sizes

Larger or smaller Angular rating component? Add size="lg" or size="sm" for additional sizes.

import { Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-sizes',
  imports: [RatingComponent],
  templateUrl: './rating-sizes.component.html',
  styleUrl: './rating-sizes.component.scss'
})
export class RatingSizesComponent {}
<c-rating size="sm" value="3" />
<c-rating value="3" />
<c-rating size="lg" value="3" />
:host {
  .rating {
    display: flex;
  }
}

Precision

Adjust the granularity of the Rating component by setting precision prop. This attribute allows for fractional ratings, such as quarter values, to provide more precise feedback. Valid values: 1 | 0.5 | 0.25 | 0.125.

import { Component, signal } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-precision',
  imports: [RatingComponent],
  templateUrl: './rating-precision.component.html',
  styleUrl: './rating-precision.component.scss'
})
export class RatingPrecisionComponent {
  readonly value = signal(3);
}
<c-rating [(value)]="value" precision="0.25" />
<div>{{ value() }}</div>

Number of items

Control the total number of rating items displayed by using itemCount property. You can create a Angular Rating component with a custom scale, be it larger for detailed assessments or smaller for simplicity.

import { Component } from '@angular/core';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-number-of-items',
  imports: [RatingComponent],
  templateUrl: './rating-number-of-items.component.html',
  styleUrl: './rating-number-of-items.component.scss'
})
export class RatingNumberOfItemsComponent {}
<c-rating itemCount="20" value="7" />
<c-rating itemCount="3" value="1" />
:host {
  .rating {
    display: flex;
  }
}

Custom icons

Customize the Angular Rating component with your choice of SVG icons by assigning new values to the activeIcon and icon properties. This allows for a unique look tailored to the design language of your site or application.

The Rating component can be customized with either SVG or font icons, allowing for visual alignment with your application’s design. You can specify different icons for each rating value to enhance user interaction.

In the example below, we demonstrate how to set custom icons using SVG, allowing for detailed customization of the visual elements within the Rating component.

import { Component } from '@angular/core';
import { RatingComponent, TemplateIdDirective } from '@coreui/angular';
import { IconDirective } from '@coreui/icons-angular';
import { cilStar, cilCircle } from '@coreui/icons';

@Component({
  selector: 'docs-rating-custom-icons',
  imports: [RatingComponent, TemplateIdDirective, IconDirective],
  templateUrl: './rating-custom-icons.component.html',
})
export class RatingCustomIconsComponent {
  icons = { cilStar, cilCircle };
}
<c-rating value="3" icon="iconTemplate" activeIcon="activeIconTemplate">
  <ng-template cTemplateId="iconTemplate">
    <svg [cIcon]="icons.cilCircle" [class]="{icon: false}"></svg>
  </ng-template>
  <ng-template cTemplateId="activeIconTemplate">
    <svg [cIcon]="icons.cilStar" [class]="{icon: false}"></svg>
  </ng-template>
</c-rating>

In the example below, we use font icons from the CoreUI Icons set. In the activeIcon configuration, we also apply the utility class text-danger to change the icon’s color to red when it is active

import { Component } from '@angular/core';
import { RatingComponent, TemplateIdDirective } from '@coreui/angular';
import { IconModule } from '@coreui/icons-angular';
import { cilHeart } from '@coreui/icons';

@Component({
  selector: 'docs-rating-custom-icons-2',
  imports: [RatingComponent, TemplateIdDirective, IconModule],
  templateUrl: './rating-custom-icons-2.component.html',
})
export class RatingCustomIcons2Component {
  icons = { cilHeart };
}
<c-rating value="3" icon="iconTemplate" activeIcon="activeIconTemplate">
  <ng-template cTemplateId="iconTemplate">
    <svg [cIcon]="icons.cilHeart" size="lg"></svg>
  </ng-template>
  <ng-template cTemplateId="activeIconTemplate">
    <svg [cIcon]="icons.cilHeart" size="lg" class="text-danger"></svg>
  </ng-template>
</c-rating>

For a more dynamic experience, define different icons for each rating value, enhancing the visual feedback:

import { NgClass } from '@angular/common';
import { Component, inject, signal, OnInit, computed } from '@angular/core';
import { RatingComponent, TemplateIdDirective } from '@coreui/angular';
import { IconDirective, IconSetService } from '@coreui/icons-angular';
import { cilMoodVeryBad, cilMoodBad, cilMeh, cilMoodGood, cilMoodVeryGood } from '@coreui/icons';

@Component({
  selector: 'docs-rating-custom-icons-3',
  imports: [IconDirective, RatingComponent, TemplateIdDirective, NgClass],
  templateUrl: './rating-custom-icons-3.component.html',
})
export class RatingCustomIcons3Component implements OnInit {
  readonly #iconSetService = inject(IconSetService);
  readonly icons = signal<string[]>([]);
  readonly activeIcons = computed(() => this.icons().map((icon) => `active_${icon}`));

  readonly value = signal<number | null>(3);

  tooltips = ['Very bad', 'Bad', 'Meh', 'Good', 'Very good'];
  activeClass = ['text-dark', 'text-danger', 'text-warning', 'text-info', 'text-success'];

  ngOnInit(): void {
    this.#iconSetService.icons = {
      cilMoodVeryBad,
      cilMoodBad,
      cilMeh,
      cilMoodGood,
      cilMoodVeryGood,
    };
    this.icons.set(Object.keys(this.#iconSetService.icons));
  }
}
<c-rating [(value)]="value" [activeIcon]="activeIcons()" [icon]="icons()" [tooltips]="tooltips" highlightOnlySelected>
  @for (icon of icons(); track icon) {
    <ng-template [cTemplateId]="icon">
      <svg cIcon [name]="icon" size="xxl"></svg>
    </ng-template>
  }
  @for (icon of activeIcons(); track icon; let index = $index) {
    <ng-template [cTemplateId]="icon">
      <svg cIcon [name]="icons()[index]" size="xxl" [ngClass]="activeClass[index]"></svg>
    </ng-template>
  }
</c-rating>

Custom feedback

The Angular Rating component integrates interactive star ratings with dynamic textual feedback using other components from CoreUI. It enables users to select a rating that updates the display and label in real-time, enhancing the interactive experience. Hover effects provide immediate feedback on potential ratings before selection, ensuring an intuitive user interface.

import { Component, computed, model, signal } from '@angular/core';
import { BadgeComponent, RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-custom-feedback',
  imports: [RatingComponent, BadgeComponent],
  templateUrl: './rating-custom-feedback.component.html'
})
export class RatingCustomFeedbackComponent {
  readonly #labels = new Map([
    [1, 'Very bad'],
    [2, 'Bad'],
    [3, 'Meh'],
    [4, 'Good'],
    [5, 'Very good']
  ]);

  readonly currentValue = model(3);
  readonly hoverValue = signal<number | null>(null);
  readonly label = computed(() => this.#labels.get(this.hoverValue() ?? this.currentValue() ?? 0));
}
<div class="d-flex align-items-center">
  <span class="me-3">{{ currentValue() ?? 0 }}/5</span>
  <c-rating
    [value]="currentValue()"
    (valueChange)="currentValue.set($event)"
    (hoverValueChange)="hoverValue.set($event)"
  />
  @if (label()) {
    <c-badge class="ms-3" color="dark">{{ label() }}</c-badge>
  }
</div>

Forms

Angular handles user input through reactive and template-driven forms. CoreUI Time Picker supports both types.

Reactive

import { JsonPipe } from '@angular/common';
import { Component, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { RatingComponent } from '@coreui/angular';

@Component({
  selector: 'docs-rating-reactive',
  imports: [RatingComponent, ReactiveFormsModule, JsonPipe],
  templateUrl: './rating-reactive.component.html'
})
export class RatingReactiveComponent {
  readonly formGroup = new FormGroup({
    ratingControl: new FormControl<null | number>(3, { nonNullable: false })
  });

  readonly formValue = signal(this.formGroup.value);

  constructor() {
    this.formGroup.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => {
      this.formValue.set(value);
    });
  }
}
<form [formGroup]="formGroup">
  <c-rating formControlName="ratingControl" allowClear />
</form>

<br>
Form value: {{ formValue() | json }}

Template driven

import { Component, signal } from '@angular/core';
import { RatingComponent } from '@coreui/angular';
import { JsonPipe } from '@angular/common';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'docs-rating-template-driven',
  imports: [FormsModule, JsonPipe, RatingComponent],
  templateUrl: './rating-template-driven.component.html'
})
export class RatingTemplateDrivenComponent {
  readonly rating = signal<number | null>(3);
}
<form #form="ngForm">
  <c-rating [(ngModel)]="rating" name="ratingControl" allowClear />
</form>

<br>
Form value: {{ form.value | json }}

Signal forms

import { JsonPipe } from '@angular/common';
import { Component, signal } from '@angular/core';
import { form, FormField, required } from '@angular/forms/signals';
import { RatingComponent, FormFeedbackComponent } from '@coreui/angular';

interface RatingFormModel {
  rating: number | null;
}

@Component({
  selector: 'docs-rating-signal-forms',
  imports: [RatingComponent, FormField, JsonPipe, FormFeedbackComponent],
  templateUrl: './rating-signal-forms.component.html'
})
export class RatingSignalFormsComponent {

  readonly ratingModel = signal<RatingFormModel>({
    rating: 3
  });

  readonly ratingForm = form(this.ratingModel, (schemaPath) => {
    required(schemaPath.rating, { message: 'Rating is required' });
  });
}
@let ctrl = ratingForm.rating();

<form>
  <c-rating [formField]="ratingForm.rating" allowClear [class]="{'is-invalid': ctrl.invalid(), 'is-valid': !ctrl.invalid()}" />
  @if (ctrl.invalid()) {
    @for (error of ctrl.errors(); track error) {
      <c-form-feedback [valid]="false">
        {{ error.message }}
      </c-form-feedback>
    }
  } @else {
  <c-form-feedback [valid]="true">
    Your rating: {{ ratingModel().rating }}
  </c-form-feedback>
  }
</form>

Customizing

CSS variables

Angular Rating use local CSS variables on .rating for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.

--cui-rating-gap: #{$rating-gap};
--cui-rating-transition: #{$rating-transition};
--cui-rating-item-height: #{$rating-item-height};
--cui-rating-item-color: #{$rating-item-color};
--cui-rating-item-scale-transform: #{$rating-item-scale-transform};
--cui-rating-item-active-color: #{$rating-item-active-color};
--cui-rating-item-icon: #{escape-svg($rating-item-icon)};

How to use CSS variables

const vars = {
  '--my-css-var': 10,
  '--my-another-css-var': "red"
}
<c-rating [ngStyle]="vars" />;

SASS variables

$rating-gap:                   .0625rem !default;
$rating-transition:            color .15s ease-out, transform .15s ease-out !default;
$rating-item-height-sm:        1rem !default;
$rating-item-height:           1.25rem !default;
$rating-item-height-lg:        1.5rem !default;
$rating-item-color:            var(--cui-tertiary-color) !default;
$rating-item-scale-transform:  scale(1.2) !default;
$rating-item-active-color:     var(--cui-warning) !default;
$rating-item-icon:             url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='currentColor' d='M470.935,194.043,333.8,171.757,270.227,48.22a16,16,0,0,0-28.454,0L178.2,171.757,41.065,194.043A16,16,0,0,0,32.273,221.1l97.845,98.636L108.936,457.051a16,16,0,0,0,23.02,16.724L256,411.2l124.044,62.576a16,16,0,0,0,23.02-16.724L381.882,319.74,479.727,221.1A16,16,0,0,0,470.935,194.043Z'%3E%3C/path%3E%3C/svg%3E") !default;

API reference

Rating Module

import { RatingModule } from '@coreui/angular-pro';

@NgModule({
    imports: [RatingModule,]
})
export class AppModule() { }

c-rating

component

jsx
import { RatingComponent } from '@coreui/angular-pro'

Props

PropertyDefaultType
activeIcon[]string[]

The default icon to display when the item is selected.

allowClearfalseboolean

Enables the clearing upon clicking the selected item again.

ariaLabel5.7.7+(value, itemCount) => `${value} of ${itemCount}`object

Function that returns the accessible label (aria-label) for each rating item. Receives the item's value and the total item count.

disabledfalseboolean

Toggle the disabled state for the component.

highlightOnlySelectedfalseboolean

If enabled, only the currently selected icon will be visibly highlighted.

icon[]string[]

The default icon to display when the item is not selected.

itemCount5number

Specifies the total number of stars to be displayed in the star rating component. This property determines the scale of the rating, such as out of 5 stars, 10 stars, etc.

precision1number

Minimum increment value change allowed.

readOnlyfalseboolean

Toggle the readonly state for the component.

sizeundefined'', 'sm', 'lg', 'custom'

Size the component small, large, or custom if you define custom icons with custom height.

tooltipsundefinedboolean, string[]

Enable tooltips with default values or set specific labels for each icon.

valuenullstring, number, null

The value attribute of component.

Events

Event name
hoverValueChange

Event emitted on mouseenter and mouseleave.

  • $event number | null
valueChange

Emitted when value changes.

  • $event string | number | null