DescriptionCard#
DescriptionCard displays label/value pairs as a structured metadata
summary — useful for order details, profiles, plant care notes, exam
results, or any place that needs a tidy "card of facts".
Live Preview#
class DescriptionCardDefaultExample extends StatelessComponent {
const DescriptionCardDefaultExample({super.key});
@override
Component build(BuildContext context) {
return const DescriptionCard(
title: 'Order Detail',
rows: [
DescriptionRow(label: 'Order', value: 'ORD-2025-00391'),
DescriptionRow(label: 'Item', value: 'AirPods Pro 2'),
DescriptionRow(label: 'Total', value: r'$369.00', isEmphasized: true),
],
);
}
}
class DescriptionCardDefaultExample extends StatelessWidget {
const DescriptionCardDefaultExample({super.key});
@override
Widget build(BuildContext context) {
return const DescriptionCard(
title: 'Order Detail',
rows: [
DescriptionRow(label: 'Order', value: 'ORD-2025-00391'),
DescriptionRow(label: 'Item', value: 'AirPods Pro 2'),
DescriptionRow(label: 'Total', value: '$369.00', isEmphasized: true),
],
);
}
}
class DescriptionCardFilledExample extends StatelessComponent {
const DescriptionCardFilledExample({super.key});
@override
Component build(BuildContext context) {
return const DescriptionCard(
title: 'Profile',
variant: CoreDescriptionCardVariant.filled,
rows: [
DescriptionRow(label: 'Name', value: 'Hong Gildong'),
DescriptionRow(label: 'Email', value: 'hong@example.com'),
DescriptionRow(label: 'Phone', value: '010-1234-5678'),
],
);
}
}
class DescriptionCardFilledExample extends StatelessWidget {
const DescriptionCardFilledExample({super.key});
@override
Widget build(BuildContext context) {
return const DescriptionCard(
title: 'Profile',
variant: CoreDescriptionCardVariant.filled,
rows: [
DescriptionRow(label: 'Name', value: 'Hong Gildong'),
DescriptionRow(label: 'Email', value: 'hong@example.com'),
DescriptionRow(label: 'Phone', value: '010-1234-5678'),
],
);
}
}
class DescriptionCardGhostExample extends StatelessComponent {
const DescriptionCardGhostExample({super.key});
@override
Component build(BuildContext context) {
return const DescriptionCard(
variant: CoreDescriptionCardVariant.ghost,
rows: [
DescriptionRow(label: 'Name', value: 'Kim Cheolsu'),
DescriptionRow(label: 'Email', value: 'kim@example.com'),
DescriptionRow(label: 'Phone', value: '010-1234-5678'),
],
);
}
}
class DescriptionCardGhostExample extends StatelessWidget {
const DescriptionCardGhostExample({super.key});
@override
Widget build(BuildContext context) {
return const DescriptionCard(
variant: CoreDescriptionCardVariant.ghost,
rows: [
DescriptionRow(label: 'Name', value: 'Kim Cheolsu'),
DescriptionRow(label: 'Email', value: 'kim@example.com'),
DescriptionRow(label: 'Phone', value: '010-1234-5678'),
],
);
}
}
class DescriptionCardVerticalExample extends StatelessComponent {
const DescriptionCardVerticalExample({super.key});
@override
Component build(BuildContext context) {
return const DescriptionCard(
title: 'Plant Care',
layout: CoreDescriptionCardLayout.vertical,
rowWeight: CoreDescriptionCardRowWeight.labelProminent,
rows: [
DescriptionRow(label: 'Species', value: 'Monstera Deliciosa'),
DescriptionRow(label: 'Watering', value: 'Every 7 days'),
DescriptionRow(label: 'Light', value: 'Indirect bright light'),
DescriptionRow(label: 'Temperature', value: '18°C – 27°C'),
],
);
}
}
class DescriptionCardVerticalExample extends StatelessWidget {
const DescriptionCardVerticalExample({super.key});
@override
Widget build(BuildContext context) {
return const DescriptionCard(
title: 'Plant Care',
layout: CoreDescriptionCardLayout.vertical,
rowWeight: CoreDescriptionCardRowWeight.labelProminent,
rows: [
DescriptionRow(label: 'Species', value: 'Monstera Deliciosa'),
DescriptionRow(label: 'Watering', value: 'Every 7 days'),
DescriptionRow(label: 'Light', value: 'Indirect bright light'),
DescriptionRow(label: 'Temperature', value: '18°C – 27°C'),
],
);
}
}
class DescriptionCardSpaceBetweenExample extends StatelessComponent {
const DescriptionCardSpaceBetweenExample({super.key});
@override
Component build(BuildContext context) {
return const DescriptionCard(
alignment: CoreDescriptionCardAlignment.spaceBetween,
showRowDividers: true,
rows: [
DescriptionRow(label: 'Product', value: 'AirPods Pro 2'),
DescriptionRow(label: 'Brand', value: 'Apple'),
DescriptionRow(label: 'Price', value: r'$369.00'),
DescriptionRow(label: 'Stock', value: '12'),
],
);
}
}
class DescriptionCardSpaceBetweenExample extends StatelessWidget {
const DescriptionCardSpaceBetweenExample({super.key});
@override
Widget build(BuildContext context) {
return const DescriptionCard(
alignment: CoreDescriptionCardAlignment.spaceBetween,
showRowDividers: true,
rows: [
DescriptionRow(label: 'Product', value: 'AirPods Pro 2'),
DescriptionRow(label: 'Brand', value: 'Apple'),
DescriptionRow(label: 'Price', value: '$369.00'),
DescriptionRow(label: 'Stock', value: '12'),
],
);
}
}
class DescriptionCardPlaceholderExample extends StatelessComponent {
const DescriptionCardPlaceholderExample({super.key});
@override
Component build(BuildContext context) {
return const DescriptionCard(
title: 'Empty Rows',
emptyValueBehavior: CoreDescriptionCardEmptyBehavior.placeholder,
emptyPlaceholder: 'Not provided',
rows: [
DescriptionRow(label: 'Name', value: 'Hong Gildong'),
DescriptionRow(label: 'Phone'),
DescriptionRow(label: 'Email'),
DescriptionRow(label: 'Address', value: 'Seoul, Gangnam-gu'),
],
);
}
}
class DescriptionCardPlaceholderExample extends StatelessWidget {
const DescriptionCardPlaceholderExample({super.key});
@override
Widget build(BuildContext context) {
return const DescriptionCard(
title: 'Empty Rows',
emptyValueBehavior: CoreDescriptionCardEmptyBehavior.placeholder,
emptyPlaceholder: 'Not provided',
rows: [
DescriptionRow(label: 'Name', value: 'Hong Gildong'),
DescriptionRow(label: 'Phone'),
DescriptionRow(label: 'Email'),
DescriptionRow(label: 'Address', value: 'Seoul, Gangnam-gu'),
],
);
}
}
When to Use#
Use this component:
- Listing detail facts as label/value pairs
- Showing structured metadata (order, profile, vehicle history, …)
- Emphasising a totals/score row (
isEmphasized: true) - Adding a footer action area (
bottomAction)
Use a different component:
Tablefor many records that need sorting/comparisonStatfor a single KPI valueCardfor free-form layout
Props#
DescriptionCard#
| Prop | Type | Default | Description |
|---|---|---|---|
rows |
List<DescriptionRow> |
required | Row data list |
size |
CoreDescriptionCardSize |
md |
Card size scale (xs/sm/md/lg/xl) |
layout |
CoreDescriptionCardLayout |
horizontal |
Row layout direction |
variant |
CoreDescriptionCardVariant |
outlined |
Card style (filled/outlined/ghost) |
title |
String? |
null |
Optional title text |
titleLeading |
Widget? / Component? |
null |
Widget rendered before the title |
titleTrailing |
Widget? / Component? |
null |
Widget rendered after the title |
showDivider |
bool |
true |
Draw divider below the title |
showRowDividers |
bool |
false |
Draw dividers between rows |
bottomAction |
Widget? / Component? |
null |
Bottom action area |
showBottomActionDivider |
bool |
true |
Draw divider above the bottom action |
alignment |
CoreDescriptionCardAlignment |
fixed |
Horizontal alignment (fixed or spaceBetween) |
valueOverflow |
CoreDescriptionCardOverflow |
wrap |
Long-value handling (wrap or ellipsis) |
rowWeight |
CoreDescriptionCardRowWeight |
valueProminent |
Default emphasis direction |
emptyValueBehavior |
CoreDescriptionCardEmptyBehavior |
hide |
Null-row handling (hide or placeholder) |
emptyPlaceholder |
String |
'-' |
Placeholder text for null rows |
onTap |
VoidCallback? |
null |
Card tap callback |
descriptionCardStyle |
CoreDescriptionCardStyle? |
null |
Per-instance chrome + dimensional + text-slot overrides (background / border / radius / padding / shadow / divider / default + emphasised label/value text styles) |
DescriptionRow#
| Prop | Type | Default | Description |
|---|---|---|---|
label | String | required | Row label |
value | String? | null | Row value |
valueWidget |
Widget? / Component? |
null |
Custom value widget — wins over value |
leading |
Widget? / Component? |
null |
Widget rendered before the label |
trailing |
Widget? / Component? |
null |
Widget rendered after the value |
onTap |
VoidCallback? |
null |
Row tap callback |
labelTextStyle |
CoreTextStyle? |
null |
Per-row label text slot override (full typographic surface:
fontSize
/
fontWeight
/
letterSpacing
/
color
/
lineHeight
/
fontFamily
)
|
valueTextStyle |
CoreTextStyle? |
null |
Per-row value text slot override |
isEmphasized |
bool |
false |
Apply the card's emphasised label/value text style to this row |
스타일 시스템 (Style System)#
DescriptionCard 의 모든 chrome / dimensional / text-slot 오버라이드는
단일 descriptionCardStyle slot 으로 흐릅니다. 평면 chrome 파라미터
(padding / borderRadius / backgroundColor
/ borderColor /
borderWidth / boxShadow) 과 별도의 emphasisStyle
클래스는 Epic
#1370 phase 5 에서 CoreDescriptionCardStyle 의 nested 필드로
통합되었습니다.
CoreDescriptionCardStyle#
| Field | Type | Description |
|---|---|---|
backgroundColor |
CoreColor? |
Card background fill colour |
borderColor | CoreColor? | Card border stroke colour |
borderWidth |
double? |
Card border stroke width (logical px) |
borderRadius | CoreBorderRadius? | Card border radius |
padding | CoreEdgeInsets? | Card content padding |
boxShadow |
List<CoreShadowLayer>? |
Card shadow |
dividerColor |
CoreColor? |
Title / row / bottom-action divider colour |
labelTextStyle |
CoreTextStyle? |
Default label text slot (per-row, before emphasis) |
valueTextStyle |
CoreTextStyle? |
Default value text slot (per-row, before emphasis) |
emphasizedLabelTextStyle |
CoreTextStyle? |
Label slot applied to isEmphasized: true 행 |
emphasizedValueTextStyle |
CoreTextStyle? |
Value slot applied to isEmphasized: true 행 |
Resolve chain#
design system default
→ theme.descriptionCard.style (project base)
→ parent component slot override (e.g. a wrapping form)
→ widget.descriptionCardStyle (per-instance)
→ row.labelTextStyle / row.valueTextStyle (per-row overrides)
각 단계는 non-null 필드만 덮어쓰며, nested CoreTextStyle slot 도
재귀적으로 merge 됩니다 (fontSize 만 바꾸면 색상/굵기는 base 에서
상속).
Cross-platform Notes#
| Concern | Flutter | Web |
|---|---|---|
| Row data class | DescriptionRow | DescriptionRow |
| Style class | CoreDescriptionCardStyle (platform-neutral) |
CoreDescriptionCardStyle (platform-neutral) |
| Color override type | CoreColor → Color at render |
CoreColor → CSS string at render |
| Padding/radius override | CoreEdgeInsets / CoreBorderRadius → Flutter at render |
CoreEdgeInsets / CoreBorderRadius → CSS at render |
| Box shadow override | List<CoreShadowLayer> → List<BoxShadow> at render |
List<CoreShadowLayer> → CSS string at render |
Row onTap | ✅ | ✅ |
| Custom value widget | ✅ | ✅ |