Text | CoUI

Text

일관된 타이포그래피를 제공하는 텍스트 컴포넌트

Text#

Text 는 시멘틱 typography 토큰을 적용해 일관된 텍스트 렌더링을 제공하는 컴포넌트입니다. Flutter 와 Web 양쪽이 거의 동일한 사용 패턴을 갖도록 설계되어, 같은 코드 모양으로 양쪽 플랫폼 모두 작성 가능합니다.

⚡ 권장 패턴: chain 사용#

CoUI Text 의 권장 사용법은 chain modifier 입니다. .bodyMedium / .primary / .semiBold / .italic 처럼 token 이름을 chain 으로 적용하면 양쪽 플랫폼이 일관된 결과를 보장합니다.

// ✅ 권장: chain only
Text('Hello').bodyMedium.semiBold.primary
Text('Error').bodySmall.error.underline
Text('Long text').s14.maxLines(2).overflow(CoreTextOverflow.ellipsis)

// ⚠️ 비권장: 직접 TextStyle 주입
// `style:` 와 같은 직접 prop 은 다른 디자인 시스템과의 호환을 위해 유지
// 되어 있지만, 양쪽 플랫폼의 동작 일치를 보장하기 어려운 케이스가 있어
// 권장하지 않습니다. CoUI 표준 chain 으로 작성하세요.
Text('Hello', style: theme.typography.bodyMedium.copyWith(...))

Live Preview#

Web
The quick brown fox jumps over the lazy dog
Flutter
Loading Flutter...
Text('The quick brown fox jumps over the lazy dog').bodyMedium
const Text('The quick brown fox jumps over the lazy dog').bodyMedium

Per-facet variants#

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 시멘틱 typography (display / headline / title / body / label) 가 필요할 때
  • 토큰 기반 색상 / 굵기 / 기울임 등 chain 으로 스타일을 표현하고 싶을 때
  • light / dark 테마 변경에 자동 반응해야 할 때

대신 다른 컴포넌트를 사용하세요:

  • Badge: 텍스트를 배지 형태로 강조할 때
  • Input / TextField: 사용자 텍스트 입력이 필요할 때
  • Link: 클릭 가능한 링크 텍스트가 필요할 때

기본 사용법 (Basic Usage)#

// 기본 텍스트 — bodyMedium + onSurface 자동 적용
Text('안녕하세요')

// chain — 시멘틱 typography
Text('헤딩').headlineLarge
Text('본문').bodyMedium

// chain — 색상
Text('강조').primary
Text('에러 메시지').error

// chain — 조합 (뒤가 override)
Text('제목').headlineSmall.semiBold.primary

// TextStyle 직접 — CoUI 토큰 사용 (Flutter SDK 표준)
Text(
  '커스텀',
  style: TextStyle(
    color: cs.primary,
    fontSize: CoreFontSize.s14,
    fontWeight: CoreFontWeight.semiBold.weight,  // .weight: int → FontWeight
  ),
)
// 기본 텍스트 — bodyMedium + onSurface 자동 적용
Text('안녕하세요')

// chain — 시멘틱 typography (Flutter 와 동일)
Text('헤딩').headlineLarge
Text('본문').bodyMedium

// chain — 색상 (Flutter 와 동일)
Text('강조').primary
Text('에러 메시지').error

// chain — 조합 (뒤가 override)
Text('제목').headlineSmall.semiBold.primary

// TextStyle 직접 — CoUI 토큰 사용 (Flutter 와 같은 파라미터 + 같은 토큰)
Text(
  '커스텀',
  style: TextStyle(
    color: cs.primary,
    fontSize: CoreFontSize.s14,
    fontWeight: CoreFontWeight.scale.semibold,   // .scale.semibold: String 토큰
  ),
)

chain 메서드#

Typography (시멘틱) — 15#

chainTailwind 클래스
.displayLarge / .displayMedium / .displaySmall text-display-large / text-display-medium / text-display-small
.headlineLarge / .headlineMedium / .headlineSmall text-headline-large / text-headline-medium / text-headline-small
.titleLarge / .titleMedium / .titleSmall text-title-large / text-title-medium / text-title-small
.bodyLarge / .bodyMedium / .bodySmall text-body-large / text-body-medium / text-body-small
.labelLarge / .labelMedium / .labelSmall text-label-large / text-label-medium / text-label-small

Font weight (primitive) — 9#

.thin (100) / .extraLight (200) / .light (300) / .regular (400) / .medium (500) / .semiBold (600) / .bold (700) / .extraBold (800) / .black (900)

색상 (ColorScheme M3 토큰) — 45 + 7 alias#

모든 theme.colorScheme.<token> chain 으로 노출. build 시점에 resolve 되어 Theme override 자동 반영.

