npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dtd-ui/vue

v0.1.5

Published

DTD Design System UI Component Library for Vue 3 and Tailwind CSS

Readme

@dtd-ui/vue

npm version license vue typescript tailwind

Pustaka komponen antarmuka pengguna (UI Component Library) resmi DTD Design System berbasis Vue 3 dan Tailwind CSS v4 untuk ekosistem aplikasi web Direktorat Transformasi Digital (DTD) Universitas Indonesia. Menyediakan rangkaian komponen formulir, tabel data interaktif, navigasi, serta modul dialog dan notifikasi dengan identitas visual kuning Makara yang konsisten.


Daftar Isi


Fitur Utama

  • 13 Komponen Produksi Siap Pakai:
    • 9 Komponen UI & Formulir (ui/): BaseButton, BaseCheckbox, BaseInput, BaseInputDate, BaseInputDateRangePicker, BaseSelect, BaseSelectMultiple, BaseBreadcrumb, BaseDataTable.
    • 4 Komponen Popup & Feedback (popup/): BaseDialog, BaseConfirmDialog, BaseLoadingDialog, BaseToast.
  • Injeksi Gaya Otomatis (Zero CSS Import): Seluruh stylesheet Tailwind CSS dan variabel tema telah di-bundle dan di-inject secara otomatis melalui JavaScript (vite-plugin-css-injected-by-js).
  • Dukungan TypeScript Kelas Satu: Dilengkapi definisi tipe .d.ts penuh, generics pada komponen tabel (BaseDataTable<T>), serta dokumentasi JSDoc berbahasa Indonesia untuk autocomplete di IDE.
  • Responsif & Ramah Aksesibilitas: Tabel data otomatis bertransformasi menjadi tampilan kartu (card list) pada layar perangkat seluler (< 640px), serta popup dan dropdown dirender menggunakan <Teleport to="body"> untuk mencegah masalah pemotongan kontainer (overflow: hidden).
  • Kustomisasi Mudah via CSS Variables: Seluruh skema warna, border, bayangan fokus, dan radius sudut dapat disesuaikan secara dinamis melalui variabel :root.
  • Dual Module Format: Mendukung sistem modul modern ESM (dtd-ui-vue.es.js) dan UMD (dtd-ui-vue.umd.js).

Instalasi & Dependensi

Instal paket @dtd-ui/vue beserta peer dependency yang dibutuhkan di proyek Vue 3 Anda:

npm install @dtd-ui/vue

Peer Dependencies & Dependensi Ikon

Paket ini membutuhkan vue versi ^3.0.0 dan menggunakan @iconify/vue untuk merender ikon pada tombol, tabel, serta dialog:

npm install vue@^3.0.0 @iconify/vue@^5.0.3

| Paket | Versi | Status | Keterangan | | :--- | :--- | :--- | :--- | | vue | ^3.0.0 | Peer Dependency (Wajib) | Kerangka kerja utama Vue 3 | | @iconify/vue | ^5.0.3 | Dependency Terintegrasi | Komponen ikon dinamis (Lucide, Solar, dll.) |


Mulai Cepat (Quickstart)

[!TIP] Anda tidak perlu mengimpor file CSS secara terpisah karena @dtd-ui/vue otomatis menyuntikkan gaya komponen ke dalam <head> saat komponen diimpor.

1. Penggunaan Langsung (Per Komponen)

Impor komponen dan tipe yang Anda perlukan langsung dari @dtd-ui/vue:

<script setup lang="ts">
import { ref } from 'vue'
import {
  BaseButton,
  BaseInput,
  BaseSelect,
  BaseConfirmDialog,
  BaseToast,
  type SelectOption,
} from '@dtd-ui/vue'

const nama = ref('')
const prodi = ref<string | null>(null)
const showConfirm = ref(false)
const showToast = ref(false)

const prodiOptions: SelectOption<string>[] = [
  { label: 'Ilmu Komputer', value: 'ik' },
  { label: 'Sistem Informasi', value: 'si' },
  { label: 'Teknik Komputer', value: 'tk' },
]

function handleSave() {
  showConfirm.value = false
  showToast.value = true
}
</script>

<template>
  <div class="p-6 max-w-md space-y-4">
    <BaseInput
      v-model="nama"
      label="Nama Lengkap"
      placeholder="Masukkan nama mahasiswa..."
      required
    />

    <BaseSelect
      v-model="prodi"
      :options="prodiOptions"
      label="Program Studi"
      placeholder="Pilih program studi..."
      searchable
      required
    />

    <BaseButton variant="primary" icon="lucide:save" @click="showConfirm = true">
      Simpan Data
    </BaseButton>

    <BaseConfirmDialog
      v-model="showConfirm"
      type="info"
      title="Konfirmasi Penyimpanan"
      message="Apakah Anda yakin data yang dimasukkan sudah benar?"
      confirm-label="Ya, Simpan"
      cancel-label="Periksa Kembali"
      @confirm="handleSave"
    />

    <BaseToast
      v-model="showToast"
      type="success"
      title="Berhasil Disimpan"
      message="Data mahasiswa telah berhasil diperbarui ke dalam sistem."
      :duration="3000"
    />
  </div>
</template>

2. Registrasi Global

Jika Anda ingin mendaftarkan seluruh atau sebagian komponen secara global pada file entri aplikasi (main.ts):

// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import {
  BaseButton,
  BaseCheckbox,
  BaseInput,
  BaseInputDate,
  BaseInputDateRangePicker,
  BaseSelect,
  BaseSelectMultiple,
  BaseBreadcrumb,
  BaseDataTable,
  BaseDialog,
  BaseConfirmDialog,
  BaseLoadingDialog,
  BaseToast,
} from '@dtd-ui/vue'

const app = createApp(App)

const components = {
  BaseButton,
  BaseCheckbox,
  BaseInput,
  BaseInputDate,
  BaseInputDateRangePicker,
  BaseSelect,
  BaseSelectMultiple,
  BaseBreadcrumb,
  BaseDataTable,
  BaseDialog,
  BaseConfirmDialog,
  BaseLoadingDialog,
  BaseToast,
}

Object.entries(components).forEach(([name, component]) => {
  app.component(name, component)
})

app.mount('#app')

Kategori 1: Komponen UI & Formulir (ui/)

1. BaseButton

