Skip to content

feat(InputRating): new component - #283

Merged
IgorShevchik merged 2 commits into
mainfrom
feat/input-rating
Jul 19, 2026
Merged

feat(InputRating): new component#283
IgorShevchik merged 2 commits into
mainfrom
feat/input-rating

Conversation

@IgorShevchik

Copy link
Copy Markdown
Collaborator

Summary

Adds the InputRating component — a star-rating input built on reka-ui RatingRoot — plus a test-infra fix that keeps storage-dependent specs green on Node 24/25.

InputRating (feat)

  • New src/runtime/components/InputRating.vue + theme src/theme/input-rating.ts.
  • Props forwarded from RatingRoot: length, step, name, disabled, required, clearable, hoverable, modelValue, defaultValue; plus readonly, id, icon (default star), color (air-primary), size (md), orientation (horizontal).
  • Custom item slot exposing { index, filled }.
  • Form integration, full spec + vue/nuxt snapshots, demo & nuxt playground pages, registered in types, theme, and the icons dictionary.

Test infra fix (test)

  • Node 24/25 ship a built-in localStorage global that, without a --localstorage-file path, is a stub with undefined methods and shadows happy-dom's working implementation. Storage specs such as useResizable then fail locally with localStorage.setItem is not a function.
  • Added an in-memory Storage shim (test/utils/patchWebStorage.ts) wired into both the vue and nuxt test setups. It no-ops when a functional localStorage already exists (Node 22 + happy-dom), so CI is untouched, and is version-agnostic — unlike --no-experimental-webstorage, which the repo .npmrc node-options would override and which crashes Node 20 (still allowed by engines).

Test plan

  • pnpm test5557 passed, 6 skipped, 0 failed (local Node 25).
  • vue-tsc --noEmit clean.

🤖 Generated with Claude Code

IgorShevchik and others added 2 commits July 17, 2026 14:37
Node 24/25 ship a built-in localStorage global that, without a
--localstorage-file path, is a stub with undefined methods and shadows
happy-dom's working implementation. Storage-dependent specs such as
useResizable then fail with "localStorage.setItem is not a function".

Install an in-memory Storage shim in both the vue and nuxt test setups,
guarded to no-op when a functional localStorage already exists
(Node 22 + happy-dom), so CI stays untouched. Version-agnostic: avoids
--no-experimental-webstorage, which the repo .npmrc node-options would
override and which crashes Node 20 (still allowed by engines).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@IgorShevchik
IgorShevchik merged commit d08b583 into main Jul 19, 2026
1 check passed
@IgorShevchik
IgorShevchik deleted the feat/input-rating branch July 19, 2026 04:28
IgorShevchik added a commit that referenced this pull request Aug 6, 2026
…318)

Syncs upstream nuxt/ui commit 702f481. The ### Size example's
::component-code front matter carried a stray `- defaultValue` entry hanging
off the end of the items.size list, which made `items` a malformed
mapping/sequence mix and offered `defaultValue` as if it were a selectable
`size` value — it is already handled by the block's `ignore:` list.

b24ui carried the identical defect (InputRating arrived via the fork's own
PR #283, evidently from the same source example), so the line was removed
verbatim. items.size is now a clean xs..xl list.

Docs-content only. Suite: 5565 passed / 6 skipped.

Ledger: cursor -> 702f481; previous entry 5afbd5c reconciled to PR #317.


Claude-Session: https://claude.ai/code/session_01JS8ypVfQSFzYVZzkTHhURb

Co-authored-by: Shevchik Igor <noreply@anthropic.com>
IgorShevchik added a commit that referenced this pull request Aug 22, 2026
Ports three upstream commits, contiguous in `v4` (§6 4b):
`d6c3802a` (nuxt/ui #6848) · `f62aa143` (no-op) · `aa5f4af0`.

**`d6c3802a`, against `Range`.** Upstream's `Slider` is this fork's `Range`; the
reka primitives keep their own names, so only the wrapper differs. This is the
second commit in that family — `f3c2ac21` (#431) already moved `useFormField`'s
derived attributes onto the thumb. What still did not get there was **the
caller's own** `aria-*`: `v-bind="rootProps"` put them on `SliderRoot`, which is
not the element with `role="slider"`. A screen reader announcing the thumb read
Reka UI's placeholder name `Thumb` while the author's `aria-label` sat on a
wrapper that announces nothing.

The fix stops inheriting attributes and routes six of them by hand. With one
thumb they go to the thumb and everything else stays on the root; the `'Thumb'`
fallback applies only when the caller gave neither a label nor a `labelledby`.
With several thumbs they stay on the root, because Reka UI already names each
thumb by position (`Minimum`/`Maximum`, `Value n of m`) and one repeated label
would make them indistinguishable — the root takes `role="group"` instead, unless
the caller supplied a `role`, which wins.

Our `Range.vue` matched upstream's pre-image on both thumb lines and on the
`SliderRoot` binding, so the diff applies unchanged apart from `ui`→`b24ui` and
`UTooltip`→`B24Tooltip`. `pick`/`omit` already exist in `../utils`.

**`f62aa143`** is a no-op: upstream's release bookkeeping. This fork has its own
release train and its `CHANGELOG.md` is generated from our commits.

**`aa5f4af0`** turns upstream's "coming" badges into what shipped. The shape
transfers; every value is fork-specific, and each was checked against this
repo's tags with `git tag --contains` rather than assumed to match upstream's
timing:

- `experimental.componentDetection`: `Soon` → **`2.12+`**, not their `4.11+` —
  `530b9616` (#396) is in no tag before `v2.12.0`
- `input-rating.md`: `New` dropped — `d08b5830` (#283) shipped in `v2.10.0`, two
  releases back, so the badge was stale here too
- `splitter.md`, `progress-group.md`: badge **added**, not edited — both first
  appear in `v2.12.0` and our pages never carried one
- the `::note` badges upstream removes were never added here: `07f3fe8d` ported
  those notes without them, precisely because this commit deletes them

Left alone: `calendar.md`, `drawer.md`, `modal.md`, `slideover.md` and the two
`With external scroll element` badges — this fork's own markers on sections
upstream's commit does not mention.

Verified by mutation, not by a passing suite. Upstream's 14 `aria` cases and 2
render cases are ported; with `Range.vue` reverted and the tests kept, **11 of
the 14 fail** plus all 3 affected render cases. The 3 that pass either way pin
behaviour that was already right — the `'Thumb'` fallback, not grouping an
unlabelled range, leaving non-`aria` attributes on the root — and are kept as
regression pins rather than counted as evidence.

Badges checked in the built navigation data: `splitter` and `progress-group`
carry `New`, `input-rating` no longer does, `scroll-area` is untouched, and
`2.12+` renders on the Vue installation page.

Gate with `CI=true`: `dev:prepare` · `lint` · `typecheck` · `test` (7016 passed,
6 skipped, 308 files) · `build` · `docs:generate`.

Ledger: cursor → `aa5f4af0` (upstream HEAD), three entries, parity snapshot
refreshed (one line, zero package differences).

Co-authored-by: Shevchik Igor <noreply@anthropic.com>
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.

1 participant