components/elements/IconWheel/IconWheel.jsxjavascript
import "./IconWheel.scss";
// ring radius in em, distributed the same way SelectWidget spreads its
// options: evenly around the circle, starting at the top (-90deg) clockwise
//was 11 before
const NODE_RADIUS = 30;
//was 16.5 before
// const LABEL_RADIUS = 14;
/**
* N icon nodes with text labels evenly spaced around a decorative ring
* ("iconWheel" element type) - unlike CircleInfographic/SelectWidget, purely
* decorative and non-interactive.
*
* @param {Object} props
* @param {Array<{icon: string, label: string}>} props.items - Ring nodes.
*/
export const IconWheel = ({ items }) => {
return (
<div className="icon-wheel">
<div className="icon-wheel__ring icon-wheel__ring--outer" />
<div className="icon-wheel__ring icon-wheel__ring--dashed" />
<div className="icon-wheel__ring icon-wheel__ring--buttons">
{items.map((item, index) => {
const angle = -90 + index * (360 / items.length);
const radians = (angle * Math.PI) / 180;
const cos = Math.cos(radians);
const sin = Math.sin(radians);
// side determines label text alignment: to the outside of the ring
const side = cos > 0.3 ? "right" : cos < -0.3 ? "left" : "center";
return (
<div key={item.label || 0} className="icon-wheel__spoke">
{item.label || item.icon ? (
<div>
<div
className="icon-wheel__node"
style={{ "--x": `${NODE_RADIUS * cos}em`, "--y": `${NODE_RADIUS * sin}em` }}>
<img className="icon-wheel__icon" src={item.icon} alt="" />
<span
className={`icon-wheel__label icon-wheel__label--${side}`}
// style={{ "--x": `${LABEL_RADIUS * cos}em`, "--y": `${LABEL_RADIUS * sin}em` }}
>
{item.label}
</span>
</div>
</div>
) : (
<div> </div>
)}
</div>
);
})}
</div>
</div>
);
};