Komponen tombol aksi interaktif dengan dukungan berbagai varian warna, tiga ukuran standar, penempatan ikon di sisi kiri/kanan (menggunakan @iconify/vue), mode khusus ikon (icon-only), serta indikator pemuatan (loading spinner).

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | icon | string \| undefined | undefined | Nama ikon dari Iconify yang ditampilkan di sisi kiri label (contoh: 'lucide:plus'). | | iconRight | string \| undefined | undefined | Nama ikon dari Iconify yang ditampilkan di sisi kanan label. Diabaikan saat iconOnly atau loading bernilai true. | | iconOnly | boolean | false | Jika true, hanya menampilkan ikon tanpa label teks dan menyesuaikan dimensi tombol menjadi persegi (sm: h-7 w-7, md: h-9 w-9, lg: h-11 w-11). | | variant | 'primary' \| 'secondary' \| 'danger' \| 'ghost' \| 'success' \| 'warning' \| 'info' | 'secondary' | Gaya visual tombol yang menentukan skema warna latar, teks, border, dan efek hover. | | size | 'sm' \| 'md' \| 'lg' | 'md' | Ukuran dimensi tombol beserta padding, ukuran font, dan ukuran ikon. | | disabled | boolean | false | Menonaktifkan interaksi tombol dan mengubah tampilan menjadi status disabled. | | loading | boolean | false | Menampilkan animasi spinner berputar dan menonaktifkan interaksi klik tombol. | | type | 'button' \| 'submit' \| 'reset' | 'button' | Menentukan atribut tipe HTML standar pada elemen <button>. |

Events / Emits

Komponen ini meneruskan event DOM standar secara langsung pada elemen <button> root (seperti @click). Tidak ada custom emit khusus yang didefinisikan di dalam komponen.

Slots & Metode Terekspos

  • Slots:
    • default: Konten atau label teks tombol (disembunyikan secara otomatis apabila iconOnly bernilai true).
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseButton } from '@dtd-ui/vue'

const isSaving = ref(false)
</script>

<template>
  <div class="flex flex-wrap items-center gap-3">
    <!-- Varian Utama & Sekunder (Kuning DTD) -->
    <BaseButton variant="primary" icon="lucide:check">Simpan</BaseButton>
    <BaseButton variant="secondary">Aksi Standar</BaseButton>

    <!-- Varian Status & Ghost -->
    <BaseButton variant="success" icon="lucide:refresh-cw">Sinkronisasi</BaseButton>
    <BaseButton variant="danger" icon="lucide:trash-2">Hapus</BaseButton>
    <BaseButton variant="warning">Peringatan</BaseButton>
    <BaseButton variant="info" icon-right="lucide:arrow-right">Detail</BaseButton>
    <BaseButton variant="ghost">Batal</BaseButton>

    <!-- Mode Loading & Icon Only -->
    <BaseButton variant="primary" :loading="isSaving">Memproses...</BaseButton>
    <BaseButton variant="ghost" icon="lucide:settings" icon-only size="md" />
  </div>
</template>

2. BaseCheckbox

Komponen input kotak centang (checkbox) kustom yang mendukung pengikatan dua arah (v-model), status parsial (indeterminate), penanda wajib/opsional, serta tampilan pesan kesalahan (error).

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | boolean | false | Nilai status terikat dari checkbox (digunakan secara internal oleh v-model). | | label | string \| undefined | undefined | Label teks yang ditampilkan di sebelah kanan kotak centang. | | optional | boolean \| undefined | undefined | Menampilkan penanda "(Opsional)" bernada pudar di samping label teks. | | required | boolean \| undefined | undefined | Menambahkan tanda bintang merah (*) di sebelah label dan mengaktifkan sorotan border merah saat tidak dicentang. | | disabled | boolean \| undefined | undefined | Menonaktifkan interaksi klik dan meredupkan tampilan checkbox. | | error | string \| undefined | undefined | Menampilkan teks pesan kesalahan (error) berwarna merah di bawah checkbox. | | indeterminate | boolean \| undefined | undefined | Menampilkan ikon garis mendatar parsial (indeterminate) terlepas dari nilai modelValue. |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (value: boolean) | Dipancarkan saat pengguna mengubah status centang melalui klik pada baris atau input checkbox. |

Slots & Metode Terekspos

  • Slots: Tidak ada (menggunakan prop label).
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseCheckbox } from '@dtd-ui/vue'

const setujuSyarat = ref(false)
const pilihSebagian = ref(false)
</script>

<template>
  <div class="space-y-3">
    <BaseCheckbox
      v-model="setujuSyarat"
      label="Saya menyetujui seluruh syarat dan ketentuan pendaftaran"
      required
      :error="!setujuSyarat ? 'Persetujuan wajib dicentang' : undefined"
    />

    <BaseCheckbox
      v-model="pilihSebagian"
      label="Pilih Semua Peserta"
      :indeterminate="true"
    />
  </div>
</template>

3. BaseInput

Komponen input teks serbaguna yang mendukung tipe text, password (dilengkapi tombol toggle lihat/sembunyikan kata sandi), email, number (konversi otomatis ke tipe Number), dan tel (sanitasi otomatis karakter telepon hanya ke 0-9, +, -, (, ), dan spasi), serta penyisipan ikon HTML/SVG di sisi kiri (prefix) maupun kanan (suffix).

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | string \| number | Wajib | Nilai yang terikat pada input (digunakan untuk v-model). | | type | 'text' \| 'password' \| 'email' \| 'number' \| 'tel' | 'text' | Tipe input HTML yang menentukan perilaku input dan validasi karakter. | | label | string \| undefined | undefined | Teks label deskriptif yang ditempatkan di bagian atas kolom input. | | placeholder | string \| undefined | undefined | Teks petunjuk yang tampil saat bidang input kosong. | | optional | boolean \| undefined | undefined | Menampilkan penanda "(Opsional)" di sebelah teks label. | | required | boolean \| undefined | undefined | Menambahkan tanda bintang merah (*) wajib isi dan indikator border merah ketika nilai kosong. | | disabled | boolean \| undefined | undefined | Menonaktifkan bidang input dan mencegah pengetikan. | | error | string \| undefined | undefined | Teks pesan kesalahan yang dirender dengan warna merah di bawah kolom input. | | prefixIcon | string \| undefined | undefined | String kode mentah HTML/SVG (v-html) untuk dirender sebagai ikon sisi kiri dalam input. | | suffixIcon | string \| undefined | undefined | String kode mentah HTML/SVG (v-html) untuk dirender sebagai ikon sisi kanan. Diabaikan jika type="password". |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (value: string \| number) | Dipancarkan setiap kali nilai input berubah. Mengembalikan number jika type="number", atau string yang telah dibersihkan untuk tipe lainnya. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseInput } from '@dtd-ui/vue'

const email = ref('')
const password = ref('')
const telepon = ref('')
const searchSvg = `<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>`
</script>

<template>
  <div class="space-y-4">
    <BaseInput
      v-model="email"
      type="email"
      label="Alamat Email"
      placeholder="[email protected]"
      :prefix-icon="searchSvg"
      required
    />

    <BaseInput
      v-model="password"
      type="password"
      label="Kata Sandi"
      placeholder="Masukkan kata sandi..."
      required
    />

    <BaseInput
      v-model="telepon"
      type="tel"
      label="Nomor Telepon"
      placeholder="+62 812-xxxx-xxxx"
      optional
    />
  </div>
