mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-09-29 17:34:27 -04:00
* 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>
47 lines
1.9 KiB
React
47 lines
1.9 KiB
React
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>
|
||
);
|
||
}
|