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

mokona-ui

v0.0.14

Published

React UI component library

Readme

mokona-ui

React UI 컴포넌트 라이브러리.

풍부한 애니메이션 반응, CSS variable 기반 다크모드, React 17~19 지원을 목표로 설계했습니다.


설치

npm install mokona-ui
# or
pnpm add mokona-ui

소비자 프로젝트에서 스타일시트를 한 번 import합니다.

import "mokona-ui/styles.css";

사용법

전체 import

import { Button, Toast, BottomSheet } from "mokona-ui";

Subpath import (트리쉐이킹 최적화)

필요한 컴포넌트만 가져오면 불필요한 코드가 번들에 포함되지 않습니다.

import { Button } from "mokona-ui/button";
import { TextField } from "mokona-ui/textfield";
import { toast, Toaster } from "mokona-ui/toast";

컴포넌트

Foundation

| 컴포넌트 | 설명 | |---|---| | Button | 탄성 tap 애니메이션, 5가지 variant, loading 상태 | | Text | 타이포그래피 토큰 래퍼, as prop으로 시맨틱 태그 지정 | | Divider | 수평/수직, spacing 조절 |

<Button variant="primary" size="md" loading>계속하기</Button>
<Button variant="danger" fullWidth>삭제</Button>

<Text variant="title1">잔액 조회</Text>
<Text variant="body2" color="muted">오늘 사용 금액</Text>

Input

| 컴포넌트 | 설명 | |---|---| | TextField | label, helperText, errorMessage, 접근성 aria 자동 처리, size (sm/md/lg) | | Checkbox | 체크 시 path draw 애니메이션, Radix 접근성, size (sm/md/lg) | | Toggle | label + description 레이아웃 내장, Radix Switch 기반, size (sm/md/lg) | | RadioGroup | items 배열로 선언, size (sm/md/lg) | | Textarea | 자동 높이 조절, label/helper 내장 | | Select | Radix 기반 드롭다운, options 배열 | | Slider | 범위 슬라이더, Radix Slider 기반 | | SegmentedControl | 탭 전환 컨트롤, sliding 인디케이터 애니메이션, size (sm/md) | | NumericSpinner | +/- 버튼으로 숫자 입력, min/max/step 지원 | | SearchField | 검색 입력 + 지우기 버튼 | | OTPInput | N자리 일회용 코드 입력 |

<TextField label="이메일" placeholder="[email protected]" isError errorMessage="올바른 이메일 형식이 아닙니다" size="lg" />

<Checkbox label="전체 동의" size="md" onCheckedChange={setChecked} />

<Toggle label="푸시 알림" description="혜택 및 이벤트 소식을 받습니다" size="sm" />

<RadioGroup
  value={plan}
  onChange={setPlan}
  items={[{ value: "basic", label: "기본", description: "월 9,900원" }, { value: "pro", label: "프로", description: "월 19,900원" }]}
  size="lg"
/>

<SegmentedControl items={[{ value: "day", label: "일" }, { value: "week", label: "주" }, { value: "month", label: "월" }]} value={period} onChange={setPeriod} />

Feedback

| 컴포넌트 | 설명 | |---|---| | Toast / Toaster / toast() | 함수 호출 방식, 4가지 variant, 콘텐츠 너비 자동 조절, 텍스트 선택 가능 | | BottomSheet | spring 슬라이드 + 드래그로 닫기 | | Badge | 6가지 variant, 3가지 size | | Chip | 선택/해제 상태, 제거 버튼 내장 | | Progress | value 기반 determinate, indeterminate prop으로 스트라이프 애니메이션, size/color 지원 | | Alert | 아이콘 + 제목 + 설명, 4가지 variant | | AlertDialog / ConfirmDialog | 모달 형태 확인 다이얼로그 | | Rating | 별점 입력/표시 |

// 앱 최상단에 Toaster 한 번 추가
<Toaster />

// 어디서든 함수로 호출
toast("송금이 완료되었습니다");
toast.positive("계좌가 연결되었습니다");
toast.negative("오류가 발생했습니다", { description: "잠시 후 다시 시도해주세요" });

// Progress
<Progress value={72} showLabel />
<Progress indeterminate color="primary" />  {/* 스트라이프 흐름 애니메이션 */}

Layout / 기타

| 컴포넌트 | 설명 | |---|---| | Card | 3가지 variant, onClick 시 tap 애니메이션 자동 활성화 | | Spinner | 4가지 size, 3가지 color | | Skeleton | text / circular / rectangular variant, multi-line 지원 | | Tabs | line / pill variant | | Accordion | 아코디언, Radix 기반 | | Table | columns + data 배열 선언형 | | Pagination | 페이지 이동 버튼 | | Stepper | 단계 진행 표시 | | Avatar | 이미지 + fallback 이니셜 | | Tooltip | hover 시 설명 팝업 | | Popover | 클릭 시 떠있는 패널 | | DropdownMenu | 컨텍스트 메뉴 | | Modal / Drawer | 전체 화면 오버레이 / 사이드 패널 | | Calendar / DatePicker | 날짜 선택 | | BottomCTA | 화면 하단 고정 CTA 버튼 영역 | | ListRow | 아이템 목록 행 (아이콘 + 텍스트 + 우측 액션) | | Result | 성공/실패/로딩 결과 화면 | | Empty | 빈 상태 안내 | | Icon | lucide-react 기반 아이콘 래퍼 | | Form | react-hook-form 연동 Form 필드 |

