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

@ihab_giihan/core

v0.1.36

Published

Shared package extracted from the speechear project. It contains UI components, shared styles, and common app-level utilities.

Readme

@ihab_giihan/core

Shared package extracted from the speechear project. It contains UI components, shared styles, and common app-level utilities.

개요

이 패키지는 React 기반 UI 컴포넌트와 공용 스타일을 제공합니다. 외부 프로젝트에서 사용할 때는 몇 가지 사용 규칙을 반드시 따라야 합니다 — 아래 **"외부 프로젝트에서 꼭 맞춰야 하는 사용 방식"**을 먼저 읽어주세요.

📦 외부 프로젝트 첫 도입 가이드: CONSUMING.md — 설치/peerDeps, import 경로, 미디어 리졸버 주입, 디자인시스템 vs app/* 구분, i18n 공유 방법.

📚 디자인 시스템 & 개발 시스템 상세 레퍼런스: docs/design-system-reference.md — 토큰(색상·타이포·간격·그림자·z-index), 컴포넌트 47/공개 export 79, 훅 26 카탈로그.

⚠️ BREAKING (다음 메이저): 공개 경로가 @ihab_giihan/core/Example/*@ihab_giihan/core/app/*로 변경되었습니다.

Build

  1. From repository root:
cd packages/core
npm install
npm run build

빌드 결과는 packages/core/dist에 생성됩니다.

외부 프로젝트에서 꼭 맞춰야 하는 사용 방식

  • React 인스턴스 중복 금지: reactreact-dom은 peer dependency입니다. 외부 프로젝트에 동일한 React 인스턴스가 하나만 설치되어 있어야 합니다. 문제가 의심되면 npm ls react로 확인하세요.
  • CSS 임포트 위치와 범위: 컴포넌트 스타일(또는 토큰)이 적용되려면 적절한 시점에 CSS를 import 해야 합니다. 보통 앱 진입점(src/main.tsx 또는 Next.js의 _app.tsx)에서 한 번만 import 합니다.
  • CoreScope 또는 클래스 적용: 패키지 스타일은 .ihab-core-scope 범위 내에서 동작하도록 작성되어 있습니다. 따라서 컴포넌트가 렌더되는 DOM을 반드시 CoreScope로 감싸거나 루트 요소에 ihab-core-scope 클래스를 적용해야 합니다. 예:
import '@ihab_giihan/core/styles.css'
import { CoreScope } from '@ihab_giihan/core'

export default function App(){
	return (
		<CoreScope>
			{/* @ihab_giihan/core 컴포넌트들 */}
		</CoreScope>
	)
}

또는 CoreScope를 사용하지 않는 경우:

import '@ihab_giihan/core/styles.css'

export default function App(){
	return (
		<div className="ihab-core-scope">
			{/* 컴포넌트들 */}
		</div>
	)
}

CSS 사용 옵션 (권장 방식)

  • styles.css (권장): 전체 토큰(커스텀 프로퍼티)과 컴포넌트 스타일이 포함된 파일입니다. 토큰은 :where(.ihab-core-scope){...}에 선언되므로 CoreScope로 감싼 영역에서만 적용됩니다. 토큰과 컴포넌트 스타일 모두 필요하면 styles.css만 import 하세요.
  • components.css (경량): 컴포넌트별 스타일만 포함한 경량 CSS입니다. 이 파일만 import 하면 컴포넌트 룩앤필은 적용되지만 토큰(색상/간격 등)이 필요하면 별도로 styles.css를 함께 import 해야 합니다.

예시:

// 전체 토큰 + 컴포넌트 스타일(권장)
import '@ihab_giihan/core/styles.css'

// 또는 컴포넌트 스타일만 (토큰은 별도)
import '@ihab_giihan/core/components.css'
import '@ihab_giihan/core/styles.css' // 토큰이 필요하면 함께 import

Subpath imports

패키지는 기능별로 subpath를 제공합니다. 예:

import { CoreScope, Button } from '@ihab_giihan/core'
import { Button as CompButton } from '@ihab_giihan/core/components'
import { useMediaQuery } from '@ihab_giihan/core/hooks'
import { speak } from '@ihab_giihan/core/utils'

컴포넌트 전용 엔트리를 사용할 때는 @ihab_giihan/core/components.css를 사용하여 컴포넌트 스타일만 로드할 수 있습니다.

컴포넌트 사용 예시

모든 예시는 CoreScope 또는 ihab-core-scope 클래스 안에서 렌더링되어야 합니다.

Button

import { Button } from '@ihab_giihan/core'

