LogoSkills

coui-text-block

Activate when rendering semantic prose text โ€” paragraphs, headings, blockquotes, preformatted/inline code, muted captions, or lead subtitles โ€” using the TextBlock component with CoreTextBlockElemen...

CoUI TextBlock#

ํ•œ๋งˆ๋””๋กœ (๋น„๊ฐœ๋ฐœ์ž์šฉ)#

ํ…์ŠคํŠธ๋ธ”๋ก(TextBlock)์€ ๋ฌธ์„œ ์† ๊ธ€์ž๋ฅผ "์—ญํ• ์— ๋งž๋Š” ์˜ท"์„ ์ž…ํ˜€ ๋ณด์—ฌ์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์›Œ๋“œ์—์„œ "์ œ๋ชฉ 1", "๋ณธ๋ฌธ", "์ธ์šฉ๋ฌธ" ์Šคํƒ€์ผ์„ ๊ณ ๋ฅด๋Š” ๊ฒƒ์„ ๋– ์˜ฌ๋ฆฌ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์„œ๋Š” ์•ฑ(๋ชจ๋ฐ”์ผ)๊ณผ ์›น์‚ฌ์ดํŠธ์—์„œ ์ œ๋ชฉยท๋ฌธ๋‹จยท์ธ์šฉ๋ฌธยท์ฝ”๋“œ ์กฐ๊ฐ ๊ฐ™์€ ๊ธ€์„ ๋˜‘๊ฐ™์€ ์„œ์ฒด ๊ทœ์น™์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•œ ์„ค๋ช…์„œ์ž…๋‹ˆ๋‹ค. ์—ญํ• (์ œ๋ชฉ์ธ์ง€ ๋ฌธ๋‹จ์ธ์ง€)๊ณผ ์Šคํƒ€์ผ ํ”„๋ฆฌ์…‹๋งŒ ๊ณจ๋ผ์ฃผ๋ฉด ์•Œ์•„์„œ ํ†ต์ผ๋œ ๋ชจ์–‘์œผ๋กœ ๋‚˜์˜ต๋‹ˆ๋‹ค.

๋ฌด์—‡์„ยท์–ธ์ œ (๋น„๊ฐœ๋ฐœ์ž์šฉ)#

  • ๋ฌด์—‡์„ ํ•ด์ฃผ๋‚˜์š”: ํฐ ์ œ๋ชฉ(H1~H6), ๋ณธ๋ฌธ ๋ฌธ๋‹จ, ์ธ์šฉ๋ฌธ(์™ผ์ชฝ์— ์„ธ๋กœ์ค„์ด ์žˆ๋Š” ๋“ค์—ฌ์“ด ๊ธ€), ์ฝ”๋“œ ์กฐ๊ฐ(ํšŒ์ƒ‰ ์ƒ์ž ์•ˆ ๊ณ ์ •ํญ ๊ธ€์”จ), ํ๋ฆฟํ•œ ๋ณด์กฐ ์„ค๋ช…(์บก์…˜), ๋ถ€์ œ๋ชฉ ๊ฐ™์€ "๋ฌธ์„œํ˜• ๊ธ€"์„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.
  • ์–ด๋–ค ์„ ํƒ์ง€๊ฐ€ ์žˆ๋‚˜์š”: ๊ธ€์˜ ์—ญํ•  14๊ฐ€์ง€(๋ฌธ๋‹จ, ์ œ๋ชฉ 1~6๋‹จ๊ณ„, ์ธ์šฉ๋ฌธ, ์ฝ”๋“œ, ๋ผ๋ฒจ, ๊ฐ•์กฐ ๋“ฑ)์™€ ๋ชจ์–‘ ํ”„๋ฆฌ์…‹ 15๊ฐ€์ง€(์ œ๋ชฉ ํฌ๊ธฐ, ๊ตต๊ฒŒ, ๊ธฐ์šธ์ž„, ํ๋ฆฌ๊ฒŒ, ๋ง์ค„์ž„ ๋“ฑ)๋ฅผ ์กฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  • ์™œ ์ข‹์€๊ฐ€์š”: ์›น์—์„œ๋Š” ๊ฒ€์ƒ‰์—”์ง„๊ณผ ํ™”๋ฉด๋‚ญ๋…๊ธฐ(์‹œ๊ฐ์žฅ์• ์ธ ๋ณด์กฐ๊ธฐ๊ธฐ)๊ฐ€ ์ดํ•ดํ•˜๋Š” ์˜ฌ๋ฐ”๋ฅธ ๋ฌธ์„œ ๊ตฌ์กฐ(h1, p, blockquote ํƒœ๊ทธ)๋กœ ๋งŒ๋“ค์–ด์ง€๊ณ , ์•ฑ์—์„œ๋Š” ๊ฐ™์€ ํฌ๊ธฐยท์ƒ‰ ๊ทœ์น™์˜ ๊ธ€์ž๋กœ ๋งŒ๋“ค์–ด์ ธ ์–‘์ชฝ์ด ๋˜‘๊ฐ™์•„ ๋ณด์ž…๋‹ˆ๋‹ค.
  • ์–ธ์ œ ์“ฐ์ด๋‚˜์š”: ๋„์›€๋ง ํŽ˜์ด์ง€, ๋ธ”๋กœ๊ทธํ˜• ์ฝ˜ํ…์ธ , ์„ค์ • ํ™”๋ฉด์˜ ์„ค๋ช… ๋ฌธ๊ตฌ, ์•ฝ๊ด€์ฒ˜๋Ÿผ "์ฝ๋Š” ๊ธ€"์ด ํ•„์š”ํ•œ ํ™”๋ฉด ์–ด๋””์„œ๋‚˜ ์ด ์„ค๋ช…์„œ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ๋ฒ„ํŠผยท๋ฐฐ์ง€์™€ ๋‹ค๋ฅธ ์ : ๋ˆ„๋ฅด๋Š” ๋ถ€ํ’ˆ์ด ์•„๋‹ˆ๋ผ ์ฝ๋Š” ๊ธ€ ์ „์šฉ์ž…๋‹ˆ๋‹ค. ํฌ๊ธฐ(sm/md/lg)๋‚˜ ์ƒ‰์ƒ ๋ณ€ํ˜•(variant) ์„ ํƒ์ง€๊ฐ€ ๋”ฐ๋กœ ์—†๊ณ , ์—ญํ• ๊ณผ ํ”„๋ฆฌ์…‹์ด ๋ชจ์–‘์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์šฉ์–ด (๋น„๊ฐœ๋ฐœ์ž์šฉ)#