카테고리chain
Surface (8) .surface .surfaceDim .surfaceBright .surfaceContainerLowest .surfaceContainerLow .surfaceContainer .surfaceContainerHigh .surfaceContainerHighest
On surface + tint (3) .onSurface .onSurfaceVariant .surfaceTint
Primary (4) .primary .onPrimary .primaryContainer .onPrimaryContainer
Secondary (4) .secondary .onSecondary .secondaryContainer .onSecondaryContainer
Tertiary (4) .tertiary .onTertiary .tertiaryContainer .onTertiaryContainer
Error (4) .error .onError .errorContainer .onErrorContainer
Success (4) .success .onSuccess .successContainer .onSuccessContainer
Warning (4) .warning .onWarning .warningContainer .onWarningContainer
Info (4) .info .onInfo .infoContainer .onInfoContainer
Outline (2).outline .outlineVariant
Inverse (3) .inverseSurface .inverseOnSurface .inversePrimary
Misc (2).shadow .scrim
Aliases (7) .accent (= .tertiary ) / .accentForeground (= .onTertiary ) / .neutral (= .outline ) / .neutralForeground (= .onSurfaceVariant ) / .baseContent (= .onSurface ) / .primaryForeground (= .onPrimary ) / .secondaryForeground (= .onSecondary )

스타일 modifier — 4#

.italic / .underline / .lineThrough / .overline

chain 동작 메커니즘#

체인은 왼쪽부터 순서대로 적용되며, 같은 prop 은 뒤의 chain 이 override 합니다 (copyWith 시멘틱):

// 1. bodyLarge typography 적용
// 2. .semiBold 가 fontWeight override (typography 의 base weight 위에)
// 3. 최종: text-body-large + font-semibold
Text('hi').bodyLarge.semiBold

// 1. headlineSmall typography 적용
// 2. .italic 가 fontStyle 추가
// 3. .accent 가 color 추가
// 결과: text-headline-small + italic + text-tertiary
Text('hi').headlineSmall.italic.accent

빌드 시 단일 <span> 으로 emit — nested wrapper 없이 Tailwind class 로 조립됩니다.

TextStyle#

Flutter#

Flutter SDK TextStyle 그대로 사용 — 모든 Flutter 표준 prop (fontSize, fontWeight, color, decoration, shadows, foreground, ...) 사용 가능.

Text('hi', style: theme.typography.bodyMedium.copyWith(
  fontWeight: FontWeight.w600,
  color: Colors.red,
))

Web#

Web TextStyleFlutter SDK TextStyle 과 동일한 파라미터 이름 을 사용합니다. 타입만 플랫폼별로 자연스럽게 다릅니다 (예: Flutter Color ↔ Web String Tailwind 토큰).

class TextStyle {
  final String? color;            // 'primary' (Tailwind color token)
  final String? backgroundColor;  // 'surface-container'
  final double? fontSize;         // CoreFontSize.s14 등
  final String? fontWeight;       // 'semibold' (CoreFontWeight.scale.*)
  final String? fontStyle;        // 'italic' / 'normal'
  final String? fontFamily;       // 'sans' / 'mono'
  final double? letterSpacing;    // em
  final double? height;           // line-height multiplier
  final String? decoration;       // 'underline' / 'line-through'
  final String? decorationColor;
}

build 시 token 필드는 Tailwind 클래스 (text-${color}, font-${fontWeight} 등) 로 조립되고, raw 값 (fontSize / height / letterSpacing) 은 inline CSS 로 emit 됩니다. 이 패턴은 코드베이스의 다른 컴포넌트들('bg-${cs.primary}' 등 string-token 보간) 과 일관됩니다.

시멘틱 typography 적용은 chain 으로 (Text('hi').bodyMedium) — chain 이 내부적으로 CoreTypography.coui 의 토큰을 읽어 TextStylefontSize/fontWeight/height/letterSpacing 을 채워줍니다.

양쪽 플랫폼 차이 (Platform Differences)#

핵심: 양쪽 모두 같은 CoUI 토큰 (cs.primary / CoreFontWeight.scale.semibold 등) 을 사용합니다. 단 ColorScheme/Typography 가 반환하는 타입 이 플랫폼 native API 에 맞춰 다릅니다.

propFlutter 반환 타입Web 반환 타입
cs.primary Color (dart:ui) — 위젯에 직접 주입 String 'primary' — Tailwind 클래스 보간
CoreFontWeight.scale.semibold (Flutter는 보통 FontWeight.w600 사용) String 'semibold' — Tailwind 클래스 보간
CoreFontSize.s14 / CoreLineHeight.h160 double double ✅ (양쪽 동일)
decoration TextDecoration (combinable) String Tailwind 단일 utility
fontStyle FontStyle enum String ('italic' / 'normal')

파라미터 이름 양쪽 동일 + 토큰 이름 양쪽 동일Text('hi', style: TextStyle(color: cs.primary, fontSize: ..., fontWeight: ...)) 형태로 사용자 코드가 같은 모양. 다른 컴포넌트들 (CoCard(cardStyle: CoreCardStyle(backgroundColor: cs.surface)) 등) 과 동일한 토큰 패턴.

chain 표현 (Text('hi').bodyMedium.primary.semiBold) 은 양쪽 100% 동일.

접근성 (Accessibility)#

  • 본문 텍스트: 배경 대비 WCAG AA (4.5:1) 이상
  • 보조 텍스트 (.neutralForeground): 배경 대비 최소 3:1
  • light / dark 토글 시 CSS variable (--coui-on-surface 등) 자동 반응 — text 색이 테마에 맞게 자동 전환
  • Link: 클릭 가능한 링크 텍스트
  • Badge: 텍스트 배지 (상태/카운트 강조)
  • Tooltip: 호버 시 추가 설명 표시