</template>

4. BaseInputDate

Komponen pemilih tanggal tunggal (single date picker) interaktif dengan popover kalender yang memiliki navigasi bertingkat beranimasi (Hari -> Bulan -> Dekade 10 Tahun), batas tanggal minimum/maksimum (min/max), dan tombol hapus pilihan.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | string | Wajib | Nilai tanggal terikat (v-model) mengikuti format string tanggal standar (misal '2026-10-15') atau sesuai prop format. | | label | string \| undefined | undefined | Teks label deskriptif di bagian atas kolom input tanggal. | | placeholder | string \| undefined | 'Pilih tanggal' | Teks petunjuk saat nilai input tanggal dalam kondisi kosong. | | optional | boolean \| undefined | undefined | Menampilkan tanda "(Opsional)" di samping teks label. | | required | boolean \| undefined | undefined | Menambahkan tanda bintang merah (*) di sebelah label dan menampilkan pesan "Kolom ini wajib diisi" saat kosong (jika error tidak diisi). | | disabled | boolean \| undefined | undefined | Menonaktifkan interaksi bidang input dan dropdown kalender. | | error | string \| undefined | undefined | Teks pesan kesalahan khusus yang ditampilkan dengan warna merah di bawah input. | | min | string \| undefined | undefined | Batas tanggal minimal yang diizinkan untuk dipilih (format YYYY-MM-DD, DD/MM/YYYY, atau string tanggal valid). | | max | string \| undefined | undefined | Batas tanggal maksimal yang diizinkan untuk dipilih. | | showIcon | boolean \| undefined | true | Menentukan apakah ikon kalender ditampilkan di sisi kiri dalam kolom input. | | format | string \| undefined | 'yyyy-MM-dd' | Format representasi tampilan dan nilai output tanggal (mendukung token dd, MM, yyyy, contoh: 'yyyy-MM-dd' atau 'dd/MM/yyyy'). | | size | 'sm' \| 'md' \| undefined | 'md' | Ukuran dimensi vertikal kolom input dan ukuran font (sm: py-1.5 text-xs, md: py-3 text-[0.92rem]). |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (value: string) | Dipancarkan saat tanggal baru dipilih dari kalender atau dikosongkan ('') melalui tombol hapus. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseInputDate } from '@dtd-ui/vue'

const tanggalUjian = ref('2026-05-10')
</script>

<template>
  <BaseInputDate
    v-model="tanggalUjian"
    label="Tanggal Pelaksanaan Ujian"
    placeholder="Pilih tanggal ujian"
    format="yyyy-MM-dd"
    min="2026-01-01"
    max="2026-12-31"
    required
  />
</template>

5. BaseInputDateRangePicker

Komponen pemilih rentang tanggal (date range picker) dengan tampilan dua panel kalender berdampingan (dual-month), pratinjau sorotan rentang saat kursor diarahkan (hover preview), pengurutan tanggal awal dan akhir secara otomatis, serta penutupan popover otomatis setelah tanggal kedua dipilih.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | DateRangeValue | Wajib | Objek rentang tanggal terikat ({ start: string \| null, end: string \| null }) untuk v-model. | | label | string \| undefined | undefined | Teks label deskriptif di bagian atas kolom input rentang tanggal. | | placeholder | string \| undefined | 'Pilih rentang tanggal' | Teks petunjuk saat belum ada rentang tanggal yang dipilih. | | optional | boolean \| undefined | undefined | Menampilkan tanda "(Opsional)" di samping teks label. | | required | boolean \| undefined | undefined | Menambahkan tanda bintang merah (*) dan sorotan border merah ketika rentang belum dipilih. | | disabled | boolean \| undefined | undefined | Menonaktifkan interaksi bidang input dan popover kalender. | | error | string \| undefined | undefined | Teks pesan kesalahan khusus yang ditampilkan di bawah input. | | format | string \| undefined | 'dd/MM/yyyy' | Format token representasi tanggal untuk parsing dan pemformatan tampilan (mendukung token dd, MM, yyyy). | | minDate | Date \| string \| null \| undefined | null | Batas tanggal minimal yang dapat dipilih dalam kalender. | | maxDate | Date \| string \| null \| undefined | null | Batas tanggal maksimal yang dapat dipilih dalam kalender. |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (value: DateRangeValue) | Dipancarkan saat tanggal kedua selesai dipilih ({ start, end }) atau saat pilihan dihapus ({ start: null, end: null }). |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseInputDateRangePicker, type DateRangeValue } from '@dtd-ui/vue'

const periodePendaftaran = ref<DateRangeValue>({
  start: '01/06/2026',
  end: '15/06/2026',
})
</script>

<template>
  <BaseInputDateRangePicker
    v-model="periodePendaftaran"
    label="Periode Pendaftaran"
    format="dd/MM/yyyy"
    required
  />
</template>

6. BaseSelect

Komponen dropdown pilihan tunggal (single select) dengan fitur pencarian opsi secara langsung (searchable), indikator status loading, dukungan opsi nonaktif (disabled option), menu dropdown yang di-<Teleport to="body">, serta metode validasi internal yang terekspos.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | string \| number \| null | null | Nilai terpilih yang terikat pada v-model. | | options | SelectOption<any>[] | [] | Daftar opsi pilihan yang berisi objek { label, value, disabled? }. | | label | string \| undefined | undefined | Teks label di atas komponen select. | | optional | boolean \| undefined | false | Menampilkan penanda teks "(Opsional)" di samping label. | | required | boolean \| undefined | false | Menandakan kolom wajib diisi (*) dan menampilkan pesan "<label> wajib diisi" di kanan atas saat validasi gagal. | | disabled | boolean \| undefined | false | Menonaktifkan interaksi dropdown. | | searchable | boolean \| undefined | false | Mengaktifkan kolom input pencarian di bagian atas menu dropdown. | | placeholder | string \| undefined | undefined | Teks placeholder pada trigger (default internal: 'Pilih...') dan pada kolom pencarian (default internal: 'Cari opsi...'). | | loading | boolean \| undefined | false | Menampilkan animasi spinner beserta teks 'Memuat...' dan menonaktifkan buka/tutup dropdown. |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (value: any) | Dipancarkan saat pengguna memilih salah satu opsi dari daftar. | | change | (value: any, option: SelectOption<any> \| undefined) | Dipancarkan bersamaan saat opsi dipilih, menyertakan nilai dan objek SelectOption lengkap. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods (defineExpose):
    • validate(): boolean: Memicu validasi wajib isi (required) secara manual dari komponen induk (via template ref). Mengembalikan true jika valid dan false jika kosong namun wajib diisi.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseSelect, type SelectOption } from '@dtd-ui/vue'