<Card variant="elevated" onClick={() => navigate("/detail")}>
  <Text variant="body2" color="muted">토스뱅크 통장</Text>
  <Text variant="title2">1,234,567원</Text>
</Card>

<Skeleton variant="text" lines={3} />
<Skeleton variant="circular" width={48} height={48} />

다크모드

CSS variable 기반으로 구현되어 있습니다. data-theme="dark" 속성 하나로 전체 테마가 전환됩니다.

// 다크모드 적용
document.documentElement.setAttribute("data-theme", "dark");

// 라이트모드 복귀
document.documentElement.removeAttribute("data-theme");

Tailwind darkMode 클래스도 함께 지원합니다.

<html class="dark"> ... </html>

디자인 토큰

CSS variable로 정의된 토큰을 직접 사용할 수 있습니다.

/* 컬러 */
var(--color-primary)        /* #3182F6 */
var(--color-positive)       /* #00B493 */
var(--color-negative)       /* #F04452 */
var(--color-warning)        /* #FF8A00 */
var(--color-foreground)
var(--color-muted)
var(--color-border)

/* 그림자 */
var(--shadow-sm)
var(--shadow-md)
var(--shadow-lg)
var(--shadow-overlay)

TypeScript 토큰 상수도 export합니다.

import { colors, typography } from "mokona-ui";

colors.primary.DEFAULT // "#3182f6"
typography.title1      // { fontSize: "22px", lineHeight: "1.4", fontWeight: 700 }

Peer Dependencies

{
  "react": "^17 || ^18 || ^19",
  "react-dom": "^17 || ^18 || ^19"
}

성능 설계

LazyMotion으로 Framer Motion 번들 절감

모든 애니메이션 컴포넌트에 LazyMotion + domAnimation + m.* 패턴을 적용했습니다. motion.* 대신 m.*을 사용하면 Framer Motion의 고급 기능(3D, layout animation 등)을 제외한 기본 기능만 로드해 번들 크기를 줄입니다.

// ❌ 전체 번들 포함
import { motion } from "framer-motion";

// ✅ domAnimation만 로드 (~30% 절감)
import { LazyMotion, domAnimation, m } from "framer-motion";
<LazyMotion features={domAnimation}>
  <m.div whileTap={{ scale: 0.96 }} />
</LazyMotion>

useSyncExternalStore 기반 Toast 상태

useToast는 React 18의 useSyncExternalStore로 구현했습니다. 여러 컴포넌트가 useToast()를 구독해도 상태 변경 시 setState가 한 번만 발생합니다.

// ❌ 기존: N개 구독자 → N번 setState
listeners.forEach((l) => l(toasts));

// ✅ 개선: React가 배치 처리
useSyncExternalStore(subscribe, getSnapshot);

Subpath exports로 트리쉐이킹

Button만 사용해도 BottomSheet(Framer Motion drag 포함)가 번들에 들어가는 문제를 방지합니다.

// BottomSheet 코드가 번들에 포함되지 않음
import { Button } from "mokona-ui/button";

Skeleton GPU 가속

shimmer 애니메이션에 will-change: transform을 적용해 GPU 합성 레이어로 분리했습니다. 여러 Skeleton이 동시에 렌더링될 때 CPU 부하가 줄어듭니다.

Card 리마운트 방지

interactive prop 유무에 따라 motion.divdiv를 분기하면 prop이 바뀔 때 컴포넌트가 리마운트됩니다. 항상 motion.div를 사용하고 whileTap만 조건부로 적용해 이 문제를 방지했습니다.


Showcase

컴포넌트 데모 앱이 showcase/ 폴더에 포함되어 있습니다 (Next.js).

cd showcase && pnpm dev   # http://localhost:3000

개발

# 컴포넌트 개발 서버
pnpm storybook            # http://localhost:6006

# 빌드
pnpm build

# 테스트
pnpm test

# 릴리즈 — package.json version 올리고 커밋/푸시하면 GitHub Actions가 자동 배포
# (수동 배포 시: pnpm publish — prepublishOnly로 build 자동 선행 실행)

더 자세한 내용은 CLAUDE.md · TECH.md · PROJECT.md를 참고하세요.


스택

  • Radix UI — 접근성 primitives
  • Tailwind CSS v3 — CSS variable 기반 토큰 시스템
  • CVA (class-variance-authority) — variant 관리
  • Framer Motion v10 — 애니메이션
  • tsup — ESM + CJS 듀얼 번들
  • Storybook 8 — 컴포넌트 문서 및 테스트
  • Vitest — 단위 테스트
  • Changesets — 버전 관리 및 npm 배포