Modal
- Guidelines
- Implementation
1. Information Dialog
Hộp thoại:
- Yêu cầu user xác minh xem họ muốn tiếp tục hay hủy thao tác
- Hiển thị thông tin user cần được biết
Hộp thoại cùng với dim background chen ngang trước khi hệ thống thực hiện lệnh của user
Note: Max number of stacking modals = 2
Components
Anatomy
- 1Container
- Required
- 2Custom View
- Optional
- Có thể edit tuỳ ý trong view này
- 3Main Items
- Required
- Include
- Title
- Description
- 4Add-on Items
- Optional
- Can be these items
- 5Divider
- Required
- 6Action
- Required
- Hiển thị:
- Default: 1 primary action (blue or red)
- Optional: thêm tối đa 2 secondary actions
- Vị trí:
- Default: horizontal
- Trường hợp text dài, chiều ngang không đủ hiện -> đổi sang dạng vertical
- 77. Dim Background
- Required
Specs
Max height of dialog = 80% screen height
Behavior
Dismiss
User có thể tắt Modal bằng cách
- Tap out to dismiss (tapOutsideToDismiss)
- Có thể ON/OFF
- Default = ON
- Tap dismissive button (bên ngoài truyền vào)
Focused Text Input with keyboard
Trường hợp 1 Modal được đẩy lên trên keyboard
- Modal cách keyboard 16px
Trường hợp 2 Modal được đẩy lên đã chạm status bar nhưng không đủ chỗ đẩy full modal
- Vùng Content thành Scrollview
- Focused Text Input cách keyboard 32px
Điều kiện đóng keyboard
Thoả 1 trong các điều kiện sau:
- Khi user bấm vào bất kì vùng nào trong InformationDialog, ngoài các InputField
- Khi user dismiss InformationDialog
*Khi user scroll trong InformationDialog, không đóng keyboard.
Usage
Confirmation Dialog
Normal
Dialog xuất hiện sau khi user chọn hành động bất kì c ần được confirm trước khi hành động được thực hiện
Danger
Dialog xuất hiện sau khi user chọn hành động mang tính destructive (Xóa, Thoát, Thu hồi, Đăng xuất,...) cần được confirm trước khi hành động được thực hiện
Text Input
Dialog xuất hiện sau khi user chọn hành động mà sau đó cần nhập thông tin để tiếp tục quá trình thực hiện hành động
2. Promotion Popup
- Hộp thoại được sử dụng cho mục đích promote, introduce, onboarding cho tính năng mới
- Nên được sử dụng đúng context vì mức độ interruption rất lớn
Components
Anatomy
- 5Container
- Required
- 6Content View
- Required
- 7Action
- Required
- Hiển thị
- Default: 1 primary button (blue)
- Optional: thêm tối đa 1 secondary button
- 8Dim Background
- Required
Content View
Gồm 2 phần:
- Content Page
- Page Indicator
- 1Content Page
- Required
- Gồm 2 loại:
- 1. Custom (vertical tự custom content)
- 2. Default
- 1Image View
- Required
- 2Title
- Required
- Không limit số dòng
- Font-size: h-normal
- 3Description
- Required
- Number of text rows
- Design: maximum 3 rows
- 1 text row: do not use icon
- 2 - 3 text rows: use icon as bullet point
- Dev: can add multiple
- Font-size: t-normal
- 2Page Indicator
- Sử dụng khi có từ 2 content page trở lên được truyền vào
Specs
Max height of dialog = 80% screen height
Content Page
1. Custom (Vertical tự custom)
Recommended spacing specs
2. Default
Behavior
Behavior
User có thể tắt Modal bằng cách
- Tap out to dismiss (maskClosable)
- Có thể ON/OFF
- Default = OFF
- Bấm dismissive button (bên ngoài truyền vào)
Scroll
Khi Modal chứa content vượt quá max height, cần hiển thị scrollbar. Animation: dùng ScrollView của native
Usage
Transparent background
Filled background
Sử dụng để hiển thị nội dung quan trọng hoặc yêu cầu người dùng thực hiện một hành động cụ thể trước khi tiếp tục sử dụng tính năng của ứng dụng
Properties
ModalActions
Name | Type | Default | Description |
---|---|---|---|
close | boolean | false | Nếu được set thành |
danger | boolean | false | Hiển thị action dưới dạng nút danger |
disabled | boolean | false | Trạng thái hoạt động của action |
highLight | boolean | false | Hiển thị action dưới dạng nút highlight |
text | string | Chữ trên nút | |
onClick | (e: React.MouseEvent) => void | Callback được gọi khi action được click |
Modal
Name | Type | Default | Description |
---|---|---|---|
actions | ModalActions[] | Mảng thiết lập các nút để người dùng thực hiện các hành động trên hộp thoại. | |
actionsDivider | boolean | false | Hiển thị viền phân cách giữa các action. |
afterClose | () => void | Callback được gọi sau khi hộp thoại đóng | |
coverSrc | string | Đường dẫn đến hình ảnh cover của hộp thoại | |
description | string | Nội dung của hộp thoại, được hiển thị phía dưới tiêu đề. Nếu nội dung cần hiển thị không phải là text, sử dụng | |
height | string | number | Chiều cao của hộp thoại. Nếu không được thiết lập, modal sẽ có chiều cao mặc định theo chiều cao của nội dung và chiều cao của màn hình. | |
mask | boolean | true | Mask là một lớp overlay màu xám được phủ lên các thành phần bên dưới hộp thoại, ngăn không cho người dùng tương tác với các nội dung đó và tập trung vào hộp thoại được mở. |
maskClassName | string | CSS class cho mask | |
maskClosable | boolean | true | Cho phép đóng hộp thoại khi click vào mask. |
maskStyle | React.CSSProperties | Inline style cho mask | |
modalClassName | string | CSS class cho modal | |
modalStyle | React.CSSProperties | Inline style cho hộp thoại | |
ref | React.MutableRefObject | ||
title | string | Tiêu đề của hộp thoại, được hiển thị ở phía trên cùng của hộp thoại. | |
unmountOnClose | boolean | false | Mặc định khi người dùng đóng hộp thoại, modal vẫn còn được render trong DOM và chỉ bị ẩn đi. Thiết lập này cho phép gỡ hộp thoại khỏi cây DOM hoàn toàn sau khi đóng. Thiết lập này có thể giúp giảm bộ nhớ được sử dụng trong trường hợp hộp thoại có nội dung lớn. Tuy nhiên, khi hộp thoại được mở lại, nội dung của hộp thoại sẽ được render lại từ đầu. Phù hợp với những hộp thoại chỉ sử dụng một lần. |
verticalActions | boolean | false | Hiển thị các action theo chiều dọc, thay vì mặc định là theo chiều ngang. |
visible | boolean | false | Trạng thái hiển thị của hộp thoại. Cần được sử dụng chung với |
width | string | number | Độ rộng của hộp thoại. Nếu không được thiết lập, modal sẽ có độ rộng mặc định theo độ rộng của nội dung và chiều rộng của màn hình. | |
zIndex | number | Độ sâu của hộp thoại, dùng để xác định thứ tự hiển thị của hộp thoại trong trường hợp có nhiều modal được mở cùng lúc. | |
onClose | (e: React.SyntheticEvent) => void | Callback được gọi khi người dùng yêu cầu đóng hộp thoại. Cần phải cập nhật lại giá trị của |
Example
import React, { useState } from "react"; import { Page, Button, Text, Modal, Box } from "zmp-ui"; export default function HomePage(props) { const [modalVisible, setModalVisible] = useState(false); const [dialogVisible, setDialogVisible] = useState(false); const [vDialogVisible, setVDialogVisible] = useState(false); const [popupVisible, setPopupVisible] = useState(false); return ( <Page className="section-container"> <Text.Title size="small">Dialog & Modal</Text.Title> <Box mt={4}> <Button variant="secondary" fullWidth onClick={() => { setDialogVisible(true); }} > Info Dialog </Button> </Box> <Box mt={4}> <Button variant="secondary" fullWidth onClick={() => { setVDialogVisible(true); }} > Info Dialog Vertical Actions </Button> </Box> <Box mt={4}> <Button variant="secondary" fullWidth onClick={() => { setPopupVisible(true); }} > Custom Modal </Button> </Box> <Box mt={4}> <Button variant="secondary" fullWidth onClick={() => { setModalVisible(true); }} > Custom Modal With Cover </Button> </Box> <Modal visible={dialogVisible} title="This is the title" onClose={() => { setDialogVisible(false); }} actions={[ { text: "Button", }, { text: "Button", close: true, highLight: true, }, ]} description="This is a very long message that can be displayed in 3 lines" /> <Modal visible={vDialogVisible} title="This is the title" onClose={() => { setVDialogVisible(false); }} verticalActions actions={[ { text: "Long Text Button", }, { text: "Long Text Button", close: true, highLight: true, }, ]} description="This is a very long message that can be displayed in 3 lines" /> <Modal visible={popupVisible} title="This is the title" onClose={() => { setPopupVisible(false); }} verticalActions description="This is a very long message that can be displayed in 3 lines" > <Box p={6}> <Button onClick={() => { setPopupVisible(false); }} fullWidth > Xác nhận </Button> </Box> </Modal> <Modal visible={modalVisible} title="ZaUI 2.0 Modal" coverSrc={"https://images.unsplash.com/photo-1561336313-0bd5e0b27ec8"} onClose={() => { setModalVisible(false); }} zIndex={1200} actions={[ { text: "Button", }, { text: "Cancel", close: true, highLight: true, }, ]} description="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged." /> </Page> ); }