소개

UI Components

Next.js 16과 React 19로 구현한 UI 컴포넌트 가이드입니다. 마크업과 클래스 조합으로 버튼·폼·피드백·네비게이션 등 50여 개 컴포넌트를 확인할 수 있으며, 컴포넌트 자체는 HTML·CSS만으로도 다른 프로젝트에 적용할 수 있습니다.

개요

Next.js App Router에서 정적 사이트로 사전 렌더링하는 디자인 시스템 문서이자 재사용 가능한 UI 패턴 모음입니다. 각 컴포넌트 페이지에서 라이브 데모, 마크업 예시, 클래스·속성 표, 디자인 토큰을 함께 제공합니다.

  • OOCSS 구조— 블록(.btn) + 파트(.btn_label) + 스킨·크기·상태 클래스를 조합해 사용합니다.
  • 디자인 토큰— 색상·간격·타이포 등은_tokens.scss의 CSS 변수로 관리하며, 라이트/다크 테마를 지원합니다.디자인 토큰문서에서 기본값과 사용 방법을 확인할 수 있습니다.
  • 접근성role· aria-*속성과 키보드·포커스 패턴을 컴포넌트별로 안내합니다.
  • Next.js 정적 사이트Next.js 16 App Router + React 19로 개발하며,output: 'export'설정으로 정적 사이트를 생성합니다. 문서는src/doc/의 JSX 파일로 관리합니다.

기본 React 방식과 Next.js 방식의 차이

기본 React SPA는 브라우저에서 하나의 앱을 실행하고 모든 화면 전환을 처리합니다. 현재 가이드는 Next.js App Router가 문서별 정적 HTML과 메타데이터를 만들고, React가 필요한 데모 상호작용만 담당하도록 구성했습니다.

기본 방식

React SPA

하나의 클라이언트 앱이 화면과 경로를 모두 처리합니다.

시작
index.html · src/main.jsx
경로
React Router에서 처리
출력
Vite → dist/

장점

  • 구조와 설정이 단순합니다.
  • 프레임워크 의존성이 낮고 정적 호스팅이 쉽습니다.

단점

  • 초기 화면이 JavaScript 실행에 의존합니다.
  • 검색·공유 메타데이터와 직접 URL 접근을 별도로 구성해야 합니다.
적합한 경우검색 노출보다 클라이언트 상호작용이 중요한 도구·관리 화면
현재 구성

Next.js

App Router가 정적 HTML과 경로를 만들고 React가 상호작용을 담당합니다.

시작
app/layout.jsx · [[...slug]]/page.jsx
경로
Next.js App Router
출력
Next.js export → out/

장점

  • 문서별 HTML과 메타데이터를 빌드 시 생성합니다.
  • 파일 라우팅·내부 링크·basePath를 Next.js에서 일관되게 관리합니다.

단점

  • 서버·클라이언트 컴포넌트 경계를 구분해야 합니다.
  • 서버 기능은 정적 export에서 사용할 수 없습니다.
적합한 경우검색 가능한 정적 문서·콘텐츠와 점진적인 클라이언트 상호작용

즉, 컴포넌트와 상태 관리는 동일한 React 방식으로 작성하고, 페이지 생성·정적 export·배포 경로 같은 애플리케이션 구조는 Next.js가 담당합니다.

빠른 시작

이 가이드 저장소를 클론한 뒤 의존성을 설치하고 Next.js 개발 서버를 실행합니다. 서버가 시작되면 http://localhost:3000에서 확인할 수 있습니다. 자세한 내용은 설치 및 사용을 참고하세요.

설치 및 사용

# 의존성 설치
pnpm install

# Next.js 개발 서버
pnpm dev

# Next.js 정적 빌드
pnpm build

컴포넌트 카테고리

왼쪽 사이드바에서 컴포넌트를 선택하거나, 아래 카테고리 카드로 바로 이동할 수 있습니다.

이 저장소 구조

App Router가 문서별 정적 경로·HTML·메타데이터를 생성합니다. SCSS·React 문서 소스는 src/에서 관리하며, 정적 export 결과는 out/에 생성됩니다.

