LogoSkills

resources-agent

UI component, theme, and extension method generation specialist. Used for CoUI customization and common widget implementation

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/shared:resources
Aliases/ui:theme, /widget:create
ToolsRead, Edit, Write, Glob, Grep
Modelsonnet
Skillsflutter-ui

/shared:resources โ€” ํ™”๋ฉด ๊ณตํ†ต๋ถ€ํ’ˆยท๋””์ž์ธ ๋‹ด๋‹น#

UI ๋ถ€ํ’ˆ, ํ…Œ๋งˆ(์ƒ‰ยท๊ธ€๊ผด), ๊ณตํ†ต ์œ„์ ฏ์„ ๋งŒ๋“ค๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ์ „๋ฌธ ์—์ด์ „ํŠธ

ํ•œ๋งˆ๋””๋กœ#

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

๋ˆ„๊ฐ€ยท์–ธ์ œ ์“ฐ๋‚˜์š”#

  • ์•ฑ์˜ ์ƒ‰์ƒยท๊ธ€๊ผดยท์ „์ฒด ํ…Œ๋งˆ(๋ฐ์€ ๋ชจ๋“œ / ์–ด๋‘์šด ๋ชจ๋“œ)๋ฅผ ์ •ํ•˜๊ฑฐ๋‚˜ ๋ฐ”๊ฟ€ ๋•Œ
  • ์—ฌ๋Ÿฌ ํ™”๋ฉด์—์„œ ๋ฐ˜๋ณตํ•ด์„œ ์“ฐ๋Š” ๊ณตํ†ต ์œ„์ ฏ(๋ฐฐ๋„ˆ, ์นด๋“œ, ํŒ์—…์ฐฝ, ํ‘œ ๋“ฑ)์ด ํ•„์š”ํ•  ๋•Œ
  • CoUI ๋””์ž์ธ ์‹œ์Šคํ…œ์˜ ๋ฒ„ํŠผยท๋ฑƒ์ง€ ๊ฐ™์€ ๋ถ€ํ’ˆ์„ ์šฐ๋ฆฌ ์•ฑ์— ๋งž๊ฒŒ ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆํ•  ๋•Œ
  • /shared:resources ๋ช…๋ น์„ ๋ถ€๋ฅด๋ฉด ์ด ๋‹ด๋‹น์ž๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. (/ui:theme, /widget:create ๋กœ๋„ ํ˜ธ์ถœ ๊ฐ€๋Šฅ)

๋ฌด์—‡์„ ํ•ด์ฃผ๋‚˜์š”#

package/resources ํŒจํ‚ค์ง€ ์•ˆ์— ๊ณตํ†ต ์ž์›์„ ๋งŒ๋“ค์–ด ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ๋“ค:

  • AppTheme โ€” ์•ฑ์˜ ๋ฐ์€ ๋ชจ๋“œ / ์–ด๋‘์šด ๋ชจ๋“œ ํ…Œ๋งˆ (app_theme.dart)
  • ์ƒ‰์ƒยท๊ธ€๊ผด ์ •์˜ โ€” ์ƒ‰์ƒํ‘œ(app_color_scheme.dart)์™€ Pretendard ๊ธ€๊ผด ๊ธฐ๋ฐ˜ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ(app_typography.dart)
  • ๊ณตํ†ต ์œ„์ ฏ โ€” ํ‘œ(table_builder.dart), ํ™•์ธ ํŒ์—…(confirm_dialog.dart), ๋ฐฐ๋„ˆยท์นด๋“œ ๋“ฑ
  • ํŽธ์˜ ๋‹จ์ถ• ์ฝ”๋“œ โ€” ํ™”๋ฉด ์–ด๋””์„œ๋“  ํ…Œ๋งˆยท์ƒ‰ยท๊ธ€๊ผด์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•˜๊ฒŒ ํ•ด ์ฃผ๋Š” BuildContext ํ™•์žฅ ๋ฉ”์„œ๋“œ
  • ์ปค์Šคํ…€ SVG ์•„์ด์ฝ˜ โ€” Figma์—์„œ exportํ•œ, CoUI ํ‘œ์ค€ ์•„์ด์ฝ˜(Lucide)์— ์—†๋Š” ๋ธŒ๋žœ๋“œ/์ปค์Šคํ…€ ์•„์ด์ฝ˜์„ assets/svg/์— ๋ณด๊ด€ํ•˜๊ณ  flutter_gen์œผ๋กœ ํƒ€์ž… ์„ธ์ดํ”„ํ•˜๊ฒŒ ์ ‘๊ทผ (Assets.svg.xxx)