const lokasiUjian = ref<string | null>(null)
const selectRef = ref<InstanceType<typeof BaseSelect> | null>(null)

const daftarLokasi: SelectOption<string>[] = [
  { label: 'Kampus UI Depok', value: 'depok' },
  { label: 'Kampus UI Salemba', value: 'salemba' },
  { label: 'Gedung Laboratorium (Penuh)', value: 'lab', disabled: true },
]

function submitForm() {
  if (!selectRef.value?.validate()) return
  // Lanjutkan proses submit
}
</script>

<template>
  <div class="space-y-3">
    <BaseSelect
      ref="selectRef"
      v-model="lokasiUjian"
      :options="daftarLokasi"
      label="Lokasi Ujian"
      placeholder="Pilih lokasi kampus..."
      searchable
      required
    />
  </div>
</template>

7. BaseSelectMultiple

Komponen dropdown multi-pilihan (multi-select) yang menampilkan item terpilih sebagai chip ringkas di dalam trigger, dilengkapi badge penghitung kelebihan chip (+N dengan tooltip), fitur "Pilih Semua" (mendukung status indeterminate sesuai hasil filter pencarian), serta opsi menampilkan daftar lengkap item terpilih di bawah komponen.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | string[] | Wajib | Array berisi kumpulan nilai (value) opsi yang sedang terpilih (v-model). | | options | SelectOption<any>[] | Wajib | Daftar opsi pilihan yang tersedia. | | label | string \| undefined | undefined | Teks label di bagian atas komponen. | | optional | boolean \| undefined | undefined | Menampilkan penanda teks "(Opsional)" di samping label. | | required | boolean \| undefined | undefined | Menambahkan tanda bintang merah (*) dan mengaktifkan validasi wajib isi minimal 1 item. | | disabled | boolean \| undefined | undefined | Menonaktifkan interaksi komponen. | | searchable | boolean \| undefined | undefined | Menampilkan input pencarian di dalam menu dropdown. | | placeholder | string \| undefined | undefined | Teks saat belum ada opsi terpilih (default internal: 'Pilih...') dan placeholder input pencarian (default internal: 'Cari...'). | | maxVisibleChips | number \| undefined | 2 (computed) | Jumlah maksimum chip yang ditampilkan di dalam baris trigger sebelum diringkas menjadi badge +N. | | loading | boolean \| undefined | undefined | Menampilkan animasi spinner dan teks 'Memuat...' ketika opsi belum dipilih. | | showSelectedList | boolean \| undefined | undefined | Jika true, menampilkan daftar seluruh item terpilih dalam bentuk badge/chip di bawah trigger input. | | selectedListRemovable | boolean \| undefined | undefined | Jika true (bersama showSelectedList), menampilkan tombol hapus (x) pada setiap chip di daftar bawah. |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (value: string[]) | Dipancarkan setiap kali item ditambah, dihapus, atau saat tombol "Pilih Semua" diklik. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods (defineExpose):
    • validate(): boolean: Memvalidasi apakah setidaknya satu item telah dipilih ketika required bernilai true. Mengembalikan true jika valid dan false jika gagal.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseSelectMultiple, type SelectOption } from '@dtd-ui/vue'

const selectedRooms = ref<string[]>(['r101', 'r102'])

const roomOptions: SelectOption<string>[] = [
  { label: 'Ruang 101 - Gedung A', value: 'r101' },
  { label: 'Ruang 102 - Gedung A', value: 'r102' },
  { label: 'Ruang 201 - Gedung B', value: 'r201' },
  { label: 'Lab Komputer 1', value: 'lab1' },
]
</script>

<template>
  <BaseSelectMultiple
    v-model="selectedRooms"
    :options="roomOptions"
    label="Ruang Ujian"
    placeholder="Cari dan pilih ruangan..."
    searchable
    required
    :max-visible-chips="2"
    show-selected-list
    :selected-list-removable="true"
  />
</template>

8. BaseBreadcrumb

Komponen navigasi jejak halaman (breadcrumb) dengan pemisah ikon panah kanan (chevron) dan penanganan klik navigasi pada setiap item sebelum halaman aktif terakhir.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | items | BreadcrumbItem[] | Wajib | Daftar item breadcrumb berurutan dari root hingga halaman aktif saat ini. Item terakhir dirender sebagai halaman aktif (teks tebal berwarna --btn-primary dan tidak memancarkan event klik). |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | navigate | (item: BreadcrumbItem) | Dipancarkan saat pengguna mengklik salah satu item breadcrumb selain item terakhir. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { BaseBreadcrumb, type BreadcrumbItem } from '@dtd-ui/vue'

const crumbs: BreadcrumbItem[] = [
  { label: 'Beranda', route: '/' },
  { label: 'Manajemen Pengawas', route: '/pengawas' },
  { label: 'Detail Penugasan' },
]

function onNavigate(item: BreadcrumbItem) {
  if (item.route) {
    console.log('Navigasi menuju:', item.route)
  }
}
</script>

<template>
  <BaseBreadcrumb :items="crumbs" @navigate="onNavigate" />
</template>

9. BaseDataTable