app/                                      # Next.js App Router 진입점
├── layout.jsx                             # HTML 루트, 전역 SCSS, 폰트, 공통 metadata
├── not-found.jsx                          # 등록되지 않은 경로에 표시하는 404 페이지
└── [[...slug]]/
    └── page.jsx                           # 모든 문서 URL을 처리하는 catch-all 정적 라우트
                                             · generateStaticParams로 문서 경로 생성
                                             · generateMetadata로 페이지별 metadata 생성

public/                                    # 빌드 과정 없이 URL로 제공되는 정적 파일
└── _assets/images/favicon/                # 브라우저·모바일·PWA용 favicon과 manifest

scripts/
└── deploy-main.sh                         # 정적 빌드 후 main 브랜치 배포를 수행하는 스크립트

src/
├── assets/                                # 소스에서 import하는 폰트·이미지 리소스
│   ├── fonts/pass.woff                    # 가이드에서 사용하는 로컬 웹폰트
│   └── images/                            # 이미지 모듈과 컴포넌트 데모 이미지
│
├── components/                            # 실제 서비스에서도 재사용 가능한 React UI 컴포넌트
│   ├── Button.jsx                         # 단일 컴포넌트 구현 예시
│   ├── Grid.jsx · GridCol.jsx             # Grid 레이아웃 부모·자식 컴포넌트
│   ├── Flex.jsx · FlexItem.jsx            # Flex 레이아웃 부모·자식 컴포넌트
│   └── guide/                             # 문서 사이트 전용 표시 컴포넌트
│       ├── DemoSection.jsx                # 실행 예시와 코드 영역
│       ├── GuideCodeBlock.jsx             # 소스 코드 블록
│       ├── ApiSection.jsx · ApiTable.jsx  # Props·클래스·토큰 API 표
│       └── GuideSidebar.jsx               # 좌측 문서 내비게이션
│
├── context/
│   └── GuideSidebarContext.jsx            # 모바일 사이드바 열림 상태를 공유하는 Context
│
├── data/                                  # 앱 전역에서 사용하는 공통 데이터
│   ├── navigation.js                      # 좌측 메뉴 그룹·라벨·URL·slug 정의
│   ├── doc-registry.js                    # 메뉴를 기반으로 정적 경로와 metadata 생성
│   ├── common-icons.js                    # 공통 Icon SVG path 데이터
│   └── *-demo.js                          # 여러 문서에서 공유하는 데모 데이터
│
├── doc/                                   # 가이드에 렌더링되는 문서 콘텐츠
│   ├── components/                        # URL /components/{slug}의 컴포넌트 문서
│   │   ├── button.jsx                     # Button 설명·실행 예시·API 섹션
│   │   ├── grid.jsx                       # Grid 문서
│   │   └── flex.jsx                       # Flex 문서
│   ├── content/                           # MDX로 작성하는 독립 문서 콘텐츠
│   │   └── repository-structure.mdx       # 소개 페이지의 저장소 구조 코드 블록
│   ├── pages/                             # 소개·설치·디자인 토큰 같은 일반 문서
│   │   ├── intro.jsx
│   │   ├── getting-started.jsx
│   │   └── design-tokens.jsx
│   └── data/                              # 문서별 Props·클래스·토큰·예시 데이터
│       ├── *-api.js                       # 각 컴포넌트 API 표 데이터
│       ├── intro-data.js                  # 소개 페이지 데이터와 코드 예시
│       └── getting-started-data.js        # 설치 및 사용 페이지 데이터
│
├── hooks/                                 # 상태와 DOM 동작을 캡슐화한 React hooks
│   ├── useDemoCode.js                     # 실행된 컴포넌트에서 예시 코드 생성
│   ├── useTheme.js                        # 테마 상태·저장·DOM 속성 관리
│   └── useTabs*.js                        # Tabs 스크롤과 indicator 동작
│
├── layouts/
│   └── GuideLayout.jsx                    # 헤더·사이드바·본문을 조합하는 문서 레이아웃
│
├── legacy/                                # data-* 기반 HTML 데모 초기화 코드
│   ├── overlay-init.js                    # Modal·Popover·Tooltip 등 overlay 초기화
│   ├── carousel-init.js                   # Swiper 기반 Carousel 초기화
│   └── *-init.js                          # 컴포넌트별 DOM 이벤트 초기화
│
├── next/
│   └── DocContent.jsx                     # 문서 로드와 데모 초기화를 담당하는 client 경계
│
├── scss/                                  # 전역 토큰·레이아웃·컴포넌트 스타일
│   ├── main.scss                          # app/layout.jsx가 불러오는 최종 SCSS 진입점
│   ├── _tokens.scss                       # 색상·간격·크기 등 기본 디자인 토큰
│   ├── _themes.scss                       # 라이트·다크 테마별 CSS 변수
│   ├── _utilities.scss                    # Grid·Flex·spacing 등 공통 유틸리티
│   ├── _layout.scss · _sidebar.scss       # 가이드 공통 레이아웃 스타일
│   └── components/
│       ├── _index.scss                    # 컴포넌트 SCSS 모음 진입점
│       └── _{component}.scss              # 컴포넌트별 구조·상태·변형 스타일
│
└── utils/                                 # 컴포넌트와 문서가 공유하는 순수 함수
    ├── doc-loader.js                      # 문서 모듈 import와 docKey 매핑
    ├── format-*-code.js                   # 데모 코드를 읽기 좋게 변환
    ├── normalize-dom-props.js             # React props를 DOM 속성으로 정규화
    └── overlay-*.js                       # overlay 위치·화살표·offset 계산