์–ด๋–ป๊ฒŒ ์“ฐ๋‚˜์š”#

# ํ…Œ๋งˆ(์ƒ‰ยท๊ธ€๊ผด) ๋งŒ๋“ค๊ธฐ
/shared:resources component_type=theme component_name=AppTheme

# ๊ณตํ†ต ์œ„์ ฏ ๋งŒ๋“ค๊ธฐ (์˜ˆ: ํ‘œ ๋ถ€ํ’ˆ)
/shared:resources component_type=widget component_name=TableBuilder category=table

# ํŽธ์˜ ๋‹จ์ถ• ์ฝ”๋“œ(ํ™•์žฅ ๋ฉ”์„œ๋“œ) ๋งŒ๋“ค๊ธฐ
/shared:resources component_type=extension component_name=ThemeContext
  • component_type (ํ•„์ˆ˜): theme(ํ…Œ๋งˆ) / widget(๊ณตํ†ต ์œ„์ ฏ) / extension(ํ™•์žฅ ๋ฉ”์„œ๋“œ) ์ค‘ ํ•˜๋‚˜
  • component_name (ํ•„์ˆ˜): ๋งŒ๋“ค ๋ถ€ํ’ˆ ์ด๋ฆ„ (PascalCase, ์˜ˆ: TableBuilder)
  • category (์„ ํƒ): ์œ„์ ฏ ์ข…๋ฅ˜ โ€” banner, card, dialog, table ๋“ฑ

์•ˆ์—์„œ ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๋‚˜์š”#

์š”์ฒญํ•œ ๋ถ€ํ’ˆ ์ข…๋ฅ˜์— ๋งž์ถฐ ์ •ํ•ด์ง„ ํŒจํ„ด๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๊ณ , ๋งˆ์ง€๋ง‰์— ๋น ์ง„ ๊ฒŒ ์—†๋Š”์ง€ ์ ๊ฒ€ํ•ฉ๋‹ˆ๋‹ค.

  1. ํ…Œ๋งˆ ๋งŒ๋“ค๊ธฐ โ€” ๋ฐ์€/์–ด๋‘์šด ๋ชจ๋“œ ์ƒ‰์ƒํ‘œ๋ฅผ ์ƒ์ˆ˜๋กœ ์ •์˜ํ•˜๊ณ , Pretendard ๊ธ€๊ผด์„ ์ž…ํžŒ ๋’ค, ๋‘˜์„ ๋ฌถ์–ด ์•ฑ ์ „์ฒด ํ…Œ๋งˆ(AppTheme)๋กœ ์™„์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ณตํ†ต ์œ„์ ฏ ๋งŒ๋“ค๊ธฐ โ€” ํ‘œยทํŒ์—…์ฐฝ ๊ฐ™์€ ์žฌ์‚ฌ์šฉ ๋ถ€ํ’ˆ์„ ์ •ํ•ด์ง„ ๊ตฌ์กฐ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. (์˜ˆ: ์ •๋ ฌยท์ปฌ๋Ÿผ ํฌ๊ธฐ์กฐ์ ˆยท์ˆœ์„œ๋ณ€๊ฒฝ์ด ๋˜๋Š” ๋ฒ”์šฉ ํ‘œ)
  3. ํŽธ์˜ ๋‹จ์ถ• ์ฝ”๋“œ ๋งŒ๋“ค๊ธฐ โ€” ํ™”๋ฉด ์ฝ”๋“œ์—์„œ context.colorScheme์ฒ˜๋Ÿผ ์งง๊ฒŒ ํ…Œ๋งˆยท์ƒ‰ยท๊ธ€๊ผด์— ์ ‘๊ทผํ•˜๋„๋ก ํ™•์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  4. CoUI ํ‘œ์ค€ ํ™•์ธ โ€” ๋ฒ„ํŠผยท๋ฑƒ์ง€ยท์•„์ด์ฝ˜ ๊ฐ™์€ ๋ถ€ํ’ˆ์€ CoUI์˜ ์ตœ์‹  ํ‘œ์ค€ ๋ฐฉ์‹(CoButton(variant: ...) ๋“ฑ)์— ๋งž๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  5. ๋งˆ๋ฌด๋ฆฌ ์ ๊ฒ€ โ€” ๋ฐ์€/์–ด๋‘์šด ํ…Œ๋งˆ๊ฐ€ ๋ชจ๋‘ ์ •์˜๋๋Š”์ง€, ์ฃผ์„์ด ๋‹ฌ๋ ธ๋Š”์ง€ ๋“ฑ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋กœ ๋น ์ง„ ๋ถ€๋ถ„์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

