Skip to content

Commit 016a515

Browse files
authored
feat: rework metric cards to tabs (#2580)
1 parent c09d9be commit 016a515

38 files changed

+835
-752
lines changed

src/components/DiagnosticCard/DiagnosticCard.scss

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/components/DiagnosticCard/DiagnosticCard.tsx

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/components/DoughnutMetrics/DoughnutMetrics.scss

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,75 @@
11
.ydb-doughnut-metrics {
22
--doughnut-border: 16px;
3-
--doughnut-color: var(--ydb-color-status-green);
4-
--doughnut-backdrop-color: var(--g-color-base-positive-light);
3+
--doughnut-width: 100px;
4+
--doughnut-wrapper-indent: calc(var(--doughnut-border) + 5px);
5+
--doughnut-color: var(--g-color-base-positive-heavy);
6+
--doughnut-backdrop-color: var(--g-color-base-generic);
57
--doughnut-overlap-color: var(--g-color-base-positive-heavy-hover);
8+
--doughnut-text-color: var(--g-color-text-positive-heavy);
9+
610
&__doughnut {
711
position: relative;
812

9-
width: 100px;
13+
width: var(--doughnut-width);
1014
aspect-ratio: 1;
1115

1216
border-radius: 50%;
17+
mask: radial-gradient(circle at center, transparent 46%, #000 46.5%);
1318

1419
transform: rotate(180deg);
15-
&::before {
16-
display: block;
17-
18-
height: calc(100% - calc(var(--doughnut-border) * 2));
20+
}
1921

20-
content: '';
22+
// Size modifiers - using visually centered values
23+
&__doughnut_size_small {
24+
--doughnut-border: 12px;
25+
--doughnut-width: 65px;
26+
--doughnut-wrapper-indent: 15px;
27+
}
2128

22-
border-radius: 50%;
23-
background-color: var(--g-color-base-background);
29+
&__doughnut_size_medium {
30+
--doughnut-border: 16px;
31+
--doughnut-width: 100px;
32+
--doughnut-wrapper-indent: calc(var(--doughnut-border) + 5px);
33+
}
2434

25-
transform: translate(var(--doughnut-border), var(--doughnut-border));
26-
aspect-ratio: 1;
27-
}
35+
&__doughnut_size_large {
36+
--doughnut-border: 20px;
37+
--doughnut-width: 130px;
38+
--doughnut-wrapper-indent: 25px;
2839
}
29-
&__doughnut_status_warning {
30-
--doughnut-color: var(--ydb-color-status-yellow);
31-
--doughnut-backdrop-color: var(--g-color-base-warning-light);
40+
41+
&_status_warning {
42+
--doughnut-color: var(--g-color-base-warning-heavy);
3243
--doughnut-overlap-color: var(--g-color-base-warning-heavy-hover);
44+
--doughnut-text-color: var(--g-color-text-warning);
3345
}
34-
&__doughnut_status_danger {
35-
--doughnut-color: var(--ydb-color-status-red);
36-
--doughnut-backdrop-color: var(--g-color-base-danger-light);
46+
&_status_danger {
47+
--doughnut-color: var(--g-color-base-danger-heavy);
3748
--doughnut-overlap-color: var(--g-color-base-danger-heavy-hover);
49+
--doughnut-text-color: var(--g-color-base-danger-heavy);
3850
}
3951
&__text-wrapper {
40-
--wrapper-indent: calc(var(--doughnut-border) + 5px);
41-
4252
position: absolute;
43-
top: var(--wrapper-indent);
44-
right: var(--wrapper-indent);
53+
z-index: 1;
54+
top: var(--doughnut-wrapper-indent);
55+
left: var(--doughnut-wrapper-indent);
4556

4657
display: flex;
4758
flex-direction: column;
4859
justify-content: center;
4960
align-items: center;
5061

51-
width: calc(100% - calc(var(--wrapper-indent) * 2));
62+
width: calc(100% - calc(var(--doughnut-wrapper-indent) * 2));
5263

5364
text-align: center;
5465

55-
transform: rotate(180deg);
5666
aspect-ratio: 1;
5767
}
68+
5869
&__value {
59-
position: absolute;
60-
bottom: 20px;
70+
color: var(--doughnut-text-color);
6171
}
72+
6273
&__legend-note {
6374
display: flex;
6475
}

src/components/DoughnutMetrics/DoughnutMetrics.tsx

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22

3-
import type {TextProps} from '@gravity-ui/uikit';
3+
import type {HelpMarkProps, TextProps} from '@gravity-ui/uikit';
44
import {Flex, HelpMark, Text} from '@gravity-ui/uikit';
55

66
import {cn} from '../../utils/cn';
@@ -10,30 +10,53 @@ import './DoughnutMetrics.scss';
1010

1111
const b = cn('ydb-doughnut-metrics');
1212

13+
const SizeContext = React.createContext<'small' | 'medium' | 'large'>('medium');
14+
1315
interface LegendProps {
1416
children?: React.ReactNode;
1517
variant?: TextProps['variant'];
1618
color?: TextProps['color'];
1719
note?: React.ReactNode;
20+
noteIconSize?: HelpMarkProps['iconSize'];
1821
}
1922

20-
function Legend({children, variant = 'subheader-3', color = 'primary', note}: LegendProps) {
23+
function Legend({
24+
children,
25+
variant = 'subheader-3',
26+
color = 'primary',
27+
note,
28+
noteIconSize,
29+
}: LegendProps) {
2130
return (
2231
<Flex gap={1} alignItems="center">
2332
<Text variant={variant} color={color} className={b('legend')} as="div">
2433
{children}
2534
</Text>
2635
{note && (
27-
<HelpMark className={b('legend-note')} popoverProps={{placement: 'right'}}>
36+
<HelpMark
37+
iconSize={noteIconSize || 'm'}
38+
className={b('legend-note')}
39+
popoverProps={{placement: 'right'}}
40+
>
2841
{note}
2942
</HelpMark>
3043
)}
3144
</Flex>
3245
);
3346
}
34-
function Value({children, variant = 'subheader-2'}: LegendProps) {
47+
function Value({children, variant}: LegendProps) {
48+
const size = React.useContext(SizeContext);
49+
50+
const sizeVariantMap = {
51+
small: 'subheader-1',
52+
medium: 'subheader-2',
53+
large: 'subheader-3',
54+
} as const;
55+
56+
const finalVariant = variant || sizeVariantMap[size];
57+
3558
return (
36-
<Text variant={variant} className={b('value')}>
59+
<Text variant={finalVariant} className={b('value')}>
3760
{children}
3861
</Text>
3962
);
@@ -44,9 +67,16 @@ interface DoughnutProps {
4467
fillWidth: number;
4568
children?: React.ReactNode;
4669
className?: string;
70+
size?: 'small' | 'medium' | 'large';
4771
}
4872

49-
export function DoughnutMetrics({status, fillWidth, children, className}: DoughnutProps) {
73+
export function DoughnutMetrics({
74+
status,
75+
fillWidth,
76+
children,
77+
className,
78+
size = 'medium',
79+
}: DoughnutProps) {
5080
let filledDegrees = fillWidth * 3.6;
5181
let doughnutFillVar = 'var(--doughnut-color)';
5282
let doughnutBackdropVar = 'var(--doughnut-backdrop-color)';
@@ -57,17 +87,17 @@ export function DoughnutMetrics({status, fillWidth, children, className}: Doughn
5787
doughnutFillVar = 'var(--doughnut-overlap-color)';
5888
}
5989

90+
const doughnutStyle: React.CSSProperties = {
91+
background: `conic-gradient(${doughnutFillVar} 0deg ${filledDegrees}deg, ${doughnutBackdropVar} ${filledDegrees}deg 360deg)`,
92+
};
93+
6094
return (
61-
<div className={b(null, className)}>
62-
<div
63-
style={{
64-
background: `conic-gradient(${doughnutFillVar} 0deg ${filledDegrees}deg, ${doughnutBackdropVar} ${filledDegrees}deg 360deg)`,
65-
}}
66-
className={b('doughnut', {status})}
67-
>
95+
<SizeContext.Provider value={size}>
96+
<div className={b({status}, className)} style={{position: 'relative'}}>
97+
<div style={doughnutStyle} className={b('doughnut', {size})}></div>
6898
<div className={b('text-wrapper')}>{children}</div>
6999
</div>
70-
</div>
100+
</SizeContext.Provider>
71101
);
72102
}
73103

src/components/MetricChart/MetricChart.scss

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22
display: flex;
33
flex-direction: column;
44

5-
padding: var(--g-spacing-4) var(--g-spacing-4) var(--g-spacing-2);
5+
width: 100%;
6+
padding: 0;
67

7-
border: 1px solid var(--g-color-line-generic);
8-
border-radius: 8px;
8+
border: none;
99

10-
&_noBorder {
11-
padding: 0;
12-
13-
border: none;
10+
&__toolbar {
11+
margin-bottom: 10px;
1412
}
1513

1614
&__chart {

0 commit comments

Comments
 (0)