feat(design-system): F003 – complete design system foundation
Design tokens: - lib/ds.ts: DS_COLORS (resultType/confidence/risk/availability/freshness/dataQuality), scoreToConfidenceLevel(), scoreToDataQualityLevel() - lib/constants.ts: added CONFIDENCE_LABELS, DATA_QUALITY_LABELS Badge system (src/components/badges/): - ResultTypeBadge, ConfidenceBadge, RiskBadge, AvailabilityBadge, FreshnessBadge, DataQualityBadge - All use DS_COLORS, MUI Chip size=small, lucide icons, German labels from constants Score components (src/components/scores/): - ConfidenceScore: numeric % with color from utils.confidenceHex - DataQualityScore: LinearProgress + qualitative label - ScoreBar: horizontal bar with label/value/weight - ScoreBreakdownMini: ScoreFactor[] mapped to ScoreBars with Tooltip explanations Card system (src/components/cards/): - DecisionCard: header+badges+score+body+actions, selected/loading/restricted states - CompactCard: single-row 48px card with leading/trailing slots - MetricCard: KPI card with label/value/delta/icon (extracted pattern from SupplyDashboard) Panel system (src/components/panels/): - InfoPanel: outlined Paper with icon+title header - DetailPanel: Accordion sections in bordered Paper - WarningPanel: MUI Alert with warning/critical severity Table components (src/components/tables/): - DataTableShell: Paper+TableContainer+Table with loading/empty/toolbar slots - TableToolbar: flex row with title/count/filters/actions - FilterBar: deletable Chips with clear-all - EmptyTableState: centered empty row spanning all cols - LoadingRows: Skeleton cell rows Form components (src/components/forms/): - TextInput: MUI TextField wrapper with onChange(string) signature - SelectField: generic SelectField<T extends string> with MUI Select - PriorityChipGroup: togglable Chip set (single/multi select) - FieldWithConfidence: label+value+ConfidenceBadge for AI-parsed fields UI additions (src/components/ui/): - CardSkeleton, PanelLoadingState, UnauthorizedState, RestrictedState Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { Box, Card, Typography } from '@mui/material'
|
||||
import { TrendingUp, TrendingDown } from 'lucide-react'
|
||||
import type { SxProps, Theme } from '@mui/material'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
interface MetricDelta {
|
||||
value: string
|
||||
positive: boolean
|
||||
}
|
||||
|
||||
interface MetricCardProps {
|
||||
label: string
|
||||
value: string | number
|
||||
delta?: MetricDelta
|
||||
icon?: ReactNode
|
||||
color?: string
|
||||
sx?: SxProps<Theme>
|
||||
}
|
||||
|
||||
export function MetricCard({ label, value, delta, icon, color = '#1e3a5f', sx }: MetricCardProps) {
|
||||
return (
|
||||
<Card sx={{ p: 2.5, ...sx }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>
|
||||
<Box>
|
||||
<Typography
|
||||
sx={{ fontSize: '0.6875rem', fontWeight: 600, color: 'text.disabled', textTransform: 'uppercase', letterSpacing: '0.08em', mb: 0.5 }}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: '1.75rem', fontWeight: 700, color, lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}>
|
||||
{value}
|
||||
</Typography>
|
||||
{delta && (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.25, mt: 0.5 }}>
|
||||
{delta.positive
|
||||
? <TrendingUp size={12} color="#1a7a4a" />
|
||||
: <TrendingDown size={12} color="#c0392b" />}
|
||||
<Typography
|
||||
sx={{ fontSize: '0.75rem', color: delta.positive ? '#1a7a4a' : '#c0392b', fontWeight: 500 }}
|
||||
>
|
||||
{delta.value}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
{icon && (
|
||||
<Box
|
||||
sx={{
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 1.5,
|
||||
bgcolor: `${color}18`,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{icon}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user