Download apps/web/src/components/console/MetadataList.tsx from hunian003/message: direct link, hf CLI and curl.
- Browser
- Download file 2.84 kB
-
https://huggingface.co/spaces/hunian003/message/resolve/main/apps/web/src/components/console/MetadataList.tsx
- Command line
-
hf download hf://spaces/hunian003/message/apps/web/src/components/console/MetadataList.tsx
-
curl -L -o MetadataList.tsx https://huggingface.co/spaces/hunian003/message/resolve/main/apps/web/src/components/console/MetadataList.tsx
2.84 kB
| import React from 'react'; | |
| import { cn } from '@/lib/utils'; | |
| /** | |
| * 控制台元数据列表组件 | |
| * 用于展示键值对形式的元数据信息 | |
| */ | |
| interface MetadataItem { | |
| /** 键名 */ | |
| key: string; | |
| /** 值 */ | |
| value: React.ReactNode; | |
| /** 是否为可选字段 */ | |
| optional?: boolean; | |
| } | |
| interface MetadataListProps { | |
| /** 元数据列表 */ | |
| items: MetadataItem[]; | |
| /** 布局方向 */ | |
| layout?: 'vertical' | 'horizontal'; | |
| /** 额外的 className */ | |
| className?: string; | |
| } | |
| /** | |
| * 元数据列表组件 | |
| * 用于控制台中展示键值对信息 | |
| */ | |
| export function MetadataList({ | |
| items, | |
| layout = 'vertical', | |
| className, | |
| }: MetadataListProps) { | |
| // 过滤掉空值 | |
| const visibleItems = items.filter( | |
| (item) => item.value !== null && item.value !== undefined && item.value !== '' | |
| ); | |
| if (visibleItems.length === 0) { | |
| return ( | |
| <div className={cn('py-2 text-xs text-console-text-muted', className)}> | |
| 暂无元数据 | |
| </div> | |
| ); | |
| } | |
| if (layout === 'horizontal') { | |
| return ( | |
| <div className={cn('flex flex-wrap gap-x-4 gap-y-1', className)}> | |
| {visibleItems.map((item) => ( | |
| <div key={item.key} className="flex items-center gap-1.5 text-xs"> | |
| <span className="text-console-text-secondary">{item.key}:</span> | |
| <span className="text-console-text-primary">{item.value}</span> | |
| </div> | |
| ))} | |
| </div> | |
| ); | |
| } | |
| return ( | |
| <dl className={cn('space-y-1', className)}> | |
| {visibleItems.map((item) => ( | |
| <div key={item.key} className="flex items-start gap-2 text-xs"> | |
| <dt className="w-24 shrink-0 text-console-text-secondary"> | |
| {item.key} | |
| {item.optional && ( | |
| <span className="ml-1 text-console-text-muted">(可选)</span> | |
| )} | |
| </dt> | |
| <dd className="flex-1 min-w-0 text-console-text-primary"> | |
| {item.value} | |
| </dd> | |
| </div> | |
| ))} | |
| </dl> | |
| ); | |
| } | |
| /** | |
| * 元数据项组件 | |
| * 单个键值对展示 | |
| */ | |
| interface MetadataEntryProps { | |
| /** 键名 */ | |
| label: string; | |
| /** 值 */ | |
| value: React.ReactNode; | |
| /** 是否为可选字段 */ | |
| optional?: boolean; | |
| /** 额外的 className */ | |
| className?: string; | |
| } | |
| export function MetadataEntry({ | |
| label, | |
| value, | |
| optional, | |
| className, | |
| }: MetadataEntryProps) { | |
| if (value === null || value === undefined || value === '') { | |
| return null; | |
| } | |
| return ( | |
| <div className={cn('flex items-start gap-2 text-xs', className)}> | |
| <span className="w-24 shrink-0 text-console-text-secondary"> | |
| {label} | |
| {optional && ( | |
| <span className="ml-1 text-console-text-muted">(可选)</span> | |
| )} | |
| </span> | |
| <span className="flex-1 min-w-0 text-console-text-primary"> | |
| {value} | |
| </span> | |
| </div> | |
| ); | |
| } | |