Komponen tabel data generik (generic="T extends Record<string, any>") yang kaya fitur: mendukung pencarian instan multi-kolom, paginasi dengan pemilih ukuran halaman (10, 25, 50, 100), penomoran baris otomatis, seleksi baris dengan checkbox (multi-row selection), kolom aksi bawaan (view, edit, delete) lengkap dengan modal dialog konfirmasi terintegrasi, skeleton loading, serta tata letak responsif yang otomatis berubah menjadi daftar kartu (card list) pada layar mobile.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | columns | DataTableColumn<T>[] | Wajib | Definisi kolom tabel (key, label, field dot-path, formatter, perataan, lebar, dll.). | | data | T[] | Wajib | Array objek data baris yang akan ditampilkan. | | loading | boolean | false | Menampilkan 5 baris skeleton loader saat data sedang dimuat. | | emptyText | string | 'Tidak ada data untuk ditampilkan' | Teks yang ditampilkan ketika array data kosong. | | rowKey | keyof T \| ((row: T) => string \| number) | undefined | Properti kunci unik atau fungsi pengambil ID unik untuk setiap baris (penting untuk performa v-for dan fitur selectable). | | paginated | boolean | false | Mengaktifkan fitur paginasi dan pemilih jumlah baris per halaman di bagian footer. | | pageSize | number | 10 | Jumlah baris awal per halaman saat paginated bernilai true. | | showRowNumber | boolean | false | Menampilkan kolom nomor urut (#) otomatis yang menyesuaikan dengan halaman aktif. | | clickableRows | boolean | false | Mengubah kursor baris menjadi pointer dan memancarkan event @row-click saat baris diklik. | | striped | boolean | true | Memberikan warna latar selang-seling pada baris genap dan ganjil. | | searchable | boolean | false | Menampilkan kotak input pencarian di bagian toolbar atas tabel. | | searchPlaceholder | string | 'Cari...' | Teks placeholder pada kotak pencarian tabel. | | searchFields | string[] \| undefined | undefined | Daftar path field yang dicari (mendukung notasi titik seperti 'unit.nama'). Jika tidak diisi, otomatis mencari pada seluruh field yang didefinisikan di columns. | | headerBgColor | string | 'var(--bg-secondary, #f9fafb)' | Warna latar belakang header tabel (<thead>). | | headerTextColor | string | 'var(--text-secondary)' | Warna teks pada header tabel. | | footerBgColor | string | 'var(--bg-secondary, #f9fafb)' | Warna latar belakang footer tabel. | | footerTextColor | string | 'var(--text-secondary)' | Warna teks pada footer tabel. | | stripeColorEven | string | '#f8fafc' | Warna latar belakang baris berindeks genap (0, 2, 4...) ketika striped aktif. | | stripeColorOdd | string | '#eef1f5' | Warna latar belakang baris berindeks ganjil (1, 3, 5...) ketika striped aktif. | | actions | DataTableActions<T> | undefined | undefined | Konfigurasi tombol aksi bawaan (view, edit, delete) beserta dialog konfirmasinya. | | actionsLabel | string | 'Aksi' | Label header untuk kolom aksi. | | actionsWidth | string \| undefined | undefined | Lebar spesifik untuk kolom aksi (misal '120px'). | | entityLabel | string | 'data tersimpan' | Label nama entitas yang ditampilkan pada teks ringkasan jumlah data di footer (contoh: 'peserta', 'panitia'). | | selectable | boolean | false | Mengaktifkan kolom checkbox seleksi baris beserta indikator jumlah terpilih dan tombol pilih/hapus semua di toolbar. | | selectedRows | T[] | [] | Daftar baris yang sedang terpilih (gunakan bersama v-model:selected-rows). | | selectAllLabel | string | 'Pilih Semua' | Label tombol untuk memilih seluruh baris yang cocok dengan filter pencarian saat ini. | | deselectAllLabel | string | 'Hapus Semua' | Label tombol untuk membatalkan seluruh pilihan baris. | | rowSelectable | ((row: T) => boolean) \| undefined | undefined | Fungsi predikat untuk menentukan apakah suatu baris diizinkan untuk diseleksi (dicentang). |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | row-click | (row: T) | Dipancarkan saat suatu baris diklik (hanya aktif apabila clickableRows bernilai true). | | view | (row: T) | Dipancarkan saat aksi view diklik (atau setelah dikonfirmasi jika confirm !== false). | | edit | (row: T) | Dipancarkan saat aksi edit diklik (atau setelah dikonfirmasi jika confirm !== false). | | delete | (row: T) | Dipancarkan saat aksi delete diklik (atau setelah dikonfirmasi jika confirm !== false). | | update:selectedRows | (rows: T[]) | Dipancarkan saat daftar baris yang dicentang berubah (mendukung v-model:selected-rows). |

Slots & Metode Terekspos

  • Slots:
    • #toolbar-actions: Slot di sisi kanan atas toolbar (sejajar dengan kolom pencarian) untuk menempatkan tombol aksi tambahan seperti tombol "Tambah Data" atau "Ekspor".
    • #cell-<key>="{ row, value, isMobileCard }": Slot kustomisasi tampilan sel untuk kolom dengan key tertentu. Menerima slot props:
      • row: T — Objek data baris penuh.
      • value: string — Nilai teks hasil pemformatan bawaan atau formatter.
      • isMobileCard: boolean — Bernilai true jika sel sedang dirender di dalam tampilan kartu mobile (< 640px), atau false jika di dalam tabel desktop.
    • #footer-left="{ rangeText, total, currentPage, totalPages, pageSize }": Slot untuk mengganti teks informasi rentang halaman pada footer tampilan mobile.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import {
  BaseDataTable,
  BaseButton,
  type DataTableColumn,
  type DataTableActions,
} from '@dtd-ui/vue'

interface Panitia {
  id: number
  nama: string
  nip: string
  unit: { nama: string }
  aktif: boolean
}

const daftarPanitia = ref<Panitia[]>([
  { id: 1, nama: 'Budi Santoso', nip: '198801012015041001', unit: { nama: 'Fasilkom' }, aktif: true },
  { id: 2, nama: 'Siti Rahma', nip: '199203122019032005', unit: { nama: 'FT' }, aktif: false },
])

const barisTerpilih = ref<Panitia[]>([])

const columns: DataTableColumn<Panitia>[] = [
  { key: 'nama', label: 'Nama Panitia', field: 'nama' },
  { key: 'nip', label: 'NIP', field: 'nip', hideOnMobile: true },
  { key: 'unit', label: 'Unit Kerja', field: 'unit.nama', align: 'center' },
  { key: 'status', label: 'Status', align: 'center' },
]

const actions: DataTableActions<Panitia> = {
  view: { confirm: false, label: 'Lihat Detail' },
  edit: { confirm: false },
  delete: {
    confirmTitle: 'Hapus Panitia?',
    confirmMessage: (row) => `Apakah Anda yakin ingin menghapus "${row.nama}"?`,
    confirmLabel: 'Ya, Hapus',
  },
}
</script>

<template>
  <BaseDataTable
    v-model:selected-rows="barisTerpilih"
    :columns="columns"
    :data="daftarPanitia"
    row-key="id"
    searchable
    search-placeholder="Cari nama atau NIP..."
    :search-fields="['nama', 'nip', 'unit.nama']"
    paginated
    :page-size="10"
    show-row-number
    selectable
    :row-selectable="(row) => row.aktif"
    :actions="actions"
    entity-label="panitia terdaftar"
    @view="(row) => console.log('Lihat:', row)"
    @edit="(row) => console.log('Edit:', row)"
    @delete="(row) => console.log('Hapus:', row)"
  >
    <template #toolbar-actions>
      <BaseButton variant="primary" icon="lucide:plus" size="sm">
        Tambah Panitia
      </BaseButton>
    </template>

    <template #cell-status="{ row }">
      <span
        class="px-2 py-0.5 rounded-full text-xs font-medium"
        :class="row.aktif ? 'bg-green-100 text-green-700' : 'bg-slate-200 text-slate-600'"
      >
        {{ row.aktif ? 'Aktif' : 'Nonaktif' }}
      </span>
    </template>
  </BaseDataTable>
</template>

Kategori 2: Komponen Popup & Feedback (popup/)