// label prop 방식
<Button variant="default_main" label="저장" onClick={() => {}} />

// children 방식 (label과 동일, label이 있으면 label 우선)
<Button variant="default_main">저장</Button>

// 아이콘 포함
<Button variant="default_main" icon="save" label="저장" />

// 비활성화
<Button variant="default_main" label="처리 중" disabled />

// 토글 버튼
<Button variant="default" label="즐겨찾기" toggleable selected={isFav} onClick={toggle} />

주요 variant 값: default · default_main · default_sub · default_transparent · default_transparent_gray · disabled


Loader

import { Loader } from '@ihab_giihan/core'

// 스피너 (기본)
<Loader />
<Loader size={32} label="불러오는 중..." />

// 프로그레스 바
<Loader variant="bar" progress={67} label="업로드 중..." />

SearchField

import { SearchField } from '@ihab_giihan/core'

const [query, setQuery] = React.useState('')

<SearchField
  value={query}
  onChange={setQuery}
  placeholder="훈련 검색"
  suggestions={['일상 듣기', '소음 훈련', '받아쓰기']}
/>

ProgressIndicator

import { ProgressIndicator } from '@ihab_giihan/core'

// max=5개 단계, 현재 index=2까지 활성화
<ProgressIndicator max={5} index={2} />

Header (AppHeader)

Header는 앱 전체 레이아웃의 사이드 내비게이션입니다. 팝업 타이틀이 아닙니다. 이름 충돌 방지용 AppHeader alias도 제공됩니다.

import { Header, AppHeader } from '@ihab_giihan/core'

const navItems = [
  { key: 'home', label: '홈', icon: 'home' },
  { key: 'training', label: '훈련', icon: 'dumbbell' },
  { key: 'profile', label: '프로필', icon: 'user-round' },
]

<Header
  items={navItems}
  activeKey={currentKey}
  onChange={(key) => navigate(key)}
  onSetting={() => openSettings()}
  onHelp={() => openHelp()}
  onAccount={() => openAccount()}
/>

SideNavFooter

import { SideNavFooter } from '@ihab_giihan/core'

<SideNavFooter
  onSetting={() => openSettings()}
  onHelp={() => openHelp()}
  onAccount={() => openAccount()}
/>

TooltipInfo / TooltipTextBox

import { TooltipInfo, TooltipTextBox } from '@ihab_giihan/core'

// 간단한 툴팁
<TooltipInfo anchorRect={btnRef.current?.getBoundingClientRect()} text="도움말 텍스트" onClose={() => {}} />

// 텍스트박스 툴팁 (글씨 크기 조절, 다크모드 지원)
<TooltipTextBox
  text={['첫 번째 문장입니다.', '두 번째 문장입니다.']}
  anchorRect={anchorRect}
  onClose={() => setOpen(false)}
/>

IconGridMenu

import { IconGridMenu } from '@ihab_giihan/core'

const categories = [
  { key: 'daily', label: '일상', icon: 'coffee' },
  { key: 'noise', label: '소음', icon: 'volume-2' },
  { key: 'story', label: '이야기', icon: 'book-open' },
]

<IconGridMenu
  categories={categories}
  selected={selectedKey}
  onSelect={(key) => setSelectedKey(key)}
/>

PaymentPlan

import { PaymentPlan, type PaymentPlanData } from '@ihab_giihan/core'

const plan: PaymentPlanData = {
  id: 'pro',
  title: '프로',
  subtitle: '개인 집중 훈련',
  quote: '가장 인기',
  colorToken: 'main',
  recommendedFor: ['집중 훈련이 필요한 분', '매일 꾸준히 연습하고 싶은 분'],
  features: ['모든 훈련 모듈', '무제한 이용', '통계 분석'],
  tiers: [
    { id: 'monthly', label: '월간', price: '9,900원', badge: '추천' },
    { id: 'yearly', label: '연간', price: '89,000원', badge: '2개월 무료' },
  ],
}

<PaymentPlan plan={plan} period="monthly" onSelect={(tier) => handleSelect(tier)} />

NoiseTrainingPagePopup

소음 훈련 팝업입니다. trainingData.contexts에 문장 배열을 전달하세요.

import { NoiseTrainingPagePopup, type TrainingData } from '@ihab_giihan/core'

const trainingData: TrainingData = {
  id: 'noise-01',
  title: '카페 소음 훈련',
  contexts: [
    { sentence: '오늘 날씨가 정말 좋습니다.', contextCode: 'ctx_001' },
    { sentence: '회의가 3시에 시작됩니다.', contextCode: 'ctx_002' },
  ],
}

