컴포넌트 공방: 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
rx.alert_dialog.rootrx.alert_dialog.triggerrx.alert_dialog.contentrx.alert_dialog.titlerx.alert_dialog.descriptionrx.alert_dialog.actionrx.alert_dialog.cancel공식 문서
공방 주문서
프로젝트 목록의 휴지통 버튼을 누르면 바로 지우지 말고, 정말 지울지 한 번 더 묻는 창을 띄워 주세요.
rx.alert_dialog는 사용자의 흐름을 멈추고 답을 받는 확인 창입니다. 일반 Dialog와 달리 창 바깥을 눌러도 닫히지 않아서, 사용자는 '취소'나 '실행' 중 하나를 골라야 합니다(Esc 키는 취소로 처리됩니다). 삭제, 권한 회수처럼 되돌리기 어려운 일 앞에 둡니다.
alert_dialog.root: 모든 부품을 감쌉니다.alert_dialog.trigger: 누르면 창을 여는 요소를 감쌉니다.alert_dialog.content: 창의 내용입니다.alert_dialog.title: 창의 제목입니다. 열릴 때 화면 읽기 프로그램이 읽습니다.alert_dialog.description: 덧붙이는 설명입니다(생략 가능). 열릴 때 함께 읽힙니다.alert_dialog.action: 실행 버튼을 감쌉니다. 누르면 창이 닫힙니다.alert_dialog.cancel: 취소 버튼을 감쌉니다. 누르면 창이 닫힙니다. 실행 버튼과 눈으로 구별되게 만듭니다.rx.alert_dialog.root(
rx.alert_dialog.trigger(
rx.button("Revoke access"),
),
rx.alert_dialog.content(
rx.alert_dialog.title("Revoke access"),
rx.alert_dialog.description(
"Are you sure? This application will no longer be accessible and any existing sessions will be expired.",
),
rx.flex(
rx.alert_dialog.cancel(
rx.button("Cancel"),
),
rx.alert_dialog.action(
rx.button("Revoke access"),
),
spacing="3",
),
),
)창의 여백은 content의 size로, 버튼 배치는 감싼 rx.flex의 justify로 정합니다. 실행 버튼에는 일의 무게에 맞는 색을 줍니다.
속성 바꿔 보기
title
action
color
size
justify
rx.alert_dialog.root(
rx.alert_dialog.trigger(rx.button("Delete", color_scheme="red")),
rx.alert_dialog.content(
rx.alert_dialog.title("Delete this file?"),
rx.alert_dialog.description("This action cannot be undone.", size="2"),
rx.flex(
rx.alert_dialog.cancel(rx.button("Cancel", variant="soft", color_scheme="gray")),
rx.alert_dialog.action(rx.button("Delete", color_scheme="red")),
spacing="3",
margin_top="16px",
justify="end",
),
size="3",
max_width="450px",
),
)| 부품 | 속성 | 값 | 쓰임 |
|---|---|---|---|
root | open | True / False | 열림을 State로 정하기(제어) |
root | default_open | True / False | 처음 그릴 때 열어 두기(비제어) |
root | on_open_change | 이벤트 | 열리거나 닫힐 때. 새 열림 값(bool)을 넘긴다 |
content | size | "1" ~ "4" | 여백과 모서리 크기 |
content | force_mount | True / False | 닫혀 있어도 DOM에 두기(애니메이션용) |
content | on_open_auto_focus · on_close_auto_focus | 이벤트 | 열리며 창 안에, 닫히며 트리거에 초점이 갈 때 |
content | on_escape_key_down | 이벤트 | Esc 키를 눌렀을 때 |
trigger, title, description, action, cancel에는 공통 이벤트만 있습니다. Dialog의 content에 있던 '바깥 누르기' 이벤트는 여기에는 없습니다. 바깥을 눌러도 닫히지 않기 때문입니다.
실행 버튼과 트리거를 붉게, 취소는 회색 soft로 힘을 빼고, 두 버튼을 justify="end"로 오른쪽에 모은 모습입니다. 창 너비는 style={"max_width": 450}으로 줄였습니다.
rx.alert_dialog.root(
rx.alert_dialog.trigger(
rx.button("Revoke access", color_scheme="red"),
),
rx.alert_dialog.content(
rx.alert_dialog.title("Revoke access"),
rx.alert_dialog.description(
"Are you sure? This application will no longer be accessible and any existing sessions will be expired.",
size="2",
),
rx.flex(
rx.alert_dialog.cancel(
rx.button("Cancel", variant="soft", color_scheme="gray"),
),
rx.alert_dialog.action(
rx.button("Revoke access", color_scheme="red", variant="solid"),
),
spacing="3",
margin_top="16px",
justify="end",
),
style={"max_width": 450},
),
)rx.inset으로 표를 창의 양옆 가장자리까지 붙이면, 지울 대상을 한눈에 보여 줄 수 있습니다.
rx.alert_dialog.root(
rx.alert_dialog.trigger(
rx.button("Delete Users", color_scheme="red"),
),
rx.alert_dialog.content(
rx.alert_dialog.title("Delete Users"),
rx.alert_dialog.description(
"Are you sure you want to delete these users? This action is permanent and cannot be undone.",
size="2",
),
rx.inset(
rx.table.root(
rx.table.header(
rx.table.row(
rx.table.column_header_cell("Full Name"),
rx.table.column_header_cell("Email"),
rx.table.column_header_cell("Group"),
),
),
rx.table.body(
rx.table.row(
rx.table.row_header_cell("Danilo Rosa"),
rx.table.cell("danilo@example.com"),
rx.table.cell("Developer"),
),
rx.table.row(
rx.table.row_header_cell("Zahra Ambessa"),
rx.table.cell("zahra@example.com"),
rx.table.cell("Admin"),
),
),
),
side="x",
margin_top="24px",
margin_bottom="24px",
),
rx.flex(
rx.alert_dialog.cancel(
rx.button("Cancel", variant="soft", color_scheme="gray"),
),
rx.alert_dialog.action(
rx.button("Delete users", color_scheme="red"),
),
spacing="3",
justify="end",
),
style={"max_width": 500},
),
)alert_dialog.root의 on_open_change는 열릴 때 True, 닫힐 때 False를 넘깁니다.
Opened or closed: 0 times
Alert dialog open: no
class AlertDialogEventState(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: ", AlertDialogEventState.num_opens, " times"),
rx.text("Alert dialog open: ", rx.cond(AlertDialogEventState.opened, "yes", "no")),
rx.alert_dialog.root(
rx.alert_dialog.trigger(
rx.button("Revoke access", color_scheme="red"),
),
rx.alert_dialog.content(
rx.alert_dialog.title("Revoke access"),
rx.alert_dialog.description(
"Are you sure? This application will no longer be accessible and any existing sessions will be expired.",
size="2",
),
rx.flex(
rx.alert_dialog.cancel(
rx.button("Cancel", variant="soft", color_scheme="gray"),
),
rx.alert_dialog.action(
rx.button("Revoke access", color_scheme="red", variant="solid"),
),
spacing="3",
margin_top="16px",
justify="end",
),
style={"max_width": 450},
),
on_open_change=AlertDialogEventState.count_opens,
),
direction="column",
spacing="3",
align="start",
)open에 State 값을 연결하면 alert_dialog.trigger 없이, 창 바깥의 버튼으로 창을 열 수 있습니다. 창 안의 취소·실행 버튼도 같은 핸들러로 값을 뒤집어 창을 닫습니다. Esc 키로 닫힐 때도 State가 따라오도록 on_open_change를 함께 연결합니다.
공식 문서의 예제는 self.opened = ~self.opened로 값을 뒤집는데, 파이썬에서 ~는 bool을 정수(-1, -2)로 바꿉니다. 여기서는 not self.opened를 씁니다.
class AlertDialogControlState(rx.State):
opened: bool = False
@rx.event
def dialog_open(self):
self.opened = not self.opened
@rx.event
def set_opened(self, value: bool):
self.opened = value
rx.box(
rx.alert_dialog.root(
rx.alert_dialog.content(
rx.alert_dialog.title("Revoke access"),
rx.alert_dialog.description(
"Are you sure? This application will no longer be accessible and any existing sessions will be expired.",
),
rx.flex(
rx.alert_dialog.cancel(
rx.button("Cancel", on_click=AlertDialogControlState.dialog_open),
),
rx.alert_dialog.action(
rx.button("Revoke access", on_click=AlertDialogControlState.dialog_open),
),
spacing="3",
),
),
open=AlertDialogControlState.opened,
on_open_change=AlertDialogControlState.set_opened,
),
rx.button("Button to Open the Dialog", on_click=AlertDialogControlState.dialog_open),
)Dialog와 같은 방식으로 rx.form을 넣을 수 있습니다. 제출 버튼을 alert_dialog.action으로 감싸면 제출과 동시에 창이 닫힙니다. 실제 데이터베이스 저장은 Dialog 페이지의 코드와 같습니다.
class AlertDialogFormState(rx.State):
current_user: dict[str, str] = {}
@rx.event
def add_user(self, form_data: dict):
self.current_user = form_data
# Here you would save the user to a database (see the Database course).
return rx.toast.info(
f"User {form_data.get('name', '')} has been added.", position="bottom-right"
)
rx.alert_dialog.root(
rx.alert_dialog.trigger(
rx.button(rx.icon("plus", size=26), rx.text("Add User", size="4")),
),
rx.alert_dialog.content(
rx.alert_dialog.title("Add New User"),
rx.alert_dialog.description("Fill the form with the user's info"),
rx.form(
rx.flex(
rx.input(placeholder="User Name", name="name"),
rx.input(placeholder="user@reflex.dev", name="email"),
rx.flex(
rx.alert_dialog.cancel(
rx.button("Cancel", variant="soft", color_scheme="gray"),
),
rx.alert_dialog.action(
rx.button("Submit", type="submit"),
),
spacing="3",
justify="end",
),
direction="column",
spacing="4",
),
on_submit=AlertDialogFormState.add_user,
reset_on_submit=False,
),
max_width="450px",
),
)목록의 항목마다 휴지통 버튼과 확인 창을 붙입니다. 실행 버튼의 on_click에 지울 이름을 넘기고, 핸들러가 목록에서 그 항목을 뺀 뒤 알림을 띄웁니다. 취소를 누르거나 Esc를 누르면 아무 일도 일어나지 않습니다.
Website
Mobile app
Newsletter
class AlertDialogProjectState(rx.State):
projects: list[str] = ["Website", "Mobile app", "Newsletter"]
@rx.event
def delete_project(self, name: str):
self.projects = [p for p in self.projects if p != name]
return rx.toast.success(f"Deleted {name}")
@rx.event
def restore(self):
self.projects = ["Website", "Mobile app", "Newsletter"]
rx.vstack(
rx.foreach(
AlertDialogProjectState.projects,
lambda name: rx.flex(
rx.text(name),
rx.spacer(),
rx.alert_dialog.root(
rx.alert_dialog.trigger(
rx.icon_button(rx.icon("trash-2"), color_scheme="red", variant="ghost", aria_label="Delete"),
),
rx.alert_dialog.content(
rx.alert_dialog.title("Delete project?"),
rx.alert_dialog.description(
"The project ", rx.text.strong(name), " and all its files will be deleted.",
size="2",
),
rx.flex(
rx.alert_dialog.cancel(rx.button("Cancel", variant="soft", color_scheme="gray")),
rx.alert_dialog.action(
rx.button("Delete", color_scheme="red", on_click=AlertDialogProjectState.delete_project(name)),
),
spacing="3",
margin_top="16px",
justify="end",
),
max_width="420px",
),
),
width="100%",
align="center",
padding="6px 10px",
border=f"1px solid {rx.color('gray', 5)}",
border_radius="6px",
),
),
rx.button("Restore all", size="1", variant="soft", on_click=AlertDialogProjectState.restore),
width="100%",
max_width="360px",
)공방 노트
root · trigger · content · title · description · action · cancel. 바깥을 눌러도 닫히지 않는다.
action과 cancel은 둘 다 창을 닫는다. 실제로 할 일은 action 안 버튼의 on_click에 연결한다.
실행 버튼은 일의 무게에 맞는 색(삭제는 red), 취소는 회색 soft로 구별한다.
open으로 제어할 때는 on_open_change도 연결해 Esc로 닫힌 경우를 State에 돌려준다.
되돌릴 수 있는 일이라면 확인 창 대신 실행 후 '되돌리기' 알림(Toast)도 고려한다.
새 교시·새 강의 소식 받기
이 강의에 새 교시가 더해지거나 이어지는 강의가 열리면 이메일로 알려 드려요.
R
ReflexKR
눌러 보며 배우는 파이썬과 Reflex. 모든 예제는 Reflex 0.10.0에서 직접 실행해 확인했습니다.
ReflexKR은 배너 광고 없이 무료로 운영돼요. 도움이 되셨다면 커피 한 잔으로 응원해 주세요.
© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
질문과 답변
이 교시에서 궁금한 점을 남겨 주세요. 모든 언어 페이지의 질문이 함께 모입니다.