@ttdk-design-system/library-react 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI_GUIDE.md +6518 -0
- package/llms.txt +6518 -0
- package/package.json +1098 -4
- package/src/core/index.ts +2 -0
- package/src/core/tailwind-preset.cjs +62 -0
- package/src/core/tailwind-preset.ts +85 -0
- package/src/core/theme/tokens.css +663 -0
- package/src/core/types.ts +836 -0
- package/src/index.ts +17 -0
- package/src/tailwind-preset.cjs +62 -0
- package/src/tailwind-preset.ts +85 -0
- package/src/types.ts +1 -0
- package/src/web/accordion/AI_GUIDE.md +149 -0
- package/src/web/accordion/accordion.css +1 -0
- package/src/web/accordion/accordion.tsx +430 -0
- package/src/web/accordion/index.ts +3 -0
- package/src/web/accordion/manifest.json +351 -0
- package/src/web/alert/AI_GUIDE.md +139 -0
- package/src/web/alert/alert.css +1 -0
- package/src/web/alert/alert.tsx +318 -0
- package/src/web/alert/index.ts +3 -0
- package/src/web/alert/manifest.json +240 -0
- package/src/web/avatar/AI_GUIDE.md +118 -0
- package/src/web/avatar/avatar.css +1 -0
- package/src/web/avatar/avatar.tsx +233 -0
- package/src/web/avatar/index.ts +3 -0
- package/src/web/avatar/manifest.json +195 -0
- package/src/web/badge/AI_GUIDE.md +94 -0
- package/src/web/badge/badge.css +1 -0
- package/src/web/badge/badge.tsx +140 -0
- package/src/web/badge/index.ts +2 -0
- package/src/web/badge/manifest.json +141 -0
- package/src/web/banner/AI_GUIDE.md +130 -0
- package/src/web/banner/banner.css +1 -0
- package/src/web/banner/banner.tsx +334 -0
- package/src/web/banner/index.ts +3 -0
- package/src/web/banner/manifest.json +240 -0
- package/src/web/breadcrumb/AI_GUIDE.md +120 -0
- package/src/web/breadcrumb/breadcrumb.css +1 -0
- package/src/web/breadcrumb/breadcrumb.tsx +306 -0
- package/src/web/breadcrumb/index.ts +3 -0
- package/src/web/breadcrumb/manifest.json +225 -0
- package/src/web/button/AI_GUIDE.md +121 -0
- package/src/web/button/button.css +1 -0
- package/src/web/button/button.tsx +287 -0
- package/src/web/button/index.ts +2 -0
- package/src/web/button/manifest.json +177 -0
- package/src/web/calendar/AI_GUIDE.md +151 -0
- package/src/web/calendar/calendar.css +1 -0
- package/src/web/calendar/calendar.tsx +1611 -0
- package/src/web/calendar/index.ts +3 -0
- package/src/web/calendar/manifest.json +470 -0
- package/src/web/card/AI_GUIDE.md +133 -0
- package/src/web/card/card.css +1 -0
- package/src/web/card/card.tsx +408 -0
- package/src/web/card/index.ts +4 -0
- package/src/web/card/manifest.json +357 -0
- package/src/web/checkbox/AI_GUIDE.md +146 -0
- package/src/web/checkbox/checkbox.css +1 -0
- package/src/web/checkbox/checkbox.tsx +307 -0
- package/src/web/checkbox/index.ts +2 -0
- package/src/web/checkbox/manifest.json +294 -0
- package/src/web/chip/AI_GUIDE.md +186 -0
- package/src/web/chip/chip.css +1 -0
- package/src/web/chip/chip.tsx +230 -0
- package/src/web/chip/index.ts +2 -0
- package/src/web/chip/manifest.json +186 -0
- package/src/web/dropdown/AI_GUIDE.md +167 -0
- package/src/web/dropdown/dropdown.css +1 -0
- package/src/web/dropdown/dropdown.tsx +1274 -0
- package/src/web/dropdown/index.ts +3 -0
- package/src/web/dropdown/manifest.json +576 -0
- package/src/web/flex/AI_GUIDE.md +113 -0
- package/src/web/flex/flex-item.tsx +97 -0
- package/src/web/flex/flex.css +1 -0
- package/src/web/flex/flex.tsx +108 -0
- package/src/web/flex/index.ts +5 -0
- package/src/web/flex/manifest.json +162 -0
- package/src/web/form/index.ts +7 -0
- package/src/web/grid/AI_GUIDE.md +112 -0
- package/src/web/grid/grid-item.tsx +112 -0
- package/src/web/grid/grid.css +1 -0
- package/src/web/grid/grid.tsx +99 -0
- package/src/web/grid/index.ts +5 -0
- package/src/web/grid/manifest.json +153 -0
- package/src/web/index.ts +86 -0
- package/src/web/input/AI_GUIDE.md +159 -0
- package/src/web/input/index.ts +3 -0
- package/src/web/input/input.css +1 -0
- package/src/web/input/input.tsx +537 -0
- package/src/web/input/manifest.json +465 -0
- package/src/web/input-number/AI_GUIDE.md +164 -0
- package/src/web/input-number/index.ts +3 -0
- package/src/web/input-number/input-number.css +1 -0
- package/src/web/input-number/input-number.tsx +1193 -0
- package/src/web/input-number/manifest.json +575 -0
- package/src/web/modal/AI_GUIDE.md +171 -0
- package/src/web/modal/index.ts +3 -0
- package/src/web/modal/manifest.json +375 -0
- package/src/web/modal/modal.css +1 -0
- package/src/web/modal/modal.tsx +571 -0
- package/src/web/pagination/AI_GUIDE.md +148 -0
- package/src/web/pagination/index.ts +21 -0
- package/src/web/pagination/manifest.json +432 -0
- package/src/web/pagination/pagination-content.tsx +45 -0
- package/src/web/pagination/pagination-ellipsis.tsx +54 -0
- package/src/web/pagination/pagination-first.tsx +155 -0
- package/src/web/pagination/pagination-item.tsx +45 -0
- package/src/web/pagination/pagination-last.tsx +155 -0
- package/src/web/pagination/pagination-link.tsx +121 -0
- package/src/web/pagination/pagination-next.tsx +158 -0
- package/src/web/pagination/pagination-previous.tsx +158 -0
- package/src/web/pagination/pagination.css +1 -0
- package/src/web/pagination/pagination.tsx +687 -0
- package/src/web/popover/AI_GUIDE.md +163 -0
- package/src/web/popover/index.ts +3 -0
- package/src/web/popover/manifest.json +396 -0
- package/src/web/popover/popover.css +1 -0
- package/src/web/popover/popover.tsx +702 -0
- package/src/web/radio/AI_GUIDE.md +155 -0
- package/src/web/radio/index.ts +2 -0
- package/src/web/radio/manifest.json +294 -0
- package/src/web/radio/radio.css +1 -0
- package/src/web/radio/radio.tsx +290 -0
- package/src/web/selectbox/AI_GUIDE.md +216 -0
- package/src/web/selectbox/index.ts +3 -0
- package/src/web/selectbox/manifest.json +477 -0
- package/src/web/selectbox/selectbox.css +1 -0
- package/src/web/selectbox/selectbox.tsx +1048 -0
- package/src/web/sonner/AI_GUIDE.md +98 -0
- package/src/web/sonner/index.ts +114 -0
- package/src/web/sonner/manifest.json +132 -0
- package/src/web/sonner/sonner.css +1 -0
- package/src/web/sonner/sonner.tsx +177 -0
- package/src/web/table/AI_GUIDE.md +145 -0
- package/src/web/table/index.ts +35 -0
- package/src/web/table/manifest.json +168 -0
- package/src/web/table/table-body.tsx +45 -0
- package/src/web/table/table-caption.tsx +45 -0
- package/src/web/table/table-cell.tsx +74 -0
- package/src/web/table/table-empty.tsx +108 -0
- package/src/web/table/table-footer.tsx +45 -0
- package/src/web/table/table-head.tsx +80 -0
- package/src/web/table/table-header.tsx +45 -0
- package/src/web/table/table-row.tsx +69 -0
- package/src/web/table/table.css +1 -0
- package/src/web/table/table.tsx +305 -0
- package/src/web/tabs/AI_GUIDE.md +150 -0
- package/src/web/tabs/index.ts +3 -0
- package/src/web/tabs/manifest.json +315 -0
- package/src/web/tabs/tabs.css +1 -0
- package/src/web/tabs/tabs.tsx +332 -0
- package/src/web/text/AI_GUIDE.md +129 -0
- package/src/web/text/index.ts +3 -0
- package/src/web/text/manifest.json +195 -0
- package/src/web/text/text.css +1 -0
- package/src/web/text/text.tsx +689 -0
- package/src/web/textarea/AI_GUIDE.md +141 -0
- package/src/web/textarea/index.ts +3 -0
- package/src/web/textarea/manifest.json +438 -0
- package/src/web/textarea/textarea.css +1 -0
- package/src/web/textarea/textarea.tsx +467 -0
- package/src/web/tooltip/AI_GUIDE.md +110 -0
- package/src/web/tooltip/index.ts +3 -0
- package/src/web/tooltip/manifest.json +222 -0
- package/src/web/tooltip/tooltip.css +1 -0
- package/src/web/tooltip/tooltip.tsx +423 -0
- package/src/webview/bottomsheet/AI_GUIDE.md +141 -0
- package/src/webview/bottomsheet/bottomsheet.css +1 -0
- package/src/webview/bottomsheet/bottomsheet.tsx +603 -0
- package/src/webview/bottomsheet/index.ts +4 -0
- package/src/webview/bottomsheet/manifest.json +377 -0
- package/src/webview/button/AI_GUIDE.md +79 -0
- package/src/webview/button/button-ios.css +1 -0
- package/src/webview/button/button-ios.tsx +138 -0
- package/src/webview/button/button-material.css +1 -0
- package/src/webview/button/button-material.tsx +138 -0
- package/src/webview/button/index.ts +7 -0
- package/src/webview/button/manifest.json +148 -0
- package/src/webview/index.ts +7 -0
- package/tailwind-preset.cjs +62 -0
- package/tailwind-preset.js +62 -0
- package/ttdk-manifest.json +10188 -0
- package/README.md +0 -3
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# <Modal /> — TTDK Component Reference
|
|
2
|
+
|
|
3
|
+
Komponen Modal TTDK Design System — Selaras dengan Spesifikasi Nuxt UI Modal (UModal): - Mode controlled (v-model:open / open) dan uncontrolled (defaultOpen) - Backdrop blur overlay redup dengan penguncian scroll latar belakang otomatis (preventScroll) - Pilihan ukuran responsif ('xs' s/d '5xl' serta 'fullscreen') - Struktur slot terstandarisasi (#header, #body, #footer, #content) - Penanganan dismissible & preventClose (Escape key, backdrop click, callback onClosePrevent) - Animasi scale-in dan efek visual getar (shake) saat penutupan dicegah
|
|
4
|
+
|
|
5
|
+
## 1. Stylesheets & Theming (Pure CSS)
|
|
6
|
+
Import the corresponding stylesheet for the theme you wish to use:
|
|
7
|
+
- **COMMON Theme**: `import "@ttdk-design-system/library-<react|vue|svelte>/web/modal/modal.css";`
|
|
8
|
+
|
|
9
|
+
## 2. Subpath Component Import
|
|
10
|
+
```ts
|
|
11
|
+
// React
|
|
12
|
+
import Modal from "@ttdk-design-system/library-react/web/modal";
|
|
13
|
+
|
|
14
|
+
// Vue 3
|
|
15
|
+
import Modal from "@ttdk-design-system/library-vue/web/modal";
|
|
16
|
+
|
|
17
|
+
// Svelte
|
|
18
|
+
import Modal from "@ttdk-design-system/library-svelte/web/modal";
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 3. Props & API Reference
|
|
22
|
+
|
|
23
|
+
| Prop | Type | Default | Description |
|
|
24
|
+
| :--- | :--- | :--- | :--- |
|
|
25
|
+
| `open?` | `boolean` | `-` | Status visibilitas modal (mode terkontrol / controlled state). Mendukung `v-model:open` / `v-model` pada Vue 3 dan controlled prop `open` pada React. |
|
|
26
|
+
| `defaultOpen?` | `boolean` | `false` | Status visibilitas awal saat pertama kali dirender (uncontrolled initial state). |
|
|
27
|
+
| `title?` | `string` | `-` | Judul teks di bagian header modal. |
|
|
28
|
+
| `description?` | `string` | `-` | Deskripsi penjelasan di bagian header modal di bawah judul. |
|
|
29
|
+
| `close?` | `boolean | any` | `true` | Menampilkan tombol tutup 'X' di pojok kanan atas header. Berikan `false` untuk menyembunyikan tombol tutup. |
|
|
30
|
+
| `closeIcon?` | `any` | `-` | Ikon kustom untuk tombol tutup. |
|
|
31
|
+
| `fullscreen?` | `boolean` | `false` | Menjadikan modal tampil dalam ukuran layar penuh (fullscreen 100vw x 100vh). |
|
|
32
|
+
| `size?` | `ModalSize` | `md` | Skala ukuran lebar maksimum modal dialog ('xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | 'full'). |
|
|
33
|
+
| `dismissible?` | `boolean` | `true` | Mengizinkan modal ditutup saat pengguna mengeklik latar belakang (backdrop) atau menekan tombol `Escape`. |
|
|
34
|
+
| `preventClose?` | `boolean` | `false` | Mencegah modal ditutup saat klik di luar atau tombol `Escape` (alias selaras Nuxt UI prevent-close). Jika bernilai `true`, popover/modal tidak dapat ditutup kecuali melalui tombol aksi eksplisit di dalam modal. |
|
|
35
|
+
| `overlay?` | `boolean` | `true` | Menampilkan lapisan latar belakang redup (backdrop overlay). |
|
|
36
|
+
| `modal?` | `boolean` | `true` | Menjadikan modal sebagai dialog modal yang memusatkan fokus interaksi pengguna. |
|
|
37
|
+
| `scrollable?` | `boolean` | `true` | Mengaktifkan area konten body yang dapat digulir jika isi modal melebihi tinggi layar. |
|
|
38
|
+
| `preventScroll?` | `boolean` | `true` | Mengunci scrolling halaman web latar belakang saat modal sedang terbuka (body scroll lock). |
|
|
39
|
+
| `lockScroll?` | `boolean` | `true` | Alias untuk `preventScroll`. |
|
|
40
|
+
| `content?` | `any` | `-` | Konten kustom untuk seluruh dialog (menggantikan header, body, dan footer default). |
|
|
41
|
+
| `header?` | `any` | `-` | Konten kustom untuk bagian header modal. |
|
|
42
|
+
| `body?` | `any` | `-` | Konten kustom untuk bagian isi utama (body) modal. |
|
|
43
|
+
| `footer?` | `any` | `-` | Konten kustom untuk bagian footer (biasanya tombol aksi Batal / Konfirmasi). |
|
|
44
|
+
| `ui?` | `ModalUiProps` | `-` | Kustomisasi CSS variables atau token visual melalui UiProps. |
|
|
45
|
+
| `className?` | `string` | `-` | Class CSS kustom pada elemen pembungkus terluar. |
|
|
46
|
+
| `class?` | `string` | `-` | Class CSS kustom (alias framework Vue). |
|
|
47
|
+
| `style?` | `any` | `-` | Style inline kustom pada kontainer dialog. |
|
|
48
|
+
| `overlayClass?` | `string` | `-` | Class CSS kustom untuk lapisan backdrop overlay. |
|
|
49
|
+
| `overlayStyle?` | `UiProps` | `-` | Style kustom untuk lapisan backdrop overlay (UiProps). |
|
|
50
|
+
| `contentClass?` | `string` | `-` | Class CSS kustom untuk kartu panel modal dialog. |
|
|
51
|
+
| `contentStyle?` | `UiProps` | `-` | Style kustom untuk kartu panel modal dialog (UiProps). |
|
|
52
|
+
| `headerClass?` | `string` | `-` | Class CSS kustom untuk header modal. |
|
|
53
|
+
| `headerStyle?` | `UiProps` | `-` | Style kustom untuk header modal (UiProps). |
|
|
54
|
+
| `bodyClass?` | `string` | `-` | Class CSS kustom untuk body modal. |
|
|
55
|
+
| `bodyStyle?` | `UiProps` | `-` | Style kustom untuk body modal (UiProps). |
|
|
56
|
+
| `footerClass?` | `string` | `-` | Class CSS kustom untuk footer modal. |
|
|
57
|
+
| `footerStyle?` | `UiProps` | `-` | Style kustom untuk footer modal (UiProps). |
|
|
58
|
+
| `onUpdateOpen?` | `(open: boolean) => void` | `-` | Callback event saat status terbuka/tertutup berubah (kompatibel dengan v-model:open pada Vue 3). |
|
|
59
|
+
| `onOpenChange?` | `(open: boolean) => void` | `-` | Callback event saat status terbuka/tertutup berubah (alias standar React). |
|
|
60
|
+
| `onOpen?` | `() => void` | `-` | Callback event saat modal terbuka. |
|
|
61
|
+
| `onClose?` | `() => void` | `-` | Callback event saat modal ditutup. |
|
|
62
|
+
| `onClosePrevent?` | `() => void` | `-` | Callback event saat pengguna mencoba menutup modal tetapi dicegah karena preventClose={true} atau dismissible={false}. |
|
|
63
|
+
| `children?` | `any` | `-` | Elemen pemicu (trigger), tombol, atau konten modal default. |
|
|
64
|
+
|
|
65
|
+
## 4. Usage Examples
|
|
66
|
+
|
|
67
|
+
### React Example
|
|
68
|
+
```tsx
|
|
69
|
+
import { useState } from "react";
|
|
70
|
+
import Modal from "@ttdk-design-system/library-react/web/modal";
|
|
71
|
+
import Button from "@ttdk-design-system/library-react/button";
|
|
72
|
+
import "@ttdk-design-system/library-react/web/modal/modal.css";
|
|
73
|
+
import "@ttdk-design-system/library-react/button/button.css";
|
|
74
|
+
|
|
75
|
+
export function Example() {
|
|
76
|
+
const [open, setOpen] = useState(false);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<>
|
|
80
|
+
<Button variant="primary" onClick={() => setOpen(true)}>
|
|
81
|
+
Buka Modal
|
|
82
|
+
</Button>
|
|
83
|
+
|
|
84
|
+
<Modal
|
|
85
|
+
open={open}
|
|
86
|
+
onOpenChange={setOpen}
|
|
87
|
+
title="Konfirmasi Tindakan Medis"
|
|
88
|
+
description="Pastikan data nakes dan rekam medis pasien sudah sesuai sebelum melanjutkan."
|
|
89
|
+
footer={
|
|
90
|
+
<div style={{ display: "flex", justifyContent: "flex-end", gap: "8px" }}>
|
|
91
|
+
<Button variant="ghost" onClick={() => setOpen(false)}>
|
|
92
|
+
Batal
|
|
93
|
+
</Button>
|
|
94
|
+
<Button variant="primary" onClick={() => setOpen(false)}>
|
|
95
|
+
Konfirmasi
|
|
96
|
+
</Button>
|
|
97
|
+
</div>
|
|
98
|
+
}
|
|
99
|
+
>
|
|
100
|
+
<p style={{ margin: 0, fontSize: "14px", color: "var(--ttdk-text-secondary)" }}>
|
|
101
|
+
Tindakan ini akan mencatat log integrasi data ke dalam platform SATUSEHAT Kementerian Kesehatan RI.
|
|
102
|
+
</p>
|
|
103
|
+
</Modal>
|
|
104
|
+
</>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Vue 3 Example
|
|
110
|
+
```vue
|
|
111
|
+
<script setup lang="ts">
|
|
112
|
+
import { ref } from "vue";
|
|
113
|
+
import Modal from "@ttdk-design-system/library-vue/web/modal";
|
|
114
|
+
import Button from "@ttdk-design-system/library-vue/button";
|
|
115
|
+
import "@ttdk-design-system/library-vue/web/modal/modal.css";
|
|
116
|
+
import "@ttdk-design-system/library-vue/button/button.css";
|
|
117
|
+
|
|
118
|
+
const isOpen = ref(false);
|
|
119
|
+
</script>
|
|
120
|
+
|
|
121
|
+
<template>
|
|
122
|
+
<Button variant="primary" @click="isOpen = true">
|
|
123
|
+
Buka Modal
|
|
124
|
+
</Button>
|
|
125
|
+
|
|
126
|
+
<Modal
|
|
127
|
+
v-model:open="isOpen"
|
|
128
|
+
title="Konfirmasi Tindakan Medis"
|
|
129
|
+
description="Pastikan data nakes dan rekam medis pasien sudah sesuai sebelum melanjutkan."
|
|
130
|
+
>
|
|
131
|
+
<template #body>
|
|
132
|
+
<p style="margin: 0; font-size: 14px; color: var(--ttdk-text-secondary)">
|
|
133
|
+
Tindakan ini akan mencatat log integrasi data ke dalam platform SATUSEHAT Kementerian Kesehatan RI.
|
|
134
|
+
</p>
|
|
135
|
+
</template>
|
|
136
|
+
<template #footer="{ close }">
|
|
137
|
+
<div style="display: flex; justify-content: flex-end; gap: 8px">
|
|
138
|
+
<Button variant="ghost" @click="close">Batal</Button>
|
|
139
|
+
<Button variant="primary" @click="close">Konfirmasi</Button>
|
|
140
|
+
</div>
|
|
141
|
+
</template>
|
|
142
|
+
</Modal>
|
|
143
|
+
</template>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Svelte Example
|
|
147
|
+
```svelte
|
|
148
|
+
<script lang="ts">
|
|
149
|
+
import Modal from "@ttdk-design-system/library-svelte/web/modal";
|
|
150
|
+
import Button from "@ttdk-design-system/library-svelte/button";
|
|
151
|
+
import "@ttdk-design-system/library-svelte/web/modal/modal.css";
|
|
152
|
+
import "@ttdk-design-system/library-svelte/button/button.css";
|
|
153
|
+
|
|
154
|
+
let isOpen = false;
|
|
155
|
+
</script>
|
|
156
|
+
|
|
157
|
+
<Button variant="primary" on:click={() => (isOpen = true)}>
|
|
158
|
+
Buka Modal
|
|
159
|
+
</Button>
|
|
160
|
+
|
|
161
|
+
<Modal
|
|
162
|
+
open={isOpen}
|
|
163
|
+
title="Konfirmasi Tindakan Medis"
|
|
164
|
+
description="Pastikan data nakes dan rekam medis pasien sudah sesuai sebelum melanjutkan."
|
|
165
|
+
onOpenChange={(val) => (isOpen = val)}
|
|
166
|
+
>
|
|
167
|
+
<p style="margin: 0; font-size: 14px; color: var(--ttdk-text-secondary)">
|
|
168
|
+
Tindakan ini akan mencatat log integrasi data ke dalam platform SATUSEHAT Kementerian Kesehatan RI.
|
|
169
|
+
</p>
|
|
170
|
+
</Modal>
|
|
171
|
+
```
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ttdk-design-system/modal",
|
|
3
|
+
"component": "Modal",
|
|
4
|
+
"folder": "modal",
|
|
5
|
+
"description": "Komponen Modal TTDK Design System — Selaras dengan Spesifikasi Nuxt UI Modal (UModal): - Mode controlled (v-model:open / open) dan uncontrolled (defaultOpen) - Backdrop blur overlay redup dengan penguncian scroll latar belakang otomatis (preventScroll) - Pilihan ukuran responsif ('xs' s/d '5xl' serta 'fullscreen') - Struktur slot terstandarisasi (#header, #body, #footer, #content) - Penanganan dismissible & preventClose (Escape key, backdrop click, callback onClosePrevent) - Animasi scale-in dan efek visual getar (shake) saat penutupan dicegah",
|
|
6
|
+
"stylesheets": [
|
|
7
|
+
{
|
|
8
|
+
"theme": "common",
|
|
9
|
+
"file": "modal.css",
|
|
10
|
+
"importPath": "web/modal/modal.css"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"props": {
|
|
14
|
+
"open": {
|
|
15
|
+
"name": "open",
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"optional": true,
|
|
18
|
+
"default": null,
|
|
19
|
+
"description": "Status visibilitas modal (mode terkontrol / controlled state). Mendukung `v-model:open` / `v-model` pada Vue 3 dan controlled prop `open` pada React.",
|
|
20
|
+
"example": null,
|
|
21
|
+
"param": null
|
|
22
|
+
},
|
|
23
|
+
"defaultOpen": {
|
|
24
|
+
"name": "defaultOpen",
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"optional": true,
|
|
27
|
+
"default": "false",
|
|
28
|
+
"description": "Status visibilitas awal saat pertama kali dirender (uncontrolled initial state).",
|
|
29
|
+
"example": null,
|
|
30
|
+
"param": null
|
|
31
|
+
},
|
|
32
|
+
"title": {
|
|
33
|
+
"name": "title",
|
|
34
|
+
"type": "string",
|
|
35
|
+
"optional": true,
|
|
36
|
+
"default": null,
|
|
37
|
+
"description": "Judul teks di bagian header modal.",
|
|
38
|
+
"example": null,
|
|
39
|
+
"param": null
|
|
40
|
+
},
|
|
41
|
+
"description": {
|
|
42
|
+
"name": "description",
|
|
43
|
+
"type": "string",
|
|
44
|
+
"optional": true,
|
|
45
|
+
"default": null,
|
|
46
|
+
"description": "Deskripsi penjelasan di bagian header modal di bawah judul.",
|
|
47
|
+
"example": null,
|
|
48
|
+
"param": null
|
|
49
|
+
},
|
|
50
|
+
"close": {
|
|
51
|
+
"name": "close",
|
|
52
|
+
"type": "boolean | any",
|
|
53
|
+
"optional": true,
|
|
54
|
+
"default": "true",
|
|
55
|
+
"description": "Menampilkan tombol tutup 'X' di pojok kanan atas header. Berikan `false` untuk menyembunyikan tombol tutup.",
|
|
56
|
+
"example": null,
|
|
57
|
+
"param": null
|
|
58
|
+
},
|
|
59
|
+
"closeIcon": {
|
|
60
|
+
"name": "closeIcon",
|
|
61
|
+
"type": "any",
|
|
62
|
+
"optional": true,
|
|
63
|
+
"default": null,
|
|
64
|
+
"description": "Ikon kustom untuk tombol tutup.",
|
|
65
|
+
"example": null,
|
|
66
|
+
"param": null
|
|
67
|
+
},
|
|
68
|
+
"fullscreen": {
|
|
69
|
+
"name": "fullscreen",
|
|
70
|
+
"type": "boolean",
|
|
71
|
+
"optional": true,
|
|
72
|
+
"default": "false",
|
|
73
|
+
"description": "Menjadikan modal tampil dalam ukuran layar penuh (fullscreen 100vw x 100vh).",
|
|
74
|
+
"example": null,
|
|
75
|
+
"param": null
|
|
76
|
+
},
|
|
77
|
+
"size": {
|
|
78
|
+
"name": "size",
|
|
79
|
+
"type": "ModalSize",
|
|
80
|
+
"optional": true,
|
|
81
|
+
"default": "md",
|
|
82
|
+
"description": "Skala ukuran lebar maksimum modal dialog ('xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | 'full').",
|
|
83
|
+
"example": null,
|
|
84
|
+
"param": null
|
|
85
|
+
},
|
|
86
|
+
"dismissible": {
|
|
87
|
+
"name": "dismissible",
|
|
88
|
+
"type": "boolean",
|
|
89
|
+
"optional": true,
|
|
90
|
+
"default": "true",
|
|
91
|
+
"description": "Mengizinkan modal ditutup saat pengguna mengeklik latar belakang (backdrop) atau menekan tombol `Escape`.",
|
|
92
|
+
"example": null,
|
|
93
|
+
"param": null
|
|
94
|
+
},
|
|
95
|
+
"preventClose": {
|
|
96
|
+
"name": "preventClose",
|
|
97
|
+
"type": "boolean",
|
|
98
|
+
"optional": true,
|
|
99
|
+
"default": "false",
|
|
100
|
+
"description": "Mencegah modal ditutup saat klik di luar atau tombol `Escape` (alias selaras Nuxt UI prevent-close). Jika bernilai `true`, popover/modal tidak dapat ditutup kecuali melalui tombol aksi eksplisit di dalam modal.",
|
|
101
|
+
"example": null,
|
|
102
|
+
"param": null
|
|
103
|
+
},
|
|
104
|
+
"overlay": {
|
|
105
|
+
"name": "overlay",
|
|
106
|
+
"type": "boolean",
|
|
107
|
+
"optional": true,
|
|
108
|
+
"default": "true",
|
|
109
|
+
"description": "Menampilkan lapisan latar belakang redup (backdrop overlay).",
|
|
110
|
+
"example": null,
|
|
111
|
+
"param": null
|
|
112
|
+
},
|
|
113
|
+
"modal": {
|
|
114
|
+
"name": "modal",
|
|
115
|
+
"type": "boolean",
|
|
116
|
+
"optional": true,
|
|
117
|
+
"default": "true",
|
|
118
|
+
"description": "Menjadikan modal sebagai dialog modal yang memusatkan fokus interaksi pengguna.",
|
|
119
|
+
"example": null,
|
|
120
|
+
"param": null
|
|
121
|
+
},
|
|
122
|
+
"scrollable": {
|
|
123
|
+
"name": "scrollable",
|
|
124
|
+
"type": "boolean",
|
|
125
|
+
"optional": true,
|
|
126
|
+
"default": "true",
|
|
127
|
+
"description": "Mengaktifkan area konten body yang dapat digulir jika isi modal melebihi tinggi layar.",
|
|
128
|
+
"example": null,
|
|
129
|
+
"param": null
|
|
130
|
+
},
|
|
131
|
+
"preventScroll": {
|
|
132
|
+
"name": "preventScroll",
|
|
133
|
+
"type": "boolean",
|
|
134
|
+
"optional": true,
|
|
135
|
+
"default": "true",
|
|
136
|
+
"description": "Mengunci scrolling halaman web latar belakang saat modal sedang terbuka (body scroll lock).",
|
|
137
|
+
"example": null,
|
|
138
|
+
"param": null
|
|
139
|
+
},
|
|
140
|
+
"lockScroll": {
|
|
141
|
+
"name": "lockScroll",
|
|
142
|
+
"type": "boolean",
|
|
143
|
+
"optional": true,
|
|
144
|
+
"default": "true",
|
|
145
|
+
"description": "Alias untuk `preventScroll`.",
|
|
146
|
+
"example": null,
|
|
147
|
+
"param": null
|
|
148
|
+
},
|
|
149
|
+
"content": {
|
|
150
|
+
"name": "content",
|
|
151
|
+
"type": "any",
|
|
152
|
+
"optional": true,
|
|
153
|
+
"default": null,
|
|
154
|
+
"description": "Konten kustom untuk seluruh dialog (menggantikan header, body, dan footer default).",
|
|
155
|
+
"example": null,
|
|
156
|
+
"param": null
|
|
157
|
+
},
|
|
158
|
+
"header": {
|
|
159
|
+
"name": "header",
|
|
160
|
+
"type": "any",
|
|
161
|
+
"optional": true,
|
|
162
|
+
"default": null,
|
|
163
|
+
"description": "Konten kustom untuk bagian header modal.",
|
|
164
|
+
"example": null,
|
|
165
|
+
"param": null
|
|
166
|
+
},
|
|
167
|
+
"body": {
|
|
168
|
+
"name": "body",
|
|
169
|
+
"type": "any",
|
|
170
|
+
"optional": true,
|
|
171
|
+
"default": null,
|
|
172
|
+
"description": "Konten kustom untuk bagian isi utama (body) modal.",
|
|
173
|
+
"example": null,
|
|
174
|
+
"param": null
|
|
175
|
+
},
|
|
176
|
+
"footer": {
|
|
177
|
+
"name": "footer",
|
|
178
|
+
"type": "any",
|
|
179
|
+
"optional": true,
|
|
180
|
+
"default": null,
|
|
181
|
+
"description": "Konten kustom untuk bagian footer (biasanya tombol aksi Batal / Konfirmasi).",
|
|
182
|
+
"example": null,
|
|
183
|
+
"param": null
|
|
184
|
+
},
|
|
185
|
+
"ui": {
|
|
186
|
+
"name": "ui",
|
|
187
|
+
"type": "ModalUiProps",
|
|
188
|
+
"optional": true,
|
|
189
|
+
"default": null,
|
|
190
|
+
"description": "Kustomisasi CSS variables atau token visual melalui UiProps.",
|
|
191
|
+
"example": null,
|
|
192
|
+
"param": null
|
|
193
|
+
},
|
|
194
|
+
"className": {
|
|
195
|
+
"name": "className",
|
|
196
|
+
"type": "string",
|
|
197
|
+
"optional": true,
|
|
198
|
+
"default": null,
|
|
199
|
+
"description": "Class CSS kustom pada elemen pembungkus terluar.",
|
|
200
|
+
"example": null,
|
|
201
|
+
"param": null
|
|
202
|
+
},
|
|
203
|
+
"class": {
|
|
204
|
+
"name": "class",
|
|
205
|
+
"type": "string",
|
|
206
|
+
"optional": true,
|
|
207
|
+
"default": null,
|
|
208
|
+
"description": "Class CSS kustom (alias framework Vue).",
|
|
209
|
+
"example": null,
|
|
210
|
+
"param": null
|
|
211
|
+
},
|
|
212
|
+
"style": {
|
|
213
|
+
"name": "style",
|
|
214
|
+
"type": "any",
|
|
215
|
+
"optional": true,
|
|
216
|
+
"default": null,
|
|
217
|
+
"description": "Style inline kustom pada kontainer dialog.",
|
|
218
|
+
"example": null,
|
|
219
|
+
"param": null
|
|
220
|
+
},
|
|
221
|
+
"overlayClass": {
|
|
222
|
+
"name": "overlayClass",
|
|
223
|
+
"type": "string",
|
|
224
|
+
"optional": true,
|
|
225
|
+
"default": null,
|
|
226
|
+
"description": "Class CSS kustom untuk lapisan backdrop overlay.",
|
|
227
|
+
"example": null,
|
|
228
|
+
"param": null
|
|
229
|
+
},
|
|
230
|
+
"overlayStyle": {
|
|
231
|
+
"name": "overlayStyle",
|
|
232
|
+
"type": "UiProps",
|
|
233
|
+
"optional": true,
|
|
234
|
+
"default": null,
|
|
235
|
+
"description": "Style kustom untuk lapisan backdrop overlay (UiProps).",
|
|
236
|
+
"example": null,
|
|
237
|
+
"param": null
|
|
238
|
+
},
|
|
239
|
+
"contentClass": {
|
|
240
|
+
"name": "contentClass",
|
|
241
|
+
"type": "string",
|
|
242
|
+
"optional": true,
|
|
243
|
+
"default": null,
|
|
244
|
+
"description": "Class CSS kustom untuk kartu panel modal dialog.",
|
|
245
|
+
"example": null,
|
|
246
|
+
"param": null
|
|
247
|
+
},
|
|
248
|
+
"contentStyle": {
|
|
249
|
+
"name": "contentStyle",
|
|
250
|
+
"type": "UiProps",
|
|
251
|
+
"optional": true,
|
|
252
|
+
"default": null,
|
|
253
|
+
"description": "Style kustom untuk kartu panel modal dialog (UiProps).",
|
|
254
|
+
"example": null,
|
|
255
|
+
"param": null
|
|
256
|
+
},
|
|
257
|
+
"headerClass": {
|
|
258
|
+
"name": "headerClass",
|
|
259
|
+
"type": "string",
|
|
260
|
+
"optional": true,
|
|
261
|
+
"default": null,
|
|
262
|
+
"description": "Class CSS kustom untuk header modal.",
|
|
263
|
+
"example": null,
|
|
264
|
+
"param": null
|
|
265
|
+
},
|
|
266
|
+
"headerStyle": {
|
|
267
|
+
"name": "headerStyle",
|
|
268
|
+
"type": "UiProps",
|
|
269
|
+
"optional": true,
|
|
270
|
+
"default": null,
|
|
271
|
+
"description": "Style kustom untuk header modal (UiProps).",
|
|
272
|
+
"example": null,
|
|
273
|
+
"param": null
|
|
274
|
+
},
|
|
275
|
+
"bodyClass": {
|
|
276
|
+
"name": "bodyClass",
|
|
277
|
+
"type": "string",
|
|
278
|
+
"optional": true,
|
|
279
|
+
"default": null,
|
|
280
|
+
"description": "Class CSS kustom untuk body modal.",
|
|
281
|
+
"example": null,
|
|
282
|
+
"param": null
|
|
283
|
+
},
|
|
284
|
+
"bodyStyle": {
|
|
285
|
+
"name": "bodyStyle",
|
|
286
|
+
"type": "UiProps",
|
|
287
|
+
"optional": true,
|
|
288
|
+
"default": null,
|
|
289
|
+
"description": "Style kustom untuk body modal (UiProps).",
|
|
290
|
+
"example": null,
|
|
291
|
+
"param": null
|
|
292
|
+
},
|
|
293
|
+
"footerClass": {
|
|
294
|
+
"name": "footerClass",
|
|
295
|
+
"type": "string",
|
|
296
|
+
"optional": true,
|
|
297
|
+
"default": null,
|
|
298
|
+
"description": "Class CSS kustom untuk footer modal.",
|
|
299
|
+
"example": null,
|
|
300
|
+
"param": null
|
|
301
|
+
},
|
|
302
|
+
"footerStyle": {
|
|
303
|
+
"name": "footerStyle",
|
|
304
|
+
"type": "UiProps",
|
|
305
|
+
"optional": true,
|
|
306
|
+
"default": null,
|
|
307
|
+
"description": "Style kustom untuk footer modal (UiProps).",
|
|
308
|
+
"example": null,
|
|
309
|
+
"param": null
|
|
310
|
+
},
|
|
311
|
+
"onUpdateOpen": {
|
|
312
|
+
"name": "onUpdateOpen",
|
|
313
|
+
"type": "(open: boolean) => void",
|
|
314
|
+
"optional": true,
|
|
315
|
+
"default": null,
|
|
316
|
+
"description": "Callback event saat status terbuka/tertutup berubah (kompatibel dengan v-model:open pada Vue 3).",
|
|
317
|
+
"example": null,
|
|
318
|
+
"param": null
|
|
319
|
+
},
|
|
320
|
+
"onOpenChange": {
|
|
321
|
+
"name": "onOpenChange",
|
|
322
|
+
"type": "(open: boolean) => void",
|
|
323
|
+
"optional": true,
|
|
324
|
+
"default": null,
|
|
325
|
+
"description": "Callback event saat status terbuka/tertutup berubah (alias standar React).",
|
|
326
|
+
"example": null,
|
|
327
|
+
"param": null
|
|
328
|
+
},
|
|
329
|
+
"onOpen": {
|
|
330
|
+
"name": "onOpen",
|
|
331
|
+
"type": "() => void",
|
|
332
|
+
"optional": true,
|
|
333
|
+
"default": null,
|
|
334
|
+
"description": "Callback event saat modal terbuka.",
|
|
335
|
+
"example": null,
|
|
336
|
+
"param": null
|
|
337
|
+
},
|
|
338
|
+
"onClose": {
|
|
339
|
+
"name": "onClose",
|
|
340
|
+
"type": "() => void",
|
|
341
|
+
"optional": true,
|
|
342
|
+
"default": null,
|
|
343
|
+
"description": "Callback event saat modal ditutup.",
|
|
344
|
+
"example": null,
|
|
345
|
+
"param": null
|
|
346
|
+
},
|
|
347
|
+
"onClosePrevent": {
|
|
348
|
+
"name": "onClosePrevent",
|
|
349
|
+
"type": "() => void",
|
|
350
|
+
"optional": true,
|
|
351
|
+
"default": null,
|
|
352
|
+
"description": "Callback event saat pengguna mencoba menutup modal tetapi dicegah karena preventClose={true} atau dismissible={false}.",
|
|
353
|
+
"example": null,
|
|
354
|
+
"param": null
|
|
355
|
+
},
|
|
356
|
+
"children": {
|
|
357
|
+
"name": "children",
|
|
358
|
+
"type": "any",
|
|
359
|
+
"optional": true,
|
|
360
|
+
"default": null,
|
|
361
|
+
"description": "Elemen pemicu (trigger), tombol, atau konten modal default.",
|
|
362
|
+
"example": null,
|
|
363
|
+
"param": null
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
"subInterfaces": {},
|
|
367
|
+
"supportedFrameworks": [
|
|
368
|
+
"react",
|
|
369
|
+
"vue",
|
|
370
|
+
"svelte"
|
|
371
|
+
],
|
|
372
|
+
"themes": [
|
|
373
|
+
"tw"
|
|
374
|
+
]
|
|
375
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ttdk-modal-portal{z-index:var(--ttdk-z-modal,9999);box-sizing:border-box;justify-content:center;align-items:center;padding:16px;display:flex;position:fixed;inset:0;overflow:hidden auto}.ttdk-modal-overlay{z-index:1;-webkit-backdrop-filter:blur(4px);background-color:#0f172a99;animation:.2s cubic-bezier(.16,1,.3,1) forwards ttdkModalFadeIn;position:fixed;inset:0}:root[data-theme=dark] .ttdk-modal-overlay,.dark .ttdk-modal-overlay{background-color:#000000bf}.ttdk-modal-dialog{z-index:2;background-color:var(--card,#fff);width:100%;color:var(--foreground,#0f172a);border:1px solid var(--border,#e2e8f0);border-radius:var(--ttdk-radius-xl,12px);box-sizing:border-box;outline:none;flex-direction:column;margin:auto;animation:.22s cubic-bezier(.16,1,.3,1) forwards ttdkModalScaleIn;display:flex;position:relative;overflow:hidden;box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a,0 0 1px #0000000d}.ttdk-modal-dialog.ttdk-modal-anim-done{opacity:1;animation:none;transform:none}:root[data-theme=dark] .ttdk-modal-dialog,.dark .ttdk-modal-dialog{background-color:var(--card,#0f172a);color:var(--foreground,#f8fafc);border-color:var(--border,#1e293b);box-shadow:0 25px 50px -12px #0009}.ttdk-modal-dialog.ttdk-modal-shake{animation:.35s cubic-bezier(.36,.07,.19,.97) both ttdkModalShake!important}.ttdk-modal-dialog[data-size=xs]{max-width:320px}.ttdk-modal-dialog[data-size=sm]{max-width:384px}.ttdk-modal-dialog[data-size=md]{max-width:448px}.ttdk-modal-dialog[data-size=lg]{max-width:512px}.ttdk-modal-dialog[data-size=xl]{max-width:576px}.ttdk-modal-dialog[data-size="2xl"]{max-width:672px}.ttdk-modal-dialog[data-size="3xl"]{max-width:768px}.ttdk-modal-dialog[data-size="4xl"]{max-width:896px}.ttdk-modal-dialog[data-size="5xl"]{max-width:1024px}.ttdk-modal-dialog[data-size=full]{width:100%;max-width:100vw}.ttdk-modal-dialog[data-fullscreen=true]{border:none;border-radius:0;width:100vw;max-width:100vw;height:100vh;max-height:100vh;margin:0}.ttdk-modal-portal:has(.ttdk-modal-dialog[data-fullscreen=true]){padding:0}.ttdk-modal-header{border-bottom:1px solid var(--border,#f1f5f9);flex-shrink:0;justify-content:space-between;align-items:flex-start;gap:12px;padding:18px 20px;display:flex}:root[data-theme=dark] .ttdk-modal-header,.dark .ttdk-modal-header{border-bottom-color:var(--border,#1e293b)}.ttdk-modal-header-info{flex-direction:column;flex:1;gap:4px;display:flex}.ttdk-modal-title{color:var(--foreground,#0f172a);margin:0;font-size:16px;font-weight:600;line-height:1.4}:root[data-theme=dark] .ttdk-modal-title,.dark .ttdk-modal-title{color:var(--foreground,#f8fafc)}.ttdk-modal-description{color:var(--muted-foreground,#64748b);margin:0;font-size:13.5px;line-height:1.5}:root[data-theme=dark] .ttdk-modal-description,.dark .ttdk-modal-description{color:var(--muted-foreground,#94a3b8)}.ttdk-modal-close{border-radius:var(--ttdk-radius-md,6px);width:32px;height:32px;color:var(--muted-foreground,#64748b);cursor:pointer;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;transition:background-color .15s,color .15s;display:inline-flex}.ttdk-modal-close:hover{background-color:var(--muted,#f1f5f9);color:var(--foreground,#0f172a)}:root[data-theme=dark] .ttdk-modal-close:hover,.dark .ttdk-modal-close:hover{background-color:var(--muted,#1e293b);color:var(--foreground,#f8fafc)}.ttdk-modal-close:focus-visible{outline:2px solid var(--primary,#0d9488);outline-offset:2px}.ttdk-modal-close svg{stroke-width:2.2px;stroke-linecap:round;stroke-linejoin:round}.ttdk-modal-body{color:var(--foreground,#0f172a);flex:auto;padding:20px;font-size:14px;line-height:1.6}:root[data-theme=dark] .ttdk-modal-body,.dark .ttdk-modal-body{color:var(--foreground,#f8fafc)}.ttdk-modal-dialog[data-scrollable=true] .ttdk-modal-body{overscroll-behavior:contain;max-height:calc(85vh - 140px);overflow-y:auto}.ttdk-modal-dialog[data-fullscreen=true] .ttdk-modal-body{max-height:none;overflow-y:auto}.ttdk-modal-footer{border-top:1px solid var(--border,#f1f5f9);background-color:var(--ttdk-surface-subtle,#fafafa);flex-shrink:0;justify-content:flex-end;align-items:center;gap:10px;padding:16px 20px;display:flex}:root[data-theme=dark] .ttdk-modal-footer,.dark .ttdk-modal-footer{border-top-color:var(--border,#1e293b);background-color:#0f172a66}.ttdk-modal-trigger-wrapper{display:inline-block}@keyframes ttdkModalFadeIn{0%{opacity:0}to{opacity:1}}@keyframes ttdkModalScaleIn{0%{opacity:0;transform:scale(.95)translateY(-8px)}to{opacity:1;transform:scale(1)translateY(0)}}@keyframes ttdkModalShake{0%,to{transform:translate(0)}20%,60%{transform:translate(-6px)}40%,80%{transform:translate(6px)}}
|