@gemafajarramadhan/dynamic-ui 1.1.12 → 1.1.13

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 CHANGED
@@ -1318,6 +1318,1149 @@ export {}
1318
1318
 
1319
1319
  ---
1320
1320
 
1321
+ ## Referensi Props Komponen
1322
+
1323
+ Berikut adalah dokumentasi lengkap props untuk setiap komponen yang tersedia.
1324
+
1325
+ ---
1326
+
1327
+ ### `DataTable`
1328
+
1329
+ Komponen tabel data yang mendukung mode API (fetch otomatis) maupun data statis, dengan pagination, sorting, filtering, dan action button.
1330
+
1331
+ | Prop | Tipe | Default | Deskripsi |
1332
+ |------|------|---------|-----------|
1333
+ | `columns` | `TableColumn[]` | `[]` | Definisi kolom tabel |
1334
+ | `data` | `any[]` | `[]` | Data statis (mode non-API) |
1335
+ | `perPage` | `number` | `10` | Jumlah baris per halaman |
1336
+ | `loading` | `boolean` | `false` | Status loading eksternal |
1337
+ | `hasActions` | `boolean` | `false` | Tampilkan kolom aksi baris |
1338
+ | `nested` | `boolean` | `false` | Mode nested (tampilan kompak tanpa header search) |
1339
+ | `apiModule` | `string` | — | Module API untuk fetch data |
1340
+ | `apiAction` | `string` | `'list'` | Action API |
1341
+ | `apiMethod` | `string` | — | HTTP method (`GET`/`POST`) |
1342
+ | `apiUrl` | `string` | — | URL endpoint API langsung |
1343
+ | `apiParams` | `object` | `{}` | Parameter tambahan untuk request API |
1344
+ | `tableConfig` | `any` | — | Konfigurasi JSON lengkap tabel (dari backend) |
1345
+ | `dynamicColumns` | `boolean` | `false` | Gunakan kolom dinamis dari response API |
1346
+ | `enableQuickSearch` | `boolean` | `true` | Aktifkan pencarian cepat (debounce) |
1347
+ | `showPagination` | `boolean` | `true` | Tampilkan pagination |
1348
+ | `ignorePermissions` | `boolean` | `false` | Abaikan cek permission |
1349
+ | `permissionBase` | `string` | — | Base path untuk permission check |
1350
+
1351
+ ```vue
1352
+ <template>
1353
+ <!-- Mode API -->
1354
+ <DataTable
1355
+ api-url="/api/users"
1356
+ api-method="POST"
1357
+ :columns="[
1358
+ { key: 'name', label: 'Nama', sortable: true },
1359
+ { key: 'email', label: 'Email' },
1360
+ ]"
1361
+ :per-page="25"
1362
+ />
1363
+
1364
+ <!-- Mode data statis -->
1365
+ <DataTable
1366
+ :data="myData"
1367
+ :columns="columns"
1368
+ />
1369
+ </template>
1370
+ ```
1371
+
1372
+ ---
1373
+
1374
+ ### `DCodeButton`
1375
+
1376
+ Tombol dengan berbagai variant, warna kustom, ikon Lucide, dan tooltip.
1377
+
1378
+ | Prop | Tipe | Default | Deskripsi |
1379
+ |------|------|---------|-----------|
1380
+ | `text` | `string` | `''` | Teks tombol |
1381
+ | `icon` | `string` | — | Nama ikon Lucide (e.g. `'Save'`, `'Trash2'`) |
1382
+ | `variant` | `'default'\|'secondary'\|'destructive'\|'outline'\|'ghost'\|'link'\|'tonal'\|'elevated'` | `'default'` | Variant tampilan |
1383
+ | `size` | `'default'\|'sm'\|'lg'\|'icon'` | `'default'` | Ukuran tombol |
1384
+ | `tooltip` | `string` | `''` | Teks tooltip |
1385
+ | `bgColor` | `string` | `''` | Warna background kustom (tailwind/hex) |
1386
+ | `textColor` | `string` | `''` | Warna teks kustom |
1387
+ | `hoverBgColor` | `string` | `''` | Warna background saat hover |
1388
+ | `borderColor` | `string` | `''` | Warna border kustom |
1389
+ | `disabled` | `boolean` | `false` | Nonaktifkan tombol |
1390
+ | `type` | `'button'\|'submit'\|'reset'` | `'button'` | Tipe HTML button |
1391
+ | `visible` | `boolean` | `true` | Tampilkan/sembunyikan tombol |
1392
+ | `skeleton` | `boolean` | `false` | Tampilkan skeleton loading |
1393
+
1394
+ ```vue
1395
+ <template>
1396
+ <DCodeButton text="Simpan" icon="Save" variant="default" />
1397
+ <DCodeButton text="Hapus" icon="Trash2" variant="destructive" tooltip="Hapus data ini" />
1398
+ <DCodeButton text="Submit" type="submit" :disabled="isLoading" />
1399
+ </template>
1400
+ ```
1401
+
1402
+ ---
1403
+
1404
+ ### `DCodeTextField`
1405
+
1406
+ Input teks dengan banyak fitur: filter karakter, transformasi case, clearable, password toggle.
1407
+
1408
+ | Prop | Tipe | Default | Deskripsi |
1409
+ |------|------|---------|-----------|
1410
+ | `modelValue` | `string\|number\|null` | — | Value input (v-model) |
1411
+ | `prependInner` | `string` | — | Teks/ikon di sisi kiri input |
1412
+ | `clearable` | `boolean` | — | Tampilkan tombol clear |
1413
+ | `hideClearWhenEmpty` | `boolean` | — | Sembunyikan tombol clear saat kosong |
1414
+ | `textCase` | `'none'\|'uppercase'\|'lowercase'\|'titlecase'\|'sentencecase'` | `'none'` | Transformasi huruf |
1415
+ | `applyTextCaseToValue` | `boolean` | `true` | Terapkan transformasi ke v-model |
1416
+ | `valueType` | `'free'\|'number'\|'letter'\|'letternumber'\|'email'\|'password'` | `'free'` | Filter jenis karakter yang diperbolehkan |
1417
+ | `allowSpaces` | `boolean` | — | Izinkan spasi |
1418
+ | `allowChars` | `string\|string[]` | — | Karakter tambahan yang diizinkan |
1419
+ | `pattern` | `RegExp` | — | Regex validasi |
1420
+ | `visible` | `boolean` | `true` | Tampilkan/sembunyikan |
1421
+ | `skeleton` | `boolean` | `false` | Tampilkan skeleton |
1422
+ | `returnNumber` | `boolean` | — | Emit nilai sebagai number |
1423
+ | `error` | `string\|null` | — | Pesan error validasi |
1424
+
1425
+ ```vue
1426
+ <template>
1427
+ <DCodeTextField
1428
+ v-model="form.name"
1429
+ label="Nama Lengkap"
1430
+ placeholder="Masukkan nama..."
1431
+ text-case="titlecase"
1432
+ clearable
1433
+ />
1434
+ <DCodeTextField
1435
+ v-model="form.email"
1436
+ label="Email"
1437
+ value-type="email"
1438
+ :error="errors.email"
1439
+ />
1440
+ <DCodeTextField
1441
+ v-model="form.password"
1442
+ label="Password"
1443
+ value-type="password"
1444
+ />
1445
+ </template>
1446
+ ```
1447
+
1448
+ ---
1449
+
1450
+ ### `DCodeTextarea`
1451
+
1452
+ Textarea dengan karakter counter, filter, dan transformasi case.
1453
+
1454
+ | Prop | Tipe | Default | Deskripsi |
1455
+ |------|------|---------|-----------|
1456
+ | `modelValue` | `string\|number\|null` | — | Value (v-model) |
1457
+ | `clearable` | `boolean` | — | Tombol clear |
1458
+ | `hideClearWhenEmpty` | `boolean` | `true` | Sembunyikan clear saat kosong |
1459
+ | `textCase` | `'none'\|'uppercase'\|'lowercase'\|'titlecase'\|'sentencecase'` | `'none'` | Transformasi huruf |
1460
+ | `applyTextCaseToValue` | `boolean` | `true` | Terapkan ke v-model |
1461
+ | `valueType` | `'free'\|'number'\|'letter'\|'letternumber'` | `'free'` | Filter karakter |
1462
+ | `allowSpaces` | `boolean` | `true` | Izinkan spasi |
1463
+ | `allowChars` | `string\|string[]` | — | Karakter tambahan |
1464
+ | `pattern` | `RegExp` | — | Regex validasi |
1465
+ | `visible` | `boolean` | `true` | Tampilkan/sembunyikan |
1466
+ | `skeleton` | `boolean` | `false` | Skeleton loading |
1467
+ | `showCharCount` | `boolean` | `true` | Tampilkan counter karakter |
1468
+ | `returnNumber` | `boolean` | `false` | Emit sebagai number |
1469
+ | `error` | `string\|null` | `null` | Pesan error |
1470
+
1471
+ ```vue
1472
+ <template>
1473
+ <DCodeTextarea
1474
+ v-model="form.description"
1475
+ label="Deskripsi"
1476
+ placeholder="Masukkan deskripsi..."
1477
+ :show-char-count="true"
1478
+ maxlength="500"
1479
+ />
1480
+ </template>
1481
+ ```
1482
+
1483
+ ---
1484
+
1485
+ ### `DCodeAutoComplete`
1486
+
1487
+ Dropdown autocomplete dengan fetch API otomatis dan pencarian.
1488
+
1489
+ | Prop | Tipe | Default | Deskripsi |
1490
+ |------|------|---------|-----------|
1491
+ | `modelValue` | `any` | — | Value terpilih (v-model) |
1492
+ | `endpoint` | `{ apiUrl?, apiMethod?, apiModule?, apiAction? }` | — | Konfigurasi endpoint API |
1493
+ | `apiParams` | `object` | `{}` | Parameter tambahan request |
1494
+ | `fetchItems` | `Function` | — | Fungsi custom fetch (alternatif endpoint) |
1495
+ | `itemTitle` | `string\|Function` | `'name'` | Field label item |
1496
+ | `itemValue` | `string\|Function` | `'id'` | Field nilai item |
1497
+ | `returnObject` | `boolean` | `false` | Return objek penuh |
1498
+ | `autoFetchOnOpen` | `boolean` | `true` | Fetch saat dropdown terbuka |
1499
+ | `autoFetchOnMount` | `boolean` | `false` | Fetch saat mount |
1500
+ | `clearable` | `boolean` | `false` | Tombol clear |
1501
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1502
+ | `visible` | `boolean` | `true` | Tampilkan/sembunyikan |
1503
+ | `skeleton` | `boolean` | `false` | Skeleton loading |
1504
+ | `error` | `string\|null` | `null` | Pesan error |
1505
+ | `icon` | `Component` | — | Ikon kiri input |
1506
+
1507
+ ```vue
1508
+ <template>
1509
+ <DCodeAutoComplete
1510
+ v-model="form.departemenId"
1511
+ label="Departemen"
1512
+ :endpoint="{ apiUrl: '/api/master/departemen' }"
1513
+ item-title="nama"
1514
+ item-value="id"
1515
+ clearable
1516
+ />
1517
+ </template>
1518
+ ```
1519
+
1520
+ ---
1521
+
1522
+ ### `DCodeInfiniteAutoComplete`
1523
+
1524
+ Autocomplete dengan pagination infinite scroll (load more saat scroll ke bawah).
1525
+
1526
+ | Prop | Tipe | Default | Deskripsi |
1527
+ |------|------|---------|-----------|
1528
+ | `modelValue` | `any` | — | Value (v-model) |
1529
+ | `endpoint` | `{ apiUrl?, apiMethod? }` | — | Endpoint API |
1530
+ | `apiParams` | `object` | `{}` | Parameter tambahan |
1531
+ | `fetchItems` | `Function` | — | Custom fetch |
1532
+ | `itemTitle` | `string\|Function` | `'name'` | Field label |
1533
+ | `itemValue` | `string\|Function` | `'id'` | Field nilai |
1534
+ | `itemSubtitle` | `string\|Function` | — | Field subtitle item |
1535
+ | `returnObject` | `boolean` | `false` | Return objek penuh |
1536
+ | `autoFetchOnOpen` | `boolean` | `true` | Fetch saat buka |
1537
+ | `refreshOnOpen` | `boolean` | `false` | Refresh data setiap buka |
1538
+ | `clearable` | `boolean` | `false` | Tombol clear |
1539
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1540
+ | `visible` | `boolean` | `true` | Tampilkan |
1541
+ | `skeleton` | `boolean` | `false` | Skeleton |
1542
+ | `error` | `string\|null` | `null` | Error message |
1543
+ | `icon` | `Component` | — | Ikon prefix |
1544
+ | `pageSize` | `number` | `20` | Jumlah item per halaman |
1545
+
1546
+ ```vue
1547
+ <template>
1548
+ <DCodeInfiniteAutoComplete
1549
+ v-model="form.userId"
1550
+ label="Pilih User"
1551
+ :endpoint="{ apiUrl: '/api/users', apiMethod: 'GET' }"
1552
+ item-title="fullName"
1553
+ item-value="id"
1554
+ :page-size="15"
1555
+ />
1556
+ </template>
1557
+ ```
1558
+
1559
+ ---
1560
+
1561
+ ### `DCodeMultiSelect`
1562
+
1563
+ Dropdown multi-pilihan dengan chip tags dan search.
1564
+
1565
+ | Prop | Tipe | Default | Deskripsi |
1566
+ |------|------|---------|-----------|
1567
+ | `modelValue` | `any[]` | — | Array nilai terpilih (v-model) |
1568
+ | `items` | `object[]` | `[]` | Data statis |
1569
+ | `endpoint` | `{ apiUrl?, apiMethod?, apiOptions? }` | — | Endpoint API |
1570
+ | `fetchItems` | `Function` | — | Custom fetch |
1571
+ | `autoFetchOnOpen` | `boolean` | `true` | Fetch saat buka |
1572
+ | `autoFetchOnMount` | `boolean` | `false` | Fetch saat mount |
1573
+ | `refreshOnOpen` | `boolean` | `false` | Refresh setiap buka |
1574
+ | `label` | `string` | `''` | Label dropdown |
1575
+ | `placeholder` | `string` | `'Pilih data…'` | Placeholder |
1576
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1577
+ | `clearable` | `boolean` | `false` | Tombol clear |
1578
+ | `searchable` | `boolean` | `false` | Aktifkan search |
1579
+ | `searchPlaceholder` | `string` | `'Cari…'` | Placeholder search |
1580
+ | `visible` | `boolean` | `true` | Tampilkan |
1581
+ | `skeleton` | `boolean` | `false` | Skeleton |
1582
+ | `maxChips` | `number\|null` | `2` | Maks chip ditampilkan |
1583
+ | `maxSelected` | `number\|null` | `3` | Maks pilihan |
1584
+ | `itemTitle` | `string\|Function` | — | Field label |
1585
+ | `itemValue` | `string\|Function` | — | Field nilai |
1586
+ | `returnObject` | `boolean` | — | Return objek penuh |
1587
+ | `error` | `string\|null` | — | Error message |
1588
+
1589
+ ```vue
1590
+ <template>
1591
+ <DCodeMultiSelect
1592
+ v-model="form.tags"
1593
+ label="Tags"
1594
+ :items="availableTags"
1595
+ item-title="name"
1596
+ item-value="id"
1597
+ :max-selected="5"
1598
+ searchable
1599
+ />
1600
+ </template>
1601
+ ```
1602
+
1603
+ ---
1604
+
1605
+ ### `DCodeDatePicker`
1606
+
1607
+ Date picker atau date range picker dengan berbagai format.
1608
+
1609
+ | Prop | Tipe | Default | Deskripsi |
1610
+ |------|------|---------|-----------|
1611
+ | `modelValue` | `string\|[string,string]\|null` | — | Value tanggal (v-model) |
1612
+ | `range` | `boolean` | `true` | Mode range (pilih 2 tanggal) |
1613
+ | `autoRangeDays` | `number\|null` | `null` | Otomatis set range N hari |
1614
+ | `disablePast` | `boolean` | `false` | Nonaktifkan tanggal masa lalu |
1615
+ | `maxDaysAhead` | `number\|null` | `null` | Maks hari ke depan |
1616
+ | `placeholder` | `string` | `'Pilih tanggal'` | Placeholder |
1617
+ | `label` | `string` | — | Label |
1618
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1619
+ | `clearable` | `boolean` | `true` | Tombol clear |
1620
+ | `displayFormat` | `string` | `'dd/MM/yyyy'` | Format tampilan |
1621
+ | `modelType` | `string` | `'yyyy-MM-dd'` | Format v-model |
1622
+ | `locale` | `'id'\|'en'` | `'en'` | Bahasa kalender |
1623
+ | `placement` | `string` | `'bottom-start'` | Posisi dropdown |
1624
+ | `prependInner` | `string` | — | Teks prefix |
1625
+ | `error` | `string\|null` | `null` | Error message |
1626
+ | `tone` | `string` | `'primary'` | Warna tema kalender |
1627
+ | `skeleton` | `boolean` | `false` | Skeleton loading |
1628
+
1629
+ ```vue
1630
+ <template>
1631
+ <!-- Single date -->
1632
+ <DCodeDatePicker
1633
+ v-model="form.tanggal"
1634
+ label="Tanggal Lahir"
1635
+ :range="false"
1636
+ display-format="dd MMMM yyyy"
1637
+ locale="id"
1638
+ />
1639
+
1640
+ <!-- Date range -->
1641
+ <DCodeDatePicker
1642
+ v-model="form.periode"
1643
+ label="Periode"
1644
+ :range="true"
1645
+ />
1646
+ </template>
1647
+ ```
1648
+
1649
+ ---
1650
+
1651
+ ### `DCodeDateRangePicker`
1652
+
1653
+ Date range picker sederhana berbasis popover input.
1654
+
1655
+ | Prop | Tipe | Default | Deskripsi |
1656
+ |------|------|---------|-----------|
1657
+ | `modelValue` | `{ start, end }\|null` | — | Range tanggal (v-model) |
1658
+ | `placeholder` | `string` | `'YYYY-MM-DD - YYYY-MM-DD'` | Placeholder |
1659
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1660
+ | `clearable` | `boolean` | `true` | Tombol clear |
1661
+ | `returnType` | `'date'\|'iso'\|'yyyy-mm-dd'` | `'yyyy-mm-dd'` | Format return |
1662
+ | `requireBoth` | `boolean` | `false` | Wajib isi keduanya |
1663
+
1664
+ ```vue
1665
+ <template>
1666
+ <DCodeDateRangePicker
1667
+ v-model="form.periode"
1668
+ placeholder="Pilih periode..."
1669
+ return-type="yyyy-mm-dd"
1670
+ />
1671
+ </template>
1672
+ ```
1673
+
1674
+ ---
1675
+
1676
+ ### `DCodeCurrencyField`
1677
+
1678
+ Input angka dengan format mata uang otomatis.
1679
+
1680
+ | Prop | Tipe | Default | Deskripsi |
1681
+ |------|------|---------|-----------|
1682
+ | `modelValue` | `number\|null` | — | Nilai angka (v-model) |
1683
+ | `currency` | `string` | `'IDR'` | Kode mata uang (`'IDR'`, `'USD'`) |
1684
+ | `locale` | `string` | `'en-US'` | Locale format angka |
1685
+ | `label` | `string` | — | Label field |
1686
+ | `placeholder` | `string` | — | Placeholder |
1687
+ | `error` | `string\|null` | — | Error message |
1688
+ | `disabled` | `boolean` | — | Nonaktifkan |
1689
+ | `readonly` | `boolean` | — | Read-only |
1690
+ | `clearable` | `boolean` | — | Tombol clear |
1691
+ | `hideClearWhenEmpty` | `boolean` | `true` | Sembunyikan clear jika kosong |
1692
+ | `prependInner` | `string` | — | Override simbol mata uang |
1693
+ | `skeleton` | `boolean` | `false` | Skeleton loading |
1694
+
1695
+ ```vue
1696
+ <template>
1697
+ <DCodeCurrencyField
1698
+ v-model="form.harga"
1699
+ label="Harga"
1700
+ currency="IDR"
1701
+ clearable
1702
+ :error="errors.harga"
1703
+ />
1704
+ </template>
1705
+ ```
1706
+
1707
+ ---
1708
+
1709
+ ### `DCodeCheckbox`
1710
+
1711
+ Checkbox dengan label dan dukungan indeterminate state.
1712
+
1713
+ | Prop | Tipe | Default | Deskripsi |
1714
+ |------|------|---------|-----------|
1715
+ | `modelValue` | `boolean\|null` | — | Nilai checkbox (v-model) |
1716
+ | `visible` | `boolean` | `true` | Tampilkan |
1717
+ | `skeleton` | `boolean` | `false` | Skeleton |
1718
+ | `indeterminate` | `boolean` | `false` | State indeterminate |
1719
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1720
+
1721
+ Gunakan attr `label` untuk teks di samping checkbox.
1722
+
1723
+ ```vue
1724
+ <template>
1725
+ <DCodeCheckbox
1726
+ v-model="form.setuju"
1727
+ label="Saya setuju dengan syarat & ketentuan"
1728
+ required
1729
+ />
1730
+ </template>
1731
+ ```
1732
+
1733
+ ---
1734
+
1735
+ ### `DCodeSwitch`
1736
+
1737
+ Toggle switch dengan berbagai ukuran, warna, dan tooltip.
1738
+
1739
+ | Prop | Tipe | Default | Deskripsi |
1740
+ |------|------|---------|-----------|
1741
+ | `modelValue` | `boolean` | `false` | Status switch (v-model) |
1742
+ | `label` | `string` | `''` | Label teks |
1743
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1744
+ | `size` | `'small'\|'medium'\|'large'` | `'medium'` | Ukuran switch |
1745
+ | `color` | `'primary'\|'success'\|'warning'\|'danger'` | `'primary'` | Warna aktif |
1746
+ | `loading` | `boolean` | `false` | Status loading |
1747
+ | `labelPosition` | `'left'\|'right'` | `'right'` | Posisi label |
1748
+ | `required` | `boolean` | `false` | Required |
1749
+ | `showTooltip` | `boolean` | `false` | Tampilkan tooltip |
1750
+ | `tooltipActiveText` | `string` | `'Aktif'` | Teks tooltip saat aktif |
1751
+ | `tooltipInactiveText` | `string` | `'Tidak Aktif'` | Teks tooltip saat nonaktif |
1752
+
1753
+ ```vue
1754
+ <template>
1755
+ <DCodeSwitch
1756
+ v-model="form.isActive"
1757
+ label="Status Aktif"
1758
+ color="success"
1759
+ size="medium"
1760
+ :show-tooltip="true"
1761
+ />
1762
+ </template>
1763
+ ```
1764
+
1765
+ ---
1766
+
1767
+ ### `DCodeRadio`
1768
+
1769
+ Grup radio button yang bisa fetch opsi dari API.
1770
+
1771
+ | Prop | Tipe | Default | Deskripsi |
1772
+ |------|------|---------|-----------|
1773
+ | `modelValue` | `any` | — | Value terpilih (v-model) |
1774
+ | `label` | `string` | `'name'` | Key field label dari opsi |
1775
+ | `options` | `any[]` | `[]` | Opsi data statis |
1776
+ | `apiUrl` | `string` | `''` | URL endpoint API untuk fetch opsi |
1777
+ | `apiMethod` | `'GET'\|'POST'` | `'GET'` | HTTP method |
1778
+ | `dataPath` | `string` | `''` | Path ke array data dalam response |
1779
+ | `layout` | `boolean` | `true` | Layout horizontal (true) / vertikal |
1780
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1781
+ | `required` | `boolean` | `false` | Required |
1782
+ | `error` | `string\|null` | `null` | Error message |
1783
+ | `size` | `'sm'\|'md'\|'lg'` | `'md'` | Ukuran radio |
1784
+ | `color` | `string` | `'blue'` | Warna accent |
1785
+ | `model` | `string` | `'id'` | Key field nilai dari opsi |
1786
+
1787
+ ```vue
1788
+ <template>
1789
+ <!-- Dengan opsi statis -->
1790
+ <DCodeRadio
1791
+ v-model="form.gender"
1792
+ :options="[
1793
+ { id: 'L', name: 'Laki-laki' },
1794
+ { id: 'P', name: 'Perempuan' },
1795
+ ]"
1796
+ />
1797
+
1798
+ <!-- Dengan API -->
1799
+ <DCodeRadio
1800
+ v-model="form.statusId"
1801
+ api-url="/api/master/status"
1802
+ label="nama"
1803
+ model="id"
1804
+ />
1805
+ </template>
1806
+ ```
1807
+
1808
+ ---
1809
+
1810
+ ### `DCodeRadioCustom`
1811
+
1812
+ Radio button dengan tampilan card kustom dan ikon.
1813
+
1814
+ | Prop | Tipe | Default | Deskripsi |
1815
+ |------|------|---------|-----------|
1816
+ | `modelValue` | `any` | — | Value (v-model) |
1817
+ | `icon` | `string` | — | Nama ikon Lucide untuk setiap card |
1818
+ | `label` | `string` | `'name'` | Key field label |
1819
+ | `options` | `any[]` | `[]` | Opsi statis |
1820
+ | `apiUrl` | `string` | `''` | URL API |
1821
+ | `apiMethod` | `'GET'\|'POST'` | `'GET'` | HTTP method |
1822
+ | `dataPath` | `string` | `''` | Path data dalam response |
1823
+ | `layout` | `boolean` | `true` | Horizontal layout |
1824
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1825
+ | `required` | `boolean` | `false` | Required |
1826
+ | `error` | `string\|null` | `null` | Error message |
1827
+ | `size` | `'sm'\|'md'\|'lg'` | `'md'` | Ukuran |
1828
+ | `color` | `string` | `'blue'` | Warna highlight |
1829
+ | `model` | `string` | `'id'` | Key field nilai |
1830
+
1831
+ ```vue
1832
+ <template>
1833
+ <DCodeRadioCustom
1834
+ v-model="form.plan"
1835
+ :options="[
1836
+ { id: 'basic', name: 'Basic', icon: 'Star' },
1837
+ { id: 'pro', name: 'Pro', icon: 'Zap' },
1838
+ ]"
1839
+ label="name"
1840
+ model="id"
1841
+ />
1842
+ </template>
1843
+ ```
1844
+
1845
+ ---
1846
+
1847
+ ### `DCodeOtpInput`
1848
+
1849
+ Input OTP digit-per-digit dengan submit otomatis ke API.
1850
+
1851
+ | Prop | Tipe | Default | Deskripsi |
1852
+ |------|------|---------|-----------|
1853
+ | `modelValue` | `string` | `''` | Nilai OTP (v-model) |
1854
+ | `totalInput` | `number` | `6` | Jumlah digit OTP |
1855
+ | `default` | `string` | `''` | Default nilai awal |
1856
+ | `label` | `string` | `''` | Label |
1857
+ | `endpoint` | `{ apiMethod?, apiUrl? }` | — | Endpoint untuk submit OTP |
1858
+ | `submitFn` | `Function` | — | Custom submit function |
1859
+
1860
+ Events: `complete` (OTP penuh), `success`, `error`, `loading`
1861
+
1862
+ ```vue
1863
+ <template>
1864
+ <DCodeOtpInput
1865
+ v-model="otp"
1866
+ :total-input="6"
1867
+ label="Kode OTP"
1868
+ :endpoint="{ apiUrl: '/api/auth/verify-otp', apiMethod: 'POST' }"
1869
+ @complete="handleOtpComplete"
1870
+ />
1871
+ </template>
1872
+ ```
1873
+
1874
+ ---
1875
+
1876
+ ### `DCodeFileField`
1877
+
1878
+ Upload file dengan validasi tipe & ukuran, preview, dan upload ke API.
1879
+
1880
+ | Prop | Tipe | Default | Deskripsi |
1881
+ |------|------|---------|-----------|
1882
+ | `modelValue` | `File\|null` | — | File terpilih (v-model) |
1883
+ | `label` | `string` | `'Upload File'` | Label |
1884
+ | `hint` | `string` | — | Teks petunjuk |
1885
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1886
+ | `previewHeight` | `number` | `190` | Tinggi preview (px) |
1887
+ | `previewWidth` | `number` | — | Lebar preview (px) |
1888
+ | `allowedTypes` | `string\|null` | `null` | Tipe file diizinkan (e.g. `'pdf,doc'`) |
1889
+ | `accept` | `string` | — | Attribute accept HTML |
1890
+ | `minSizeMb` | `number\|null` | `null` | Ukuran file minimum (MB) |
1891
+ | `maxSizeMb` | `number` | `5` | Ukuran file maksimum (MB) |
1892
+ | `endpoint` | `{ apiMethod?, apiUrl? }` | — | Endpoint upload |
1893
+ | `uploadFn` | `Function` | — | Custom upload function |
1894
+
1895
+ ```vue
1896
+ <template>
1897
+ <DCodeFileField
1898
+ v-model="form.dokumen"
1899
+ label="Upload Dokumen"
1900
+ allowed-types="pdf,doc,docx"
1901
+ :max-size-mb="10"
1902
+ :endpoint="{ apiUrl: '/api/upload', apiMethod: 'POST' }"
1903
+ @uploaded="handleUploaded"
1904
+ @error="handleError"
1905
+ />
1906
+ </template>
1907
+ ```
1908
+
1909
+ ---
1910
+
1911
+ ### `DCodeImageField`
1912
+
1913
+ Upload gambar dengan crop/resize dialog terintegrasi.
1914
+
1915
+ | Prop | Tipe | Default | Deskripsi |
1916
+ |------|------|---------|-----------|
1917
+ | `modelValue` | `File\|null` | — | File gambar (v-model) |
1918
+ | `label` | `string` | `'Upload Gambar'` | Label |
1919
+ | `hint` | `string` | `'Drag & drop atau klik area ini'` | Petunjuk |
1920
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1921
+ | `allowedTypes` | `string\|null` | `null` | Tipe gambar diizinkan |
1922
+ | `accept` | `string` | `'image/*'` | Accept HTML |
1923
+ | `minSizeMb` | `number\|null` | `null` | Min ukuran (MB) |
1924
+ | `maxSizeMb` | `number` | `2` | Maks ukuran (MB) |
1925
+ | `title` | `string` | `'Hasil Gambar'` | Judul preview |
1926
+ | `description` | `string` | `''` | Deskripsi preview |
1927
+ | `previewWidth` | `number` | `360` | Lebar preview |
1928
+ | `previewHeight` | `number` | `220` | Tinggi preview |
1929
+ | `aspectRatio` | `number\|null` | `null` | Rasio aspek crop |
1930
+ | `outputWidth` | `number\|null` | `null` | Lebar output (px) |
1931
+ | `outputHeight` | `number\|null` | `null` | Tinggi output (px) |
1932
+ | `quality` | `number` | `0.92` | Kualitas output (0-1) |
1933
+ | `autoOpenEditor` | `boolean` | `true` | Buka editor saat file dipilih |
1934
+ | `minWidth` | `number\|null` | `null` | Min lebar gambar |
1935
+ | `minHeight` | `number\|null` | `null` | Min tinggi gambar |
1936
+ | `maxWidth` | `number\|null` | `null` | Maks lebar gambar |
1937
+ | `maxHeight` | `number\|null` | `null` | Maks tinggi gambar |
1938
+ | `endpoint` | `{ apiMethod?, apiUrl? }` | — | Endpoint upload |
1939
+ | `uploadFn` | `Function` | — | Custom upload |
1940
+ | `editUseOriginal` | `boolean` | `false` | Edit dari foto asli (bukan ter-crop) |
1941
+
1942
+ ```vue
1943
+ <template>
1944
+ <DCodeImageField
1945
+ v-model="form.foto"
1946
+ label="Foto Profil"
1947
+ :aspect-ratio="1"
1948
+ :output-width="300"
1949
+ :output-height="300"
1950
+ :max-size-mb="2"
1951
+ />
1952
+ </template>
1953
+ ```
1954
+
1955
+ ---
1956
+
1957
+ ### `DCodeDropzone`
1958
+
1959
+ Area drag-and-drop untuk upload file.
1960
+
1961
+ | Prop | Tipe | Default | Deskripsi |
1962
+ |------|------|---------|-----------|
1963
+ | `label` | `string` | `'Upload File'` | Label |
1964
+ | `hint` | `string` | `'Drag & drop file di sini atau klik area ini'` | Petunjuk |
1965
+ | `accept` | `string` | `'image/*'` | Tipe file diterima |
1966
+ | `maxSizeMb` | `number` | `2` | Maks ukuran (MB) |
1967
+ | `mode` | `'single'\|'multiple'` | `'single'` | Mode pilih satu/banyak |
1968
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
1969
+ | `showSelected` | `boolean` | `true` | Tampilkan nama file terpilih |
1970
+ | `error` | `string\|null` | `null` | Error message |
1971
+
1972
+ Events: `picked` (File), `picked:multiple` (File[]), `error` (string)
1973
+
1974
+ ```vue
1975
+ <template>
1976
+ <DCodeDropzone
1977
+ label="Upload CSV"
1978
+ accept=".csv,.xlsx"
1979
+ :max-size-mb="5"
1980
+ mode="single"
1981
+ @picked="handleFile"
1982
+ />
1983
+ </template>
1984
+ ```
1985
+
1986
+ ---
1987
+
1988
+ ### `DCodeUploadFile`
1989
+
1990
+ Komponen upload file sederhana dengan tombol browse.
1991
+
1992
+ | Prop | Tipe | Default | Deskripsi |
1993
+ |------|------|---------|-----------|
1994
+ | `modelValue` | `any` | — | File (v-model) |
1995
+ | `label` | `string` | — | Label |
1996
+ | `accept` | `string` | — | Tipe file diterima |
1997
+ | `errorMessage` | `string` | — | Pesan error |
1998
+
1999
+ ```vue
2000
+ <template>
2001
+ <DCodeUploadFile
2002
+ v-model="form.file"
2003
+ label="Upload Berkas"
2004
+ accept=".pdf,.doc"
2005
+ />
2006
+ </template>
2007
+ ```
2008
+
2009
+ ---
2010
+
2011
+ ### `DCodeFileResult`
2012
+
2013
+ Menampilkan preview file yang sudah dipilih dengan opsi edit/replace/remove.
2014
+
2015
+ | Prop | Tipe | Default | Deskripsi |
2016
+ |------|------|---------|-----------|
2017
+ | `file` | `File\|null` | — | File untuk ditampilkan |
2018
+ | `title` | `string` | `'File Terpilih'` | Judul card |
2019
+ | `description` | `string` | `''` | Deskripsi |
2020
+ | `disabled` | `boolean` | `false` | Nonaktifkan aksi |
2021
+ | `previewHeight` | `number` | `190` | Tinggi preview |
2022
+ | `previewWidth` | `number` | `220` | Lebar preview |
2023
+ | `showEdit` | `boolean` | `true` | Tampilkan tombol Edit |
2024
+ | `showReplace` | `boolean` | `true` | Tampilkan tombol Ganti |
2025
+ | `showRemove` | `boolean` | `true` | Tampilkan tombol Hapus |
2026
+ | `forceFileIcon` | `boolean` | `false` | Selalu tampilkan ikon file (bukan preview gambar) |
2027
+
2028
+ Events: `edit`, `replace`, `remove`
2029
+
2030
+ ```vue
2031
+ <template>
2032
+ <DCodeFileResult
2033
+ :file="uploadedFile"
2034
+ title="Dokumen Saya"
2035
+ :show-edit="false"
2036
+ @replace="handleReplace"
2037
+ @remove="handleRemove"
2038
+ />
2039
+ </template>
2040
+ ```
2041
+
2042
+ ---
2043
+
2044
+ ### `DCodeImageResult`
2045
+
2046
+ Menampilkan preview gambar yang sudah dipilih.
2047
+
2048
+ | Prop | Tipe | Default | Deskripsi |
2049
+ |------|------|---------|-----------|
2050
+ | `file` | `File\|null` | — | File gambar |
2051
+ | `title` | `string` | `'Hasil Gambar'` | Judul card |
2052
+ | `description` | `string` | `''` | Deskripsi |
2053
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
2054
+ | `previewHeight` | `number` | `190` | Tinggi preview |
2055
+ | `previewWidth` | `number` | `220` | Lebar preview |
2056
+ | `showEdit` | `boolean` | `true` | Tombol edit |
2057
+ | `showReplace` | `boolean` | `true` | Tombol ganti |
2058
+ | `showRemove` | `boolean` | `true` | Tombol hapus |
2059
+
2060
+ Events: `edit`, `replace`, `remove`
2061
+
2062
+ ```vue
2063
+ <template>
2064
+ <DCodeImageResult
2065
+ :file="imageFile"
2066
+ title="Foto Profil"
2067
+ @edit="openCropper"
2068
+ @remove="clearImage"
2069
+ />
2070
+ </template>
2071
+ ```
2072
+
2073
+ ---
2074
+
2075
+ ### `DCodeImageCropperDialog`
2076
+
2077
+ Dialog crop / resize gambar menggunakan Uppy + ImageEditor.
2078
+
2079
+ | Prop | Tipe | Default | Deskripsi |
2080
+ |------|------|---------|-----------|
2081
+ | `modelValue` | `boolean` | — | Status dialog (v-model) |
2082
+ | `file` | `File\|null` | — | File gambar sumber |
2083
+ | `title` | `string` | `'Resize & Crop Gambar'` | Judul dialog |
2084
+ | `description` | `string` | `''` | Deskripsi |
2085
+ | `aspectRatio` | `number\|null` | `null` | Rasio aspek (e.g. `16/9`) |
2086
+ | `outputWidth` | `number\|null` | `null` | Lebar output (px) |
2087
+ | `outputHeight` | `number\|null` | `null` | Tinggi output (px) |
2088
+ | `quality` | `number` | `0.92` | Kualitas gambar output |
2089
+ | `autoOpenEditor` | `boolean` | `false` | Buka editor otomatis |
2090
+
2091
+ Events: `update:modelValue`, `done` (File), `cancel`
2092
+
2093
+ ```vue
2094
+ <template>
2095
+ <DCodeImageCropperDialog
2096
+ v-model="cropperOpen"
2097
+ :file="selectedFile"
2098
+ :aspect-ratio="16/9"
2099
+ :output-width="1280"
2100
+ :output-height="720"
2101
+ @done="handleCropDone"
2102
+ />
2103
+ </template>
2104
+ ```
2105
+
2106
+ ---
2107
+
2108
+ ### `DCodeDialog`
2109
+
2110
+ Modal dialog yang dapat dikonfigurasi dengan slot.
2111
+
2112
+ | Prop | Tipe | Default | Deskripsi |
2113
+ |------|------|---------|-----------|
2114
+ | `modelValue` | `boolean` | `false` | Status buka/tutup (v-model) |
2115
+ | `title` | `string` | `''` | Judul dialog |
2116
+ | `icon` | `string` | `''` | Nama ikon Lucide di header |
2117
+ | `maxWidth` | `string\|number` | `500` | Lebar maksimum (px atau string CSS) |
2118
+ | `persistent` | `boolean` | `true` | Tidak tutup saat klik di luar |
2119
+ | `contentClass` | `string` | `'p-5'` | Class pada area konten |
2120
+ | `contentStyle` | `object\|string` | `{}` | Style tambahan konten |
2121
+
2122
+ ```vue
2123
+ <template>
2124
+ <DCodeDialog v-model="dialogOpen" title="Konfirmasi Hapus" icon="Trash2" :max-width="400">
2125
+ <p>Apakah Anda yakin ingin menghapus data ini?</p>
2126
+ <template #footer>
2127
+ <DCodeButton text="Batal" variant="outline" @click="dialogOpen = false" />
2128
+ <DCodeButton text="Hapus" variant="destructive" @click="confirmDelete" />
2129
+ </template>
2130
+ </DCodeDialog>
2131
+ </template>
2132
+ ```
2133
+
2134
+ ---
2135
+
2136
+ ### `DCodeDialogCloseBtn`
2137
+
2138
+ Tombol close berbentuk lingkaran untuk digunakan di dalam dialog.
2139
+
2140
+ | Prop | Tipe | Default | Deskripsi |
2141
+ |------|------|---------|-----------|
2142
+ | `icon` | `string` | `'X'` | Nama ikon Lucide |
2143
+ | `iconSize` | `string\|number` | `22` | Ukuran ikon |
2144
+
2145
+ ```vue
2146
+ <template>
2147
+ <DCodeDialogCloseBtn @click="dialogOpen = false" />
2148
+ </template>
2149
+ ```
2150
+
2151
+ ---
2152
+
2153
+ ### `DCodeIconDropdown`
2154
+
2155
+ Dropdown untuk memilih ikon dari library Lucide.
2156
+
2157
+ | Prop | Tipe | Default | Deskripsi |
2158
+ |------|------|---------|-----------|
2159
+ | `modelValue` | `string\|null` | — | Nama ikon terpilih (v-model) |
2160
+ | `label` | `string` | — | Label field |
2161
+ | `placeholder` | `string` | `'Pilih icon…'` | Placeholder |
2162
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
2163
+ | `required` | `boolean` | `false` | Required |
2164
+ | `clearable` | `boolean` | `true` | Tombol clear |
2165
+ | `columns` | `number` | `4` | Jumlah kolom grid ikon |
2166
+ | `maxHeight` | `string` | `'335px'` | Tinggi maksimum dropdown |
2167
+ | `iconSize` | `number` | `20` | Ukuran ikon dalam grid (px) |
2168
+ | `pageSize` | `number` | `120` | Jumlah ikon per halaman |
2169
+
2170
+ ```vue
2171
+ <template>
2172
+ <DCodeIconDropdown
2173
+ v-model="form.icon"
2174
+ label="Pilih Ikon Menu"
2175
+ :columns="5"
2176
+ clearable
2177
+ />
2178
+ </template>
2179
+ ```
2180
+
2181
+ ---
2182
+
2183
+ ### `DCodeLabel`
2184
+
2185
+ Label teks dengan ikon opsional dan berbagai ukuran.
2186
+
2187
+ | Prop | Tipe | Default | Deskripsi |
2188
+ |------|------|---------|-----------|
2189
+ | `label` | `string` | — | Teks label (alias dari `text`) |
2190
+ | `text` | `string` | — | Teks label |
2191
+ | `textSize` | `'xs'\|'sm'\|'base'\|'lg'\|'xl'\|'2xl'\|'3xl'\|'4xl'\|'5xl'\|'6xl'` | `'xs'` | Ukuran teks |
2192
+ | `textType` | `'BOLD'\|'ITALIC'\|'REGULAR'` | `'REGULAR'` | Gaya teks |
2193
+ | `icon` | `string` | — | Nama ikon Lucide |
2194
+ | `iconClass` | `string` | — | Class tambahan untuk ikon |
2195
+
2196
+ ```vue
2197
+ <template>
2198
+ <DCodeLabel label="Total Transaksi" text-size="lg" text-type="BOLD" />
2199
+ <DCodeLabel text="Info" icon="Info" text-size="sm" />
2200
+ </template>
2201
+ ```
2202
+
2203
+ ---
2204
+
2205
+ ### `DCodeCard`
2206
+
2207
+ Kontainer kartu dengan header, subtitle, actions slot, dan footer slot.
2208
+
2209
+ | Prop | Tipe | Default | Deskripsi |
2210
+ |------|------|---------|-----------|
2211
+ | `level` | `1\|2\|3` | `1` | Level nesting (mempengaruhi background) |
2212
+ | `title` | `string` | — | Judul card |
2213
+ | `subtitle` | `string` | — | Subtitle card |
2214
+ | `shadow` | `boolean` | `false` | Tambahkan drop shadow |
2215
+ | `border` | `boolean` | `true` | Tampilkan border |
2216
+ | `padding` | `string` | `'p-6'` | Class padding (tailwind) |
2217
+
2218
+ Slots: `default` (konten), `header`, `actions`, `footer`
2219
+
2220
+ ```vue
2221
+ <template>
2222
+ <DCodeCard title="Data Pengguna" subtitle="Daftar semua user" shadow>
2223
+ <template #actions>
2224
+ <DCodeButton text="Tambah" icon="Plus" />
2225
+ </template>
2226
+
2227
+ <!-- Konten -->
2228
+ <p>Isi card di sini...</p>
2229
+
2230
+ <template #footer>
2231
+ <span class="text-sm text-gray-500">Updated 5 minutes ago</span>
2232
+ </template>
2233
+ </DCodeCard>
2234
+ </template>
2235
+ ```
2236
+
2237
+ ---
2238
+
2239
+ ### `DCodeProgressBar`
2240
+
2241
+ Progress bar global yang biasanya dipasang di layout untuk indikator loading API.
2242
+
2243
+ | Prop | Tipe | Default | Deskripsi |
2244
+ |------|------|---------|-----------|
2245
+ | `isApiLoading` | `boolean` | `false` | Tampilkan progress bar |
2246
+ | `apiProgress` | `number` | `0` | Persentase progress (0-100) |
2247
+
2248
+ ```vue
2249
+ <template>
2250
+ <!-- Biasanya di App.vue atau Layout -->
2251
+ <DCodeProgressBar :is-api-loading="isLoading" :api-progress="loadingProgress" />
2252
+ </template>
2253
+ ```
2254
+
2255
+ ---
2256
+
2257
+ ### `DCodeProgress`
2258
+
2259
+ Progress bar inline yang bisa digunakan di dalam konten.
2260
+
2261
+ | Prop | Tipe | Default | Deskripsi |
2262
+ |------|------|---------|-----------|
2263
+ | `modelValue` | `number` | `0` | Nilai progress (v-model) |
2264
+ | `max` | `number` | `100` | Nilai maksimum |
2265
+ | `label` | `string` | `''` | Label teks |
2266
+ | `showValue` | `boolean` | `false` | Tampilkan persentase |
2267
+ | `color` | `string` | `'blue'` | Warna bar (`'blue'`, `'green'`, `'red'`, `'yellow'`, `'purple'`, `'gray'`) |
2268
+ | `size` | `'sm'\|'md'\|'lg'` | `'md'` | Ketebalan bar |
2269
+ | `striped` | `boolean` | `false` | Tampilan garis-garis |
2270
+ | `animated` | `boolean` | `false` | Animasi gerak |
2271
+
2272
+ ```vue
2273
+ <template>
2274
+ <DCodeProgress
2275
+ :model-value="75"
2276
+ label="Progress Upload"
2277
+ color="green"
2278
+ size="lg"
2279
+ :show-value="true"
2280
+ animated
2281
+ />
2282
+ </template>
2283
+ ```
2284
+
2285
+ ---
2286
+
2287
+ ### `DCodeSlider`
2288
+
2289
+ Input slider (range) dengan label, min/max, dan mark.
2290
+
2291
+ | Prop | Tipe | Default | Deskripsi |
2292
+ |------|------|---------|-----------|
2293
+ | `modelValue` | `number` | `0` | Nilai slider (v-model) |
2294
+ | `min` | `number` | `0` | Nilai minimum |
2295
+ | `max` | `number` | `100` | Nilai maksimum |
2296
+ | `step` | `number` | `1` | Langkah perubahan |
2297
+ | `disabled` | `boolean` | `false` | Nonaktifkan |
2298
+ | `label` | `string` | `''` | Label |
2299
+ | `required` | `boolean` | `false` | Required |
2300
+ | `error` | `string\|null` | `null` | Error message |
2301
+ | `showValue` | `boolean` | `true` | Tampilkan nilai saat ini |
2302
+ | `valuePrefix` | `string` | `''` | Prefix nilai (e.g. `'Rp'`) |
2303
+ | `valueSuffix` | `string` | `''` | Suffix nilai (e.g. `'%'`) |
2304
+ | `marks` | `{ value: number; label: string }[]` | `[]` | Mark pada slider |
2305
+ | `color` | `string` | `'blue'` | Warna slider |
2306
+ | `size` | `'sm'\|'md'\|'lg'` | `'md'` | Ukuran track |
2307
+
2308
+ ```vue
2309
+ <template>
2310
+ <DCodeSlider
2311
+ v-model="form.diskon"
2312
+ label="Diskon"
2313
+ :min="0"
2314
+ :max="100"
2315
+ :step="5"
2316
+ value-suffix="%"
2317
+ color="green"
2318
+ :marks="[
2319
+ { value: 0, label: '0%' },
2320
+ { value: 50, label: '50%' },
2321
+ { value: 100, label: '100%' },
2322
+ ]"
2323
+ />
2324
+ </template>
2325
+ ```
2326
+
2327
+ ---
2328
+
2329
+ ### `DCodeChart`
2330
+
2331
+ Komponen chart berbasis Chart.js yang mendukung berbagai tipe grafik.
2332
+
2333
+ | Prop | Tipe | Default | Deskripsi |
2334
+ |------|------|---------|-----------|
2335
+ | `type` | `string` | `'line'` | Tipe chart: `'line'`, `'bar'`, `'pie'`, `'doughnut'` |
2336
+ | `modelValue` | `any` | — | Data chart (v-model) – format Chart.js |
2337
+ | `data` | `any` | — | Data chart (alternatif v-model) |
2338
+ | `options` | `any` | — | Opsi Chart.js custom |
2339
+ | `width` | `number` | `400` | Lebar canvas |
2340
+ | `height` | `number` | `300` | Tinggi canvas (px) |
2341
+ | `loading` | `boolean` | `false` | Status loading |
2342
+ | `error` | `string\|null` | `null` | Pesan error |
2343
+ | `showInfo` | `boolean` | `false` | Tampilkan info dataset/datapoints |
2344
+ | `responsive` | `boolean` | `true` | Responsif |
2345
+ | `maintainAspectRatio` | `boolean` | `false` | Pertahankan rasio aspek |
2346
+ | `theme` | `string` | `'light'` | Tema: `'light'` / `'dark'` |
2347
+ | `colors` | `string[]` | 10 warna default | Palet warna |
2348
+ | `label` | `string` | — | Label di atas chart |
2349
+ | `required` | `boolean` | `false` | Required indicator |
2350
+
2351
+ Events: `click`, `hover`, `ready`
2352
+
2353
+ ```vue
2354
+ <script setup>
2355
+ const chartData = {
2356
+ labels: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei'],
2357
+ datasets: [{
2358
+ label: 'Penjualan',
2359
+ data: [120, 190, 300, 250, 400],
2360
+ }]
2361
+ }
2362
+ </script>
2363
+
2364
+ <template>
2365
+ <DCodeChart
2366
+ type="bar"
2367
+ :model-value="chartData"
2368
+ :height="350"
2369
+ label="Laporan Penjualan"
2370
+ theme="light"
2371
+ />
2372
+ </template>
2373
+ ```
2374
+
2375
+ ---
2376
+
2377
+ ### `DCodeWizard`
2378
+
2379
+ Komponen wizard/stepper multi-langkah dengan navigasi dan loading data per tab.
2380
+
2381
+ | Prop | Tipe | Default | Deskripsi |
2382
+ |------|------|---------|-----------|
2383
+ | `tabs` | `WizardTab[]` | — | **Required.** Definisi tab/langkah |
2384
+ | `modelValue` | `number\|string` | — | Index/key tab aktif (v-model) |
2385
+ | `defaultTab` | `number` | — | Tab default yang aktif |
2386
+ | `allowTabClick` | `boolean` | — | Izinkan klik langsung ke tab |
2387
+ | `disabled` | `boolean` | — | Nonaktifkan navigasi |
2388
+ | `cache` | `boolean` | — | Cache data tab yang sudah dimuat |
2389
+ | `autoFetchOnMount` | `boolean` | — | Fetch data tab aktif saat mount |
2390
+ | `apiOptions` | `object\|Function` | — | Opsi API tambahan |
2391
+ | `isVertical` | `boolean` | — | Layout vertical |
2392
+ | `isWizard` | `boolean` | — | Mode wizard (step-by-step, tidak bisa loncat) |
2393
+ | `typeWizard` | `'number'\|'icon'\|'none'\|null` | — | Tipe indikator langkah |
2394
+ | `showNavigation` | `boolean` | — | Tampilkan tombol navigasi Prev/Next |
2395
+ | `submitText` | `string` | — | Teks tombol submit di langkah terakhir |
2396
+ | `loading` | `boolean` | — | Loading eksternal |
2397
+
2398
+ **`WizardTab` type:**
2399
+ ```ts
2400
+ type WizardTab = {
2401
+ key: string
2402
+ title: string
2403
+ description?: string
2404
+ icon?: Component
2405
+ disabled?: boolean
2406
+ endpoint?: { apiUrl?, apiMethod?, apiModule?, apiAction? }
2407
+ fetchData?: () => Promise<any>
2408
+ isDataTable?: boolean
2409
+ }
2410
+ ```
2411
+
2412
+ ```vue
2413
+ <script setup>
2414
+ import { ref } from 'vue'
2415
+ const steps = [
2416
+ { key: 'info', title: 'Info Dasar' },
2417
+ { key: 'detail', title: 'Detail' },
2418
+ { key: 'review', title: 'Review' },
2419
+ ]
2420
+ const activeStep = ref(0)
2421
+ </script>
2422
+
2423
+ <template>
2424
+ <DCodeWizard
2425
+ v-model="activeStep"
2426
+ :tabs="steps"
2427
+ is-wizard
2428
+ type-wizard="number"
2429
+ :show-navigation="true"
2430
+ submit-text="Selesai"
2431
+ @submit="handleSubmit"
2432
+ >
2433
+ <template #info>
2434
+ <!-- Konten step Info Dasar -->
2435
+ </template>
2436
+ <template #detail>
2437
+ <!-- Konten step Detail -->
2438
+ </template>
2439
+ <template #review>
2440
+ <!-- Konten step Review -->
2441
+ </template>
2442
+ </DCodeWizard>
2443
+ </template>
2444
+ ```
2445
+
2446
+ ---
2447
+
2448
+ ### `DCodeTimelineWithIcons`
2449
+
2450
+ Komponen timeline interaktif dengan berbagai tipe item (flight, interview, dll.).
2451
+
2452
+ Komponen ini merender timeline visual dari array item yang sudah terdefinisi di dalamnya. Cocok digunakan untuk menampilkan riwayat proses, activity log, atau alur perjalanan.
2453
+
2454
+ > ℹ️ Komponen ini tidak memiliki props eksternal — data dan tampilan dikonfigurasi secara internal. Gunakan sebagai komponen display/demo timeline.
2455
+
2456
+ ```vue
2457
+ <template>
2458
+ <DCodeTimelineWithIcons />
2459
+ </template>
2460
+ ```
2461
+
2462
+ ---
2463
+
1321
2464
  ## Lisensi
1322
2465
 
1323
2466
  MIT © [Gema Fajar Ramadhan](https://github.com/gemafajarramadhan)