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

@ceplok-ui/design-kit-react

v0.4.0

Published

Design tokens, tipografi, dan komponen React (Tailwind v4) untuk Ceplok Design System

Readme

@ceplok-ui/design-kit-react

Design tokens, tipografi, dan komponen React (Tailwind v4) untuk Ceplok Design System. Dipindahkan 1:1 dari versi Laravel/Blade (tpl/design-kit) ke komponen React yang bisa dipublish lewat NPM.

Isi

  • Tokens (@theme): palet warna (primary, gray, red, orange, yellow, green, purple), semantic aliases (brand, feedback-*, content, surface, border), skala tipografi (display → caption), spacing, radius, shadow, font Lato, serta font alternatif Inter (font-alt) dan Arial (font-alt-2). Panduan lengkap token dan tema gelap ada di COLOR.md.
  • Komponen umum: Alert, Avatar, Badge, Breadcrumb, Button, Card, Clipboard, Container, Drawer, Dropdown, Footer, Hero, Icon, Modal, Navbar, Pagination, Popover, Sidebar, Spinner, Table, Toast.
  • Komponen form: InputField, FloatingLabel, TextArea, Select, Search, Datepicker, Upload, Radio, Toggle, Checkbox.
  • Ikon: logo brand & sosial (Github, Instagram, …) dari barrel utama, plus ikon UI lewat subpath icons/outline dan icons/solid.

Install

npm install @ceplok-ui/design-kit-react

Peer deps: react >=18, react-dom >=18, tailwindcss ^4. Ketiganya disediakan consumer — package ini tidak mem-bundle React maupun Tailwind.

Pakai

Package mengirim CSS sumber, bukan CSS yang sudah dikompilasi. Artinya consumer wajib memakai Tailwind v4, dan setup-nya cuma dua baris di file CSS kamu:

/* src/index.css */
@import '@ceplok-ui/design-kit-react/styles.css';
@source '../node_modules/@ceplok-ui/design-kit-react/dist/**/*.js';

Jangan menambahkan @import 'tailwindcss' lagi — styles.css sudah memanggilnya berikut token @theme, font Lato, base layer, dan class .ds-*.

// main.tsx
import './index.css'
import { Button, Card, InputField } from '@ceplok-ui/design-kit-react'
import { User } from '@ceplok-ui/design-kit-react/icons/outline'

export default function App() {
  return (
    <Card title="Halo" description="Kartu dari design kit">
      <InputField label="Nama lengkap" icon={<User className="size-4" />} />
      <Button>Simpan</Button>
    </Card>
  )
}

Wajib: baris @source

Tailwind v4 tidak memindai node_modules saat mendeteksi sumber class secara otomatis. Tanpa baris @source di atas, komponen tetap ter-render tetapi tanpa satu pun class utility-nya — tidak ada error, hanya tampilan yang berantakan. Bedanya terukur:

| Setup | Ukuran CSS | h-9.25 (Select) | size-3.5 | bg-brand | | ---------------- | ---------- | ----------------- | ---------- | ---------- | | tanpa @source | 13,6 kB | hilang | hilang | hilang | | dengan @source | 27,3 kB | ada | ada | ada |

Alternatif: hanya token, tanpa base style kit

Kalau project kamu sudah punya base style sendiri dan hanya butuh token:

@import 'tailwindcss';
@import '@ceplok-ui/design-kit-react/tokens.css';
@source '../node_modules/@ceplok-ui/design-kit-react/dist/**/*.js';

Token dan seluruh utility komponen tetap ter-generate, tapi kamu kehilangan font Lato, base layer (body, focus ring global), dan class .ds-card / .ds-eyebrow / .ds-nav-link / .ds-scroll-x / .ds-scroll-y.

Tema gelap & token warna

