@designbasekorea/ui-wc
v0.8.11
Published
Designbase Web Components 및 React wrapper — 앱·마케팅·AI 채팅·인증 UI 라이브러리
Readme
@designbasekorea/ui-wc
Designbase Web Components — Vue 3, Angular, React, vanilla HTML에서 공통으로 사용하는 웹 컴포넌트 라이브러리입니다.
100여 개의 커스텀 엘리먼트를 제공하며, React 전용 wrapper(@designbasekorea/ui-wc/react)도 포함합니다.
품질 규격
이 라이브러리의 컴포넌트는 접근성·웹표준·성능·DX·UX 규격을 기준으로 개발·평가됩니다.
| 문서 | 용도 | |---|---| | 품질 규격 | 규칙 정의 (P0/P1/P2, 규칙 ID) | | 컴포넌트 체크리스트 | 컴포넌트 작업 시 복사해 쓰는 체크리스트 | | 스코어카드 | 전체 컴포넌트 자동 채점 결과 | | 런타임 접근성 리포트 | axe-core · 키보드 시나리오 검증 결과 | | 스타일 전략 | Light DOM 결정과 CSS 규약 |
npm run audit:quality # 정적 규격 감사 → docs/quality/SCORECARD.md
npm run audit:axe # axe-core 런타임 접근성 검증 (build 선행 필요)
npm run verify:docs # 문서 ↔ 구현 정합성v0.7.3 업데이트
- Sidebar 프롭 정리:
variant(외형default·wrapper) /theme(색상default·dark·light), 외형별 접힌 폭 - SegmentControl·SearchBar radius를 사이즈별 기본값으로, pill은
appearance옵션으로 분리 - RangeSlider 레이블·마커 간격 및 사이즈별 마커 폰트 정리
- Tabs full-width 리사이즈 시 인디케이터 재계산(ResizeObserver)
- SegmentControl 인디케이터 튐·FloatingActionButton 로딩 스피너 수정
- ui-wc SCSS 독립 관리로 전환
v0.7.1 업데이트
- Sidebar
nav-top·nav·nav-bottom커스텀 내비게이션 슬롯 추가 - React wrapper에서 슬롯을
children으로 전달하는 사용법 문서화 - 커스텀 내비게이션 데모·API 레퍼런스·가이드 최신화
v0.7.0 업데이트
- AI 채팅·채팅방·채팅 위젯을 위한 Chat 컴포넌트 모음 추가
- CookieBanner, Signature, DownloadProgress 추가
- OTP·이메일·전화번호·2단계 인증 컴포넌트 추가
- SectionHero, Testimonial, SectionTestimonials, SectionFaq 레이아웃과 변형 개선
- Sidebar 설정 패널 전환과 메뉴·프로필 인터랙션 개선
- React wrapper, Web Component 속성·이벤트 타입 및 예제 문서 최신화
설치
npm install @designbasekorea/ui-wc @designbasekorea/tokens @designbasekorea/theme기본 사용법
// CSS (필수 — 순서 중요)
import '@designbasekorea/tokens/dist/css/tokens.css';
import '@designbasekorea/theme/dist/css/theme.css';
import '@designbasekorea/ui-wc/dist/index.css';
// 전체 등록 (모든 컴포넌트를 한 번에)
import '@designbasekorea/ui-wc';<db-button variant="primary">저장</db-button>
<db-input label="이메일" placeholder="[email protected]"></db-input>
<db-tabs items='[{"id":"a","label":"홈"},{"id":"b","label":"탐색"}]'></db-tabs>링크 속성은 http:, https:, mailto:, tel: 등 허용된 스킴만 동작합니다. AI 채팅·마크다운의 html 본문은 허용 태그/속성으로 정제되며, 애플리케이션이 직접 Node를 마운트하는 API는 호출자가 신뢰된 콘텐츠만 전달해야 합니다.
트리셰이킹 / 개별 import
빌드 번들 크기를 줄이려면 ./components/* 경로로 개별 임포트합니다. 사용한 컴포넌트만 번들에 포함됩니다.
import '@designbasekorea/tokens/dist/css/tokens.css';
import '@designbasekorea/theme/dist/css/theme.css';
import '@designbasekorea/ui-wc/dist/index.css';
// 필요한 컴포넌트만 임포트
import '@designbasekorea/ui-wc/components/db-button';
import '@designbasekorea/ui-wc/components/db-input';TypeScript에서 클래스를 직접 임포트할 수도 있습니다.
import { DbButton } from '@designbasekorea/ui-wc/components/db-button';React wrapper
import '@designbasekorea/tokens/dist/css/tokens.css';
import '@designbasekorea/theme/dist/css/theme.css';
import '@designbasekorea/ui-wc/dist/index.css';
import { Button, Input, Toggle } from '@designbasekorea/ui-wc/react';
<Button variant="primary" onDbClick={() => save()}>저장</Button>
<Input label="이메일" onChange={e => setValue(e.detail.value)} />
<Toggle checked={agreed} onDbChange={e => setAgreed(e.detail.checked)} />명령형 헬퍼
DOM 없이 JavaScript로 토스트·확인 다이얼로그를 직접 제어합니다.
toast
import { toast } from '@designbasekorea/ui-wc';
// 단축 메서드
toast.success('저장되었습니다');
toast.error('오류가 발생했습니다', { description: '잠시 후 다시 시도하세요' });
toast.warning('용량이 거의 찼습니다');
toast.info('업데이트가 준비됐습니다');
// 전체 옵션
toast({
title: '처리 중…',
status: 'info',
duration: 0, // 0이면 수동으로 닫을 때까지 유지
position: 'bottom-center',
showProgress: true,
});
// 수동 제어
const handle = toast.success('파일 업로드 완료');
handle.close(); // 프로그래밍으로 닫기
// 전체 닫기
toast.dismissAll();
toast.dismissAll('top-right'); // 특정 위치만position 옵션: top-right (기본) · top-left · top-center · bottom-right · bottom-left · bottom-center
confirm
import { confirm } from '@designbasekorea/ui-wc';
// 전역 confirm과 충돌을 피하려면:
import { dbConfirm } from '@designbasekorea/ui-wc';
const ok = await confirm({
title: '정말 삭제하시겠습니까?',
message: '이 작업은 되돌릴 수 없습니다.',
variant: 'danger',
confirmText: '삭제',
cancelText: '취소',
});
if (ok) deleteItem();property 설정 (복합 데이터)
JSON 문자열 속성 대신 JavaScript 배열·객체를 직접 할당할 수 있습니다.
const tabs = document.querySelector('db-tabs');
// 이전 방식 (여전히 동작)
tabs.setAttribute('items', JSON.stringify([{ id: 'a', label: '홈' }]));
// 권장 방식 — property setter
tabs.items = [
{ id: 'home', label: '홈' },
{ id: 'search', label: '탐색' },
];
const navbar = document.querySelector('db-navbar');
navbar.items = [{ label: '소개', href: '/about' }];
navbar.userProfile = { name: '홍길동', avatar: '/avatar.png' };
navbar.userProfile = null; // 프로필 영역 제거property setter를 지원하는 컴포넌트: db-tabs, db-navbar, db-sidebar, db-bottom-navigation, db-tutorial, db-gradient, db-section-feature, db-section-hero, db-section-app-download, db-table
Sidebar 커스텀 내비게이션
db-sidebar의 메인 영역에는 데이터 기반 items·sections와 함께 커스텀 콘텐츠를 넣을 수 있습니다.
nav-top: 스크롤 메뉴 위의 고정 영역nav: 기본 메뉴 뒤의 스크롤 영역nav-bottom: 하단 메뉴 위의 고정 영역
<db-sidebar sections='[{"id":"main","items":[{"id":"home","label":"홈"}]}]'>
<div slot="nav-top">검색 또는 빠른 링크</div>
<div slot="nav" role="tree" aria-label="라이브러리">
<!-- 트리, 폴더, 필터 등 자유로운 UI -->
</div>
<div slot="nav-bottom">동기화 상태</div>
</db-sidebar>React wrapper에서도 최상위 자식에 같은 slot 값을 지정합니다.
<Sidebar sections={sections}>
<LibraryQuickLinks slot="nav-top" />
<LibraryTree slot="nav" />
<SyncStatus slot="nav-bottom" />
</Sidebar>커스텀 영역의 내부 스타일과 상호작용은 사용하는 앱에서 정의하며, 사이드바가 접히면 세 슬롯 모두 숨겨집니다.
폼 통합
db-toggle과 db-select는 formAssociated = true를 지원해 네이티브 <form> 제출에 참여합니다.
<form id="settings-form">
<db-toggle name="notify" value="yes"></db-toggle>
<db-select name="lang" options='[{"value":"ko","label":"한국어"},{"value":"en","label":"English"}]'></db-select>
<button type="submit">저장</button>
</form>document.getElementById('settings-form').addEventListener('submit', e => {
const data = new FormData(e.target);
// data.get('notify') → 'yes' (토글이 켜진 경우)
// data.get('lang') → 'ko'
});
// form.reset() 시 자동 초기화
// form disabled 시 자동 비활성화db-input과 db-textarea는 내부 <input>/<textarea>가 Light DOM에 있어 기존에도 form 제출에 참여하며, 이번 업데이트로 host 엘리먼트에서 네이티브 input/change 이벤트도 발행합니다.
// host 엘리먼트에서 네이티브 이벤트 수신 가능
document.querySelector('db-input').addEventListener('change', e => {
console.log(e.target.value); // e.target === <db-input>
});
document.querySelector('db-input').addEventListener('input', handler);컴포넌트 목록
현재 100개 이상의 컴포넌트를 제공합니다. 전체 목록은 Storybook을 참고하세요.
폼 / 입력
| 태그 | 설명 |
|------|------|
| db-button | 버튼/링크 (variant, size, loading, icon, href 지원) |
| db-input | 텍스트 입력 (password, search, number scrub 지원) |
| db-textarea | 여러 줄 텍스트 입력 |
| db-select | 드롭다운 선택 (단일/다중, 검색 지원) |
| db-checkbox | 체크박스 |
| db-toggle | 토글 스위치 |
| db-radio | 라디오 버튼 |
| db-range-slider | 범위 슬라이더 |
| db-rating | 별점 입력 |
| db-color-picker | 색상 선택기 |
| db-date-picker | 날짜 선택 |
| db-time-picker | 시간 선택 |
| db-search-bar | 검색 바 |
| db-form | 폼 컨테이너 |
피드백 / 오버레이
| 태그 | 설명 |
|------|------|
| db-modal | 모달 다이얼로그 |
| db-confirm | 확인 다이얼로그 |
| db-toast | 토스트 알림 |
| db-tooltip | 툴팁 |
| db-popover | 팝오버 |
| db-drawer | 사이드 드로어 |
| db-bottom-sheet | 하단 시트 |
| db-alert | 인라인 알림 |
| db-banner | 배너 |
| db-backdrop | 배경 오버레이 |
| db-spinner | 로딩 스피너 |
| db-skeleton | 스켈레톤 로더 |
탐색
| 태그 | 설명 |
|------|------|
| db-tabs | 탭 |
| db-navbar | 상단 네비게이션 바 |
| db-sidebar | 사이드바 |
| db-bottom-navigation | 하단 탭 네비게이션 |
| db-breadcrumbs | 브레드크럼 |
| db-pagination | 페이지네이션 |
| db-page-header | 페이지 헤더 |
| db-segment-control | 세그먼트 컨트롤 |
| db-stepper | 단계 진행 |
| db-progress-step | 프로그레스 스텝 |
데이터 표시
| 태그 | 설명 |
|------|------|
| db-table | 테이블 |
| db-card | 카드 |
| db-badge | 뱃지 |
| db-chip | 칩 |
| db-avatar | 아바타 |
| db-stat | 통계 수치 |
| db-timeline | 타임라인 |
| db-list | 리스트 |
| db-empty-state | 빈 상태 |
| db-progress | 진행률 바 |
| db-progressbar | 게이지형 진행바 |
| db-indicator | 단계 표시기 |
| db-countdown | 카운트다운 |
레이아웃
| 태그 | 설명 |
|------|------|
| db-container | 콘텐츠 컨테이너 |
| db-stack | 수직/수평 스택 |
| db-grid · db-grid-item | 그리드 레이아웃 |
| db-divider | 구분선 |
| db-scroll-area | 스크롤 영역 |
| db-split-view | 분할 뷰 |
| db-resizable-panels | 크기 조절 패널 |
| db-masonry | 메이슨리 레이아웃 |
| db-toolbar | 툴바 |
| db-section | 섹션 래퍼 |
미디어
| 태그 | 설명 |
|------|------|
| db-image | 이미지 (lazy load, fallback) |
| db-image-list | 이미지 목록 |
| db-lightbox | 라이트박스 |
| db-carousel | 캐러셀 슬라이더 |
| db-video-player | 비디오 플레이어 |
| db-youtube-player | 유튜브 플레이어 |
| db-audio-player | 오디오 플레이어 |
기타
| 태그 | 설명 |
|------|------|
| db-accordion | 아코디언 |
| db-dropdown | 드롭다운 메뉴 |
| db-context-menu | 컨텍스트 메뉴 |
| db-menu-item | 메뉴 아이템 |
| db-reorder | 드래그 정렬 |
| db-dropzone | 파일 드롭존 |
| db-file-uploader | 파일 업로더 |
| db-code-block | 코드 블록 |
| db-markdown-editor | 마크다운 에디터 |
| db-tutorial | 온보딩 튜토리얼 |
| db-calendar | 달력 |
| db-share | 공유 버튼 |
| db-floating-action-button | FAB |
| db-top-banner | 최상단 배너 |
| db-onboarding-modal | 온보딩 모달 |
| db-label | 레이블 |
| db-logo | 로고 |
| db-gradient | 그라디언트 배경 |
| db-marquee | 마르키 스크롤 |
| db-animation-text | 텍스트 애니메이션 |
| db-animation-background | 배경 애니메이션 |
| db-cursor-follower | 커서 팔로워 |
| db-section-hero | 히어로 섹션 |
| db-section-feature | 피처 섹션 |
| db-section-contact | 문의 섹션 |
| db-section-app-download | 앱 다운로드 섹션 |
| db-app-badge | 앱스토어/구글플레이 뱃지 |
| db-ad-banner | 광고 배너 |
| db-testimonial | 추천사 |
주요 이벤트
모든 커스텀 이벤트는 db- 접두사를 사용하며 bubbles: true, composed: true로 발행됩니다.
| 이벤트 | 발행 컴포넌트 | detail |
|--------|-------------|---------|
| db-click | db-button | — |
| db-input | db-input, db-textarea | { value: string } |
| db-change | db-input, db-textarea, db-select, db-checkbox, db-toggle, db-radio, db-range-slider, db-rating, db-tabs, … | { value } 또는 { checked } |
| db-focus / db-blur | db-input, db-textarea | — |
| db-open / db-close | db-modal, db-drawer, db-bottom-sheet, db-toast, … | — |
| db-confirm / db-cancel | db-confirm | — |
| db-step-change | db-tutorial | { step: number } |
| db-page-change | db-pagination | { page: number } |
| db-sort | db-table | { column, direction } |
| db-select | db-table | { selectedRows } |
db-input, db-textarea는 네이티브 input / change 이벤트도 host에서 함께 발행합니다.
스타일 커스터마이징
Light DOM 기반으로 렌더링되므로 CSS 선택자로 직접 스타일링할 수 있습니다.
/* 글로벌 CSS 변수로 테마 조정 */
:root {
--db-color-primary: #6366f1;
--db-radius-m: 8px;
}
/* 또는 컴포넌트 내부 클래스 직접 스타일링 */
db-button .designbase-wc-button {
font-weight: 700;
}자세한 내용은 docs/STYLING.md.
프레임워크별 가이드
Storybook
npm run storybook
# http://localhost:6007