LogoSkills

flutter-ui

Convert Figma designs to Flutter UI components (CoUI design system)

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/flutter:ui
Aliases/ui, /21, /coui
Categorykobic-development
Complexitymoderate
MCP Serversmagic, figma, serena

/flutter:ui โ€” ํ”ผ๊ทธ๋งˆ ๋””์ž์ธ์„ ํ™”๋ฉด ์ฝ”๋“œ๋กœ#

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

๋””์ž์ด๋„ˆ๊ฐ€ ๊ทธ๋ฆฐ ํ”ผ๊ทธ๋งˆ ๋””์ž์ธ์„ ๋ณด๊ณ , ๊ทธ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š” ์•ฑ ํ™”๋ฉด ์ฝ”๋“œ(Flutter)๋กœ ์˜ฎ๊ฒจ์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๋„๋ฉด(ํ”ผ๊ทธ๋งˆ)์„ ๊ฑด๋„ค๋ฉด ์šฐ๋ฆฌ ํšŒ์‚ฌ ํ‘œ์ค€ ๋ถ€ํ’ˆ(CoUI)์œผ๋กœ ์‹ค์ œ ํ™”๋ฉด์„ ์กฐ๋ฆฝํ•ด ์ฃผ๋Š” ์…ˆ์ด์—์š”.

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

  • ๋””์ž์ด๋„ˆ๊ฐ€ ๋งŒ๋“  ํ”ผ๊ทธ๋งˆ ํ™”๋ฉดยท์ปดํฌ๋„ŒํŠธ๋ฅผ ์‹ค์ œ ์•ฑ ํ™”๋ฉด์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•  ๋•Œ
  • ์šฐ๋ฆฌ ํšŒ์‚ฌ ๋””์ž์ธ ์‹œ์Šคํ…œ(CoUI)์— ๋งž์ถฐ ๋ฒ„ํŠผยท์นด๋“œยท์ž…๋ ฅ์ฐฝ ๊ฐ™์€ UI๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค ๋•Œ
  • ๋น ๋ฅด๊ฒŒ /ui, /21, /coui ๊ฐ™์€ ์งง์€ ๋ณ„์นญ์œผ๋กœ ํ˜ธ์ถœํ•˜๊ณ  ์‹ถ์„ ๋•Œ

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

  • ํ”ผ๊ทธ๋งˆ ํ™”๋ฉด์„ ๋ถ„์„ํ•ด ์šฐ๋ฆฌ ํ‘œ์ค€ ๋ถ€ํ’ˆ(CoUI ์œ„์ ฏ)์œผ๋กœ ๋ฐ”๊พผ ํ™”๋ฉด ์ฝ”๋“œ(Widget ํŒŒ์ผ) ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.
  • ์ƒ‰์ƒยท๊ธ€์žยท๊ฐ„๊ฒฉ์„ ์ž„์˜๋กœ ์ •ํ•˜์ง€ ์•Š๊ณ  ํšŒ์‚ฌ ๋””์ž์ธ ํ† ํฐ(์ •ํ•ด์ง„ ์ƒ‰ยท๊ธ€๊ผดยท์—ฌ๋ฐฑ ๊ทœ์น™)์— ๋งž์ถฅ๋‹ˆ๋‹ค.
  • ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•ด๋‹น ๊ธฐ๋Šฅ ํด๋”์— ๋ฐฐ์น˜ํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ ์นดํƒˆ๋กœ๊ทธ(Widgetbook UseCase) ์™€ ํ…Œ์ŠคํŠธ ํŒŒ์ผ๊นŒ์ง€ ํ•จ๊ป˜ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

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

# ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ
/flutter-ui button --name SubmitButton --feature common

# ํ”ผ๊ทธ๋งˆ ์นด๋“œ ๋””์ž์ธ์„ ๋ณ€ํ™˜ํ•˜๊ธฐ (--figma-node ๋กœ ํ”ผ๊ทธ๋งˆ ๋…ธ๋“œ ์ง€์ •)
/flutter-ui card --figma-node 12:345 --name ProductCard --feature store

# ํ™”๋ฉด ์ „์ฒด๋ฅผ ๋ณ€ํ™˜ํ•˜๊ธฐ
/flutter-ui page --figma-node 1:100 --name HomePage --feature home
  • component_type(ํ•„์ˆ˜): ๋งŒ๋“ค ์ข…๋ฅ˜ โ€” button, card, form, page ๋“ฑ
  • --figma-node: ๋ณ€ํ™˜ํ•  ํ”ผ๊ทธ๋งˆ ๋…ธ๋“œ ID (์˜ˆ: 12:345)
  • --name: ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„ (์˜ˆ: ProductCard)
  • --feature: ์–ด๋А ๊ธฐ๋Šฅ ๋ชจ๋“ˆ์— ๋„ฃ์„์ง€ (์˜ˆ: home, store)

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

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

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

Triggers#

  • When converting Figma frames/components to Flutter
  • CoUI design system based UI development
  • When using /ui, /21 keywords

Context Trigger Pattern#

/flutter-ui {component_type} [--options]

Parameters#

ParameterRequiredDescriptionExample
component_typeโœ…Component typebutton, card, form, page
--figma-nodeโŒFigma node ID12:345
--nameโŒComponent nameProductCard
--featureโŒFeature modulehome, store

