Skip to content

Commit

Permalink
Merge pull request #241 from appwrite/feat-progress-circle
Browse files Browse the repository at this point in the history
progress circle component
  • Loading branch information
ArmanNik authored Nov 29, 2024
2 parents 1bb1b3a + 8d3efcf commit 017ed85
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
86 changes: 86 additions & 0 deletions v2/pink-sb/src/lib/ProgressCircle.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<script lang="ts">
type $$Props = {
progress: number;
size: 's' | 'm' | 'l';
};
export let progress: $$Props['progress'] = 0;
export let size: $$Props['size'] = 'm';
function getPixelSize(pixelSize: $$Props['size']) {
switch (pixelSize) {
case 's':
return 24;
case 'm':
return 36;
case 'l':
return 48;
}
}
$: pixelSize = getPixelSize(size);
</script>

<div>
<svg
width={pixelSize}
height={pixelSize}
viewBox="0 0 {pixelSize} {pixelSize}"
class="circular-progress"
style="--progress-target: {progress}; --circle-size: {pixelSize}px"
>
<circle class="bg"></circle>
<circle class="fg"></circle>
</svg>
</div>

<style>
.circular-progress {
--size: var(--circle-size);
--half-size: calc(var(--size) / 2);
--stroke-width: 2px;
--radius: calc((var(--size) - var(--stroke-width)) / 2);
--circumference: calc(var(--radius) * pi * 2);
--dash: calc((var(--progress) * var(--circumference)) / 100);
animation: progress-animation 1s linear 0s 1 forwards;
@media (prefers-reduced-motion: reduce) {
animation: none;
}
}
.circular-progress circle {
cx: var(--half-size);
cy: var(--half-size);
r: var(--radius);
stroke-width: var(--stroke-width);
fill: none;
stroke-linecap: round;
}
.circular-progress circle.bg {
stroke: var(--color-bgcolor-neutral-tertiary);
}
.circular-progress circle.fg {
transform: rotate(-90deg);
transform-origin: var(--half-size) var(--half-size);
stroke-dasharray: var(--dash) calc(var(--circumference) - var(--dash));
transition: stroke-dasharray 0.3s linear 0s;
stroke: var(--brand-pink-500);
}
@property --progress {
syntax: '<number>';
inherits: false;
initial-value: 0;
}
@keyframes progress-animation {
from {
--progress: 0;
}
to {
--progress: var(--progress-target);
}
}
</style>
1 change: 1 addition & 0 deletions v2/pink-sb/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export { default as Root } from './Root.svelte';
export { default as Status } from './Status.svelte';
export { default as Tag } from './Tag.svelte';
export { default as ToggleButton } from './ToggleButton.svelte';
export { default as ProgressCircle } from './ProgressCircle.svelte';
export { default as Tooltip } from './Tooltip.svelte';
export { default as Table } from './table/index.js';
export { default as Card } from './card/index.js';
Expand Down
40 changes: 40 additions & 0 deletions v2/pink-sb/src/stories/ProgressCircle.stories.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script context="module" lang="ts">
import { ProgressCircle } from '$lib/index.js';
import type { MetaProps } from '@storybook/addon-svelte-csf';
import { Story, Template } from '@storybook/addon-svelte-csf';
export const meta: MetaProps = {
title: 'Components/ProgressCircle',
component: ProgressCircle,
args: {
progress: 30,
size: 'm'
},
argTypes: {
progress: {
control: 'number',
description: 'Progress percentage'
},
size: {
options: ['s', 'm', 'l'],
control: { type: 'select' }
}
}
};
</script>

<div class="wrapper">
<Template let:args>
<ProgressCircle {...args} />
</Template>
</div>
<Story name="Size S" args={{ size: 's' }} />
<Story name="Size M" args={{ size: 'm' }} />
<Story name="Size L" args={{ size: 'l' }} />

<style>
.wrapper {
margin: 100px auto;
width: 400px;
}
</style>

0 comments on commit 017ed85

Please sign in to comment.