diff options
| author | Adam <[email protected]> | 2025-10-17 15:22:08 -0500 |
|---|---|---|
| committer | Adam <[email protected]> | 2025-10-17 15:22:11 -0500 |
| commit | 335d83365521728181248b13a55386a10ae41ef0 (patch) | |
| tree | 2400f15608681c84777c3f9a897552cdbdc206a5 /packages/desktop/src/components/progress-circle.tsx | |
| parent | 1dba01e0577eb2012e3b6fe99b3a171875c6dab8 (diff) | |
| download | opencode-335d83365521728181248b13a55386a10ae41ef0.tar.gz opencode-335d83365521728181248b13a55386a10ae41ef0.zip | |
wip: desktop work
Diffstat (limited to 'packages/desktop/src/components/progress-circle.tsx')
| -rw-r--r-- | packages/desktop/src/components/progress-circle.tsx | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/packages/desktop/src/components/progress-circle.tsx b/packages/desktop/src/components/progress-circle.tsx new file mode 100644 index 000000000..d56197ed3 --- /dev/null +++ b/packages/desktop/src/components/progress-circle.tsx @@ -0,0 +1,48 @@ +import { Component, createMemo } from "solid-js" + +interface ProgressCircleProps { + percentage: number + size?: number + strokeWidth?: number +} + +export const ProgressCircle: Component<ProgressCircleProps> = (props) => { + // --- Set default values for props --- + const size = () => props.size || 16 + const strokeWidth = () => props.strokeWidth || 3 + + // --- Constants for SVG calculation --- + const viewBoxSize = 16 + const center = viewBoxSize / 2 + const radius = () => center - strokeWidth() / 2 + const circumference = createMemo(() => 2 * Math.PI * radius()) + + // --- Reactive Calculation for the progress offset --- + const offset = createMemo(() => { + const clampedPercentage = Math.max(0, Math.min(100, props.percentage || 0)) + const progress = clampedPercentage / 100 + return circumference() * (1 - progress) + }) + + return ( + <svg + width={size()} + height={size()} + viewBox={`0 0 ${viewBoxSize} ${viewBoxSize}`} + fill="none" + class="transform -rotate-90" + > + <circle cx={center} cy={center} r={radius()} class="stroke-border-weak-base" stroke-width={strokeWidth()} /> + <circle + cx={center} + cy={center} + r={radius()} + class="stroke-border-active" + stroke-width={strokeWidth()} + stroke-dasharray={circumference().toString()} + stroke-dashoffset={offset()} + style={{ transition: "stroke-dashoffset 0.35s cubic-bezier(0.65, 0, 0.35, 1)" }} + /> + </svg> + ) +} |
