LogoSkills

coui-mockup-window

Activate when creating OS window mockups, desktop app frame previews, or macOS-style window chrome with traffic-light dots using the MockupWindow widget with CoreMockupWindowStyle, CoreMockupWindow...

CoUI MockupWindow#

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

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

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

  • ๋ฌด์—‡์„ ํ•ด์ฃผ๋‚˜์š”: ๋‚ด์šฉ๋ฌผ ์œ„์— "์ œ๋ชฉ ํ‘œ์‹œ์ค„ + ์‹ ํ˜ธ๋“ฑ ์  3๊ฐœ"๊ฐ€ ๋ถ™์€ ๋ฐ์Šคํฌํ†ฑ ์ฐฝ ํ”„๋ ˆ์ž„์„ ์”Œ์›Œ ์ค๋‹ˆ๋‹ค. ํ…Œ๋‘๋ฆฌยท๋‘ฅ๊ทผ ๋ชจ์„œ๋ฆฌยท๋ฐฐ๊ฒฝ์ƒ‰๊นŒ์ง€ ์•Œ์•„์„œ ํ†ต์ผ๋œ ๋ชจ์–‘์œผ๋กœ ๋‚˜์˜ต๋‹ˆ๋‹ค.
  • ์–ธ์ œ ์“ฐ์ด๋‚˜์š”: ๋žœ๋”ฉ/์†Œ๊ฐœ ํŽ˜์ด์ง€์—์„œ ์•ฑ ํ™”๋ฉด์„ ์ฐฝ ์•ˆ์— ๋‹ด์•„ ๋ณด์—ฌ์ค„ ๋•Œ, ๋ฌธ์„œยทํฌํŠธํด๋ฆฌ์˜ค์—์„œ ๋ฐ๋ชจ ํ™”๋ฉด์„ ์—ฐ์ถœํ•  ๋•Œ, ๋””์ž์ธ ์‹œ์•ˆ์—์„œ "์ด๊ฑด ๋ฐ์Šคํฌํ†ฑ ์•ฑ ํ™”๋ฉด์ด๋‹ค"๋ผ๊ณ  ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ๋ˆŒ๋ฆฌ๋Š” ๊ฑด๊ฐ€์š”: ์•„๋‹ˆ์š”. ๋นจ๊ฐ•ยท๋…ธ๋ž‘ยท์ดˆ๋ก ์ ์€ ์ˆœ์ˆ˜ํ•œ ์žฅ์‹์ด๋ผ ํด๋ฆญ/ํƒญํ•ด๋„ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊พธ๋ฐ€ ์ˆ˜ ์žˆ๋‚˜์š”: ๋ฐฐ๊ฒฝ์ƒ‰, ํ…Œ๋‘๋ฆฌ์ƒ‰, ๋ชจ์„œ๋ฆฌ ๋‘ฅ๊ธ€๊ธฐ, ์ œ๋ชฉ ํ‘œ์‹œ์ค„ ๋†’์ด, ์  ํฌ๊ธฐยท์ƒ‰๊นŒ์ง€ ์„ธ๋ถ€ ์„ค์ • ํ•œ ๊ณณ(mockupWindowStyle)์—์„œ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ•œ ๋ฒˆ ์ •ํ•ด๋‘๋ฉด ํ†ต์ผ๋ฉ๋‹ˆ๋‹ค: ์•ฑ(Flutter)๊ณผ ์›น ์–‘์ชฝ์—์„œ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๊ณ , ํ”„๋กœ์ ํŠธ ์ „์ฒด์˜ ๊ธฐ๋ณธ ๋ชจ์–‘์„ ํ•œ๊ณณ(ํ…Œ๋งˆ)์—์„œ ์ •ํ•ด๋‘˜ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ˜•์ œ ๋ถ€ํ’ˆ๋„ ์žˆ์Šต๋‹ˆ๋‹ค: ๋ธŒ๋ผ์šฐ์ € ์ฐฝ(MockupBrowser), ํœด๋Œ€ํฐ ํ”„๋ ˆ์ž„(MockupPhone), ์ฝ”๋“œ ํ™”๋ฉด(MockupCode)๋„ ๊ฐ™์€ ๊ณ„์—ด์˜ "์—ฐ์ถœ์šฉ ์•ก์ž"์ž…๋‹ˆ๋‹ค.

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

