So I am trying to build this custom component to indicate direction in a form of a pie chart, where the direction is indicated by the chart's slice.
I am using CSS to achieve this, but I only managed to make the slice static. I need the slice to change angles based on component props (start and end angles).
I am having troubles passing custom css variables to the element and making css conic-gradient function work with the given variables.
I don't know if it matters, but for the context, this is in React project, using MUI library with tailwind.
Below is my component:
(Notice how I set properties of the element by using plain document. Is this wrong? It feels wrong, but I didn't find other way, how to set custom css varaibles.)
import "./DirectionIndicator.css";
type Props = {
startAngle: number
endAngle: number
}
export default function DirectionIndicator(props: Props) {
const element = document?.getElementById("pieSlice")
if (element) {
element.style.setProperty("--startAngle", props.startAngle.toString())
element.style.setProperty("--endAngle", props.endAngle.toString())
}
return (
<div className={"pieContainer"}>
<div className={"pieBackground"}>
<div id="pieSlice" className={"slice"}/>
<div className={"innerCircle"}>
<div className={"content"}>
<b>N</b>
</div>
</div>
</div>
</div>
)
}
and this is my css:
(Notice in class .slice there are two lines containing conic-gradient function. They are identical, except one is using the --startAngle and --endAngle variables instead of hardcoded values. When I use the line with hardcoded values, css works fine. When I switch for the one with variables, slice doesn't show. I don't understand what's wrong. I tried to remove setting the values in component via JS and use the default values from CSS file, but that doesn't work neither. Indicator remains empty.)
.pieContainer {
height: var(--containerSize);
position: relative;
--containerSize: 100px;
--innerCircleSize: 70px;
--directionColor: #590;
--innerCircleColor: #fff;
}
.pieBackground {
position: absolute;
width: var(--containerSize);
height: var(--containerSize);
border-radius: 100%;
box-shadow: 0px 2px 5px rgba(0,0,0,0.5);
}
.slice {
--startAngle: 0;
--endAngle: 12;
transition: all 1000ms;
width: var(--containerSize);
height: var(--containerSize);
border-radius: 100%;
/*background: conic-gradient(from var(--startAngle)deg, var(--directionColor) var(--endAngle)deg, transparent 1deg);*/
background: conic-gradient(from 60deg, var(--directionColor) 120deg, transparent 1deg);
}
.innerCircle {
position: absolute;
width: var(--innerCircleSize);
height: var(--innerCircleSize);
background-color: var(--innerCircleColor);
border-radius: 100%;
top: calc((var(--containerSize) - var(--innerCircleSize)) / 2);
left: calc((var(--containerSize) - var(--innerCircleSize)) / 2);
box-shadow: 2px 5px 8px rgba(0,0,0,0.5) inset;
color: black;
}
.innerCircle .content {
position: absolute;
display: block;
width: var(--innerCircleSize);
top: 5px;
left: 0;
text-align: center;
font-size: 12px;
}
I will be very grateful for any tips on how to fix this. Thank you!

