@lindle/linoardo 1.0.21 → 1.0.22

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.
@@ -0,0 +1,312 @@
1
+ import { twMerge } from 'tailwind-merge';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+
4
+ // src/Feedback/Progress/index.tsx
5
+ var clampPercent = (value) => {
6
+ if (value === void 0 || value === null || Number.isNaN(value)) {
7
+ return 0;
8
+ }
9
+ return Math.min(100, Math.max(0, value));
10
+ };
11
+ var statusIconMap = {
12
+ success: "mdi mdi-check",
13
+ exception: "mdi mdi-alert"
14
+ };
15
+ var strokeColorByStatus = {
16
+ normal: "rgb(99 102 241)",
17
+ active: "rgb(99 102 241)",
18
+ success: "rgb(16 185 129)",
19
+ exception: "rgb(239 68 68)"
20
+ };
21
+ var trailColorDefault = "rgb(229 231 235)";
22
+ var resolveStroke = (status, strokeColor, gradientId) => {
23
+ if (!strokeColor) {
24
+ return { color: strokeColorByStatus[status] };
25
+ }
26
+ if (typeof strokeColor === "string") {
27
+ return { color: strokeColor };
28
+ }
29
+ const id = gradientId ?? `progress-gradient-${Math.random().toString(16).slice(2)}`;
30
+ return {
31
+ color: `url(#${id})`,
32
+ gradient: { id, from: strokeColor.from, to: strokeColor.to },
33
+ cssGradient: `linear-gradient(90deg, ${strokeColor.from}, ${strokeColor.to})`
34
+ };
35
+ };
36
+ var resolveRotation = (gapPosition) => {
37
+ switch (gapPosition) {
38
+ case "bottom":
39
+ return 90;
40
+ case "left":
41
+ return 180;
42
+ case "right":
43
+ return 0;
44
+ case "top":
45
+ default:
46
+ return -90;
47
+ }
48
+ };
49
+ var buildGradientId = (strokeColor) => {
50
+ if (strokeColor && typeof strokeColor !== "string") {
51
+ const from = strokeColor.from.replace(/\W+/g, "");
52
+ const to = strokeColor.to.replace(/\W+/g, "");
53
+ return `progress-gradient-${from}-${to}`;
54
+ }
55
+ return void 0;
56
+ };
57
+ var InfoNode = ({ status, percent, successPercent, format }) => {
58
+ const iconClass = status === "success" || status === "exception" ? statusIconMap[status] : void 0;
59
+ const content = typeof format === "function" ? format(percent, successPercent) : iconClass ? /* @__PURE__ */ jsx("i", { className: iconClass, "aria-hidden": true }) : `${Math.round(percent)}%`;
60
+ return /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-200", children: content });
61
+ };
62
+ var renderSteps = (percent, steps, status, strokeStyle, trailColor, height) => {
63
+ const filled = Math.round(percent / 100 * steps);
64
+ const stepStyle = height ? { height } : {};
65
+ return /* @__PURE__ */ jsx("div", { className: "flex w-full items-center gap-1", style: stepStyle, children: Array.from({ length: steps }).map((_, idx) => {
66
+ const isFilled = idx < filled;
67
+ const resolvedStyle = {
68
+ ...isFilled ? strokeStyle : { backgroundColor: trailColor ?? trailColorDefault },
69
+ height
70
+ };
71
+ return /* @__PURE__ */ jsx(
72
+ "span",
73
+ {
74
+ className: twMerge(
75
+ "flex-1 rounded-full",
76
+ isFilled ? void 0 : "bg-gray-200 dark:bg-gray-800",
77
+ status === "active" && isFilled ? "animate-pulse" : void 0
78
+ ),
79
+ style: resolvedStyle
80
+ },
81
+ idx
82
+ );
83
+ }) });
84
+ };
85
+ var LineProgress = ({
86
+ percent,
87
+ status,
88
+ successPercent,
89
+ format,
90
+ showInfo = true,
91
+ strokeWidth,
92
+ trailColor,
93
+ strokeColor,
94
+ success,
95
+ size = "default",
96
+ steps,
97
+ className,
98
+ style,
99
+ ...rest
100
+ }) => {
101
+ const height = strokeWidth ?? (size === "small" ? 6 : size === "large" ? 12 : 8);
102
+ const gradientId = buildGradientId(strokeColor);
103
+ const { color, gradient, cssGradient } = resolveStroke(status, strokeColor, gradientId);
104
+ const stepStrokeStyle = gradient ? { backgroundImage: cssGradient } : { backgroundColor: color };
105
+ const lineStyle = {
106
+ height,
107
+ backgroundColor: trailColor ?? trailColorDefault
108
+ };
109
+ const barStyle = {
110
+ width: `${percent}%`,
111
+ height,
112
+ backgroundColor: color,
113
+ background: gradient ? cssGradient : color
114
+ };
115
+ const successWidth = successPercent ? Math.min(successPercent, percent) : 0;
116
+ const successColor = success?.strokeColor ?? "rgb(16 185 129)";
117
+ return /* @__PURE__ */ jsxs("div", { className: twMerge("flex w-full items-center gap-3", className), style, ...rest, children: [
118
+ /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-hidden rounded-full", style: lineStyle, children: typeof steps === "number" && steps > 1 ? renderSteps(percent, steps, status, stepStrokeStyle, trailColor, height) : /* @__PURE__ */ jsxs(Fragment, { children: [
119
+ /* @__PURE__ */ jsx(
120
+ "div",
121
+ {
122
+ className: twMerge(
123
+ "h-full rounded-full transition-[width] duration-300 ease-out",
124
+ status === "active" ? "animate-pulse" : void 0
125
+ ),
126
+ style: barStyle
127
+ }
128
+ ),
129
+ successWidth > 0 ? /* @__PURE__ */ jsx(
130
+ "div",
131
+ {
132
+ className: "absolute inset-y-0 left-0 rounded-full transition-[width] duration-300 ease-out",
133
+ style: { width: `${successWidth}%`, height, backgroundColor: successColor }
134
+ }
135
+ ) : null
136
+ ] }) }),
137
+ showInfo ? /* @__PURE__ */ jsx(InfoNode, { status, percent, successPercent, format }) : null
138
+ ] });
139
+ };
140
+ var CircleProgress = ({
141
+ percent,
142
+ status,
143
+ successPercent,
144
+ format,
145
+ showInfo = true,
146
+ strokeWidth,
147
+ trailColor,
148
+ strokeColor,
149
+ success,
150
+ width = 120,
151
+ type,
152
+ gapDegree,
153
+ gapPosition = "top",
154
+ className,
155
+ style,
156
+ ...rest
157
+ }) => {
158
+ const stroke = strokeWidth ?? 10;
159
+ const radius = (width - stroke) / 2;
160
+ const circumference = 2 * Math.PI * radius;
161
+ const gap = type === "dashboard" ? gapDegree ?? 75 : gapDegree ?? 0;
162
+ const perimeter = circumference - gap / 360 * circumference;
163
+ const dashOffsetBase = gap / 360 * circumference / 2;
164
+ const dashArray = `${perimeter} ${circumference}`;
165
+ const gradientId = buildGradientId(strokeColor);
166
+ const { color, gradient } = resolveStroke(status, strokeColor, gradientId);
167
+ const rotation = resolveRotation(gapPosition);
168
+ const successColor = success?.strokeColor ?? "rgb(16 185 129)";
169
+ const progressDashOffset = (100 - percent) / 100 * perimeter + dashOffsetBase;
170
+ const successDashOffset = (100 - successPercent) / 100 * perimeter + dashOffsetBase;
171
+ return /* @__PURE__ */ jsx("div", { className: twMerge("inline-flex flex-col items-center justify-center", className), style, ...rest, children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", style: { width, height: width }, children: [
172
+ /* @__PURE__ */ jsxs(
173
+ "svg",
174
+ {
175
+ width,
176
+ height: width,
177
+ viewBox: `0 0 ${width} ${width}`,
178
+ className: "absolute inset-0 overflow-visible",
179
+ style: { transform: `rotate(${rotation}deg)` },
180
+ children: [
181
+ gradient ? /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradient.id, x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
182
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: gradient.from }),
183
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: gradient.to })
184
+ ] }) }) : null,
185
+ /* @__PURE__ */ jsx(
186
+ "circle",
187
+ {
188
+ cx: width / 2,
189
+ cy: width / 2,
190
+ r: radius,
191
+ strokeWidth: stroke,
192
+ stroke: trailColor ?? trailColorDefault,
193
+ fill: "none",
194
+ strokeDasharray: dashArray,
195
+ strokeDashoffset: dashOffsetBase,
196
+ strokeLinecap: "round"
197
+ }
198
+ ),
199
+ /* @__PURE__ */ jsx(
200
+ "circle",
201
+ {
202
+ cx: width / 2,
203
+ cy: width / 2,
204
+ r: radius,
205
+ strokeWidth: stroke,
206
+ stroke: color,
207
+ fill: "none",
208
+ strokeDasharray: dashArray,
209
+ strokeDashoffset: progressDashOffset,
210
+ strokeLinecap: "round",
211
+ className: twMerge(status === "active" ? "animate-[spin_3s_linear_infinite]" : void 0)
212
+ }
213
+ ),
214
+ successPercent > 0 ? /* @__PURE__ */ jsx(
215
+ "circle",
216
+ {
217
+ cx: width / 2,
218
+ cy: width / 2,
219
+ r: radius,
220
+ strokeWidth: stroke,
221
+ stroke: successColor,
222
+ fill: "none",
223
+ strokeDasharray: dashArray,
224
+ strokeDashoffset: successDashOffset,
225
+ strokeLinecap: "round"
226
+ }
227
+ ) : null
228
+ ]
229
+ }
230
+ ),
231
+ showInfo ? /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-800 dark:text-gray-100", children: /* @__PURE__ */ jsx(InfoNode, { status, percent, successPercent, format }) }) }) : null
232
+ ] }) });
233
+ };
234
+ var Progress = (props) => {
235
+ const toNumber = (value) => {
236
+ if (typeof value === "string") {
237
+ const parsed = Number.parseFloat(value);
238
+ return Number.isFinite(parsed) ? parsed : void 0;
239
+ }
240
+ return value;
241
+ };
242
+ const {
243
+ percent: rawPercent = 0,
244
+ success,
245
+ status: providedStatus,
246
+ type = "line",
247
+ showInfo = true,
248
+ format,
249
+ strokeWidth,
250
+ trailColor,
251
+ strokeColor,
252
+ width,
253
+ size,
254
+ steps,
255
+ gapDegree,
256
+ gapPosition,
257
+ className,
258
+ style,
259
+ ...restProps
260
+ } = props;
261
+ const percent = clampPercent(toNumber(rawPercent));
262
+ const successPercent = clampPercent(toNumber(success?.percent));
263
+ const status = providedStatus ?? (percent >= 100 ? "success" : "normal");
264
+ const resolvedClassName = twMerge("min-w-[200px]", className);
265
+ if (type === "circle" || type === "dashboard") {
266
+ return /* @__PURE__ */ jsx(
267
+ CircleProgress,
268
+ {
269
+ ...restProps,
270
+ type,
271
+ percent,
272
+ successPercent,
273
+ success,
274
+ status,
275
+ showInfo,
276
+ className: resolvedClassName,
277
+ format,
278
+ strokeWidth,
279
+ trailColor,
280
+ strokeColor,
281
+ width,
282
+ gapDegree,
283
+ gapPosition,
284
+ style
285
+ }
286
+ );
287
+ }
288
+ return /* @__PURE__ */ jsx(
289
+ LineProgress,
290
+ {
291
+ percent,
292
+ successPercent,
293
+ success,
294
+ status,
295
+ showInfo,
296
+ className: resolvedClassName,
297
+ format,
298
+ strokeWidth,
299
+ trailColor,
300
+ strokeColor,
301
+ size,
302
+ steps,
303
+ style,
304
+ ...restProps
305
+ }
306
+ );
307
+ };
308
+ var Progress_default = Progress;
309
+
310
+ export { Progress_default };
311
+ //# sourceMappingURL=chunk-Z5A2OIDI.js.map
312
+ //# sourceMappingURL=chunk-Z5A2OIDI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Feedback/Progress/index.tsx"],"names":[],"mappings":"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","file":"chunk-Z5A2OIDI.js","sourcesContent":["import * as React from 'react';\nimport { twMerge } from 'tailwind-merge';\nimport type { ProgressProps, ProgressStatus, ProgressType } from './types.progress';\n\nconst clampPercent = (value?: number) => {\n if (value === undefined || value === null || Number.isNaN(value)) {\n return 0;\n }\n return Math.min(100, Math.max(0, value));\n};\n\nconst statusIconMap: Record<Exclude<ProgressStatus, 'normal' | 'active'>, string> = {\n success: 'mdi mdi-check',\n exception: 'mdi mdi-alert'\n};\n\nconst strokeColorByStatus: Record<ProgressStatus, string> = {\n normal: 'rgb(99 102 241)',\n active: 'rgb(99 102 241)',\n success: 'rgb(16 185 129)',\n exception: 'rgb(239 68 68)'\n};\n\nconst trailColorDefault = 'rgb(229 231 235)';\n\nconst resolveStroke = (\n status: ProgressStatus,\n strokeColor?: ProgressProps['strokeColor'],\n gradientId?: string\n): { color: string; gradient?: { id: string; from: string; to: string }; cssGradient?: string } => {\n if (!strokeColor) {\n return { color: strokeColorByStatus[status] };\n }\n if (typeof strokeColor === 'string') {\n return { color: strokeColor };\n }\n const id = gradientId ?? `progress-gradient-${Math.random().toString(16).slice(2)}`;\n return {\n color: `url(#${id})`,\n gradient: { id, from: strokeColor.from, to: strokeColor.to },\n cssGradient: `linear-gradient(90deg, ${strokeColor.from}, ${strokeColor.to})`\n };\n};\n\nconst resolveRotation = (gapPosition: NonNullable<ProgressProps['gapPosition']>) => {\n switch (gapPosition) {\n case 'bottom':\n return 90;\n case 'left':\n return 180;\n case 'right':\n return 0;\n case 'top':\n default:\n return -90;\n }\n};\n\nconst buildGradientId = (strokeColor?: ProgressProps['strokeColor']) => {\n if (strokeColor && typeof strokeColor !== 'string') {\n const from = strokeColor.from.replace(/\\W+/g, '');\n const to = strokeColor.to.replace(/\\W+/g, '');\n return `progress-gradient-${from}-${to}`;\n }\n return undefined;\n};\n\nconst InfoNode: React.FC<{\n status: ProgressStatus;\n percent: number;\n successPercent: number;\n format?: ProgressProps['format'];\n}> = ({ status, percent, successPercent, format }) => {\n const iconClass =\n status === 'success' || status === 'exception' ? statusIconMap[status] : undefined;\n\n const content =\n typeof format === 'function'\n ? format(percent, successPercent)\n : iconClass\n ? <i className={iconClass} aria-hidden />\n : `${Math.round(percent)}%`;\n\n return <span className='text-sm font-medium text-gray-700 dark:text-gray-200'>{content}</span>;\n};\n\nconst renderSteps = (\n percent: number,\n steps: number,\n status: ProgressStatus,\n strokeStyle: { backgroundColor?: string; backgroundImage?: string },\n trailColor?: string,\n height?: number\n) => {\n const filled = Math.round((percent / 100) * steps);\n const stepStyle: React.CSSProperties = height ? { height } : {};\n\n return (\n <div className='flex w-full items-center gap-1' style={stepStyle}>\n {Array.from({ length: steps }).map((_, idx) => {\n const isFilled = idx < filled;\n const resolvedStyle: React.CSSProperties = {\n ...(isFilled ? strokeStyle : { backgroundColor: trailColor ?? trailColorDefault }),\n height\n };\n return (\n <span\n key={idx}\n className={twMerge(\n 'flex-1 rounded-full',\n isFilled ? undefined : 'bg-gray-200 dark:bg-gray-800',\n status === 'active' && isFilled ? 'animate-pulse' : undefined\n )}\n style={resolvedStyle}\n />\n );\n })}\n </div>\n );\n};\n\nconst LineProgress: React.FC<ProgressProps & { percent: number; status: ProgressStatus; successPercent: number }> = ({\n percent,\n status,\n successPercent,\n format,\n showInfo = true,\n strokeWidth,\n trailColor,\n strokeColor,\n success,\n size = 'default',\n steps,\n className,\n style,\n ...rest\n}) => {\n const height = strokeWidth ?? (size === 'small' ? 6 : size === 'large' ? 12 : 8);\n const gradientId = buildGradientId(strokeColor);\n const { color, gradient, cssGradient } = resolveStroke(status, strokeColor, gradientId);\n const stepStrokeStyle = gradient ? { backgroundImage: cssGradient } : { backgroundColor: color };\n const lineStyle: React.CSSProperties = {\n height,\n backgroundColor: trailColor ?? trailColorDefault\n };\n const barStyle: React.CSSProperties = {\n width: `${percent}%`,\n height,\n backgroundColor: color,\n background: gradient ? cssGradient : color\n };\n\n const successWidth = successPercent ? Math.min(successPercent, percent) : 0;\n const successColor = success?.strokeColor ?? 'rgb(16 185 129)';\n\n return (\n <div className={twMerge('flex w-full items-center gap-3', className)} style={style} {...rest}>\n <div className='relative w-full overflow-hidden rounded-full' style={lineStyle}>\n {typeof steps === 'number' && steps > 1\n ? renderSteps(percent, steps, status, stepStrokeStyle, trailColor, height)\n : (\n <>\n <div\n className={twMerge(\n 'h-full rounded-full transition-[width] duration-300 ease-out',\n status === 'active' ? 'animate-pulse' : undefined\n )}\n style={barStyle}\n />\n {successWidth > 0 ? (\n <div\n className='absolute inset-y-0 left-0 rounded-full transition-[width] duration-300 ease-out'\n style={{ width: `${successWidth}%`, height, backgroundColor: successColor }}\n />\n ) : null}\n </>\n )}\n </div>\n {showInfo ? <InfoNode status={status} percent={percent} successPercent={successPercent} format={format} /> : null}\n </div>\n );\n};\n\nconst CircleProgress: React.FC<ProgressProps & { percent: number; status: ProgressStatus; successPercent: number }> = ({\n percent,\n status,\n successPercent,\n format,\n showInfo = true,\n strokeWidth,\n trailColor,\n strokeColor,\n success,\n width = 120,\n type,\n gapDegree,\n gapPosition = 'top',\n className,\n style,\n ...rest\n}) => {\n const stroke = strokeWidth ?? 10;\n const radius = (width - stroke) / 2;\n const circumference = 2 * Math.PI * radius;\n const gap = type === 'dashboard' ? gapDegree ?? 75 : gapDegree ?? 0;\n const perimeter = circumference - (gap / 360) * circumference;\n const dashOffsetBase = (gap / 360) * circumference / 2;\n const dashArray = `${perimeter} ${circumference}`;\n const gradientId = buildGradientId(strokeColor);\n const { color, gradient } = resolveStroke(status, strokeColor, gradientId);\n const rotation = resolveRotation(gapPosition);\n const successColor = success?.strokeColor ?? 'rgb(16 185 129)';\n\n const progressDashOffset = ((100 - percent) / 100) * perimeter + dashOffsetBase;\n const successDashOffset = ((100 - successPercent) / 100) * perimeter + dashOffsetBase;\n\n return (\n <div className={twMerge('inline-flex flex-col items-center justify-center', className)} style={style} {...rest}>\n <div className='relative flex items-center justify-center' style={{ width, height: width }}>\n <svg\n width={width}\n height={width}\n viewBox={`0 0 ${width} ${width}`}\n className='absolute inset-0 overflow-visible'\n style={{ transform: `rotate(${rotation}deg)` }}\n >\n {gradient ? (\n <defs>\n <linearGradient id={gradient.id} x1='0%' y1='0%' x2='100%' y2='0%'>\n <stop offset='0%' stopColor={gradient.from} />\n <stop offset='100%' stopColor={gradient.to} />\n </linearGradient>\n </defs>\n ) : null}\n <circle\n cx={width / 2}\n cy={width / 2}\n r={radius}\n strokeWidth={stroke}\n stroke={trailColor ?? trailColorDefault}\n fill='none'\n strokeDasharray={dashArray}\n strokeDashoffset={dashOffsetBase}\n strokeLinecap='round'\n />\n <circle\n cx={width / 2}\n cy={width / 2}\n r={radius}\n strokeWidth={stroke}\n stroke={color}\n fill='none'\n strokeDasharray={dashArray}\n strokeDashoffset={progressDashOffset}\n strokeLinecap='round'\n className={twMerge(status === 'active' ? 'animate-[spin_3s_linear_infinite]' : undefined)}\n />\n {successPercent > 0 ? (\n <circle\n cx={width / 2}\n cy={width / 2}\n r={radius}\n strokeWidth={stroke}\n stroke={successColor}\n fill='none'\n strokeDasharray={dashArray}\n strokeDashoffset={successDashOffset}\n strokeLinecap='round'\n />\n ) : null}\n </svg>\n {showInfo ? (\n <div className='absolute inset-0 flex items-center justify-center'>\n <div className='text-sm font-semibold text-gray-800 dark:text-gray-100'>\n <InfoNode status={status} percent={percent} successPercent={successPercent} format={format} />\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n};\n\nconst Progress: React.FC<ProgressProps> = props => {\n const toNumber = (value?: number | string) => {\n if (typeof value === 'string') {\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return value;\n };\n\n const {\n percent: rawPercent = 0,\n success,\n status: providedStatus,\n type = 'line',\n showInfo = true,\n format,\n strokeWidth,\n trailColor,\n strokeColor,\n width,\n size,\n steps,\n gapDegree,\n gapPosition,\n className,\n style,\n ...restProps\n } = props;\n\n const percent = clampPercent(toNumber(rawPercent));\n const successPercent = clampPercent(toNumber(success?.percent));\n const status: ProgressStatus = providedStatus ?? (percent >= 100 ? 'success' : 'normal');\n const resolvedClassName = twMerge('min-w-[200px]', className);\n\n if (type === 'circle' || type === 'dashboard') {\n return (\n <CircleProgress\n {...restProps}\n type={type}\n percent={percent}\n successPercent={successPercent}\n success={success}\n status={status}\n showInfo={showInfo}\n className={resolvedClassName}\n format={format}\n strokeWidth={strokeWidth}\n trailColor={trailColor}\n strokeColor={strokeColor}\n width={width}\n gapDegree={gapDegree}\n gapPosition={gapPosition}\n style={style}\n />\n );\n }\n\n return (\n <LineProgress\n percent={percent}\n successPercent={successPercent}\n success={success}\n status={status}\n showInfo={showInfo}\n className={resolvedClassName}\n format={format}\n strokeWidth={strokeWidth}\n trailColor={trailColor}\n strokeColor={strokeColor}\n size={size}\n steps={steps}\n style={style}\n {...restProps}\n />\n );\n};\n\nexport type { ProgressProps, ProgressStatus, ProgressType } from './types.progress';\nexport default Progress;\n"]}