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

tfg-design-system

v1.1.1

Published

Platform-agnostic design token library for TFG apps (React Native + Next.js)

Readme

TFG 디자인 시스템

tfg-app (React Native)과 tfg-web (Next.js)를 위한 플랫폼 중립적 디자인 토큰 라이브러리입니다.

Figma — TheFair_Design Library에서 추출한 이 패키지는 모든 TFG 플랫폼 전반에 걸쳐 색상, 타이포그래피, 간격, 그림자, 컴포넌트 토큰의 단일 진실 공급원(Single Source of Truth)을 제공합니다.


목차


설치

tfg-app / tfg-web에서 워크스페이스 또는 상대 경로를 통해 이 패키지를 추가합니다:

// package.json (tfg-app 또는 tfg-web 내)
{
  "dependencies": {
    "tfg-design-system": "file:../tfg-design-system"
  }
}

이후 실행:

# tfg-design-system 먼저 빌드
cd ../tfg-design-system
npm run build

# 앱에서 설치
npm install

Architecture

src/
 ├── tokens/              # 플랫폼 중립적 원시 값 (모두 숫자)
 │   ├── colors.ts        # 16진수 색상 문자열
 │   ├── typography.ts    # 폰트 스케일 (픽셀 수치)
 │   ├── spacing.ts       # 4px 기반 간격 스케일
 │   ├── radius.ts        # 테두리 반지름 스케일
 │   ├── shadows.ts       # 그림자 원시 값
 │   └── index.ts         # 모든 토큰 재내보내기
 ├── platform/            # 플랫폼별 어댑터
 │   ├── types.ts         # 공유 TypeScript 타입
 │   ├── web.ts           # CSS 어댑터 (px 문자열, box-shadow)
 │   └── native.ts        # React Native 어댑터 (fontWeight 문자열, shadow 속성)
 ├── components/          # 컴포넌트 수준 스타일 토큰
 │   └── button.ts        # 버튼 / 토글 토큰
 └── index.ts             # 메인 진입점 (공개 API)

설계 원칙

| 항목 | 결정 사항 | |------|-----------| | 숫자 타입 | 모든 크기 토큰은 number (px) 형태로 저장. 어댑터가 플랫폼 형식으로 변환. | | 색상 타입 | 16진수 문자열 — 플랫폼 무관, 변환 불필요. | | fontWeight | number 형태로 저장 (400, 600…). RN 어댑터가 string으로 변환 ('400', '600'…). | | lineHeight | 절대 px number로 저장 (예: fontSize × 1.36). RN은 그대로 사용, CSS 어댑터는 '22px'로 변환. | | letterSpacing | fontSize × -0.025 (Figma −2.5% 관례). 음수 픽셀 값. | | fontFamily | 플랫폼별 별도: RN은 폰트 파일명, Web은 Pretendard Variable 사용. | | Shadows | 완전히 다른 구조: RN은 shadowColor/Offset/Opacity/Radius/elevation, CSS는 box-shadow 문자열. |


Token Overview

모든 토큰 파일은 src/tokens/에 위치하며 플랫폼 중립적 — 순수한 숫자와 문자열을 내보냅니다.

| Module | Export | Description | |------|----------|------| | colors.ts | colors | 전체 팔레트 + 시맨틱 색상 | | typography.ts | typography | 폰트 스케일, 굵기, 패밀리 | | spacing.ts | spacing | 4px 기반 간격 값 | | radius.ts | radius | 테두리 반지름 값 | | shadows.ts | shadows | 그림자 원시 값 (색상, 불투명도, 오프셋) |

src/platform/의 플랫폼 어댑터가 이를 바로 사용 가능한 스타일로 변환합니다:

| 내보내기 | 대상 | 설명 | |----------|------|------| | webTokens | Next.js / React DOM | typography (px 문자열) + shadows (box-shadow 문자열) | | nativeTokens | React Native | typography (숫자 + 문자열 fontWeight) + shadows (RN 속성) |


사용법

React Native (tfg-app)

import { nativeTokens, colors, spacing, radius } from 'tfg-design-system'
import { StyleSheet } from 'react-native'

const styles = StyleSheet.create({
  // Typography — 텍스트 스타일에 직접 스프레드
  heading: {
    ...nativeTokens.typography.heading,
    // → { fontSize: 20, lineHeight: 28, letterSpacing: -0.5,
    //     fontWeight: '600', fontFamily: 'Pretendard-SemiBold',
    //     includeFontPadding: false }
    color: colors.greyScale.grey_900,
  },

  body: {
    ...nativeTokens.typography.body,
    // → { fontSize: 16, lineHeight: 21.76, fontWeight: '400', ... }
    color: colors.greyScale.grey_700,
  },

  // Shadows — 컨테이너 스타일에 직접 스프레드
  card: {
    ...nativeTokens.shadows.normal,
    // → { shadowColor: 'rgba(0,0,0,0.05)', shadowOffset: {width:0, height:2},
    //     shadowOpacity: 1, shadowRadius: 8, elevation: 4 }
    backgroundColor: colors.background.normal,
    borderRadius: radius.md,          // 12
    padding: spacing[8],              // 16
  },

  // 색상 직접 사용
  primaryButton: {
    backgroundColor: colors.primary.main, // '#7FFFFF'
    borderRadius: radius.sm,              // 8
  },
})