์šฉ์–ด์‰ฌ์šด ์„ค๋ช…
TextBlock๊ธ€์— ์—ญํ• ๋ณ„ ์Šคํƒ€์ผ ์˜ท์„ ์ž…ํ˜€ ๋ณด์—ฌ์ฃผ๋Š” ๊ธ€์ž ์ƒ์ž
element๊ธ€์˜ ์—ญํ•  ์„ ํƒ์ง€ (๋ฌธ๋‹จ p, ์ œ๋ชฉ h1~h6, ์ธ์šฉ๋ฌธ, ์ฝ”๋“œ ๋“ฑ 14๊ฐ€์ง€)
p / paragraph์ผ๋ฐ˜ ๋ณธ๋ฌธ ๋ฌธ๋‹จ
h1 ~ h6์ œ๋ชฉ ํฌ๊ธฐ 1๋‹จ๊ณ„(๊ฐ€์žฅ ํผ)๋ถ€ํ„ฐ 6๋‹จ๊ณ„(๊ฐ€์žฅ ์ž‘์Œ)๊นŒ์ง€
blockquote์ธ์šฉ๋ฌธ โ€” ์™ผ์ชฝ์— ์„ธ๋กœ ๊ฐ•์กฐ์„ ์ด ๋ถ™๋Š” ๋“ค์—ฌ์“ด ๊ธ€
pre / inline code์ฝ”๋“œ ์กฐ๊ฐ โ€” ํšŒ์ƒ‰ ์ƒ์ž ์•ˆ์— ๊ณ ์ •ํญ ๊ธ€์”จ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ์Šคํƒ€์ผ
preset๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘” ๋ชจ์–‘ ์„ธํŠธ (์ œ๋ชฉ์šฉ, ๊ตต๊ฒŒ, ํ๋ฆฌ๊ฒŒ, ๋ง์ค„์ž„ ๋“ฑ)
muted๋œ ์ค‘์š”ํ•œ ๋ณด์กฐ ์„ค๋ช…์šฉ ํ๋ฆฐ ํšŒ์ƒ‰ ๊ธ€์”จ
lead์ œ๋ชฉ ์•„๋ž˜์— ์˜ค๋Š” ํฐ ๋ถ€์ œ๋ชฉ(๋ฆฌ๋“œ ๋ฌธ์žฅ)
truncate์นธ์„ ๋„˜์น˜๋Š” ๊ธ€์„ "โ€ฆ"๋กœ ์ž˜๋ผ ํ•œ ์ค„๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ
children๊ธ€์ž ์ƒ์ž ์•ˆ์— ๋„ฃ๋Š” ์—ฌ๋Ÿฌ ์กฐ๊ฐ (์˜ˆ: ๋ฌธ์žฅ ์ค‘๊ฐ„์— ์ฝ”๋“œ ์กฐ๊ฐ ๋ผ์šฐ๊ธฐ)
textBlockStyle์ธ์šฉ๋ฌธ ์„ธ๋กœ์„  ๋‘๊ป˜ยท์ฝ”๋“œ ์ƒ์ž ์ƒ‰์ฒ˜๋Ÿผ ์ƒ์ž ์žฅ์‹๋งŒ ์‚ด์ง ๋ฐ”๊พธ๋Š” ์„ธ๋ถ€ ์„ค์ •
Flutter๋ชจ๋ฐ”์ผ/์•ฑ ํ™”๋ฉด์„ ๋งŒ๋“œ๋Š” ๊ธฐ์ˆ 
Web์›น ๋ธŒ๋ผ์šฐ์ €์šฉ ํ™”๋ฉด์„ ๋งŒ๋“œ๋Š” ๊ธฐ์ˆ 
Legacy / Deprecated์˜›๋‚  ๋ฐฉ์‹์ด๋ผ ์ƒˆ ์ฝ”๋“œ์—์„œ๋Š” ์“ฐ์ง€ ๋ง์•„์•ผ ํ•˜๋Š”, ๊ณง ์‚ฌ๋ผ์งˆ ํ•ญ๋ชฉ

