@dtd-ui/vue

DTD Design System UI Component Library for Vue 3 and Tailwind CSS
Install
npm install @dtd-ui/vue
Latest Version:0.1.5
Vue:3
License:MIT
Last Updated:Oct 19, 2026
Links: npm
Maintainer: dtd.ui

@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="nama@ui.ac.id"
      :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

}

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 */

}

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.

Related Packages

@waler/ui

Design system Vue 3 da WALER, sobre Reka UI e Tailwind CSS v4

2,928
@infineon/infineon-design-system-vue

Vue wrapper for Infineon Design System Web Components

228,032 37
@celestia-island/hikari

Hikari UI library, Vue 3 runtime — one design system for Vue 3 and Rust/WASM app...

49,986 25
@hidearea-design/vue

Vue 3 wrapper for hidearea-design components

645
@sabrenski/spire-ui-vue

A modern, themeable Vue 3 component library with 57+ components, TypeScript supp...

42,505

Version History

Version Released Vue License
0.1.5 ^3.0.0 MIT
0.1.4 ^3.0.0 MIT
0.1.3 ^3.0.0
0.1.2 ^3.0.0
0.1.1 ^3.0.0
Pre-releases (1)
Version Released License
0.0.0-stage