@libs-ui/components-modal
v0.2.356-25
Published
> Component Modal mạnh mẽ và linh hoạt hỗ trợ hiển thị nội dung trên một lớp phủ, giúp tập trung sự chú ý của người dùng vào một tác vụ cụ thể.
Readme
@libs-ui/components-modal
Component Modal mạnh mẽ và linh hoạt hỗ trợ hiển thị nội dung trên một lớp phủ, giúp tập trung sự chú ý của người dùng vào một tác vụ cụ thể.
Giới thiệu
LibsUiComponentsModalComponent là một standalone component cung cấp giải pháp hiển thị modal chuyên nghiệp với các tính năng:
- ✅ Đa dạng Mode: Hỗ trợ hiển thị ở giữa màn hình (
center) hoặc trượt từ bên phải (offset-right). - ✅ Cấu trúc linh hoạt: Tích hợp sẵn Header, Body, Footer với khả năng tùy biến nội dung cao qua cả
@Inputvà content projection. - ✅ Quản lý trạng thái: Hỗ trợ đóng modal qua phím
Escape, backdrop, hoặc các nút điều khiển. - ✅ Signals Ready: Sử dụng Angular Signals cho việc quản lý hiển thị và cấu hình.
- ✅ Hiệu ứng mượt mà: Tích hợp các animation chuyển cảnh hiện đại.
Khi nào sử dụng
- Khi cần xác nhận một hành động quan trọng từ người dùng (Confirm dialog).
- Khi hiển thị form nhập liệu hoặc chi tiết thông tin mà không muốn rời khỏi trang hiện tại.
- Khi cần thông báo kết quả thao tác (Success/Error/Warning messages).
- Khi hiển thị các tài liệu, hướng dẫn hoặc nội dung phụ trợ.
Cài đặt
# npm
npm install @libs-ui/components-modal
# yarn
yarn add @libs-ui/components-modalImport
import { LibsUiComponentsModalComponent } from '@libs-ui/components-modal';
@Component({
standalone: true,
imports: [LibsUiComponentsModalComponent],
// ...
})
export class YourComponent {}Ví dụ
Basic Modal (Center)
<libs_ui-components-modal
[(show)]="isVisible"
mode="center"
title="Tiêu đề Modal"
[bodyConfig]="{
lines: [{ text: 'Nội dung thông báo đơn giản ở đây.' }]
}"
(outEvent)="onModalEvent($event)"></libs_ui-components-modal>Advanced (Offset Right with Custom Content)
<libs_ui-components-modal
[(show)]="isDetailOpen"
mode="offset-right"
width="600px"
title="Chi tiết đơn hàng"
(outEvent)="handlerEvent($event)">
<div class="libs-ui-modal-body-custom p-4">
<!-- Nội dung phức tạp của bạn ở đây -->
<app-order-detail [data]="currentOrder"></app-order-detail>
</div>
<div class="libs-ui-modal-footer-custom px-4 py-3 flex justify-end gap-2">
<button (click)="isDetailOpen = false">Đóng</button>
<button (click)="save()">Lưu thay đổi</button>
</div>
</libs_ui-components-modal>Buttons Footer (3 Zones)
// Cấu hình buttons footer theo 3 vùng
modalRef.setInput('buttonsFooter', {
left: [
{ label: 'Xóa', type: 'button-danger', action: async () => console.log('delete') },
],
center: [
{ label: 'Bỏ qua', type: 'button-third' },
],
right: [
{ label: 'Hủy', type: 'button-third', action: async () => modalRef.instance.outEvent.emit('cancel') },
{ label: 'Lưu', action: async () => console.log('save') },
],
});API
libs_ui-components-modal
Inputs
| Property | Type | Default | Description |
| --------------------------------------------- | ---------------------------- | ---------------- | ----------------------------------------------------------- |
| [(show)] | boolean | true | Điều khiển trạng thái hiển thị của modal (Two-way binding). |
| [mode] | 'center' \| 'offset-right' | 'offset-right' | Chế độ hiển thị của modal. |
| [width] | string | undefined | Chiều rộng của modal (Model). |
| [height] | string | undefined | Chiều cao của modal (Model). |
| [maxWidth] | string | undefined | Chiều rộng tối đa (Model). |
| [maxHeight] | string | undefined | Chiều cao tối đa (Model). |
| [minWidth] | string | undefined | Chiều rộng tối thiểu (Model). |
| [title] | string | '' | Tiêu đề hiển thị trên header. |
| [zIndex] | number | 1200 | Thứ tự hiển thị lớp phủ. |
| [isFullScreen] | boolean | false | Bật chế độ hiển thị toàn màn hình. |
| [disable] | boolean | false | Vô hiệu hóa các tương tác trong modal (Model). |
| [headerConfig] | IModalHeaderConfig | {} | Cấu hình chi tiết cho phần Header. |
| [bodyConfig] | IModalBodyConfig | {} | Cấu hình nội dung mặc định phần Body. |
| [footerConfig] | IModalFooterConfig | {} | Cấu hình phần Footer. |
| [buttonsFooter] | { left?: IButton[]; center?: IButton[]; right?: IButton[] } | { right: [Cancel, Agree] } | Cấu hình buttons footer theo 3 vùng (Model). |
| [escapeKeyboardCloseModal] | boolean | false | Cho phép đóng modal khi nhấn phím Escape. |
| [isBackdropTransparent] | boolean | undefined | Làm trong suốt lớp màn mờ (backdrop). |
| [isBackgroundTransparentModal] | boolean | undefined | Làm trong suốt nền của modal. |
| [isSizeBackdropByWidthHeightInput] | boolean | undefined | Backdrop co giãn theo width/height của modal. |
| [hasShadowBoxWhenHiddenBackDropTransparent] | boolean | undefined | Hiển thị bóng đổ khi backdrop trong suốt. |
| [classIncludeModalWrapper] | string | ... | Class CSS bổ sung cho container bao ngoài modal. |
| [ignoreCommunicateMicroEvent] | boolean | undefined | Bỏ qua việc gửi postMessage tới parent window. |
| [titleUseXssFilter] | boolean | undefined | Bật bộ lọc XSS cho tiêu đề. |
| [titleUseTooltip] | boolean | undefined | Hiển thị tooltip cho tiêu đề. |
| [titleUseInnerText] | boolean | undefined | Render tiêu đề dưới dạng innerText. |
| [isClickOutsideClose] | boolean | false | Cho phép đóng/huỷ modal khi click ra ngoài backdrop. |
Outputs
| Property | Type | Description |
| ---------------------- | -------------------------------------- | ---------------------------------------------------------------------------------- |
| (outEvent) | EventEmitter<TYPE_MODAL_EVENT> | Phát ra các sự kiện khi người dùng tương tác (close, back, agree, cancel). |
| (outScrollContent) | EventEmitter<Event> | Phát ra khi người dùng cuộn nội dung bên trong modal. |
| (outFunctionControl) | EventEmitter<IModalFunctionsControl> | (Trừ Modal V2) Cung cấp bộ hàm điều khiển modal từ bên ngoài. Đối với Modal V2, bạn sử dụng FunctionsControl nội bộ. |
Dành riêng cho Modal V2 (Kiến trúc Event-Driven mới)
Modal V2 loại bỏ hoàn toàn sự phụ thuộc vào HTML Template. Bắt buộc khởi tạo động qua `LibsUiDynamicComponentService` và giao tiếp qua `Subject`:
// Định nghĩa Stream Types
export interface IDynamicBodyEventOut { eventName: 'PROCESS_DONE'; data?: { message: string } }
export type TDynamicBodyEventIn = 'PROCESS_DATA';
// 1. Mở Modal V2
this.activeModalRef = this.dynamicService.resolveComponentFactory(LibsUiComponentsModalV2Component);
// 2. Chế độ thiết lập input (lưu ý bổ sung show/disable)
setInputs(this.activeModalRef, {
title: 'Modal V2 Standard Architecture',
mode: 'center',
buttonsFooter: {
right: [
{
label: 'Thực thi',
action: async (fc: IModalV2FunctionsControl<TDynamicBodyEventIn, IDynamicBodyEventOut, unknown>) => {
// Gửi event xuống Component con (Body)
fc.getEventToComponentStream().next({ groupEvent: 'custom', eventName: 'PROCESS_DATA' });
}
}
]
},
show: true,
disable: false,
});
this.dynamicService.addToBody(this.activeModalRef);
// 3. Quản lý tương tác 2 chiều và lắng nghe từ Component con
const fc = this.activeModalRef.instance.FunctionsControl;
fc.getEventToModalStream().subscribe((event) => {
if (event.eventName === 'PROCESS_DONE') {
fc.hide();
}
});Methods (via Controls)
| Method | Parameters | Description |
| ------------------------ | ---------- | -------------------------------------- |
| show() | - | Mở hiển thị modal. |
| hide() | - | Đóng ẩn modal. |
| setStateDisable(state) | boolean | Cập nhật trạng thái disable của modal. |
Types & Interfaces
export interface IModalHeaderConfig {
hasBackButton?: boolean;
removeButtonClose?: boolean;
hidden?: boolean;
classTitle?: string;
// ...
}
export interface IModalBodyConfig {
lines?: Array<{ text: string; class?: string }>;
iconType?: 'warning' | 'success' | 'fail' | 'information';
// ...
}Công nghệ
| Technology | Purpose | | --------------- | --------------------------------------------- | | Angular 18+ | Framework chính | | Angular Signals | Quản lý state reactive (model, input, signal) | | RxJS | Xử lý sự kiện (timer, scroll, keyup) | | Standard CSS | Hệ thống layout và animation |
License
MIT