โš™๏ธ ์ƒ์„ธ ์˜ต์…˜ยท์‹คํ–‰ ๋ช…์„ธ (๊ฐœ๋ฐœ์ž / AI ์—์ด์ „ํŠธ์šฉ)

Role#

Creates and manages UI elements in the Resources package.

  • AppTheme (Light/Dark mode)
  • CoUI Flutter component customization
  • Common widgets (Banner, Card, Dialog, Table)
  • BuildContext extension methods

Activation Conditions#

  • /shared:resources Activated when command is invoked
  • Invoked during UI component, theme, and extension method work

Parameters#

ParameterRequiredDescription
component_typeโœ…theme, widget, extension
component_nameโœ…Component name (PascalCase)
categoryโŒWidget category (banner, card, dialog, table etc.)

Package Structure#

package/resources/
โ”œโ”€โ”€ assets/
โ”‚   โ””โ”€โ”€ svg/                          # ์ปค์Šคํ…€/๋ธŒ๋žœ๋“œ SVG ์•„์ด์ฝ˜ ์›๋ณธ (Lucide์— ์—†๋Š” ๊ฒƒ๋งŒ)
โ”‚       โ”œโ”€โ”€ action_bell.svg
โ”‚       โ””โ”€โ”€ bottom_navi_home_off.svg
โ”œโ”€โ”€ pubspec.yaml                       # flutter_gen_runner + flutter_gen ์„ค์ •
โ””โ”€โ”€ lib/
    โ”œโ”€โ”€ resources.dart                # Export ํŒŒ์ผ
    โ””โ”€โ”€ src/
        โ”œโ”€โ”€ core/
        โ”‚   โ”œโ”€โ”€ extensions/           # BuildContext ํ™•์žฅ
        โ”‚   โ”‚   โ””โ”€โ”€ theme_context_extension.dart
        โ”‚   โ”œโ”€โ”€ locale/               # ๋กœ์ผ€์ผ ์œ ํ‹ธ๋ฆฌํ‹ฐ
        โ”‚   โ”œโ”€โ”€ size/                 # ์‚ฌ์ด์ฆˆ ์ƒ์ˆ˜
        โ”‚   โ”œโ”€โ”€ theme/                # ํ…Œ๋งˆ ์ •์˜
        โ”‚   โ”‚   โ”œโ”€โ”€ app_theme.dart
        โ”‚   โ”‚   โ”œโ”€โ”€ app_color_scheme.dart
        โ”‚   โ”‚   โ”œโ”€โ”€ app_typography.dart
        โ”‚   โ”‚   โ””โ”€โ”€ app_component_theme.dart
        โ”‚   โ”œโ”€โ”€ util/                 # ์œ ํ‹ธ๋ฆฌํ‹ฐ
        โ”‚   โ””โ”€โ”€ generated/
        โ”‚       โ””โ”€โ”€ assets.gen.dart   # flutter_gen ์ž๋™ ์ƒ์„ฑ โ†’ Assets.svg.xxx
        โ””โ”€โ”€ widgets/                  # ๊ณตํ†ต ์œ„์ ฏ
            โ”œโ”€โ”€ banner/
            โ”œโ”€โ”€ card/
            โ”œโ”€โ”€ console/
            โ”œโ”€โ”€ dialog/
            โ”œโ”€โ”€ navigation/
            โ””โ”€โ”€ table/

Custom SVG Icon Workflow#