사용 가능한 타이포그래피 변형

| Key | fontSize | fontWeight | lineHeight | |-----|----------|-----------|-----------| | display1 | 56 | 400 | 64.4 | | display2 | 40 | 400 | 48 | | title1 | 36 | 600 | 45 | | title2 | 28 | 600 | 36.4 | | title3 | 24 | 400 | 32.4 | | heading | 20 | 600 | 28 | | body | 16 | 400 | 21.76 | | label | 14 | 400 | 19.32 | | caption | 12 | 400 | 16.32 | | tiny | 10 | 400 | 13.6 |

fontWeight 토큰으로 다른 굵기 적용: { ...nativeTokens.typography.body, fontWeight: '600', fontFamily: 'Pretendard-SemiBold' }


Next.js / CSS (tfg-web)

import { webTokens, colors, spacing, radius } from 'tfg-design-system'
import type { CSSProperties } from 'react'

// Typography — React.CSSProperties로 직접 사용
const headingStyle: CSSProperties = {
  ...webTokens.typography.heading,
  // → { fontSize: '20px', lineHeight: '28px', letterSpacing: '-0.5px',
  //     fontWeight: 600, fontFamily: 'Pretendard Variable, ...' }
  color: colors.greyScale.grey_900,
}

// Shadow — CSS box-shadow 값으로 사용
const cardStyle: CSSProperties = {
  boxShadow: webTokens.shadows.normal,
  // → '0px 2px 8px rgba(0, 0, 0, 0.05)'
  backgroundColor: colors.background.normal,
  borderRadius: `${radius.md}px`,
  padding: `${spacing[8]}px`,
}

// CSS Modules / Tailwind 커스텀 값
export const cssVars = {
  '--color-primary': colors.primary.main,
  '--shadow-card': webTokens.shadows.normal,
  '--font-body': webTokens.typography.body.fontSize,
}

사용 가능한 그림자 변형

| 키 | CSS 출력 | |----|---------| | normal | 0px 2px 8px rgba(0, 0, 0, 0.05) | | emphasize | 2px 4px 10px rgba(0, 0, 0, 0.078) | | strong | 0px 2px 10px rgba(0, 0, 0, 0.239) | | heavy | 0px 2px 10px rgba(0, 0, 0, 0.322) | | normalBottom | 0px -4px 4px rgba(0, 0, 0, 0.251) |


플랫폼 차이점

| 속성 | React Native | CSS / Next.js | |------|-------------|--------------| | fontSize | number (예: 16) | string (예: '16px') | | lineHeight | number 절대 px | string (예: '21.76px') | | fontWeight | string ('600') | number (600) | | letterSpacing | number px | string px | | fontFamily | 파일명 ('Pretendard-SemiBold') | CSS명 ('Pretendard Variable') | | shadow | shadowColor + shadowOffset + shadowOpacity + shadowRadius + elevation | box-shadow: X Y blur rgba(...) | | includeFontPadding | false (Android 전용) | ❌ 해당 없음 |

핵심: React Native에서 fontWeight는 반드시 string ('400', '600')이어야 하며, number가 아닙니다. nativeTokens가 이를 자동으로 처리합니다.


토큰 레퍼런스

색상

import { colors } from 'tfg-design-system'

colors.primary.main        // '#7FFFFF' — 민트 프라이머리
colors.primary.secondary   // '#3FE9DC'
colors.greyScale.grey_900  // '#1A1A1A' — 거의 검정색
colors.greyScale.white     // '#FFFFFF'
colors.line.normal         // '#F7F7F8' — 구분선
colors.line.neutral        // '#EDEDF3'
colors.background.normal   // '#FFFFFF'
colors.background.highlight // '#F4F8FB' — 파란색조 배경
colors.background.muted    // '#CBD6D8' — 은은한 뮤트 배경

// 팔레트
colors.green.green_normal  // '#40BA60'
colors.red.red_50          // '#E31D2E'
colors.blue.blue_100       // '#2979FF'

타이포그래피

import { typography, fontFamily, fontWeight } from 'tfg-design-system'

// 원시 스케일 값 (모두 숫자)
typography.scale.title1
// → { fontSize: 36, lineHeight: 45, letterSpacing: -0.9, fontWeight: 600 }

