Popup | CoUI

Popup

메뉴·드롭다운·툴팁 등 플로팅 콘텐츠를 담는 chrome 스타일 컨테이너

Popup#

메뉴·드롭다운·툴팁처럼 떠 있는 콘텐츠를 담는 chrome 스타일 컨테이너입니다. 보더, 그림자, 둥근 모서리, 배경을 가진 패널 안에 자식을 배치합니다.

Popup은 레거시 Flutter MenuPopup과 Web Popup을 통일한 컴포넌트입니다. Flutter와 Web이 동일한 파라미터 이름·동작·시각을 갖습니다.

Live Preview#

Web
Flutter
Loading Flutter...
class PopupDefaultExample extends StatelessComponent {
  const PopupDefaultExample({super.key});

  @override
  Component build(BuildContext context) {
    return Popup(
      children: [
        div(
          [Text('Profile').bodyMedium],
          classes:
              'px-${CoreSpace.scale.space8} py-${CoreSpace.scale.space4}',
        ),
        div(
          [Text('Settings').bodyMedium],
          classes:
              'px-${CoreSpace.scale.space8} py-${CoreSpace.scale.space4}',
        ),
        div(
          [Text('Sign out').bodyMedium],
          classes:
              'px-${CoreSpace.scale.space8} py-${CoreSpace.scale.space4}',
        ),
      ],
    );
  }
}
class PopupDefaultExample extends StatelessWidget {
  const PopupDefaultExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Popup(
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(
            horizontal: CoreSpace.space8,
            vertical: CoreSpace.space4,
          ),
          child: Text('Profile').bodyMedium,
        ),
        Padding(
          padding: const EdgeInsets.symmetric(
            horizontal: CoreSpace.space8,
            vertical: CoreSpace.space4,
          ),
          child: Text('Settings').bodyMedium,
        ),
        Padding(
          padding: const EdgeInsets.symmetric(
            horizontal: CoreSpace.space8,
            vertical: CoreSpace.space4,
          ),
          child: Text('Sign out').bodyMedium,
        ),
      ],
    );
  }
}

사용 시기 (When to Use)#

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

  • 메뉴 / 드롭다운 / 툴팁의 플로팅 패널 chrome 이 필요할 때
  • 떠 있는 콘텐츠에 일관된 보더 / 그림자 / 배경이 필요할 때

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

  • Popover: 트리거에 anchor 된 위치 계산이 필요한 팝오버에
  • DropdownMenu: 액션 목록을 가진 완전한 드롭다운 메뉴에
  • Card: 인라인(비-플로팅) 콘텐츠 카드에

기본 사용법 (Basic Usage)#

Popup(
  children: const [
    Text('Profile'),
    Text('Settings'),
    Text('Sign out'),
  ],
)
Popup(
  children: [
    div([text('Profile')]),
    div([text('Settings')]),
    div([text('Sign out')]),
  ],
)

Props / Parameters#

속성타입기본값설명
childrenList<W>필수패널 내부에 배치되는 콘텐츠
openbooltrue패널 표시 여부
direction CoreAxis vertical 자식 배치 축
popupStyle CorePopupStyle? null 인스턴스별 패널 chrome 스타일

스타일 시스템 (Style System)#

Popup의 모든 chrome 오버라이드는 단일 CorePopupStyle 슬롯으로 흐릅니다 (Epic #1415 option D).

Resolve chain#

CorePopupStyle.defaultX                          // 디자인 시스템 기본값
  → CorePopupTheme.style                          // 프로젝트 공통
  → widget.popupStyle                             // 인스턴스별

CorePopupStyle 필드#

필드타입적용 영역
paddingCoreEdgeInsets?패널 내부 패딩
borderRadiusCoreBorderRadius?패널 모서리 반경
borderWidthdouble?패널 보더 두께
backgroundColorCoreColor?패널 배경색
borderColorCoreColor?패널 보더 색
boxShadowList<CoreShadowLayer>?패널 그림자
minWidthdouble?패널 최소 너비
Popup(
  popupStyle: const CorePopupStyle(
    backgroundColor: CoreColor.token(CoreColors.surfaceContainer),
    borderRadius: CoreBorderRadius.all(CoreRadius.radius16),
  ),
  children: const [Text('Item')],
)

동작 스펙 (Behavior)#

Popup은 chrome 컨테이너입니다 — 위치 계산이나 외부 클릭 닫기 같은 오버레이 동작은 포함하지 않습니다. openfalse면 아무것도 렌더링하지 않습니다. 위치 계산이 필요하면 Popover를 사용하세요.

접근성 (Accessibility)#

  • 루트 컨테이너는 role="menu" (Web)

크로스 플랫폼 차이점 (Platform Differences)#

Popup은 Flutter와 Web이 동일한 children / open / direction / popupStyle API와 동작을 갖습니다. Flutter는 DecoratedBox + ClipRRect, Web은 inline CSS로 동일한 보더 / 그림자 / 둥근 모서리를 렌더링합니다.