@7onic-ui/react 0.3.9 → 0.3.11
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 +2 -2
- package/dist/chart.mjs +3 -9
- package/dist/chart.mjs.map +1 -1
- package/dist/chunk-2WIIXHOV.mjs +148 -0
- package/dist/chunk-2WIIXHOV.mjs.map +1 -0
- package/dist/chunk-53MIUPSY.mjs +13 -0
- package/dist/chunk-53MIUPSY.mjs.map +1 -0
- package/dist/chunk-BN5BEA3V.mjs +195 -0
- package/dist/chunk-BN5BEA3V.mjs.map +1 -0
- package/dist/chunk-C5D3VRNJ.mjs +504 -0
- package/dist/chunk-C5D3VRNJ.mjs.map +1 -0
- package/dist/chunk-COW3B62M.mjs +214 -0
- package/dist/chunk-COW3B62M.mjs.map +1 -0
- package/dist/chunk-CTH6SN5Y.mjs +114 -0
- package/dist/chunk-CTH6SN5Y.mjs.map +1 -0
- package/dist/chunk-D3NTQNDW.mjs +440 -0
- package/dist/chunk-D3NTQNDW.mjs.map +1 -0
- package/dist/chunk-DDRYEJBJ.mjs +164 -0
- package/dist/chunk-DDRYEJBJ.mjs.map +1 -0
- package/dist/chunk-DJAEXCRU.mjs +190 -0
- package/dist/chunk-DJAEXCRU.mjs.map +1 -0
- package/dist/chunk-DYYQOHQR.mjs +214 -0
- package/dist/chunk-DYYQOHQR.mjs.map +1 -0
- package/dist/chunk-EG2GTK65.mjs +443 -0
- package/dist/chunk-EG2GTK65.mjs.map +1 -0
- package/dist/chunk-FHUAH6AJ.mjs +93 -0
- package/dist/chunk-FHUAH6AJ.mjs.map +1 -0
- package/dist/chunk-GD4YE5AE.mjs +209 -0
- package/dist/chunk-GD4YE5AE.mjs.map +1 -0
- package/dist/chunk-HHX4GABH.mjs +129 -0
- package/dist/chunk-HHX4GABH.mjs.map +1 -0
- package/dist/chunk-HS2VRYSX.mjs +148 -0
- package/dist/chunk-HS2VRYSX.mjs.map +1 -0
- package/dist/chunk-IHHI3LIN.mjs +155 -0
- package/dist/chunk-IHHI3LIN.mjs.map +1 -0
- package/dist/chunk-IJ2FZ3L5.mjs +159 -0
- package/dist/chunk-IJ2FZ3L5.mjs.map +1 -0
- package/dist/chunk-IPCIC2BI.mjs +148 -0
- package/dist/chunk-IPCIC2BI.mjs.map +1 -0
- package/dist/chunk-JCJEVXER.mjs +170 -0
- package/dist/chunk-JCJEVXER.mjs.map +1 -0
- package/dist/chunk-KBPYAMGS.mjs +157 -0
- package/dist/chunk-KBPYAMGS.mjs.map +1 -0
- package/dist/chunk-L55ABE4H.mjs +283 -0
- package/dist/chunk-L55ABE4H.mjs.map +1 -0
- package/dist/chunk-LJJ6K4IU.mjs +318 -0
- package/dist/chunk-LJJ6K4IU.mjs.map +1 -0
- package/dist/chunk-ND6TUVP2.mjs +148 -0
- package/dist/chunk-ND6TUVP2.mjs.map +1 -0
- package/dist/chunk-NWFMJWGX.mjs +165 -0
- package/dist/chunk-NWFMJWGX.mjs.map +1 -0
- package/dist/chunk-PTAPPOKU.mjs +117 -0
- package/dist/chunk-PTAPPOKU.mjs.map +1 -0
- package/dist/chunk-PVTBM7V7.mjs +316 -0
- package/dist/chunk-PVTBM7V7.mjs.map +1 -0
- package/dist/chunk-Q5WVLK2L.mjs +77 -0
- package/dist/chunk-Q5WVLK2L.mjs.map +1 -0
- package/dist/chunk-R7FJEO4K.mjs +252 -0
- package/dist/chunk-R7FJEO4K.mjs.map +1 -0
- package/dist/chunk-RKSB2N5L.mjs +206 -0
- package/dist/chunk-RKSB2N5L.mjs.map +1 -0
- package/dist/chunk-S4DGVKBK.mjs +151 -0
- package/dist/chunk-S4DGVKBK.mjs.map +1 -0
- package/dist/chunk-S4T4PU7F.mjs +114 -0
- package/dist/chunk-S4T4PU7F.mjs.map +1 -0
- package/dist/chunk-SDDAGZWA.mjs +224 -0
- package/dist/chunk-SDDAGZWA.mjs.map +1 -0
- package/dist/chunk-SZPZOGPC.mjs +394 -0
- package/dist/chunk-SZPZOGPC.mjs.map +1 -0
- package/dist/chunk-T5A4APEL.mjs +140 -0
- package/dist/chunk-T5A4APEL.mjs.map +1 -0
- package/dist/chunk-V5UFWYFI.mjs +255 -0
- package/dist/chunk-V5UFWYFI.mjs.map +1 -0
- package/dist/chunk-W6YNEU53.mjs +175 -0
- package/dist/chunk-W6YNEU53.mjs.map +1 -0
- package/dist/chunk-XK52LYR4.mjs +182 -0
- package/dist/chunk-XK52LYR4.mjs.map +1 -0
- package/dist/chunk-YIAH6KHV.mjs +164 -0
- package/dist/chunk-YIAH6KHV.mjs.map +1 -0
- package/dist/chunk-YZ7HHFKA.mjs +375 -0
- package/dist/chunk-YZ7HHFKA.mjs.map +1 -0
- package/dist/chunk-ZDRUTJ4T.mjs +119 -0
- package/dist/chunk-ZDRUTJ4T.mjs.map +1 -0
- package/dist/components/accordion.mjs +19 -0
- package/dist/components/accordion.mjs.map +1 -0
- package/dist/components/alert.mjs +15 -0
- package/dist/components/alert.mjs.map +1 -0
- package/dist/components/avatar.mjs +23 -0
- package/dist/components/avatar.mjs.map +1 -0
- package/dist/components/badge.mjs +11 -0
- package/dist/components/badge.mjs.map +1 -0
- package/dist/components/breadcrumb.mjs +23 -0
- package/dist/components/breadcrumb.mjs.map +1 -0
- package/dist/components/button-group.mjs +11 -0
- package/dist/components/button-group.mjs.map +1 -0
- package/dist/components/button.mjs +12 -0
- package/dist/components/button.mjs.map +1 -0
- package/dist/components/card.mjs +25 -0
- package/dist/components/card.mjs.map +1 -0
- package/dist/components/chat-input.mjs +15 -0
- package/dist/components/chat-input.mjs.map +1 -0
- package/dist/components/chat-message.mjs +17 -0
- package/dist/components/chat-message.mjs.map +1 -0
- package/dist/components/checkbox.mjs +12 -0
- package/dist/components/checkbox.mjs.map +1 -0
- package/dist/components/divider.mjs +11 -0
- package/dist/components/divider.mjs.map +1 -0
- package/dist/components/drawer.mjs +33 -0
- package/dist/components/drawer.mjs.map +1 -0
- package/dist/components/dropdown.mjs +35 -0
- package/dist/components/dropdown.mjs.map +1 -0
- package/dist/components/field.mjs +19 -0
- package/dist/components/field.mjs.map +1 -0
- package/dist/components/icon-button.mjs +12 -0
- package/dist/components/icon-button.mjs.map +1 -0
- package/dist/components/input.mjs +12 -0
- package/dist/components/input.mjs.map +1 -0
- package/dist/components/metric-card.mjs +23 -0
- package/dist/components/metric-card.mjs.map +1 -0
- package/dist/components/modal.mjs +57 -0
- package/dist/components/modal.mjs.map +1 -0
- package/dist/components/navigation-menu.mjs +27 -0
- package/dist/components/navigation-menu.mjs.map +1 -0
- package/dist/components/pagination.mjs +33 -0
- package/dist/components/pagination.mjs.map +1 -0
- package/dist/components/popover.mjs +23 -0
- package/dist/components/popover.mjs.map +1 -0
- package/dist/components/progress.mjs +11 -0
- package/dist/components/progress.mjs.map +1 -0
- package/dist/components/quick-reply.mjs +15 -0
- package/dist/components/quick-reply.mjs.map +1 -0
- package/dist/components/radio-group.mjs +16 -0
- package/dist/components/radio-group.mjs.map +1 -0
- package/dist/components/segmented.mjs +15 -0
- package/dist/components/segmented.mjs.map +1 -0
- package/dist/components/select.mjs +24 -0
- package/dist/components/select.mjs.map +1 -0
- package/dist/components/skeleton.mjs +11 -0
- package/dist/components/skeleton.mjs.map +1 -0
- package/dist/components/slider.mjs +12 -0
- package/dist/components/slider.mjs.map +1 -0
- package/dist/components/spinner.mjs +11 -0
- package/dist/components/spinner.mjs.map +1 -0
- package/dist/components/switch.mjs +12 -0
- package/dist/components/switch.mjs.map +1 -0
- package/dist/components/table.mjs +23 -0
- package/dist/components/table.mjs.map +1 -0
- package/dist/components/tabs.mjs +19 -0
- package/dist/components/tabs.mjs.map +1 -0
- package/dist/components/textarea.mjs +12 -0
- package/dist/components/textarea.mjs.map +1 -0
- package/dist/components/toast.mjs +13 -0
- package/dist/components/toast.mjs.map +1 -0
- package/dist/components/toggle-group.mjs +15 -0
- package/dist/components/toggle-group.mjs.map +1 -0
- package/dist/components/toggle.mjs +11 -0
- package/dist/components/toggle.mjs.map +1 -0
- package/dist/components/tooltip.mjs +21 -0
- package/dist/components/tooltip.mjs.map +1 -0
- package/dist/components/typing-indicator.mjs +11 -0
- package/dist/components/typing-indicator.mjs.map +1 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +95 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +296 -7536
- package/dist/index.mjs.map +1 -1
- package/llms.txt +50 -32
- package/package.json +14 -14
- package/dist/chart.d.mts +0 -147
- package/dist/index.d.mts +0 -1535
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
cn
|
|
4
|
+
} from "./chunk-53MIUPSY.mjs";
|
|
5
|
+
|
|
6
|
+
// src/components/ui/spinner.tsx
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { cva } from "class-variance-authority";
|
|
9
|
+
var RING_SIZES = {
|
|
10
|
+
sm: 16,
|
|
11
|
+
default: 24,
|
|
12
|
+
lg: 32
|
|
13
|
+
};
|
|
14
|
+
var RING_STROKE = {
|
|
15
|
+
sm: 2,
|
|
16
|
+
default: 2.5,
|
|
17
|
+
lg: 3
|
|
18
|
+
};
|
|
19
|
+
var DOT_SIZES = {
|
|
20
|
+
sm: 4,
|
|
21
|
+
default: 6,
|
|
22
|
+
lg: 8
|
|
23
|
+
};
|
|
24
|
+
var DOT_GAP = {
|
|
25
|
+
sm: 3,
|
|
26
|
+
default: 4,
|
|
27
|
+
lg: 5
|
|
28
|
+
};
|
|
29
|
+
var BAR_WIDTHS = {
|
|
30
|
+
sm: 2,
|
|
31
|
+
default: 3,
|
|
32
|
+
lg: 4
|
|
33
|
+
};
|
|
34
|
+
var BAR_HEIGHTS = {
|
|
35
|
+
sm: 12,
|
|
36
|
+
default: 16,
|
|
37
|
+
lg: 24
|
|
38
|
+
};
|
|
39
|
+
var BAR_GAP = {
|
|
40
|
+
sm: 2,
|
|
41
|
+
default: 3,
|
|
42
|
+
lg: 4
|
|
43
|
+
};
|
|
44
|
+
var ORBIT_SIZES = {
|
|
45
|
+
sm: 22,
|
|
46
|
+
default: 32,
|
|
47
|
+
lg: 44
|
|
48
|
+
};
|
|
49
|
+
var ORBIT_STROKE = {
|
|
50
|
+
sm: 2.5,
|
|
51
|
+
default: 3,
|
|
52
|
+
lg: 3.5
|
|
53
|
+
};
|
|
54
|
+
var DOT_COUNT = 3;
|
|
55
|
+
var BAR_COUNT = 4;
|
|
56
|
+
var RING_VIEWBOX = 24;
|
|
57
|
+
var RING_CENTER = 12;
|
|
58
|
+
var strokeColorMap = {
|
|
59
|
+
default: "stroke-foreground",
|
|
60
|
+
primary: "stroke-primary",
|
|
61
|
+
current: "stroke-current"
|
|
62
|
+
};
|
|
63
|
+
var bgColorMap = {
|
|
64
|
+
default: "bg-foreground",
|
|
65
|
+
primary: "bg-primary",
|
|
66
|
+
current: "bg-current"
|
|
67
|
+
};
|
|
68
|
+
var SPEED_MS = { slow: 1500, default: 1e3, fast: 750 };
|
|
69
|
+
var ORBIT_SPEED_MS = { slow: 2e3, default: 1500, fast: 1e3 };
|
|
70
|
+
var spinnerVariants = cva(
|
|
71
|
+
"inline-flex items-center justify-center shrink-0",
|
|
72
|
+
{
|
|
73
|
+
variants: {
|
|
74
|
+
size: {
|
|
75
|
+
sm: "",
|
|
76
|
+
default: "",
|
|
77
|
+
lg: ""
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
defaultVariants: {
|
|
81
|
+
size: "default"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
var Spinner = React.forwardRef(
|
|
86
|
+
({
|
|
87
|
+
className,
|
|
88
|
+
variant = "ring",
|
|
89
|
+
orbitStyle = "ring",
|
|
90
|
+
size,
|
|
91
|
+
color = "default",
|
|
92
|
+
speed = "default",
|
|
93
|
+
label,
|
|
94
|
+
...props
|
|
95
|
+
}, ref) => {
|
|
96
|
+
const resolvedSize = size || "default";
|
|
97
|
+
const orbitMap = {
|
|
98
|
+
ring: OrbitSpinner,
|
|
99
|
+
dots: OrbitDotsSpinner,
|
|
100
|
+
cube: OrbitCubeSpinner,
|
|
101
|
+
flip: OrbitFlipSpinner,
|
|
102
|
+
morph: OrbitMorphSpinner
|
|
103
|
+
};
|
|
104
|
+
return /* @__PURE__ */ React.createElement(
|
|
105
|
+
"div",
|
|
106
|
+
{
|
|
107
|
+
ref,
|
|
108
|
+
role: "status",
|
|
109
|
+
"aria-label": label || "Loading",
|
|
110
|
+
className: cn(spinnerVariants({ size }), className),
|
|
111
|
+
...props
|
|
112
|
+
},
|
|
113
|
+
variant === "ring" && /* @__PURE__ */ React.createElement(RingSpinner, { size: resolvedSize, color, speed }),
|
|
114
|
+
variant === "dots" && /* @__PURE__ */ React.createElement(DotsSpinner, { size: resolvedSize, color, speed }),
|
|
115
|
+
variant === "bars" && /* @__PURE__ */ React.createElement(BarsSpinner, { size: resolvedSize, color, speed }),
|
|
116
|
+
variant === "orbit" && (() => {
|
|
117
|
+
const OrbitComponent = orbitMap[orbitStyle];
|
|
118
|
+
return /* @__PURE__ */ React.createElement(OrbitComponent, { size: resolvedSize, color, speed });
|
|
119
|
+
})()
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
Spinner.displayName = "Spinner";
|
|
124
|
+
function RingSpinner({ size, color, speed }) {
|
|
125
|
+
const diameter = RING_SIZES[size];
|
|
126
|
+
const stroke = RING_STROKE[size];
|
|
127
|
+
const r = (RING_VIEWBOX - stroke) / 2;
|
|
128
|
+
const circumference = 2 * Math.PI * r;
|
|
129
|
+
return /* @__PURE__ */ React.createElement(
|
|
130
|
+
"svg",
|
|
131
|
+
{
|
|
132
|
+
viewBox: `0 0 ${RING_VIEWBOX} ${RING_VIEWBOX}`,
|
|
133
|
+
width: diameter,
|
|
134
|
+
height: diameter,
|
|
135
|
+
fill: "none",
|
|
136
|
+
className: "animate-spin",
|
|
137
|
+
style: { animationDuration: `${SPEED_MS[speed]}ms` }
|
|
138
|
+
},
|
|
139
|
+
/* @__PURE__ */ React.createElement(
|
|
140
|
+
"circle",
|
|
141
|
+
{
|
|
142
|
+
cx: RING_CENTER,
|
|
143
|
+
cy: RING_CENTER,
|
|
144
|
+
r,
|
|
145
|
+
className: "stroke-border",
|
|
146
|
+
strokeWidth: stroke
|
|
147
|
+
}
|
|
148
|
+
),
|
|
149
|
+
/* @__PURE__ */ React.createElement(
|
|
150
|
+
"circle",
|
|
151
|
+
{
|
|
152
|
+
cx: RING_CENTER,
|
|
153
|
+
cy: RING_CENTER,
|
|
154
|
+
r,
|
|
155
|
+
className: strokeColorMap[color],
|
|
156
|
+
strokeWidth: stroke,
|
|
157
|
+
strokeDasharray: circumference,
|
|
158
|
+
strokeDashoffset: circumference * 0.75,
|
|
159
|
+
strokeLinecap: "round"
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
function DotsSpinner({ size, color, speed }) {
|
|
165
|
+
const dotSize = DOT_SIZES[size];
|
|
166
|
+
const gap = DOT_GAP[size];
|
|
167
|
+
return /* @__PURE__ */ React.createElement("div", { className: "inline-flex items-center", style: { gap } }, Array.from({ length: DOT_COUNT }, (_, i) => /* @__PURE__ */ React.createElement(
|
|
168
|
+
"div",
|
|
169
|
+
{
|
|
170
|
+
key: i,
|
|
171
|
+
className: cn(
|
|
172
|
+
"rounded-full animate-spinner-dot",
|
|
173
|
+
bgColorMap[color]
|
|
174
|
+
),
|
|
175
|
+
style: {
|
|
176
|
+
width: dotSize,
|
|
177
|
+
height: dotSize,
|
|
178
|
+
animationDuration: `${SPEED_MS[speed]}ms`,
|
|
179
|
+
animationDelay: `${i * (SPEED_MS[speed] / DOT_COUNT / 1.5)}ms`
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
)));
|
|
183
|
+
}
|
|
184
|
+
function BarsSpinner({ size, color, speed }) {
|
|
185
|
+
const barWidth = BAR_WIDTHS[size];
|
|
186
|
+
const barHeight = BAR_HEIGHTS[size];
|
|
187
|
+
const gap = BAR_GAP[size];
|
|
188
|
+
return /* @__PURE__ */ React.createElement("div", { className: "inline-flex items-center", style: { gap, height: barHeight } }, Array.from({ length: BAR_COUNT }, (_, i) => /* @__PURE__ */ React.createElement(
|
|
189
|
+
"div",
|
|
190
|
+
{
|
|
191
|
+
key: i,
|
|
192
|
+
className: cn(
|
|
193
|
+
"rounded-full animate-spinner-bar origin-center",
|
|
194
|
+
bgColorMap[color]
|
|
195
|
+
),
|
|
196
|
+
style: {
|
|
197
|
+
width: barWidth,
|
|
198
|
+
height: barHeight,
|
|
199
|
+
animationDuration: `${SPEED_MS[speed]}ms`,
|
|
200
|
+
animationDelay: `${i * (SPEED_MS[speed] / BAR_COUNT / 1.5)}ms`
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
)));
|
|
204
|
+
}
|
|
205
|
+
var orbitTextColorMap = {
|
|
206
|
+
default: "text-foreground",
|
|
207
|
+
primary: "text-primary",
|
|
208
|
+
current: ""
|
|
209
|
+
};
|
|
210
|
+
function OrbitSpinner({ size, color, speed }) {
|
|
211
|
+
const diameter = ORBIT_SIZES[size];
|
|
212
|
+
const stroke = ORBIT_STROKE[size];
|
|
213
|
+
const r = (RING_VIEWBOX - stroke * 2) / 2;
|
|
214
|
+
return /* @__PURE__ */ React.createElement(
|
|
215
|
+
"div",
|
|
216
|
+
{
|
|
217
|
+
className: cn(orbitTextColorMap[color]),
|
|
218
|
+
style: {
|
|
219
|
+
width: diameter,
|
|
220
|
+
height: diameter,
|
|
221
|
+
perspective: diameter * 3,
|
|
222
|
+
position: "relative"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
/* @__PURE__ */ React.createElement(
|
|
226
|
+
"svg",
|
|
227
|
+
{
|
|
228
|
+
viewBox: `0 0 ${RING_VIEWBOX} ${RING_VIEWBOX}`,
|
|
229
|
+
width: diameter,
|
|
230
|
+
height: diameter,
|
|
231
|
+
fill: "none",
|
|
232
|
+
className: "absolute inset-0 animate-spinner-orbit",
|
|
233
|
+
style: { animationDuration: `${ORBIT_SPEED_MS[speed]}ms` }
|
|
234
|
+
},
|
|
235
|
+
/* @__PURE__ */ React.createElement(
|
|
236
|
+
"circle",
|
|
237
|
+
{
|
|
238
|
+
cx: RING_CENTER,
|
|
239
|
+
cy: RING_CENTER,
|
|
240
|
+
r,
|
|
241
|
+
stroke: "currentColor",
|
|
242
|
+
strokeWidth: stroke
|
|
243
|
+
}
|
|
244
|
+
)
|
|
245
|
+
),
|
|
246
|
+
/* @__PURE__ */ React.createElement(
|
|
247
|
+
"svg",
|
|
248
|
+
{
|
|
249
|
+
viewBox: `0 0 ${RING_VIEWBOX} ${RING_VIEWBOX}`,
|
|
250
|
+
width: diameter,
|
|
251
|
+
height: diameter,
|
|
252
|
+
fill: "none",
|
|
253
|
+
className: "absolute inset-0 animate-spinner-orbit",
|
|
254
|
+
style: {
|
|
255
|
+
animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,
|
|
256
|
+
transform: "rotateZ(90deg)",
|
|
257
|
+
animationDirection: "reverse",
|
|
258
|
+
animationDelay: "-0.4s",
|
|
259
|
+
opacity: 0.35
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
/* @__PURE__ */ React.createElement(
|
|
263
|
+
"circle",
|
|
264
|
+
{
|
|
265
|
+
cx: RING_CENTER,
|
|
266
|
+
cy: RING_CENTER,
|
|
267
|
+
r,
|
|
268
|
+
stroke: "currentColor",
|
|
269
|
+
strokeWidth: stroke
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
)
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
var ORBIT_DOT_SIZE = { sm: 3, default: 4, lg: 6 };
|
|
276
|
+
function OrbitDotsSpinner({ size, color, speed }) {
|
|
277
|
+
const diameter = ORBIT_SIZES[size];
|
|
278
|
+
const dotSize = ORBIT_DOT_SIZE[size];
|
|
279
|
+
const orbitRadius = (diameter - dotSize) / 2;
|
|
280
|
+
return /* @__PURE__ */ React.createElement(
|
|
281
|
+
"div",
|
|
282
|
+
{
|
|
283
|
+
className: cn(orbitTextColorMap[color]),
|
|
284
|
+
style: {
|
|
285
|
+
width: diameter,
|
|
286
|
+
height: diameter,
|
|
287
|
+
perspective: diameter * 3,
|
|
288
|
+
position: "relative"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
/* @__PURE__ */ React.createElement(
|
|
292
|
+
"div",
|
|
293
|
+
{
|
|
294
|
+
className: "animate-spinner-orbit",
|
|
295
|
+
style: {
|
|
296
|
+
animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,
|
|
297
|
+
width: "100%",
|
|
298
|
+
height: "100%",
|
|
299
|
+
position: "relative",
|
|
300
|
+
transformStyle: "preserve-3d"
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
[0, 120, 240].map((angle) => /* @__PURE__ */ React.createElement(
|
|
304
|
+
"div",
|
|
305
|
+
{
|
|
306
|
+
key: angle,
|
|
307
|
+
className: "absolute rounded-full",
|
|
308
|
+
style: {
|
|
309
|
+
width: dotSize,
|
|
310
|
+
height: dotSize,
|
|
311
|
+
backgroundColor: "currentColor",
|
|
312
|
+
left: "50%",
|
|
313
|
+
top: "50%",
|
|
314
|
+
transform: `translate(-50%, -50%) rotate(${angle}deg) translateX(${orbitRadius}px)`
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
))
|
|
318
|
+
)
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
var CUBE_SIZES = { sm: 12, default: 18, lg: 26 };
|
|
322
|
+
function OrbitCubeSpinner({ size, color, speed }) {
|
|
323
|
+
const cubeSize = CUBE_SIZES[size];
|
|
324
|
+
const half = cubeSize / 2;
|
|
325
|
+
const radius = Math.round(cubeSize * 0.15);
|
|
326
|
+
const overlap = 1;
|
|
327
|
+
const faceBase = {
|
|
328
|
+
position: "absolute",
|
|
329
|
+
width: cubeSize + overlap * 2,
|
|
330
|
+
height: cubeSize + overlap * 2,
|
|
331
|
+
backgroundColor: "currentColor",
|
|
332
|
+
borderRadius: radius,
|
|
333
|
+
top: -overlap,
|
|
334
|
+
left: -overlap
|
|
335
|
+
};
|
|
336
|
+
return /* @__PURE__ */ React.createElement(
|
|
337
|
+
"div",
|
|
338
|
+
{
|
|
339
|
+
className: cn(orbitTextColorMap[color]),
|
|
340
|
+
style: {
|
|
341
|
+
width: cubeSize,
|
|
342
|
+
height: cubeSize,
|
|
343
|
+
perspective: cubeSize * 6
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
/* @__PURE__ */ React.createElement(
|
|
347
|
+
"div",
|
|
348
|
+
{
|
|
349
|
+
style: {
|
|
350
|
+
width: cubeSize,
|
|
351
|
+
height: cubeSize,
|
|
352
|
+
transform: "rotateX(-25deg) rotateZ(15deg)",
|
|
353
|
+
transformStyle: "preserve-3d"
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
/* @__PURE__ */ React.createElement(
|
|
357
|
+
"div",
|
|
358
|
+
{
|
|
359
|
+
className: "animate-spinner-orbit",
|
|
360
|
+
style: {
|
|
361
|
+
animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,
|
|
362
|
+
width: cubeSize,
|
|
363
|
+
height: cubeSize,
|
|
364
|
+
position: "relative",
|
|
365
|
+
transformStyle: "preserve-3d"
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
/* @__PURE__ */ React.createElement("div", { style: { ...faceBase, transform: `translateZ(${half}px)`, opacity: 0.25 } }),
|
|
369
|
+
/* @__PURE__ */ React.createElement("div", { style: { ...faceBase, transform: `translateZ(${-half}px)`, opacity: 0.1 } }),
|
|
370
|
+
/* @__PURE__ */ React.createElement("div", { style: { ...faceBase, transform: `rotateY(-90deg) translateZ(${half}px)`, opacity: 0.2 } }),
|
|
371
|
+
/* @__PURE__ */ React.createElement("div", { style: { ...faceBase, transform: `rotateY(90deg) translateZ(${half}px)`, opacity: 0.2 } }),
|
|
372
|
+
/* @__PURE__ */ React.createElement("div", { style: { ...faceBase, transform: `rotateX(90deg) translateZ(${half}px)`, opacity: 0.15 } }),
|
|
373
|
+
/* @__PURE__ */ React.createElement("div", { style: { ...faceBase, transform: `rotateX(-90deg) translateZ(${half}px)`, opacity: 0.08 } })
|
|
374
|
+
)
|
|
375
|
+
)
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
var FLIP_SIZES = { sm: 14, default: 20, lg: 28 };
|
|
379
|
+
function OrbitFlipSpinner({ size, color, speed }) {
|
|
380
|
+
const sqSize = FLIP_SIZES[size];
|
|
381
|
+
return /* @__PURE__ */ React.createElement(
|
|
382
|
+
"div",
|
|
383
|
+
{
|
|
384
|
+
className: cn(orbitTextColorMap[color]),
|
|
385
|
+
style: {
|
|
386
|
+
width: sqSize,
|
|
387
|
+
height: sqSize,
|
|
388
|
+
perspective: sqSize * 4
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
/* @__PURE__ */ React.createElement("div", { style: { transform: "rotateX(25deg)", transformStyle: "preserve-3d", width: "100%", height: "100%" } }, /* @__PURE__ */ React.createElement(
|
|
392
|
+
"div",
|
|
393
|
+
{
|
|
394
|
+
className: "animate-spinner-orbit",
|
|
395
|
+
style: {
|
|
396
|
+
animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,
|
|
397
|
+
width: "100%",
|
|
398
|
+
height: "100%",
|
|
399
|
+
borderRadius: "25%",
|
|
400
|
+
backgroundColor: "currentColor",
|
|
401
|
+
opacity: 0.85
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
))
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
var MORPH_SIZES = { sm: 16, default: 24, lg: 34 };
|
|
408
|
+
function OrbitMorphSpinner({ size, color, speed }) {
|
|
409
|
+
const morphSize = MORPH_SIZES[size];
|
|
410
|
+
return /* @__PURE__ */ React.createElement(
|
|
411
|
+
"div",
|
|
412
|
+
{
|
|
413
|
+
className: cn(orbitTextColorMap[color]),
|
|
414
|
+
style: {
|
|
415
|
+
width: morphSize,
|
|
416
|
+
height: morphSize,
|
|
417
|
+
perspective: morphSize * 3
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
/* @__PURE__ */ React.createElement(
|
|
421
|
+
"div",
|
|
422
|
+
{
|
|
423
|
+
className: "animate-spinner-morph",
|
|
424
|
+
style: {
|
|
425
|
+
animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,
|
|
426
|
+
width: "100%",
|
|
427
|
+
height: "100%",
|
|
428
|
+
backgroundColor: "currentColor",
|
|
429
|
+
opacity: 0.85
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
)
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export {
|
|
437
|
+
spinnerVariants,
|
|
438
|
+
Spinner
|
|
439
|
+
};
|
|
440
|
+
//# sourceMappingURL=chunk-D3NTQNDW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/spinner.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Ring SVG sizes per size variant (diameter in px) */\nconst RING_SIZES = {\n sm: 16,\n default: 24,\n lg: 32,\n} as const\n\n/** Ring stroke widths per size */\nconst RING_STROKE = {\n sm: 2,\n default: 2.5,\n lg: 3,\n} as const\n\n/** Dot sizes (diameter in px) */\nconst DOT_SIZES = {\n sm: 4,\n default: 6,\n lg: 8,\n} as const\n\n/** Dot container gap per size */\nconst DOT_GAP = {\n sm: 3,\n default: 4,\n lg: 5,\n} as const\n\n/** Bar widths per size */\nconst BAR_WIDTHS = {\n sm: 2,\n default: 3,\n lg: 4,\n} as const\n\n/** Bar heights per size */\nconst BAR_HEIGHTS = {\n sm: 12,\n default: 16,\n lg: 24,\n} as const\n\n/** Bar gap per size */\nconst BAR_GAP = {\n sm: 2,\n default: 3,\n lg: 4,\n} as const\n\n/** Orbit sizes (diameter in px) */\nconst ORBIT_SIZES = {\n sm: 22,\n default: 32,\n lg: 44,\n} as const\n\n/** Orbit ring stroke widths per size */\nconst ORBIT_STROKE = {\n sm: 2.5,\n default: 3,\n lg: 3.5,\n} as const\n\n\n/** Number of dots in dots variant */\nconst DOT_COUNT = 3\n\n/** Number of bars in bars variant */\nconst BAR_COUNT = 4\n\n/** SVG viewBox for ring spinner */\nconst RING_VIEWBOX = 24\n\n/** SVG center for ring spinner */\nconst RING_CENTER = 12\n\n// ============================================================================\n// Color mapping\n// ============================================================================\n\nconst strokeColorMap = {\n default: 'stroke-foreground',\n primary: 'stroke-primary',\n current: 'stroke-current',\n} as const\n\nconst bgColorMap = {\n default: 'bg-foreground',\n primary: 'bg-primary',\n current: 'bg-current',\n} as const\n\n// ============================================================================\n// Speed mapping\n// ============================================================================\n\n/** Speed durations in ms for ring/dots/bars */\nconst SPEED_MS = { slow: 1500, default: 1000, fast: 750 } as const\n/** Speed durations in ms for orbit (slower) */\nconst ORBIT_SPEED_MS = { slow: 2000, default: 1500, fast: 1000 } as const\n\n// ============================================================================\n// Variants (CVA)\n// ============================================================================\n\nconst spinnerVariants = cva(\n 'inline-flex items-center justify-center shrink-0',\n {\n variants: {\n size: {\n sm: '',\n default: '',\n lg: '',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n }\n)\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type OrbitStyle = 'ring' | 'dots' | 'cube' | 'flip' | 'morph'\n\nexport interface SpinnerProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof spinnerVariants> {\n /** Visual variant */\n variant?: 'ring' | 'dots' | 'bars' | 'orbit'\n /** Orbit sub-style (only when variant=\"orbit\") */\n orbitStyle?: OrbitStyle\n /** Spinner color */\n color?: 'default' | 'primary' | 'current'\n /** Animation speed */\n speed?: 'slow' | 'default' | 'fast'\n /** Accessibility label */\n label?: string\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nconst Spinner = React.forwardRef<HTMLDivElement, SpinnerProps>(\n ({\n className,\n variant = 'ring',\n orbitStyle = 'ring',\n size,\n color = 'default',\n speed = 'default',\n label,\n ...props\n }, ref) => {\n const resolvedSize = size || 'default'\n\n const orbitMap = {\n ring: OrbitSpinner,\n dots: OrbitDotsSpinner,\n cube: OrbitCubeSpinner,\n flip: OrbitFlipSpinner,\n morph: OrbitMorphSpinner,\n } as const\n\n return (\n <div\n ref={ref}\n role=\"status\"\n aria-label={label || 'Loading'}\n className={cn(spinnerVariants({ size }), className)}\n {...props}\n >\n {variant === 'ring' && (\n <RingSpinner size={resolvedSize} color={color} speed={speed} />\n )}\n {variant === 'dots' && (\n <DotsSpinner size={resolvedSize} color={color} speed={speed} />\n )}\n {variant === 'bars' && (\n <BarsSpinner size={resolvedSize} color={color} speed={speed} />\n )}\n {variant === 'orbit' && (() => {\n const OrbitComponent = orbitMap[orbitStyle]\n return <OrbitComponent size={resolvedSize} color={color} speed={speed} />\n })()}\n </div>\n )\n }\n)\nSpinner.displayName = 'Spinner'\n\n// ============================================================================\n// Ring Spinner (SVG circle with animate-spin)\n// ============================================================================\n\nfunction RingSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const diameter = RING_SIZES[size]\n const stroke = RING_STROKE[size]\n const r = (RING_VIEWBOX - stroke) / 2\n const circumference = 2 * Math.PI * r\n\n return (\n <svg\n viewBox={`0 0 ${RING_VIEWBOX} ${RING_VIEWBOX}`}\n width={diameter}\n height={diameter}\n fill=\"none\"\n className=\"animate-spin\"\n style={{ animationDuration: `${SPEED_MS[speed]}ms` }}\n >\n {/* Track */}\n <circle\n cx={RING_CENTER}\n cy={RING_CENTER}\n r={r}\n className=\"stroke-border\"\n strokeWidth={stroke}\n />\n {/* Indicator */}\n <circle\n cx={RING_CENTER}\n cy={RING_CENTER}\n r={r}\n className={strokeColorMap[color]}\n strokeWidth={stroke}\n strokeDasharray={circumference}\n strokeDashoffset={circumference * 0.75}\n strokeLinecap=\"round\"\n />\n </svg>\n )\n}\n\n// ============================================================================\n// Dots Spinner (3 pulsing dots)\n// ============================================================================\n\nfunction DotsSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const dotSize = DOT_SIZES[size]\n const gap = DOT_GAP[size]\n\n return (\n <div className=\"inline-flex items-center\" style={{ gap }}>\n {Array.from({ length: DOT_COUNT }, (_, i) => (\n <div\n key={i}\n className={cn(\n 'rounded-full animate-spinner-dot',\n bgColorMap[color],\n )}\n style={{\n width: dotSize,\n height: dotSize,\n animationDuration: `${SPEED_MS[speed]}ms`,\n animationDelay: `${i * (SPEED_MS[speed] / DOT_COUNT / 1.5)}ms`,\n }}\n />\n ))}\n </div>\n )\n}\n\n// ============================================================================\n// Bars Spinner (4 pulsing bars)\n// ============================================================================\n\nfunction BarsSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const barWidth = BAR_WIDTHS[size]\n const barHeight = BAR_HEIGHTS[size]\n const gap = BAR_GAP[size]\n\n return (\n <div className=\"inline-flex items-center\" style={{ gap, height: barHeight }}>\n {Array.from({ length: BAR_COUNT }, (_, i) => (\n <div\n key={i}\n className={cn(\n 'rounded-full animate-spinner-bar origin-center',\n bgColorMap[color],\n )}\n style={{\n width: barWidth,\n height: barHeight,\n animationDuration: `${SPEED_MS[speed]}ms`,\n animationDelay: `${i * (SPEED_MS[speed] / BAR_COUNT / 1.5)}ms`,\n }}\n />\n ))}\n </div>\n )\n}\n\n// ============================================================================\n// Orbit Spinner (3D rotating ring)\n// ============================================================================\n\nconst orbitTextColorMap = {\n default: 'text-foreground',\n primary: 'text-primary',\n current: '',\n} as const\n\nfunction OrbitSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const diameter = ORBIT_SIZES[size]\n const stroke = ORBIT_STROKE[size]\n const r = (RING_VIEWBOX - stroke * 2) / 2\n\n return (\n <div\n className={cn(orbitTextColorMap[color])}\n style={{\n width: diameter,\n height: diameter,\n perspective: diameter * 3,\n position: 'relative',\n }}\n >\n {/* Ring 1 — solid, Y-axis rotation */}\n <svg\n viewBox={`0 0 ${RING_VIEWBOX} ${RING_VIEWBOX}`}\n width={diameter}\n height={diameter}\n fill=\"none\"\n className=\"absolute inset-0 animate-spinner-orbit\"\n style={{ animationDuration: `${ORBIT_SPEED_MS[speed]}ms` }}\n >\n <circle\n cx={RING_CENTER}\n cy={RING_CENTER}\n r={r}\n stroke=\"currentColor\"\n strokeWidth={stroke}\n />\n </svg>\n {/* Ring 2 — solid, perpendicular, reverse direction */}\n <svg\n viewBox={`0 0 ${RING_VIEWBOX} ${RING_VIEWBOX}`}\n width={diameter}\n height={diameter}\n fill=\"none\"\n className=\"absolute inset-0 animate-spinner-orbit\"\n style={{\n animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,\n transform: 'rotateZ(90deg)',\n animationDirection: 'reverse',\n animationDelay: '-0.4s',\n opacity: 0.35,\n }}\n >\n <circle\n cx={RING_CENTER}\n cy={RING_CENTER}\n r={r}\n stroke=\"currentColor\"\n strokeWidth={stroke}\n />\n </svg>\n </div>\n )\n}\n\n// ============================================================================\n// Orbit Dots — 3 dots orbiting in 3D path\n// ============================================================================\n\n/** Orbit dot size per spinner size */\nconst ORBIT_DOT_SIZE = { sm: 3, default: 4, lg: 6 } as const\n\nfunction OrbitDotsSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const diameter = ORBIT_SIZES[size]\n const dotSize = ORBIT_DOT_SIZE[size]\n const orbitRadius = (diameter - dotSize) / 2\n\n return (\n <div\n className={cn(orbitTextColorMap[color])}\n style={{\n width: diameter,\n height: diameter,\n perspective: diameter * 3,\n position: 'relative',\n }}\n >\n <div\n className=\"animate-spinner-orbit\"\n style={{\n animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,\n width: '100%',\n height: '100%',\n position: 'relative',\n transformStyle: 'preserve-3d',\n }}\n >\n {[0, 120, 240].map((angle) => (\n <div\n key={angle}\n className=\"absolute rounded-full\"\n style={{\n width: dotSize,\n height: dotSize,\n backgroundColor: 'currentColor',\n left: '50%',\n top: '50%',\n transform: `translate(-50%, -50%) rotate(${angle}deg) translateX(${orbitRadius}px)`,\n }}\n />\n ))}\n </div>\n </div>\n )\n}\n\n// ============================================================================\n// Orbit Cube — wireframe cube rotating in 3D\n// ============================================================================\n\n/** Cube face sizes per spinner size */\nconst CUBE_SIZES = { sm: 12, default: 18, lg: 26 } as const\n\nfunction OrbitCubeSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const cubeSize = CUBE_SIZES[size]\n const half = cubeSize / 2\n const radius = Math.round(cubeSize * 0.15)\n\n const overlap = 1\n const faceBase: React.CSSProperties = {\n position: 'absolute',\n width: cubeSize + overlap * 2,\n height: cubeSize + overlap * 2,\n backgroundColor: 'currentColor',\n borderRadius: radius,\n top: -overlap,\n left: -overlap,\n }\n\n return (\n <div\n className={cn(orbitTextColorMap[color])}\n style={{\n width: cubeSize,\n height: cubeSize,\n perspective: cubeSize * 6,\n }}\n >\n {/* Diagonal tilt — shows top + corner for depth */}\n <div\n style={{\n width: cubeSize,\n height: cubeSize,\n transform: 'rotateX(-25deg) rotateZ(15deg)',\n transformStyle: 'preserve-3d',\n }}\n >\n {/* Y-axis rotation */}\n <div\n className=\"animate-spinner-orbit\"\n style={{\n animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,\n width: cubeSize,\n height: cubeSize,\n position: 'relative',\n transformStyle: 'preserve-3d',\n }}\n >\n <div style={{ ...faceBase, transform: `translateZ(${half}px)`, opacity: 0.25 }} />\n <div style={{ ...faceBase, transform: `translateZ(${-half}px)`, opacity: 0.1 }} />\n <div style={{ ...faceBase, transform: `rotateY(-90deg) translateZ(${half}px)`, opacity: 0.2 }} />\n <div style={{ ...faceBase, transform: `rotateY(90deg) translateZ(${half}px)`, opacity: 0.2 }} />\n <div style={{ ...faceBase, transform: `rotateX(90deg) translateZ(${half}px)`, opacity: 0.15 }} />\n <div style={{ ...faceBase, transform: `rotateX(-90deg) translateZ(${half}px)`, opacity: 0.08 }} />\n </div>\n </div>\n </div>\n )\n}\n\n// ============================================================================\n// Orbit Flip — rounded square tumbling in 3D\n// ============================================================================\n\n/** Flip square sizes per spinner size */\nconst FLIP_SIZES = { sm: 14, default: 20, lg: 28 } as const\n\nfunction OrbitFlipSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const sqSize = FLIP_SIZES[size]\n\n return (\n <div\n className={cn(orbitTextColorMap[color])}\n style={{\n width: sqSize,\n height: sqSize,\n perspective: sqSize * 4,\n }}\n >\n <div style={{ transform: 'rotateX(25deg)', transformStyle: 'preserve-3d', width: '100%', height: '100%' }}>\n <div\n className=\"animate-spinner-orbit\"\n style={{\n animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,\n width: '100%',\n height: '100%',\n borderRadius: '25%',\n backgroundColor: 'currentColor',\n opacity: 0.85,\n }}\n />\n </div>\n </div>\n )\n}\n\n// ============================================================================\n// Orbit Morph — organic shape morphing + 3D rotation\n// ============================================================================\n\n/** Morph sizes per spinner size */\nconst MORPH_SIZES = { sm: 16, default: 24, lg: 34 } as const\n\nfunction OrbitMorphSpinner({ size, color, speed }: {\n size: 'sm' | 'default' | 'lg'\n color: 'default' | 'primary' | 'current'\n speed: 'slow' | 'default' | 'fast'\n}) {\n const morphSize = MORPH_SIZES[size]\n\n return (\n <div\n className={cn(orbitTextColorMap[color])}\n style={{\n width: morphSize,\n height: morphSize,\n perspective: morphSize * 3,\n }}\n >\n <div\n className=\"animate-spinner-morph\"\n style={{\n animationDuration: `${ORBIT_SPEED_MS[speed]}ms`,\n width: '100%',\n height: '100%',\n backgroundColor: 'currentColor',\n opacity: 0.85,\n }}\n />\n </div>\n )\n}\n\nexport { Spinner, spinnerVariants }\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
cn
|
|
4
|
+
} from "./chunk-53MIUPSY.mjs";
|
|
5
|
+
|
|
6
|
+
// src/components/ui/progress.tsx
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import * as ProgressPrimitive from "@radix-ui/react-progress";
|
|
9
|
+
import { cva } from "class-variance-authority";
|
|
10
|
+
var CIRCULAR_VIEWBOX = 100;
|
|
11
|
+
var CIRCULAR_CENTER = 50;
|
|
12
|
+
var CIRCULAR_SIZES = {
|
|
13
|
+
sm: 32,
|
|
14
|
+
default: 48,
|
|
15
|
+
lg: 64
|
|
16
|
+
};
|
|
17
|
+
var CIRCULAR_THICKNESS = {
|
|
18
|
+
sm: 4,
|
|
19
|
+
default: 5,
|
|
20
|
+
lg: 6
|
|
21
|
+
};
|
|
22
|
+
var CIRCULAR_FONT_SIZES = {
|
|
23
|
+
sm: "text-2xs",
|
|
24
|
+
default: "text-xs",
|
|
25
|
+
lg: "text-sm"
|
|
26
|
+
};
|
|
27
|
+
var linearTrackVariants = cva(
|
|
28
|
+
"relative w-full overflow-hidden bg-border rounded-full",
|
|
29
|
+
{
|
|
30
|
+
variants: {
|
|
31
|
+
size: {
|
|
32
|
+
sm: "h-1",
|
|
33
|
+
default: "h-2",
|
|
34
|
+
lg: "h-3"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
defaultVariants: {
|
|
38
|
+
size: "default"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
var colorMap = {
|
|
43
|
+
default: "bg-foreground",
|
|
44
|
+
primary: "bg-primary"
|
|
45
|
+
};
|
|
46
|
+
var circularColorMap = {
|
|
47
|
+
default: "stroke-foreground",
|
|
48
|
+
primary: "stroke-primary"
|
|
49
|
+
};
|
|
50
|
+
var valueFontSizes = {
|
|
51
|
+
sm: "text-xs",
|
|
52
|
+
default: "text-sm",
|
|
53
|
+
lg: "text-base"
|
|
54
|
+
};
|
|
55
|
+
var Progress = React.forwardRef(({
|
|
56
|
+
className,
|
|
57
|
+
type = "linear",
|
|
58
|
+
value = 0,
|
|
59
|
+
max = 100,
|
|
60
|
+
size,
|
|
61
|
+
variant = "default",
|
|
62
|
+
color = "default",
|
|
63
|
+
indicatorClassName,
|
|
64
|
+
showValue = false,
|
|
65
|
+
formatLabel,
|
|
66
|
+
animated = false,
|
|
67
|
+
thickness,
|
|
68
|
+
label,
|
|
69
|
+
...props
|
|
70
|
+
}, ref) => {
|
|
71
|
+
const resolvedSize = size || "default";
|
|
72
|
+
const clampedValue = Math.min(Math.max(value, 0), max);
|
|
73
|
+
const percentage = clampedValue / max * 100;
|
|
74
|
+
const valueLabel = formatLabel ? formatLabel(clampedValue, max) : `${Math.round(percentage)}%`;
|
|
75
|
+
if (type === "circular") {
|
|
76
|
+
const diameter = CIRCULAR_SIZES[resolvedSize];
|
|
77
|
+
const strokeWidth = thickness ?? CIRCULAR_THICKNESS[resolvedSize];
|
|
78
|
+
const r = (CIRCULAR_VIEWBOX - strokeWidth) / 2;
|
|
79
|
+
const circumference = 2 * Math.PI * r;
|
|
80
|
+
const offset = circumference * (1 - percentage / 100);
|
|
81
|
+
return /* @__PURE__ */ React.createElement(
|
|
82
|
+
"div",
|
|
83
|
+
{
|
|
84
|
+
className: cn("inline-flex items-center gap-2", className),
|
|
85
|
+
role: "progressbar",
|
|
86
|
+
"aria-valuenow": clampedValue,
|
|
87
|
+
"aria-valuemin": 0,
|
|
88
|
+
"aria-valuemax": max,
|
|
89
|
+
"aria-label": label
|
|
90
|
+
},
|
|
91
|
+
/* @__PURE__ */ React.createElement("div", { className: "relative", style: { width: diameter, height: diameter } }, /* @__PURE__ */ React.createElement(
|
|
92
|
+
"svg",
|
|
93
|
+
{
|
|
94
|
+
viewBox: `0 0 ${CIRCULAR_VIEWBOX} ${CIRCULAR_VIEWBOX}`,
|
|
95
|
+
className: "transform -rotate-90",
|
|
96
|
+
width: diameter,
|
|
97
|
+
height: diameter
|
|
98
|
+
},
|
|
99
|
+
/* @__PURE__ */ React.createElement(
|
|
100
|
+
"circle",
|
|
101
|
+
{
|
|
102
|
+
cx: CIRCULAR_CENTER,
|
|
103
|
+
cy: CIRCULAR_CENTER,
|
|
104
|
+
r,
|
|
105
|
+
fill: "none",
|
|
106
|
+
className: "stroke-border",
|
|
107
|
+
strokeWidth
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
/* @__PURE__ */ React.createElement(
|
|
111
|
+
"circle",
|
|
112
|
+
{
|
|
113
|
+
cx: CIRCULAR_CENTER,
|
|
114
|
+
cy: CIRCULAR_CENTER,
|
|
115
|
+
r,
|
|
116
|
+
fill: "none",
|
|
117
|
+
className: cn(indicatorClassName || circularColorMap[color], "transition-[stroke-dashoffset] duration-normal ease-out"),
|
|
118
|
+
strokeWidth,
|
|
119
|
+
strokeDasharray: circumference,
|
|
120
|
+
strokeDashoffset: offset,
|
|
121
|
+
strokeLinecap: "round"
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
), showValue && resolvedSize !== "sm" && /* @__PURE__ */ React.createElement("div", { className: cn(
|
|
125
|
+
"absolute inset-0 flex items-center justify-center font-semibold font-mono tabular-nums text-foreground",
|
|
126
|
+
CIRCULAR_FONT_SIZES[resolvedSize]
|
|
127
|
+
) }, valueLabel))
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
const stripedBg = variant === "striped" ? "bg-[length:1rem_1rem] bg-[linear-gradient(45deg,rgba(255,255,255,0.15)_25%,transparent_25%,transparent_50%,rgba(255,255,255,0.15)_50%,rgba(255,255,255,0.15)_75%,transparent_75%,transparent)]" : "";
|
|
131
|
+
return /* @__PURE__ */ React.createElement("div", { className: cn("flex items-center gap-3", showValue && "w-full", className) }, /* @__PURE__ */ React.createElement(
|
|
132
|
+
ProgressPrimitive.Root,
|
|
133
|
+
{
|
|
134
|
+
ref,
|
|
135
|
+
className: cn(linearTrackVariants({ size })),
|
|
136
|
+
value: clampedValue,
|
|
137
|
+
max,
|
|
138
|
+
"aria-label": label,
|
|
139
|
+
...props
|
|
140
|
+
},
|
|
141
|
+
/* @__PURE__ */ React.createElement(
|
|
142
|
+
ProgressPrimitive.Indicator,
|
|
143
|
+
{
|
|
144
|
+
className: cn(
|
|
145
|
+
"h-full transition-[width] duration-normal ease-out rounded-full",
|
|
146
|
+
indicatorClassName || colorMap[color],
|
|
147
|
+
stripedBg,
|
|
148
|
+
animated && variant === "striped" && "animate-progress-stripe"
|
|
149
|
+
),
|
|
150
|
+
style: { width: `${percentage}%` }
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
), showValue && /* @__PURE__ */ React.createElement("span", { className: cn(
|
|
154
|
+
"shrink-0 font-semibold font-mono tabular-nums text-foreground",
|
|
155
|
+
valueFontSizes[resolvedSize]
|
|
156
|
+
) }, valueLabel));
|
|
157
|
+
});
|
|
158
|
+
Progress.displayName = "Progress";
|
|
159
|
+
|
|
160
|
+
export {
|
|
161
|
+
linearTrackVariants,
|
|
162
|
+
Progress
|
|
163
|
+
};
|
|
164
|
+
//# sourceMappingURL=chunk-DDRYEJBJ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/progress.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as ProgressPrimitive from '@radix-ui/react-progress'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '@/lib/utils'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Circular SVG viewBox size */\nconst CIRCULAR_VIEWBOX = 100\n/** Circular center point */\nconst CIRCULAR_CENTER = 50\n\n/** Circular sizes (diameter in px) */\nconst CIRCULAR_SIZES = {\n sm: 32,\n default: 48,\n lg: 64,\n} as const\n\n/** Circular stroke thickness per size */\nconst CIRCULAR_THICKNESS = {\n sm: 4,\n default: 5,\n lg: 6,\n} as const\n\n/** Circular value font sizes */\nconst CIRCULAR_FONT_SIZES = {\n sm: 'text-2xs',\n default: 'text-xs',\n lg: 'text-sm',\n} as const\n\n// ============================================================================\n// Linear Progress\n// ============================================================================\n\nconst linearTrackVariants = cva(\n 'relative w-full overflow-hidden bg-border rounded-full',\n {\n variants: {\n size: {\n sm: 'h-1',\n default: 'h-2',\n lg: 'h-3',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n }\n)\n\nconst colorMap = {\n default: 'bg-foreground',\n primary: 'bg-primary',\n} as const\n\nconst circularColorMap = {\n default: 'stroke-foreground',\n primary: 'stroke-primary',\n} as const\n\nconst valueFontSizes = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ProgressProps\n extends Omit<React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>, 'children'>,\n VariantProps<typeof linearTrackVariants> {\n /** Progress type */\n type?: 'linear' | 'circular'\n /** Current value (0 to max) */\n value?: number\n /** Maximum value */\n max?: number\n /** Visual variant (linear only) */\n variant?: 'default' | 'striped'\n /** Indicator color */\n color?: 'default' | 'primary'\n /** Custom indicator class (overrides color) */\n indicatorClassName?: string\n /** Show percentage value */\n showValue?: boolean\n /** Custom label formatter */\n formatLabel?: (value: number, max: number) => string\n /** Animate striped variant */\n animated?: boolean\n /** Circular stroke thickness override */\n thickness?: number\n /** Accessibility label */\n label?: string\n}\n\nconst Progress = React.forwardRef<\n React.ElementRef<typeof ProgressPrimitive.Root>,\n ProgressProps\n>(({\n className,\n type = 'linear',\n value = 0,\n max = 100,\n size,\n variant = 'default',\n color = 'default',\n indicatorClassName,\n showValue = false,\n formatLabel,\n animated = false,\n thickness,\n label,\n ...props\n}, ref) => {\n const resolvedSize = size || 'default'\n const clampedValue = Math.min(Math.max(value, 0), max)\n const percentage = (clampedValue / max) * 100\n\n const valueLabel = formatLabel\n ? formatLabel(clampedValue, max)\n : `${Math.round(percentage)}%`\n\n // ── Circular ──\n if (type === 'circular') {\n const diameter = CIRCULAR_SIZES[resolvedSize]\n const strokeWidth = thickness ?? CIRCULAR_THICKNESS[resolvedSize]\n const r = (CIRCULAR_VIEWBOX - strokeWidth) / 2\n const circumference = 2 * Math.PI * r\n const offset = circumference * (1 - percentage / 100)\n\n return (\n <div\n className={cn('inline-flex items-center gap-2', className)}\n role=\"progressbar\"\n aria-valuenow={clampedValue}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-label={label}\n >\n <div className=\"relative\" style={{ width: diameter, height: diameter }}>\n <svg\n viewBox={`0 0 ${CIRCULAR_VIEWBOX} ${CIRCULAR_VIEWBOX}`}\n className=\"transform -rotate-90\"\n width={diameter}\n height={diameter}\n >\n {/* Track */}\n <circle\n cx={CIRCULAR_CENTER}\n cy={CIRCULAR_CENTER}\n r={r}\n fill=\"none\"\n className=\"stroke-border\"\n strokeWidth={strokeWidth}\n />\n {/* Indicator */}\n <circle\n cx={CIRCULAR_CENTER}\n cy={CIRCULAR_CENTER}\n r={r}\n fill=\"none\"\n className={cn(indicatorClassName || circularColorMap[color], 'transition-[stroke-dashoffset] duration-normal ease-out')}\n strokeWidth={strokeWidth}\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n />\n </svg>\n {/* Center value */}\n {showValue && resolvedSize !== 'sm' && (\n <div className={cn(\n 'absolute inset-0 flex items-center justify-center font-semibold font-mono tabular-nums text-foreground',\n CIRCULAR_FONT_SIZES[resolvedSize]\n )}>\n {valueLabel}\n </div>\n )}\n </div>\n </div>\n )\n }\n\n // ── Linear ──\n const stripedBg = variant === 'striped'\n ? 'bg-[length:1rem_1rem] bg-[linear-gradient(45deg,rgba(255,255,255,0.15)_25%,transparent_25%,transparent_50%,rgba(255,255,255,0.15)_50%,rgba(255,255,255,0.15)_75%,transparent_75%,transparent)]'\n : ''\n\n return (\n <div className={cn('flex items-center gap-3', showValue && 'w-full', className)}>\n <ProgressPrimitive.Root\n ref={ref}\n className={cn(linearTrackVariants({ size }))}\n value={clampedValue}\n max={max}\n aria-label={label}\n {...props}\n >\n <ProgressPrimitive.Indicator\n className={cn(\n 'h-full transition-[width] duration-normal ease-out rounded-full',\n indicatorClassName || colorMap[color],\n stripedBg,\n animated && variant === 'striped' && 'animate-progress-stripe',\n )}\n style={{ width: `${percentage}%` }}\n />\n </ProgressPrimitive.Root>\n {showValue && (\n <span className={cn(\n 'shrink-0 font-semibold font-mono tabular-nums text-foreground',\n valueFontSizes[resolvedSize]\n )}>\n {valueLabel}\n </span>\n )}\n </div>\n )\n})\nProgress.displayName = 'Progress'\n\nexport { Progress, linearTrackVariants }\n"],"mappings":"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","names":[]}
|