// 폰트 굵기 (숫자)
fontWeight.regular   // 400
fontWeight.medium    // 500
fontWeight.semibold  // 600
fontWeight.bold      // 700

// 폰트 패밀리
fontFamily.native.semibold  // 'Pretendard-SemiBold'
fontFamily.web.fallback     // 'Pretendard Variable, Pretendard, ...'

그림자

import { shadows } from 'tfg-design-system'

// 원시 값 (플랫폼 중립적)
shadows.normal
// → { color: '#000000', opacity: 0.05, offsetX: 0, offsetY: 2, blurRadius: 8, ... }

// 플랫폼 어댑터로 스타일 출력:
import { webTokens, nativeTokens } from 'tfg-design-system'

webTokens.shadows.normal          // '0px 2px 8px rgba(0, 0, 0, 0.05)'
nativeTokens.shadows.normal       // { shadowColor: 'rgba(0,0,0,0.05)', shadowOffset: {width:0, height:2}, ... }

Spacing

import { spacing } from 'tfg-design-system'

spacing[0]   // 0
spacing[4]   // 8   (인덱스 × 2, 4px 기반)
spacing[8]   // 16  ← 기본 페이지 패딩
spacing[12]  // 24
spacing[16]  // 32

// React Native:  paddingHorizontal: spacing[8]    → 16
// CSS/Next.js:   padding: `${spacing[8]}px`        → '16px'

Border Radius

import { radius } from 'tfg-design-system'

radius.none   // 0
radius.xs     // 4
radius.sm     // 8   ← 버튼 기본값
radius.md     // 12  ← 카드 기본값
radius.lg     // 16
radius.xl     // 24
radius.full   // 999 — 알약 / 원형

Component Tokens — Button

import { buttonTokens } from 'tfg-design-system'

// Sizes
buttonTokens.size.lg.height           // 56
buttonTokens.size.lg.paddingHorizontal // 16
buttonTokens.size.lg.borderRadius      // 8
buttonTokens.size.lg.fontWeight        // 600

// Variants
buttonTokens.variant.contained.primary.backgroundColor  // '#7FFFFF'
buttonTokens.variant.contained.primary.textColor        // '#000000'
buttonTokens.variant.outlined.primary.borderColor       // '#EDEDF3'
buttonTokens.variant.outlined.primary.borderWidth       // 1

// Toggle
buttonTokens.toggle.track.width           // 51
buttonTokens.toggle.track.active.backgroundColor  // '#7FFFFF'
buttonTokens.toggle.thumb.size            // 27

빌드

# 의존성 설치
npm install

# 빌드 (lib/ 디렉토리에 출력)
npm run build

# 감시 모드 빌드 (개발 중)
npm run build:watch

빌드 결과물은 lib/에 위치합니다:

  • lib/index.js — CommonJS 진입점
  • lib/index.d.ts — TypeScript 선언 파일
  • lib/index.d.ts.map — 선언 소스맵 (IDE go-to-source용)

파일 구조

tfg-design-system/
 ├── src/
 │   ├── tokens/
 │   │   ├── colors.ts          ← 모든 색상 (Figma 시맨틱 + 전체 팔레트)
 │   │   ├── typography.ts      ← 폰트 스케일, 굵기, 패밀리
 │   │   ├── spacing.ts         ← 4px 기반 간격
 │   │   ├── radius.ts          ← 테두리 반지름 값
 │   │   ├── shadows.ts         ← 그림자 원시 값 (Figma 출처)
 │   │   └── index.ts           ← tokens/ 배럴 내보내기
 │   ├── platform/
 │   │   ├── types.ts           ← 공유 TS 타입 (NativeTextStyle 등)
 │   │   ├── web.ts             ← CSS 어댑터 (toPx, toBoxShadow, webTokens)
 │   │   └── native.ts          ← RN 어댑터 (toNativeFontWeight, nativeTokens)
 │   ├── components/
 │   │   └── button.ts          ← 버튼/토글 컴포넌트 토큰
 │   └── index.ts               ← 공개 API — 여기서 import
 ├── lib/                       ← 빌드 결과물 (자동 생성, 직접 수정 금지)
 ├── package.json
 ├── tsconfig.json
 └── README.md

Figma 출처

토큰 값은 Figma → TheFair_Design Library에서 추출됩니다:

| Figma 페이지 | 토큰 카테고리 | |-------------|-------------| | 색상 - Semantic | colors.primary, colors.line, colors.background | | 색상 - Semantic (Elevation) | shadows.* | | 색상 - Semantic (Variable defs) | typography.scale.* | | tfg-app 코드베이스 | colors.palette (green, red, blue 등) |

letterSpacing 공식: fontSize × -0.025 (Figma: fontSize의 −2.5%)