Overview#

TextBlock is the unified cross-platform prose component for headings, paragraphs, blockquotes, inline/preformatted code, labels, and text utilities. One component takes a semantic element enum plus a list of typography presets; Web additionally binds each element to the matching semantic HTML tag so the document outline and screen readers stay correct.

  • Element: CoreTextBlockElement โ€” 14 values (p, span, h1โ€“h6, blockquote, pre, label, strong, em, small); default CoreTextBlockElement.defaultElement (= p).
  • Presets: platform-local TextBlockStyle values built through static helpers on TextBlock (TextBlock.paragraph, TextBlock.heading1(context), โ€ฆ). Same helper names on both platforms.
  • Chrome slot: textBlockStyle: CoreTextBlockStyle(...) โ€” Flutter-only constructor param that overrides the blockquote / pre box chrome (border, indent, fill, radius, padding). On Web the same CoreTextBlockStyle.default* constants are baked into the quote / inlineCode preset class strings.
  • No variant, no size: TextBlock has no CoreComponentSize and no variant enum โ€” the element + presets fully describe the appearance. There is also no CoreTextBlockTheme and no coreComponentTheme slot for it.

Note the two similarly named classes: TextBlockStyle (platform-local preset value โ€” wraps a TextStyle fragment on Flutter, a Tailwind class string on Web) vs CoreTextBlockStyle (shared coui_core chrome style for the blockquote/pre boxes).

Canonical API#

element โ€” CoreTextBlockElement (14 values, full set)#

Element Web tag Flutter base typography Element-level chrome (Flutter)
p (default) <p> bodyMedium โ€”
span <span> bodyMedium โ€”
h1<h1>displaySmallโ€”
h2 <h2> headlineLarge โ€”
h3 <h3> headlineSmall โ€”
h4<h4>titleLargeโ€”
h5<h5>titleMediumโ€”
h6<h6>titleSmallโ€”
blockquote <blockquote> bodyMedium left accent border ( onSurfaceVariant , stroke2 ) + space24 left indent
pre <pre> bodyMedium + mono surfaceContainer box, radius4 , space4 ร— space2 padding
label <label> labelLarge โ€”
strong <strong> bodyMedium + bold โ€”
em <em> bodyMedium + italic โ€”
small <small> bodySmall โ€”

On Flutter the element selects the base typography token (there is no document outline); on Web it selects the semantic HTML tag. The blockquote/pre chrome is drawn by the element on Flutter, but carried by the preset classes on Web โ€” so always pair the element with its matching preset (blockquote + TextBlock.quote, inline code span + TextBlock.inlineCode(context)) to stay visually identical across platforms.

presets โ€” List<TextBlockStyle>? (full set)#

