svelte-comp 1.0.6 β 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -10
- package/dist/lib/ProgressCircle.svelte +191 -0
- package/dist/lib/ProgressCircle.svelte.d.ts +39 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,17 +15,15 @@ npm install svelte-comp
|
|
|
15
15
|
|
|
16
16
|
## π§ Setup TailwindCSS
|
|
17
17
|
|
|
18
|
-
Install Tailwind and the Vite plugin:
|
|
19
|
-
|
|
20
18
|
```bash
|
|
21
19
|
npm install tailwindcss @tailwindcss/vite
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
`vite.config.ts`:
|
|
25
23
|
|
|
26
24
|
```ts
|
|
27
25
|
import { defineConfig } from "vite";
|
|
28
|
-
import svelte from "@
|
|
26
|
+
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
|
29
27
|
import tailwindcss from "@tailwindcss/vite";
|
|
30
28
|
|
|
31
29
|
export default defineConfig({
|
|
@@ -36,7 +34,7 @@ export default defineConfig({
|
|
|
36
34
|
});
|
|
37
35
|
```
|
|
38
36
|
|
|
39
|
-
Add
|
|
37
|
+
Add to `src/app.css`:
|
|
40
38
|
|
|
41
39
|
```css
|
|
42
40
|
@import "tailwindcss";
|
|
@@ -47,21 +45,48 @@ Add global styles in `src/app.css` (or main stylesheet):
|
|
|
47
45
|
|
|
48
46
|
## π Components included
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
Accordion β’ Button β’ Card β’ Carousel β’ CheckBox β’ CodeView β’ ColorPicker β’
|
|
49
|
+
DatePicker β’ Dialog β’ Field β’ FilePicker β’ Form β’ Hamburger β’ Menu β’
|
|
50
|
+
PaginatedCard β’ Pagination β’ ProgressBar β’ ProgressCircle β’ Radio β’ Select
|
|
51
|
+
β’ Slider β’ Splitter β’ Switch β’ Tabs β’ Table β’ ThemeToggle β’ TimePicker
|
|
52
|
+
Toast β’ Tooltip
|
|
54
53
|
|
|
55
54
|
Full component list in repository.
|
|
56
55
|
|
|
57
56
|
---
|
|
58
57
|
|
|
58
|
+
## π Quick example
|
|
59
|
+
|
|
60
|
+
Accordion usage:
|
|
61
|
+
|
|
62
|
+
```svelte
|
|
63
|
+
<script lang="ts">
|
|
64
|
+
import { Accordion } from "svelte-comp";
|
|
65
|
+
|
|
66
|
+
const items = [
|
|
67
|
+
{ title: "First", content: "This is the first item" },
|
|
68
|
+
{ title: "Second", content: "This is the second item" },
|
|
69
|
+
{ title: "Third", content: "This is the third item" }
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const handleToggle = (index: number, open: boolean) => {
|
|
73
|
+
console.log(index, open);
|
|
74
|
+
};
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<Accordion {items} multiple defaultOpen={[0]} sz="md" onToggle={handleToggle} />
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
59
82
|
## π License
|
|
60
83
|
|
|
61
|
-
MIT License
|
|
84
|
+
MIT License
|
|
62
85
|
|
|
63
86
|
---
|
|
64
87
|
|
|
65
88
|
## π Links
|
|
66
89
|
|
|
67
90
|
GitHub: [https://github.com/MaestroFusion360/svelte-comp](https://github.com/MaestroFusion360/svelte-comp)
|
|
91
|
+
|
|
92
|
+
Demo: [https://maestrofusion360.github.io/svelte-comp/](https://maestrofusion360.github.io/svelte-comp/)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
<!-- src/lib/ProgressCircle.svelte -->
|
|
2
|
+
<script lang="ts">
|
|
3
|
+
/**
|
|
4
|
+
* @component ProgressCircle
|
|
5
|
+
* @description Circular progress indicator for visualizing completion or load state (0-100). Supports indeterminate mode.
|
|
6
|
+
* @prop value {number} - Current progress value
|
|
7
|
+
* @default 0
|
|
8
|
+
* @prop indeterminate {boolean} - Enables spinning infinite mode
|
|
9
|
+
* @default false
|
|
10
|
+
* @prop size {number} - Diameter in px
|
|
11
|
+
* @default 48
|
|
12
|
+
* @prop stroke {number} - Stroke width in px
|
|
13
|
+
* @default 4
|
|
14
|
+
* @prop variant {ComponentVariant} - Color/style variant
|
|
15
|
+
* @options default|neutral|success|warning|error
|
|
16
|
+
* @default default
|
|
17
|
+
* @prop label {string} - Optional text shown in center
|
|
18
|
+
* @default ""
|
|
19
|
+
* @prop max {number} - Max progress value for normalization
|
|
20
|
+
* @default 100
|
|
21
|
+
* @prop class {string} - Extra wrapper classes
|
|
22
|
+
* @default ""
|
|
23
|
+
* @note Clamps value between 0-max
|
|
24
|
+
* @note Uses SVG stroke-dashoffset animation
|
|
25
|
+
* @note Accessible role=progressbar with aria-valuenow
|
|
26
|
+
* @note Works in both determinate/indeterminate modes
|
|
27
|
+
*/
|
|
28
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
29
|
+
import { type SizeKey, type ComponentVariant, TEXT } from "./types";
|
|
30
|
+
import { cx, clamp } from "../utils";
|
|
31
|
+
|
|
32
|
+
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
33
|
+
value?: number;
|
|
34
|
+
indeterminate?: boolean;
|
|
35
|
+
sz?: SizeKey;
|
|
36
|
+
variant?: ComponentVariant;
|
|
37
|
+
class?: string;
|
|
38
|
+
label?: string;
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
let {
|
|
43
|
+
value = 0,
|
|
44
|
+
indeterminate = false,
|
|
45
|
+
sz = "md",
|
|
46
|
+
variant = "default",
|
|
47
|
+
class: externalClass = "",
|
|
48
|
+
label = "",
|
|
49
|
+
disabled = false,
|
|
50
|
+
...rest
|
|
51
|
+
}: Props = $props();
|
|
52
|
+
|
|
53
|
+
const sizes: Record<SizeKey, { diameter: number; stroke: number }> = {
|
|
54
|
+
xs: { diameter: 40, stroke: 4 },
|
|
55
|
+
sm: { diameter: 48, stroke: 5 },
|
|
56
|
+
md: { diameter: 56, stroke: 6 },
|
|
57
|
+
lg: { diameter: 64, stroke: 7 },
|
|
58
|
+
xl: { diameter: 72, stroke: 8 },
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const pctValue = $derived(clamp(value, 0, 100));
|
|
62
|
+
const pctText = $derived(Math.round(pctValue));
|
|
63
|
+
|
|
64
|
+
const geometry = $derived(sizes[sz]);
|
|
65
|
+
const center = $derived(geometry.diameter / 2);
|
|
66
|
+
const radius = $derived(center - geometry.stroke / 2);
|
|
67
|
+
const circumference = $derived(2 * Math.PI * radius);
|
|
68
|
+
|
|
69
|
+
const dashOffset = $derived(((100 - pctValue) / 100) * circumference);
|
|
70
|
+
const dashArray = $derived(`${circumference} ${circumference}`);
|
|
71
|
+
const indeterminateDash = $derived(`${circumference * 0.3} ${circumference}`);
|
|
72
|
+
|
|
73
|
+
const strokeColor = $derived(
|
|
74
|
+
variant === "neutral"
|
|
75
|
+
? "stroke-[var(--color-bg-secondary)]"
|
|
76
|
+
: "stroke-[var(--color-bg-primary)]"
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const rootClass = $derived(
|
|
80
|
+
cx(
|
|
81
|
+
"inline-flex flex-col items-center gap-1 data-[disabled=true]:opacity-[var(--opacity-disabled)] data-[disabled=true]:cursor-not-allowed",
|
|
82
|
+
externalClass
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<div
|
|
88
|
+
class={rootClass}
|
|
89
|
+
role="progressbar"
|
|
90
|
+
aria-valuemin="0"
|
|
91
|
+
aria-valuemax="100"
|
|
92
|
+
aria-valuenow={indeterminate ? undefined : pctText}
|
|
93
|
+
data-disabled={disabled ? "true" : undefined}
|
|
94
|
+
{...rest}
|
|
95
|
+
>
|
|
96
|
+
{#if label}
|
|
97
|
+
<span class="text-[var(--color-text-muted)] select-none {TEXT[sz]}">
|
|
98
|
+
{label}
|
|
99
|
+
</span>
|
|
100
|
+
{/if}
|
|
101
|
+
|
|
102
|
+
<div
|
|
103
|
+
class="relative inline-flex items-center justify-center"
|
|
104
|
+
style={`width:${geometry.diameter}px;height:${geometry.diameter}px;`}
|
|
105
|
+
>
|
|
106
|
+
<svg
|
|
107
|
+
class="pc-svg"
|
|
108
|
+
viewBox={`0 0 ${geometry.diameter} ${geometry.diameter}`}
|
|
109
|
+
role="presentation"
|
|
110
|
+
aria-hidden="true"
|
|
111
|
+
>
|
|
112
|
+
<g class="pc-rot">
|
|
113
|
+
<circle
|
|
114
|
+
class="pc-track"
|
|
115
|
+
cx={center}
|
|
116
|
+
cy={center}
|
|
117
|
+
r={radius}
|
|
118
|
+
stroke-width={geometry.stroke}
|
|
119
|
+
></circle>
|
|
120
|
+
|
|
121
|
+
{#if indeterminate}
|
|
122
|
+
<circle
|
|
123
|
+
class={cx("pc-bar pc-indet", strokeColor)}
|
|
124
|
+
cx={center}
|
|
125
|
+
cy={center}
|
|
126
|
+
r={radius}
|
|
127
|
+
stroke-width={geometry.stroke}
|
|
128
|
+
stroke-dasharray={indeterminateDash}
|
|
129
|
+
></circle>
|
|
130
|
+
{:else}
|
|
131
|
+
<circle
|
|
132
|
+
class={cx("pc-bar", strokeColor)}
|
|
133
|
+
cx={center}
|
|
134
|
+
cy={center}
|
|
135
|
+
r={radius}
|
|
136
|
+
stroke-width={geometry.stroke}
|
|
137
|
+
stroke-dasharray={dashArray}
|
|
138
|
+
stroke-dashoffset={dashOffset}
|
|
139
|
+
></circle>
|
|
140
|
+
{/if}
|
|
141
|
+
</g>
|
|
142
|
+
</svg>
|
|
143
|
+
|
|
144
|
+
{#if !indeterminate}
|
|
145
|
+
<div
|
|
146
|
+
class="absolute inset-0 flex items-center justify-center text-[var(--color-text-muted)] font-medium select-none {TEXT[
|
|
147
|
+
sz
|
|
148
|
+
]}"
|
|
149
|
+
>
|
|
150
|
+
{pctText}%
|
|
151
|
+
</div>
|
|
152
|
+
{/if}
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<style>
|
|
157
|
+
.pc-svg {
|
|
158
|
+
width: 100%;
|
|
159
|
+
height: 100%;
|
|
160
|
+
}
|
|
161
|
+
.pc-rot {
|
|
162
|
+
transform: rotate(-90deg);
|
|
163
|
+
transform-origin: center;
|
|
164
|
+
}
|
|
165
|
+
.pc-track {
|
|
166
|
+
fill: none;
|
|
167
|
+
stroke: var(--border-color-default);
|
|
168
|
+
}
|
|
169
|
+
.pc-bar {
|
|
170
|
+
fill: none;
|
|
171
|
+
stroke-linecap: round;
|
|
172
|
+
transition:
|
|
173
|
+
stroke-dashoffset 0.25s ease,
|
|
174
|
+
stroke 0.2s ease;
|
|
175
|
+
transform-origin: center;
|
|
176
|
+
}
|
|
177
|
+
.pc-indet {
|
|
178
|
+
animation: pc-spin 1.2s linear infinite;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
:global {
|
|
182
|
+
@keyframes pc-spin {
|
|
183
|
+
0% {
|
|
184
|
+
transform: rotate(0deg);
|
|
185
|
+
}
|
|
186
|
+
100% {
|
|
187
|
+
transform: rotate(360deg);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
</style>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @component ProgressCircle
|
|
3
|
+
* @description Circular progress indicator for visualizing completion or load state (0-100). Supports indeterminate mode.
|
|
4
|
+
* @prop value {number} - Current progress value
|
|
5
|
+
* @default 0
|
|
6
|
+
* @prop indeterminate {boolean} - Enables spinning infinite mode
|
|
7
|
+
* @default false
|
|
8
|
+
* @prop size {number} - Diameter in px
|
|
9
|
+
* @default 48
|
|
10
|
+
* @prop stroke {number} - Stroke width in px
|
|
11
|
+
* @default 4
|
|
12
|
+
* @prop variant {ComponentVariant} - Color/style variant
|
|
13
|
+
* @options default|neutral|success|warning|error
|
|
14
|
+
* @default default
|
|
15
|
+
* @prop label {string} - Optional text shown in center
|
|
16
|
+
* @default ""
|
|
17
|
+
* @prop max {number} - Max progress value for normalization
|
|
18
|
+
* @default 100
|
|
19
|
+
* @prop class {string} - Extra wrapper classes
|
|
20
|
+
* @default ""
|
|
21
|
+
* @note Clamps value between 0-max
|
|
22
|
+
* @note Uses SVG stroke-dashoffset animation
|
|
23
|
+
* @note Accessible role=progressbar with aria-valuenow
|
|
24
|
+
* @note Works in both determinate/indeterminate modes
|
|
25
|
+
*/
|
|
26
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
27
|
+
import { type SizeKey, type ComponentVariant } from "./types";
|
|
28
|
+
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
29
|
+
value?: number;
|
|
30
|
+
indeterminate?: boolean;
|
|
31
|
+
sz?: SizeKey;
|
|
32
|
+
variant?: ComponentVariant;
|
|
33
|
+
class?: string;
|
|
34
|
+
label?: string;
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
};
|
|
37
|
+
declare const ProgressCircle: import("svelte").Component<Props, {}, "">;
|
|
38
|
+
type ProgressCircle = ReturnType<typeof ProgressCircle>;
|
|
39
|
+
export default ProgressCircle;
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { default as Menu } from "./Menu.svelte";
|
|
|
15
15
|
export { default as PaginatedCard } from "./PaginatedCard.svelte";
|
|
16
16
|
export { default as Pagination } from "./Pagination.svelte";
|
|
17
17
|
export { default as ProgressBar } from "./ProgressBar.svelte";
|
|
18
|
+
export { default as ProgressCircle } from "./ProgressCircle.svelte";
|
|
18
19
|
export { default as Radio } from "./Radio.svelte";
|
|
19
20
|
export { default as Select } from "./Select.svelte";
|
|
20
21
|
export { default as Slider } from "./Slider.svelte";
|
package/dist/lib/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export { default as Menu } from "./Menu.svelte";
|
|
|
16
16
|
export { default as PaginatedCard } from "./PaginatedCard.svelte";
|
|
17
17
|
export { default as Pagination } from "./Pagination.svelte";
|
|
18
18
|
export { default as ProgressBar } from "./ProgressBar.svelte";
|
|
19
|
+
export { default as ProgressCircle } from "./ProgressCircle.svelte";
|
|
19
20
|
export { default as Radio } from "./Radio.svelte";
|
|
20
21
|
export { default as Select } from "./Select.svelte";
|
|
21
22
|
export { default as Slider } from "./Slider.svelte";
|
package/package.json
CHANGED