CNAME                                     # 정적 호스팅에서 사용할 사용자 도메인
README.md                                 # 저장소 소개와 설치·실행 명령
package.json                              # 패키지 정보, 의존성, pnpm 명령
pnpm-lock.yaml                            # 재현 가능한 의존성 버전 잠금
jsconfig.json                             # @/ 경로 별칭과 JavaScript 분석 설정
mdx-components.js                        # MDX 기본 HTML 요소를 가이드 컴포넌트에 연결
next.config.mjs                           # 정적 export·basePath·이미지·Sass·MDX 설정

.next/                                    # Next.js 개발·빌드 캐시 (Git 제외)
node_modules/                             # pnpm으로 설치한 의존성 (Git 제외)
out/                                      # pnpm build가 생성하는 정적 배포 결과 (Git 제외)

컴포넌트 마크업·SCSS는 다른 프로젝트에도 가져다 쓸 수 있습니다. React 데모는src/scss/main.scss를 import해 동일한 디자인 시스템을 공유합니다.

네이밍 · 클래스 규칙

컴포넌트 스타일은 OOCSS 패턴을 따릅니다. 아래 규칙을 익혀 두면 문서와 소스를 일관되게 읽을 수 있습니다.

패턴예시설명
블록.btn · .alert · .empty컴포넌트 루트 구조 클래스
블록_파트.btn_label · .empty_desc하위 요소 (언더스코어 1개)
블록_변형.btn_filled · .alert_sm스킨·크기·레이아웃 변형
color_*.color_primary · .color_danger공통 의미 색상 (여러 컴포넌트에서 재사용)
is-*.is-open · .is-loadingJS·상태 토글 클래스

문서 페이지 구성

컴포넌트 문서는 src/doc/components/의 JSX로 작성합니다. App Router의 선택적 catch-all 페이지가 generateStaticParams로 경로를 만들고 URL에 맞는 문서를 렌더링합니다. 각 문서는 docMeta로 제목과 네비게이션 정보를 관리합니다.

export const docMeta = {
  title: 'Button | UXKM Guide',
  activeNav: 'button',
  pageTitle: 'Button',
};

import Button from '@/components/Button.jsx';
import DemoSection from '@/components/guide/DemoSection.jsx';

export default function ButtonDoc() {
  return (
    <>
      <div className="page_intro">
        <h1>Button</h1>
        <p className="lead">…</p>
      </div>
      <DemoSection headingId="basic-heading" title="기본">
        <Button variant="filled" color="primary" label="저장" />
      </DemoSection>
    </>
  );
}