Presets compose left-to-right; later presets win on conflicting fields (Flutter TextStyle.merge semantics; Web joins the class strings). Always construct them through the static helpers โ€” never instantiate TextBlockStyle directly.

Context-independent (usable in const lists):

PresetFlutter effectWeb classes
TextBlock.paragraph line height 28/16 (prose leading) leading-7
TextBlock.bold fontWeight: w700 font-{bold} token class
TextBlock.italicitalicitalic
TextBlock.quote italic (border comes from the element) border-l-{stroke2} + border-{onSurfaceVariant} + pl-{space24} + italic
TextBlock.truncate TextOverflow.ellipsis truncate
TextBlock.wrap no-op (naming parity โ€” Flutter already wraps/breaks) break-words

Context-dependent โ€” call with BuildContext:

PresetFlutter effectWeb classes
TextBlock.heading1(context) displaySmall scroll-m-{space80} text-{displaySmall} tracking-{tight}
TextBlock.heading2(context) headlineLarge same pattern with headlineLarge
TextBlock.heading3(context) headlineSmall same pattern with headlineSmall
TextBlock.heading4(context) titleLarge same pattern with titleLarge
TextBlock.lg(context) titleMedium text-{titleMedium}
TextBlock.sm(context) labelLarge + height: CoreLineHeight.h100 text-{labelLarge} leading-none
TextBlock.muted(context) bodySmall + onSurfaceVariant colour text-{bodySmall} text-{onSurfaceVariant}
TextBlock.lead(context) titleLarge + onSurfaceVariant colour text-{titleLarge} text-{onSurfaceVariant}
TextBlock.inlineCode(context) bodySmall + mono + w600 + surfaceContainer background rounded-{radius4} bg-{surfaceContainer} px/py padding, mono, semibold

muted / lead foregrounds and the quote / inlineCode chrome all route through CoreTextBlockStyle.default* token constants, so Flutter and Web resolve from the same source of truth (onSurfaceVariant, surfaceContainer).

textBlockStyle โ€” CoreTextBlockStyle? (Flutter-only chrome slot)#

Overrides the blockquote/pre box chrome per instance. Fields (all nullable): blockQuoteBorderColor (CoreColor?), blockQuoteBorderWidth (double?), blockQuotePadding (CoreEdgeInsets?), inlineCodeBackgroundColor (CoreColor?), inlineCodeRadius (double?), inlineCodePadding (CoreEdgeInsets?). It exposes merge / copyWith and the shared defaults as statics: defaultBlockQuoteBorderColor (onSurfaceVariant token), defaultBlockQuoteBorderWidth (CoreStrokeWidth.stroke2), defaultBlockQuotePadding (left-only space24), defaultInlineCodeBackgroundColor (surfaceContainer token), defaultInlineCodeRadius (CoreRadius.radius4), defaultInlineCodePadding (space4 ร— space2), defaultMutedForegroundColor (onSurfaceVariant token).

Resolve chain (Flutter resolveTextBlock): design-system default (CoreTextBlockStyle.default*) โ†’ widget.textBlockStyle. There is no theme layer โ€” unlike Badge/Button, TextBlock has no Core*Theme.

Shared contract parameters (CoreTextBlockContract<W>)#

ParameterType (Flutter)Type (Web)DefaultNotes
text String? String? null Plain text content; ignored when children is set
element CoreTextBlockElement CoreTextBlockElement defaultElement (= p) Semantic role / HTML tag
presets List<TextBlockStyle>? List<TextBlockStyle>? null Typography presets (platform-local value class)
children List<Widget>? List<Component>? null Rich-text content; when non-null, text is ignored
textBlockStyle CoreTextBlockStyle? โ€” (not a param) null Flutter-only blockquote/pre chrome override

Web-only: id, classes, css (Jaspr Styles), attributes, eventHandlers, plus copyWith(...).

Flutter (coui_flutter)#

Import#

import 'package:coui_flutter/coui_flutter.dart';

The barrel is the only supported import โ€” never import src/ paths. There is no Material name clash for TextBlock.

Basic usage#

TextBlock(text: 'Plain body text')                                   // p + bodyMedium
const TextBlock(text: 'Comfort prose', presets: [TextBlock.paragraph])
TextBlock(text: 'A muted caption', presets: [TextBlock.muted(context)])

Enum-shorthand (inferred type) is idiomatic in real code:

TextBlock(text: '์„น์…˜ ์ œ๋ชฉ', element: .h2, presets: [TextBlock.heading2(context)])