<NoiseTrainingPagePopup
  trainingData={trainingData}
  popupTitle="소음 훈련"
  onResult={(result) => console.log('점수:', result?.score)}
  onClose={() => setOpen(false)}
  onBack={() => goBack()}
/>

contexts는 소음 훈련 전용입니다. 일반 선택형 훈련은 TrainingPagePopup + items 배열을 사용하세요.


Effect_PartyPopper

훈련 완료 등 성공 이벤트에 사용할 수 있는 폭죽 애니메이션입니다.

import { Effect_PartyPopper } from '@ihab_giihan/core'

<Effect_PartyPopper
  active={showConfetti}
  count={60}
  duration={2500}
  onComplete={() => setShowConfetti(false)}
/>

배포·사용 권장 사항 (Exports · 타입 · 자원 · 스코핑)

아래는 패키지를 외부 프로젝트에서 안정적으로 사용하기 위한 권장 설정과 예시입니다.

  • 일관된 Exports: 소스는 명시적 named-export(export * from './components')를 사용합니다. 소비자에서는 가능한 한 named import를 권장합니다:
// 권장 (tree-shake 가능)
import { CoreScope, Button } from '@ihab_giihan/core'

// 서브패스 사용 (필요시)
import { Button } from '@ihab_giihan/core/components'
  • ESM / CJS 일관성: 번들(ESM)과 CommonJS(CJS)는 같은 named export를 제공합니다. 기본 사용법은 named import 또는 네임스페이스 import입니다.
import { Button, CoreScope } from '@ihab_giihan/core'
import * as Core from '@ihab_giihan/core'

기본 export는 하위 호환용 오브젝트로 제공되지만, 새 코드에서는 Core.default 같은 접근에 의존하지 말고 위 두 패턴을 권장합니다.

  • 타입 선언 (d.ts) 서브패스: 각 subpath에 대한 .d.tsdist/packages/core/src/*.d.ts에 생성됩니다. package.jsonexports에는 subpath별 types가 매핑되어 있어 TypeScript에서 다음처럼 인식됩니다:
import { Button } from '@ihab_giihan/core/components' // types available
  • 정적 자원(logo 등): 빌드 시 레포 루트 logo/ 디렉터리(존재하는 경우)를 dist/logo/로 복사합니다. 패키지 내부 절대경로에 직접 의존하지 않도록 setAssetBaseUrl() API를 제공합니다.
import { setAssetBaseUrl } from '@ihab_giihan/core'

setAssetBaseUrl('https://cdn.example.com/ihab-assets')

이후 패키지 내부 로고/배경 이미지는 위 베이스 URL을 기준으로 해석됩니다. 소비자에서 로고를 사용하려면 권장 순서는:

  1. 앱의 퍼블릭(public) 디렉터리에 로고를 두고 호스팅
  2. 패키지에 포함된 로고를 직접 사용하려면(비권장) import LogoUrl from '@ihab_giihan/core/dist/logo/Logo_speechear.svg' 처럼 소비자의 번들러가 처리하도록 import

패키지 내 exports"./logo/*": "./dist/logo/*" 매핑을 추가했으나, 번들러/런타임 환경에 따라 서브패스 접근이 제한될 수 있으니 퍼블릭 호스팅을 우선 권장합니다.

  • CSS 스코핑 (CoreScope): 이 패키지는 .ihab-core-scope 네임스페이스로 스타일을 범위화합니다. 권장 사용법:
import '@ihab_giihan/core/styles.css'
import { CoreScope } from '@ihab_giihan/core'

export default function App(){
	return (
		<CoreScope>
			{/* 컴포넌트 */}
		</CoreScope>
	)
}

충돌 회피 팁:

  • 전역 클래스 네임이나 토큰 이름을 피하고 ihab-core- 접두어를 유지하세요.

  • 다른 라이브러리와 네임 충돌이 우려된다면, 상위 요소에 추가 클래스를 부여하고 더 구체적인 선택자를 사용하세요.

  • default 의존 지양: 하위 호환용 default export가 존재하더라도 새 코드에서는 명시적 named import 또는 import * as Core를 우선 권장합니다.

  • 긴급 폴백 export: 소비자에서 자주 찾는 TrainingPagePopupBottom, TrainingPagePopupTitle는 루트 및 components 엔트리에서 직접 가져올 수 있습니다.

import { TrainingPagePopupBottom, TrainingPagePopupTitle } from '@ihab_giihan/core'

위 가이드들은 소비자 프로젝트의 번들러(ESBuild/Vite/Webpack) 설정과 타겟 런타임에 따라 조정될 수 있습니다.