์šฉ์–ด์‰ฌ์šด ์„ค๋ช…
MockupWindow๋งฅ ์Šคํƒ€์ผ ์ฐฝ ๋ชจ์–‘์„ ํ‰๋‚ด ๋‚ด๋Š” ์žฅ์‹์šฉ ์•ก์ž ๋ถ€ํ’ˆ
title bar (์ œ๋ชฉ ํ‘œ์‹œ์ค„)์ฐฝ ๋งจ ์œ„์˜ ๊ฐ€๋กœ ๋  โ€” ์‹ ํ˜ธ๋“ฑ ์  3๊ฐœ๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ์ž๋ฆฌ
traffic light (์‹ ํ˜ธ๋“ฑ ์ )์™ผ์ชฝ ์œ„ ๋นจ๊ฐ•(๋‹ซ๊ธฐ)ยท๋…ธ๋ž‘(์ตœ์†Œํ™”)ยท์ดˆ๋ก(์ตœ๋Œ€ํ™”) ์žฅ์‹ ์  3๊ฐœ
child์ฐฝ ์•ˆ์— ๋„ฃ๋Š” ๋‚ด์šฉ๋ฌผ (์Šคํฌ๋ฆฐ์ƒท, ํ…์ŠคํŠธ, ๋ฐ๋ชจ ํ™”๋ฉด ๋“ฑ)
mockupWindowStyle์ด ์ฐฝ ํ•˜๋‚˜๋งŒ ๋‹ค๋ฅด๊ฒŒ(์ƒ‰ยทํฌ๊ธฐยท๋ชจ์„œ๋ฆฌ ๋“ฑ) ๊พธ๋ฏธ๋Š” ์„ธ๋ถ€ ์„ค์ • ์นธ
theme / themingํ”„๋กœ์ ํŠธ ์ „์ฒด ์ฐฝ ์•ก์ž์— ๊ณตํ†ต ์ ์šฉ๋˜๋Š” ๊ธฐ๋ณธ ๋ชจ์–‘ ์„ค์ •
Flutter๋ชจ๋ฐ”์ผ/์•ฑ ํ™”๋ฉด์„ ๋งŒ๋“œ๋Š” ๊ธฐ์ˆ 
Web์›น ๋ธŒ๋ผ์šฐ์ €์šฉ ํ™”๋ฉด์„ ๋งŒ๋“œ๋Š” ๊ธฐ์ˆ 
Legacy / Deprecated์˜›๋‚  ๋ฐฉ์‹์ด๋ผ ์ƒˆ ์ฝ”๋“œ์—์„œ๋Š” ์“ฐ์ง€ ๋ง์•„์•ผ ํ•˜๋Š”, ๊ณง ์‚ฌ๋ผ์งˆ ํ•ญ๋ชฉ

Overview#

MockupWindow is the unified cross-platform OS-window mockup: an outer frame with a title bar carrying three macOS-style traffic-light dots (close/minimize/maximize) above a content slot. It is a pure display component โ€” the dots are decorative, there are no callbacks, and there are no semantic enums (no variant, no size). The entire surface is:

  • child โ€” optional window content (Widget? on Flutter, Component? on Web).
  • mockupWindowStyle โ€” the single per-instance style slot (CoreMockupWindowStyle), covering every chrome/colour/dimensional knob.

It implements the shared CoreMockupWindowContract<W> from coui_core, so Flutter and Web take the same style type and resolve through the same chain. Sibling mockups in the same family: MockupBrowser, MockupPhone, MockupCode โ€” all recolourable at once via the shared CoreMockupTheme.

Rendered structure (both platforms):