CoUI's CoIcon(CoLucideIcons.x) covers the standard icon set. When a Figma design uses a brand/custom icon with no Lucide equivalent:

  1. Export the icon from Figma as SVG
  2. Add it to package/resources/assets/svg/ (check assets.gen.dart first โ€” don't duplicate an existing entry)
  3. Regenerate: melos run generate:assets (re-runs flutter_gen_runner)
  4. Reference via the generated accessor: Assets.svg.iconBestseller.svg(width: 24, height: 24)

Never hardcode an SvgPicture.asset('assets/svg/...') path directly โ€” always go through the generated Assets.svg.* accessor so renames/moves are caught at compile time.


Import Order (Required)#

// 1. Flutter standard
import 'package:flutter/material.dart';

// 2. CoUI Flutter
import 'package:coui_flutter/coui_flutter.dart';

// 3. ๋‚ด๋ถ€ ๋ชจ๋“ˆ
import '../theme/app_color_scheme.dart';
import '../theme/app_typography.dart';

Core Patterns#

1. AppTheme Definition#

import 'package:coui_flutter/coui_flutter.dart';
import 'package:flutter/material.dart';

import 'app_color_scheme.dart';
import 'app_component_theme.dart';
import 'app_typography.dart';

/// ์•ฑ ํ…Œ๋งˆ ์ •์˜
///
/// CoUI์˜ [ThemeData]๋ฅผ ํ™•์žฅํ•˜์—ฌ Light/Dark ๋ชจ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
abstract final class AppTheme {
  /// default ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ” ๋†’์ด
  static const double defaultNavBarHeight = 60;

  // ============ Light Theme ============
  static const ColorScheme _lightColorScheme = AppColorScheme.light;
  static const Typography _lightTypography = AppTypography.pretendard;

  /// Light ํ…Œ๋งˆ
  static ThemeData get light => ThemeData.new(
        colorScheme: _lightColorScheme,
        componentTheme: AppComponentTheme.from(
          colorScheme: _lightColorScheme,
          typography: _lightTypography,
        ),
        typography: _lightTypography,
      );

  // ============ Dark Theme ============
  static const ColorScheme _darkColorScheme = AppColorScheme.dark;
  static const Typography _darkTypography = AppTypography.pretendard;

  /// Dark ํ…Œ๋งˆ
  static ThemeData get dark => ThemeData.new(
        colorScheme: _darkColorScheme,
        componentTheme: AppComponentTheme.from(
          colorScheme: _darkColorScheme,
          typography: _darkTypography,
        ),
        typography: _darkTypography,
      );
}

2. ColorScheme Definition#

import 'package:coui_flutter/coui_flutter.dart';

/// ์•ฑ ์ƒ‰์ƒ ์Šคํ‚ด ์ •์˜
abstract final class AppColorScheme {
  /// Light ๋ชจ๋“œ ์ƒ‰์ƒ ์Šคํ‚ด
  static const ColorScheme light = ColorScheme(
    brightness: Brightness.light,
    primary: Color(0xFF1976D2),
    onPrimary: Color(0xFFFFFFFF),
    secondary: Color(0xFF03DAC6),
    onSecondary: Color(0xFF000000),
    error: Color(0xFFB00020),
    onError: Color(0xFFFFFFFF),
    surface: Color(0xFFFFFFFF),
    onSurface: Color(0xFF000000),
    // ... ์ถ”๊ฐ€ ์ƒ‰์ƒ
  );

  /// Dark ๋ชจ๋“œ ์ƒ‰์ƒ ์Šคํ‚ด
  static const ColorScheme dark = ColorScheme(
    brightness: Brightness.dark,
    primary: Color(0xFF90CAF9),
    onPrimary: Color(0xFF000000),
    // ... ์ถ”๊ฐ€ ์ƒ‰์ƒ
  );
}

3. Typography Definition#

import 'package:coui_flutter/coui_flutter.dart';
import 'package:flutter/material.dart' as material;

/// ์•ฑ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์ •์˜
abstract final class AppTypography {
  /// Pretendard ํฐํŠธ ๊ธฐ๋ฐ˜ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ
  static const Typography pretendard = Typography(
    fontFamily: 'Pretendard',
    displayLarge: material.TextStyle(
      fontSize: 57,
      fontWeight: material.FontWeight.w400,
      letterSpacing: -0.25,
    ),
    displayMedium: material.TextStyle(
      fontSize: 45,
      fontWeight: material.FontWeight.w400,
    ),
    // ... ์ถ”๊ฐ€ ์Šคํƒ€์ผ
  );
}

4. BuildContext Extension Methods#

import 'package:coui_flutter/coui_flutter.dart';
import 'package:flutter/material.dart';

/// Resources ํ…Œ๋งˆ ํ™•์žฅ
extension ResourcesThemeContextExtension on BuildContext {
  /// ComponentThemeData ์ ‘๊ทผ
  ComponentThemeData? get componentTheme => Theme.of(this).componentTheme;

  /// ColorScheme ์ ‘๊ทผ
  ColorScheme get colorScheme => Theme.of(this).colorScheme;

  /// Typography ์ ‘๊ทผ
  Typography get typography => Theme.of(this).typography;

  /// TextTheme ์ ‘๊ทผ
  TextTheme get textTheme => Theme.of(this).textTheme;
}

5. Common Widget Pattern (TableBuilder)#

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

/// ๋ฒ”์šฉ ํ…Œ์ด๋ธ” ๋นŒ๋”
///
/// ์ •๋ ฌ, ์ปฌ๋Ÿผ ๋ฆฌ์‚ฌ์ด์ฆˆ, ๋ฆฌ์˜ค๋”, ๊ฐ€์‹œ์„ฑ ์ œ์–ด ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
class TableBuilder<T, TSortField> extends HookWidget {
  /// TableBuilder ์ƒ์„ฑ์ž
  const TableBuilder({
    required this.items,
    required this.columns,
    this.isLoading = false,
    this.sortState,
    this.onSortChanged,
    this.enableColumnResize = false,
    this.enableColumnReorder = false,
    this.visibilityController,
    this.onRowTap,
    this.rowHeight,
    this.headerHeight,
    super.key,
  });

  /// ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ ํ•ญ๋ชฉ
  final List<T> items;

  /// ์ปฌ๋Ÿผ ์ •์˜
  final List<TableColumnDef<T, TSortField>> columns;

  /// ๋กœ๋”ฉ ์ƒํƒœ
  final bool isLoading;

  /// ์ •๋ ฌ ์ƒํƒœ
  final SortState<TSortField>? sortState;

  /// ์ •๋ ฌ ๋ณ€๊ฒฝ ์ฝœ๋ฐฑ
  final ValueChanged<SortState<TSortField>>? onSortChanged;

  /// ์ปฌ๋Ÿผ ๋ฆฌ์‚ฌ์ด์ฆˆ ํ™œ์„ฑํ™”
  final bool enableColumnResize;

  /// ์ปฌ๋Ÿผ ๋ฆฌ์˜ค๋” ํ™œ์„ฑํ™”
  final bool enableColumnReorder;

  /// ๊ฐ€์‹œ์„ฑ ์ปจํŠธ๋กค๋Ÿฌ
  final ColumnVisibilityController? visibilityController;

  /// ํ–‰ ํƒญ ์ฝœ๋ฐฑ
  final ValueChanged<T>? onRowTap;

  /// ํ–‰ ๋†’์ด
  final double? rowHeight;

  /// ํ—ค๋” ๋†’์ด
  final double? headerHeight;

  @override
  Widget build(BuildContext context) {
    // ํ…Œ์ด๋ธ” ๊ตฌํ˜„...
  }
}

/// ํ…Œ์ด๋ธ” ์ปฌ๋Ÿผ ์ •์˜
class TableColumnDef<T, TSortField> {
  const TableColumnDef({
    required this.id,
    required this.title,
    required this.cellBuilder,
    this.width,
    this.minWidth,
    this.maxWidth,
    this.sortField,
    this.isVisible = true,
  });

  final String id;
  final String title;
  final Widget Function(T item) cellBuilder;
  final double? width;
  final double? minWidth;
  final double? maxWidth;
  final TSortField? sortField;
  final bool isVisible;
}

6. Dialog Pattern#

import 'package:flutter/material.dart';

/// Show confirmation dialog
Future<bool?> showConfirmDialog(
  BuildContext context, {
  required String title,
  required String message,
  String? confirmText,
  String? cancelText,
}) {
  return showDialog<bool>(
    context: context,
    builder: (context) => AlertDialog(
      title: Text(title),
      content: Text(message),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context, false),
          child: Text(cancelText ?? '์ทจ์†Œ'),
        ),
        TextButton(
          onPressed: () => Navigator.pop(context, true),
          child: Text(confirmText ?? 'ํ™•์ธ'),
        ),
      ],
    ),
  );
}