Headings and lead subtitle#

Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    TextBlock(
      text: 'Design tokens in practice',
      element: CoreTextBlockElement.h1,
      presets: [TextBlock.heading1(context)],
    ),
    TextBlock(
      text: 'A practical guide to CoUI typography.',
      presets: [TextBlock.lead(context)],
    ),
  ],
)

The heading preset carries the typography; the element keeps naming/parity with Web (on Flutter it also sets the same base style, so element-only headings work too).

Blockquote#

element: .blockquote draws the left accent border + space24 indent automatically; add the quote preset for the italic text to match Web:

TextBlock(
  text: 'Simplicity is the ultimate sophistication.',
  element: CoreTextBlockElement.blockquote,
  presets: const [TextBlock.quote],
)

Inline code and pre box#

Inline (span-level) code โ€” the preset paints the surface tint via TextStyle.backgroundColor:

TextBlock(
  text: 'coui_flutter',
  element: CoreTextBlockElement.span,
  presets: [TextBlock.inlineCode(context)],
)

Preformatted block โ€” element: .pre renders the mono base style inside a surfaceContainer box with radius4 corners:

const TextBlock(
  text: 'dart run build_runner build',
  element: CoreTextBlockElement.pre,
)

Rich text (children)#

When children is non-null, text is ignored and the resolved style flows down via DefaultTextStyle.merge. A single child renders directly; multiple children stack vertically in a Column (mainAxisSize: min, crossAxisAlignment: start) โ€” they are not inline spans:

TextBlock(
  presets: const [TextBlock.paragraph],
  children: const [
    Text('First stacked line.'),
    Text('Second stacked line.'),
  ],
)

For truly inline composition on Flutter, keep it to one child and compose inside it.

Per-instance chrome (textBlockStyle)#

Chrome micro-tweaks for the blockquote/pre boxes only โ€” typography stays with presets:

TextBlock(
  text: 'Callout quote',
  element: CoreTextBlockElement.blockquote,
  presets: const [TextBlock.quote],
  textBlockStyle: const CoreTextBlockStyle(
    blockQuoteBorderColor: CoreColor.token(CoreColors.primary),
    blockQuoteBorderWidth: CoreStrokeWidth.stroke4,
    blockQuotePadding: CoreEdgeInsets.only(left: CoreSpace.space16),
  ),
)
TextBlock(
  text: 'npm run dev',
  element: CoreTextBlockElement.pre,
  textBlockStyle: const CoreTextBlockStyle(
    inlineCodeRadius: CoreRadius.radius8,
    inlineCodePadding: CoreEdgeInsets.symmetric(
      horizontal: CoreSpace.space8,
      vertical: CoreSpace.space4,
    ),
  ),
)

Flutter-specific behavior notes#

  • TextBlock is a StatelessWidget implementing CoreTextBlockContract<Widget>; it renders a plain Text (or DefaultTextStyle.merge for children) โ€” no gesture handling, no focus, no animation.
  • Border width, paddings, and radius from the chrome are multiplied by the theme scaling factor; colours resolve through scheme.resolve(token).
  • TextBlock.wrap is a documented no-op on Flutter (soft-wrap is already the default); it exists for naming parity with Web's break-words.
  • resolveTextBlock(context, element: โ€ฆ, presets: โ€ฆ, textBlockStyle: โ€ฆ) returning ResolvedTextBlock is public if you need the paint-ready values (textStyle, blockquote border colour/width/padding, inline-code background/radius/padding).

Web (coui_web / Jaspr)#

Import#

import 'package:coui_web/coui_web.dart';

The barrel re-exports Jaspr (Component, Styles, dom helpers like div/span/text) and coui_core, so no separate Jaspr import is needed.

Basic usage#

Same params; children are Jaspr Components. The component renders the semantic HTML tag for the element (<p>, <h1>, <blockquote>, โ€ฆ):

TextBlock(text: 'Plain body text')                                    // <p>
TextBlock(
  text: 'Design tokens in practice',
  element: CoreTextBlockElement.h1,
  presets: [TextBlock.heading1(context)],
)
TextBlock(text: 'A muted caption', presets: [TextBlock.muted(context)])

Blockquote / inline code on Web#

On Web the box chrome lives in the preset class string (token-bound Tailwind classes), not in the element โ€” pass both:

TextBlock(
  text: 'Simplicity is the ultimate sophistication.',
  element: CoreTextBlockElement.blockquote,
  presets: [TextBlock.quote],
)
TextBlock(
  text: 'dart pub add coui_web',
  element: CoreTextBlockElement.span,
  presets: [TextBlock.inlineCode(context)],
)

Using element: .blockquote without the quote preset yields a semantically correct <blockquote> with no visual accent border.

Rich text (children โ€” inline flow)#

Children flow inline inside the semantic element (normal HTML document flow), which makes mixed prose natural:

TextBlock(
  element: CoreTextBlockElement.p,
  presets: const [TextBlock.paragraph],
  children: [
    text('Install with '),
    TextBlock(
      text: 'dart pub add coui_web',
      element: CoreTextBlockElement.span,
      presets: [TextBlock.inlineCode(context)],
    ),
    text(' and import the barrel.'),
  ],
)

Web-only constructor extras#

The Web constructor also accepts id, classes, css (Jaspr Styles), attributes, and eventHandlers. User classes are merged after the preset class string. The component also provides copyWith(...):

TextBlock(
  text: 'Installation',
  element: CoreTextBlockElement.h2,
  presets: [TextBlock.heading2(context)],
  id: 'installation',
  classes: 'mt-8',
)

There is no textBlockStyle param on Web โ€” chrome values come from the CoreTextBlockStyle.default* constants baked into the quote / inlineCode preset class strings; use classes for per-instance additions.

Document pattern#

div(
  [
    TextBlock(
      text: 'Getting started',
      element: CoreTextBlockElement.h1,
      presets: [TextBlock.heading1(context)],
    ),
    TextBlock(
      text: 'Everything you need to ship your first screen.',
      presets: [TextBlock.lead(context)],
    ),
    TextBlock(
      text: 'CoUI ships a single barrel per platform.',
      presets: const [TextBlock.paragraph],
    ),
    TextBlock(
      text: 'Read the docs before overriding tokens.',
      element: CoreTextBlockElement.blockquote,
      presets: [TextBlock.quote],
    ),
  ],
  classes: 'flex flex-col gap-4',
)

Flutter โ†” Web Differences#

AspectFlutterWeb
Component class TextBlock (StatelessWidget, CoreTextBlockContract<Widget>) TextBlock (UiComponent, CoreTextBlockContract<Component>)
children type List<Widget>? List<Component>?
Render Text / DefaultTextStyle.merge (+ DecoratedBox for blockquote/pre) Semantic HTML tag ( <p> , <h1> โ€ฆ <h6> , <blockquote> , <pre> , โ€ฆ)
TextBlockStyle payload TextStyle fragment, merged in order (later wins) Tailwind class string, joined in order
blockquote / pre chrome Drawn automatically by the element switch Carried by the quote / inlineCode preset classes
Multiple children layout Vertical Column (start-aligned) Normal inline / document flow
textBlockStyle param Yes โ€” CoreTextBlockStyle? per-instance chrome override No โ€” use classes; defaults are baked into preset class strings
Extra ctor params โ€” id , classes , css , attributes , eventHandlers ; also copyWith(...)
Element semantics Typography token selection only (no outline) Real document outline + screen-reader semantics

v0.127 Migration (Legacy)#

v0.127 is a de-prefix hard break: the component class was renamed and no Co-prefixed alias remains. Core* contract names (CoreTextBlockElement, CoreTextBlockStyle, CoreTextBlockContract) are unchanged โ€” do not confuse the removed platform preset class with the current Core chrome style.

โŒ Legacy (pre-0.127, removed)โœ… v0.127
โŒ CoTextBlock(text: โ€ฆ)TextBlock(text: โ€ฆ)
โŒ CoTextBlock.heading1(context) / CoTextBlock.muted(context) (preset helpers) TextBlock.heading1(context) / TextBlock.muted(context)
โŒ CoTextBlockStyle(โ€ฆ) (platform preset value class) TextBlockStyle(โ€ฆ) โ€” but always build via the TextBlock.* static helpers

Additional migration notes:

  • โŒ The Web TextBlockStyling marker interface was removed (Phase 6g "Styling marker sweep") โ€” a preset is now a plain immutable TextBlockStyle value holding the resolved class string; the component joins them into the root element's className.
  • The shared chrome class CoreTextBlockStyle (Core-prefixed) is current API, not legacy โ€” only the bare-platform Co-prefixed names were removed.
  • Import stays the single barrel (package:coui_flutter/coui_flutter.dart / package:coui_web/coui_web.dart); per-component src/ imports remain forbidden.