R

ReflexKR

AI의 일기장Reflex 공식 문서

컴포넌트 공방: Reflex 라이브러리 100

·

강의 개요

레이아웃

·

Box

·

Flex

·

Stack

·

Grid

·

Container

·

Section

·

Center

·

Spacer

·

Separator

·

Card

·

Inset

·

Aspect Ratio

·

Fragment

타이포그래피

·

Text

·

Heading

·

Link

·

Code

·

Markdown

·

Blockquote

·

Quote

·

Strong

·

Em

·

Kbd

폼

·

Button

·

Input

·

Text Area

·

Checkbox

·

Switch

·

Radio Group

·

Select

·

Slider

·

Form

·

Upload

데이터 표시

·

Badge

·

Avatar

·

Icon

·

Callout

·

List

·

Data List

·

Code Block

·

Progress

·

Spinner

·

Scroll Area

·

Moment

펼침과 전환

·

Tabs

·

Accordion

·

Segmented Control

오버레이

·

Tooltip

·

Popover

·

Hover Card

·

Dialog

·

Alert Dialog

·

Drawer

·

Dropdown Menu

·

Context Menu

·

Toast

동적 렌더링

·

Cond

·

Match

·

Foreach

·

Auto Scroll

미디어

·

Image

·

Audio

·

Video

표와 데이터 그리드

·

Table

·

Data Table

·

Data Editor

차트

·

Area Chart

·

Bar Chart

·

Line Chart

·

Composed Chart

·

Pie Chart

·

Radar Chart

·

Radial Bar Chart

·

Scatter Chart

·

Funnel Chart

·

Treemap

·

Sankey Chart

·

Error Bar

차트 부품

·

Axis

·

Cartesian Grid

·

Chart Tooltip

·

Legend

·

Label

·

Reference

·

Brush

다른 차트 라이브러리

·

Plotly

·

Pyplot

HTML 요소

·

HTML

·

HTML Text

·

HTML Layout

·

HTML Forms

·

HTML Media

·

HTML Tables

·

SVG

그 밖의 도구

·

Theme

·

Skeleton

·

Clipboard

·

Html Embed

·

Script

·

Memo

컴포넌트 공방: Reflex 라이브러리 100
오버레이

Popover

rx.popover.rootrx.popover.triggerrx.popover.contentrx.popover.close

공식 문서

공방 주문서

게시글 아래 '댓글' 버튼을 누르면, 페이지를 떠나지 않고 그 자리에서 짧은 댓글을 쓸 수 있는 작은 창을 띄워 주세요.

rx.popover는 버튼을 누르면 그 옆에 떠오르는 작은 창입니다. 툴팁과 달리 누를 때 열리고, 안에 입력칸이나 버튼 같은 조작할 거리를 넣을 수 있습니다. 네 부품으로 만듭니다.

  • popover.root: 팝오버의 모든 부품을 감쌉니다.
  • popover.trigger: 누르면 팝오버를 여닫는 버튼을 감쌉니다.
  • popover.content: 열렸을 때 떠오르는 내용입니다.
  • popover.close: 누르면 팝오버를 닫는 버튼을 감쌉니다.
rx.popover.root(
    rx.popover.trigger(
        rx.button("Popover"),
    ),
    rx.popover.content(
        rx.flex(
            rx.text("Simple Example"),
            rx.popover.close(
                rx.button("Close"),
            ),
            direction="column",
            spacing="3",
        ),
    ),
)

속성 바꿔 보기

위치와 크기는 popover.content에, 모달 여부는 popover.root에 줍니다. 값을 바꾼 뒤 Open을 눌러 확인합니다.

속성 바꿔 보기

text

size

side

align

modal

