# Rating A star rating for collecting feedback or showing a score. Set `defaultValue` (the stars shown on load — a float, so half-stars work with `fractions`), `count` (number of symbols), and `fractions` (sub-symbol granularity). Add `readOnly` to show a fixed score, or leave `defaultValue` off for an empty rating the reader fills in. Use it as `{% rating %}` in Markdown, or call it from Python logic (loops, snippets) via `component('aardvark', 'rating', …)`. ## Default value `defaultValue` is the number of stars shown on load. Leave it off for an empty rating.
Source: Markdown ```aardvark {% rating defaultValue=3 %} ``` Source: Python ```python component('aardvark', 'rating', defaultValue=3) ``` ## Fractions, count, color, and size `fractions` adds sub-symbol steps (`2` gives half-stars), so a `defaultValue` of `2.5` lands on a half. `count` sets the number of symbols; `color` and `size` style them.
Source: Markdown ```aardvark {% rating defaultValue=2.5 fractions=2 count=5 color="yellow" size="lg" %} ``` Source: Python ```python component('aardvark', 'rating', defaultValue=2.5, fractions=2, count=5, color='yellow', size='lg') ``` ## Read-only score `readOnly` makes the rating display-only — the reader can't change it. Use it to show a score you've computed.
Source: Markdown ```aardvark {% rating defaultValue=4 readOnly=true %} ``` Source: Python ```python component('aardvark', 'rating', defaultValue=4, readOnly=True) ``` ## With other components Pair a read-only rating with text to show an average score inline, or an interactive one with a heading to prompt feedback. Average customer rating: How was this page?
Source: Markdown ```aardvark Average customer rating: {% rating defaultValue=4.5 fractions=2 readOnly=true %} How was this page? {% rating count=5 name='page-helpfulness' %} ``` Source: Python ```python component('aardvark', 'rating', defaultValue=4.5, fractions=2, readOnly=True) component('aardvark', 'rating', count=5, name='page-helpfulness') ``` ## Attributes Omit any attribute to take its Mantine default. | Attribute | Valid values | Description | | --- | --- | --- | | `defaultValue` | number (float OK) | Stars selected on load. A float, so `2.5` works with `fractions`. | | `count` | integer | Number of symbols (default `5`). | | `fractions` | integer | Sub-symbol steps — `2` gives half-stars, `4` quarters (default `1`). | | `color` | theme color name (`yellow`, `blue`, …) | Color of the filled symbols. | | `size` | `xs`, `sm`, `md`, `lg`, `xl` | Overall size. | | `readOnly` | bare flag (`true`) | Display-only; the reader can't change it. | | `name` | string | Radio-group name — set a stable one if a page has several ratings. | | `attr` | dict (`attr={…}`) | Raw HTML attributes (e.g. `onchange`) applied to the rendered root. | ## CSS Selectors Target a `{% rating %}` from your own CSS with the island data attribute or the Mantine Styles API part classes: ```css /* Every Rating instance on the page */ [data-aardvark-island="Rating"] { } /* Mantine Styles API parts */ .mantine-Rating-root { } .mantine-Rating-symbolGroup { } .mantine-Rating-starSymbol { } ``` ## Injecting Attributes `attr={…}` forwards a dict of raw HTML attributes — including inline event handlers — straight onto the widget's rendered root. It's the same mechanism every component supports: it can't ride the tag as a single scalar like `color="yellow"`, so it gets its own `attr={…}`. A rating is only useful if you can *read* the result, so here's the canonical use — hang an `onchange` on it and send each selection to Google Analytics:
Source: Markdown ```aardvark {% rating count=5 attr={'onchange': ''' (() => { if (this.dataset.rated) return; // fire once, even if they re-pick this.dataset.rated = '1'; const rating = Number(event.target.value); // the star the reader picked window.gtag && gtag('event', 'rating_submitted', { event_label: 'docs-helpfulness', value: rating, }); })() '''} %} ``` Source: Python ```python component('aardvark', 'rating', count=5, attr={'onchange': ''' (() => { if (this.dataset.rated) return; this.dataset.rated = '1'; const rating = Number(event.target.value); window.gtag && gtag('event', 'rating_submitted', { event_label: 'docs-helpfulness', value: rating, }); })() '''}) ``` **Reading the value.** A `change` from any star bubbles up to the root the handler sits on, so `event.target.value` is the chosen rating. (`this` inside the handler is that root *element*, not the value — if you'd rather go through it, `Number(this.querySelector('input:checked').value)` works too.) `Number(…)` also handles fractional values like `2.5`. What makes this a *good* event: - **`'rating_submitted'`** — a clear, present-tense GA4 event name, not a generic `click`, so it reads well in reports and the Realtime view. - **`event_label: 'docs-helpfulness'`** — a stable, human-readable label naming *which* rating. Give each widget its own (`docs-helpfulness`, `pricing-clarity`, …) so several ratings stay distinct instead of blurring into one. (In GA4 `event_label` is a custom parameter — register it as a custom dimension in your property to see it in reports; `value` is built in. We skip Universal Analytics' `event_category` — GA4 doesn't use it.) - **`value`** — the stars the reader chose, as a number GA4 can average. - **`window.gtag &&`** — a guard so the handler is a no-op when GA isn't on the page (local preview, a consent gate) rather than throwing. - **fires once** — `onchange` runs on *every* selection, so the `this.dataset.rated` flag sends the event on the first pick only; changing 3 → 5 stars won't send two events. (The default theme's page-feedback widget guards the same way.) A site can lock handlers down with an `attrPolicy` in `aardvark.config.yaml` (e.g. `deny: ['on*']`).