CoUI Co Component Standard#

๊ธฐ์ค€: coui v0.97.15 (latest). kobic vendored๋Š” v0.92.0์ด๋ผ gap/input ๋“ฑ ์ผ๋ถ€ API๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ.

CoUI exposes a single unified Co<X> widget per component. Style is selected via the variant: / size: enums; per-instance chrome overrides flow through one Core<X>Style object (buttonStyle / badgeStyle / inputStyle / iconStyle). There are no Button.primary() / PrimaryBadge / Gap.s4() / FormTextField / HeroIcon APIs.

ComponentWidgetVariant enumRemoved
ButtonCoButton(variant: ...)CoreButtonVariantButton.primary(), ButtonStyle.ghost()
BadgeCoBadge(variant: ...)CoreBadgeVariantPrimaryBadge, DestructiveBadge
IconCoIcon(CoLucideIcons.x)โ€”HeroIcon(HeroIcons.x)
InputCoInput(type: ...) / CoTextField (labelled)CoreInputVariantFormTextField, InputFeature.*
GapCoGap.spaceN() / CoGap(gapStyle: CoreGapStyle(...))โ€”Gap.s*, Spacing.s*, Insets.*, CoGap(size: CoreSpace.spaceN) (v0.92)

Shared size enum CoreComponentSize: xs ยท sm ยท md ยท lg ยท xl. Spacing tokens CoreSpace.spaceN โ€” the token name equals its pixel value. Typography via context.textStyles.<size><weight> (e.g. lgSemibold).

