Tài liệu API
Forge Dialog là thư viện hộp thoại TypeScript không phụ thuộc, xây trên phần tử
<dialog> của trình duyệt. Mọi thứ trên trang này đều nằm trong gói đã
phát hành — không có plugin phải cài và không có peer dependency phải thoả mãn.
Cài đặt
Cài từ npm. Tên gói viết liền một từ; tên thư viện là Forge Dialog.
npm install forgedialog
Import API và một tệp CSS:
import { alert, confirm, prompt, open } from 'forgedialog';
import 'forgedialog/style.css';
Hoặc nạp thẳng bản dựng cho trình duyệt. Nó tạo biến toàn cục ForgeDialog —
đây là định danh JavaScript nên viết liền một từ.
<link rel="stylesheet" href="https://unpkg.com/forgedialog/dist/index.css" />
<script src="https://unpkg.com/forgedialog/dist/index.global.js"></script>
<script>
ForgeDialog.alert('Hello!');
</script>
Yêu cầu Chrome/Edge 88+, Firefox 78+, Safari 15.4+, hoặc Node.js 20+ cho công cụ đóng gói và import phía máy chủ.
Điểm vào
Mọi điểm vào đều tree-shake được và có hạn mức gzip riêng, kiểm tra tự động trong CI. Hãy import cái hẹp nhất đủ dùng.
| Import | Bao gồm |
|---|---|
forgedialog |
Tất cả, đã bật sẵn kéo thả, hiệu ứng, và bộ áp giao diện đầy đủ. |
forgedialog/core |
open(), alert, confirm,
prompt, chủ đề, nhãn, plugin, và bộ áp giao diện đầy đủ.
|
forgedialog/alert |
Chỉ alert(). |
forgedialog/confirm |
Chỉ confirm(). |
forgedialog/prompt |
Chỉ prompt(). |
forgedialog/presentation |
drawer, bottomSheet, lightbox,
loading, toast, commandPalette,
notificationCenter.
|
forgedialog/workflows |
form, formWizard, wizard. |
forgedialog/interactions |
Bộ điều khiển kéo thả. Có tác dụng phụ: chỉ cần import là kéo thả được bật. |
forgedialog/animations |
Các hiệu ứng dựng sẵn. Có tác dụng phụ: chỉ cần import là hiệu ứng được bật. |
forgedialog/appearance |
Bộ áp giao diện đầy đủ. Có tác dụng phụ: import nó là nâng cấp các điểm vào chuyên biệt. |
forgedialog/react |
useForgeDialog() cho React. |
forgedialog/vue |
useForgeDialog() cho Vue. |
forgedialog/svelte |
Action dialogTrigger. |
forgedialog/web-component |
defineForgeDialog() và ForgeDialogElement. |
Import theo năng lực
Các điểm vào chuyên biệt (/alert, /confirm,
/prompt) đi kèm bộ áp giao diện nhẹ, chỉ gồm độ mờ nền, lớp phủ, viền, và
các bóng dựng sẵn. Thêm năng lực bằng cách import chúng để lấy tác dụng phụ:
import 'forgedialog/appearance'; // per-component colour, radius, hover
import 'forgedialog/interactions'; // dragging
import 'forgedialog/animations'; // animation presets
import { alert } from 'forgedialog/alert';
forgedialog và forgedialog/core đã có sẵn bộ áp giao diện đầy
đủ, nên chỉ cần import thêm khi bạn dùng điểm vào chuyên biệt.
Tệp CSS
forgedialog/style.css là tệp gộp tất cả. Muốn gửi ít CSS hơn thì chỉ ghép
các lớp mà trang thật sự dùng — core.css thì luôn bắt buộc.
import 'forgedialog/style/core.css'; // required
import 'forgedialog/style/forms.css'; // form fields and file dropzones
import 'forgedialog/style/workflows.css'; // wizard stepper
import 'forgedialog/style/toast.css';
import 'forgedialog/style/lightbox.css';
import 'forgedialog/style/command.css';
import 'forgedialog/style/draggable.css';
Mọi quy tắc đều nằm trong cascade layer forgedialog, nên CSS không đặt
trong layer của bạn sẽ thắng mà không cần !important.
alert, confirm, prompt
Bản thay thế trả về promise cho các hàm dựng sẵn của trình duyệt.
| Chữ ký hàm | Trả về |
|---|---|
alert(message, options?) |
Promise<void> |
confirm(message, options?) |
Promise<boolean> — false khi đóng bằng Escape
hoặc click nền
|
prompt(message, options?) |
Promise<string | null> — null khi bị huỷ |
await alert('Saved successfully.', { title: 'Success' });
const ok = await confirm('Delete this item?', { title: 'Please confirm' });
const name = await prompt('What is your name?', {
defaultValue: 'Ada Lovelace',
inputType: 'text',
inputLabel: 'Full name',
placeholder: 'Type a name',
validate: (value) => (value.trim() ? true : 'Name is required'),
});
alert và confirm tự động nhận role="alertdialog".
prompt nhận thêm các tuỳ chọn ở trên, bên cạnh mọi trường của
DialogOptions.
open()
API tầng thấp. Nó trả về DialogInstance ngay lập tức chứ không phải promise, nên hộp thoại có thể được cập nhật, di chuyển, hoặc đóng từ bất cứ đâu.
import { open } from 'forgedialog';
const dialog = open({
title: 'Custom dialog',
content: (container) => container.append(renderForm()),
buttons: [
{ text: 'Cancel', onClick: (i) => i.close(null) },
{ text: 'Save', role: 'primary', autoFocus: true, onClick: (i) => i.close(read()) },
],
});
const result = await dialog.whenClosed(); // the result, or undefined
const { result: r, reason } = await dialog.whenSettled(); // result plus why it closed
Nội dung và HTML không tin cậy
content nhận một chuỗi (hiển thị dưới dạng văn bản), một
phần tử, hoặc một hàm dựng. Còn HTML thì phải quyết định rõ ràng:
// Untrusted markup: pass a sanitizer.
open({ html: userContent, sanitizeHtml: (h) => DOMPurify.sanitize(h) });
// Markup you already trust.
open({ unsafeHtml: '<p>Generated by us</p>' });
Lý do đóng
Mỗi lần đóng đều kèm một lý do: 'button', 'escape',
'backdrop', 'api', 'abort', hoặc
'destroy'. Đọc nó bằng whenSettled().
DialogOptions
Được nhận bởi open() và mọi hàm tiện ích dựng trên nó.
| Tuỳ chọn | Kiểu | Mô tả |
|---|---|---|
title |
string |
Chữ ở thanh tiêu đề. Nếu bỏ trống, hộp thoại vẫn có nhãn ẩn về mặt thị giác để công nghệ hỗ trợ gọi được tên nó. |
message |
string | HTMLElement |
Văn bản hoặc phần tử cho phần thân. |
content |
string | HTMLElement | (container) => void |
Nội dung phần thân. Chuỗi được hiển thị dưới dạng văn bản. |
html |
string |
HTML, chỉ được hiển thị khi có kèm sanitizeHtml. |
unsafeHtml |
string |
HTML chèn nguyên trạng. Chỉ dùng cho nội dung bạn kiểm soát được. |
sanitizeHtml |
(html: string) => string |
Hàm làm sạch áp cho html. |
buttons |
ButtonConfig[] |
Các nút ở chân hộp thoại. Xem bên dưới. |
type |
'alert' | 'confirm' | 'prompt' | 'form' | 'wizard' | 'custom'
|
Loại ngữ nghĩa. alert và confirm mặc định dùng
role="alertdialog".
|
role |
'dialog' | 'alertdialog' |
Ghi đè role suy ra từ type. |
size |
'sm' | 'md' | 'lg' | 'xl' | 'fullscreen' |
Bề rộng dựng sẵn. |
presentation |
'modal' | 'drawer-left' | 'drawer-right' | 'bottom-sheet' | 'lightbox'
|
Cách hộp thoại xuất hiện và vị trí nó nằm. |
animation |
'fade' | 'scale' | 'slide' | 'spring' | 'bounce' | 'blur' | 'none'
|
Cần năng lực animations. Tôn trọng prefers-reduced-motion. |
appearance |
DialogAppearance |
Tạo kiểu riêng cho từng hộp thoại. Xem Giao diện. |
draggable |
boolean | DraggableOptions |
Xem Kéo thả. |
closable |
boolean |
Hiện nút đóng ở thanh tiêu đề. Mặc định true. |
closeOnEscape |
boolean |
Mặc định true. |
closeOnOverlayClick |
boolean |
Mặc định true. |
initialFocus |
string | HTMLElement | (root) => HTMLElement | null |
Phần tử nhận tiêu điểm khi mở. Mặc định là phần tử tab được đầu tiên. |
restoreFocus |
boolean |
Trả tiêu điểm về phần tử đã mở hộp thoại khi đóng. Mặc định true.
|
portalTarget |
HTMLElement |
Nơi hộp thoại được gắn vào. Mặc định là document.body. |
className |
string |
Các class thêm vào phần tử hộp thoại. |
labels |
Partial<DialogLabels> |
Ghi đè nhãn cho riêng hộp thoại này. |
signal |
AbortSignal |
Huỷ bỏ sẽ đóng hộp thoại với lý do 'abort'. |
data |
unknown |
Dữ liệu tuỳ ý, đọc được từ các hook. |
onOpen |
(instance) => void | Promise<void> |
Sau khi hộp thoại mở. |
onBeforeClose |
(instance, result) => boolean | void | Promise<…> |
Trả về false để giữ nó mở. |
onClose |
(instance, result) => void | Promise<void> |
Sau khi hộp thoại đóng. |
onError |
(error, instance) => void |
Theo dõi lỗi trong vòng đời, những lỗi này được dọn dẹp tự động. |
ButtonConfig
| Trường | Kiểu | Mô tả |
|---|---|---|
text |
string |
Nhãn. Bắt buộc. |
role |
'primary' | 'secondary' | 'danger' |
Mức nhấn thị giác. |
onClick |
(instance) => void | Promise<void> |
Hàm xử lý khi bấm. |
closesDialog |
boolean |
Đóng hộp thoại sau khi chạy onClick. |
result |
TResult |
Giá trị hộp thoại trả về khi nút này đóng nó. |
autoFocus |
boolean |
Nhận tiêu điểm khi mở. |
disabled |
boolean |
Hiển thị nút ở trạng thái vô hiệu. |
id |
string |
Id của phần tử, tiện cho việc kiểm thử. |
DialogInstance
| Thành phần | Trả về | Mô tả |
|---|---|---|
open() |
Promise<void> |
Mở một hộp thoại chưa được mở. |
close(result?, reason?) |
Promise<void> |
Đóng kèm một kết quả. |
cancel(reason?) |
Promise<void> |
Đóng mà không có kết quả. |
destroy() |
Promise<void> |
Đóng rồi gỡ bỏ phần tử cùng các listener của nó. |
update(partialOptions) |
void |
Đổi kiểu hoặc vẽ lại hộp thoại tại chỗ, ngay khi nó đang mở. |
whenClosed() |
Promise<TResult | undefined> |
Trả về kết quả. |
whenSettled() |
Promise<{ result, reason }> |
Trả về kết quả kèm lý do đóng. |
isOpen() |
boolean |
Hộp thoại có đang mở hay không. |
getState() |
DialogState |
'idle' | 'opening' | 'open' | 'closing' | 'closed' | 'destroyed'.
|
getPosition() |
{ x, y } |
Độ dịch chuyển kéo hiện tại. |
setPosition({ x, y }) |
{ x, y } |
Di chuyển hộp thoại, giới hạn trong vùng cho phép. |
resetPosition() |
void |
Đưa nó về giữa. |
element |
HTMLElement |
Phần tử hộp thoại. |
id |
string |
Id duy nhất. |
Giao diện
Các tuỳ chỉnh giao diện chỉ áp cho một hộp thoại và đổi được lúc chạy bằng
update(). Giá trị độ mờ bị kẹp trong khoảng 0..1; số trần cho
độ dày, bo góc, và độ nhoè được hiểu là pixel.
| Trường | Kiểu | Áp dụng cho |
|---|---|---|
opacity |
number |
Toàn bộ nền hộp thoại. |
surfaceColor |
string |
Nền hộp thoại. |
overlayOpacity |
number |
Lớp phủ phía sau nó. |
backdropBlur |
number | string |
Bán kính làm mờ lớp phủ. |
titleColor |
string |
Chữ ở thanh tiêu đề. |
titleBackground |
string |
Nền thanh tiêu đề. Mặc định trong suốt và bị cắt theo góc bo của hộp thoại. |
titleOpacity |
number |
Thanh tiêu đề. |
contentColor |
string |
Chữ ở phần thân. |
contentOpacity |
number |
Phần thân. |
borderColor |
string |
Viền. |
borderOpacity |
number |
Viền. |
borderWidth |
number | string |
Viền. |
borderStyle |
'none' | 'solid' | 'dashed' | 'dotted' | 'double' |
Viền. |
radius |
number | string | DialogCornerRadius |
Các góc. Xem Bo góc. |
shadow |
ShadowPreset | string | DialogShadowConfig |
Xem Đổ bóng. |
hover |
DialogHoverAppearance |
Xem Hover. |
open({
title: 'Styled',
appearance: {
opacity: 0.96,
surfaceColor: '#12141a',
overlayOpacity: 0.55,
backdropBlur: 12,
titleColor: '#ffd166',
titleBackground: '#1b1740',
contentColor: '#c8ccd4',
borderColor: '#7c5cff',
borderWidth: 2,
radius: 20,
shadow: { angle: 135, distance: 24, blur: 60, opacity: 0.45 },
},
});
Bộ áp đầy đủ đi kèm forgedialog và forgedialog/core. Với điểm
vào chuyên biệt, hãy thêm import 'forgedialog/appearance' — không có nó thì
các trường nâng cao bị bỏ qua chứ không báo lỗi.
Đổ bóng
shadow nhận ba dạng.
| Dạng | Ví dụ |
|---|---|
| Bóng dựng sẵn |
shadow: 'xl' — một trong none, sm,
md, lg, xl
|
| Bất kỳ giá trị box-shadow nào của CSS | shadow: '0 10px 40px rgb(0 0 0 / 30%)' |
| Ghép từ các thành phần | shadow: { angle: 90, distance: 18, blur: 48, opacity: 0.3 } |
| Thành phần | Kiểu | Ý nghĩa |
|---|---|---|
angle |
number |
Hướng bóng đổ, tính bằng độ: 0 lên trên, 90 sang phải,
180 xuống dưới (mặc định), 270 sang trái.
|
distance |
number | string |
Bóng bị hắt đi xa bao nhiêu. |
blur |
number | string |
Độ mềm. |
spread |
number | string |
Độ nở ra trước khi làm mờ. |
color |
string |
Màu bóng. |
opacity |
number |
Độ đậm, 0..1. |
inset |
boolean |
Đổ bóng vào phía trong. |
Bo góc
radius nhận một giá trị dùng chung cho mọi góc, bất kỳ chuỗi
border-radius nào của CSS, hoặc một object khai theo từng góc. Góc không có
trong object đó vẫn giữ bo góc của chủ đề chứ không tụt về 0.
appearance: { radius: 20 }
appearance: { radius: '20px 20px 4px 4px' }
appearance: { radius: { topLeft: 24, topRight: 24, bottomRight: 4, bottomLeft: 4 } }
Drawer giữ góc vuông và bottom sheet chỉ bo hai góc trên, trừ khi
radius nói khác.
Hover
hover chỉ đổi kiểu hộp thoại khi con trỏ đang ở trên nó, và chỉ với hộp
thoại có yêu cầu — mọi hộp thoại khác đứng yên hoàn toàn. Nó dùng lại các trường màu, bo
góc, và đổ bóng, cộng thêm ba trường riêng.
| Trường | Kiểu | Mô tả |
|---|---|---|
lift |
number | string |
Hộp thoại nhấc lên bao nhiêu. |
scale |
number |
Hệ số phóng, ví dụ 1.02. |
duration |
number | string |
Thời lượng chuyển động. |
Biến đổi khi hover tôn trọng prefers-reduced-motion và bị tạm ngưng trong
lúc kéo hộp thoại, nên không thể đẩy nó ra ngoài vùng giới hạn.
Kéo thả
draggable: true là đủ để kéo hộp thoại bằng thanh tiêu đề. Dạng object thêm
ràng buộc, hỗ trợ bàn phím, và ghi nhớ vị trí. Kéo thả cần năng lực interactions, thứ mà
forgedialog đã bật sẵn cho bạn.
| Tuỳ chọn | Kiểu | Mô tả |
|---|---|---|
handle |
'header' | string | HTMLElement |
Thứ khởi động thao tác kéo. Mặc định là thanh tiêu đề. |
axis |
'both' | 'x' | 'y' |
Khoá chuyển động theo một trục. |
bounds |
'viewport' | HTMLElement | DOMRect |
Vùng mà hộp thoại bị giới hạn trong đó. |
initialPosition |
{ x, y } |
Vị trí lệch ban đầu. |
keyboard |
boolean |
Di chuyển bằng phím mũi tên khi tay cầm đang có tiêu điểm. |
keyboardStep |
number |
Số pixel mỗi lần nhấn phím. |
persistKey |
string |
Ghi nhớ vị trí qua các phiên dưới khoá này. |
onDragStart / onDrag / onDragEnd |
(event) => void |
Mỗi hàm nhận { position, originalEvent }. |
Bottom sheet giữ cử chỉ vuốt để đóng của riêng nó và bỏ qua kéo thả thông thường.
Drawer, sheet, lightbox, trạng thái tải
import { drawer, bottomSheet, lightbox, loading } from 'forgedialog';
drawer({ title: 'Settings', side: 'right', content: renderSettings });
bottomSheet({ title: 'Share', content: renderShare });
lightbox('/photo.jpg', { alt: 'A photo', caption: 'Taken in 2026' });
const task = loading('Uploading…');
task.update('Almost there…');
await task.close();
Đây chỉ là open() kèm một giá trị presentation dựng sẵn, nên
mọi trường của DialogOptions vẫn dùng được.
Biểu mẫu
form() dựng một hộp thoại có kiểm tra từ danh sách trường và trả về các giá
trị, hoặc null nếu bị huỷ. Tên trường được suy ra vào kiểu kết quả, nên
values.email đã có kiểu mà không cần ép.
import { form } from 'forgedialog';
const values = await form(
[
{ name: 'email', type: 'email', label: 'Email', required: true },
{ name: 'plan', type: 'select', label: 'Plan', options: [
{ value: 'free', label: 'Free' },
{ value: 'pro', label: 'Pro' },
] },
{ name: 'notes', type: 'textarea', label: 'Notes', rows: 4 },
],
{ title: 'Sign up', submitText: 'Create account' },
);
Các kiểu trường: text, password, email,
number, date, textarea, select,
checkbox, radio, file. Mỗi trường nhận
label, defaultValue, placeholder,
helpText, required, và một hàm validate; kiểu số
có thêm min, max, step, còn kiểu tệp có thêm
accept, multiple, maxFiles, và
maxSizeBytes.
formWizard(steps, options?) trải đúng các trường đó ra nhiều bước, kèm
nextText, backText, finishText, và callback
onStepChange.
Wizard
wizard() là dạng tổng quát: mỗi bước tự vẽ nội dung tuỳ ý, có thể kiểm tra
dữ liệu, và có thể chọn bước kế tiếp dựa trên dữ liệu đã thu thập.
import { wizard } from 'forgedialog';
const flow = wizard({
initialData: { email: '', plan: 'free' },
persistKey: 'signup', // resumes where the user left off
confirmUnsaved: true, // asks before discarding progress
steps: [
{ id: 'account', title: 'Account', render: renderAccount, validate: validateAccount },
{ id: 'plan', title: 'Plan', render: renderPlan,
next: (data) => (data.plan === 'pro' ? 'billing' : 'review') },
{ id: 'billing', title: 'Billing', render: renderBilling },
{ id: 'review', title: 'Review', render: renderReview },
],
});
const data = await flow.result; // the data, or null if cancelled
Bộ điều khiển còn cung cấp next(), back(),
goTo(stepId), getData(), và instance bên dưới.
Toast và thông báo
import { toast, notificationCenter, getNotificationHistory } from 'forgedialog';
toast('Saved', { tone: 'success' });
// A duration of 0 or Infinity keeps it up until dismiss() is called.
const upload = toast('Uploading…', { duration: 0 });
upload.dismiss();
toast('Message sent', { action: { text: 'Undo', onClick: undoSend } });
notificationCenter(); // a dialog listing past toasts
getNotificationHistory(); // the same list as data
Các sắc thái gồm info, success, warning, và
danger. clearNotificationHistory() xoá sạch nhật ký.
Bảng lệnh
import { commandPalette } from 'forgedialog';
commandPalette([
{ id: 'new', label: 'New document', shortcut: '⌘N', run: createDocument },
{ id: 'search', label: 'Search', keywords: ['find', 'filter'], run: openSearch },
]);
Gõ để lọc theo nhãn và theo keywords; bảng lệnh trả về id của lệnh đã chạy.
Chủ đề
import { setTheme, getTheme, setThemePreset } from 'forgedialog';
setTheme('dark'); // 'light' | 'dark' | 'system'
getTheme();
setThemePreset('glass'); // 'default' | 'minimal' | 'glass' | 'material'
setTheme() ghi data-fd-theme lên <html>.
CSS của bạn có thể đọc chính thuộc tính đó để trang và hộp thoại đổi chủ đề cùng lúc —
đây đúng là cách site này làm.
Biến CSS
Mọi thứ thuộc về hình thức đều là một biến trên :root, nên viết được cả một
chủ đề mà không đụng tới JavaScript.
| Biến | Mặc định |
|---|---|
--fd-color-surface |
#ffffff |
--fd-color-text |
#1a1d23 |
--fd-color-text-muted |
#5b6270 |
--fd-color-border |
#e2e4e9 |
--fd-color-overlay |
rgba(15, 17, 21, 0.5) |
--fd-color-primary / --fd-color-primary-text |
#315fce / #ffffff |
--fd-color-secondary / --fd-color-secondary-text
|
#eceef2 / #1a1d23 |
--fd-color-danger / --fd-color-danger-text |
#e5484d / #ffffff |
--fd-radius |
10px |
--fd-shadow |
0 20px 60px rgba(15, 17, 21, 0.25) |
--fd-spacing-sm / md / lg |
8px / 16px / 24px |
--fd-font-family |
bộ phông hệ thống |
--fd-duration-fast / --fd-duration-normal |
120ms / 200ms |
--fd-easing |
cubic-bezier(0.16, 1, 0.3, 1) |
--fd-z-index-base |
1000 |
Các biến riêng từng hộp thoại mà appearance API ghi ra (--fd-dialog-radius,
--fd-dialog-shadow, --fd-dialog-title-background, và những cái
còn lại) cũng đặt tay được, nếu bạn thích tạo kiểu bằng CSS hơn bằng JavaScript.
Nhãn và đa ngôn ngữ
import { setLabels, getLabels } from 'forgedialog';
setLabels({
ok: 'Đồng ý',
cancel: 'Huỷ',
close: 'Đóng',
submit: 'Gửi',
fieldRequired: 'Bắt buộc',
promptPlaceholder: 'Nhập nội dung',
notifications: 'Thông báo',
});
Nhãn đặt theo cách này áp dụng ở mọi nơi; từng hộp thoại vẫn ghi đè được bằng tuỳ chọn
labels của riêng nó.
Plugin và hook
Năm hook vòng đời chạy cho mọi hộp thoại: beforeOpen,
afterOpen, beforeClose, afterClose, và
beforeDestroy.
import { on, off, registerPlugin } from 'forgedialog';
// A single hook.
on('afterOpen', ({ instance, options }) => track('dialog', options.title));
// Or a plugin bundling several.
registerPlugin({
name: 'analytics',
install: (api) => api.on('afterClose', ({ reason }) => track('close', reason)),
hooks: {
beforeClose: ({ preventClose, result }) => {
if (result === undefined) preventClose?.();
},
},
});
Mỗi hook nhận { instance, options, result, reason, preventClose }. Gọi
preventClose() trong beforeClose sẽ giữ hộp thoại mở.
Adapter cho framework
Mỗi adapter là một lớp bọc mỏng quanh open(), gắn vòng đời hộp thoại vào
vòng đời component, nên không còn gì sót lại sau khi component bị gỡ.
// React and Vue share the same hook shape.
import { useForgeDialog } from 'forgedialog/react';
const { open } = useForgeDialog();
await open({ title: 'Hi' }).whenClosed();
// Svelte: an action on the triggering element.
import { dialogTrigger } from 'forgedialog/svelte';
// <button use:dialogTrigger={{ title: 'Hi' }}>Open</button>
// Web component.
import { defineForgeDialog } from 'forgedialog/web-component';
defineForgeDialog(); // <forge-dialog open title="Hi" message="…" size="md">
TypeScript, SSR, và CSP
-
Có kiểu cho cả ESM lẫn CJS.
open<T>()luồn kiểu kết quả của nó quabuttons,whenClosed(), và các hook. - Import gói này trên máy chủ không đụng tới DOM, nên an toàn với bản dựng SSR; hộp thoại chỉ được tạo khi bạn gọi API trong trình duyệt.
-
Bản build không chứa
evalvànew Function, điều này được kiểm tra trong CI, nên nó chạy được dưới Content Security Policy nghiêm ngặt. Chính site này cũng đang chạy dưới một CSP như vậy. - Mọi điểm vào đều có hạn mức gzip bắt buộc, kiểm tra ở từng pull request.