vue-salayout
Kumpulan komponen layout Vue 3 — kartu dasar hingga region yang bisa dibuka/tutup — dengan styling self-contained.
Versi: 0.1.0-beta.2 Kategori: UI Component (Vue 3)
TL;DR
vue-salayout menyediakan komponen layout berbasis region (header, footer, tag, leftSide, rightSide, body/children) dengan accent color, padding, dan corner-radius yang saling konsisten secara otomatis. Selain component siap-pakai, composable headless (useDisclosure) juga diekspor untuk yang butuh markup custom penuh. Semua styling sudah ter-compile dan self-inject — tidak butuh konfigurasi Tailwind apa pun di sisi consumer.
Components:
import {
BasicCard, Disclosure, SimpleDisclosure, Accordion,
NotificationCard, LoadingCard, ProgressBar,
} from '@bpmlib/vue-salayout';Composables:
import { useDisclosure } from '@bpmlib/vue-salayout';Lihat daftar lengkap tiap component di Component Catalog.
Installation & Setup
Requirements
| Dependency | Versi | Status | Deskripsi |
|---|---|---|---|
vue | ^3.3.0 | Required | Vue 3 framework |
Tailwind CSS tidak perlu di-install di project consumer — semua utility class sudah di-compile menjadi CSS asli saat build library ini sendiri. Lihat Styling di tiap halaman component untuk detail.
Package Installation
npm install @bpmlib/vue-salayoutyarn add @bpmlib/vue-salayoutpnpm add @bpmlib/vue-salayoutbun install @bpmlib/vue-salayoutImport
Basic Import:
import { BasicCard, Disclosure, Accordion } from '@bpmlib/vue-salayout';CSS Import:
// main.ts
import '@bpmlib/vue-salayout/style.css';Tidak ada langkah app.use(...) — semua component dipakai langsung sebagai SFC import biasa, tanpa registrasi global.
Quick Start
Contoh paling sederhana — satu BasicCard dengan header dan body:
<script setup lang="ts">
import { BasicCard } from '@bpmlib/vue-salayout';
</script>
<template>
<BasicCard>
<template #header>Judul Kartu</template>
Isi kartu di sini.
</BasicCard>
</template>Untuk contoh penggunaan lengkap tiap component (props, slot, region), buka halaman masing-masing di Component Catalog.
Core Concepts
Headless Core + Stylized Wrapper
Logika region/state yang dipakai bersama (warna, padding, corner-radius, open/close) ditulis sebagai composable headless internal (useCardFoundation, useDisclosure) yang tidak diekspor publik — masing-masing hanya mengembalikan keputusan (class, boolean, state), tanpa render apa pun. Tiap component stylized (BasicCard, Disclosure) memanggil composable ini lalu menulis template dan DOM-nya sendiri. Konsekuensinya: struktur <div> sedikit terduplikasi antar component, tapi tiap component bebas punya markup/atribut yang genuinely berbeda (mis. header Disclosure jadi <button> dengan aria-expanded).
Region Anatomy: Content vs Chrome
Tiap kartu punya dua jenis region:
- Content (
body/children) — region eksplorasi bebas, tanpa layout baku, untuk konten apa pun. - Chrome (
header/footer/leftSide/rightSide/tag) — region label/aksi pendek, otomatis dapatflex items-center gap-2.
Padding tiap region mengikuti grid alignment: header/footer berbagi batas kiri/kanan body (padding horizontal sama), leftSide/rightSide berbagi batas atas/bawah body (padding vertikal sama).
Accent Palette & alt Shading
Semua warna diambil dari satu set token CSS custom property (tokens.css), masing-masing family (primary, secondary, ternary, success, danger, card) punya 3 shade: base, alt (differentiator stacking dalam family yang sama, bukan warna brand kedua), dan foreground. Semua otomatis swap ke nilai dark mode di bawah class .dark, jadi tidak perlu varian dark: manual.
type CardAccent =
| 'primary' | 'primary-alt'
| 'secondary' | 'secondary-alt'
| 'ternary' | 'ternary-alt'
| 'success' | 'success-alt'
| 'danger' | 'danger-alt'
| 'card' | 'card-alt';Region body/children adalah pasangan yang saling beralternasi: kalau tidak ada yang diset eksplisit lewat alt, body selalu base dan children selalu alt (supaya children yang bertumpuk tidak menyatu visual dengan body). Kalau salah satu diset eksplisit, sisi lainnya otomatis membalik ke kebalikannya. Kalau keduanya diset eksplisit, keduanya dihormati apa adanya.
children juga bisa diberi warna family yang independen dari body lewat childrenColor/color.children — kalau tidak diset, children tetap default ke family body (cuma shade -alt-nya yang beda, seperti di atas).
Resolusi Warna: color, bodyColor, dan Prop Standalone
Tiap region punya prop warna standalone-nya sendiri (bodyColor, headerColor, childrenColor, dst.) plus satu prop gabungan color yang bisa berupa string (hanya menyasar body) atau object per-region. Urutan resolusi selalu sama untuk semua region di semua component: prop standalone eksplisit → key yang cocok di color → default hardcoded region tersebut.
type CardColor = CardAccent | Partial<Record<CardColorSlotKey, CardAccent>>;CardColorSlotKey mencakup semua region yang bisa diwarnai, termasuk body dan children — tidak ada region yang dikecualikan dari object form.
Toggle Props: alt & noPadding
alt dan noPadding sama-sama menerima bentuk polymorphic yang sama:
type CardToggle = boolean | CardSlotKey[] | Partial<Record<CardSlotKey, boolean>>;boolean— hanya menyasarbody- Array region (
['header', 'footer']) — region yang disebut jaditrue, sisanya default - Object per-region (
{ header: true, footer: false }) — gate eksplisit per region
Bedanya: alt melakukan auto-link body/children (lihat Accent Palette & alt Shading), noPadding tidak — tiap region mengikuti persis apa yang diminta, tanpa efek samping ke region lain.
Expandable Family: Disclosure, SimpleDisclosure & Accordion
Disclosure adalah BasicCard yang region children-nya bisa dibuka/tutup lewat baris trigger terpisah (caret + label) di dalam region tersebut. SimpleDisclosure menyederhanakan pola ini — seluruh body itu sendiri jadi trigger-nya (klik di mana saja pada kartu), tanpa baris trigger terpisah, cocok dipakai saat konten body sudah cukup jelas sebagai area klik. Keduanya bisa dipakai berdiri sendiri (uncontrolled, defaultOpen/v-model) atau dikoordinasi oleh Accordion sebagai parent lewat provide/inject — saat nested di dalam Accordion, state open/close-nya otomatis didelegasikan ke context milik Accordion (single-open secara default, atau multiple untuk multi-open), dan keduanya bisa dicampur bebas di dalam satu Accordion yang sama. Detail per component ada di halaman masing-masing.
Headless API: useDisclosure
Logika buka/tutup yang dipakai Disclosure dan SimpleDisclosure juga diekspor langsung sebagai composable (useDisclosure) untuk yang butuh membangun UI disclosure custom sepenuhnya, tanpa markup/CSS bawaan library ini sama sekali. Lihat halaman useDisclosure untuk API lengkap.
Component Catalog
Layout
| Component | Type | Description |
|---|---|---|
| BasicCard | Stylized | Kartu dasar dengan region header/footer/tag/leftSide/rightSide/body/children |
Expandable
| Component | Type | Description |
|---|---|---|
| Disclosure | Stylized | Kartu dengan baris trigger terpisah, region children bisa dibuka/tutup |
| SimpleDisclosure | Stylized | Kartu tanpa baris trigger terpisah — seluruh body jadi trigger |
| Accordion | Provider/Context | Mengoordinasikan open/close beberapa Disclosure/SimpleDisclosure sekaligus |
Feedback
| Component | Type | Description |
|---|---|---|
| NotificationCard | Stylized | Kartu notifikasi status dengan icon badge dan title pill |
| LoadingCard | Stylized | Indikator loading dengan icon + judul + progress bar opsional |
| ProgressBar | Stylized | Progress bar liquid-tube berdiri sendiri, juga dipakai internal oleh LoadingCard |
Headless
| Export | Type | Description |
|---|---|---|
| useDisclosure | Composable | State buka/tutup + ARIA props, tanpa markup/CSS bawaan |