ComponentTheme Extension (CoreTheme / CoreStyle)#

Project-wide component defaults are configured through the CoUI CoreComponentTheme (passed to Theme/ThemeData as coreComponentTheme). Each per-component slot (button, icon, gap, badge, โ€ฆ) carries a Core<X>Theme whose style is a Core<X>Style.

import 'package:coui_flutter/coui_flutter.dart';

/// ์•ฑ ์ปดํฌ๋„ŒํŠธ ํ…Œ๋งˆ (CoUI CoreComponentTheme ๊ธฐ๋ฐ˜)
abstract final class AppComponentTheme {
  /// ColorScheme๊ณผ Typography๋กœ CoreComponentTheme ์ƒ์„ฑ
  static CoreComponentTheme from({
    required ColorScheme colorScheme,
    required Typography typography,
  }) {
    return CoreComponentTheme(
      // ๋ฒ„ํŠผ ๊ธฐ๋ณธ chrome (variant ๋ณ„ override ๋Š” variantStyles)
      button: CoreButtonTheme(
        style: CoreButtonStyle(
          textStyle: typography.smSemibold,
        ),
      ),
      // ์•„์ด์ฝ˜ ๊ธฐ๋ณธ ํฌ๊ธฐ/์ƒ‰
      icon: CoreIconTheme(
        style: CoreIconStyle(
          size: 24,
          color: colorScheme.onSurface.toValue(),
        ),
      ),
      // ๊ฐ„๊ฒฉ ํ† ํฐ ๊ธฐ๋ณธ๊ฐ’ (CoreGapTheme ์€ style: CoreGapStyle(size:) ์‚ฌ์šฉ)
      gap: const CoreGapTheme(style: CoreGapStyle(size: CoreSpace.space4)),
      // ... ์ถ”๊ฐ€ ์Šฌ๋กฏ: badge / card / dialog / input ...
    );
  }
}

Slot field names (button, icon, gap, badge, โ€ฆ) and Core<X>Style fields are authoritative in package/coui/packages/coui_core/lib/src/component/core_component_theme.dart and the per-component contracts (.../contracts/<component>/<component>_theme.dart). Verify against those before applying.


Reference Files#

package/resources/lib/src/core/theme/app_theme.dart
package/resources/lib/src/core/extensions/theme_context_extension.dart
package/resources/lib/src/widgets/table/table_builder.dart
package/resources/lib/src/widgets/dialog/confirm_dialog.dart

Checklist#

  • CoUI Package import Verify
  • Light/Dark Both themes Definition
  • Define ColorScheme as constants
  • Apply Pretendard font for Typography
  • Implement BuildContext extension methods
  • Write KDoc comments on widgets
  • Place super.key as last parameter
  • Specify Type parameters when using Generic Types
  • Custom icon: verify no existing Assets.svg.* entry before adding a new SVG file
  • Custom icon: ran melos run generate:assets after adding/removing an SVG under assets/svg/