@damarkuncoro/agnostic-ui-base
v0.1.0
Published
Agnostic UI Base
Maintainers
Readme
@damarkuncoro/agnostic-ui-base
Lapisan logika UI (Base) untuk Agnostic UI. Paket ini mengimplementasikan logika non-visual yang bersandar pada kontrak tipe dari @damarkuncoro/agnostic-ui-contracts. Fokus: resolusi props default, pembentukan state runtime, dan atribut a11y. Tidak bergantung pada framework (React/Vue) maupun Tailwind.
Ringkas
- Import via alias:
@damarkuncoro/agnostic-ui-base - Bergantung ke:
@damarkuncoro/agnostic-ui-contracts - Tanggung jawab:
resolve props→state→a11y - Tanpa UI framework dan styling (SRP, DRY, KISS, YAGNI)
Instalasi & Import
Monorepo sudah memetakan alias ke source melalui tsconfig.base.json.
// Gunakan hook/utility dari Base
import { useUiButton } from '@damarkuncoro/agnostic-ui-base'Kontrak diimpor melalui alias:
import { type UiButtonProps } from '@damarkuncoro/agnostic-ui-contracts'Struktur Direktori
packages/agnostic-ui-base/
├─ src/
│ ├─ ui/
│ │ └─ button/
│ │ ├─ use-button.ts
│ │ ├─ resolve-button-props.ts
│ │ ├─ create-button-state.ts
│ │ ├─ create-button-a11y.ts
│ │ └─ index.ts
│ └─ index.ts
└─ dist/ (hasil build)
## API Surface
- `useUiButton(props: UiButtonProps)` → mengorkestrasi resolusi props, state, dan a11y
- Sumber: `src/ui/button/use-button.ts`
- `resolveUiButtonProps(props)` → menggabungkan default + validasi kontrak
- `createUiButtonState(resolved)` → membentuk state runtime yang diturunkan dari props
- `createUiButtonA11y(resolved, state)` → atribut aksesibilitas berdasarkan props/state
Tipe terkait:
- `UiButtonResolvedProps` → props yang sudah dimerge dengan default
- `UiButtonBase` → hasil dari `useUiButton` berisi `{ props, state, a11y }`
## Contoh Penggunaan
### 1) Menggunakan Base di adapter/komponen
```ts
import { useUiButton } from '@damarkuncoro/agnostic-ui-base'
import { type UiButtonProps } from '@damarkuncoro/agnostic-ui/contracts'
export function createButtonModel(props: UiButtonProps) {
const base = useUiButton(props)
// base.props → props final (dengan default)
// base.state → state runtime
// base.a11y → atribut aksesibilitas
return base
}2) Integrasi dengan Skin (kelas Tailwind)
import { useUiButton } from '@damarkuncoro/agnostic-ui-base'
import { shadcn } from '@damarkuncoro/agnostic-ui-skin'
const { props } = useUiButton({ variant: 'primary', size: 'md' })
const className = shadcn.getButtonClass(props.variant, props.size)3) Validasi props via kontrak (otomatis di Base)
import { useUiButton } from '@damarkuncoro/agnostic-ui-base'
// size/variant/type dll divalidasi oleh kontrak; error bila tidak valid
const { props } = useUiButton({ size: 'md', variant: 'primary' })Build & Test
- Build:
pnpm --filter @damarkuncoro/agnostic-ui-base build- Test:
pnpm --filter @damarkuncoro/agnostic-ui-base testKonfigurasi terkait:
packages/agnostic-ui-base/package.json→build,testpackages/agnostic-ui-base/tsconfig.json→outDir: distpackages/agnostic-ui-base/vitest.config.ts→ alias untuk@damarkuncoro/agnostic-ui/contracts
Arsitektur & Aturan Dependency
- Base → bergantung ke Contract
- Skin → bergantung ke Base + Theme
- Adapter (React/Vue) → menggabungkan Base + Skin (+ Theme bila perlu)
- Contract → tidak bergantung apa pun
Prinsip:
- SRP: Base hanya mengurus logika non-visual
- DRY: Resolusi props dan a11y terpusat
- KISS/YAGNI: API sederhana, tanpa over-engineering
- SOLID: Mematuhi kontrak yang stabil, komposisi di layer atas
Struktur Direktori
packages/agnostic-ui-base/
├─ src/
│ ├─ ui/
│ │ └─ button/
│ │ ├─ use-button.ts
│ │ └─ index.ts
│ └─ index.ts
├─ test/
│ └─ ui/
│ └─ button/
│ └─ use-button.spec.ts
├─ package.json
├─ tsconfig.json
└─ vitest.config.tsCatatan
- Entry ekspor:
packages/agnostic-ui-base/src/index.ts - Ikuti kontrak dari
@damarkuncoro/agnostic-ui-contractsuntuk tipe, props, state, a11y - Tambahkan komponen Base baru (mis.
input,switch) dengan pola yang sama:resolve → state → a11y
