diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Rating/BitRating.razor b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Rating/BitRating.razor
index b4abcda1fa..678778382b 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Rating/BitRating.razor
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Rating/BitRating.razor
@@ -9,112 +9,186 @@
var displayValue = _DisplayValue;
var tabbableIndex = _TabbableIndex;
var interactive = IsEnabled && ReadOnly is false;
+ // A name given by reference wins over one given inline, so only one of the two is ever rendered. A
+ // read-only rating named by reference adds its value to the reference from a hidden element of its own.
+ var nameReference = _NameReference;
+ var rendersValueText = ReadOnly && nameReference is not null;
+ var labelledBy = rendersValueText ? $"{nameReference} {_valueTextId}" : nameReference;
+ var ariaLabel = nameReference is null ? _AriaLabel : null;
+ var describedBy = _AriaDescribedBy;
}
@* A read-only rating is no longer a set of choices but a picture of a value, so it drops the radiogroup
and is announced as a single labelled image instead of a group of unreachable radios. That also takes
- aria-required and aria-disabled with it: neither is supported on the img role, and an unchangeable
- picture of a value has nothing to require or disable in the first place. *@
+ the four states of a field with it - aria-readonly, aria-required, aria-disabled and aria-invalid - none
+ of which the img role supports, and none of which an unchangeable picture of a value has anything to say
+ about: there is nothing to require, disable or correct in the first place. *@
+@* A name given by reference wins over one given inline, so only one of aria-labelledby and aria-label
+ is ever rendered: the visible label names the group when there is one, the explicit strings when not.
+ OnFocusIn and OnFocusOut are raised from Ratings.setup rather than from @onfocusin and @onfocusout, which
+ would also report every move of the focus from one item to the next. *@
- @for (int item = 1; item <= max; item++)
+ @* Not a label element: with no single input to point a "for" at, a label here would label nothing;
+ the group is named through aria-labelledby referencing this id instead. *@
+ @if (HasLabel)
{
- var index = item;
- var percentage = GetPercentage(index);
- var isCurrent = index == CurrentValue;
- // A per-item icon replaces the shared pair for that position only, which is what turns a plain
- // scale into one that changes shape as it fills - a frown at one end and a grin at the other.
- var itemSelectedIcon = GetSelectedIcon?.Invoke(index) ?? selectedIcon;
- var itemUnselectedIcon = GetUnselectedIcon?.Invoke(index) ?? unselectedIcon;
-
-