45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
'use client'
|
|
|
|
import type { ComponentRenderProps } from '@json-render/react'
|
|
|
|
type KVItem = {
|
|
label: string; value: string; bold?: boolean
|
|
variant?: string; isTotalRow?: boolean
|
|
}
|
|
|
|
const variantStyles: Record<string, string> = {
|
|
default: '',
|
|
highlight: 'bg-gray-50 font-semibold',
|
|
muted: 'text-gray-400',
|
|
success: 'text-green-600',
|
|
danger: 'text-red-600',
|
|
}
|
|
|
|
export function KeyValueList({ element }: ComponentRenderProps) {
|
|
const { items, compact } = element.props as { items: KVItem[]; compact?: boolean }
|
|
|
|
return (
|
|
<div className="bg-white rounded-xl shadow-sm overflow-hidden">
|
|
{items.map((item, i) => {
|
|
const isTotalRow = item.isTotalRow
|
|
const rowClass = isTotalRow
|
|
? 'bg-blue-900 text-white px-6 py-4'
|
|
: item.variant === 'success'
|
|
? 'bg-green-50 px-6 py-3'
|
|
: `${variantStyles[item.variant || 'default']} px-6 ${compact ? 'py-2' : 'py-3'} border-b border-gray-100 last:border-b-0`
|
|
|
|
return (
|
|
<div key={i} className={`flex justify-between items-center ${rowClass}`}>
|
|
<span className={`${isTotalRow ? 'text-base font-semibold' : 'text-sm text-gray-500'} ${item.variant === 'success' ? 'text-green-700' : ''}`}>
|
|
{item.label}
|
|
</span>
|
|
<span className={`font-mono ${isTotalRow ? 'text-xl font-bold' : item.bold ? 'font-semibold text-gray-900' : 'font-medium text-gray-900'} ${item.variant === 'success' ? 'text-green-600' : ''} ${item.variant === 'danger' ? 'text-red-600' : ''}`}>
|
|
{item.value}
|
|
</span>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
)
|
|
}
|