@gemafajarramadhan/dynamic-ui 1.0.5 → 1.0.7
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/README.md +432 -34
- package/dist/dynamic-ui.es.js +1947 -1891
- package/dist/dynamic-ui.umd.js +4 -4
- package/package.json +1 -1
- package/dist/webcomponents/dynamic-ui.css +0 -1
- package/dist/webcomponents/dynamic-ui.es.js +0 -12332
- package/dist/webcomponents/dynamic-ui.umd.js +0 -48
- package/dist/webcomponents/vite.svg +0 -1
package/README.md
CHANGED
|
@@ -8,11 +8,18 @@ Library **Vue 3** component yang bisa digunakan di berbagai framework (Vue, Reac
|
|
|
8
8
|
|
|
9
9
|
- [Fitur](#fitur)
|
|
10
10
|
- [Instalasi](#instalasi)
|
|
11
|
+
- [⚡ Konfigurasi API (WAJIB)](#-konfigurasi-api-wajib)
|
|
12
|
+
- [Vue 3](#konfigurasi-api-di-vue-3)
|
|
13
|
+
- [Nuxt 3](#konfigurasi-api-di-nuxt-3)
|
|
14
|
+
- [React / Next.js](#konfigurasi-api-di-react--nextjs)
|
|
15
|
+
- [Angular](#konfigurasi-api-di-angular)
|
|
16
|
+
- [Vanilla JS (window global)](#konfigurasi-api-via-window-global)
|
|
11
17
|
- [Komponen Base (Vue Components)](#komponen-base-vue-components)
|
|
12
18
|
- [Daftar Komponen](#daftar-komponen)
|
|
13
19
|
- [Penggunaan di Vue 3 (Import Per Komponen)](#penggunaan-di-vue-3-import-per-komponen)
|
|
14
20
|
- [Penggunaan di Vue 3 (Global Plugin)](#penggunaan-di-vue-3-global-plugin)
|
|
15
21
|
- [Penggunaan di Nuxt 3](#penggunaan-di-nuxt-3-vue-components)
|
|
22
|
+
- [DCodeAutoComplete – Komponen dengan API](#dcodeautocomplete--komponen-dengan-api)
|
|
16
23
|
- [Web Components (Framework Agnostic)](#web-components-framework-agnostic)
|
|
17
24
|
- [API Referensi Web Components](#api-referensi-web-components)
|
|
18
25
|
- [Logic Registry API](#logic-registry-api)
|
|
@@ -36,6 +43,7 @@ Library **Vue 3** component yang bisa digunakan di berbagai framework (Vue, Reac
|
|
|
36
43
|
- 🔌 **Logic Registry** – Daftarkan custom business logic dari aplikasi host tanpa perlu memodifikasi library.
|
|
37
44
|
- 🎨 **Style Bundled** – CSS sudah ter-bundle, cukup import satu file style.
|
|
38
45
|
- 🌐 **i18n Ready** – Mendukung internasionalisasi (vue-i18n).
|
|
46
|
+
- 🔐 **API Config** – Base URL dan auth token diambil dari **host project**, bukan dari env package ini.
|
|
39
47
|
|
|
40
48
|
---
|
|
41
49
|
|
|
@@ -54,6 +62,173 @@ pnpm add @gemafajarramadhan/dynamic-ui
|
|
|
54
62
|
|
|
55
63
|
---
|
|
56
64
|
|
|
65
|
+
## ⚡ Konfigurasi API (WAJIB)
|
|
66
|
+
|
|
67
|
+
> **Penting:** Komponen seperti `DCodeAutoComplete` melakukan HTTP request ke API. Base URL dan auth token **diambil dari host project**, bukan dari `.env` package ini. Anda **wajib** mengkonfigurasi ini di aplikasi host sebelum menggunakan komponen.
|
|
68
|
+
|
|
69
|
+
Library menggunakan sistem konfigurasi terpusat via `setApiConfig()` (atau via Vue Plugin). Berikut urutan prioritas resolusi base URL:
|
|
70
|
+
|
|
71
|
+
| Prioritas | Sumber |
|
|
72
|
+
|-----------|--------|
|
|
73
|
+
| 1️⃣ Tertinggi | `apiBaseUrl` via plugin / `setApiConfig()` |
|
|
74
|
+
| 2️⃣ | `window.__MICRO_API_BASE_URL__` (global) |
|
|
75
|
+
| 3️⃣ | `import.meta.env.VITE_API_BASE_URL` (env host) |
|
|
76
|
+
| 4️⃣ Terendah | `''` (same-origin fallback) |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### Konfigurasi API di Vue 3
|
|
81
|
+
|
|
82
|
+
Cara paling direkomendasikan: lewatkan config saat `app.use()`.
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
// main.js
|
|
86
|
+
import { createApp } from 'vue'
|
|
87
|
+
import App from './App.vue'
|
|
88
|
+
import DynamicUI from '@gemafajarramadhan/dynamic-ui'
|
|
89
|
+
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
90
|
+
|
|
91
|
+
const app = createApp(App)
|
|
92
|
+
|
|
93
|
+
app.use(DynamicUI, {
|
|
94
|
+
// ✅ Base URL API dari env HOST project
|
|
95
|
+
apiBaseUrl: import.meta.env.VITE_API_BASE_URL,
|
|
96
|
+
|
|
97
|
+
// ✅ Token auth terkini (dipanggil setiap request)
|
|
98
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
99
|
+
|
|
100
|
+
// ✅ Atau gunakan custom headers penuh (override Authorization)
|
|
101
|
+
// getHeaders: () => ({
|
|
102
|
+
// Authorization: `Bearer ${store.getters.token}`,
|
|
103
|
+
// 'X-App-ID': 'my-app',
|
|
104
|
+
// }),
|
|
105
|
+
|
|
106
|
+
// ✅ Callback ketika response 401 (Unauthorized)
|
|
107
|
+
onUnauthorized: () => {
|
|
108
|
+
router.push('/login')
|
|
109
|
+
},
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
app.mount('#app')
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
> File `.env` di host project Anda:
|
|
116
|
+
> ```env
|
|
117
|
+
> VITE_API_BASE_URL=https://api.example.com
|
|
118
|
+
> ```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### Konfigurasi API di Nuxt 3
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// plugins/dynamic-ui.ts
|
|
126
|
+
import DynamicUI from '@gemafajarramadhan/dynamic-ui'
|
|
127
|
+
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
128
|
+
|
|
129
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
130
|
+
const config = useRuntimeConfig()
|
|
131
|
+
|
|
132
|
+
nuxtApp.vueApp.use(DynamicUI, {
|
|
133
|
+
// Ambil dari runtimeConfig Nuxt
|
|
134
|
+
apiBaseUrl: config.public.apiBaseUrl,
|
|
135
|
+
|
|
136
|
+
getAuthToken: () => useCookie('access_token').value ?? null,
|
|
137
|
+
|
|
138
|
+
onUnauthorized: () => {
|
|
139
|
+
navigateTo('/login')
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> File `nuxt.config.ts` di host project:
|
|
146
|
+
> ```ts
|
|
147
|
+
> export default defineNuxtConfig({
|
|
148
|
+
> runtimeConfig: {
|
|
149
|
+
> public: {
|
|
150
|
+
> apiBaseUrl: process.env.VITE_API_BASE_URL, // set di .env
|
|
151
|
+
> },
|
|
152
|
+
> },
|
|
153
|
+
> })
|
|
154
|
+
> ```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### Konfigurasi API di React / Next.js
|
|
159
|
+
|
|
160
|
+
Gunakan fungsi `setApiConfig()` secara langsung (tidak perlu Vue plugin).
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
// src/lib/dynamic-ui-config.ts (jalankan sebelum render app)
|
|
164
|
+
import { setApiConfig } from '@gemafajarramadhan/dynamic-ui'
|
|
165
|
+
|
|
166
|
+
setApiConfig({
|
|
167
|
+
apiBaseUrl: process.env.NEXT_PUBLIC_API_BASE_URL,
|
|
168
|
+
|
|
169
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
170
|
+
|
|
171
|
+
onUnauthorized: () => {
|
|
172
|
+
window.location.href = '/login'
|
|
173
|
+
},
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Panggil di entry point:
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
// app/layout.tsx atau _app.tsx
|
|
181
|
+
'use client'
|
|
182
|
+
import '@/lib/dynamic-ui-config' // ← jalankan konfigurasi lebih dulu
|
|
183
|
+
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
> File `.env.local` di host project Next.js:
|
|
187
|
+
> ```env
|
|
188
|
+
> NEXT_PUBLIC_API_BASE_URL=https://api.example.com
|
|
189
|
+
> ```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### Konfigurasi API di Angular
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
// main.ts
|
|
197
|
+
import { setApiConfig } from '@gemafajarramadhan/dynamic-ui'
|
|
198
|
+
import '@gemafajarramadhan/dynamic-ui'
|
|
199
|
+
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
200
|
+
|
|
201
|
+
// Konfigurasi sebelum bootstrap
|
|
202
|
+
setApiConfig({
|
|
203
|
+
apiBaseUrl: (window as any).__env?.API_BASE_URL || 'https://api.example.com',
|
|
204
|
+
|
|
205
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
206
|
+
|
|
207
|
+
onUnauthorized: () => {
|
|
208
|
+
window.location.href = '/login'
|
|
209
|
+
},
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
platformBrowserDynamic().bootstrapModule(AppModule)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### Konfigurasi API via Window Global
|
|
218
|
+
|
|
219
|
+
Alternatif tanpa import fungsi – set sebelum library dimuat:
|
|
220
|
+
|
|
221
|
+
```html
|
|
222
|
+
<script>
|
|
223
|
+
// Set sebelum import library
|
|
224
|
+
window.__MICRO_API_BASE_URL__ = 'https://api.example.com'
|
|
225
|
+
window.__MICRO_AUTH_TOKEN__ = 'your-auth-token' // atau ambil dari cookie/localStorage
|
|
226
|
+
</script>
|
|
227
|
+
<script type="module" src="./main.js"></script>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
57
232
|
## Komponen Base (Vue Components)
|
|
58
233
|
|
|
59
234
|
Selain Web Components, library ini juga menyediakan **27 komponen Vue** yang bisa digunakan langsung di aplikasi Vue 3, Nuxt 3, dan framework apapun yang mendukung Vue.
|
|
@@ -70,7 +245,7 @@ Selain Web Components, library ini juga menyediakan **27 komponen Vue** yang bis
|
|
|
70
245
|
| `DCodeSwitch` | Toggle switch |
|
|
71
246
|
| `DCodeRadioCustom` | Radio button dengan opsi kustom |
|
|
72
247
|
| `DCodeLabel` | Label untuk form |
|
|
73
|
-
| `DCodeAutoComplete` | Input autocomplete dengan pencarian |
|
|
248
|
+
| `DCodeAutoComplete` | Input autocomplete dengan pencarian dan fetch API otomatis |
|
|
74
249
|
| `DCodeMultiSelect` | Dropdown multi-pilihan |
|
|
75
250
|
| `DCodeDatePicker` | Date picker kalender |
|
|
76
251
|
| `DCodeDateRangePicker` | Date range picker |
|
|
@@ -96,10 +271,6 @@ Selain Web Components, library ini juga menyediakan **27 komponen Vue** yang bis
|
|
|
96
271
|
|
|
97
272
|
Cara paling ringan: import hanya komponen yang diperlukan.
|
|
98
273
|
|
|
99
|
-
```bash
|
|
100
|
-
npm install @gemafajarramadhan/dynamic-ui
|
|
101
|
-
```
|
|
102
|
-
|
|
103
274
|
```vue
|
|
104
275
|
<!-- MyForm.vue -->
|
|
105
276
|
<script setup>
|
|
@@ -153,7 +324,12 @@ import DynamicUI from '@gemafajarramadhan/dynamic-ui'
|
|
|
153
324
|
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
154
325
|
|
|
155
326
|
const app = createApp(App)
|
|
156
|
-
|
|
327
|
+
|
|
328
|
+
app.use(DynamicUI, {
|
|
329
|
+
apiBaseUrl: import.meta.env.VITE_API_BASE_URL,
|
|
330
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
331
|
+
})
|
|
332
|
+
|
|
157
333
|
app.mount('#app')
|
|
158
334
|
```
|
|
159
335
|
|
|
@@ -180,7 +356,12 @@ import DynamicUI from '@gemafajarramadhan/dynamic-ui'
|
|
|
180
356
|
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
181
357
|
|
|
182
358
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
183
|
-
|
|
359
|
+
const config = useRuntimeConfig()
|
|
360
|
+
|
|
361
|
+
nuxtApp.vueApp.use(DynamicUI, {
|
|
362
|
+
apiBaseUrl: config.public.apiBaseUrl,
|
|
363
|
+
getAuthToken: () => useCookie('access_token').value ?? null,
|
|
364
|
+
})
|
|
184
365
|
})
|
|
185
366
|
```
|
|
186
367
|
|
|
@@ -198,6 +379,158 @@ Kemudian gunakan di page atau component manapun:
|
|
|
198
379
|
|
|
199
380
|
---
|
|
200
381
|
|
|
382
|
+
## DCodeAutoComplete – Komponen dengan API
|
|
383
|
+
|
|
384
|
+
`DCodeAutoComplete` adalah komponen autocomplete yang bisa **langsung fetch data dari API** menggunakan konfigurasi yang sudah di-set di host project.
|
|
385
|
+
|
|
386
|
+
> ⚠️ Pastikan sudah mengatur [Konfigurasi API](#-konfigurasi-api-wajib) sebelum menggunakan fitur endpoint.
|
|
387
|
+
|
|
388
|
+
### Perilaku Default
|
|
389
|
+
|
|
390
|
+
- Setiap fetch otomatis mengirimkan `page=1` dan `perPage=100` sebagai query parameter default.
|
|
391
|
+
- Nilai ini bisa di-override via prop `apiParams`.
|
|
392
|
+
|
|
393
|
+
### Props Utama
|
|
394
|
+
|
|
395
|
+
| Prop | Tipe | Default | Deskripsi |
|
|
396
|
+
|------|------|---------|-----------|
|
|
397
|
+
| `modelValue` | `any` | — | Value terpilih (v-model) |
|
|
398
|
+
| `endpoint.apiUrl` | `string` | — | URL endpoint API (path atau full URL) |
|
|
399
|
+
| `endpoint.apiMethod` | `string` | `'GET'` | HTTP method |
|
|
400
|
+
| `apiParams` | `object` | `{}` | Query params tambahan (di-merge & bisa override default) |
|
|
401
|
+
| `itemTitle` | `string\|Function` | `'name'` | Field nama tampilan dari tiap item |
|
|
402
|
+
| `itemValue` | `string\|Function` | `'id'` | Field nilai dari tiap item |
|
|
403
|
+
| `returnObject` | `boolean` | `false` | Jika `true`, v-model menyimpan objek penuh, bukan hanya `id` |
|
|
404
|
+
| `clearable` | `boolean` | `false` | Tampilkan tombol hapus pilihan |
|
|
405
|
+
| `disabled` | `boolean` | `false` | Nonaktifkan komponen |
|
|
406
|
+
| `autoFetchOnOpen` | `boolean` | `true` | Fetch otomatis saat dropdown dibuka pertama kali |
|
|
407
|
+
| `autoFetchOnMount` | `boolean` | `false` | Fetch otomatis saat komponen pertama kali di-mount |
|
|
408
|
+
|
|
409
|
+
### Contoh Penggunaan
|
|
410
|
+
|
|
411
|
+
#### Fetch dari API dengan URL langsung
|
|
412
|
+
|
|
413
|
+
```vue
|
|
414
|
+
<template>
|
|
415
|
+
<DCodeAutoComplete
|
|
416
|
+
v-model="selectedId"
|
|
417
|
+
label="Pilih Departemen"
|
|
418
|
+
:endpoint="{ apiUrl: '/api/master/departemen', apiMethod: 'GET' }"
|
|
419
|
+
item-title="nama"
|
|
420
|
+
item-value="id"
|
|
421
|
+
clearable
|
|
422
|
+
/>
|
|
423
|
+
</template>
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
> Request yang dikirim: `GET /api/master/departemen?page=1&perPage=100`
|
|
427
|
+
> Base URL diambil otomatis dari konfigurasi host project (`apiBaseUrl`).
|
|
428
|
+
|
|
429
|
+
#### Dengan Parameter Tambahan
|
|
430
|
+
|
|
431
|
+
```vue
|
|
432
|
+
<template>
|
|
433
|
+
<DCodeAutoComplete
|
|
434
|
+
v-model="selectedId"
|
|
435
|
+
label="Pilih Jabatan"
|
|
436
|
+
:endpoint="{ apiUrl: '/api/master/jabatan' }"
|
|
437
|
+
:apiParams="{ idDepartemen: selectedDeptId, isActive: true }"
|
|
438
|
+
item-title="namaJabatan"
|
|
439
|
+
item-value="idJabatan"
|
|
440
|
+
/>
|
|
441
|
+
</template>
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
> Request yang dikirim: `GET /api/master/jabatan?page=1&perPage=100&idDepartemen=5&isActive=true`
|
|
445
|
+
|
|
446
|
+
#### Override Default Pagination
|
|
447
|
+
|
|
448
|
+
```vue
|
|
449
|
+
<template>
|
|
450
|
+
<!-- Ganti perPage menjadi 50 -->
|
|
451
|
+
<DCodeAutoComplete
|
|
452
|
+
v-model="selected"
|
|
453
|
+
label="Pilih Data"
|
|
454
|
+
:endpoint="{ apiUrl: '/api/data' }"
|
|
455
|
+
:apiParams="{ perPage: 50 }"
|
|
456
|
+
item-title="nama"
|
|
457
|
+
item-value="id"
|
|
458
|
+
/>
|
|
459
|
+
</template>
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
#### Dengan Data Statis (tanpa API)
|
|
463
|
+
|
|
464
|
+
```vue
|
|
465
|
+
<template>
|
|
466
|
+
<DCodeAutoComplete
|
|
467
|
+
v-model="selected"
|
|
468
|
+
label="Pilih Status"
|
|
469
|
+
:items="[
|
|
470
|
+
{ id: 1, name: 'Aktif' },
|
|
471
|
+
{ id: 0, name: 'Nonaktif' },
|
|
472
|
+
]"
|
|
473
|
+
item-title="name"
|
|
474
|
+
item-value="id"
|
|
475
|
+
/>
|
|
476
|
+
</template>
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
#### Return Object Penuh
|
|
480
|
+
|
|
481
|
+
```vue
|
|
482
|
+
<script setup>
|
|
483
|
+
import { ref } from 'vue'
|
|
484
|
+
|
|
485
|
+
const selectedUser = ref(null) // akan berisi { id: 1, name: 'John', email: '...' }
|
|
486
|
+
</script>
|
|
487
|
+
|
|
488
|
+
<template>
|
|
489
|
+
<DCodeAutoComplete
|
|
490
|
+
v-model="selectedUser"
|
|
491
|
+
label="Pilih User"
|
|
492
|
+
:endpoint="{ apiUrl: '/api/users' }"
|
|
493
|
+
item-title="name"
|
|
494
|
+
item-value="id"
|
|
495
|
+
return-object
|
|
496
|
+
/>
|
|
497
|
+
</template>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Format Response API yang Diharapkan
|
|
501
|
+
|
|
502
|
+
```json
|
|
503
|
+
{
|
|
504
|
+
"status": true,
|
|
505
|
+
"data": {
|
|
506
|
+
"data": [
|
|
507
|
+
{ "id": 1, "name": "Item A" },
|
|
508
|
+
{ "id": 2, "name": "Item B" }
|
|
509
|
+
]
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Atau format flat:
|
|
515
|
+
|
|
516
|
+
```json
|
|
517
|
+
{
|
|
518
|
+
"data": [
|
|
519
|
+
{ "id": 1, "name": "Item A" }
|
|
520
|
+
]
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
Atau array langsung:
|
|
525
|
+
|
|
526
|
+
```json
|
|
527
|
+
[
|
|
528
|
+
{ "id": 1, "name": "Item A" }
|
|
529
|
+
]
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
201
534
|
## Web Components (Framework Agnostic)
|
|
202
535
|
|
|
203
536
|
Untuk digunakan di **React, Angular, Svelte**, atau framework lainnya, gunakan mode Web Components.
|
|
@@ -252,13 +585,13 @@ import {
|
|
|
252
585
|
|
|
253
586
|
---
|
|
254
587
|
|
|
255
|
-
##
|
|
588
|
+
## Penggunaan di Berbagai Framework
|
|
256
589
|
|
|
257
590
|
---
|
|
258
591
|
|
|
259
592
|
### 1. Vanilla HTML / JavaScript
|
|
260
593
|
|
|
261
|
-
Cara paling sederhana. Import library dari
|
|
594
|
+
Cara paling sederhana. Import library dari bundler, lalu gunakan custom element di HTML.
|
|
262
595
|
|
|
263
596
|
```html
|
|
264
597
|
<!DOCTYPE html>
|
|
@@ -279,10 +612,17 @@ Cara paling sederhana. Import library dari CDN atau bundler, lalu gunakan custom
|
|
|
279
612
|
|
|
280
613
|
<!-- Import library (registrasi Web Components otomatis) -->
|
|
281
614
|
<script type="module">
|
|
282
|
-
import '@gemafajarramadhan/dynamic-ui'
|
|
615
|
+
import '@gemafajarramadhan/dynamic-ui'
|
|
616
|
+
import { setApiConfig } from '@gemafajarramadhan/dynamic-ui'
|
|
617
|
+
|
|
618
|
+
// ✅ Konfigurasi API dari host project
|
|
619
|
+
setApiConfig({
|
|
620
|
+
apiBaseUrl: 'https://api.example.com',
|
|
621
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
622
|
+
})
|
|
283
623
|
|
|
284
624
|
// --- Setup Form ---
|
|
285
|
-
const form = document.querySelector('#myForm')
|
|
625
|
+
const form = document.querySelector('#myForm')
|
|
286
626
|
form.config = {
|
|
287
627
|
title: 'Registrasi User',
|
|
288
628
|
sections: [
|
|
@@ -306,25 +646,25 @@ Cara paling sederhana. Import library dari CDN atau bundler, lalu gunakan custom
|
|
|
306
646
|
},
|
|
307
647
|
],
|
|
308
648
|
actions: [{ key: 'submit', label: 'Daftar', component: 'DCodeButton' }],
|
|
309
|
-
}
|
|
649
|
+
}
|
|
310
650
|
|
|
311
651
|
form.addEventListener('submit', (e) => {
|
|
312
|
-
console.log('Data Form:', e.detail)
|
|
313
|
-
})
|
|
652
|
+
console.log('Data Form:', e.detail)
|
|
653
|
+
})
|
|
314
654
|
|
|
315
655
|
// --- Setup DataTable ---
|
|
316
|
-
const table = document.querySelector('#myTable')
|
|
656
|
+
const table = document.querySelector('#myTable')
|
|
317
657
|
table.config = {
|
|
318
658
|
titleID: 'Daftar User',
|
|
319
659
|
headers: [
|
|
320
660
|
{ text: 'Nama', value: 'name' },
|
|
321
661
|
{ text: 'Email', value: 'email' },
|
|
322
662
|
],
|
|
323
|
-
}
|
|
663
|
+
}
|
|
324
664
|
|
|
325
665
|
table.addEventListener('action', (e) => {
|
|
326
|
-
console.log('Action:', e.detail)
|
|
327
|
-
})
|
|
666
|
+
console.log('Action:', e.detail)
|
|
667
|
+
})
|
|
328
668
|
</script>
|
|
329
669
|
|
|
330
670
|
</body>
|
|
@@ -333,7 +673,7 @@ Cara paling sederhana. Import library dari CDN atau bundler, lalu gunakan custom
|
|
|
333
673
|
|
|
334
674
|
---
|
|
335
675
|
|
|
336
|
-
### 2. Vue 3
|
|
676
|
+
### 2. Vue 3 (Web Components)
|
|
337
677
|
|
|
338
678
|
Di Vue 3, Web Components bisa dipakai langsung seperti HTML element biasa. Gunakan `ref` untuk set properti objek.
|
|
339
679
|
|
|
@@ -366,12 +706,19 @@ export default defineConfig({
|
|
|
366
706
|
// main.js
|
|
367
707
|
import { createApp } from 'vue'
|
|
368
708
|
import App from './App.vue'
|
|
369
|
-
|
|
370
|
-
// Import library (registrasi Web Components)
|
|
371
|
-
import '@gemafajarramadhan/dynamic-ui'
|
|
709
|
+
import DynamicUI from '@gemafajarramadhan/dynamic-ui'
|
|
372
710
|
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
373
711
|
|
|
374
|
-
createApp(App)
|
|
712
|
+
const app = createApp(App)
|
|
713
|
+
|
|
714
|
+
// ✅ Konfigurasi API dari env host project
|
|
715
|
+
app.use(DynamicUI, {
|
|
716
|
+
apiBaseUrl: import.meta.env.VITE_API_BASE_URL,
|
|
717
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
718
|
+
onUnauthorized: () => router.push('/login'),
|
|
719
|
+
})
|
|
720
|
+
|
|
721
|
+
app.mount('#app')
|
|
375
722
|
```
|
|
376
723
|
|
|
377
724
|
#### Komponen Vue (`MyForm.vue`)
|
|
@@ -429,11 +776,17 @@ Di React, gunakan `useRef` dan `useEffect` untuk set properti DOM secara imperat
|
|
|
429
776
|
import React from 'react'
|
|
430
777
|
import ReactDOM from 'react-dom/client'
|
|
431
778
|
import App from './App'
|
|
432
|
-
|
|
433
|
-
// Import library (registrasi Web Components)
|
|
779
|
+
import { setApiConfig } from '@gemafajarramadhan/dynamic-ui'
|
|
434
780
|
import '@gemafajarramadhan/dynamic-ui'
|
|
435
781
|
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
436
782
|
|
|
783
|
+
// ✅ Konfigurasi API dari env host project
|
|
784
|
+
setApiConfig({
|
|
785
|
+
apiBaseUrl: import.meta.env.VITE_API_BASE_URL,
|
|
786
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
787
|
+
onUnauthorized: () => { window.location.href = '/login' },
|
|
788
|
+
})
|
|
789
|
+
|
|
437
790
|
ReactDOM.createRoot(document.getElementById('root')).render(<App />)
|
|
438
791
|
```
|
|
439
792
|
|
|
@@ -562,6 +915,19 @@ declare global {
|
|
|
562
915
|
|
|
563
916
|
Di Next.js dengan App Router, Web Components harus di-import di sisi klien (`'use client'`).
|
|
564
917
|
|
|
918
|
+
#### Setup Konfigurasi API
|
|
919
|
+
|
|
920
|
+
```ts
|
|
921
|
+
// lib/dynamic-ui-config.ts
|
|
922
|
+
import { setApiConfig } from '@gemafajarramadhan/dynamic-ui'
|
|
923
|
+
|
|
924
|
+
setApiConfig({
|
|
925
|
+
apiBaseUrl: process.env.NEXT_PUBLIC_API_BASE_URL!,
|
|
926
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
927
|
+
onUnauthorized: () => { window.location.href = '/login' },
|
|
928
|
+
})
|
|
929
|
+
```
|
|
930
|
+
|
|
565
931
|
#### Setup di Layout atau Client Component
|
|
566
932
|
|
|
567
933
|
```tsx
|
|
@@ -569,8 +935,7 @@ Di Next.js dengan App Router, Web Components harus di-import di sisi klien (`'us
|
|
|
569
935
|
'use client'
|
|
570
936
|
|
|
571
937
|
import { useEffect, useRef } from 'react'
|
|
572
|
-
|
|
573
|
-
// Import hanya di sisi klien
|
|
938
|
+
import '@/lib/dynamic-ui-config'
|
|
574
939
|
import('@gemafajarramadhan/dynamic-ui')
|
|
575
940
|
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
576
941
|
|
|
@@ -639,6 +1004,11 @@ export default function HomePage() {
|
|
|
639
1004
|
> const DynamicFormClient = dynamic(() => import('@/components/DynamicForm'), { ssr: false })
|
|
640
1005
|
> ```
|
|
641
1006
|
|
|
1007
|
+
> File `.env.local` di host project:
|
|
1008
|
+
> ```env
|
|
1009
|
+
> NEXT_PUBLIC_API_BASE_URL=https://api.example.com
|
|
1010
|
+
> ```
|
|
1011
|
+
|
|
642
1012
|
---
|
|
643
1013
|
|
|
644
1014
|
### 5. Angular
|
|
@@ -666,16 +1036,30 @@ export class AppModule {}
|
|
|
666
1036
|
|
|
667
1037
|
```ts
|
|
668
1038
|
// main.ts
|
|
669
|
-
import {
|
|
670
|
-
import { AppModule } from './app/app.module'
|
|
671
|
-
|
|
672
|
-
// Import library (registrasi Web Components)
|
|
1039
|
+
import { setApiConfig } from '@gemafajarramadhan/dynamic-ui'
|
|
673
1040
|
import '@gemafajarramadhan/dynamic-ui'
|
|
674
1041
|
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
675
1042
|
|
|
1043
|
+
// ✅ Konfigurasi API dari environment Angular
|
|
1044
|
+
import { environment } from './environments/environment'
|
|
1045
|
+
|
|
1046
|
+
setApiConfig({
|
|
1047
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
1048
|
+
getAuthToken: () => localStorage.getItem('access_token'),
|
|
1049
|
+
onUnauthorized: () => { window.location.href = '/login' },
|
|
1050
|
+
})
|
|
1051
|
+
|
|
676
1052
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
|
677
1053
|
```
|
|
678
1054
|
|
|
1055
|
+
> File `src/environments/environment.ts`:
|
|
1056
|
+
> ```ts
|
|
1057
|
+
> export const environment = {
|
|
1058
|
+
> production: false,
|
|
1059
|
+
> apiBaseUrl: 'https://api.example.com',
|
|
1060
|
+
> }
|
|
1061
|
+
> ```
|
|
1062
|
+
|
|
679
1063
|
#### Komponen Angular (`dynamic-form.component.ts`)
|
|
680
1064
|
|
|
681
1065
|
```ts
|
|
@@ -761,11 +1145,18 @@ Buat file plugin dengan suffix `.client.ts` agar hanya dijalankan di sisi klien
|
|
|
761
1145
|
|
|
762
1146
|
```ts
|
|
763
1147
|
// plugins/dynamic-ui.client.ts
|
|
764
|
-
import '@gemafajarramadhan/dynamic-ui'
|
|
1148
|
+
import DynamicUI from '@gemafajarramadhan/dynamic-ui'
|
|
765
1149
|
import '@gemafajarramadhan/dynamic-ui/style.css'
|
|
766
1150
|
|
|
767
|
-
export default defineNuxtPlugin(() => {
|
|
768
|
-
|
|
1151
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
1152
|
+
const config = useRuntimeConfig()
|
|
1153
|
+
|
|
1154
|
+
// ✅ Konfigurasi API dari runtimeConfig Nuxt (env host project)
|
|
1155
|
+
nuxtApp.vueApp.use(DynamicUI, {
|
|
1156
|
+
apiBaseUrl: config.public.apiBaseUrl,
|
|
1157
|
+
getAuthToken: () => useCookie('access_token').value ?? null,
|
|
1158
|
+
onUnauthorized: () => navigateTo('/login'),
|
|
1159
|
+
})
|
|
769
1160
|
})
|
|
770
1161
|
```
|
|
771
1162
|
|
|
@@ -774,6 +1165,11 @@ export default defineNuxtPlugin(() => {
|
|
|
774
1165
|
```ts
|
|
775
1166
|
// nuxt.config.ts
|
|
776
1167
|
export default defineNuxtConfig({
|
|
1168
|
+
runtimeConfig: {
|
|
1169
|
+
public: {
|
|
1170
|
+
apiBaseUrl: process.env.VITE_API_BASE_URL, // set di .env
|
|
1171
|
+
},
|
|
1172
|
+
},
|
|
777
1173
|
vue: {
|
|
778
1174
|
compilerOptions: {
|
|
779
1175
|
// Arahkan Nuxt/Vue agar tidak menganggap element ini sebagai Vue component
|
|
@@ -912,6 +1308,8 @@ declare global {
|
|
|
912
1308
|
// Untuk global window registry
|
|
913
1309
|
interface Window {
|
|
914
1310
|
__MICRO_LOGIC_REGISTRY__?: Record<string, DynamicUI.LogicModule>
|
|
1311
|
+
__MICRO_API_BASE_URL__?: string
|
|
1312
|
+
__MICRO_AUTH_TOKEN__?: string
|
|
915
1313
|
}
|
|
916
1314
|
}
|
|
917
1315
|
|