cynx-ui 1.3.6 → 1.3.7

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.
@@ -1,133 +1,133 @@
1
- import { useEffect, useRef } from 'react';
2
-
3
- const SIZES = {
4
- xs: { height: 4, fontSize: '.68rem' },
5
- sm: { height: 5, fontSize: '.75rem' },
6
- md: { height: 6, fontSize: '.82rem' },
7
- lg: { height: 8, fontSize: '.9rem' },
8
- xl: { height: 10, fontSize: '1rem' },
9
- };
10
-
11
- export default function LineProgress({
12
- value = 0,
13
- segments,
14
- size = 'md',
15
- customSize,
16
- color = 'var(--blue)',
17
- trackColor = 'var(--bd2, #e0e0e4)',
18
- label = '',
19
- showPercent = true,
20
- animated = true,
21
- rounded = true,
22
- indeterminate = false,
23
- speed = 1,
24
- height,
25
- gap = 5,
26
- labelGap = 2,
27
- className = '',
28
- style = {},
29
- }) {
30
- const base = SIZES[size] || SIZES.md;
31
- const barHeight = height ?? (customSize || base.height);
32
- const fontSize = customSize ? `${Math.max(11, customSize * 1.6)}px` : base.fontSize;
33
- const pct = Math.min(100, Math.max(0, value));
34
- const radius = rounded ? barHeight / 2 : 0;
35
-
36
- const barRef = useRef(null);
37
-
38
- // Indeterminate animation
39
- useEffect(() => {
40
- if (!indeterminate || !barRef.current) return;
41
- let pos = -40, direction = 1, raf;
42
- let lastTime = performance.now();
43
-
44
- function tick(now) {
45
- const dt = (now - lastTime) / 16.67;
46
- lastTime = now;
47
- pos += direction * 1.2 * speed * dt;
48
- if (pos > 100) { pos = 100; direction = -1; }
49
- if (pos < -40) { pos = -40; direction = 1; }
50
- if (barRef.current) {
51
- barRef.current.style.left = pos + '%';
52
- barRef.current.style.width = '40%';
53
- }
54
- raf = requestAnimationFrame(tick);
55
- }
56
- raf = requestAnimationFrame(tick);
57
- return () => cancelAnimationFrame(raf);
58
- }, [indeterminate, speed]);
59
-
60
- const transitionStyle = animated ? 'flex .5s cubic-bezier(0.4,0,0.2,1)' : 'none';
61
- const hasSegments = Array.isArray(segments) && segments.length > 0;
62
- const rawSum = hasSegments ? segments.reduce((sum, s) => sum + (Number(s.value) || 0), 0) : 0;
63
-
64
- return (
65
- <div className={className} style={{ display: 'inline-flex', flexDirection: 'column', gap: labelGap, width: '100%', ...style }}>
66
- {(label || showPercent) && (
67
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
68
- {label && <span style={{ fontSize, fontWeight: 600, color: 'var(--primary-text, #1a1a2e)' }}>{label}</span>}
69
- {showPercent && !indeterminate && !hasSegments && (
70
- <span style={{ fontSize, fontWeight: 600, color: 'var(--muted, #9ca3af)', fontVariantNumeric: 'tabular-nums', marginLeft: label ? 0 : 'auto' }}>
71
- {Math.round(pct)}%
72
- </span>
73
- )}
74
- </div>
75
- )}
76
- <div style={{
77
- height: barHeight, borderRadius: radius,
78
- background: 'transparent', position: 'relative',
79
- display: 'flex', gap: gap, overflow: 'hidden',
80
- }}>
81
- {indeterminate ? (
82
- <>
83
- <div style={{ flex: 1, borderRadius: radius, background: trackColor }} />
84
- <div
85
- ref={barRef}
86
- style={{
87
- position: 'absolute', top: 0, height: '100%',
88
- width: '40%', borderRadius: radius,
89
- background: color, opacity: 0.85,
90
- }}
91
- />
92
- </>
93
- ) : hasSegments && rawSum > 0 ? (
94
- <>
95
- {segments.map((seg, idx) => {
96
- const segVal = Number(seg.value) || 0;
97
- if (segVal <= 0) return null;
98
- const ratioPct = (segVal / rawSum) * 100;
99
- return (
100
- <div
101
- key={idx}
102
- title={seg.label ? `${seg.label}: ${segVal}` : undefined}
103
- style={{
104
- flex: ratioPct,
105
- height: '100%',
106
- borderRadius: radius,
107
- background: seg.color || color,
108
- transition: transitionStyle,
109
- }}
110
- />
111
- );
112
- })}
113
- </>
114
- ) : (
115
- <>
116
- <div ref={barRef} style={{
117
- flex: pct > 0 ? pct : 0, minWidth: pct > 0 ? barHeight : 0,
118
- borderRadius: radius, background: color,
119
- transition: transitionStyle,
120
- }} />
121
- {pct < 100 && (
122
- <div style={{
123
- flex: 100 - pct,
124
- borderRadius: radius, background: trackColor,
125
- transition: transitionStyle,
126
- }} />
127
- )}
128
- </>
129
- )}
130
- </div>
131
- </div>
132
- );
133
- }
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ const SIZES = {
4
+ xs: { height: 4, fontSize: '.68rem' },
5
+ sm: { height: 5, fontSize: '.75rem' },
6
+ md: { height: 6, fontSize: '.82rem' },
7
+ lg: { height: 8, fontSize: '.9rem' },
8
+ xl: { height: 10, fontSize: '1rem' },
9
+ };
10
+
11
+ export default function LineProgress({
12
+ value = 0,
13
+ segments,
14
+ size = 'md',
15
+ customSize,
16
+ color = 'var(--blue)',
17
+ trackColor = 'var(--bd2, #e0e0e4)',
18
+ label = '',
19
+ showPercent = true,
20
+ animated = true,
21
+ rounded = true,
22
+ indeterminate = false,
23
+ speed = 1,
24
+ height,
25
+ gap = 5,
26
+ labelGap = 2,
27
+ className = '',
28
+ style = {},
29
+ }) {
30
+ const base = SIZES[size] || SIZES.md;
31
+ const barHeight = height ?? (customSize || base.height);
32
+ const fontSize = customSize ? `${Math.max(11, customSize * 1.6)}px` : base.fontSize;
33
+ const pct = Math.min(100, Math.max(0, value));
34
+ const radius = rounded ? barHeight / 2 : 0;
35
+
36
+ const barRef = useRef(null);
37
+
38
+ // Indeterminate animation
39
+ useEffect(() => {
40
+ if (!indeterminate || !barRef.current) return;
41
+ let pos = -40, direction = 1, raf;
42
+ let lastTime = performance.now();
43
+
44
+ function tick(now) {
45
+ const dt = (now - lastTime) / 16.67;
46
+ lastTime = now;
47
+ pos += direction * 1.2 * speed * dt;
48
+ if (pos > 100) { pos = 100; direction = -1; }
49
+ if (pos < -40) { pos = -40; direction = 1; }
50
+ if (barRef.current) {
51
+ barRef.current.style.left = pos + '%';
52
+ barRef.current.style.width = '40%';
53
+ }
54
+ raf = requestAnimationFrame(tick);
55
+ }
56
+ raf = requestAnimationFrame(tick);
57
+ return () => cancelAnimationFrame(raf);
58
+ }, [indeterminate, speed]);
59
+
60
+ const transitionStyle = animated ? 'flex .5s cubic-bezier(0.4,0,0.2,1)' : 'none';
61
+ const hasSegments = Array.isArray(segments) && segments.length > 0;
62
+ const rawSum = hasSegments ? segments.reduce((sum, s) => sum + (Number(s.value) || 0), 0) : 0;
63
+
64
+ return (
65
+ <div className={className} style={{ display: 'inline-flex', flexDirection: 'column', gap: labelGap, width: '100%', ...style }}>
66
+ {(label || showPercent) && (
67
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
68
+ {label && <span style={{ fontSize, fontWeight: 600, color: 'var(--primary-text, #1a1a2e)' }}>{label}</span>}
69
+ {showPercent && !indeterminate && !hasSegments && (
70
+ <span style={{ fontSize, fontWeight: 600, color: 'var(--muted, #9ca3af)', fontVariantNumeric: 'tabular-nums', marginLeft: label ? 0 : 'auto' }}>
71
+ {Math.round(pct)}%
72
+ </span>
73
+ )}
74
+ </div>
75
+ )}
76
+ <div style={{
77
+ height: barHeight, borderRadius: radius,
78
+ background: 'transparent', position: 'relative',
79
+ display: 'flex', gap: gap, overflow: 'hidden',
80
+ }}>
81
+ {indeterminate ? (
82
+ <>
83
+ <div style={{ flex: 1, borderRadius: radius, background: trackColor }} />
84
+ <div
85
+ ref={barRef}
86
+ style={{
87
+ position: 'absolute', top: 0, height: '100%',
88
+ width: '40%', borderRadius: radius,
89
+ background: color, opacity: 0.85,
90
+ }}
91
+ />
92
+ </>
93
+ ) : hasSegments && rawSum > 0 ? (
94
+ <>
95
+ {segments.map((seg, idx) => {
96
+ const segVal = Number(seg.value) || 0;
97
+ if (segVal <= 0) return null;
98
+ const ratioPct = (segVal / rawSum) * 100;
99
+ return (
100
+ <div
101
+ key={idx}
102
+ title={seg.label ? `${seg.label}: ${segVal}` : undefined}
103
+ style={{
104
+ flex: ratioPct,
105
+ height: '100%',
106
+ borderRadius: radius,
107
+ background: seg.color || color,
108
+ transition: transitionStyle,
109
+ }}
110
+ />
111
+ );
112
+ })}
113
+ </>
114
+ ) : (
115
+ <>
116
+ <div ref={barRef} style={{
117
+ flex: pct > 0 ? pct : 0, minWidth: pct > 0 ? barHeight : 0,
118
+ borderRadius: radius, background: color,
119
+ transition: transitionStyle,
120
+ }} />
121
+ {pct < 100 && (
122
+ <div style={{
123
+ flex: 100 - pct,
124
+ borderRadius: radius, background: trackColor,
125
+ transition: transitionStyle,
126
+ }} />
127
+ )}
128
+ </>
129
+ )}
130
+ </div>
131
+ </div>
132
+ );
133
+ }
@@ -1,132 +1,132 @@
1
- import { useEffect, useRef } from 'react';
2
-
3
- const SIZES = {
4
- xs: { height: 4, fontSize: '.68rem' },
5
- sm: { height: 5, fontSize: '.75rem' },
6
- md: { height: 6, fontSize: '.82rem' },
7
- lg: { height: 8, fontSize: '.9rem' },
8
- xl: { height: 10, fontSize: '1rem' },
9
- };
10
-
11
- export default function LinearProgress({
12
- value = 0,
13
- segments,
14
- size = 'md',
15
- customSize,
16
- color = 'var(--blue, #3b82f6)',
17
- trackColor = 'var(--bd2, #e0e0e4)',
18
- label = '',
19
- showPercent = true,
20
- animated = true,
21
- rounded = true,
22
- indeterminate = false,
23
- speed = 1,
24
- height,
25
- gap = 5,
26
- labelGap = 2,
27
- className = '',
28
- style = {},
29
- }) {
30
- const base = SIZES[size] || SIZES.md;
31
- const barHeight = height ?? (customSize || base.height);
32
- const fontSize = customSize ? `${Math.max(11, customSize * 1.6)}px` : base.fontSize;
33
- const pct = Math.min(100, Math.max(0, value));
34
- const radius = rounded ? barHeight / 2 : 0;
35
-
36
- const barRef = useRef(null);
37
-
38
- useEffect(() => {
39
- if (!indeterminate || !barRef.current) return;
40
- let pos = -40, direction = 1, raf;
41
- let lastTime = performance.now();
42
-
43
- function tick(now) {
44
- const dt = (now - lastTime) / 16.67;
45
- lastTime = now;
46
- pos += direction * 1.2 * speed * dt;
47
- if (pos > 100) { pos = 100; direction = -1; }
48
- if (pos < -40) { pos = -40; direction = 1; }
49
- if (barRef.current) {
50
- barRef.current.style.left = pos + '%';
51
- barRef.current.style.width = '40%';
52
- }
53
- raf = requestAnimationFrame(tick);
54
- }
55
- raf = requestAnimationFrame(tick);
56
- return () => cancelAnimationFrame(raf);
57
- }, [indeterminate, speed]);
58
-
59
- const transitionStyle = animated ? 'flex .5s cubic-bezier(0.4,0,0.2,1)' : 'none';
60
- const hasSegments = Array.isArray(segments) && segments.length > 0;
61
- const rawSum = hasSegments ? segments.reduce((sum, s) => sum + (Number(s.value) || 0), 0) : 0;
62
-
63
- return (
64
- <div className={className} style={{ display: 'inline-flex', flexDirection: 'column', gap: labelGap, width: '100%', ...style }}>
65
- {(label || showPercent) && (
66
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
67
- {label && <span style={{ fontSize, fontWeight: 600, color: 'var(--primary-text, #1a1a2e)' }}>{label}</span>}
68
- {showPercent && !indeterminate && !hasSegments && (
69
- <span style={{ fontSize, fontWeight: 600, color: 'var(--muted, #9ca3af)', fontVariantNumeric: 'tabular-nums', marginLeft: label ? 0 : 'auto' }}>
70
- {Math.round(pct)}%
71
- </span>
72
- )}
73
- </div>
74
- )}
75
- <div style={{
76
- height: barHeight, borderRadius: radius,
77
- background: 'transparent', position: 'relative',
78
- display: 'flex', gap: gap, overflow: 'hidden',
79
- }}>
80
- {indeterminate ? (
81
- <>
82
- <div style={{ flex: 1, borderRadius: radius, background: trackColor }} />
83
- <div
84
- ref={barRef}
85
- style={{
86
- position: 'absolute', top: 0, height: '100%',
87
- width: '40%', borderRadius: radius,
88
- background: color, opacity: 0.85,
89
- }}
90
- />
91
- </>
92
- ) : hasSegments && rawSum > 0 ? (
93
- <>
94
- {segments.map((seg, idx) => {
95
- const segVal = Number(seg.value) || 0;
96
- if (segVal <= 0) return null;
97
- const ratioPct = (segVal / rawSum) * 100;
98
- return (
99
- <div
100
- key={idx}
101
- title={seg.label ? `${seg.label}: ${segVal}` : undefined}
102
- style={{
103
- flex: ratioPct,
104
- height: '100%',
105
- borderRadius: radius,
106
- background: seg.color || color,
107
- transition: transitionStyle,
108
- }}
109
- />
110
- );
111
- })}
112
- </>
113
- ) : (
114
- <>
115
- <div ref={barRef} style={{
116
- flex: pct > 0 ? pct : 0, minWidth: pct > 0 ? barHeight : 0,
117
- borderRadius: radius, background: color,
118
- transition: transitionStyle,
119
- }} />
120
- {pct < 100 && (
121
- <div style={{
122
- flex: 100 - pct,
123
- borderRadius: radius, background: trackColor,
124
- transition: transitionStyle,
125
- }} />
126
- )}
127
- </>
128
- )}
129
- </div>
130
- </div>
131
- );
132
- }
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ const SIZES = {
4
+ xs: { height: 4, fontSize: '.68rem' },
5
+ sm: { height: 5, fontSize: '.75rem' },
6
+ md: { height: 6, fontSize: '.82rem' },
7
+ lg: { height: 8, fontSize: '.9rem' },
8
+ xl: { height: 10, fontSize: '1rem' },
9
+ };
10
+
11
+ export default function LinearProgress({
12
+ value = 0,
13
+ segments,
14
+ size = 'md',
15
+ customSize,
16
+ color = 'var(--blue, #3b82f6)',
17
+ trackColor = 'var(--bd2, #e0e0e4)',
18
+ label = '',
19
+ showPercent = true,
20
+ animated = true,
21
+ rounded = true,
22
+ indeterminate = false,
23
+ speed = 1,
24
+ height,
25
+ gap = 5,
26
+ labelGap = 2,
27
+ className = '',
28
+ style = {},
29
+ }) {
30
+ const base = SIZES[size] || SIZES.md;
31
+ const barHeight = height ?? (customSize || base.height);
32
+ const fontSize = customSize ? `${Math.max(11, customSize * 1.6)}px` : base.fontSize;
33
+ const pct = Math.min(100, Math.max(0, value));
34
+ const radius = rounded ? barHeight / 2 : 0;
35
+
36
+ const barRef = useRef(null);
37
+
38
+ useEffect(() => {
39
+ if (!indeterminate || !barRef.current) return;
40
+ let pos = -40, direction = 1, raf;
41
+ let lastTime = performance.now();
42
+
43
+ function tick(now) {
44
+ const dt = (now - lastTime) / 16.67;
45
+ lastTime = now;
46
+ pos += direction * 1.2 * speed * dt;
47
+ if (pos > 100) { pos = 100; direction = -1; }
48
+ if (pos < -40) { pos = -40; direction = 1; }
49
+ if (barRef.current) {
50
+ barRef.current.style.left = pos + '%';
51
+ barRef.current.style.width = '40%';
52
+ }
53
+ raf = requestAnimationFrame(tick);
54
+ }
55
+ raf = requestAnimationFrame(tick);
56
+ return () => cancelAnimationFrame(raf);
57
+ }, [indeterminate, speed]);
58
+
59
+ const transitionStyle = animated ? 'flex .5s cubic-bezier(0.4,0,0.2,1)' : 'none';
60
+ const hasSegments = Array.isArray(segments) && segments.length > 0;
61
+ const rawSum = hasSegments ? segments.reduce((sum, s) => sum + (Number(s.value) || 0), 0) : 0;
62
+
63
+ return (
64
+ <div className={className} style={{ display: 'inline-flex', flexDirection: 'column', gap: labelGap, width: '100%', ...style }}>
65
+ {(label || showPercent) && (
66
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
67
+ {label && <span style={{ fontSize, fontWeight: 600, color: 'var(--primary-text, #1a1a2e)' }}>{label}</span>}
68
+ {showPercent && !indeterminate && !hasSegments && (
69
+ <span style={{ fontSize, fontWeight: 600, color: 'var(--muted, #9ca3af)', fontVariantNumeric: 'tabular-nums', marginLeft: label ? 0 : 'auto' }}>
70
+ {Math.round(pct)}%
71
+ </span>
72
+ )}
73
+ </div>
74
+ )}
75
+ <div style={{
76
+ height: barHeight, borderRadius: radius,
77
+ background: 'transparent', position: 'relative',
78
+ display: 'flex', gap: gap, overflow: 'hidden',
79
+ }}>
80
+ {indeterminate ? (
81
+ <>
82
+ <div style={{ flex: 1, borderRadius: radius, background: trackColor }} />
83
+ <div
84
+ ref={barRef}
85
+ style={{
86
+ position: 'absolute', top: 0, height: '100%',
87
+ width: '40%', borderRadius: radius,
88
+ background: color, opacity: 0.85,
89
+ }}
90
+ />
91
+ </>
92
+ ) : hasSegments && rawSum > 0 ? (
93
+ <>
94
+ {segments.map((seg, idx) => {
95
+ const segVal = Number(seg.value) || 0;
96
+ if (segVal <= 0) return null;
97
+ const ratioPct = (segVal / rawSum) * 100;
98
+ return (
99
+ <div
100
+ key={idx}
101
+ title={seg.label ? `${seg.label}: ${segVal}` : undefined}
102
+ style={{
103
+ flex: ratioPct,
104
+ height: '100%',
105
+ borderRadius: radius,
106
+ background: seg.color || color,
107
+ transition: transitionStyle,
108
+ }}
109
+ />
110
+ );
111
+ })}
112
+ </>
113
+ ) : (
114
+ <>
115
+ <div ref={barRef} style={{
116
+ flex: pct > 0 ? pct : 0, minWidth: pct > 0 ? barHeight : 0,
117
+ borderRadius: radius, background: color,
118
+ transition: transitionStyle,
119
+ }} />
120
+ {pct < 100 && (
121
+ <div style={{
122
+ flex: 100 - pct,
123
+ borderRadius: radius, background: trackColor,
124
+ transition: transitionStyle,
125
+ }} />
126
+ )}
127
+ </>
128
+ )}
129
+ </div>
130
+ </div>
131
+ );
132
+ }