import type React from 'react'; import type {InfoViewerItem} from './InfoViewer'; type LabelMap = { [label in keyof T]?: string; }; type ValueFormatters = { [label in keyof T]?: (value: T[label]) => React.ReactNode; }; function formatLabel(label: keyof Shape, map: LabelMap) { return map[label] ?? label; } function formatValue( label: Key, value: Shape[Key], formatters: ValueFormatters, defaultFormatter?: (value: Shape[Key]) => React.ReactNode, ) { const formatter = formatters[label] || defaultFormatter; const formattedValue = formatter ? formatter(value) : value; return formattedValue; } interface CreateInfoFormatterOptions { values?: ValueFormatters; labels?: LabelMap; defaultValueFormatter?: (value: Shape[keyof Shape]) => React.ReactNode; } export function createInfoFormatter>({ values: valueFormatters, labels: labelMap, defaultValueFormatter, }: CreateInfoFormatterOptions) { return (label: Key, value: Shape[Key]) => ({ label: formatLabel(label, labelMap || {}), value: formatValue(label, value, valueFormatters || {}, defaultValueFormatter), }); } export const formatObject = >( formatter: (value: Key, label: Shape[Key]) => InfoViewerItem, obj?: Partial, ): InfoViewerItem[] => { if (!obj) { return []; } return Object.entries(obj) .map(([label, value]) => formatter(label, value)) .filter(({value}) => Boolean(value)); };