| // --------------------------------------------------------------------------- | |
| // customer-grid / Stars.tsx | |
| // The DOM star atom for RATING fields (wave-5 item 11) — the cell picker and | |
| // the record drawer render the same mark. Inline SVG vector paths, NEVER an | |
| // emoji glyph (owner constant); the grid CANVAS twin is cells.ts's | |
| // ratingCellRenderer, which draws the same 5-point star as a path. | |
| // --------------------------------------------------------------------------- | |
| export function StarIcon({ on }: { on: boolean }) { | |
| return ( | |
| <svg width="18" height="18" viewBox="0 0 20 20" aria-hidden> | |
| <polygon | |
| points="10,1.8 12.5,7.2 18.4,7.7 13.9,11.6 15.3,17.4 10,14.3 4.7,17.4 6.1,11.6 1.6,7.7 7.5,7.2" | |
| fill={on ? "#A98A3E" : "none"} | |
| stroke={on ? "#A98A3E" : "rgba(118,143,182,0.55)"} | |
| strokeWidth="1.2" | |
| strokeLinejoin="round" | |
| /> | |
| </svg> | |
| ); | |
| } | |
| /** A read-only star row ("3 of 5" as marks). The picker renders its own buttons. */ | |
| export function StarRow({ value, max }: { value: number; max: number }) { | |
| return ( | |
| <span className="cg-stars cg-stars--static" aria-label={`${value} of ${max}`}> | |
| {Array.from({ length: max }, (_, i) => ( | |
| <StarIcon key={i} on={i < value} /> | |
| ))} | |
| </span> | |
| ); | |
| } | |