Files
growstuff/app/javascript/components/StarRating.jsx
T
Brenda WallaceandClaude Opus 5 7e181982ff Upgrade Font Awesome to 6.7.2 (#4846)
* Restore the Ruby 4.0.6 upgrade

PR #4831 committed a stale Gemfile.lock over the newer one, taking
.ruby-version back to 3.2.3 and rolling back active_median, dalli,
parallel, rbs and selenium-webdriver. Dockerfile and
.devcontainer/Dockerfile still build on Ruby 4, so the Gemfile's version
check fails against the image.

Restores both files to what they were before that merge.

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

* Upgrade Font Awesome from 5.15.1 to 6.7.2

Font names have moved on twice since this was pinned: the codebase still
carried Font Awesome 4 names that render as an empty box, and FA6 icons
such as fa-ellipsis-vertical were unavailable.

The 6.x gem no longer ships _font-awesome-sprockets.scss, but its
@font-face rules still call fa-font-path(), so application.scss defines
that against Sprockets' font-path helper. Its fonts live under
assets/fonts/font-awesome, which is already in the precompile list.

Icon names:
- The bare "fa" prefix is not a style in 6. Every "fa fa-<name>" becomes
  "fas fa-<name>" (38 call sites, all solid; the one brands icon already
  used fab).
- fa-sun-o was a Font Awesome 4 name and had been rendering as a box;
  now fa-sun.
- fa-pencil was likewise broken under 5, where it was fa-pencil-alt. It
  exists again in 6, so the existing name now works.
- activity_icon asked for 'fa-truck-pickup' through a helper that already
  adds the prefix, so it emitted "fa-fa-truck-pickup".

Verified that the solid, regular and brands fonts all resolve through
the asset pipeline.

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

* couple more places to upgrade font awesome

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-24 13:39:38 +09:30

47 lines
1.9 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, {useState} from 'react';
const STARS = [1, 2, 3, 4, 5];
const WORDS = {1: 'Poor', 5: 'Great'};
// A rating out of five as stars. They are real radio buttons underneath, so
// the arrow keys and screen readers work as they do for any radio group; the
// stars just light up as far as the one hovered, or chosen. `value` is a number
// from 1 to 5, or null for no rating, and Clear puts it back to that.
export default function StarRating({id, label, value, onChange}) {
const [hovered, setHovered] = useState(null);
const lit = hovered ?? value ?? 0;
return (
<fieldset className="star-rating">
<legend className="form-label">{label}</legend>
<div className="star-rating-stars" onMouseLeave={() => setHovered(null)}>
{STARS.map((number) => (
<React.Fragment key={number}>
<input
type="radio"
className="visually-hidden"
id={`${id}-${number}`}
name={id}
checked={value === number}
onChange={() => onChange(number)}
/>
<label
htmlFor={`${id}-${number}`}
className={`star-rating-star${number <= lit ? ' star-rating-star--lit' : ''}`}
title={WORDS[number] ? `${number} – ${WORDS[number]}` : `${number} of 5`}
onMouseEnter={() => setHovered(number)}
>
<i className={`${number <= lit ? 'fas' : 'far'} fa-star`} aria-hidden="true" />
<span className="visually-hidden">{number} of 5{WORDS[number] ? `, ${WORDS[number]}` : ''}</span>
</label>
</React.Fragment>
))}
<span className="star-rating-value">{value ? `${value} of 5` : 'Not rated'}</span>
{value && (
<button type="button" className="btn btn-sm btn-link" onClick={() => onChange(null)}>Clear</button>
)}
</div>
</fieldset>
);
}