Komponen Ceplok Design Kit dirancang menggunakan sistem token warna semantik yang didefinisikan di tokens.css. Tema gelap diatur secara deklaratif lewat atribut data-theme="dark" alih-alih class dark: per elemen:

  • Prop darkMode: Memasang darkMode={true} pada komponen akan menyetel atribut data-theme="dark" pada elemen terluarnya.
  • Pewarisan tema otomatis: Jika sebuah elemen pembungkus memiliki atribut data-theme="dark" (misalnya <div data-theme="dark">), semua komponen di dalamnya otomatis beradaptasi ke tema gelap tanpa perlu memberikan prop darkMode satu per satu.
  • Kembali ke tema terang: Bagian di dalam area gelap dapat dikembalikan ke tema terang dengan data-theme="light" atau kelas .ds-theme-light.
  • Komponen yang mendukung data-theme: Card, Hero, Container, Sidebar, Search, Alert, Toast, InputField, FloatingLabel, TextArea, Select, Toggle, Radio, dan Checkbox.
  • Token komponen: Warna latar khusus komponen disediakan melalui token yang dapat ditimpa di CSS aplikasi consumer, seperti --color-sidebar-surface (Sidebar), serta --color-search-category-surface dan --color-search-field-surface (Search). Panduan lengkap token dan cara kerjanya ada di COLOR.md.

Komponen & props

Umum

| Komponen | Props utama | | ------------ | -------------------------------------------------------------------------------------------------------------------- | | Button | variant: filled \| outline, theme, tone, size, type: button \| submit \| reset, iconOnly, as: button \| anchor | | Badge | variant: gray \| brand \| danger \| warning \| success, size: sm \| lg, icon, dismissible, onDismiss, open, darkMode | | Avatar | src, alt, initials, size: small \| default \| large, darkMode | | Spinner | size: default \| large | | Clipboard | value, variant: default \| segmented, prefix, label, helperText, platform, onCopySuccess, darkMode | | Alert | variant, heading, icon, dismissible, actions, darkMode | | Toast | variant, heading, icon, dismissible, actions, darkMode | | Card | image, title, description, href, linkLabel, actions, darkMode | | Container | as (default div), padded (default true), darkMode | | Icon | children (SVG dengan currentColor) | | Popover | trigger, title, side, open/defaultOpen/onOpenChange, darkMode | | Dropdown | trigger, items/groups, attached, contentLabel, darkMode | | Modal | trigger atau open/onOpenChange, title, footer, variant: default \| popup, size: s \| m, closeOnBackdrop, closeOnEscape | | Drawer | open, onClose, position, size, closeOnOverlayClick, closeOnEsc, header, items, theme, darkMode | | Breadcrumb | items, separator, size, background, darkMode | | Pagination | currentPage, totalPages, onPageChange, theme, size, darkMode | | Navbar | brand, items, search, guestActions, menuPosition, user | | Hero | type, centeredContent, platform, heading, description, image, showButton, buttonLabel, darkMode | | Sidebar | items, groups, logo, collapsedLogo, user (profil + menu dropdown), collapsed, onCollapse, showCollapseButton, sticky, footer, darkMode | | Footer | logo/logoContent, menus, copyright, socials | | Table | columns, data, rowKey, search, filter, selectable, sort, headerAlign, pagination, striped, sticky, size, loading |

Warna Button diatur theme (primary | green | gray | simaya | orange | yellow) dan tone (light | dark), bukan lewat variant — variant hanya memilih terisi atau bergaris. Ukuran: xs | s | base | l | xl. Ikon di kiri atau kanan teks lewat leftIcon/rightIcon; iconOnly membuat tombol persegi berisi ikon saja. Prop type (button | submit | reset, bawaan button) meneruskan atribut HTML native ke elemen <button>, memungkinkan tombol dipakai untuk submit form. Untuk tautan pakai as="anchor" bersama href, maka Button dirender sebagai <a>.

Form

Semua komponen form meneruskan atribut elemen aslinya (value, onChange, name, required, …) dan mengaitkan label ke id serta caption ke aria-describedby secara otomatis.

| Komponen | Props khas | Ukuran (desktop / mobile) | | --------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | | InputField | label, helperText, icon, onClear, type="password", darkMode, state: default \| typing \| inactive \| failed | 52 / 40 px | | FloatingLabel | label, helperText, icon, onClear, darkMode, state: default \| active \| error | 58 / 50 px | | TextArea | label, hint, helperText, type: default \| editor, toolbar, onToolbarAction, submitLabel, onSubmit, darkMode | 162 / 120 px | | Select | label, info, helperText, placeholder, options, darkMode | 37 px | | Search | label, helperText, buttonLabel, onSearch, trigger: enter \| change \| auto, debounce, showButton, categories, onCategoryChange, darkMode | 54 / 50 / 37 px | | Datepicker | label, type: single \| period \| multiple, shortcuts, min/max, darkMode, name — nilai Date / DateRange | 42 / 42 px | | Upload | label, helperText, buttonLabel, replaceLabel, removeLabel, placeholder, type: default \| attach, onFilesChange, darkMode | 44 / 40 px | | Radio | label, helperText, darkMode | 16 / 14 px | | Toggle | label, helperText, darkMode | 40×20 / 36×18 px | | Checkbox | label, helperText, darkMode | 16 / 14 px |