Exports / Bundling 참고

  • 패키지 package.json에는 ./components.css 같은 subpath export가 추가되어 있어 import '@ihab_giihan/core/components.css'로 불러올 수 있습니다.
  • 번들러가 CSS를 제거(tree-shake)하지 않도록 sideEffects: ["dist/**/*.css"]가 설정되어 있습니다. 번들러 설정에 따라 CSS를 명시적으로 import해야 합니다.

Server-side rendering (Next.js / SSR) 사용 시 주의

  • 서버 사이드에서 CSS를 import 하면 빌드에 포함되어 렌더 차이가 날 수 있습니다. Next.js에서는 보통 _app.tsx에서 CSS를 import 하거나 클라이언트 전용 컴포넌트에서 import 하세요.
  • 클라이언트 전용 의존성(window, document)이 필요한 컴포넌트는 클라이언트에서만 렌더링되도록 처리하세요.

예시(Next.js _app.tsx):

import '../styles/globals.css'
import '@ihab_giihan/core/styles.css'
import type { AppProps } from 'next/app'

export default function App({ Component, pageProps }: AppProps) {
	return <Component {...pageProps} />
}

로컬 테스트 및 퍼블리시 가이드

  1. 패키지 빌드 & tarball 테스트:
cd packages/core
npm install
npm run build
npm pack
# 생성된 tarball을 테스트 프로젝트에 설치
npm install /absolute/path/to/packages/core/ihab_giihan-core-0.1.4.tgz
  1. 퍼블리시(권장 전 검증 완료 후):
cd packages/core
npm run build
# 버전 변경 (예: patch)
npm version patch
npm publish --access public

문제 해결 (Troubleshooting)

  • 스타일이 적용되지 않음: styles.css를 import했는지 확인하고, CoreScope로 감싸거나 루트에 ihab-core-scope 클래스를 적용했는지 확인하세요.
  • 토큰(커스텀 프로퍼티) 값이 보이지 않음: styles.css가 포함되어 있으며 번들러가 해당 CSS를 제거하지 않았는지 확인하세요. (예: sideEffects 설정 확인)
  • 아이콘/패키지 관련 오류: lucide-react 같은 peer dependency를 설치했는지 확인하세요.
  • 로고/이미지가 깨짐: 앱 시작 시 setAssetBaseUrl()을 호출했는지 확인하거나, 필요한 logo/, images/backgrounds/ 자산을 호스트 앱의 public/CDN 경로에 배치하세요.
  • 중복된 React 인스턴스: npm ls react로 의존성 트리를 검사하고, 외부 프로젝트가 동일한 React를 사용하도록 조정하세요.

로컬 예시 (간단한 App)

import React from 'react'
import '@ihab_giihan/core/styles.css'
import { CoreScope, MenuButton } from '@ihab_giihan/core'

export default function App(){
	return (
		<CoreScope>
			<MenuButton item={{ key: 'home', label: 'Home' }} />
		</CoreScope>
	)
}

문서를 더 다듬거나 추가 예시(Next.js/CRA/Vite별 설정)를 원하시면 알려주세요.

CI / 퍼블리시 자동화

패키지에는 빌드·검증용 스크립트와 GitHub Actions 워크플로가 추가되어 있습니다:

  • packages/core/scripts/smoke-test.js — tarball 생성 후 타입체크·SSR 확인을 수행하는 Node 스크립트
  • packages/core/scripts/smoke-test.sh — 빌드·pack·tarball 설치·CSS 스코프 검증을 수행하는 셸 스크립트
  • packages/core/scripts/publish-check.sh — 퍼블리시 전 빌드·pack·검증을 자동으로 수행하는 로컬 스크립트

CI 워크플로:

  • .github/workflows/core-ci.yml — PR/푸시 시 빌드·테스트·smoke-test를 실행합니다.
  • .github/workflows/core-publish.yml — 릴리스 또는 태그 푸시 시 NPM_TOKEN을 사용해 퍼블리시합니다. 퍼블리시용 비밀 키는 NPM_TOKEN으로 저장하세요.

퍼블리시 전 로컬 점검 예시:

# 패키지 루트에서
bash packages/core/scripts/publish-check.sh

자동화 / AI 통합 가이드

다른 프로젝트의 자동화(리팩터 도구, CI, LLM 에이전트 등)가 이 패키지를 안전하게 다루도록 하기 위한 체크리스트와 권장 절차입니다.

핵심 점검 항목

  • 빌드 명령 및 산출물 확인:
# 패키지 빌드
npm --prefix packages/core run build

# 예상 산출물 (packages/core/dist)
# - ihab-core.css (토큰 + 컴포넌트 스타일)
# - components.esm.css / components.cjs.css (컴포넌트 전용 CSS)
# - ihab-core.esm.js, ihab-core.cjs.js, ihab-core.umd.js
# - ihab-core.d.ts
  • CSS 스코핑 규칙: 패키지의 토큰(커스텀 프로퍼티)은 :where(.ihab-core-scope){...}에 선언됩니다. 자동화가 :root를 단순히 .ihab-core-scope :root로 prefix 하지 않도록 주의하세요. PostCSS transform을 수정할 때 아래 매핑을 유지해야 합니다:
// postcss.config.cjs - transform(selector)
if (selector === ':root') return ':where(.ihab-core-scope)'
if (selector === 'html' || selector === 'body' || selector === '#root') return '.ihab-core-scope'
  • 패키지 메타데이터 확인:

    • packages/core/package.jsonexports"./components.css"가 존재하는지 확인.
    • sideEffects"dist/**/*.css"가 포함되어 있어 번들러가 CSS를 제거하지 않도록 합니다.
  • Peer dependencies: 반드시 react, react-dom, lucide-react 등의 peer deps가 소비자 프로젝트에 설치되어야 합니다.

자동화 도구(리팩터/스크립트)를 위한 규칙

  • 절대/상대 경로 및 import 구문을 정규식으로 무분별하게 치환하지 마세요. 구문 손상을 초래할 수 있습니다.
  • 안전 권장 방식: AST 기반 툴 사용(예: ts-morph, jscodeshift, recast) — 문자열 기반 치환 대신 식별자/노드 수준에서 변경합니다.
  • 변경 전 백업 또는 커밋을 남기세요(예: git stash 또는 .bak 파일 생성).
  • 제외 패턴(무시할 것): dist/**, node_modules/**, **/*.bak.

문제 사례 (주의): 자동화가 잘못 적용되면 import Icon./Icon' 같은 구문 오류가 발생합니다. 이런 변경은 AST 검사 또는 TypeScript 빌드로 곧바로 발견됩니다.

CI 스모크 테스트 (권장)

  1. 빌드 및 tarball 검사
cd packages/core
npm run build
npm pack
tar -tzf ihab_giihan-core-*.tgz | rg 'dist/.*\.css' || (echo 'CSS 없음' && exit 1)
  1. 로컬 설치 후 타입 체크
mkdir /tmp/core-test && cd /tmp/core-test
npm init -y
npm install react react-dom lucide-react
npm install /absolute/path/to/ihab_giihan-core-0.1.4.tgz
npx tsc --noEmit
  1. CSS 토큰(스코프) 존재 확인 (간단 문자열 검사)
rg ":where\\(.ihab-core-scope\\)" node_modules/@ihab_giihan/core/dist/ihab-core.css || echo '토큰 스코프 누락'
  1. 선택적 브라우저 스모크: (Playwright/Puppeteer) 짧은 E2E로 CoreScope로 감싼 컴포넌트를 렌더하고 getComputedStyle로 토큰이 있는지 확인하세요.

퍼블리시 체크리스트 (자동화 가능)

  • npm --prefix packages/core run build 실행 성공
  • dist에 CSS/JS/d.ts 파일 존재 확인
  • npm pack 생성물에 dist/*.css 포함 확인
  • 패키지 버전 태그(npm version patch|minor|major) 및 CHANGELOG 업데이트
  • npm publish --access public 또는 레지스트리 업로드

자동화 관점 트러블슈팅 요령

  • 빌드 실패(파싱 에러): npm --prefix packages/core run build가 실패하면 최근 변경(diff)을 검사하세요 (git diff / 변경된 파일에서 .bak 탐색).
  • import 구문 깨짐: 자동 리팩터가 원인인 경우, AST 기반 도구로 복구하거나 .bak에서 복사하여 수동 복원하세요.
  • CSS 토큰이 적용되지 않음: packages/core/dist/ihab-core.css:where(.ihab-core-scope)가 포함되어 있는지 확인하세요. 포함되어 있지 않다면 postcss.config.cjs의 transform 규칙을 검토하세요.

위 체크리스트는 자동화 에이전트(LLM/봇)나 CI 파이프라인이 이 패키지를 안전하게 변경·검증할 수 있도록 고안되었습니다. 자동화용 추가 스크립트(예: smoke-test 스크립트, Pack 검사 스크립트)를 원하시면 만들어 드리겠습니다.