Execution Flow#

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  1. Figma ๋…ธ๋“œ ๋ถ„์„ (MCP: figma)           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ€ข get_selection / get_node_info        โ”‚
โ”‚  โ€ข extract_tailwind                     โ”‚
โ”‚  โ€ข scan_text_nodes                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚
                    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  2. CoUI ์ปดํฌ๋„ŒํŠธ ๋งคํ•‘                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ€ข Figma ํด๋ž˜์Šค โ†’ CoUI ์œ„์ ฏ (Co < X > )      โ”‚
โ”‚  โ€ข ์ƒ‰์ƒ ๋ณ€์ˆ˜ โ†’ appColors / colorScheme  โ”‚
โ”‚  โ€ข ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ โ†’ context.textStyles    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚
                    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  3. Flutter ์ฝ”๋“œ ์ƒ์„ฑ (MCP: magic)       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ€ข 21st_magic_component_builder         โ”‚
โ”‚  โ€ข Widget ๊ตฌ์กฐ ์ƒ์„ฑ                      โ”‚
โ”‚  โ€ข ๋ฐ˜์‘ํ˜• ๋ ˆ์ด์•„์›ƒ ์ ์šฉ                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚
                    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  4. ํ”„๋กœ์ ํŠธ ํ†ตํ•ฉ                         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ€ข Feature ์œ„์ ฏ ๋””๋ ‰ํ† ๋ฆฌ์— ๋ฐฐ์น˜           โ”‚
โ”‚  โ€ข Generate Widgetbook UseCase              โ”‚
โ”‚  โ€ข ํ…Œ์ŠคํŠธ ํŒŒ์ผ ์ƒ์„ฑ                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

CoUI Design System#

Color Mapping#

// Figma Variable โ†’ Flutter (context.theme.colorScheme / context.appColors)
base-100     โ†’ colorScheme.base100
base-200     โ†’ colorScheme.base200
base-300     โ†’ colorScheme.base300
primary      โ†’ colorScheme.primary
secondary    โ†’ colorScheme.secondary
neutral-*    โ†’ context.appColors.neutralN

Component Mapping#

FigmaFlutter/CoUINotes
btnCoButton(variant: ...)no Button.primary()
cardCoCard
inputCoInput(type: ...) / CoTextField (labelled)no FormTextField
modalCoDialog
drawerCoDrawer
navbarAppBar (in Scaffold(headers: [...]))no CoAppBar
avatarCoAvatar
badgeCoBadge(variant: ...)no PrimaryBadge
tabsTabList + Tabno CoTabBar
iconCoIcon(CoLucideIcons.x)no HeroIcon
spacingCoGap.spaceN() / CoGap(gapStyle: CoreGapStyle(...))no Gap.s*, no CoGap(size: CoreSpace.spaceN) (v0.92)

Typography#

// Figma text style โ†’ context.textStyles.<size><weight>
headline-lg  โ†’ context.textStyles.xlBold
headline-md  โ†’ context.textStyles.lgBold
body-lg      โ†’ context.textStyles.baseNormal
body-md      โ†’ context.textStyles.smNormal
label-lg     โ†’ context.textStyles.smSemibold

Output Template#

Widget File#

import 'package:core/core.dart';

/// {component_name} widget
///
/// Figma: {figma_node_link}
class {ComponentName} extends StatelessWidget {
  const {ComponentName}({
    required this.title,
    this.onTap,
    super.key,
  });

  final String title;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    // CoUI Co<X> ์œ„์ ฏ์œผ๋กœ ๊ตฌ์„ฑ (CoButton / CoBadge / CoCard / CoGap / CoIcon)
    return CoButton(
      onPressed: onTap,
      child: Text(title, style: context.textStyles.baseSemibold),
    );
  }
}

Widgetbook UseCase#

@UseCase(name: 'Default', type: {ComponentName})
Widget buildDefault(BuildContext context) {
  return const {ComponentName}(
    title: 'Sample Title',
  );
}

MCP Integration#

PhaseMCP ServerTool
Figma analysisfigmaget_node_info, extract_tailwind
UI generationmagic21st_magic_component_builder
Code searchserenafind_symbol, search_for_pattern

Core Rules#

Widget Structure#

  • Prefer const constructor
  • super.key always last parameter
  • Break into small reusable units

Styling#

  • No hardcoded colors -> use context.theme.colorScheme.* / context.appColors.*
  • Typography -> context.textStyles.<size><weight> (no Text().lg.bold chaining)
  • Spacing -> CoGap.spaceN() / CoGap(gapStyle: CoreGapStyle(...)) (no Gap.s* / Spacing.s* / Insets.* / CoGap(size: CoreSpace.spaceN) v0.92)
  • withOpacity() prohibited -> use withValues(alpha:)
  • No magic numbers -> use design tokens (CoreSpace)

Responsive#

  • Utilize LayoutBuilder or MediaQuery
  • Minimum touch target 48x48

Examples#

Button Component Creation#

/flutter-ui button --name SubmitButton --feature common

Figma Card Conversion#

/flutter-ui card --figma-node 12:345 --name ProductCard --feature store

Full Page Conversion#

/flutter-ui page --figma-node 1:100 --name HomePage --feature home

References#

  • Detailed implementation: .claude/agents/flutter-ui.md
  • CoUI components: package/coui/
  • Color system: package/resources/lib/src/core/theme/