frame (background, border, borderRadius, clipped)
  โ”œโ”€ title bar (height, horizontal padding, bottom border)
  โ”‚    โ”œโ”€ dot: close    (red   #FF5F57)
  โ”‚    โ”œโ”€ dot: minimize (amber #FFBD2E)
  โ”‚    โ””โ”€ dot: maximize (green #28C840)
  โ””โ”€ content (child)

Flutter (coui_flutter)#

Import#

import 'package:coui_flutter/coui_flutter.dart';

Single barrel only โ€” never import src/ paths.

Basic Usage#

MockupWindow(
  child: const Padding(
    padding: EdgeInsets.all(16),
    child: Text('Window content'),
  ),
)

child is optional โ€” omit it to render just the empty frame with its title bar:

const MockupWindow()

The frame clips its content (clipBehavior: antiAlias), so images or colored children are trimmed to the rounded corners automatically. The column is mainAxisSize: min / crossAxisAlignment: stretch โ€” the window hugs its content height and stretches content to the frame width.

Screenshot / demo frame pattern#

MockupWindow(
  child: SizedBox(
    height: 300,
    child: Center(child: Text('App preview')),
  ),
)

Per-instance Style (mockupWindowStyle)#

mockupWindowStyle takes a CoreMockupWindowStyle. All fields are optional; anything unset falls back through the theme chain to the design-system defaults.

MockupWindow(
  mockupWindowStyle: const CoreMockupWindowStyle(
    borderRadius: CoreBorderRadius.all(CoreRadius.radius8),
    titleBarHeight: 32,
    trafficLightSize: 10,
  ),
  child: const Text('Compact window'),
)

Recolour example (token-bound frame + custom dots):

MockupWindow(
  mockupWindowStyle: const CoreMockupWindowStyle(
    backgroundColor: CoreColor.token(CoreColors.surface),
    borderColor: CoreColor.token(CoreColors.outline),
    trafficLightCloseColor: CoreColor(0xFF888888),
    trafficLightMinimizeColor: CoreColor(0xFF888888),
    trafficLightMaximizeColor: CoreColor(0xFF888888),
  ),
  child: const Text('Monochrome chrome'),
)

Flutter-specific behavior notes#

  • All dimensional values (radius, title-bar spacing/padding/height, dot size/radius) are pre-multiplied by theme.scaling in the resolver โ€” the widget paints them as-is.
  • Colours resolve through theme.colorScheme to paint-ready Colors; the title bar's bottom divider uses the same resolved borderColor as the outer frame.
  • Dot spacing flows into Row.spacing (titleBarSpacing is a scalar, logical px).

Web (coui_web / Jaspr)#

Import#

import 'package:coui_web/coui_web.dart';

Basic Usage#

child is a Jaspr Component:

MockupWindow(
  child: div([text('Window content')], classes: 'p-4'),
)

Multiple content blocks (children)#

Web additionally accepts a children: List<Component>? โ€” rendered before child inside the frame:

MockupWindow(
  children: [
    div([text('Toolbar')], classes: 'p-2'),
    div([text('Body')], classes: 'p-4'),
  ],
)

Per-instance Style (same CoreMockupWindowStyle)#

MockupWindow(
  mockupWindowStyle: const CoreMockupWindowStyle(
    borderRadius: CoreBorderRadius.all(CoreRadius.radius8),
  ),
  child: div([text('Custom radius')]),
)

Colour channels are class-XOR-inline: a token colour (default or token override, e.g. the surface background / outline border) emits a Tailwind bg-*/border-* class and stays dark-mode reactive; a raw CoreColor(0xFF...) override goes inline. The traffic-light defaults are raw macOS palette values, so they render as inline background-color. All dimensional values (radius, gap, padding, height, dot size) are always inline rem โ€” never utility classes.

Web-only constructor extras#

The Web constructor also accepts tag (root element tag, default 'div'), id, classes, css (Jaspr Styles), attributes, and eventHandlers. User classes are merged after the resolved class string; user css is combined after the resolved inline styles. The component also provides copyWith(...).

MockupWindow(
  classes: 'max-w-3xl mx-auto',
  child: div([text('Hero demo')]),
)

Note: the Web root carries w-full โ€” it fills its container's width (constrain it with a wrapper or classes as above), whereas the Flutter frame just follows its parent constraints.

Parameters#

ParameterType (Flutter)Type (Web)DefaultNotes
child Widget? Component? null Window content (optional โ€” empty frame is valid)
mockupWindowStyle CoreMockupWindowStyle? CoreMockupWindowStyle? null Single per-instance chrome/colour/dimension slot

Web-only: children (List<Component>?, rendered before child), tag (default 'div'), id, classes, css (Jaspr Styles), attributes, eventHandlers, plus copyWith(...).

There are no variant / size enums on this component โ€” MockupWindow is a single-form display frame; every visual knob lives on the style slot below.

Style slot โ€” CoreMockupWindowStyle (full field set + defaults)#

Constructor fields (all optional) and their design-system defaults (statics on CoreMockupWindowStyle, shared by Flutter and Web):

FieldTypeDefault (static)Value
backgroundColor CoreColor? defaultBackgroundColor token surface
borderColor CoreColor? defaultBorderColor token outline (frame + title-bar divider)
borderRadius CoreBorderRadius? defaultBorderRadius CoreBorderRadius.all(CoreRadius.radius16)
titleBarSpacing double? defaultTitleBarSpacing CoreSpace.space8 (gap between dots, logical px)
titleBarPadding CoreEdgeInsets? defaultTitleBarPadding CoreEdgeInsets.symmetric(horizontal: CoreSpace.space12)
titleBarHeight double? defaultTitleBarHeight CoreSpace.space40 (logical px)
trafficLightSize double? defaultTrafficLightSize CoreSpace.space12 (logical px)
trafficLightBorderRadius CoreBorderRadius? defaultTrafficLightBorderRadius CoreBorderRadius.all(CoreRadius.radius9999) (perfect circle)
trafficLightCloseColor CoreColor? defaultTrafficLightCloseColor raw CoreColor(0xFFFF5F57) (macOS red)
trafficLightMinimizeColor CoreColor? defaultTrafficLightMinimizeColor raw CoreColor(0xFFFFBD2E) (macOS yellow)
trafficLightMaximizeColor CoreColor? defaultTrafficLightMaximizeColor raw CoreColor(0xFF28C840) (macOS green)

CoreMockupWindowStyle also exposes merge(other) and copyWith(...).

Project-level theming#

Two theme slots participate, both { style }-shaped:

  • CoreMockupWindowTheme (coreComponentTheme.mockupWindow) โ€” window-specific project defaults, carries a full CoreMockupWindowStyle.
  • CoreMockupTheme (coreComponentTheme.mockup) โ€” shared across all mockup variants (Browser/Code/Phone/Window). Its CoreMockupStyle exposes only backgroundColor / borderColor / frameColor / borderRadius; the Window resolver consumes the first three minus frameColor (phone-only) โ€” i.e. background, border, and radius can be recoloured for every mockup frame at once.

Resolve chain (lowest โ†’ highest priority; identical on both platforms):

CoreMockupWindowStyle design-system defaults
  โ†’ CoreMockupTheme.style          // shared cross-variant (bg/border/radius only)
  โ†’ CoreMockupWindowTheme.style    // ํ”„๋กœ์ ํŠธ ๊ณตํ†ต
  โ†’ widget.mockupWindowStyle       // ์ธ์Šคํ„ด์Šค๋ณ„
const CoreMockupWindowTheme(
  style: CoreMockupWindowStyle(
    borderRadius: CoreBorderRadius.all(CoreRadius.radius8),
    titleBarHeight: 32,
  ),
)

Register it on the app theme's coreComponentTheme.mockupWindow slot; the shared recolour goes on coreComponentTheme.mockup (CoreMockupTheme(style: CoreMockupStyle(...))). Both platform resolvers read the same two slots.

Flutter โ†” Web Differences#

AspectFlutterWeb
Widget class MockupWindow (StatelessWidget, CoreMockupWindowContract<Widget>) MockupWindow (UiComponent, CoreMockupWindowContract<Component>)
Child type Widget? Component? + extra children: List<Component>?
Content order title bar โ†’ child title bar โ†’ ...children โ†’ child
Render Container + Column, clipBehavior: antiAlias element (default <div> , configurable tag ) with Tailwind className + inline styles, overflow-hidden relative
Width behavior follows parent constraints root gets w-full (fills container)
Dimensions pre-multiplied by theme.scaling, painted as logical px emitted as inline rem CSS
Colours resolved via theme.colorScheme to paint-ready Color token โ†’ Tailwind class (dark-mode reactive); raw ARGB โ†’ inline CSS
Extra ctor params โ€” tag , id , classes , css , attributes , eventHandlers ; also copyWith(...)

Shared on both: mockupWindowStyle: CoreMockupWindowStyle, CoreMockupWindowTheme / shared CoreMockupTheme resolve chain, decorative-only traffic lights (no callbacks anywhere).

v0.127 Migration (Legacy)#

v0.127 is a de-prefix hard break: the widget class was renamed and no Co-prefixed alias remains. Core* contract names (CoreMockupWindowStyle, CoreMockupWindowTheme, CoreMockupTheme, CoreMockupWindowContract) are unchanged.

โŒ Legacy (pre-0.127, removed)โœ… v0.127
โŒ CoMockupWindow(child: โ€ฆ)MockupWindow(child: โ€ฆ)
โŒ CoMockupBrowser(โ€ฆ) (sibling)MockupBrowser(โ€ฆ)
โŒ CoMockupPhone(โ€ฆ) (sibling)MockupPhone(โ€ฆ)
โŒ CoMockupCode(โ€ฆ) (sibling)MockupCode(โ€ฆ)

Additional migration notes:

  • Migration is rename-only for this component: โŒ CoMockupWindow(...) โ†’ MockupWindow(...) with identical parameters (child, mockupWindowStyle).
  • App-shell exceptions that keep the prefix: CoUIApp, CoUILocalizations, CoUIScrollBehavior.
  • Import stays the single barrel: package:coui_flutter/coui_flutter.dart / package:coui_web/coui_web.dart โ€” never src/ paths.