ResponsiveGrid#
지정된 columns 개의 균등 너비 셀에 자식을 그리드로 배치합니다. responsive: true 일 때 CoreBreakpoint에 맞춰 컬럼 수가 자동 감소합니다 (기본:
md 이하 1열, lg 이하 2열, lg 이상 columns열). CoGridItem으로 감싸
colSpan/rowSpan을 적용하면 여러 셀을 차지합니다.
Live Preview#
default
Web
Item 1
Item 2
Item 3
Item 4
Item 5
Flutter
Loading Flutter...
class ResponsiveGridDefaultExample extends StatelessComponent {
const ResponsiveGridDefaultExample({super.key});
@override
Component build(BuildContext context) {
final ts = context.typography;
final cs = context.colorScheme;
final textClass = 'text-${ts.bodyMedium} text-${cs.onSurface}';
return CoResponsiveGrid(
columns: 3,
gap: CoreSpace.space16,
children: [
for (var i = 1; i <= 5; i += 1)
CoCard(
cardStyle: const CoreCardStyle(padding: CoreSpace.space16),
child: div([Component.text('Item $i')], classes: textClass),
),
],
);
}
}
class ResponsiveGridDefaultExample extends StatelessWidget {
const ResponsiveGridDefaultExample({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final textStyle = theme.typography.bodyMedium.copyWith(
color: theme.colorScheme.onSurface,
);
return CoResponsiveGrid(
columns: 3,
gap: CoreSpace.space16,
children: [
for (var i = 1; i <= 5; i += 1)
CoCard(
cardStyle: const CoreCardStyle(
padding: EdgeInsets.all(CoreSpace.space16),
),
child: Text('Item $i', style: textStyle),
),
],
);
}
}
span
Web
Spans 2 cols
Cell
Cell
Spans 2 rows
Cell
Cell
Cell
Flutter
Loading Flutter...
class ResponsiveGridSpanExample extends StatelessComponent {
const ResponsiveGridSpanExample({super.key});
@override
Component build(BuildContext context) {
final ts = context.typography;
final cs = context.colorScheme;
final textClass = 'text-${ts.bodyMedium} text-${cs.onSurface}';
const cardStyle = CoreCardStyle<String, double, double, String, bool>(
padding: CoreSpace.space16,
);
return CoResponsiveGrid(
columns: 4,
gap: CoreSpace.space16,
responsive: false,
children: [
CoGridItem(
colSpan: 2,
child: CoCard(
cardStyle: cardStyle,
child: div(
[Component.text('Spans 2 cols')],
classes: textClass,
),
),
),
CoCard(
cardStyle: cardStyle,
child: div([Component.text('Cell')], classes: textClass),
),
CoCard(
cardStyle: cardStyle,
child: div([Component.text('Cell')], classes: textClass),
),
CoGridItem(
rowSpan: 2,
child: CoCard(
cardStyle: cardStyle,
child: div(
[Component.text('Spans 2 rows')],
classes: textClass,
),
),
),
CoCard(
cardStyle: cardStyle,
child: div([Component.text('Cell')], classes: textClass),
),
CoCard(
cardStyle: cardStyle,
child: div([Component.text('Cell')], classes: textClass),
),
CoCard(
cardStyle: cardStyle,
child: div([Component.text('Cell')], classes: textClass),
),
],
);
}
}
class ResponsiveGridSpanExample extends StatelessWidget {
const ResponsiveGridSpanExample({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final textStyle = theme.typography.bodyMedium.copyWith(
color: theme.colorScheme.onSurface,
);
const cardStyle = CoreCardStyle<
Color,
EdgeInsetsGeometry,
BorderRadiusGeometry,
List<BoxShadow>,
Clip
>(padding: EdgeInsets.all(CoreSpace.space16));
return CoResponsiveGrid(
columns: 4,
gap: CoreSpace.space16,
responsive: false,
children: [
CoGridItem(
colSpan: 2,
child: CoCard(
cardStyle: cardStyle,
child: Text('Spans 2 cols', style: textStyle),
),
),
CoCard(
cardStyle: cardStyle,
child: Text('Cell', style: textStyle),
),
CoCard(
cardStyle: cardStyle,
child: Text('Cell', style: textStyle),
),
CoGridItem(
rowSpan: 2,
child: CoCard(
cardStyle: cardStyle,
child: Text('Spans 2 rows', style: textStyle),
),
),
CoCard(
cardStyle: cardStyle,
child: Text('Cell', style: textStyle),
),
CoCard(
cardStyle: cardStyle,
child: Text('Cell', style: textStyle),
),
CoCard(
cardStyle: cardStyle,
child: Text('Cell', style: textStyle),
),
],
);
}
}
사용 시기 (When to Use)#
이 컴포넌트를 사용하세요:
- 대시보드처럼 N × M 셀의 카드/모듈을 배치할 때
- 뷰포트 폭에 따라 열 수가 달라져야 할 때
Wrap이나 flex보다 명시적으로 열 수를 정하고 싶을 때
대신 다른 컴포넌트를 사용하세요:
ResponsiveContainer: 단일 콘텐츠를 화면 중앙에 max-width로 제약Row/flex: 1행 배치Wrap/ flex-wrap: 셀 너비가 content 기반인 경우
기본 사용법 (Basic Usage)#
CoResponsiveGrid(
columns: 3,
gap: CoreSpace.space16,
children: [
for (var i = 1; i <= 6; i++)
CoCard(
cardStyle: const CoreCardStyle(
padding: EdgeInsets.all(CoreSpace.space16),
),
child: Text('Item $i'),
),
],
)
col/row span#
CoResponsiveGrid(
columns: 4,
gap: CoreSpace.space16,
responsive: false,
children: [
CoGridItem(colSpan: 2, child: CoCard(child: Text('Wide'))),
CoCard(child: Text('Cell')),
CoCard(child: Text('Cell')),
CoGridItem(rowSpan: 2, child: CoCard(child: Text('Tall'))),
// ...
],
)
반응형 커스터마이징#
기본 breakpoint 매핑을 덮어쓰려면 breakpoints를 제공:
CoResponsiveGrid(
columns: 6,
breakpoints: {
CoreBreakpoint.xs: 1,
CoreBreakpoint.sm: 2,
CoreBreakpoint.md: 3,
CoreBreakpoint.lg: 4,
CoreBreakpoint.xl: 5,
CoreBreakpoint.xxl: 6,
},
children: [...],
)
Props / Parameters#
CoResponsiveGrid#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
children |
List<Widget> / List<Component> |
required | 그리드 셀 |
columns |
int? |
null → theme → 12 | 가장 넓은 breakpoint에서의 컬럼 수 |
gap |
double? |
null → theme → CoreSpace.space16 |
셀 사이 간격 (logical px) |
responsive |
bool? |
null → theme → true | breakpoint 기반 반응형 활성화 |
breakpoints |
Map<CoreBreakpoint, int>? |
null → theme → 기본 곡선 | 명시적 breakpoint → 컬럼 매핑 |
CoGridItem#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
child |
Widget / Component |
required | 셀 내용 |
colSpan | int? | null → 1 | 차지할 컬럼 수 |
rowSpan | int? | null → 1 | 차지할 행 수 |
동작 스펙 (Behavior)#
배치 알고리즘#
자식을 순서대로 좌→우, 상→하로 스캔하며 colSpan × rowSpan이 완전히 비어있는 최초의 사각형 영역을 예약합니다 (row-major packing).
렌더링#
-
Flutter:
MultiChildRenderObjectWidget→RenderCoGrid(bit-field 점유 그리드로 span 계산) -
Web: CSS Grid (
display: grid,grid-template-columns: repeat(N, minmax(0, 1fr))) +@media (min-width: ...)스코프 블록으로 responsive 처리
반응형 breakpoint 기본값#
| Breakpoint | 기본 컬럼 수 |
|---|---|
| xs (< 640px) | 1 |
| sm (≥ 640px) | 1 |
| md (≥ 768px) | 2 |
| lg (≥ 1024px) | columns |
| xl (≥ 1280px) | columns |
| xxl (≥ 1536px) | columns |
접근성 (Accessibility)#
- 정적 레이아웃 컴포넌트 — 인터랙션 없음
- 자식 위젯의 접근성은 각자 책임
크로스 플랫폼 차이점 (Platform Differences)#
| 항목 | Flutter | Web |
|---|---|---|
| 클래스명 | CoResponsiveGrid / CoGridItem | 동일 |
| 렌더링 | RenderCoGrid (custom RenderBox) |
<div class style="display:grid"> |
| col/row span | CoGridParentData + bit-mask packing |
CSS grid-column: span N / grid-row: span N |
| 반응형 | LayoutBuilder + resolveColumnsForWidth |
@media (min-width: ...) 스코프 스타일 |
| 테마 | CoreResponsiveGridTheme | 동일 |
관련 컴포넌트 (Related Components)#
- ResponsiveContainer: 단일 max-width 래퍼
- Basic: slot 기반 단일 영역 레이아웃