Prop yang dipakai bersama seluruh komponen form:

  • platform: default | mobile — mengubah ukuran. Pada Datepicker ia juga mengubah tata letak: panelnya selebar kotak, single menaruh kisinya di tengah, period memuat empat pintasannya dalam satu baris, dan multiple menumpuk kotak serta kalendernya. Pada Select, varian Mobile cuma menyempitkan wadahnya, jadi prop ini memang tidak ada; pada Upload ia tidak berpengaruh untuk type="attach", karena alasan yang sama. Search punya ukuran ketiga, compact (37px), untuk dipasang di navbar tanpa tombol cari (showButton=false). Komponen ini juga mendukung live search via trigger="change" / "auto" dengan jeda debounce (bawaan 300ms) serta tema gelap berbasis token (--color-search-category-surface dan --color-search-field-surface).
  • Upload: dibatasi khusus berkas tunggal (atribut multiple dinonaktifkan).
  • application: default | simaya — warna aksen per aplikasi.
  • state: default | inactive (InputField dan FloatingLabel punya state tambahan, lihat tabel). inactive sekaligus menonaktifkan kontrolnya.
  • Kondisi tercentang/menyala pada Radio, Toggle, dan Checkbox memakai checked/defaultChecked biasa, bukan prop state.

Catatan konsistensi: tampilan inactive masih berbeda antar komponen karena mengikuti rancangannya apa adanya — Checkbox tidak meredupkan kotaknya, Radio memakai latar gray-100, Toggle justru menggelapkan jalurnya ke gray-300. Perlu diselaraskan di rancangannya lebih dulu.

Navbar

import { Navbar } from '@ceplok-ui/design-kit-react'

<Navbar
  brand={<img src="/logo.svg" alt="" />}
  brandLabel="CEPLOK — Beranda"
  items={[
    {
      id: 'menu-1',
      label: 'Menu 1',
      children: [{ id: 'menu-1-overview', label: 'Ringkasan', href: '/menu-1' }],
    },
  ]}
  search={{
    placeholder: 'Search Civitas, Organisasi ...',
    onSubmit: (query) => console.log(query),
  }}
  guestActions={{
    login: { label: 'Masuk', href: '/login' },
    register: { label: 'Daftar', href: '/register' },
  }}
/>

Navbar bersifat router-agnostic dan responsive mulai breakpoint lg. Pada mobile, search tetap terlihat pada baris kedua di luar panel navigasi, termasuk ketika panel tertutup. Panel mobile bersifat inline dan non-modal.

Authenticated state diberikan melalui prop user. Notification merupakan API/config Navbar yang dapat dipakai bersama authenticated state:

<Navbar
  brand={<Logo />}
  brandLabel="CEPLOK — Beranda"
  items={items}
  search={{ onSubmit: (query) => console.log(query) }}
  user={{ name: 'User CEPLOK', avatarSrc: '/avatar.jpg' }}
  notification={{ unread: true, href: '/notifications' }}
/>

notification.unread tetap tersedia untuk kompatibilitas state API, tetapi desain Navbar saat ini hanya menampilkan ikon notification solid tanpa badge, dot, atau indikator unread visual.

Type publik utama meliputi NavbarProps, NavbarItem, NavbarSubItem, NavbarSearchConfig, NavbarGuestActions, NavbarUser, NavbarNotification, dan NavbarMenuPosition.

Consumer tetap wajib menambahkan @source package seperti dijelaskan pada bagian instalasi di atas agar utility Navbar ikut dihasilkan oleh Tailwind v4.

Sidebar

import { Sidebar } from '@ceplok-ui/design-kit-react'
import { ChartPie, Inbox } from 'flowbite-react-icons/solid'

