Skip to content

Commit 1d1e4db

Browse files
committed
refactor(InfoViewer): migrate to ts, adjust types
1 parent b808fe9 commit 1d1e4db

File tree

5 files changed

+51
-53
lines changed

5 files changed

+51
-53
lines changed

src/components/IndexInfoViewer/IndexInfoViewer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type {TEvDescribeSchemeResult, TIndexDescription} from '../../types/api/schema';
2-
import {InfoViewer, createInfoFormatter} from '../InfoViewer';
2+
import {InfoViewer, createInfoFormatter, InfoViewerItem} from '../InfoViewer';
33

44
const DISPLAYED_FIELDS: Set<keyof TIndexDescription> = new Set([
55
'Type',
@@ -34,7 +34,7 @@ export const IndexInfoViewer = ({data}: IndexInfoViewerProps) => {
3434
}
3535

3636
const TableIndex = data.PathDescription?.TableIndex;
37-
const info: Array<{label?: string, value?: unknown}> = [];
37+
const info: Array<InfoViewerItem> = [];
3838

3939
let key: keyof TIndexDescription;
4040
for (key in TableIndex) {

src/components/InfoViewer/InfoViewer.js

Lines changed: 0 additions & 47 deletions
This file was deleted.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import type {ReactNode} from 'react';
2+
import cn from 'bem-cn-lite';
3+
4+
import './InfoViewer.scss';
5+
6+
export interface InfoViewerItem {
7+
label: string;
8+
value: ReactNode;
9+
}
10+
11+
interface InfoViewerProps {
12+
title?: string;
13+
info?: InfoViewerItem[];
14+
dots?: boolean;
15+
className?: string;
16+
}
17+
18+
const b = cn('info-viewer');
19+
20+
const InfoViewer = ({title, info, dots = true, className}: InfoViewerProps) => (
21+
<div className={b(null, className)}>
22+
{title && <div className={b('title')}>{title}</div>}
23+
{info && info.length > 0 ? (
24+
<div className={b('items')}>
25+
{info.map((data, infoIndex) => (
26+
<div className={b('row')} key={data.label + infoIndex}>
27+
<div className={b('label')}>
28+
{data.label}
29+
{dots && <div className={b('dots')} />}
30+
</div>
31+
32+
<div className={b('value')}>{data.value}</div>
33+
</div>
34+
))}
35+
</div>
36+
) : (
37+
<>no {title} data</>
38+
)}
39+
</div>
40+
);
41+
42+
export default InfoViewer;

src/components/InfoViewer/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ import InfoViewer from './InfoViewer';
22

33
export {InfoViewer};
44
export * from './utils';
5+
export type {InfoViewerItem} from './InfoViewer';

src/components/InfoViewer/utils.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import type {ReactNode} from "react";
2+
13
type LabelMap<T> = {
24
[label in keyof T]?: string;
35
}
46

57
type ValueFormatters<T> = {
6-
[label in keyof T]?: (value: T[label]) => string | undefined;
8+
[label in keyof T]?: (value: T[label]) => ReactNode;
79
}
810

911
function formatLabel<Shape>(label: keyof Shape, map: LabelMap<Shape>) {
@@ -14,18 +16,18 @@ function formatValue<Shape, Key extends keyof Shape>(
1416
label: Key,
1517
value: Shape[Key],
1618
formatters: ValueFormatters<Shape>,
17-
defaultFormatter?: (value: Shape[Key]) => string | undefined,
19+
defaultFormatter?: (value: Shape[Key]) => ReactNode,
1820
) {
1921
const formatter = formatters[label] || defaultFormatter;
2022
const formattedValue = formatter ? formatter(value) : value;
2123

22-
return String(formattedValue ?? '');
24+
return formattedValue;
2325
}
2426

2527
interface CreateInfoFormatterOptions<Shape> {
2628
values?: ValueFormatters<Shape>,
2729
labels?: LabelMap<Shape>,
28-
defaultValueFormatter?: (value: Shape[keyof Shape]) => string | undefined,
30+
defaultValueFormatter?: (value: Shape[keyof Shape]) => ReactNode,
2931
}
3032

3133
export function createInfoFormatter<Shape extends Record<string, any>>({

0 commit comments

Comments
 (0)