md-rating spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
A subjective score on a small, discrete scale. Star (or custom-glyph) rating
with a configurable maximum, optional half-steps, a hover preview, and form
participation via ElementInternals. Not a Material Design 3 component — M3
has no rating page, so there is no spec to point at; the guidance here is house
rules derived from M3’s slider and icon-button pages plus this component’s own
behaviour.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="3" rating-label="Rate this product"></md-rating>
<md-rating value="4.5" precision="0.5" show-value-label rating-label="Average rating" readonly></md-rating>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="3" ratingLabel="Rate this product"></MdRating>
<MdRating value="4.5" precision="0.5" showValueLabel ratingLabel="Average rating" readonly></MdRating>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="3" rating-label="Rate this product"></md-rating>
<md-rating value="4.5" precision="0.5" show-value-label rating-label="Average rating" readonly></md-rating><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="3" rating-label="Rate this product"></md-rating>
<md-rating value="4.5" precision="0.5" show-value-label rating-label="Average rating" readonly></md-rating>
</template><script>
import '@awc-ui/core/define';
</script>
<md-rating value="3" rating-label="Rate this product"></md-rating>
<md-rating value="4.5" precision="0.5" show-value-label rating-label="Average rating" readonly></md-rating>
Already installed? See the
Installation guide for one-time package setup
(core + tokens, fonts). Each tab below shows two patterns for using
md-rating in your project: Option A registers every AWC UI
component at once (simplest), Option B imports only this component for
tree-shake-friendly bundles.
<!-- ─── Option A: global registration (all components) ─── -->
<script type="module">
import '@awc-ui/core/define';
</script>
<!-- ─── Option B: single import (tree-shake only md-rating) ─── -->
<script type="module">
import '@awc-ui/core/components/md-rating';
</script>
<md-rating></md-rating>// ─── Option A: typed React wrapper (registers all components) ───
// Importing from '@awc-ui/react' calls defineCustomElements() as a
// side effect, so every md-* element becomes available in the browser.
import { MdRating } from '@awc-ui/react';
export function Example() {
return <MdRating></MdRating>;
}
// ─── Option B: single import (tree-shake to only md-rating) ───
// Skip the wrapper and use the raw custom element. Smallest bundle,
// but you lose typed props/events on JSX.
import '@awc-ui/core/components/md-rating';
export function ExampleTreeShaken() {
return <md-rating></md-rating>;
}// ─── Option A: schema module (any md-* element accepted) ───
// Pair with `defineCustomElements(window)` in main.ts.
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<md-rating></md-rating>`,
})
export class ExampleComponent {}
// ─── Option B: typed directive (tree-shake friendly) ───
// Pair with `import '@awc-ui/core/components/md-rating'` in main.ts.
import { Component } from '@angular/core';
import { MdRating } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [MdRating],
template: `<md-rating></md-rating>`,
})
export class ExampleTreeShakenComponent {}<!-- ─── Option A: typed Vue wrapper (registers all components) ─── -->
<script setup lang="ts">
import { MdRating } from '@awc-ui/vue';
</script>
<template>
<MdRating></MdRating>
</template>
<!-- ─── Option B: single import (tree-shake to only md-rating) ─── -->
<script setup lang="ts">
import '@awc-ui/core/components/md-rating';
</script>
<template>
<md-rating></md-rating>
</template><!-- ─── Option A: global registration (done once in main entry) ─── -->
<!-- main.ts: -->
<!-- import { defineCustomElements } from '@awc-ui/svelte'; -->
<!-- defineCustomElements(window); -->
<md-rating></md-rating>
<!-- ─── Option B: single import (tree-shake to only md-rating) ─── -->
<script lang="ts">
import '@awc-ui/core/components/md-rating';
</script>
<md-rating></md-rating>| Situation | Use instead |
|---|---|
| An objective value on a continuum | md-slider |
| A precise number | md-text-field with type="number" |
| Binary like / dislike | md-icon-button with toggle |
| More than ~10 points of scale | md-slider |
| Progress toward completion | md-progress-indicator |
| A non-interactive status | md-badge / md-status-dot |
| Choosing among labelled options | md-radio / md-segmented-button |
| Need | Setting |
|---|---|
| A star scale the user sets | Default (interactive) |
| Display-only average | readonly |
| Half stars | precision="0.5" |
| More or fewer items | max |
| A numeric readout | show-value-label |
| Different glyphs | icon / empty-icon |
| No hover preview | hover="off" |
| Smaller glyphs | size, or --md-rating-item-size |
Five sizes. The default is md, unlike md-button
which defaults to sm.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="3" size="xs" rating-label="Extra small"></md-rating>
<md-rating value="3" size="sm" rating-label="Small"></md-rating>
<md-rating value="3" size="md" rating-label="Medium"></md-rating>
<md-rating value="3" size="lg" rating-label="Large"></md-rating>
<md-rating value="3" size="xl" rating-label="Extra large"></md-rating>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="3" size="xs" ratingLabel="Extra small"></MdRating>
<MdRating value="3" size="sm" ratingLabel="Small"></MdRating>
<MdRating value="3" size="md" ratingLabel="Medium"></MdRating>
<MdRating value="3" size="lg" ratingLabel="Large"></MdRating>
<MdRating value="3" size="xl" ratingLabel="Extra large"></MdRating>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="3" size="xs" rating-label="Extra small"></md-rating>
<md-rating value="3" size="sm" rating-label="Small"></md-rating>
<md-rating value="3" size="md" rating-label="Medium"></md-rating>
<md-rating value="3" size="lg" rating-label="Large"></md-rating>
<md-rating value="3" size="xl" rating-label="Extra large"></md-rating><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="3" size="xs" rating-label="Extra small"></md-rating>
<md-rating value="3" size="sm" rating-label="Small"></md-rating>
<md-rating value="3" size="md" rating-label="Medium"></md-rating>
<md-rating value="3" size="lg" rating-label="Large"></md-rating>
<md-rating value="3" size="xl" rating-label="Extra large"></md-rating>
</template><script>
import '@awc-ui/core/define';
</script>
<md-rating value="3" size="xs" rating-label="Extra small"></md-rating>
<md-rating value="3" size="sm" rating-label="Small"></md-rating>
<md-rating value="3" size="md" rating-label="Medium"></md-rating>
<md-rating value="3" size="lg" rating-label="Large"></md-rating>
<md-rating value="3" size="xl" rating-label="Extra large"></md-rating>Check the per-item hit target at small size and deep density — a 5-item scale
at xs gives very small targets on touch.
precision is 1 (whole steps) or 0.5 (half steps). With 0.5 the value
is fractional — don’t assume an integer.
max sets the number of items and defaults to 5. Keep it small; a 20-star
scale belongs in a md-slider.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="3" precision="1" show-value-label rating-label="Whole steps"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="7" max="10" show-value-label rating-label="Ten point scale"></md-rating>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="3" precision="1" showValueLabel ratingLabel="Whole steps"></MdRating>
<MdRating value="3.5" precision="0.5" showValueLabel ratingLabel="Half steps"></MdRating>
<MdRating value="7" max="10" showValueLabel ratingLabel="Ten point scale"></MdRating>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="3" precision="1" show-value-label rating-label="Whole steps"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="7" max="10" show-value-label rating-label="Ten point scale"></md-rating><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="3" precision="1" show-value-label rating-label="Whole steps"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="7" max="10" show-value-label rating-label="Ten point scale"></md-rating>
</template><script>
import '@awc-ui/core/define';
</script>
<md-rating value="3" precision="1" show-value-label rating-label="Whole steps"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="7" max="10" show-value-label rating-label="Ten point scale"></md-rating>show-value-label prints the numeric value beside the glyphs. Pair it with
readonly for aggregate scores — glyph count alone is not precise enough to
communicate an average.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="4" show-value-label rating-label="With value label"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Fractional value label"></md-rating>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="4" showValueLabel ratingLabel="With value label"></MdRating>
<MdRating value="2.5" precision="0.5" showValueLabel ratingLabel="Fractional value label"></MdRating>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="4" show-value-label rating-label="With value label"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Fractional value label"></md-rating><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="4" show-value-label rating-label="With value label"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Fractional value label"></md-rating>
</template><script>
import '@awc-ui/core/define';
</script>
<md-rating value="4" show-value-label rating-label="With value label"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Fractional value label"></md-rating>readonly still renders and announces the score but blocks interaction (and
switches the internal role to img). disabled also greys it out and drops it
from the tab order; soft-disabled stays focusable so keyboard users can
discover it.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="4" rating-label="Enabled"></md-rating>
<md-rating value="4" readonly rating-label="Read-only"></md-rating>
<md-rating value="4" disabled rating-label="Disabled"></md-rating>
<md-rating value="4" soft-disabled rating-label="Soft-disabled"></md-rating>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="4" ratingLabel="Enabled"></MdRating>
<MdRating value="4" readonly ratingLabel="Read-only"></MdRating>
<MdRating value="4" disabled ratingLabel="Disabled"></MdRating>
<MdRating value="4" softDisabled ratingLabel="Soft-disabled"></MdRating>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="4" rating-label="Enabled"></md-rating>
<md-rating value="4" readonly rating-label="Read-only"></md-rating>
<md-rating value="4" disabled rating-label="Disabled"></md-rating>
<md-rating value="4" soft-disabled rating-label="Soft-disabled"></md-rating><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="4" rating-label="Enabled"></md-rating>
<md-rating value="4" readonly rating-label="Read-only"></md-rating>
<md-rating value="4" disabled rating-label="Disabled"></md-rating>
<md-rating value="4" soft-disabled rating-label="Soft-disabled"></md-rating>
</template><script>
import '@awc-ui/core/define';
</script>
<md-rating value="4" rating-label="Enabled"></md-rating>
<md-rating value="4" readonly rating-label="Read-only"></md-rating>
<md-rating value="4" disabled rating-label="Disabled"></md-rating>
<md-rating value="4" soft-disabled rating-label="Soft-disabled"></md-rating>icon and empty-icon take any Material Symbols name. outline-empty (default
on) draws unfilled items as outlines; turn it off for solid empties.
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="3" icon="star" empty-icon="star" rating-label="Stars"></md-rating>
<md-rating value="3" icon="favorite" empty-icon="favorite" rating-label="Hearts"></md-rating>
<md-rating value="3" icon="bolt" empty-icon="bolt" rating-label="Bolts"></md-rating>
<md-rating value="3" icon="local_fire_department" empty-icon="local_fire_department" rating-label="Flames"></md-rating>
<md-rating value="3" outline-empty="false" rating-label="Solid empties"></md-rating>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="3" icon="star" emptyIcon="star" ratingLabel="Stars"></MdRating>
<MdRating value="3" icon="favorite" emptyIcon="favorite" ratingLabel="Hearts"></MdRating>
<MdRating value="3" icon="bolt" emptyIcon="bolt" ratingLabel="Bolts"></MdRating>
<MdRating value="3" icon="local_fire_department" emptyIcon="local_fire_department" ratingLabel="Flames"></MdRating>
<MdRating value="3" outlineEmpty="false" ratingLabel="Solid empties"></MdRating>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="3" icon="star" empty-icon="star" rating-label="Stars"></md-rating>
<md-rating value="3" icon="favorite" empty-icon="favorite" rating-label="Hearts"></md-rating>
<md-rating value="3" icon="bolt" empty-icon="bolt" rating-label="Bolts"></md-rating>
<md-rating value="3" icon="local_fire_department" empty-icon="local_fire_department" rating-label="Flames"></md-rating>
<md-rating value="3" outline-empty="false" rating-label="Solid empties"></md-rating><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="3" icon="star" empty-icon="star" rating-label="Stars"></md-rating>
<md-rating value="3" icon="favorite" empty-icon="favorite" rating-label="Hearts"></md-rating>
<md-rating value="3" icon="bolt" empty-icon="bolt" rating-label="Bolts"></md-rating>
<md-rating value="3" icon="local_fire_department" empty-icon="local_fire_department" rating-label="Flames"></md-rating>
<md-rating value="3" outline-empty="false" rating-label="Solid empties"></md-rating>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<md-rating value="3" icon="star" empty-icon="star" rating-label="Stars"></md-rating>
<md-rating value="3" icon="favorite" empty-icon="favorite" rating-label="Hearts"></md-rating>
<md-rating value="3" icon="bolt" empty-icon="bolt" rating-label="Bolts"></md-rating>
<md-rating value="3" icon="local_fire_department" empty-icon="local_fire_department" rating-label="Flames"></md-rating>
<md-rating value="3" outline-empty="false" rating-label="Solid empties"></md-rating>Keep the glyph conventional for a score. An ambiguous icon makes the scale unreadable.
hover="preview" (the default) previews the value under the pointer and emits
mdHover; it does not change value until a click. Set hover="off" on
touch-primary or very dense surfaces.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="3" hover="preview" rating-label="Hover preview on"></md-rating>
<md-rating value="3" hover="off" rating-label="Hover preview off"></md-rating>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="3" hover="preview" ratingLabel="Hover preview on"></MdRating>
<MdRating value="3" hover="off" ratingLabel="Hover preview off"></MdRating>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="3" hover="preview" rating-label="Hover preview on"></md-rating>
<md-rating value="3" hover="off" rating-label="Hover preview off"></md-rating><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="3" hover="preview" rating-label="Hover preview on"></md-rating>
<md-rating value="3" hover="off" rating-label="Hover preview off"></md-rating>
</template><script>
import '@awc-ui/core/define';
</script>
<md-rating value="3" hover="preview" rating-label="Hover preview on"></md-rating>
<md-rating value="3" hover="off" rating-label="Hover preview off"></md-rating>md-rating is form-associated via ElementInternals — it submits value
under name with no hidden input, exactly as
md-slider does. A value of 0 submits as absent
rather than "0".
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<form id="feedback">
<md-rating name="satisfaction" value="4" show-value-label rating-label="Satisfaction"></md-rating>
<md-button variant="filled" type="submit">Send feedback</md-button>
<md-button variant="text" type="reset">Reset</md-button>
</form>import { MdButton, MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<form id="feedback">
<MdRating name="satisfaction" value="4" showValueLabel ratingLabel="Satisfaction"></MdRating>
<MdButton variant="filled" type="submit">Send feedback</MdButton>
<MdButton variant="text" type="reset">Reset</MdButton>
</form>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<form id="feedback">
<md-rating name="satisfaction" value="4" show-value-label rating-label="Satisfaction"></md-rating>
<md-button variant="filled" type="submit">Send feedback</md-button>
<md-button variant="text" type="reset">Reset</md-button>
</form><script setup>
import '@awc-ui/core/define';
</script>
<template>
<form id="feedback">
<md-rating name="satisfaction" value="4" show-value-label rating-label="Satisfaction"></md-rating>
<md-button variant="filled" type="submit">Send feedback</md-button>
<md-button variant="text" type="reset">Reset</md-button>
</form>
</template><script>
import '@awc-ui/core/define';
</script>
<form id="feedback">
<md-rating name="satisfaction" value="4" show-value-label rating-label="Satisfaction"></md-rating>
<md-button variant="filled" type="submit">Send feedback</md-button>
<md-button variant="text" type="reset">Reset</md-button>
</form>Reading it back out is plain FormData — there is no wrapper API to learn:
<form id="feedback">
<md-rating name="satisfaction" value="4" show-value-label rating-label="Satisfaction"></md-rating>
<md-button variant="filled" type="submit">Send feedback</md-button>
<md-button variant="text" type="reset">Reset</md-button>
</form>
<script type="module">
document.getElementById('feedback').addEventListener('submit', (e) => {
e.preventDefault();
const data = new FormData(e.target);
console.log(Object.fromEntries(data)); // { satisfaction: '4' }
});
</script>import { MdRating, MdButton } from '@awc-ui/react';
export function FeedbackForm() {
function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const data = new FormData(e.currentTarget);
console.log(Object.fromEntries(data)); // { satisfaction: '4' }
}
return (
<form onSubmit={onSubmit}>
<MdRating name="satisfaction" value={4} showValueLabel ratingLabel="Satisfaction" />
<MdButton variant="filled" type="submit">Send feedback</MdButton>
<MdButton variant="text" type="reset">Reset</MdButton>
</form>
);
}import { Component } from '@angular/core';
// Requires AwcUiModule from '@awc-ui/angular' in the owning NgModule.
@Component({
selector: 'app-feedback-form',
template: `
<form (submit)="onSubmit($event)">
<md-rating name="satisfaction" [value]="4" [showValueLabel]="true"
ratingLabel="Satisfaction"></md-rating>
<md-button variant="filled" type="submit">Send feedback</md-button>
<md-button variant="text" type="reset">Reset</md-button>
</form>
`,
})
export class FeedbackFormComponent {
onSubmit(e: Event) {
e.preventDefault();
const data = new FormData(e.target as HTMLFormElement);
console.log(Object.fromEntries(data)); // { satisfaction: '4' }
}
}<script setup lang="ts">
import { MdRating, MdButton } from '@awc-ui/vue';
function onSubmit(e: Event) {
e.preventDefault();
const data = new FormData(e.target as HTMLFormElement);
console.log(Object.fromEntries(data)); // { satisfaction: '4' }
}
</script>
<template>
<form @submit="onSubmit">
<MdRating name="satisfaction" :value="4" :showValueLabel="true" ratingLabel="Satisfaction" />
<MdButton variant="filled" type="submit">Send feedback</MdButton>
<MdButton variant="text" type="reset">Reset</MdButton>
</form>
</template><script lang="ts">
function onSubmit(e: Event) {
e.preventDefault();
const data = new FormData(e.target as HTMLFormElement);
console.log(Object.fromEntries(data)); // { satisfaction: '4' }
}
</script>
<!-- Svelte assigns to the DOM property when one exists, so numeric props must
be written as expressions: value="4" would set the STRING "4". -->
<form on:submit={onSubmit}>
<md-rating name="satisfaction" value={4} showValueLabel={true} ratingLabel="Satisfaction"></md-rating>
<md-button variant="filled" type="submit">Send feedback</md-button>
<md-button variant="text" type="reset">Reset</md-button>
</form>getLabel is a function propgetLabel supplies the per-value screen-reader announcement. Function props do
not cross the attribute boundary, so there is no get-label attribute — set
it in JS.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating id="rating" value="3" rating-label="Rate this product"></md-rating>
<script type="module">
const rating = document.getElementById('rating');
// Function prop — no get-label attribute exists, so set it in JS.
rating.getLabel = (v) => v + ' out of ' + rating.max + ' stars';
</script>import { MdRating } from '@awc-ui/react';
// Plain function — the wrapper assigns it as a property, so it goes through
// like any other prop. No ref, no effect.
const labelFor = (v: number) => v + ' out of 5 stars';
export function ProductRating() {
return <MdRating getLabel={labelFor} value={3} ratingLabel="Rate this product" />;
}import { Component } from '@angular/core';
// Requires AwcUiModule from '@awc-ui/angular' in the owning NgModule — its
// MdRating proxy declares getLabel as an input, so it binds like any other.
@Component({
selector: 'app-product-rating',
template: `
<md-rating [getLabel]="labelFor" [value]="3" ratingLabel="Rate this product"></md-rating>
`,
})
export class ProductRatingComponent {
labelFor = (v: number) => v + ' out of 5 stars';
}<script setup lang="ts">
import { MdRating } from '@awc-ui/vue';
const labelFor = (v: number) => v + ' out of 5 stars';
</script>
<template>
<MdRating :getLabel="labelFor" :value="3" ratingLabel="Rate this product" />
</template><script lang="ts">
const labelFor = (v: number) => v + ' out of 5 stars';
</script>
<!-- Svelte assigns to the DOM property when one exists, so getLabel goes
through as a plain prop — no bind:this, no onMount. -->
<md-rating getLabel={labelFor} value={3} ratingLabel="Rate this product"></md-rating>| Event | Cancelable | Detail | Fires |
|---|---|---|---|
mdHover | no | number | null | Hover preview changes; null on leave |
mdChange | no | number | A rating is committed |
“Cancelable” here means veto honoured. Both are declared as bare
@Event()s, so Stencil emits them with its default cancelable: true —
preventDefault() succeeds and defaultPrevented reads true. The component
never checks it — mdHover is a bare notification, and mdChange is emitted
after value has already been assigned. To reject a score, write the previous
one back to value in your handler.
mdHover is a preview — never read it as the chosen value.
| You want to… | Listen to |
|---|---|
| Store the score the user picked | mdChange |
| Paint a live “you are about to pick 4” caption | mdHover |
| Clear that caption when the pointer leaves | mdHover with detail === null |
React to rating.value = 4 set from your own code | Neither — no event fires |
Both events bubble and are composed, so one delegated listener on an ancestor catches every rating. Sweep the pointer across the stars, then click:
<md-rating id="score" precision="0.5" show-value-label name="score" rating-label="Rate this product"></md-rating>
<script type="module">
const r = document.getElementById('score');
// Function prop — no get-label attribute exists, so assign it in JS.
r.getLabel = (v) => v + ' out of ' + r.max + ' stars';
r.addEventListener('mdChange', (e) => submitScore(e.detail));
r.addEventListener('mdHover', (e) => preview(e.detail)); // null on leave
</script>import { MdRating } from '@awc-ui/react';
const labelFor = (v: number) => v + ' out of 5 stars';
export function ProductRating() {
// getLabel is a FUNCTION prop; the wrapper assigns it as a property, so it
// goes through as a prop like any other. No ref, no effect.
return (
<MdRating
getLabel={labelFor}
precision={0.5}
showValueLabel
name="score"
ratingLabel="Rate this product"
onMdChange={(e) => submitScore(e.detail)}
onMdHover={(e) => preview(e.detail)}
/>
);
}import { Component } from '@angular/core';
// Requires AwcUiModule from '@awc-ui/angular' in the owning NgModule — its
// MdRating proxy declares getLabel as an input, so it binds like any other.
@Component({
selector: 'app-product-rating',
template: `
<md-rating
[getLabel]="labelFor"
[precision]="0.5"
[showValueLabel]="true"
name="score"
ratingLabel="Rate this product"
(mdChange)="onChange($event)"
(mdHover)="onHover($event)"
></md-rating>
`,
})
export class ProductRatingComponent {
labelFor = (v: number) => v + ' out of 5 stars';
onChange(e: CustomEvent<number>) { submitScore(e.detail); }
onHover(e: CustomEvent<number | null>) { preview(e.detail); }
}<script setup lang="ts">
import { MdRating } from '@awc-ui/vue';
const labelFor = (v: number) => v + ' out of 5 stars';
function onChange(e: CustomEvent<number>) { submitScore(e.detail); }
function onHover(e: CustomEvent<number | null>) { preview(e.detail); }
</script>
<template>
<MdRating
:getLabel="labelFor"
:precision="0.5"
:showValueLabel="true"
name="score"
ratingLabel="Rate this product"
@mdChange="onChange"
@mdHover="onHover"
/>
</template><script lang="ts">
const labelFor = (v: number) => v + ' out of 5 stars';
function onChange(e: CustomEvent<number>) { submitScore(e.detail); }
function onHover(e: CustomEvent<number | null>) { preview(e.detail); }
</script>
<!-- Svelte assigns to the DOM property when one exists, so getLabel goes
through as a plain prop — no bind:this, no onMount. -->
<md-rating
getLabel={labelFor}
precision={0.5}
showValueLabel={true}
name="score"
ratingLabel="Rate this product"
on:mdChange={onChange}
on:mdHover={onHover}
></md-rating>| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
value | value | number | 0 | Yes |
defaultValue | default-value | number | 0 | — |
max | max | number | 5 | Yes |
precision | precision | 1 | 0.5 | 1 | Yes |
size | size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Yes |
readonly | readonly | boolean | false | Yes |
disabled | disabled | boolean | false | Yes |
softDisabled | soft-disabled | boolean | false | Yes |
icon | icon | string | 'star' | — |
emptyIcon | empty-icon | string | 'star' | — |
outlineEmpty | outline-empty | boolean | true | Yes |
getLabel | JS only | (value: number) => string | — | — |
showValueLabel | show-value-label | boolean | false | Yes |
ratingLabel | rating-label | string | 'Rating' | — |
name | name | string | '' | Yes |
hover | hover | 'preview' | 'off' | 'preview' | Yes |
density | density | 0 | -1 | -2 | -3 | -4 | 0 | Yes |
| Method | Parameters |
|---|---|
focusRating() | none |
Override on the host element for per-instance theming:
| Property | Description |
|---|---|
--md-rating-item-size | Icon dimension (per `size`) |
--md-rating-item-gap | Space between items |
--md-rating-active-color | Filled icon color |
--md-rating-inactive-color | Empty icon color |
--md-rating-focus-ring-color | Focus ring color |
--md-rating-focus-ring-width | Focus ring width |
--md-rating-focus-ring-offset | Focus ring offset |
--md-rating-state-layer-color | Hover / press overlay color |
--md-rating-value-label-color | Color of the inline value label |
--md-rating-value-label-font | Font of the value label |
--md-rating-pop-scale | Scale on hover/active (MD3 Expressive) |
--md-rating-duration | Animation duration |
--md-rating-icon-font-family | — |
Style internal elements through shadow DOM with ::part():
| Part | Description |
|---|---|
icon-empty | The background (outline) icon |
icon-filled | The clipped foreground (filled) icon |
state-layer | Hover / press overlay — a filled glyph tracing the icon shape |
ripple | Press ripple — a glyph-clipped expanding circle |
items | The slider container |
value-label | The inline numeric value label |
rating-label names the control (default "Rating"); getLabel supplies the
per-value announcement — set both.precision step, Home
clears to 0, End jumps to max, and a digit key 0–9 sets that value
outright when it is within max. Every other key (Tab, Escape) is left
alone so a dialog or menu ancestor can still act on it. focusRating()
focuses the control programmatically.outline-empty on unless you have another cue.readonly stays readable to assistive tech (role="img"); disabled leaves
the tab order (tabindex="-1"), while soft-disabled keeps tabindex="0".size and deep density.The focusable node is the shadow-internal slider, so an IDREF can’t reach it
from outside. The component resolves the name for you instead, in this order:
host aria-labelledby → host aria-label → an associated <label for> (via
ElementInternals.labels) → the rating-label prop. Tab through these — the
first three announce three different names, the soft-disabled one still takes
focus, and the disabled one is skipped:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">default label</span>
<md-rating value="3"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rating-label</span>
<md-rating value="3" rating-label="Overall satisfaction"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">aria-labelledby</span>
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
<span id="rating-a11y-ext" style="font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant);">Product quality</span>
<md-rating value="3" aria-labelledby="rating-a11y-ext"></md-rating>
</div>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">soft-disabled</span>
<md-rating value="3" soft-disabled rating-label="Soft-disabled — still focusable"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">disabled</span>
<md-rating value="3" disabled rating-label="Disabled — skipped"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">readonly</span>
<md-rating value="3" readonly rating-label="Average rating"></md-rating>
</div>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '9rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>default label</span>
<MdRating value="3"></MdRating>
<span style={{ inlineSize: '9rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>rating-label</span>
<MdRating value="3" ratingLabel="Overall satisfaction"></MdRating>
<span style={{ inlineSize: '9rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>aria-labelledby</span>
<div style={{ display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap' }}>
<span id="rating-a11y-ext" style={{ font: 'var(--md-sys-typescale-body-small)', color: 'var(--md-sys-color-on-surface-variant)' }}>Product quality</span>
<MdRating value="3" aria-labelledby="rating-a11y-ext"></MdRating>
</div>
<span style={{ inlineSize: '9rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>soft-disabled</span>
<MdRating value="3" softDisabled ratingLabel="Soft-disabled — still focusable"></MdRating>
<span style={{ inlineSize: '9rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>disabled</span>
<MdRating value="3" disabled ratingLabel="Disabled — skipped"></MdRating>
<span style={{ inlineSize: '9rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>readonly</span>
<MdRating value="3" readonly ratingLabel="Average rating"></MdRating>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">default label</span>
<md-rating value="3"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rating-label</span>
<md-rating value="3" rating-label="Overall satisfaction"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">aria-labelledby</span>
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
<span id="rating-a11y-ext" style="font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant);">Product quality</span>
<md-rating value="3" aria-labelledby="rating-a11y-ext"></md-rating>
</div>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">soft-disabled</span>
<md-rating value="3" soft-disabled rating-label="Soft-disabled — still focusable"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">disabled</span>
<md-rating value="3" disabled rating-label="Disabled — skipped"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">readonly</span>
<md-rating value="3" readonly rating-label="Average rating"></md-rating>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">default label</span>
<md-rating value="3"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rating-label</span>
<md-rating value="3" rating-label="Overall satisfaction"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">aria-labelledby</span>
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
<span id="rating-a11y-ext" style="font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant);">Product quality</span>
<md-rating value="3" aria-labelledby="rating-a11y-ext"></md-rating>
</div>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">soft-disabled</span>
<md-rating value="3" soft-disabled rating-label="Soft-disabled — still focusable"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">disabled</span>
<md-rating value="3" disabled rating-label="Disabled — skipped"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">readonly</span>
<md-rating value="3" readonly rating-label="Average rating"></md-rating>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">default label</span>
<md-rating value="3"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rating-label</span>
<md-rating value="3" rating-label="Overall satisfaction"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">aria-labelledby</span>
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;">
<span id="rating-a11y-ext" style="font: var(--md-sys-typescale-body-small); color: var(--md-sys-color-on-surface-variant);">Product quality</span>
<md-rating value="3" aria-labelledby="rating-a11y-ext"></md-rating>
</div>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">soft-disabled</span>
<md-rating value="3" soft-disabled rating-label="Soft-disabled — still focusable"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">disabled</span>
<md-rating value="3" disabled rating-label="Disabled — skipped"></md-rating>
<span style="inline-size:9rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">readonly</span>
<md-rating value="3" readonly rating-label="Average rating"></md-rating>
</div>The last row is the one to sanity-check with a screen reader: readonly
switches the internal role from slider to img, which ignores
aria-valuetext, so the score is folded into the accessible name instead —
“Average rating: 3 Stars”.
RTL — under dir="rtl" the input axis mirrors and the glyph row does
not. Nothing opts in, but the two halves read different signals:
Under dir="rtl" | What happens | Driven by |
|---|---|---|
ArrowRight / ArrowLeft | Swap — ArrowRight walks down the scale | Computed direction (JS) |
| Pointer half/full split within an item | Mirrors — the trailing (left) edge of a glyph now means full | Computed direction (JS) |
| Value label | Moves to the left of the glyphs | Host inherits direction: rtl |
| Order of the glyphs | Unchanged — item 1 stays on the left | See below |
| The rendered half-fill inside one glyph | Unchanged — always fills from the glyph’s physical left | clip-path: inset() is physical, and the glyph spans force direction: ltr |
The row order is the surprise. The stylesheet mirrors it with
flex-direction: row-reverse, but that container has also inherited
direction: rtl from the host, and under RTL a flex row already runs
right-to-left — so the two reversals cancel and the glyphs land back in physical
left-to-right order. Measured in Chrome, the five item left edges under an
inherited dir="rtl" come out ascending: item 1 is the leftmost.
One more asymmetry worth knowing: the JS reads the computed direction,
while the CSS mirror keys off a dir attribute on the host or an ancestor.
A container styled direction: rtl in CSS with no dir attribute therefore
flips the keyboard and pointer maths and leaves the flex rule out of it
entirely. Set the attribute, not the property. See RTL.
<div dir="rtl"> <md-rating value="2.5" precision="0.5" show-value-label rating-label="التقييم"></md-rating></div>The same ratings in both directions. Nothing is re-authored between the two
rows — only dir and the translated labels change. Compare them carefully:
within each rating the stars sit in the same order in both rows, and only the
value label crosses to the other side of its glyphs. (The three ratings as a
group do reorder in the rtl row — that is the wrapping flex container, not the
component.) The
rest of the mirroring is in the keyboard and pointer maths, which a screenshot
cannot show — focus a star in the rtl row and press ArrowRight to see it
count down.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="Rating"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Average"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="Read-only"></md-rating>
</div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
</div>
</div>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>ltr</span>
<div dir="ltr" style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}>
<MdRating value="3" ratingLabel="Rating"></MdRating>
<MdRating value="2.5" precision="0.5" showValueLabel ratingLabel="Average"></MdRating>
<MdRating value="4" readonly showValueLabel ratingLabel="Read-only"></MdRating>
</div>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>rtl</span>
<div dir="rtl" style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}>
<MdRating value="3" ratingLabel="التقييم"></MdRating>
<MdRating value="2.5" precision="0.5" showValueLabel ratingLabel="المتوسط"></MdRating>
<MdRating value="4" readonly showValueLabel ratingLabel="للقراءة فقط"></MdRating>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="Rating"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Average"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="Read-only"></md-rating>
</div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="Rating"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Average"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="Read-only"></md-rating>
</div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="Rating"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="Average"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="Read-only"></md-rating>
</div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
</div>
</div>dir on the rating — let it inheritPinning dir="ltr" on a rating inside an RTL block is worse than a no-op: it
splits the control against itself. :host-context([dir="rtl"]) matches when the
host or any ancestor carries the attribute, so the pinned rating still gets
flex-direction: row-reverse from the container — but its own computed
direction is now ltr, so nothing cancels it. Measured in Chrome, the pinned
row’s five item left edges come out descending: item 1 lands on the right.
Meanwhile the JS, reading that same ltr, leaves the arrow keys and the pointer
split unmirrored.
The result is a control whose glyphs run one way and whose input runs the other:
ArrowRight counts up while the scale climbs leftward. Compare the two rows,
both inside the same dir="rtl" container:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="3" rating-label="التقييم"></md-rating>
</div>
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating dir="ltr" value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating dir="ltr" value="3" rating-label="التقييم"></md-rating>
</div>
</div>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<div dir="rtl" style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '4.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>correct</span>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}>
<MdRating value="2.5" precision="0.5" showValueLabel ratingLabel="المتوسط"></MdRating>
<MdRating value="3" ratingLabel="التقييم"></MdRating>
</div>
<span style={{ inlineSize: '4.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>wrong</span>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}>
<MdRating dir="ltr" value="2.5" precision="0.5" showValueLabel ratingLabel="المتوسط"></MdRating>
<MdRating dir="ltr" value="3" ratingLabel="التقييم"></MdRating>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="3" rating-label="التقييم"></md-rating>
</div>
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating dir="ltr" value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating dir="ltr" value="3" rating-label="التقييم"></md-rating>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="3" rating-label="التقييم"></md-rating>
</div>
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating dir="ltr" value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating dir="ltr" value="3" rating-label="التقييم"></md-rating>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="3" rating-label="التقييم"></md-rating>
</div>
<span style="inline-size:4.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating dir="ltr" value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating dir="ltr" value="3" rating-label="التقييم"></md-rating>
</div>
</div>density="-1…-4" is a local override of the inherited data-density. It drives
the same --md-sys-density-scale signal, tapering the glyph size and the gap
between items. 0 is the default value rather than a rung of its own, so the
first row below is what you get with no attribute at all:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="0" value="3" rating-label="Density 0"></md-rating><md-rating density="0" value="3.5" precision="0.5" show-value-label rating-label="Density 0 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-1" value="3" rating-label="Density -1"></md-rating><md-rating density="-1" value="3.5" precision="0.5" show-value-label rating-label="Density -1 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-2" value="3" rating-label="Density -2"></md-rating><md-rating density="-2" value="3.5" precision="0.5" show-value-label rating-label="Density -2 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-3" value="3" rating-label="Density -3"></md-rating><md-rating density="-3" value="3.5" precision="0.5" show-value-label rating-label="Density -3 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-4" value="3" rating-label="Density -4"></md-rating><md-rating density="-4" value="3.5" precision="0.5" show-value-label rating-label="Density -4 with label"></md-rating></div>
</div>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '14px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>0</span>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}><MdRating density="0" value="3" ratingLabel="Density 0"></MdRating><MdRating density="0" value="3.5" precision="0.5" showValueLabel ratingLabel="Density 0 with label"></MdRating></div>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-1</span>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}><MdRating density="-1" value="3" ratingLabel="Density -1"></MdRating><MdRating density="-1" value="3.5" precision="0.5" showValueLabel ratingLabel="Density -1 with label"></MdRating></div>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-2</span>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}><MdRating density="-2" value="3" ratingLabel="Density -2"></MdRating><MdRating density="-2" value="3.5" precision="0.5" showValueLabel ratingLabel="Density -2 with label"></MdRating></div>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-3</span>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}><MdRating density="-3" value="3" ratingLabel="Density -3"></MdRating><MdRating density="-3" value="3.5" precision="0.5" showValueLabel ratingLabel="Density -3 with label"></MdRating></div>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-4</span>
<div style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}><MdRating density="-4" value="3" ratingLabel="Density -4"></MdRating><MdRating density="-4" value="3.5" precision="0.5" showValueLabel ratingLabel="Density -4 with label"></MdRating></div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="0" value="3" rating-label="Density 0"></md-rating><md-rating density="0" value="3.5" precision="0.5" show-value-label rating-label="Density 0 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-1" value="3" rating-label="Density -1"></md-rating><md-rating density="-1" value="3.5" precision="0.5" show-value-label rating-label="Density -1 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-2" value="3" rating-label="Density -2"></md-rating><md-rating density="-2" value="3.5" precision="0.5" show-value-label rating-label="Density -2 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-3" value="3" rating-label="Density -3"></md-rating><md-rating density="-3" value="3.5" precision="0.5" show-value-label rating-label="Density -3 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-4" value="3" rating-label="Density -4"></md-rating><md-rating density="-4" value="3.5" precision="0.5" show-value-label rating-label="Density -4 with label"></md-rating></div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="0" value="3" rating-label="Density 0"></md-rating><md-rating density="0" value="3.5" precision="0.5" show-value-label rating-label="Density 0 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-1" value="3" rating-label="Density -1"></md-rating><md-rating density="-1" value="3.5" precision="0.5" show-value-label rating-label="Density -1 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-2" value="3" rating-label="Density -2"></md-rating><md-rating density="-2" value="3.5" precision="0.5" show-value-label rating-label="Density -2 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-3" value="3" rating-label="Density -3"></md-rating><md-rating density="-3" value="3.5" precision="0.5" show-value-label rating-label="Density -3 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-4" value="3" rating-label="Density -4"></md-rating><md-rating density="-4" value="3.5" precision="0.5" show-value-label rating-label="Density -4 with label"></md-rating></div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:14px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="0" value="3" rating-label="Density 0"></md-rating><md-rating density="0" value="3.5" precision="0.5" show-value-label rating-label="Density 0 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-1" value="3" rating-label="Density -1"></md-rating><md-rating density="-1" value="3.5" precision="0.5" show-value-label rating-label="Density -1 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-2" value="3" rating-label="Density -2"></md-rating><md-rating density="-2" value="3.5" precision="0.5" show-value-label rating-label="Density -2 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-3" value="3" rating-label="Density -3"></md-rating><md-rating density="-3" value="3.5" precision="0.5" show-value-label rating-label="Density -3 with label"></md-rating></div>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;"><md-rating density="-4" value="3" rating-label="Density -4"></md-rating><md-rating density="-4" value="3.5" precision="0.5" show-value-label rating-label="Density -4 with label"></md-rating></div>
</div>The two are independent signals, so they compose without extra wiring — a wrapper sets the rung for everything inside it, and any one rating can take a tighter rung of its own.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div dir="rtl" data-density="-2" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
<md-rating value="3" density="-4" rating-label="أكثر إحكاما"></md-rating>
<md-rating value="3" rating-label="افتراضي" style="--md-sys-density-scale: 0;"></md-rating>
</div>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<div dir="rtl" data-density="-2" style={{ display: 'flex', gap: '24px', flexWrap: 'wrap', alignItems: 'center' }}>
<MdRating value="3" ratingLabel="التقييم"></MdRating>
<MdRating value="2.5" precision="0.5" showValueLabel ratingLabel="المتوسط"></MdRating>
<MdRating value="4" readonly showValueLabel ratingLabel="للقراءة فقط"></MdRating>
<MdRating value="3" density="-4" ratingLabel="أكثر إحكاما"></MdRating>
<MdRating value="3" ratingLabel="افتراضي" style={{ '--md-sys-density-scale': '0' }}></MdRating>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div dir="rtl" data-density="-2" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
<md-rating value="3" density="-4" rating-label="أكثر إحكاما"></md-rating>
<md-rating value="3" rating-label="افتراضي" style="--md-sys-density-scale: 0;"></md-rating>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div dir="rtl" data-density="-2" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
<md-rating value="3" density="-4" rating-label="أكثر إحكاما"></md-rating>
<md-rating value="3" rating-label="افتراضي" style="--md-sys-density-scale: 0;"></md-rating>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div dir="rtl" data-density="-2" style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
<md-rating value="3" rating-label="التقييم"></md-rating>
<md-rating value="2.5" precision="0.5" show-value-label rating-label="المتوسط"></md-rating>
<md-rating value="4" readonly show-value-label rating-label="للقراءة فقط"></md-rating>
<md-rating value="3" density="-4" rating-label="أكثر إحكاما"></md-rating>
<md-rating value="3" rating-label="افتراضي" style="--md-sys-density-scale: 0;"></md-rating>
</div>Density — density="-1…-4" locally overrides the inherited data-density
rung; 0 is the default value, not an override. See
Density.
i18n — translate rating-label, and make getLabel locale-aware
(pluralization: “1 star” vs “2 stars”). Format the number with Intl when
show-value-label is on.
| Custom property | Purpose | Default |
|---|---|---|
--md-rating-item-size | Glyph size | Per size (16–48px) |
--md-rating-item-gap | Spacing between items | 4px |
--md-rating-active-color | Filled glyph colour | secondary |
--md-rating-inactive-color | Empty glyph colour | on-surface-variant at 30% |
--md-rating-focus-ring-color / -width / -offset | Focus ring | secondary / 3px / 2px |
--md-rating-state-layer-color | Hover / press overlay | on-surface |
--md-rating-value-label-color / -font | Numeric label | on-surface |
--md-rating-pop-scale / --md-rating-duration | Selection animation | 1.12 / 150ms |
--md-rating-icon-font-family | Glyph font | Material Symbols |
<!-- index.html <head> — the icon font the components draw from -->
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap">
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-rating value="4" icon="favorite" empty-icon="favorite" rating-label="Error toned" style="--md-rating-active-color: var(--md-sys-color-error); --md-rating-inactive-color: var(--md-sys-color-error-container);"></md-rating>
<md-rating value="3" show-value-label rating-label="Wide gap" style="--md-rating-item-gap: 16px; --md-rating-item-size: 32px;"></md-rating>// Icons need the Material Symbols stylesheet in index.html — see Installation.
import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdRating value="4" icon="favorite" emptyIcon="favorite" ratingLabel="Error toned" style={{ '--md-rating-active-color': 'var(--md-sys-color-error)', '--md-rating-inactive-color': 'var(--md-sys-color-error-container)' }}></MdRating>
<MdRating value="3" showValueLabel ratingLabel="Wide gap" style={{ '--md-rating-item-gap': '16px', '--md-rating-item-size': '32px' }}></MdRating>
</>
);
}// Icons need the Material Symbols stylesheet in index.html — see Installation.
// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-rating value="4" icon="favorite" empty-icon="favorite" rating-label="Error toned" style="--md-rating-active-color: var(--md-sys-color-error); --md-rating-inactive-color: var(--md-sys-color-error-container);"></md-rating>
<md-rating value="3" show-value-label rating-label="Wide gap" style="--md-rating-item-gap: 16px; --md-rating-item-size: 32px;"></md-rating><script setup>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<template>
<md-rating value="4" icon="favorite" empty-icon="favorite" rating-label="Error toned" style="--md-rating-active-color: var(--md-sys-color-error); --md-rating-inactive-color: var(--md-sys-color-error-container);"></md-rating>
<md-rating value="3" show-value-label rating-label="Wide gap" style="--md-rating-item-gap: 16px; --md-rating-item-size: 32px;"></md-rating>
</template><script>
// Icons need the Material Symbols stylesheet in index.html — see Installation.
import '@awc-ui/core/define';
</script>
<md-rating value="4" icon="favorite" empty-icon="favorite" rating-label="Error toned" style="--md-rating-active-color: var(--md-sys-color-error); --md-rating-inactive-color: var(--md-sys-color-error-container);"></md-rating>
<md-rating value="3" show-value-label rating-label="Wide gap" style="--md-rating-item-gap: 16px; --md-rating-item-size: 32px;"></md-rating>Every default resolves through an md-sys-color role, so a rating that sets no
custom properties follows the theme on its own:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:center;">
<md-rating value="4" rating-label="Untouched defaults"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="5" readonly rating-label="Read-only"></md-rating>
</div>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap', alignItems: 'center' }}>
<MdRating value="4" ratingLabel="Untouched defaults"></MdRating>
<MdRating value="3.5" precision="0.5" showValueLabel ratingLabel="Half steps"></MdRating>
<MdRating value="5" readonly ratingLabel="Read-only"></MdRating>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:center;">
<md-rating value="4" rating-label="Untouched defaults"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="5" readonly rating-label="Read-only"></md-rating>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:center;">
<md-rating value="4" rating-label="Untouched defaults"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="5" readonly rating-label="Read-only"></md-rating>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:center;">
<md-rating value="4" rating-label="Untouched defaults"></md-rating>
<md-rating value="3.5" precision="0.5" show-value-label rating-label="Half steps"></md-rating>
<md-rating value="5" readonly rating-label="Read-only"></md-rating>
</div>| Part | Element |
|---|---|
items | The slider container — the whole row of glyphs |
icon-empty | The background (outline) glyph |
icon-filled | The clipped foreground (filled) glyph |
state-layer | Hover / press overlay — a filled glyph tracing the icon shape |
ripple | Press ripple — a glyph-clipped expanding circle |
value-label | The inline numeric value label |
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<style>
.parts-rating::part(items) { gap: 12px; }
.parts-rating::part(icon-filled) { filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); }
.parts-rating::part(value-label) { font-variant-numeric: tabular-nums; font-weight: 700; }
</style>
<md-rating class="parts-rating" value="3" show-value-label rating-label="Styled parts"></md-rating>import { MdRating } from '@awc-ui/react';
export function Demo() {
return (
<>
<style>
.parts-rating::part(items) { gap: 12px; }
.parts-rating::part(icon-filled) { filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); }
.parts-rating::part(value-label) { font-variant-numeric: tabular-nums; font-weight: 700; }
</style>
<MdRating className="parts-rating" value="3" showValueLabel ratingLabel="Styled parts"></MdRating>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<style>
.parts-rating::part(items) { gap: 12px; }
.parts-rating::part(icon-filled) { filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); }
.parts-rating::part(value-label) { font-variant-numeric: tabular-nums; font-weight: 700; }
</style>
<md-rating class="parts-rating" value="3" show-value-label rating-label="Styled parts"></md-rating><script setup>
import '@awc-ui/core/define';
</script>
<template>
<style>
.parts-rating::part(items) { gap: 12px; }
.parts-rating::part(icon-filled) { filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); }
.parts-rating::part(value-label) { font-variant-numeric: tabular-nums; font-weight: 700; }
</style>
<md-rating class="parts-rating" value="3" show-value-label rating-label="Styled parts"></md-rating>
</template><script>
import '@awc-ui/core/define';
</script>
<style>
.parts-rating::part(items) { gap: 12px; }
.parts-rating::part(icon-filled) { filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); }
.parts-rating::part(value-label) { font-variant-numeric: tabular-nums; font-weight: 700; }
</style>
<md-rating class="parts-rating" value="3" show-value-label rating-label="Styled parts"></md-rating>md-slider ·
md-icon-button ·
md-progress-indicator ·
md-badge ·
md-segmented-button
md-ratingTwo artefacts to give your AI agent so it generates correct UI with this component. The per-component spec answers "how do I use this exact tag?". The main-llm spec answers "which tag should I pick in the first place?".
md-rating spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
System-prompt preamble · decision matrix · token reference · page recipes · anti-patterns. Paste into the system prompt at the start of a piece of work.