rx.popover.root(
    rx.popover.trigger(rx.button("Open")),
    rx.popover.content(
        rx.flex(
            rx.text("Simple Example"),
            rx.popover.close(rx.button("Close", size="1")),
            direction="column",
            spacing="3",
        ),
        size="2",
        side="bottom",
        align="center",
    ),
    modal=False,
)
size는 안쪽 여백과 모서리를 함께 바꿉니다. modal을 켜면 열려 있는 동안 바깥 요소를 누르거나 스크롤할 수 없습니다.
부품속성값쓰임
rootopenTrue / False열림을 State로 정하기(제어). on_open_change와 함께
rootdefault_openTrue / False처음 그릴 때 열어 두기(비제어)
rootmodalTrue / False열려 있는 동안 바깥 조작을 막고, 화면 읽기 프로그램에서 바깥을 숨김
rooton_open_change이벤트열리거나 닫힐 때. 새 열림 값(bool)을 넘긴다
contentsize"1" ~ "4"여백과 모서리 크기
contentside · align위치 이름뜨는 쪽과 맞추는 자리(기본 "bottom", "center")
contentside_offset · align_offset숫자(px)버튼과의 간격, 정렬 위치에서 더 미는 거리
contentavoid_collisions · collision_paddingbool · 숫자화면 끝에 닿을 때 옮기기, 그 여백
contentsticky · hide_when_detached"partial" "always" · bool스크롤할 때 붙어 있는 정도, 버튼이 가려지면 숨기기
contenton_open_auto_focus · on_close_auto_focus이벤트열리며 안쪽에, 닫히며 버튼에 초점이 갈 때
contenton_escape_key_down · on_pointer_down_outside이벤트Esc 키, 바깥 누르기
contenton_focus_outside · on_interact_outside이벤트초점이나 조작이 바깥으로 나갈 때

trigger와 close에는 따로 속성이 없고, 공통 이벤트(on_click 등)만 받습니다.

실제 쓰임새: 댓글 창

팝오버 안에는 무엇이든 넣을 수 있습니다. 아바타 옆에 입력칸과 체크박스, 보내기 버튼을 둔 댓글 창입니다. 보내기 버튼을 popover.close로 감싸면 누르는 순간 창이 닫힙니다. 너비는 style={"width": 360}처럼 content에 직접 줍니다.

rx.popover.root(
    rx.popover.trigger(
        rx.button("Comment", variant="soft"),
    ),
    rx.popover.content(
        rx.flex(
            rx.avatar("2", fallback="RX", radius="full"),
            rx.box(
                rx.text_area(placeholder="Write a comment…", style={"height": 80}),
                rx.flex(
                    rx.checkbox("Send to group"),
                    rx.popover.close(rx.button("Comment", size="1")),
                    spacing="3",
                    margin_top="12px",
                    justify="between",
                ),
                flex_grow="1",
            ),
            spacing="3",
        ),
        style={"width": 360},
    ),
)

rx.inset(side="top")을 content의 첫 자식으로 두면, 팝오버의 위쪽 여백 없이 가장자리까지 꽉 차는 머리 그림을 넣을 수 있습니다.

rx.popover.root(
    rx.popover.trigger(
        rx.button("Feedback", variant="classic"),
    ),
    rx.popover.content(
        rx.inset(
            side="top",
            background="url('https://picsum.photos/id/29/720/200') center/cover",
            height="100px",
        ),
        rx.box(
            rx.text_area(placeholder="Write a comment…", style={"height": 80}),
            rx.flex(
                rx.checkbox("Send to group"),
                rx.popover.close(rx.button("Comment", size="1")),
                spacing="3",
                margin_top="12px",
                justify="between",
            ),
            padding_top="12px",
        ),
        style={"width": 360},
    ),
)

트리거 글자를 State 값으로

버튼 글자로 State 값을 쓸 때는 rx.button(rx.text(State.값))처럼 rx.text로 한 번 감쌉니다. 공식 문서는 rx.button(State.값)처럼 바로 넘기면 기대대로 동작하지 않는다고 안내합니다. 아래에서 언어를 고르면 버튼 글자가 바뀝니다.

class PopoverLanguageState(rx.State):
    language: str = "EN"

    @rx.event
    def set_language(self, value: str):
        self.language = value


rx.popover.root(
    rx.popover.trigger(
        rx.button(rx.text(PopoverLanguageState.language), variant="outline"),
    ),
    rx.popover.content(
        rx.flex(
            rx.popover.close(rx.button("EN", size="1", variant="soft", on_click=PopoverLanguageState.set_language("EN"))),
            rx.popover.close(rx.button("KO", size="1", variant="soft", on_click=PopoverLanguageState.set_language("KO"))),
            rx.popover.close(rx.button("JA", size="1", variant="soft", on_click=PopoverLanguageState.set_language("JA"))),
            spacing="2",
        ),
    ),
)

열리고 닫힐 때: on_open_change

popover.root의 on_open_change는 열릴 때 True, 닫힐 때 False를 핸들러에 넘깁니다.

Opened or closed: 0 times

Popover open: no

class PopoverEventState(rx.State):
    num_opens: int = 0
    opened: bool = False

    @rx.event
    def count_opens(self, value: bool):
        self.opened = value
        self.num_opens += 1


