Skip to content

vue-sabutton

Koleksi button components Vue 3 — button biasa, link (anchor/Inertia), dan split/dropdown button — dengan styling self-contained.

Versi: 0.1.0-beta.0 Kategori: UI Component (Vue 3)

npm versionTypeScriptVueTailwind CSS


TL;DR

vue-sabutton menyediakan 5 komponen button: BasicButton/LinkButton (diekstrak dari sa-gw-admin's BasicButton/AnchorButton/InertiaButton) dan SplitButton/SplitLinkButton/MenuButton (dropdown-driven, desain baru tanpa precedent). Styling self-contained — tidak butuh class dari parent project, tidak ada dependency ke FontAwesome atau library icon manapun.

Components:

ts
import { BasicButton, LinkButton, SplitButton, SplitLinkButton, MenuButton } from '@bpmlib/vue-sabutton';

Lihat daftar lengkap tiap component di Component Catalog.


Installation & Setup

Requirements

DependencyVersiStatusDeskripsi
vue^3.3.0RequiredVue 3 framework
@inertiajs/vue3anyOptionalHanya dibutuhkan kalau memakai jalur Inertia-routed pada LinkButton/SplitLinkButton (inertia prop, atau href berbentuk object Wayfinder). Di-import secara dynamic (import()), tidak pernah masuk bundle consumer yang tidak memakainya.

Package Installation

bash
npm install @bpmlib/vue-sabutton
bash
yarn add @bpmlib/vue-sabutton
bash
pnpm add @bpmlib/vue-sabutton
bash
bun install @bpmlib/vue-sabutton

Import

Basic Import:

ts
import { BasicButton, LinkButton, SplitButton, SplitLinkButton, MenuButton } from '@bpmlib/vue-sabutton';

CSS Import:

ts
// main.ts
import '@bpmlib/vue-sabutton/style.css';

Import CSS ini sekali saja di entry point aplikasi — semua 5 komponen memakainya, tidak ada langkah app.use(...).

Quick Start

Contoh paling sederhana — satu BasicButton dan satu SplitButton dengan menu:

vue
<script setup lang="ts">
import { BasicButton, SplitButton } from '@bpmlib/vue-sabutton';

const menu = [
  { label: 'Duplikat', onClick: duplicate },
  { label: 'Arsipkan', onClick: archive },
  { label: 'Hapus', onClick: remove, disabled: true },
];
</script>

<template>
  <BasicButton color="primary" @click="submitForm">Simpan</BasicButton>

  <SplitButton color="primary" :menu="menu" @click="submitForm">Simpan</SplitButton>
</template>

Untuk contoh penggunaan lengkap tiap component, buka halaman masing-masing di Component Catalog.


Core Concepts

href: string vs object, dan kapan Inertia dipakai

LinkButton/SplitLinkButton menerima href: string | { url: string; method?: 'get'|'post'|'put'|'patch'|'delete' }.

  • href berbentuk object — bentuk return Wayfinder, dan bentuk yang diterima native oleh <Link> Inertia v3 — selalu di-routing lewat Inertia, tanpa ambiguitas.
  • href berbentuk string — link <a> biasa secara default. Opt-in ke Inertia routing lewat prop inertia: boolean secara eksplisit — tidak pernah di-detect otomatis dari apakah @inertiajs/vue3 ter-install (link ke https://example.com dan link ke /posts/5 sama-sama string, tapi butuh perilaku yang berlawanan).
  • target non-_self selalu override kembali ke tag native (<a>/<button>), terlepas dari bentuk href atau prop inertia — sebuah browsing context baru tidak bisa berbagi instance SPA yang sudah jalan.
  • method non-get pada href object otomatis mengubah tag yang dirender jadi <button>, mengikuti rekomendasi accessibility Inertia sendiri untuk aksi link-shaped non-GET.

Icon prop

icon menerima dua bentuk — tidak pernah lewat registry global atau import @fortawesome/*:

  • String SVG mentah, di-render lewat v-html.
  • Object duck-typed { icon: [width, height, ligatures, unicode, svgPathData] } — tuple yang sama persis dengan yang dipakai internal setiap icon object @fortawesome/free-*-svg-icons, jadi consumer yang sudah punya FA icon object bisa langsung pass tanpa reshape.

menu / menuFieldMap — kontrak item dropdown

SplitButton, SplitLinkButton, dan MenuButton berbagi kontrak item yang sama:

  • menu: T[]T genuinely unconstrained, sama seperti pola vue-saform's FormSelect.options.
  • menuFieldMap<T> — resolve field per-field (label/icon/disabled/href/onClick/inertia/target/rel/anchorIcon), masing-masing berupa string (rename property) atau function (computed value). Field yang tidak dipetakan fallback ke nama property MenuItemDef bawaan.
  • MenuItemDef (default shape saat menuFieldMap tidak dipakai): { label, icon?, disabled?, onClick?, href?, inertia?, target?, rel?, anchorIcon? }. Item dengan href dianggap link item; tanpa href dianggap action item.
  • Setiap item dengan href otomatis dapat trailing anchor-indicator (icon external-link atau angle, tergantung apakah target-nya membuka browsing context baru) — toggle lewat menuAnchorIcon (component-level) atau anchorIcon per-item.
  • Kustomisasi tampilan per-baris lewat scoped slot #item ({ item, index }) — bukan lewat full-panel-override, supaya keyboard reachability dan disabled handling tetap konsisten di setiap baris.

Arsitektur Internal (Tidak Diekspor)

Beberapa piece dipakai bersama oleh komponen-komponen di atas tapi tidak diekspor dari index.ts, jadi tidak punya halaman sendiri:

  • useButtonStyle/useButtonBadge — logic styling (warna, outline, badge, pulse) yang dipakai semua 5 komponen.
  • useDropdownTrigger/useDropdownState/useMenuKeyboardNav — state machine dropdown (posisi, outside-click, keyboard nav), di-port dari vue-saform's FormSelect.
  • MenuItem.vue — internal row renderer untuk menu; kustomisasi lewat slot #item di setiap komponen dropdown, bukan lewat import langsung.

Component Catalog

Basic

ComponentTypeDescription
BasicButtonStylizedButton form-shaped (type/submit/reset), tanpa href
LinkButtonStylizedLink navigation-shaped — anchor biasa atau Inertia routing, gabungan AnchorButton+InertiaButton

Split

ComponentTypeDescription
SplitButtonStylizedDua segmen: aksi utama (button) + caret pembuka dropdown menu
SplitLinkButtonStylizedSama seperti SplitButton, tapi segmen utama-nya link (href-driven)
ComponentTypeDescription
MenuButtonStylizedSatu trigger dengan caret inline yang membuka dropdown menu — tanpa segmen aksi terpisah