summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components/progress-circle.tsx
blob: 40d1e2022f09e4ce2fb38262cbb50ec99e6d0f6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { type ComponentProps, splitProps } from "solid-js"

export interface ProgressCircleProps extends Pick<ComponentProps<"svg">, "class" | "classList"> {
  percentage: number
  size?: number
  strokeWidth?: number
}

export function ProgressCircle(props: ProgressCircleProps) {
  const [split, rest] = splitProps(props, ["percentage", "size", "strokeWidth", "class", "classList"])

  const size = () => split.size || 18
  const r = 7

  return (
    <svg
      {...rest}
      width={size()}
      height={size()}
      viewBox="0 0 18 18"
      fill="none"
      data-component="progress-circle"
      classList={{
        ...(split.classList ?? {}),
        [split.class ?? ""]: !!split.class,
      }}
    >
      <circle cx="9" cy="9" r="7.75" stroke="currentColor" stroke-width="1.5" />
      <path
        opacity="0.5"
        d={(() => {
          const pct = Math.min(100, Math.max(0, split.percentage))
          const angle = (pct / 100) * 2 * Math.PI - Math.PI / 2
          const x = 9 + r * Math.cos(angle)
          const y = 9 + r * Math.sin(angle)
          const largeArc = pct > 50 ? 1 : 0
          return `M9 2A${r} ${r} 0 ${largeArc} 1 ${x} ${y}L9 9Z`
        })()}
        fill="currentColor"
      />
    </svg>
  )
}