<Sidebar
  logo={<Logo />}
  collapsedLogo={<LogoMark />}
  user={{
    name: 'John Doe',
    profileLabel: 'Administrator',
    items: [
      { label: 'Profil Saya', href: '/profile' },
      { label: 'Pengaturan Akun', href: '/settings' },
      { label: 'Dokumentasi', href: 'https://docs.example.com', external: true },
      { label: 'Keluar', tone: 'danger', onClick: () => handleLogout() },
    ],
  }}
  items={[
    { label: 'Dasbor', href: '/dashboard', icon: <ChartPie className="size-5" />, active: true },
    { label: 'Pesan', href: '/messages', icon: <Inbox className="size-5" />, badge: 3 },
    { label: 'Portal Eksternal', href: 'https://ipb.ac.id', external: true },
  ]}
  sticky
  showCollapseButton
  onCollapse={() => setCollapsed((v) => !v)}
  collapsed={collapsed}
/>

Sidebar menyediakan navigasi vertikal yang mendukung pengelompokan menu (groups), multi-level submenu accordion, indikator badge, dan mode rel ringkas (collapsed).

Area profil (user) mendukung menu dropdown interaktif melalui prop items atau groups (dengan dukungan pemisah separator). Pilihan aksi seperti Keluar dapat diberi warna destruktif lewat tone="danger". Menu item, subitem, dan profil juga mendukung external: true untuk membuka tautan keluar tab baru secara aman (rel="noreferrer noopener").

Tema gelap (darkMode): Sidebar mengadopsi sistem token semantik dan token komponen --color-sidebar-surface (putih di tema terang, gray-700 di tema gelap). Tema dapat diaktifkan lewat prop darkMode maupun otomatis mewarisi atribut data-theme="dark" dari kontainer pembungkusnya.

Type publik utama meliputi SidebarProps, SidebarItem, SidebarSubItem, SidebarGroup, SidebarUser, SidebarUserItem, SidebarUserGroup, dan SidebarUserItemTone.

Table

import { useState } from 'react'
import { Table, type TableColumn } from '@ceplok-ui/design-kit-react'

type Pemohon = { id: number; nama: string; layanan: string; tanggal: string }

const columns: TableColumn<Pemohon>[] = [
  { key: 'nama', header: 'Nama', emphasis: true, hideable: false, sortable: true },
  { key: 'layanan', header: 'Layanan' },
  { key: 'tanggal', header: 'Tanggal', sortable: true, sortDirections: ['desc', 'asc'] },
]

const [kata, setKata] = useState('')
const hasilCari = pemohon.filter((p) => p.nama.toLowerCase().includes(kata.toLowerCase()))

<Table
  columns={columns}
  data={hasilCari}
  rowKey="id"
  search={{ value: kata, onChange: (e) => setKata(e.target.value) }}
  filter={{}}
  selectable
  pagination={{ pageSize: 10 }}
/>

search hanya menyediakan kotaknya: atributnya diteruskan ke <input>, dan data disaring sendiri seperti di atas. filter memunculkan tombol Filter Data untuk memilih kolom yang tampil; kolom ber-hideable: false selalu tampil. Pengurutan dan pembagian halaman dikerjakan tabel. Untuk data dari server pasang manual: kirim baris halaman aktif saja beserta pagination.total, lalu tangani onSortChange dan pagination.onPageChange.

selectable menambahkan checkbox per baris dan checkbox pilih semua di judul, yang hanya mencakup halaman yang tampil. pagination.pageSizeOptions (mis. [10, 25, 50]) memunculkan pemilih jumlah baris per halaman, dan striped memberi baris zebra. Kolom berkas memakai file, mis. file: { name: (r) => r.berkas, href: (r) => r.url }: gambar dan PDF dibuka di pratinjau, berkas lain diunduh. Bentuk yang sama tersedia sebagai komponen TableFile untuk dipakai di cell sendiri.

Ikon

import { Github, Instagram } from '@ceplok-ui/design-kit-react'          // logo brand & sosial
import { User, Envelope } from '@ceplok-ui/design-kit-react/icons/outline'
import { User as UserSolid } from '@ceplok-ui/design-kit-react/icons/solid'

Outline dan solid sengaja dipisah ke subpath berbeda: banyak nama ikon sama persis di kedua set, dan pemisahan ini menjaga tree-shaking.

Development

npm run dev        # situs dokumentasi di http://localhost:5173
npm run build      # build situs dokumentasi (tsc -b + vite build)
npm run build:lib  # build package -> dist/
npm run lint       # eslint

