krds-react-components
v2.0.1
Published
Korea Responsive Design System React Components
Downloads
401
Maintainers
Readme
KRDS React Components
KRDS(Korea Responsive Design System)는 대한민국 디지털 정부를 위한 React 컴포넌트 라이브러리입니다. 반응형, 접근성을 갖춘 UI/UX를 빠르고 일관되게 개발할 수 있도록 지원합니다.
📦 설치
npm install krds-react-components styled-components
# 또는
yarn add krds-react-components styled-components
# 또는
pnpm add krds-react-components styled-components🚀 Next.js에서 사용하기 (Step by Step)
1단계: 프로젝트 생성 및 패키지 설치
# Next.js 프로젝트 생성 (TypeScript 사용 권장)
npx create-next-app@latest my-gov-app --typescript --tailwind --app
# 프로젝트 디렉토리로 이동
cd my-gov-app
# KRDS React Components와 의존성 설치
npm install krds-react-components styled-components
# TypeScript용 타입 정의 설치
npm install -D @types/styled-components2단계: Next.js Config 설정 (next.config.js)
/** @type {import('next').NextConfig} */
const nextConfig = {
compiler: {
// styled-components SSR 지원
styledComponents: true,
},
transpilePackages: ['krds-react-components'],
}
module.exports = nextConfig3단계: ThemeProvider 설정 (app/providers.tsx)
'use client'
import React from 'react'
import { ThemeProvider as KRDSThemeProvider, GlobalStyles, lightTheme } from 'krds-react-components'
import { ThemeProvider as StyledThemeProvider } from 'styled-components'
export function Providers({ children }: { children: React.ReactNode }) {
return (
<StyledThemeProvider theme={lightTheme}>
<KRDSThemeProvider initialMode="light">
<GlobalStyles />
{children}
</KRDSThemeProvider>
</StyledThemeProvider>
)
}4단계: 루트 레이아웃 설정 (app/layout.tsx)
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import { Providers } from './providers'
import './globals.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: '정부 웹사이트',
description: 'KRDS React Components를 사용한 정부 웹사이트',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="ko">
<body className={inter.className}>
<Providers>
{children}
</Providers>
</body>
</html>
)
}5단계: 메인 페이지에서 컴포넌트 사용 (app/page.tsx)
'use client'
import { useState } from 'react'
import {
Header,
Footer,
Layout,
Button,
Input,
Select,
Alert,
Card,
Table
} from 'krds-react-components'
export default function Home() {
const [formData, setFormData] = useState({
name: '',
email: '',
region: ''
})
const navigationItems = [
{ id: 'home', label: '홈', href: '/' },
{ id: 'services', label: '서비스', href: '/services' },
{ id: 'support', label: '민원신청', href: '/support' },
{ id: 'info', label: '정보공개', href: '/info' }
]
const regions = [
{ value: 'seoul', label: '서울특별시' },
{ value: 'busan', label: '부산광역시' },
{ value: 'daegu', label: '대구광역시' },
{ value: 'incheon', label: '인천광역시' }
]
const tableData = [
{ id: 1, title: '시스템 점검 안내', date: '2024-08-14', status: '진행중' },
{ id: 2, title: '신청 서비스 개선', date: '2024-08-13', status: '완료' },
{ id: 3, title: '보안 업데이트', date: '2024-08-12', status: '예정' }
]
const tableColumns = [
{ key: 'title', title: '제목', dataIndex: 'title' },
{ key: 'date', title: '날짜', dataIndex: 'date' },
{ key: 'status', title: '상태', dataIndex: 'status' }
]
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
alert(`제출 완료: ${JSON.stringify(formData, null, 2)}`)
}
return (
<Layout>
{/* 헤더 */}
<Header
logo={{ text: '정부24', href: '/' }}
navigation={navigationItems}
/>
<main style={{ padding: '2rem 0', minHeight: 'calc(100vh - 200px)' }}>
<div style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 2rem' }}>
{/* 페이지 제목 */}
<div style={{ textAlign: 'center', marginBottom: '3rem' }}>
<h1>KRDS React Components</h1>
<p>Next.js에서 한국 반응형 디자인 시스템 사용하기</p>
</div>
{/* 알림 */}
<Alert
variant="info"
title="환영합니다!"
style={{ marginBottom: '2rem' }}
>
KRDS React Components를 Next.js에서 사용하는 예시입니다.
</Alert>
{/* 폼 섹션 */}
<div style={{ marginBottom: '3rem' }}>
<h2>신청 폼 예시</h2>
<form onSubmit={handleSubmit} style={{ maxWidth: '500px' }}>
<Input
label="이름"
value={formData.name}
onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
placeholder="이름을 입력하세요"
required
style={{ marginBottom: '1rem' }}
/>
<Input
label="이메일"
type="email"
value={formData.email}
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
placeholder="이메일을 입력하세요"
required
style={{ marginBottom: '1rem' }}
/>
<Select
label="지역"
options={regions}
value={formData.region}
onChange={(value) => setFormData(prev => ({ ...prev, region: value }))}
placeholder="지역을 선택하세요"
required
style={{ marginBottom: '1.5rem' }}
/>
<div style={{ display: 'flex', gap: '1rem' }}>
<Button type="submit" variant="primary">
제출하기
</Button>
<Button
type="button"
variant="secondary"
onClick={() => setFormData({ name: '', email: '', region: '' })}
>
초기화
</Button>
</div>
</form>
</div>
{/* 테이블 섹션 */}
<div style={{ marginBottom: '3rem' }}>
<h2>공지사항</h2>
<Table
columns={tableColumns}
dataSource={tableData}
caption="공지사항 목록"
/>
</div>
{/* 버튼 그룹 */}
<div style={{ marginBottom: '3rem' }}>
<h2>버튼 예시</h2>
<div style={{ display: 'flex', gap: '1rem', flexWrap: 'wrap' }}>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="tertiary">Tertiary</Button>
<Button variant="text">Text</Button>
<Button loading>Loading</Button>
<Button disabled>Disabled</Button>
</div>
</div>
</div>
</main>
{/* 푸터 */}
<Footer
copyright="© 2024 정부24. All rights reserved."
links={[
{ label: '이용약관', href: '/terms' },
{ label: '개인정보처리방침', href: '/privacy' },
{ label: '접근성 정책', href: '/accessibility' }
]}
/>
</Layout>
)
}6단계: 프로젝트 실행
# 개발 서버 실행
npm run dev
# 빌드 (배포 전 확인)
npm run build
# 빌드된 프로젝트 실행
npm start7단계: TypeScript 설정 최적화 (tsconfig.json)
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "es6"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}8단계: 스타일드 컴포넌트 레지스트리 설정 (선택사항)
SSR 스타일 이슈 해결을 위한 설정:
app/lib/registry.tsx
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({
children,
}: {
children: React.ReactNode
}) {
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}</>
})
if (typeof window !== 'undefined') return <>{children}</>
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}app/layout.tsx 업데이트
import StyledComponentsRegistry from './lib/registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="ko">
<body className={inter.className}>
<StyledComponentsRegistry>
<Providers>
{children}
</Providers>
</StyledComponentsRegistry>
</body>
</html>
)
}
## 빠른 시작
### 1. 기본 설정
외부 앱에서 KRDS를 사용하려면 먼저 ThemeProvider와 GlobalStyles를 설정해야 합니다.
```tsx
import React from 'react'
import { ThemeProvider } from 'styled-components'
import { lightTheme, GlobalStyles } from 'krds-react-components'
function App() {
return (
<ThemeProvider theme={lightTheme}>
<GlobalStyles />
<div className="App">
{/* 여기에 앱 컨텐츠 */}
</div>
</ThemeProvider>
)
}
export default App2. 폰트 설정
PretendardGOV 폰트는 패키지에 자동으로 포함되어 있습니다. 추가 설정이 필요하지 않습니다.
참고: 인터넷 연결이 필요한 CDN 기반 폰트를 사용합니다. 오프라인 환경에서는 별도 폰트 설정이 필요할 수 있습니다.
3. 기본 컴포넌트 사용
import { Button, Input, Alert } from 'krds-react-components'
function MyPage() {
return (
<div>
<Alert variant="info" title="안내">
KRDS 컴포넌트 라이브러리에 오신 것을 환영합니다.
</Alert>
<Input
label="이름"
placeholder="이름을 입력하세요"
required
/>
<Button variant="primary" size="large">
제출하기
</Button>
</div>
)
}컴포넌트 상세 사용법
Layout Components
Header - 정부 사이트 표준 헤더
import { Header } from 'krds-react-components'
function App() {
const navigationItems = [
{ id: 'home', label: '홈', href: '/' },
{ id: 'about', label: '소개', href: '/about' },
{ id: 'services', label: '서비스', href: '/services' }
]
const userInfo = {
name: '홍길동',
department: '행정안전부',
isLoggedIn: true
}
return (
<Header
siteName="정부 웹사이트"
logoSrc="/logo.png"
navigationItems={navigationItems}
userInfo={userInfo}
showLanguageSwitcher
onLogoClick={() => window.location.href = '/'}
/>
)
}Footer - 정부 사이트 표준 푸터
import { Footer } from 'krds-react-components'
function App() {
const footerSections = [
{
title: '관련 사이트',
links: [
{ label: '정부24', href: 'https://gov.kr' },
{ label: '국민신문고', href: 'https://epeople.go.kr' }
]
}
]
return (
<Footer
siteName="행정안전부"
address="서울특별시 종로구 세종대로 209"
phone="02-2100-3000"
sections={footerSections}
showAccessibility
/>
)
}Data Display Components
Table - 데이터 테이블
import { Table } from 'krds-react-components'
function DataPage() {
const columns = [
{
key: 'name',
title: '이름',
dataIndex: 'name',
width: '20%'
},
{
key: 'department',
title: '부서',
dataIndex: 'department'
},
{
key: 'position',
title: '직책',
dataIndex: 'position'
},
{
key: 'action',
title: '작업',
dataIndex: 'action',
render: (_, record) => (
<Button size="small" onClick={() => handleEdit(record.id)}>
수정
</Button>
)
}
]
const data = [
{ id: 1, name: '홍길동', department: '행정안전부', position: '과장' },
{ id: 2, name: '김철수', department: '국토교통부', position: '주무관' }
]
return (
<Table
columns={columns}
dataSource={data}
caption="직원 목록 테이블"
bordered
striped
hoverable
/>
)
}Tab - 탭 인터페이스
import { Tab } from 'krds-react-components'
function ContentPage() {
const items = [
{
key: 'notice',
label: '공지사항',
content: (
<div>
<h3>최신 공지사항</h3>
<p>시스템 점검 안내...</p>
</div>
)
},
{
key: 'data',
label: '자료실',
content: (
<div>
<h3>다운로드 자료</h3>
<ul>
<li>사용자 가이드.pdf</li>
<li>API 문서.pdf</li>
</ul>
</div>
)
},
{
key: 'faq',
label: 'FAQ',
content: <div>자주 묻는 질문들...</div>
}
]
return (
<Tab
items={items}
defaultActiveKey="notice"
variant="line"
onChange={(key) => console.log('Active tab:', key)}
/>
)
}Accordion - 아코디언
import { Accordion } from 'krds-react-components'
function FAQPage() {
const items = [
{
key: 'faq1',
header: '서비스 이용 시간은 어떻게 되나요?',
content: (
<div>
<p>24시간 연중무휴로 서비스를 제공합니다.</p>
<p>단, 매주 일요일 새벽 2시~6시는 시스템 점검 시간입니다.</p>
</div>
)
},
{
key: 'faq2',
header: '비밀번호를 잊어버렸어요',
content: (
<div>
<p>로그인 페이지에서 '비밀번호 찾기'를 클릭하세요.</p>
<ol>
<li>본인 확인 절차를 진행합니다</li>
<li>등록된 이메일로 임시 비밀번호를 발송합니다</li>
<li>로그인 후 비밀번호를 변경하세요</li>
</ol>
</div>
)
}
]
return (
<Accordion
items={items}
multiple
bordered
collapsible
/>
)
}Navigation Components
Breadcrumb - 브레드크럼
import { Breadcrumb } from 'krds-react-components'
function DetailPage() {
const items = [
{ label: '홈', href: '/' },
{ label: '공지사항', href: '/notice' },
{ label: '시스템 점검 안내' }
]
return (
<Breadcrumb
items={items}
showHome
separator=">"
maxItems={4}
/>
)
}Pagination - 페이지네이션
import { Pagination } from 'krds-react-components'
function ListPage() {
const [currentPage, setCurrentPage] = useState(1)
const totalPages = 20
return (
<div>
{/* 리스트 내용 */}
<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={setCurrentPage}
showFirstLast
showPrevNext
maxPageButtons={5}
/>
</div>
)
}Feedback Components
Modal - 모달 다이얼로그
import { Modal, Button } from 'krds-react-components'
function ActionPage() {
const [isDeleteOpen, setIsDeleteOpen] = useState(false)
const [isInfoOpen, setIsInfoOpen] = useState(false)
const handleDelete = () => {
// 삭제 로직
setIsDeleteOpen(false)
}
return (
<div>
<Button onClick={() => setIsDeleteOpen(true)} variant="danger">
삭제
</Button>
<Button onClick={() => setIsInfoOpen(true)} variant="secondary">
정보 보기
</Button>
{/* 확인 모달 */}
<Modal
open={isDeleteOpen}
title="삭제 확인"
size="small"
onClose={() => setIsDeleteOpen(false)}
footer={
<div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>
<Button variant="secondary" onClick={() => setIsDeleteOpen(false)}>
취소
</Button>
<Button variant="danger" onClick={handleDelete}>
삭제
</Button>
</div>
}
>
<p>정말로 이 항목을 삭제하시겠습니까?</p>
<p>삭제된 데이터는 복구할 수 없습니다.</p>
</Modal>
{/* 정보 모달 */}
<Modal
open={isInfoOpen}
title="상세 정보"
size="medium"
onClose={() => setIsInfoOpen(false)}
>
<div>
<h4>서비스 안내</h4>
<p>본 서비스는 정부24와 연계하여 제공됩니다.</p>
</div>
</Modal>
</div>
)
}Form 통합 예제
import {
Input, Select, Checkbox, Radio, Textarea, Switch, Button, Alert
} from 'krds-react-components'
function RegisterForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
region: '',
gender: '',
agreement: false,
notifications: true,
description: ''
})
const [errors, setErrors] = useState({})
const regions = [
{ value: 'seoul', label: '서울특별시' },
{ value: 'busan', label: '부산광역시' },
{ value: 'daegu', label: '대구광역시' },
{ value: 'incheon', label: '인천광역시' }
]
const handleSubmit = (e) => {
e.preventDefault()
// 폼 제출 로직
}
return (
<form onSubmit={handleSubmit}>
<Alert variant="info" title="회원가입 안내">
모든 필수 항목을 입력해주세요.
</Alert>
<Input
label="이름"
value={formData.name}
onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
required
state={errors.name ? 'error' : undefined}
errorMessage={errors.name}
/>
<Input
label="이메일"
type="email"
value={formData.email}
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
required
state={errors.email ? 'error' : undefined}
errorMessage={errors.email}
/>
<Select
label="지역"
options={regions}
value={formData.region}
onChange={(value) => setFormData(prev => ({ ...prev, region: value }))}
placeholder="지역을 선택하세요"
required
/>
<fieldset>
<legend>성별</legend>
<Radio
name="gender"
value="male"
label="남성"
checked={formData.gender === 'male'}
onChange={(value) => setFormData(prev => ({ ...prev, gender: value }))}
/>
<Radio
name="gender"
value="female"
label="여성"
checked={formData.gender === 'female'}
onChange={(value) => setFormData(prev => ({ ...prev, gender: value }))}
/>
</fieldset>
<Textarea
label="자기소개"
value={formData.description}
onChange={(e) => setFormData(prev => ({ ...prev, description: e.target.value }))}
placeholder="간단한 자기소개를 입력하세요"
maxLength={500}
showCount
/>
<Checkbox
label="이용약관에 동의합니다"
checked={formData.agreement}
onChange={(checked) => setFormData(prev => ({ ...prev, agreement: checked }))}
required
/>
<Switch
label="알림 받기"
checked={formData.notifications}
onChange={(checked) => setFormData(prev => ({ ...prev, notifications: checked }))}
checkedLabel="켜짐"
uncheckedLabel="꺼짐"
/>
<div style={{ marginTop: '24px' }}>
<Button type="submit" variant="primary" size="large" fullWidth>
회원가입
</Button>
</div>
</form>
)
}컴포넌트
Button
import { Button } from 'krds-react-components'
<Button variant="primary" size="large">
기본 버튼
</Button>
<Button variant="secondary" disabled>
비활성화 버튼
</Button>
<Button variant="text" loading>
로딩 중...
</Button>Badge
import { Badge } from 'krds-react-components'
<Badge variant="primary">Label</Badge>
<Badge variant="danger" count={5} />
<Badge variant="success" dot />Form Components
Input
import { Input } from 'krds-react-components'
<Input
label="이름"
placeholder="이름을 입력하세요"
required
/>
<Input
label="이메일"
type="email"
state="error"
errorMessage="올바른 이메일을 입력하세요"
/>Checkbox
import { Checkbox } from 'krds-react-components'
<Checkbox label="이용약관 동의" required />
<Checkbox
label="마케팅 수신 동의"
description="선택사항입니다"
/>Radio
import { Radio, RadioGroup } from 'krds-react-components'
<RadioGroup name="gender" defaultValue="male">
<Radio value="male" label="남성" />
<Radio value="female" label="여성" />
<Radio value="other" label="기타" />
</RadioGroup>Select
import { Select } from 'krds-react-components'
<Select
label="지역 선택"
placeholder="지역을 선택하세요"
options={[
{ value: 'seoul', label: '서울' },
{ value: 'busan', label: '부산' },
{ value: 'daegu', label: '대구' }
]}
/>Textarea
import { Textarea } from 'krds-react-components'
<Textarea
label="의견"
placeholder="의견을 입력하세요"
maxLength={500}
showCount
/>Switch
import { Switch } from 'krds-react-components'
<Switch label="알림 받기" />
<Switch
label="다크 모드"
checkedLabel="켜짐"
uncheckedLabel="꺼짐"
/>테마
라이트 모드
기본 테마로 일반적인 사용 환경에 적합합니다.
고대비 모드
시각적 접근성이 필요한 사용자를 위한 테마입니다.
<ThemeProvider initialMode="high-contrast">
<App />
</ThemeProvider>접근성
KRDS React는 웹 접근성 지침(WCAG 2.1)을 준수하여 개발되었습니다:
- 키보드 내비게이션 지원
- 스크린 리더 호환
- 고대비 모드 지원
- 적절한 ARIA 속성
개발
# 개발 서버 시작 (Storybook)
npm run dev
# 빌드
npm run build
# 테스트
npm test
# 린트
npm run lint테마 커스터마이징
기본 테마를 확장하여 사용할 수 있습니다:
import { lightTheme } from 'krds-react-components'
const customTheme = {
...lightTheme,
colors: {
...lightTheme.colors,
primary: {
...lightTheme.colors.primary,
50: '#1a73e8' // 사용자 정의 색상
}
},
spacing: {
...lightTheme.spacing,
custom: '2.5rem' // 사용자 정의 간격
}
}
// ThemeProvider에 customTheme 사용
<ThemeProvider theme={customTheme}>
<App />
</ThemeProvider>고대비 모드
시각적 접근성이 필요한 사용자를 위한 고대비 테마를 제공합니다:
import { highContrastTheme } from 'krds-react-components'
<ThemeProvider theme={highContrastTheme}>
<App />
</ThemeProvider>TypeScript 지원
모든 컴포넌트는 완전한 TypeScript 지원을 제공합니다:
import { ButtonProps, InputProps, TableColumn } from 'krds-react-components'
// 컴포넌트 props 타입 확장
interface CustomButtonProps extends ButtonProps {
customProp?: string
}
// 테이블 컬럼 타입 정의
const columns: TableColumn[] = [
{
key: 'name',
title: '이름',
dataIndex: 'name',
render: (value: string) => <strong>{value}</strong>
}
]패키지 빌드 및 배포
개발환경 설정
# 의존성 설치
npm install
# 개발 서버 시작 (Storybook)
npm run dev
# 빌드
npm run build
# 테스트
npm test
# 린트
npm run lint
# 타입 체크
npm run type-checkNPM 배포
# 빌드
npm run build
# 배포
npm publish다른 프로젝트에서 사용
# 설치
npm install krds-react-components styled-components
# 또는 로컬 개발용
npm install file:../krds-react접근성
KRDS 컴포넌트는 웹 접근성 지침(WCAG 2.1 AA)을 준수합니다:
지원하는 접근성 기능
- 키보드 내비게이션: 모든 인터랙티브 요소는 키보드로 접근 가능
- 스크린 리더 호환: 적절한 ARIA 속성과 시맨틱 마크업 사용
- 색상 대비: WCAG AA 기준 이상의 색상 대비 제공
- 포커스 관리: 명확한 포커스 표시 및 논리적 탭 순서
- 다국어 지원: 한국어 기본, 영어 지원
접근성 사용 예제
// 스크린 리더용 텍스트
<Button>
저장
<span className="sr-only">현재 문서를</span>
</Button>
// ARIA 레이블 사용
<Input
label="검색어"
aria-describedby="search-help"
/>
<div id="search-help">
검색할 키워드를 입력하세요
</div>
// 키보드 단축키 지원
<Modal>
<p>ESC 키를 눌러 모달을 닫을 수 있습니다.</p>
</Modal>브라우저 지원
- Chrome (최신 2개 버전)
- Firefox (최신 2개 버전)
- Safari (최신 2개 버전)
- Edge (최신 2개 버전)
- Internet Explorer 11+
성능 최적화
Tree Shaking
필요한 컴포넌트만 import하여 번들 크기를 최적화할 수 있습니다:
// ✅ 권장: 개별 import
import { Button } from 'krds-react-components/Button'
import { Input } from 'krds-react-components/Input'
// ✅ 가능: 전체 import (Tree shaking 지원)
import { Button, Input } from 'krds-react-components'
// ❌ 비권장: 전체 라이브러리 import
import * as KRDS from 'krds-react-components'코드 분할
import { lazy, Suspense } from 'react'
// 필요한 시점에 로드
const Table = lazy(() => import('krds-react-components/Table'))
function DataPage() {
return (
<Suspense fallback={<div>로딩 중...</div>}>
<Table columns={columns} dataSource={data} />
</Suspense>
)
}문제 해결
스타일이 적용되지 않는 경우
- ThemeProvider가 올바르게 설정되었는지 확인
- GlobalStyle이 포함되었는지 확인
- styled-components 버전 호환성 확인
// 올바른 설정
import { ThemeProvider } from 'styled-components'
import { lightTheme, GlobalStyles } from 'krds-react-components'
<ThemeProvider theme={lightTheme}>
<GlobalStyles />
<App />
</ThemeProvider>TypeScript 오류
- @types/styled-components 설치 확인
- tsconfig.json 설정 확인
{
"compilerOptions": {
"jsx": "react-jsx",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
}
}라이센스
MIT License
기여하기
- 이 저장소를 Fork합니다
- 기능 브랜치를 생성합니다 (
git checkout -b feature/amazing-feature) - 변경사항을 커밋합니다 (
git commit -m 'Add some amazing feature') - 브랜치에 Push합니다 (
git push origin feature/amazing-feature) - Pull Request를 생성합니다
지원 및 문의
- 이슈 보고: GitHub Issues
- 문서 사이트: KRDS React 문서
- 스토리북: 컴포넌트 카탈로그
- 이메일: [email protected]
변경 이력
v1.0.0 (2025-08-14)
- 🎉 초기 릴리즈
- ✨ 모든 기본 컴포넌트 포함 (Button, Input, Table, Modal 등)
- 🎨 KRDS 디자인 시스템 완전 구현
- ♿ WCAG 2.1 AA 접근성 기준 준수
- 🔧 TypeScript 완전 지원
- 📱 반응형 디자인 지원
- 🌙 라이트/고대비 테마 지원
- 📚 Storybook 문서화