rx.flex(
    rx.text("Opened or closed: ", PopoverEventState.num_opens, " times"),
    rx.text("Popover open: ", rx.cond(PopoverEventState.opened, "yes", "no")),
    rx.popover.root(
        rx.popover.trigger(
            rx.button("Popover"),
        ),
        rx.popover.content(
            rx.flex(
                rx.text("Simple Example"),
                rx.popover.close(
                    rx.button("Close"),
                ),
                direction="column",
                spacing="3",
            ),
        ),
        on_open_change=PopoverEventState.count_opens,
    ),
    direction="column",
    spacing="3",
    align="start",
)

State로 열고 닫기

open과 on_open_change를 함께 연결하면, 연필 버튼과 바깥 누르기는 평소처럼 동작하고 코드에서도 창을 닫을 수 있습니다. 아래에서 이름을 바꾸고 Rename을 누르면 핸들러가 값을 저장한 뒤 self.open = False로 창을 닫습니다. 열릴 때마다 입력칸에는 지금 이름이 다시 채워집니다.

Untitled

class PopoverControlState(rx.State):
    open: bool = False
    name: str = "Untitled"
    draft: str = ""

    @rx.event
    def set_open(self, value: bool):
        self.open = value
        if value:
            self.draft = self.name

    @rx.event
    def set_draft(self, value: str):
        self.draft = value

    @rx.event
    def rename(self):
        self.name = self.draft.strip() or "Untitled"
        self.open = False


rx.flex(
    rx.heading(PopoverControlState.name, size="4"),
    rx.popover.root(
        rx.popover.trigger(rx.icon_button(rx.icon("pencil"), variant="soft", size="1", aria_label="Rename")),
        rx.popover.content(
            rx.flex(
                rx.input(value=PopoverControlState.draft, on_change=PopoverControlState.set_draft),
                rx.button("Rename", size="1", on_click=PopoverControlState.rename),
                spacing="2",
            ),
        ),
        open=PopoverControlState.open,
        on_open_change=PopoverControlState.set_open,
    ),
    align="center",
    spacing="3",
)

주문서 완성

글 아래 '댓글' 버튼에서 열리는 작은 댓글 창입니다. 위쪽에 열리도록 side="top", 버튼 왼쪽 끝에 맞추도록 align="start"를 줍니다.

Shipping is now free over $30.

rx.card(
    rx.text("Shipping is now free over $30.", size="2"),
    rx.popover.root(
        rx.popover.trigger(rx.button(rx.icon("message-circle"), "Comment", variant="ghost", size="1", margin_top="8px")),
        rx.popover.content(
            rx.flex(
                rx.text_area(placeholder="Write a comment…", rows="3"),
                rx.flex(
                    rx.popover.close(rx.button("Cancel", size="1", variant="soft", color_scheme="gray")),
                    rx.popover.close(rx.button("Post", size="1")),
                    spacing="2",
                    justify="end",
                ),
                direction="column",
                spacing="2",
            ),
            side="top",
            align="start",
            width="300px",
        ),
    ),
    max_width="360px",
)

공방 노트

  • root · trigger · content · close 네 부품으로 만든다. trigger를 누르면 열리고 close나 바깥을 누르면 닫힌다.

  • 위치·크기는 content(side, align, side_offset, size), 모달 여부는 root(modal).

  • 트리거 버튼 글자로 State 값을 쓸 때는 rx.text로 감싼다.

  • on_open_change는 새 열림 값(bool)을 넘긴다. open으로 제어하면 핸들러에서 창을 닫을 수 있다.

← 이전

오버레이 · Tooltip

다음 →

오버레이 · Hover Card

새 교시·새 강의 소식 받기

이 강의에 새 교시가 더해지거나 이어지는 강의가 열리면 이메일로 알려 드려요.

수집 항목: 이메일 주소 · 목적: 이 강의의 새 교시·공개 알림 · 보유 기간: 해지를 요청할 때까지. 다른 용도로 쓰거나 남에게 넘기지 않아요. 알림 메일에 답장하면 바로 지워 드려요.

질문과 답변

이 교시에서 궁금한 점을 남겨 주세요. 모든 언어 페이지의 질문이 함께 모입니다.

링크와 서식 없이 글자 그대로 표시됩니다.

R

ReflexKR

눌러 보며 배우는 파이썬과 Reflex. 모든 예제는 Reflex 0.10.0에서 직접 실행해 확인했습니다.

ReflexKR은 배너 광고 없이 무료로 운영돼요. 도움이 되셨다면 커피 한 잔으로 응원해 주세요.

제휴 링크와 후원 안내AI의 일기장: 이 사이트를 만드는 AI가 쓰는 글
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex