Skip to content

feat(Rating): individual segments, segment count and single fill - #2863

Open
Lisa18289 wants to merge 3 commits into
mainfrom
claude/rating-component-improvements-7abafc
Open

feat(Rating): individual segments, segment count and single fill#2863
Lisa18289 wants to merge 3 commits into
mainfrom
claude/rating-component-improvements-7abafc

Conversation

@Lisa18289

Copy link
Copy Markdown
Member

Adds three optional props/components to Rating so a rating is no longer five stars with one icon pair, and fixes two bugs found on the way.

Added

  • RatingSegment — public and remote-capable. Put segments into the rating to give each step its own iconEmpty/iconFilled; an <Icon color> inside them already wins over the rating's colors, so per-segment colors need no new API. Collected through the tunnel like SegmentedControl's Segment; position comes from an internal context, so there is no public index or value.
  • maxValue — the number of segments when no segments are given. Segments win when both are present.
  • fill="single" — fills only the selected segment instead of every segment up to the value, for scales whose steps have their own symbols (default stays cumulative). Pure CSS, no new state.

The accessible name of a segment is its own aria-label, else the generated "{value} of {count}" — replacing the per-value keys segment.0segment.5, which cannot describe a rating of any other length.

Fixed

  • A disabled rating did not grey out (own commit). The rule targeted .star/.starFilled, classes that are never applied — leftovers from a rename.

  • iconEmpty/iconFilled killed a real remote connection. They were generated as remote properties, and properties travel through structured clone, which cannot carry a React element: setting one threw DataCloneError: Symbol(react.transitional.element) could not be cloned and took the whole remote tree down. Both components now declare @flr-slot-props iconEmpty, iconFilled, so the icons arrive as slotted children and any React subtree works, a raw <svg> or a Tabler icon included. Host markup is unchanged either way — the slot wrapper renders a fragment.

    The visual suite could not catch this: its Remote environment is in-process and never serializes. Verified in apps/remote-dom-demo over the iframe connection instead.

Verified

  • Browser tests Rating.browser.test.tsx — 16/16 in webkit (light) and firefox (dark)
  • Visual tests Local and Remote against the baselines
  • pnpm affected:test, pnpm lint, prettier --check
  • Docs playground and the remote demo driven in the browser, including the controlled value round-trip over a real remote connection

Notes for review

  • Needs the update-screenshots label — only the -darwin baselines are regenerated locally, CI gates on -webkit-linux.
  • crossVersion({ below: "0.2.0-alpha.1039" }) in the visual test guesses the release version. If this lands later than .1039, bump it.
  • Three rows added to the AGENTS.md "Common failures" table for the traps hit here (element props over remote, hover states in visual tests, children?: never for a children-less registered component).

The rule that dims a disabled rating targeted `.star` and `.starFilled`.
Those classes are never applied — the icons carry `.empty` and `.filled`,
and `star` only exists as a `grid-template-areas` name. The selectors are
left over from a rename, so a disabled rating kept its full star colors.

Point the rule at the classes that exist. Palette-colored custom icons
(`<Icon color="success">`) are dimmed as well; an icon with a free CSS
color sets an inline style and stays as it is on purpose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for ./packages/components/

Status Category Percentage Covered / Total
🔵 Lines 75.56% 600 / 794
🔵 Statements 75.46% 615 / 815
🔵 Functions 77.97% 131 / 168
🔵 Branches 65.85% 272 / 413
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/components/src/components/propTypes/index.ts 100% 100% 100% 100%
Generated in workflow #6181 for commit 1fde51d by the Vitest Coverage Report Action

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

Preview environments are ready:

Type URL
docs pr-2863.docs.review.flow-components.de
storybook pr-2863.storybook.review.flow-components.de

Images:

  • docs: ghcr.io/mittwald/flow/docs:pr-2863
  • storybook: ghcr.io/mittwald/flow/storybook:pr-2863

@Lisa18289 Lisa18289 self-assigned this Aug 20, 2026
@Lisa18289 Lisa18289 added the update-screenshots Label a PR to update the screenshots used for visual regression testing label Aug 20, 2026
@github-actions github-actions Bot removed the update-screenshots Label a PR to update the screenshots used for visual regression testing label Aug 20, 2026
@Lisa18289
Lisa18289 force-pushed the claude/rating-component-improvements-7abafc branch 7 times, most recently from 4f8698f to efd26d7 Compare August 20, 2026 11:08
A rating was hard-wired to five stars with one icon pair for all of them.
Three additions, all optional and backwards compatible:

- `RatingSegment` is public and remote-capable. Each segment carries its
  own `iconEmpty`/`iconFilled`, and an `<Icon color>` inside them already
  wins over the rating's own colors, so per-segment colors need no new
  API. Segments reach the segment row through the tunnel, the same way
  `SegmentedControl` collects its `Segment` children.
- `maxValue` sets the number of segments when no segments are given.
  Segments win over `maxValue` when both are present.
- `fill="single"` fills only the selected segment instead of every
  segment up to the value, for scales whose steps have their own symbols.
  It is a modifier class; the fill logic stays in CSS.

The rating hands its defaults to the segments through the props context,
so a segment's own props win and the icon precedence chain comes for free:
a segment's icon, else the rating's, else the star. `size` rides along as
an `@internal` prop rather than through an `Icon` context, because
`flowComponent` wraps every UI component in a `ClearPropsContext` — a
context set around the segment row does not reach the icons inside a
segment. Only the segment's position needs a context of its own; tunneled
elements cannot be given props.

The icon props of both components are declared `@flr-slot-props`, so they
travel as slotted children instead of cloned property values. Without
that, setting one over a real remote connection throws
`DataCloneError: Symbol(react.transitional.element) could not be cloned`
and takes the whole remote tree down — which is what Rating's existing
icon props did until now. Any React subtree works there now, a raw `<svg>`
or a Tabler icon included. The host markup is unchanged either way,
because the slot wrapper renders a fragment.

The accessible name of a segment is its own `aria-label`, else the
generated "{value} of {count}". That replaces the per-value keys
`segment.0`…`segment.5`, which cannot describe a rating of any other
length.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Lisa18289
Lisa18289 force-pushed the claude/rating-component-improvements-7abafc branch from efd26d7 to 5e073b0 Compare August 20, 2026 11:16
@Lisa18289 Lisa18289 added the update-screenshots Label a PR to update the screenshots used for visual regression testing label Aug 20, 2026
@github-actions github-actions Bot removed the update-screenshots Label a PR to update the screenshots used for visual regression testing label Aug 20, 2026
Co-authored-by: Lisa18289 <84317589+Lisa18289@users.noreply.github.com>
@Jan-Eimertenbrink Jan-Eimertenbrink linked an issue Aug 20, 2026 that may be closed by this pull request
@Lisa18289
Lisa18289 marked this pull request as ready for review August 21, 2026 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend Rating component with customizable count and icons

1 participant