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

@stmjsc/ui

v1.0.6

Published

STM design system — shadcn/ui custom theo thiết kế STM + component dùng chung (HIS/EMR/RIS)

Downloads

1,061

Readme

@stmjsc/ui

Thư viện component React + hệ thống thiết kế (design system) dựng trên shadcn/ui + Radix UI + Tailwind CSS, tối ưu cho ứng dụng quản trị/nghiệp vụ tiếng Việt: viết tắt tên kiểu Việt Nam, DatePicker dd/MM/yyyy, tìm kiếm không dấu, font subset tiếng Việt, chủ đề xanh y tế với sáng/tối.

Gồm 3 lớp: primitives (shadcn đã custom style), composites (bảng dữ liệu, phân trang, thanh lọc, form, trạng thái…) và app shell (header, sidebar, chuyển module, menu người dùng). Import và dùng ngay — không cần chép code.

  • ESM, tree-shakeable, giữ "use client" per-module (component tĩnh dùng được trong RSC)
  • Token hoá bằng CSS variables → đổi màu theo thương hiệu mà không cần rebuild

Yêu cầu

| Gói | Yêu cầu | Ghi chú | |---|---|---| | React | >=19 | bắt buộc | | Tailwind CSS | 3.4.x | dùng preset của package | | Next.js | >=15 (tùy chọn) | chỉ cần cho @stmjsc/ui/shell (dùng next/link, next/navigation). Primitives và composites chạy trong bất kỳ app React 19 nào (Vite, Remix, Next…). |

Sàn Next.js >=15 là vì đây là bản Next đầu tiên hỗ trợ React 19 — không phải bắt buộc đúng bản 15. Các bản mới hơn (16+) dùng bình thường; peer dependency đã khai next: ">=15".

Cài đặt & cấu hình (Next.js ≥15 + Tailwind 3.4)

pnpm add @stmjsc/ui lucide-react
// tailwind.config.ts — BẮT BUỘC 2 dòng: preset + content quét class trong package
const config: Config = {
  presets: [require("@stmjsc/ui/preset")],
  content: [
    "./app/**/*.{ts,tsx}",
    "./components/**/*.{ts,tsx}",
    "./node_modules/@stmjsc/ui/dist/**/*.{js,mjs}"
  ]
};

App vẫn giữ globals.css với 3 directive Tailwind như mặc định (bắt buộc — không có thì Tailwind không sinh utility cho component):

/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
// app/layout.tsx — import globals + CSS tokens của package 1 lần + tự khai báo font (package chỉ dùng biến)
import "./globals.css";
import "@stmjsc/ui/styles.css";
import { Inter, JetBrains_Mono } from "next/font/google";

const inter = Inter({ subsets: ["latin", "vietnamese"], variable: "--font-sans" });
const mono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-mono" });
// <html lang="vi" className={`${inter.variable} ${mono.variable}`}>

Entry points

| Import | Nội dung | |---|---| | @stmjsc/ui | Primitives (27 component shadcn-custom) + composites (17) + cn/helpers + tokens TS | | @stmjsc/ui/shell | App shell (AppShell, AppHeader, Sidebar, ModuleSwitcher, UserMenu, ThemeToggle/ThemeProvider, MobileMenu, ShellProvider/useShell) — cần next (optional peer) | | @stmjsc/ui/preset | Tailwind 3 preset (tokens semantic + status + header/sidebar/brand, radius, font, keyframes) | | @stmjsc/ui/styles.css | CSS variables light/dark + base layer (focus ring, scrollbar) + utilities | | @stmjsc/ui/tokens | Token dạng TS object (dùng cho chart/canvas/email/PDF) |

Ví dụ

import { Button, DataTableContainer, SearchFilterBar, StatusPill } from "@stmjsc/ui";
// App shell — dữ liệu điều hướng (zones/menus) do ứng dụng tự khai báo
"use client";
import { AppShell } from "@stmjsc/ui/shell";

<AppShell
  product="APP"
  zones={zones}
  menus={sidebarMenus}
  user={user}
  roleLabels={{ admin: "Quản trị viên", staff: "Nhân viên" }}
  onLogout={logout}>
  {children}
</AppShell>

Quy ước

  • Không hardcode mã màu hex — dùng token: bg-success/15 text-success, text-warning, bg-info/15, status-purple, status-teal, bg-header, sidebar-*, brand (cyan-mint, green-accent…). Token trạng thái tự đổi sắc theo dark mode.
  • KHÔNG dùng opacity modifier trên border/input (border-border/50 sẽ sai — dark mode nhúng alpha trong biến).
  • Trạng thái nghiệp vụ: khai báo StatusConfig<T>[] trong ứng dụng — package cung cấp cơ chế + StatusPill/StatusFilterChips/getBadgeClasses/getRowStatusClasses.
  • Kích thước chuẩn: control h-10, form compact h-9, control trong bảng/phân trang h-8; ngày dd/MM/yyyy, giờ 24h; icon dùng Lucide.
  • useColumnVisibility với onLayoutChange → ứng dụng tự lưu cấu hình cột theo người dùng (server); không truyền thì tự lưu localStorage theo storageKey.

DatePicker & DateRangePicker

// Ràng buộc quá khứ/tương lai (kết hợp được với minDate/maxDate — lấy khoảng hẹp hơn)
<DatePicker value={dob} onChange={setDob} disableFuture />
<DatePicker value={apptDate} onChange={setApptDate} disablePast />
<DateRangePicker value={range} onChange={setRange} />        // {from, to}

DateRangePicker: click 1 = từ ngày, click 2 = đến ngày (click trước "từ" bắt đầu lại); gõ tay dd/MM/yyyy - dd/MM/yyyy; ngày trong khoảng highlight bg-primary/15. disableFuture/disablePast thu hẹp cả danh sách năm và vô hiệu nút "Hôm nay" khi hôm nay ngoài khoảng cho phép.

Phát triển

pnpm install
pnpm typecheck   # tsc strict + noUncheckedIndexedAccess
pnpm lint        # biome
pnpm build       # tsup → dist/ (ESM per-file, giữ "use client" per-module, kèm .d.ts)

Publish package: xem PUBLISHING.md.

License

MIT © STM JSC