TextBlock#
시맨틱 역할(element)을 가진 prose 텍스트 블록입니다. Web 은 각 element 를 시맨틱 HTML 태그(<p>·<h1>~<h6>·<blockquote>
등)에 바인딩하고, Flutter 는 동일 element 로 타이포그래피 토큰과 제목 레벨을 함께 고릅니다 — 그래서 제목이 크게 보일 뿐 아니라 스크린 리더에도 제목으로 읽힙니다. 단일
Text chain 이 한 줄 텍스트라면, TextBlock 은 제목/문단/인용 같은 문서 구조 단위입니다.
Live Preview#
문서 제목
본문은 paragraph 역할로 렌더됩니다. element 가 시맨틱 타이포 역할을 고릅니다.
class TextBlockDefaultExample extends StatelessComponent {
const TextBlockDefaultExample({super.key});
@override
Component build(BuildContext context) {
return div(
styles: Styles(raw: {'width': '360px'}),
[
div(
classes: 'flex flex-col gap-${CoreSpace.scale.space8}',
[
TextBlock(text: '문서 제목', element: CoreTextBlockElement.h3),
TextBlock(
text: '본문은 paragraph 역할로 렌더됩니다. element 가 시맨틱 타이포 역할을 고릅니다.',
),
],
),
],
);
}
}
class TextBlockDefaultExample extends StatelessWidget {
const TextBlockDefaultExample({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
width: 360,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: CoreSpace.space8,
children: [
TextBlock(text: '문서 제목', element: CoreTextBlockElement.h3),
TextBlock(
text: '본문은 paragraph 역할로 렌더됩니다. element 가 시맨틱 타이포 역할을 고릅니다.',
),
],
),
);
}
}
문서 제목
본문은 paragraph 역할로 렌더됩니다. element 가 시맨틱 타이포 역할을 고릅니다.
blockquote 는 좌측 액센트 보더 chrome 을 가진다.
class TextBlockChainExample extends StatelessComponent {
const TextBlockChainExample({super.key});
@override
Component build(BuildContext context) {
return div(
styles: Styles(raw: {'width': '360px'}),
[
div(
classes: 'flex flex-col gap-${CoreSpace.scale.space8}',
[
TextBlock(text: '문서 제목', element: CoreTextBlockElement.h3),
TextBlock(
text: '본문은 paragraph 역할로 렌더됩니다. element 가 시맨틱 타이포 역할을 고릅니다.',
),
TextBlock(
text: 'blockquote 는 좌측 액센트 보더 chrome 을 가진다.',
element: CoreTextBlockElement.blockquote,
).withStyle(
const CoreTextBlockStyle(
blockQuoteBorderColor: CoreColor.token(CoreColors.primary),
blockQuoteBorderWidth: CoreStrokeWidth.stroke4,
blockQuotePadding: CoreEdgeInsets.directional(
start: CoreSpace.space16,
),
),
),
],
),
],
);
}
}
class TextBlockChainExample extends StatelessWidget {
const TextBlockChainExample({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
width: 360,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: CoreSpace.space8,
children: [
TextBlock(text: '문서 제목', element: CoreTextBlockElement.h3),
TextBlock(
text: '본문은 paragraph 역할로 렌더됩니다. element 가 시맨틱 타이포 역할을 고릅니다.',
),
TextBlock(
text: 'blockquote 는 좌측 액센트 보더 chrome 을 가진다.',
element: CoreTextBlockElement.blockquote,
).withStyle(
const CoreTextBlockStyle(
blockQuoteBorderColor: CoreColor.token(CoreColors.primary),
blockQuoteBorderWidth: CoreStrokeWidth.stroke4,
blockQuotePadding: CoreEdgeInsets.directional(
start: CoreSpace.space16,
),
),
),
],
),
);
}
}
사용법#
// Flutter / Web 동일 — element 가 시맨틱 역할(타이포)을 고른다
TextBlock(text: '문서 제목', element: CoreTextBlockElement.h3)
TextBlock(text: '본문 단락입니다.') // element 기본값 = p
Props#
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
text |
String? |
null |
표시할 텍스트 (단순 문자열) |
element |
CoreTextBlockElement |
p |
시맨틱 역할 (
p
·
span
·
h1
h6
·
blockquote
·
large
·
small
). Web 은 HTML 태그로, Flutter 는 타이포 토큰 + 제목 레벨(
h1
h6
)로 매핑
|
presets |
List<TextBlockStyle>? |
null |
사전 정의 스타일 프리셋 (
heading1
~
heading4
·
lg
·
sm
·
muted
·
lead
·
inlineCode
등 양 플랫폼 동명 헬퍼)
|
textBlockStyle |
CoreTextBlockStyle? |
null |
chrome 단일 진입점 — blockquote / pre 박스 |
children |
List<Widget> / List<Component>? |
null |
rich-text 합성용 자식 (text 대신/함께) |
element는 구조 역할을,presets는 그 위에 얹는 시각 프리셋을 정합니다. Flutter 의 preset 헬퍼는BuildContext를 받아 테마 타이포를 해석합니다(TextBlock.heading2(context)).
CoreTextBlockStyle 필드#
| 필드 | 타입 | 설명 |
|---|---|---|
blockQuoteBorderColor |
CoreColor? |
Left accent-border colour override for
blockquote
.
null
defers to [defaultBlockQuoteBorderColor].
|
blockQuoteBorderWidth |
double? |
Left accent-border stroke width override for blockquote (logical px). |
blockQuotePadding |
CoreEdgeInsets? |
Left indent override between the
blockquote
accent border and its text. Defaults to left-only ([defaultBlockQuotePadding]); user overrides may supply four-side
CoreEdgeInsets
for richer chrome.
|
inlineCodeBackgroundColor |
CoreColor? |
Surface-fill colour override of the
pre
inline-code box.
null
defers to [defaultInlineCodeBackgroundColor].
|
inlineCodeRadius |
double? |
Corner radius override of the pre inline-code surface box (logical px). |
inlineCodePadding |
CoreEdgeInsets? |
Inner padding override inside the pre inline-code surface box. |
// Flutter / Web 동일 — withStyle 체인이 xxxStyle 슬롯으로 merge 한다
TextBlock(
text: '인용문',
element: CoreTextBlockElement.blockquote,
).withStyle(
const CoreTextBlockStyle(blockQuoteBorderWidth: CoreStrokeWidth.stroke4),
)
사용 가이드라인 (Usage Guidelines)#
✅ Do#
시각적 크기만 바꾸고 싶으면 element 대신 presets 사용
// ✅ 문서 구조는 문단(p) 유지, 시각적 크기만 크게
TextBlock(text: '강조 문구', presets: [TextBlockStyle.lead])
element 는 시맨틱 역할(제목 레벨 포함)을 정합니다 — 크기만 키우려고 h1 을 고르면 문서 아웃라인/스크린 리더에도 실제 제목으로 읽힙니다.
❌ Don't#
Flutter 에서 strong / em / blockquote / small 을 시각 효과로만 여기지 않기
// ❌ Flutter 에서는 strong 이 타이포그래피일 뿐, 실제 강조 시맨틱이 없음
TextBlock(text: '반드시 확인하세요', element: CoreTextBlockElement.strong)
Web 은 네이티브 태그가 시맨틱을 담당하지만, Flutter 는 h1~h6 만 시맨틱을 갖고 나머지(strong/em/blockquote/small)는 타이포그래피일 뿐입니다 — 강조·인용의 의미가 전달돼야 한다면 Flutter 쪽에는 소비자가 직접 Semantics 를 얹어야 합니다.
접근성 (Accessibility)#
역할 / Semantics#
element 가 시맨틱을 정하지만 두 플랫폼이 담아내는 범위가 다릅니다.
-
Flutter — 제목만 시맨틱을 갖습니다.
.h1~.h6일 때만Semantics(headingLevel:)로 감싸고(header: true는 이 킷에서 페이지 배너 랜드마크용이라 함께 쓰지 않습니다),p/span/label/strong/em/small은 시맨틱 노드 없이 텍스트만 렌더합니다.blockquote/pre는DecoratedBox+Paddingchrome 뿐이라 역시 역할이 없습니다. -
Web — ARIA 를 전혀 쓰지 않는 대신
element가 고른 네이티브 태그(<p>·<span>·<h1>~<h6>·<blockquote>·<pre>·<label>·<strong>·<em>·<small>)가 시맨틱을 담당합니다.
키보드#
처리하는 키가 없습니다.
포커스#
포커스를 받지 않고 포커스를 관리하지도 않습니다. Flutter 는 평범한 Text 를 렌더하므로 텍스트 선택도 되지 않습니다.
스크린 리더#
Flutter 는 h1~h6 만 해당 레벨의 제목으로 읽히고 나머지 element 는 역할 없는 일반 텍스트로 읽힙니다. Web 은 네이티브 태그가 그대로 전달되어 제목이 문서 아웃라인에 들어가고
blockquote / strong / em / small / label
도 각자의 HTML 시맨틱을 유지합니다. 두 플랫폼이 일치하는 지점은 제목뿐입니다.
알려진 제약#
-
blockquote/pre/strong/em/small은 Flutter 에서 타이포그래피일 뿐이고, 실제 요소 시맨틱은 Web 만 얻습니다. 강조나 인용의 의미가 읽혀야 한다면 Flutter 쪽에는 소비자가 직접Semantics를 얹어야 합니다. -
Web
<label>은for없이 렌더되므로 어떤 컨트롤과도 프로그래밍적으로 연결되지 않습니다 — 필요하면attributes로 직접 넘겨야 합니다. Flutter 에는 label 시맨틱 자체가 없습니다. -
제목 레벨은
element가 그대로 정합니다 — 시각적 크기를 위해h1을 고르면 문서 아웃라인도 그렇게 바뀝니다. 크기만 바꾸려면element대신presets를 쓰세요.
고대비 · 강제 색상처럼 전 컴포넌트에 공통으로 걸리는 축은 전역 접근성 축에서 다룹니다.