10. BaseDialog

Komponen modal dialog serbaguna untuk menampilkan informasi (info), keberhasilan (success), peringatan (warning), atau kesalahan (error). Mendukung dua mode tata letak: center (ikon besar di tengah untuk notifikasi/alert) dan left (header rata kiri dengan subjudul, tombol tutup X, dan slot isi kustom).

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | boolean | Wajib | Status keterbukaan dialog (v-model). | | type | DialogType ('error' \| 'success' \| 'warning' \| 'info') | undefined | 'error' (internal switch) | Menentukan skema warna aksen, ikon bawaan, dan varian tombol konfirmasi. | | title | string \| undefined | undefined | Judul utama modal dialog. | | message | string \| undefined | undefined | Pesan teks di dalam dialog (mendukung karakter baris baru \n melalui white-space: pre-line). | | confirmLabel | string \| undefined | 'OK' (template fallback) | Teks label pada tombol konfirmasi/utama. | | cancelLabel | string \| undefined | 'Batal' (template fallback) | Teks label pada tombol batal. | | hideCancelButton | boolean \| undefined | undefined | Jika true, menyembunyikan tombol batal sehingga hanya menampilkan tombol konfirmasi tunggal. | | layout | 'center' \| 'left' \| undefined | 'center' (template fallback) | Tata letak kartu dialog: 'center' untuk tampilan terpusat klasik, atau 'left' untuk header rata kiri beserta tombol tutup X. | | subtitle | string \| undefined | undefined | Teks subjudul kecil di bawah title (khusus digunakan saat layout="left"). | | icon | string \| undefined | undefined | Nama ikon Iconify kustom untuk menggantikan ikon bawaan dari type (contoh: 'lucide:calendar-clock'). |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (val: boolean) | Dipancarkan dengan nilai false saat tombol batal, tombol X, atau area luar overlay diklik. | | confirm | () | Dipancarkan saat tombol konfirmasi (confirmLabel) diklik. | | cancel | () | Dipancarkan bersamaan dengan penutupan dialog saat tombol batal, tombol X, atau overlay diklik. |

Slots & Metode Terekspos

  • Slots:
    • default: Konten kustom di bagian badan (body) dialog. Pada layout="left", apabila slot default diisi maka prop message akan digantikan oleh isi slot. Pada layout="center", slot default memiliki fallback ke <p class="dialog-message">{{ message }}</p>.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseDialog, BaseButton } from '@dtd-ui/vue'

const showSuccess = ref(false)
const showDetail = ref(false)
</script>

<template>
  <div class="flex gap-3">
    <BaseButton variant="success" @click="showSuccess = true">Dialog Sukses</BaseButton>
    <BaseButton variant="info" @click="showDetail = true">Dialog Detail (Left)</BaseButton>

    <!-- Layout Center (Default) -->
    <BaseDialog
      v-model="showSuccess"
      type="success"
      title="Data Berhasil Dikirim"
      message="Seluruh berkas pendaftaran telah diterima oleh sistem."
      hide-cancel-button
      confirm-label="Mengerti"
      @confirm="showSuccess = false"
    />

    <!-- Layout Left dengan Slot Kustom -->
    <BaseDialog
      v-model="showDetail"
      type="info"
      layout="left"
      icon="lucide:calendar-clock"
      title="Jadwal Sesi Ujian"
      subtitle="Gedung Rumpun Ilmu Kesehatan"
      confirm-label="Tutup"
      hide-cancel-button
      @confirm="showDetail = false"
    >
      <div class="text-sm text-slate-600 space-y-1">
        <p><strong>Sesi:</strong> Sesi 1 (Pagi)</p>
        <p><strong>Waktu:</strong> 08.00 - 10.30 WIB</p>
      </div>
    </BaseDialog>
  </div>
</template>

11. BaseConfirmDialog

Komponen modal dialog khusus untuk meminta konfirmasi pengguna sebelum menjalankan tindakan krusial (seperti menghapus data atau mengirim formulir). Dirancang untuk proses asinkron: tombol konfirmasi tidak langsung menutup dialog secara otomatis, melainkan membiarkan komponen induk mengontrol status :loading="true" hingga proses selesai.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | boolean | Wajib | Status keterbukaan dialog (v-model). | | type | ConfirmType ('warning' \| 'info' \| 'danger') | undefined | 'warning' (internal switch) | Menentukan warna ikon dan varian tombol aksi konfirmasi (warning, info, atau danger). | | title | string \| undefined | undefined | Judul pertanyaan konfirmasi. | | message | string \| undefined | undefined | Penjelasan dampak dari tindakan yang akan dikonfirmasi. | | confirmLabel | string \| undefined | 'Ya, Lanjutkan' (template fallback) | Teks pada tombol konfirmasi. | | cancelLabel | string \| undefined | 'Batal' (template fallback) | Teks pada tombol pembatalan. | | loading | boolean \| undefined | undefined | Jika true, menampilkan spinner pada tombol konfirmasi, menonaktifkan tombol batal, dan mencegah penutupan dialog. | | disableOutsideClick | boolean \| undefined | undefined | Jika true, klik pada area gelap di luar kartu dialog tidak akan menutup dialog. |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (val: boolean) | Dipancarkan dengan nilai false saat pengguna membatalkan dialog (selama loading tidak aktif). | | confirm | () | Dipancarkan saat tombol konfirmasi diklik. | | cancel | () | Dipancarkan saat tombol batal atau overlay luar diklik. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseConfirmDialog, BaseButton } from '@dtd-ui/vue'

const showDeleteDialog = ref(false)
const isDeleting = ref(false)

async function handleDelete() {
  isDeleting.value = true
  await new Promise((resolve) => setTimeout(resolve, 1500))
  isDeleting.value = false
  showDeleteDialog.value = false
}
</script>

<template>
  <BaseButton variant="danger" icon="lucide:trash-2" @click="showDeleteDialog = true">
    Hapus Data
  </BaseButton>

  <BaseConfirmDialog
    v-model="showDeleteDialog"
    type="danger"
    title="Hapus Data Peserta?"
    message="Data yang sudah dihapus tidak dapat dikembalikan lagi."
    confirm-label="Ya, Hapus Sekarang"
    cancel-label="Batal"
    :loading="isDeleting"
    :disable-outside-click="isDeleting"
    @confirm="handleDelete"
  />
</template>

12. BaseLoadingDialog

