cynx-ui 1.3.19 → 1.3.21
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/components/ActionsMenu.jsx +39 -30
- package/components/ActivityCard.jsx +16 -16
- package/components/AuthOverlay.jsx +3 -3
- package/components/BrandingCard.jsx +19 -19
- package/components/Button.jsx +4 -4
- package/components/Checkbox.jsx +2 -2
- package/components/ChipSelect.jsx +4 -4
- package/components/CircularProgress.jsx +3 -3
- package/components/Confirm.jsx +6 -6
- package/components/DatePicker.jsx +45 -45
- package/components/Dropzone.jsx +17 -17
- package/components/FilePicker.jsx +17 -17
- package/components/HoverCard.jsx +4 -4
- package/components/ImageUpload.jsx +19 -19
- package/components/Input.jsx +3 -3
- package/components/LineProgress.jsx +1 -1
- package/components/Modal.jsx +15 -15
- package/components/Pagination.jsx +5 -5
- package/components/Select.jsx +24 -24
- package/components/Spinner.jsx +4 -4
- package/components/StatBarCard.jsx +1 -1
- package/components/StatsBar.jsx +4 -4
- package/components/StatsCard.jsx +2 -2
- package/components/TabBar.jsx +6 -6
- package/components/TimePicker.jsx +69 -70
- package/components/Toast.jsx +2 -2
- package/components/UptimeBar.jsx +17 -17
- package/index.js +95 -101
- package/package.json +1 -1
- package/components/Dropdown.jsx +0 -124
- package/components/MultiSelect.jsx +0 -173
- package/components/SearchableDropdown.jsx +0 -132
|
@@ -58,8 +58,8 @@ const STYLES = `
|
|
|
58
58
|
|
|
59
59
|
.cynx-timepicker-stepper-btn:hover {
|
|
60
60
|
background: var(--surface, #ffffff);
|
|
61
|
-
border-color: var(--accent);
|
|
62
|
-
color: var(--accent);
|
|
61
|
+
border-color: var(--accent, #f99e2c);
|
|
62
|
+
color: var(--accent, #f99e2c);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
.cynx-timepicker-stepper-btn:active {
|
|
@@ -170,6 +170,7 @@ export function TimePicker({
|
|
|
170
170
|
hideIcon = false, // Legacy prop alias for showIcon = false
|
|
171
171
|
showFormatToggle = false, // Minimal default: false
|
|
172
172
|
showPresets = false, // Minimal default: false
|
|
173
|
+
presets = null, // Custom presets array e.g. ['09:00', '18:00']
|
|
173
174
|
showTimezoneSelect = false, // Minimal default: false
|
|
174
175
|
showPlaceholder = false, // Minimal default: false
|
|
175
176
|
timezone = 'Asia/Tashkent',
|
|
@@ -516,8 +517,6 @@ export function TimePicker({
|
|
|
516
517
|
const hours12List = Array.from({ length: 12 }, (_, i) => i + 1);
|
|
517
518
|
const fullMinutesList = Array.from({ length: 60 }, (_, i) => i);
|
|
518
519
|
|
|
519
|
-
const presets24 = ['00:00', '07:00', '08:00', '09:00', '12:00', '18:00', '23:00'];
|
|
520
|
-
const presets12 = ['07:00 AM', '09:00 AM', '12:00 PM', '03:00 PM', '06:00 PM', '11:00 PM'];
|
|
521
520
|
|
|
522
521
|
const inputHeight = style?.height
|
|
523
522
|
? (typeof style.height === 'number' ? `${style.height}px` : style.height)
|
|
@@ -531,7 +530,7 @@ export function TimePicker({
|
|
|
531
530
|
>
|
|
532
531
|
{label && (
|
|
533
532
|
<label
|
|
534
|
-
style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, var(--muted))', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block', marginBottom: 4 }}
|
|
533
|
+
style={{ fontSize: 11, fontWeight: 600, color: 'var(--t2, var(--muted, #797b8d))', textTransform: 'uppercase', letterSpacing: '.08em', display: 'block', marginBottom: 4 }}
|
|
535
534
|
>
|
|
536
535
|
{label}
|
|
537
536
|
</label>
|
|
@@ -555,7 +554,7 @@ export function TimePicker({
|
|
|
555
554
|
display: 'flex',
|
|
556
555
|
alignItems: 'center',
|
|
557
556
|
justifyContent: 'center',
|
|
558
|
-
color: open ? 'var(--accent)' : 'var(--t2, var(--muted, #9b9daa))',
|
|
557
|
+
color: open ? 'var(--accent, #f99e2c)' : 'var(--t2, var(--muted, #9b9daa))',
|
|
559
558
|
zIndex: 1,
|
|
560
559
|
transition: 'color .15s ease',
|
|
561
560
|
}}
|
|
@@ -584,7 +583,7 @@ export function TimePicker({
|
|
|
584
583
|
height: inputHeight,
|
|
585
584
|
paddingLeft: displayClockIcon ? (size === 'xs' ? 22 : 28) : (size === 'xs' ? 6 : 10),
|
|
586
585
|
paddingRight: size === 'xs' ? 18 : 26,
|
|
587
|
-
border: `1px solid ${open ? 'var(--accent)' : 'var(--bd, var(--border, #d7d8e0))'}`,
|
|
586
|
+
border: `1px solid ${open ? 'var(--accent, #f99e2c)' : 'var(--bd, var(--border, #d7d8e0))'}`,
|
|
588
587
|
borderRadius: 'var(--rads, 8px)',
|
|
589
588
|
fontSize: fontSize,
|
|
590
589
|
background: disabled ? 'var(--grey-1, #f5f5f8)' : 'var(--input-bg, var(--surface, #ffffff))',
|
|
@@ -630,7 +629,7 @@ export function TimePicker({
|
|
|
630
629
|
<ChevronDown
|
|
631
630
|
size={13}
|
|
632
631
|
style={{
|
|
633
|
-
color: open ? 'var(--accent)' : 'var(--t2, var(--muted, #9b9daa))',
|
|
632
|
+
color: open ? 'var(--accent, #f99e2c)' : 'var(--t2, var(--muted, #9b9daa))',
|
|
634
633
|
transform: open ? 'rotate(180deg)' : 'none',
|
|
635
634
|
transition: 'transform .2s ease, color .15s ease',
|
|
636
635
|
pointerEvents: 'none',
|
|
@@ -665,24 +664,24 @@ export function TimePicker({
|
|
|
665
664
|
>
|
|
666
665
|
{/* Header Bar: Variant Switcher */}
|
|
667
666
|
{showVariantToggle && (
|
|
668
|
-
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border))' }}>
|
|
669
|
-
<span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
|
|
667
|
+
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
|
|
668
|
+
<span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1, #0f172a))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
|
|
670
669
|
Режим
|
|
671
670
|
</span>
|
|
672
671
|
|
|
673
|
-
<div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border))' }}>
|
|
672
|
+
<div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover, #f5f5f8))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
|
|
674
673
|
<button
|
|
675
674
|
type="button"
|
|
676
675
|
onClick={() => setActiveVariant('stepper')}
|
|
677
676
|
className="cynx-timepicker-cell"
|
|
678
677
|
style={{
|
|
679
|
-
padding: '2px
|
|
678
|
+
padding: '2px 6px',
|
|
680
679
|
borderRadius: 4,
|
|
681
680
|
border: 'none',
|
|
682
681
|
fontSize: '.68rem',
|
|
683
682
|
fontWeight: activeVariant === 'stepper' ? 700 : 500,
|
|
684
|
-
background: activeVariant === 'stepper' ? 'var(--surface, var(--bg))' : 'transparent',
|
|
685
|
-
color: activeVariant === 'stepper' ? 'var(--accent,
|
|
683
|
+
background: activeVariant === 'stepper' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
|
|
684
|
+
color: activeVariant === 'stepper' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
|
|
686
685
|
boxShadow: activeVariant === 'stepper' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
|
|
687
686
|
cursor: 'pointer',
|
|
688
687
|
display: 'flex',
|
|
@@ -690,7 +689,7 @@ export function TimePicker({
|
|
|
690
689
|
gap: 3,
|
|
691
690
|
}}
|
|
692
691
|
>
|
|
693
|
-
<Sliders size={11} /> Спиннер
|
|
692
|
+
<Sliders size={11} /> Спиннер
|
|
694
693
|
</button>
|
|
695
694
|
|
|
696
695
|
<button
|
|
@@ -698,13 +697,13 @@ export function TimePicker({
|
|
|
698
697
|
onClick={() => setActiveVariant('list')}
|
|
699
698
|
className="cynx-timepicker-cell"
|
|
700
699
|
style={{
|
|
701
|
-
padding: '2px
|
|
700
|
+
padding: '2px 6px',
|
|
702
701
|
borderRadius: 4,
|
|
703
702
|
border: 'none',
|
|
704
703
|
fontSize: '.68rem',
|
|
705
704
|
fontWeight: activeVariant === 'list' ? 700 : 500,
|
|
706
|
-
background: activeVariant === 'list' ? 'var(--surface, var(--bg))' : 'transparent',
|
|
707
|
-
color: activeVariant === 'list' ? 'var(--accent,
|
|
705
|
+
background: activeVariant === 'list' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
|
|
706
|
+
color: activeVariant === 'list' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
|
|
708
707
|
boxShadow: activeVariant === 'list' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
|
|
709
708
|
cursor: 'pointer',
|
|
710
709
|
display: 'flex',
|
|
@@ -712,7 +711,7 @@ export function TimePicker({
|
|
|
712
711
|
gap: 3,
|
|
713
712
|
}}
|
|
714
713
|
>
|
|
715
|
-
<List size={11} /> Список
|
|
714
|
+
<List size={11} /> Список
|
|
716
715
|
</button>
|
|
717
716
|
</div>
|
|
718
717
|
</div>
|
|
@@ -720,12 +719,12 @@ export function TimePicker({
|
|
|
720
719
|
|
|
721
720
|
{/* Optional Format Switcher (24h / 12h) */}
|
|
722
721
|
{showFormatToggle && (
|
|
723
|
-
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border))' }}>
|
|
724
|
-
<span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
|
|
722
|
+
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
|
|
723
|
+
<span style={{ fontSize: '.68rem', fontWeight: 700, color: 'var(--fg, var(--t1, #0f172a))', textTransform: 'uppercase', letterSpacing: '.05em' }}>
|
|
725
724
|
Формат
|
|
726
725
|
</span>
|
|
727
726
|
|
|
728
|
-
<div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border))' }}>
|
|
727
|
+
<div style={{ display: 'inline-flex', background: 'var(--grey-1, var(--surface-hover, #f5f5f8))', padding: 2, borderRadius: 6, border: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
|
|
729
728
|
<button
|
|
730
729
|
type="button"
|
|
731
730
|
onClick={() => switchMode('24h')}
|
|
@@ -736,8 +735,8 @@ export function TimePicker({
|
|
|
736
735
|
border: 'none',
|
|
737
736
|
fontSize: '.68rem',
|
|
738
737
|
fontWeight: mode === '24h' ? 700 : 500,
|
|
739
|
-
background: mode === '24h' ? 'var(--surface, var(--bg))' : 'transparent',
|
|
740
|
-
color: mode === '24h' ? 'var(--accent,
|
|
738
|
+
background: mode === '24h' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
|
|
739
|
+
color: mode === '24h' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
|
|
741
740
|
boxShadow: mode === '24h' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
|
|
742
741
|
cursor: 'pointer',
|
|
743
742
|
}}
|
|
@@ -754,13 +753,13 @@ export function TimePicker({
|
|
|
754
753
|
border: 'none',
|
|
755
754
|
fontSize: '.68rem',
|
|
756
755
|
fontWeight: mode === '12h' ? 700 : 500,
|
|
757
|
-
background: mode === '12h' ? 'var(--surface, var(--bg))' : 'transparent',
|
|
758
|
-
color: mode === '12h' ? 'var(--accent,
|
|
756
|
+
background: mode === '12h' ? 'var(--surface, var(--bg, #f8fafc))' : 'transparent',
|
|
757
|
+
color: mode === '12h' ? 'var(--accent, #f99e2c)' : 'var(--muted, var(--t2, #797b8d))',
|
|
759
758
|
boxShadow: mode === '12h' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
|
|
760
759
|
cursor: 'pointer',
|
|
761
760
|
}}
|
|
762
761
|
>
|
|
763
|
-
12h
|
|
762
|
+
12h
|
|
764
763
|
</button>
|
|
765
764
|
</div>
|
|
766
765
|
</div>
|
|
@@ -780,23 +779,23 @@ export function TimePicker({
|
|
|
780
779
|
width: '100%',
|
|
781
780
|
padding: '4px 8px',
|
|
782
781
|
borderRadius: 6,
|
|
783
|
-
border: '1px solid var(--border-light, var(--border))',
|
|
784
|
-
background: 'var(--grey-1, var(--surface-hover))',
|
|
782
|
+
border: '1px solid var(--border-light, var(--border, #e2e8f0))',
|
|
783
|
+
background: 'var(--grey-1, var(--surface-hover, #f5f5f8))',
|
|
785
784
|
fontSize: '.68rem',
|
|
786
|
-
color: 'var(--fg, var(--t1))',
|
|
785
|
+
color: 'var(--fg, var(--t1, #0f172a))',
|
|
787
786
|
cursor: 'pointer',
|
|
788
787
|
fontWeight: 500,
|
|
789
788
|
}}
|
|
790
789
|
>
|
|
791
790
|
<span style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
|
792
|
-
<Globe size={12} color="var(--accent,
|
|
791
|
+
<Globe size={12} color="var(--accent, #f99e2c)" />
|
|
793
792
|
{COMMON_TIMEZONES.find(t => t.value === tz)?.label || tz}
|
|
794
793
|
</span>
|
|
795
|
-
<ChevronDown size={12} color="var(--muted, var(--t2))" />
|
|
794
|
+
<ChevronDown size={12} color="var(--muted, var(--t2, #797b8d))" />
|
|
796
795
|
</button>
|
|
797
796
|
|
|
798
797
|
{showTzPicker && (
|
|
799
|
-
<div style={{ marginTop: 4, background: 'var(--surface, var(--bg))', border: '1px solid var(--border-light, var(--border))', borderRadius: 6, boxShadow: 'var(--shadow)', padding: 4, display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
798
|
+
<div style={{ marginTop: 4, background: 'var(--surface, var(--bg, #f8fafc))', border: '1px solid var(--border-light, var(--border, #e2e8f0))', borderRadius: 6, boxShadow: 'var(--shadow, 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06))', padding: 4, display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
800
799
|
{COMMON_TIMEZONES.map(t => (
|
|
801
800
|
<button
|
|
802
801
|
key={t.value}
|
|
@@ -809,8 +808,8 @@ export function TimePicker({
|
|
|
809
808
|
border: 'none',
|
|
810
809
|
textAlign: 'left',
|
|
811
810
|
fontSize: '.68rem',
|
|
812
|
-
background: tz === t.value ? 'var(--accent,
|
|
813
|
-
color: tz === t.value ? '#ffffff' : 'var(--fg, var(--t1))',
|
|
811
|
+
background: tz === t.value ? 'var(--accent, #f99e2c)' : 'transparent',
|
|
812
|
+
color: tz === t.value ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
|
|
814
813
|
cursor: 'pointer',
|
|
815
814
|
fontWeight: tz === t.value ? 600 : 400,
|
|
816
815
|
}}
|
|
@@ -823,10 +822,10 @@ export function TimePicker({
|
|
|
823
822
|
</div>
|
|
824
823
|
)}
|
|
825
824
|
|
|
826
|
-
{/* Optional Quick Presets Bar */}
|
|
827
|
-
{
|
|
828
|
-
<div style={{ display: 'flex', gap: 4, flexWrap: 'wrap', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border))' }}>
|
|
829
|
-
{
|
|
825
|
+
{/* Optional Quick Presets Bar (only if presets array passed) */}
|
|
826
|
+
{Array.isArray(presets) && presets.length > 0 && (
|
|
827
|
+
<div style={{ display: 'flex', gap: 4, flexWrap: 'wrap', marginBottom: 8, paddingBottom: 6, borderBottom: '1px solid var(--border-light, var(--border, #e2e8f0))' }}>
|
|
828
|
+
{presets.map(p => (
|
|
830
829
|
<button
|
|
831
830
|
key={p}
|
|
832
831
|
type="button"
|
|
@@ -839,9 +838,9 @@ export function TimePicker({
|
|
|
839
838
|
padding: '3px 6px',
|
|
840
839
|
borderRadius: 4,
|
|
841
840
|
fontSize: '.68rem',
|
|
842
|
-
border: '1px solid var(--border-light, var(--border))',
|
|
843
|
-
background: inputValue === p ? 'var(--accent,
|
|
844
|
-
color: inputValue === p ? '#ffffff' : 'var(--fg, var(--t1))',
|
|
841
|
+
border: '1px solid var(--border-light, var(--border, #e2e8f0))',
|
|
842
|
+
background: inputValue === p ? 'var(--accent, #f99e2c)' : 'var(--grey-1, var(--surface-hover, #f5f5f8))',
|
|
843
|
+
color: inputValue === p ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
|
|
845
844
|
cursor: 'pointer',
|
|
846
845
|
fontWeight: 500,
|
|
847
846
|
}}
|
|
@@ -863,16 +862,16 @@ export function TimePicker({
|
|
|
863
862
|
flex: 1,
|
|
864
863
|
padding: '4px 0',
|
|
865
864
|
borderRadius: 6,
|
|
866
|
-
border: '1px solid var(--border-light, var(--border))',
|
|
865
|
+
border: '1px solid var(--border-light, var(--border, #e2e8f0))',
|
|
867
866
|
fontSize: '.75rem',
|
|
868
867
|
fontWeight: parsed.ampm === 'AM' ? 700 : 500,
|
|
869
|
-
background: parsed.ampm === 'AM' ? 'var(--accent,
|
|
870
|
-
color: parsed.ampm === 'AM' ? '#ffffff' : 'var(--fg, var(--t1))',
|
|
868
|
+
background: parsed.ampm === 'AM' ? 'var(--accent, #f99e2c)' : 'var(--grey-1, var(--surface-hover, #f5f5f8))',
|
|
869
|
+
color: parsed.ampm === 'AM' ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
|
|
871
870
|
cursor: 'pointer',
|
|
872
871
|
textAlign: 'center',
|
|
873
872
|
}}
|
|
874
873
|
>
|
|
875
|
-
AM
|
|
874
|
+
AM
|
|
876
875
|
</button>
|
|
877
876
|
<button
|
|
878
877
|
type="button"
|
|
@@ -882,16 +881,16 @@ export function TimePicker({
|
|
|
882
881
|
flex: 1,
|
|
883
882
|
padding: '4px 0',
|
|
884
883
|
borderRadius: 6,
|
|
885
|
-
border: '1px solid var(--border-light, var(--border))',
|
|
884
|
+
border: '1px solid var(--border-light, var(--border, #e2e8f0))',
|
|
886
885
|
fontSize: '.75rem',
|
|
887
886
|
fontWeight: parsed.ampm === 'PM' ? 700 : 500,
|
|
888
|
-
background: parsed.ampm === 'PM' ? 'var(--accent,
|
|
889
|
-
color: parsed.ampm === 'PM' ? '#ffffff' : 'var(--fg, var(--t1))',
|
|
887
|
+
background: parsed.ampm === 'PM' ? 'var(--accent, #f99e2c)' : 'var(--grey-1, var(--surface-hover, #f5f5f8))',
|
|
888
|
+
color: parsed.ampm === 'PM' ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
|
|
890
889
|
cursor: 'pointer',
|
|
891
890
|
textAlign: 'center',
|
|
892
891
|
}}
|
|
893
892
|
>
|
|
894
|
-
PM
|
|
893
|
+
PM
|
|
895
894
|
</button>
|
|
896
895
|
</div>
|
|
897
896
|
)}
|
|
@@ -901,13 +900,13 @@ export function TimePicker({
|
|
|
901
900
|
<div style={{ display: 'grid', gridTemplateColumns: showSeconds ? '1fr 1fr 1fr' : '1fr 1fr', gap: 10, padding: '4px 0' }}>
|
|
902
901
|
{/* Hours Stepper */}
|
|
903
902
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
|
|
904
|
-
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))' }}>
|
|
905
|
-
|
|
903
|
+
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))' }}>
|
|
904
|
+
Час
|
|
906
905
|
</div>
|
|
907
906
|
<button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepHour(1)} title="+1 Час">
|
|
908
907
|
<ChevronUp size={14} />
|
|
909
908
|
</button>
|
|
910
|
-
<div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent,
|
|
909
|
+
<div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, #f99e2c)' }}>
|
|
911
910
|
{mode === '12h' ? parsed.h12 : parsed.h24}
|
|
912
911
|
</div>
|
|
913
912
|
<button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepHour(-1)} title="-1 Час">
|
|
@@ -917,11 +916,11 @@ export function TimePicker({
|
|
|
917
916
|
|
|
918
917
|
{/* Minutes Stepper */}
|
|
919
918
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
|
|
920
|
-
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))' }}
|
|
919
|
+
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))' }}>Мин</div>
|
|
921
920
|
<button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepMinute(1)} title="+1 Мин">
|
|
922
921
|
<ChevronUp size={14} />
|
|
923
922
|
</button>
|
|
924
|
-
<div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent,
|
|
923
|
+
<div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, #f99e2c)' }}>
|
|
925
924
|
{parsed.m}
|
|
926
925
|
</div>
|
|
927
926
|
<button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepMinute(-1)} title="-1 Мин">
|
|
@@ -932,11 +931,11 @@ export function TimePicker({
|
|
|
932
931
|
{/* Seconds Stepper */}
|
|
933
932
|
{showSeconds && (
|
|
934
933
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
|
|
935
|
-
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))' }}
|
|
934
|
+
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))' }}>Сек</div>
|
|
936
935
|
<button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepSecond(1)} title="+1 Сек">
|
|
937
936
|
<ChevronUp size={14} />
|
|
938
937
|
</button>
|
|
939
|
-
<div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent,
|
|
938
|
+
<div style={{ fontSize: '1.2rem', fontWeight: 700, fontVariantNumeric: 'tabular-nums', padding: '6px 0', color: 'var(--accent, #f99e2c)' }}>
|
|
940
939
|
{parsed.s}
|
|
941
940
|
</div>
|
|
942
941
|
<button type="button" className="cynx-timepicker-stepper-btn" onClick={() => stepSecond(-1)} title="-1 Сек">
|
|
@@ -950,8 +949,8 @@ export function TimePicker({
|
|
|
950
949
|
<div style={{ display: 'grid', gridTemplateColumns: showSeconds ? '1fr 1fr 1fr' : '1fr 1fr', gap: 6 }}>
|
|
951
950
|
{/* Hours Column */}
|
|
952
951
|
<div>
|
|
953
|
-
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))', marginBottom: 4, textAlign: 'center' }}>
|
|
954
|
-
|
|
952
|
+
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))', marginBottom: 4, textAlign: 'center' }}>
|
|
953
|
+
Час
|
|
955
954
|
</div>
|
|
956
955
|
<div style={{ maxHeight: 150, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2, paddingRight: 2 }}>
|
|
957
956
|
{(mode === '12h' ? hours12List : hours24List).map(hNum => {
|
|
@@ -970,8 +969,8 @@ export function TimePicker({
|
|
|
970
969
|
fontSize: '.75rem',
|
|
971
970
|
cursor: 'pointer',
|
|
972
971
|
fontWeight: isSelected ? 700 : 400,
|
|
973
|
-
background: isSelected ? 'var(--accent,
|
|
974
|
-
color: isSelected ? '#ffffff' : 'var(--fg, var(--t1))',
|
|
972
|
+
background: isSelected ? 'var(--accent, #f99e2c)' : 'transparent',
|
|
973
|
+
color: isSelected ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
|
|
975
974
|
}}
|
|
976
975
|
>
|
|
977
976
|
{pad(hNum)}
|
|
@@ -983,7 +982,7 @@ export function TimePicker({
|
|
|
983
982
|
|
|
984
983
|
{/* Minutes Column: FULL LIST 00 to 59! */}
|
|
985
984
|
<div>
|
|
986
|
-
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))', marginBottom: 4, textAlign: 'center' }}
|
|
985
|
+
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))', marginBottom: 4, textAlign: 'center' }}>Мин</div>
|
|
987
986
|
<div style={{ maxHeight: 150, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2, paddingRight: 2 }}>
|
|
988
987
|
{fullMinutesList.map(mNum => {
|
|
989
988
|
const mStr = pad(mNum);
|
|
@@ -1002,8 +1001,8 @@ export function TimePicker({
|
|
|
1002
1001
|
fontSize: '.75rem',
|
|
1003
1002
|
cursor: 'pointer',
|
|
1004
1003
|
fontWeight: isSelected ? 700 : 400,
|
|
1005
|
-
background: isSelected ? 'var(--accent,
|
|
1006
|
-
color: isSelected ? '#ffffff' : 'var(--fg, var(--t1))',
|
|
1004
|
+
background: isSelected ? 'var(--accent, #f99e2c)' : 'transparent',
|
|
1005
|
+
color: isSelected ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
|
|
1007
1006
|
}}
|
|
1008
1007
|
>
|
|
1009
1008
|
{mStr}
|
|
@@ -1016,7 +1015,7 @@ export function TimePicker({
|
|
|
1016
1015
|
{/* Seconds Column (if showSeconds): FULL LIST 00 to 59! */}
|
|
1017
1016
|
{showSeconds && (
|
|
1018
1017
|
<div>
|
|
1019
|
-
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2))', marginBottom: 4, textAlign: 'center' }}
|
|
1018
|
+
<div style={{ fontSize: '.65rem', fontWeight: 600, color: 'var(--muted, var(--t2, #797b8d))', marginBottom: 4, textAlign: 'center' }}>Сек</div>
|
|
1020
1019
|
<div style={{ maxHeight: 150, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
1021
1020
|
{fullMinutesList.map(sNum => {
|
|
1022
1021
|
const sStr = pad(sNum);
|
|
@@ -1035,8 +1034,8 @@ export function TimePicker({
|
|
|
1035
1034
|
fontSize: '.75rem',
|
|
1036
1035
|
cursor: 'pointer',
|
|
1037
1036
|
fontWeight: isSelected ? 700 : 400,
|
|
1038
|
-
background: isSelected ? 'var(--accent,
|
|
1039
|
-
color: isSelected ? '#ffffff' : 'var(--fg, var(--t1))',
|
|
1037
|
+
background: isSelected ? 'var(--accent, #f99e2c)' : 'transparent',
|
|
1038
|
+
color: isSelected ? '#ffffff' : 'var(--fg, var(--t1, #0f172a))',
|
|
1040
1039
|
}}
|
|
1041
1040
|
>
|
|
1042
1041
|
{sStr}
|
|
@@ -1050,12 +1049,12 @@ export function TimePicker({
|
|
|
1050
1049
|
)}
|
|
1051
1050
|
|
|
1052
1051
|
{/* Footer Actions */}
|
|
1053
|
-
<div style={{ marginTop: 8, paddingTop: 6, borderTop: '1px solid var(--border-light, var(--border))', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
1052
|
+
<div style={{ marginTop: 8, paddingTop: 6, borderTop: '1px solid var(--border-light, var(--border, #e2e8f0))', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
1054
1053
|
<button
|
|
1055
1054
|
type="button"
|
|
1056
1055
|
onClick={clearTime}
|
|
1057
1056
|
className="cynx-timepicker-cell"
|
|
1058
|
-
style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--danger)', fontSize: '.7rem', fontWeight: 500 }}
|
|
1057
|
+
style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--danger, #f64747)', fontSize: '.7rem', fontWeight: 500 }}
|
|
1059
1058
|
>
|
|
1060
1059
|
Сбросить
|
|
1061
1060
|
</button>
|
|
@@ -1063,7 +1062,7 @@ export function TimePicker({
|
|
|
1063
1062
|
type="button"
|
|
1064
1063
|
onClick={closePicker}
|
|
1065
1064
|
className="cynx-timepicker-cell"
|
|
1066
|
-
style={{ padding: '3px 10px', borderRadius: 4, border: 'none', background: 'var(--accent,
|
|
1065
|
+
style={{ padding: '3px 10px', borderRadius: 4, border: 'none', background: 'var(--accent, #f99e2c)', color: '#ffffff', fontSize: '.7rem', cursor: 'pointer', fontWeight: 600, display: 'flex', alignItems: 'center', gap: 4 }}
|
|
1067
1066
|
>
|
|
1068
1067
|
<Check size={12} /> Готово
|
|
1069
1068
|
</button>
|
package/components/Toast.jsx
CHANGED
|
@@ -90,8 +90,8 @@ export function Toast({ toasts, remove, position = 'top-right', style = {} }) {
|
|
|
90
90
|
{toasts.map(t => (
|
|
91
91
|
<div key={t.id} className={`toast ${t.type}`} onClick={() => remove(t.id)}>
|
|
92
92
|
{t.type === 'ok' || t.type === 'success'
|
|
93
|
-
? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--success)" strokeWidth="2.5" strokeLinecap="round"><polyline points="20 6 9 17 4 12"/></svg>
|
|
94
|
-
: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--danger)" strokeWidth="2.5" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
|
|
93
|
+
? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--success, #27ae60)" strokeWidth="2.5" strokeLinecap="round"><polyline points="20 6 9 17 4 12"/></svg>
|
|
94
|
+
: <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--danger, #f64747)" strokeWidth="2.5" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
|
|
95
95
|
}
|
|
96
96
|
{t.msg}
|
|
97
97
|
</div>
|
package/components/UptimeBar.jsx
CHANGED
|
@@ -2,8 +2,8 @@ import { useMemo, useState, useRef } from 'react';
|
|
|
2
2
|
|
|
3
3
|
const card = {
|
|
4
4
|
background: 'var(--surface,#fff)',
|
|
5
|
-
border: '1px solid var(--border)',
|
|
6
|
-
borderRadius: 'var(--rad)',
|
|
5
|
+
border: '1px solid var(--border, #e2e8f0)',
|
|
6
|
+
borderRadius: 'var(--rad, 10px)',
|
|
7
7
|
boxShadow: 'var(--shadow, 0 1px 3px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.04))',
|
|
8
8
|
};
|
|
9
9
|
|
|
@@ -19,9 +19,9 @@ export default function UptimeBar({
|
|
|
19
19
|
successValues = [],
|
|
20
20
|
failedValues = [],
|
|
21
21
|
totalSlots = 90,
|
|
22
|
-
greenColor = 'var(--success)',
|
|
23
|
-
redColor = 'var(--danger)',
|
|
24
|
-
emptyColor = 'var(--grey-1)',
|
|
22
|
+
greenColor = 'var(--success, #27ae60)',
|
|
23
|
+
redColor = 'var(--danger, #f64747)',
|
|
24
|
+
emptyColor = 'var(--grey-1, #f5f5f8)',
|
|
25
25
|
barHeight = 28,
|
|
26
26
|
barRadius = 3,
|
|
27
27
|
leftLabel,
|
|
@@ -86,8 +86,8 @@ export default function UptimeBar({
|
|
|
86
86
|
background: dotColor || greenColor, flexShrink: 0,
|
|
87
87
|
}} />
|
|
88
88
|
)}
|
|
89
|
-
<span style={{ fontSize: '.78rem', fontWeight: 700, color: 'var(--primary-text)', letterSpacing: '-.01em' }}>{title}</span>
|
|
90
|
-
{subtitle && <span style={{ fontSize: '.65rem', color: 'var(--muted)', fontWeight: 500 }}>{subtitle}</span>}
|
|
89
|
+
<span style={{ fontSize: '.78rem', fontWeight: 700, color: 'var(--primary-text, #0f172a)', letterSpacing: '-.01em' }}>{title}</span>
|
|
90
|
+
{subtitle && <span style={{ fontSize: '.65rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{subtitle}</span>}
|
|
91
91
|
</div>
|
|
92
92
|
{/* Legend */}
|
|
93
93
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
|
@@ -145,32 +145,32 @@ export default function UptimeBar({
|
|
|
145
145
|
top: tooltipPos.y,
|
|
146
146
|
transform: 'translate(-50%, -100%)',
|
|
147
147
|
background: 'var(--surface,#fff)',
|
|
148
|
-
border: '1px solid var(--border)',
|
|
149
|
-
borderRadius: 'var(--rads)',
|
|
148
|
+
border: '1px solid var(--border, #e2e8f0)',
|
|
149
|
+
borderRadius: 'var(--rads, 8px)',
|
|
150
150
|
boxShadow: 'var(--smd, 0 4px 12px rgba(0,0,0,.12))',
|
|
151
151
|
padding: '8px 12px',
|
|
152
152
|
pointerEvents: 'none',
|
|
153
153
|
zIndex: 100,
|
|
154
154
|
whiteSpace: 'nowrap',
|
|
155
155
|
}}>
|
|
156
|
-
<div style={{ fontSize: '.65rem', color: 'var(--muted)', fontWeight: 500, marginBottom: 4 }}>
|
|
156
|
+
<div style={{ fontSize: '.65rem', color: 'var(--muted, #797b8d)', fontWeight: 500, marginBottom: 4 }}>
|
|
157
157
|
{formatDate(dates[hovered])}
|
|
158
158
|
</div>
|
|
159
159
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
|
160
160
|
{bars[hovered].success > 0 && (
|
|
161
161
|
<div style={{ fontSize: '.7rem', fontWeight: 700, color: greenColor }}>
|
|
162
162
|
{bars[hovered].success} success login{bars[hovered].success !== 1 ? 's' : ''}
|
|
163
|
-
{bars[hovered].failed > 0 && <span style={{ fontWeight: 500, color: 'var(--muted)' }}> ({Math.round((bars[hovered].success / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
|
|
163
|
+
{bars[hovered].failed > 0 && <span style={{ fontWeight: 500, color: 'var(--muted, #797b8d)' }}> ({Math.round((bars[hovered].success / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
|
|
164
164
|
</div>
|
|
165
165
|
)}
|
|
166
166
|
{bars[hovered].failed > 0 && (
|
|
167
167
|
<div style={{ fontSize: '.7rem', fontWeight: 700, color: redColor }}>
|
|
168
168
|
{bars[hovered].failed} failed login{bars[hovered].failed !== 1 ? 's' : ''}
|
|
169
|
-
{bars[hovered].success > 0 && <span style={{ fontWeight: 500, color: 'var(--muted)' }}> ({Math.round((bars[hovered].failed / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
|
|
169
|
+
{bars[hovered].success > 0 && <span style={{ fontWeight: 500, color: 'var(--muted, #797b8d)' }}> ({Math.round((bars[hovered].failed / (bars[hovered].success + bars[hovered].failed)) * 100)}%)</span>}
|
|
170
170
|
</div>
|
|
171
171
|
)}
|
|
172
172
|
{bars[hovered].success === 0 && bars[hovered].failed === 0 && (
|
|
173
|
-
<div style={{ fontSize: '.7rem', fontWeight: 500, color: 'var(--muted)' }}>
|
|
173
|
+
<div style={{ fontSize: '.7rem', fontWeight: 500, color: 'var(--muted, #797b8d)' }}>
|
|
174
174
|
No logins
|
|
175
175
|
</div>
|
|
176
176
|
)}
|
|
@@ -180,11 +180,11 @@ export default function UptimeBar({
|
|
|
180
180
|
|
|
181
181
|
{/* Footer */}
|
|
182
182
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
|
183
|
-
<span style={{ fontSize: '.58rem', color: 'var(--muted)', fontWeight: 500 }}>{leftLabel || '90 days ago'}</span>
|
|
184
|
-
<span style={{ fontSize: '.78rem', fontWeight: 700, color: greenColor, fontFamily: 'var(--mono)' }}>
|
|
183
|
+
<span style={{ fontSize: '.58rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{leftLabel || '90 days ago'}</span>
|
|
184
|
+
<span style={{ fontSize: '.78rem', fontWeight: 700, color: greenColor, fontFamily: 'var(--mono, ui-monospace, monospace)' }}>
|
|
185
185
|
{uptimePercent}%
|
|
186
186
|
</span>
|
|
187
|
-
<span style={{ fontSize: '.58rem', color: 'var(--muted)', fontWeight: 500 }}>{rightLabel || 'Today'}</span>
|
|
187
|
+
<span style={{ fontSize: '.58rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{rightLabel || 'Today'}</span>
|
|
188
188
|
</div>
|
|
189
189
|
</div>
|
|
190
190
|
);
|
|
@@ -194,7 +194,7 @@ function LegendDot({ color, label }) {
|
|
|
194
194
|
return (
|
|
195
195
|
<div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
|
|
196
196
|
<span style={{ width: 7, height: 7, borderRadius: 2, background: color, flexShrink: 0 }} />
|
|
197
|
-
<span style={{ fontSize: '.55rem', color: 'var(--muted)', fontWeight: 500 }}>{label}</span>
|
|
197
|
+
<span style={{ fontSize: '.55rem', color: 'var(--muted, #797b8d)', fontWeight: 500 }}>{label}</span>
|
|
198
198
|
</div>
|
|
199
199
|
);
|
|
200
200
|
}
|