Situs dokumentasinya berisi /foundations/* (token), /components/*, /form/* (tiap komponen form beserta playground-nya), dan /example — contoh aplikasi tujuh halaman (Dasbor, Layanan, Pengajuan, Pemohon, Modifikasi, Pengaturan, dan Simaya) yang memakai komponen kit bersama-sama.

Seluruh halaman komponen dan form memakai susunan yang sama: judul ber-anchor, blok kode menempel di tiap bagian, dan daftar isi "On this page" di kanan. Kerangkanya di docs/usulanKit.tsx.

Deploy dokumentasi

Situs dokumentasi terbit otomatis ke GitHub Pages lewat .github/workflows/deploy-docs.yml setiap ada push ke main.

GitLab main  --push mirror-->  GitHub main  --Actions-->  GitHub Pages

Sumber kebenarannya tetap GitLab. Repo GitHub hanya cermin, jadi jangan commit langsung ke sana — mirror akan menimpanya.

Penyiapan sekali jalan:

  1. GitHub — buat repo tujuan, lalu Settings -> Pages -> Build and deployment -> Source: GitHub Actions (bukan "Deploy from a branch"). Repo publik gratis; repo privat butuh GitHub Pro/Team.
  2. GitHub — buat Personal Access Token yang boleh menulis ke repo itu (classic: scope repo, atau fine-grained: Contents = Read and write).
  3. GitLab — Settings -> Repository -> Mirroring repositories -> Add:
    • URL: https://<user-github>@github.com/<org>/<repo>.git
    • Mirror direction: Push
    • Authentication method: Password -> tempel PAT dari langkah 2
    • Centang "Only mirror protected branches" bila cukup main yang ikut

Base path-nya otomatis: workflow mengisi VITE_BASE dari base_path milik Pages dan vite.config.ts memakainya, jadi konfigurasi yang sama jalan baik di <org>.github.io/<repo>/ maupun di root domain.

Karena itu rujukan berkas public/ harus lewat asset() (docs/asset.ts). Path absolut seperti /images/x.svg diukur dari root domain dan akan 404 saat situs disajikan dari sub-path; Vite hanya menulis ulang URL di index.html dan di import modul, bukan string literal di dalam kode.

Routing situs ini berbasis hash (#/components/alert), jadi tidak perlu 404.html sebagai fallback SPA.

Uji coba lokal sebelum publish

Cara paling mendekati install sungguhan — pakai tarball, bukan npm link atau file:../folder: keduanya membuat symlink sehingga React termuat dua kali dan memicu "invalid hook call".

# di package ini
npm run build:lib      # `npm pack` TIDAK menjalankan prepublishOnly, jadi build manual
npm pack               # -> ceplok-ui-design-kit-react-<versi>.tgz

# di project consumer
npm install ../react-design-system/ceplok-ui-design-kit-react-<versi>.tgz

Dependency clsx dan flowbite-react-icons ikut terpasang otomatis. Tarball adalah snapshot: setiap kali package berubah, ulangi build:lib + pack, lalu npm install lagi di consumer.

Rilis & publish

Versi mengikuti semver: selama masih di bawah 1.0.0, perubahan yang memutus menaikkan versi minor. Semua langkah di bawah dijalankan manual oleh maintainer, berurutan.

  1. Pastikan staging sudah di-merge ke main, lalu cek dari main:

    npm run build        # tsc -b + build situs dokumentasi
    npm run build:lib    # build paket
    npm pack --dry-run   # isi tarball: hanya dist/, README, LICENSE, package.json
  2. Di CHANGELOG.md, ganti judul ## [Belum dirilis] menjadi ## [x.y.z] - YYYY-MM-DD, lalu tambahkan ## [Belum dirilis] kosong di atasnya.

  3. Naikkan versi tanpa membuat commit; package.json dan package-lock.json ikut berubah:

    npm version x.y.z --no-git-tag-version
  4. Commit, beri tag, push main beserta tag-nya, lalu samakan staging agar CHANGELOG-nya tidak tertinggal:

    git commit -am "x.y.z"
    git tag -a vx.y.z -m "x.y.z"
    git push origin main vx.y.z
    git push origin main:staging   # fast-forward; bila ditolak, merge main ke staging
  5. Publish. prepublishOnly otomatis menjalankan build:lib, dan npm akan meminta OTP atau persetujuan lewat browser:

    npm login                     # bila sesi npm sudah kedaluwarsa
    npm publish --access public
  6. Cek hasilnya. Versi baru bisa butuh satu-dua menit sebelum terlihat:

    npm view @ceplok-ui/design-kit-react version dist-tags