Komponen modal dialog pemrosesan (blocking overlay) dengan animasi circular spinner, ikon opsional di tengah spinner, indeterminate progress bar, serta tombol pembatalan opsional untuk proses yang dapat dihentikan pengguna.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | boolean | Wajib | Status tampilnya dialog pemrosesan (v-model). | | title | string \| undefined | 'Memproses...' (template fallback) | Judul status pemrosesan yang sedang berlangsung. | | message | string \| undefined | undefined | Pesan deskripsi tambahan di bawah judul. | | variant | SpinnerVariant ('primary' \| 'success' \| 'warning' \| 'error') | 'primary' | Skema warna untuk animasi spinner, ikon tengah, dan progress bar. | | icon | string \| undefined | undefined | Nama ikon Iconify yang dirender tepat di tengah cincin spinner. | | cancellable | boolean \| undefined | undefined | Jika true, menampilkan tombol batal di bagian bawah dialog. | | cancelLabel | string \| undefined | 'Batal' (template fallback) | Teks label pada tombol batal (saat cancellable bernilai true). |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (val: boolean) | Dipancarkan dengan nilai false saat tombol batal diklik. | | cancel | () | Dipancarkan saat pengguna menekan tombol batal. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseLoadingDialog, BaseButton } from '@dtd-ui/vue'

const isUploading = ref(false)
</script>

<template>
  <BaseButton variant="primary" @click="isUploading = true">
    Unggah Dokumen
  </BaseButton>

  <BaseLoadingDialog
    v-model="isUploading"
    variant="primary"
    icon="lucide:upload-cloud"
    title="Mengunggah Berkas..."
    message="Mohon jangan tutup halaman ini selama proses unggah berlangsung."
    cancellable
    cancel-label="Batalkan Unggahan"
    @cancel="isUploading = false"
  />
</template>

13. BaseToast

Komponen notifikasi melayang (toast notification) yang muncul di sudut kanan atas layar (top: 24px; right: 24px) dengan efek glassmorphism, bilah progres hitung mundur (countdown shimmer bar), dan penutupan otomatis sesuai durasi yang ditentukan.

Props

| Prop | Tipe | Default | Keterangan | | :--- | :--- | :--- | :--- | | modelValue | boolean | Wajib | Status keterbukaan toast (v-model). Otomatis berubah menjadi false setelah duration berakhir. | | type | ToastType ('success' \| 'error' \| 'warning' \| 'info') | 'success' | Menentukan warna latar, border, ikon status, dan bilah progres. | | title | string | Wajib | Judul utama notifikasi toast. | | message | string \| undefined | undefined | Teks pesan penjelasan di bawah judul. | | duration | number | 3000 | Durasi tampil dalam satuan milidetik (ms) sebelum toast menutup secara otomatis. |

Events / Emits

| Event | Payload | Keterangan | | :--- | :--- | :--- | | update:modelValue | (value: boolean) | Dipancarkan dengan nilai false ketika waktu duration habis atau saat tombol tutup diklik. |

Slots & Metode Terekspos

  • Slots: Tidak ada.
  • Exposed Methods: Tidak ada.

Contoh Penggunaan

<script setup lang="ts">
import { ref } from 'vue'
import { BaseToast, BaseButton } from '@dtd-ui/vue'

const showToast = ref(false)
</script>

<template>
  <BaseButton variant="success" @click="showToast = true">
    Tampilkan Notifikasi
  </BaseButton>

  <BaseToast
    v-model="showToast"
    type="success"
    title="Sinkronisasi Berhasil"
    message="Sebanyak 250 data peserta telah berhasil disinkronkan."
    :duration="4000"
  />
</template>

Referensi Tipe & Antarmuka TypeScript

Seluruh tipe dan antarmuka (interfaces) berikut diekspor langsung dari entry utama @dtd-ui/vue:

import type {
  // UI & Form
  DateRangeValue,
  SelectOption,
  JalurOption,
  BreadcrumbItem,
  DataTableColumn,
  DataTableActions,
  DataTableActionConfig,
  DataTableActionType,
  // Popup & Feedback
  DialogType,
  ConfirmVariant,
  ConfirmType,
  SpinnerVariant,
  ToastType,
} from '@dtd-ui/vue'

DateRangeValue

Digunakan pada BaseInputDateRangePicker untuk merepresentasikan rentang tanggal awal dan akhir:

export interface DateRangeValue {
  start: string | null
  end: string | null
}

SelectOption & JalurOption

Digunakan pada BaseSelect dan BaseSelectMultiple:

export interface SelectOption<T = string | number> {
  label: string
  value: T
  disabled?: boolean
  [key: string]: any
}

export type JalurOption = SelectOption<string>

BreadcrumbItem

Digunakan pada BaseBreadcrumb:

export interface BreadcrumbItem {
  /** Label teks untuk rekam jejak halaman */
  label: string
  /** Rute atau URL tujuan (opsional) */
  route?: string
  /** Data kustom tambahan */
  [key: string]: any
}

DataTableColumn

Digunakan untuk mendefinisikan struktur kolom pada BaseDataTable:

export interface DataTableColumn<T = Record<string, any>> {
  /** Unique key kolom, dipakai untuk slot #cell-<key> dan :key di v-for */
  key: string
  /** Label header */
  label: string
  /** Dot-path field dari row, mis. "jabatan.mjp_nm_jabatan". Opsional jika pakai formatter/slot saja. */
  field?: string
  /** Formatter custom, dipanggil dengan row penuh */
  formatter?: (row: T) => string
  /** Lebar kolom (opsional), mis. "120px" atau "20%" */
  width?: string
  /** Perataan konten */
  align?: 'left' | 'center' | 'right'
  /** Sembunyikan kolom di breakpoint mobile (<640px) */
  hideOnMobile?: boolean
}

DataTableActions, DataTableActionConfig & DataTableActionType

Digunakan untuk mengonfigurasi aksi baris (view, edit, delete) pada BaseDataTable:

export type DataTableActionType = 'view' | 'edit' | 'delete'

export interface DataTableActionConfig<T = Record<string, any>> {
  /** Tampilkan tombol aksi ini. Default: true selama key-nya didefinisikan di prop `actions`. */
  show?: boolean
  /** Label aksesibilitas (aria-label/title) untuk tombolnya */
  label?: string
  /** Tampilkan dialog konfirmasi sebelum event di-emit ke parent. Default: true */
  confirm?: boolean
  /** Judul dialog konfirmasi */
  confirmTitle?: string
  /** Pesan dialog konfirmasi (string statis atau fungsi penerima row) */
  confirmMessage?: string | ((row: T) => string)
  /** Teks tombol konfirmasi */
  confirmLabel?: string
  /** Teks tombol batal, default "Batal" */
  cancelLabel?: string
}

export interface DataTableActions<T = Record<string, any>> {
  view?: boolean | DataTableActionConfig<T>
  edit?: boolean | DataTableActionConfig<T>
  delete?: boolean | DataTableActionConfig<T>
}

DialogType & ConfirmVariant

Digunakan pada BaseDialog:

export type DialogType = 'error' | 'success' | 'warning' | 'info'
export type ConfirmVariant = 'primary' | 'danger' | 'success' | 'warning'

ConfirmType

Digunakan pada BaseConfirmDialog:

export type ConfirmType = 'warning' | 'info' | 'danger'

SpinnerVariant

Digunakan pada BaseLoadingDialog:

export type SpinnerVariant = 'primary' | 'success' | 'warning' | 'error'

ToastType

Digunakan pada BaseToast:

export type ToastType = 'success' | 'error' | 'warning' | 'info'

Kustomisasi Tema & Variabel CSS

@dtd-ui/vue mendefinisikan token desain pada selektor :root (di dalam src/style.css). Anda dapat menimpa (override) variabel CSS berikut pada stylesheet aplikasi utama Anda untuk menyesuaikan tema atau mode gelap:

| Kategori | Variabel CSS | Nilai Default | Keterangan | | :--- | :--- | :--- | :--- | | Layout | --sidebar-bg | #fefefe | Warna latar belakang sidebar | | | --header-bg | #ffffff | Warna latar belakang header & trigger select | | | --header-text | #000000 | Warna teks header | | | --content-bg | #ffffff | Warna latar belakang area konten | | | --bg-primary | #ffffff | Warna latar belakang utama | | | --bg-main | #f8fafc | Warna latar belakang halaman utama | | | --bg-logo | #f6db00 | Warna kuning identitas Makara / DTD | | | --bg-logo-black | #221614 | Warna hitam identitas logo | | Text | --text-primary | #334155 | Warna teks utama | | | --text-secondary | #000000 | Warna teks sekunder / label | | | --text-light | #ffffff | Warna teks terang di atas latar gelap | | Status | --success | #22c55e | Warna indikator status berhasil (hijau) | | | --warning | #f59e0b | Warna indikator status peringatan (kuning/oranye) | | | --danger | #ef4444 | Warna indikator status bahaya/error (merah) | | | --info | #3b82f6 | Warna indikator status informasi (biru) | | Table | --table-header-bg | #1b2431 | Warna latar header tabel tema gelap | | | --table-row-odd | #ffffff | Warna latar baris ganjil tabel | | | --table-row-even | #f8fafc | Warna latar baris genap tabel | | | --table-footer-bg | #1b2431 | Warna latar footer tabel | | | --pagination-bg | #1b2431 | Warna latar komponen paginasi | | | --pagination-text | #ffffff | Warna teks komponen paginasi | | Button | --btn-primary | #2563eb | Warna latar tombol primary | | | --btn-primary-hover | #1d4ed8 | Warna latar hover tombol primary | | | --btn-primary-text | #ffffff | Warna teks tombol primary | | | --btn-sync | #16a34a | Warna latar tombol success / sinkronisasi | | | --btn-sync-hover | #15803d | Warna latar hover tombol success | | | --btn-sync-text | #ffffff | Warna teks tombol success | | | --btn-active | #f6db00 | Warna latar tombol secondary (Kuning DTD) & aksen aktif | | | --btn-hover | #e6cd00 | Warna latar hover tombol secondary | | | --btn-active-text | #1b2431 | Warna teks tombol secondary | | | --btn-danger | #ef4444 | Warna utama tombol danger | | | --btn-danger-hover | #dc2626 | Warna hover tombol danger | | | --btn-danger-text | #ffffff | Warna teks tombol danger | | | --btn-disabled | #e2e8f0 | Warna latar tombol saat disabled / loading | | | --btn-disabled-text | #94a3b8 | Warna teks tombol saat disabled / loading | | | --btn-border | transparent | Warna border tombol standar | | | --btn-border-hover | transparent | Warna border tombol saat hover | | | --btn-focus-shadow | 0 0 0 3px rgba(246, 219, 0, 0.15) | Efek bayangan cincin fokus tombol | | | --btn-radius | 8px | Radius sudut tombol | | Select / Dropdown | --dropdown-hover-bg | rgba(246, 219, 0, 0.08) | Warna latar item/trigger select saat hover | | | --dropdown-active-bg | rgba(246, 219, 0, 0.12) | Warna latar item/chip select yang terpilih | | | --dropdown-hover-border | rgba(246, 219, 0, 0.4) | Warna border trigger select saat hover | | | --dropdown-active-border | var(--btn-active) | Warna border trigger & menu select saat terbuka | | | --dropdown-hover-shadow | 0 4px 12px rgba(246, 219, 0, 0.12) | Bayangan trigger select saat hover | | | --dropdown-active-shadow | 0 0 0 3px rgba(246, 219, 0, 0.15) | Bayangan trigger select saat aktif | | Input & Border | --border-color | #e2e8f0 | Warna border umum | | | --border-primary | #e5e7eb | Warna border utama kontrol input & tabel | | | --border-secondary | #f6db00 | Warna border aksen sekunder | | | --input-bg | #ffffff | Warna latar belakang kolom input | | | --input-bg-disabled | #f1f5f9 | Warna latar belakang input saat disabled | | | --input-text | var(--text-primary) | Warna teks di dalam input | | | --input-placeholder | #94a3b8 | Warna teks placeholder & ikon input | | | --input-border | var(--border-primary) | Warna border normal kolom input | | | --input-border-width | 1px | Ketebalan garis border input | | | --input-border-hover | #cbd5e1 | Warna border input saat kursor di atasnya | | | --input-border-focus | var(--btn-active) | Warna border input saat fokus / tanggal terpilih | | | --input-focus-shadow | 0 0 0 3px rgba(246, 219, 0, 0.15) | Bayangan cincin fokus pada kolom input | | | --input-radius | 8px | Radius sudut kolom input | | Radius & Lainnya | --loading-bg | #ffffff | Warna latar belakang komponen loading | | | --radius-control | 8px | Radius sudut standar kontrol formulir (input, select, button) | | | --radius-card | 14px | Radius sudut kartu dan panel | | | --radius-dialog | 14px | Radius sudut modal dan dialog |


Pengembangan & Build

Untuk menjalankan pengembangan lokal atau mem-build paket @dtd-ui/vue dari kode sumber:

# 1. Instal seluruh dependensi
npm install

# 2. Jalankan server pengembangan (Vite playground)
npm run dev

# 3. Kompilasi deklarasi tipe TypeScript (vue-tsc) dan bundle produksi (Vite)
npm run build

# 4. Pratinjau hasil build
npm run preview

Hasil build akan disimpan di dalam direktori dist/:

  • dist/dtd-ui-vue.es.js — Bundle ES Module
  • dist/dtd-ui-vue.umd.js — Bundle UMD
  • dist/index.d.ts — Deklarasi tipe TypeScript lengkap

Lisensi

Dirilis di bawah lisensi MIT. Hak Cipta © 2026 DTD Design System Team.