# KRDS Vue > 대한민국 정부 디자인 시스템(KRDS)을 Vue 3와 TypeScript로 구현한 컴포넌트 라이브러리(@krds.ui/vue) 문서입니다. --- # 시작하기 KRDS Vue는 [KRDS(대한민국 정부 디자인 시스템)](https://www.krds.go.kr/html/site/index.html)를 Vue 3 + TypeScript 환경에서 사용할 수 있도록 구현한 컴포넌트 라이브러리입니다. 이 패키지는 **ESM 전용**이며 CommonJS `require()`는 지원하지 않습니다. ## 설치 ```sh [pnpm] pnpm add @krds.ui/vue ``` ```sh [npm] npm install @krds.ui/vue ``` ```sh [yarn] yarn add @krds.ui/vue ``` ## 스타일 애플리케이션 엔트리에서 스타일을 한 번 import합니다. CSS 안의 아이콘 URL은 패키지의 `dist/img` 자산을 기준으로 상대 경로를 사용합니다. ```ts import '@krds.ui/vue/style' ``` ## 전역 플러그인 등록 ```ts import { createApp } from 'vue' import KrdsVue from '@krds.ui/vue' import '@krds.ui/vue/style' import App from './App.vue' createApp(App).use(KrdsVue).mount('#app') ``` 특정 컴포넌트만 전역 등록할 수도 있습니다. ```ts app.use(KrdsVue, { components: ['KrdsButton', 'KrdsInput', 'KrdsModal'] }) ``` 전역 등록한 컴포넌트의 템플릿 타입 검사·자동완성(Volar/vue-tsc)을 쓰려면 `tsconfig.json`에 전역 타입을 추가합니다. 전체 컴포넌트와 `v-sr-only`, `$krds`가 전역으로 선언되므로 일부만 등록했다면 등록하지 않은 컴포넌트 사용에 주의하세요. ```json { "compilerOptions": { "types": ["@krds.ui/vue/global"] } } ``` WebStorm 등 JetBrains IDE는 이 설정 대신 패키지에 든 `web-types.json`으로 전역 컴포넌트를 인식하므로 따로 설정할 것이 없습니다. ## 개별 컴포넌트 import 전역 등록이 필요 없다면 필요한 컴포넌트만 가져옵니다. 이 문서의 예제도 모두 이 방식으로 작성되어 있어 그대로 복사해 쓸 수 있습니다. ```vue ``` ## Nuxt 서버 렌더링을 지원합니다. 스타일은 `nuxt.config.ts`에 추가하고, 플러그인에서 등록합니다. ```ts // nuxt.config.ts export default defineNuxtConfig({ css: ['@krds.ui/vue/style'] }) ``` ```ts // plugins/krds.ts (Nuxt 4 기본 구조에서는 app/plugins/krds.ts) import KrdsVue from '@krds.ui/vue' export default defineNuxtPlugin(nuxtApp => { nuxtApp.vueApp.use(KrdsVue) }) ``` Nuxt는 tsconfig를 자동 생성하므로, 전역 타입은 프로젝트의 `.d.ts` 파일에 참조를 추가합니다. ```ts // types/krds.d.ts /// ``` ## 예제 프로젝트 이 문서의 설정(플러그인 등록, 스타일, 전역 타입)을 담은 Vite + Vue 3 + TypeScript 예제가 저장소의 [`examples/vite`](https://github.com/Initializer-org/krds-vue/tree/main/examples/vite)에 있습니다. [StackBlitz에서 바로 열어](https://stackblitz.com/github/Initializer-org/krds-vue/tree/main/examples/vite) 볼 수도 있습니다. ## TypeScript 컴포넌트 props와 공통 타입을 패키지 루트에서 가져올 수 있습니다. ```ts import type { KrdsButtonProps, Size } from '@krds.ui/vue' const size: Size = 'medium' const buttonProps: KrdsButtonProps = { variant: 'primary', size, disabled: false } ``` ## 스타일과 테마 KRDS Vue 스타일은 CSS custom properties를 기반으로 합니다. 토큰 값을 조정해야 한다면 원본 CSS를 수정하지 말고 애플리케이션 CSS에서 필요한 변수만 재선언합니다. ```css :root { --krds-color-light-primary-50: #256ef4; } ``` 컬러 모드는 루트 요소의 `data-krds-mode` 속성으로 전환합니다. 이 문서 사이트 상단의 화면 모드 버튼도 같은 방식으로 고대비 모드를 켭니다. ```ts document.documentElement.setAttribute('data-krds-mode', 'high-contrast') ``` - `light`: 기본 라이트 모드 (KRDS 공식 사이트의 "기본 (밝은 배경)") - `high-contrast`: 고대비 모드 (KRDS 공식 사이트의 "선명하게 (어두운 배경)") - `theme`: 사용자 시스템 설정에 따라 라이트/고대비 스타일 적용 (KRDS 공식 사이트의 "시스템 설정") ## 브라우저 지원 | 브라우저 | 지원 버전 | | ----------------- | --------- | | Chrome, Edge | 111 이상 | | Firefox | 114 이상 | | Safari (iOS 포함) | 16.4 이상 | 산출물에 폴리필은 포함하지 않습니다. Internet Explorer는 지원하지 않습니다. --- # 공식 배너 Masthead 공식 배너는 사용자가 대한민국 정부 조직 및 관련 기관에서 운영 및 관리하는 디지털 정부서비스임을 식별할 수 있도록 제공하는 정보 배너이다. ## 기본 ```vue ``` ## API ## KrdsMasthead ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent] | 공식 배너를 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 공식 배너 문구 | --- # 운영기관 식별자 Identifier 운영기관 식별자는 디지털 정부서비스에 대한 신뢰성을 위해 서비스 운영 및 관리 주체를 안내하는 요소로 공식 배너, 푸터와 함께 서비스의 일관성, 브랜드를 확인할 수 있는 핵심 요소이다. ## 기본 ```vue ``` ## API ## KrdsIdentifier ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | logoLabel | string | 'KRDS - Korea Design System' | 로고 스크린리더 텍스트 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent] | 운영기관 식별자를 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 운영기관 안내 문구 | --- # 헤더 Header 헤더는 웹사이트의 상단 헤더 영역을 구성하는 컴포넌트이다. 유틸리티 메뉴, 브랜딩 영역, 네비게이션 메뉴를 슬롯을 통해 유연하게 구성할 수 있다. 네비게이션 슬롯에는 KrdsMainMenu 등 완성된 메뉴 컴포넌트를 그대로 전달한다. ## 기본 `utility`, `branding` 슬롯에는 KRDS 헤더 마크업을, `navigation` 슬롯에는 `KrdsMainMenu`를, `mobileNavigation` 슬롯에는 `KrdsMainMenu`(`variant="mobile"`)를 전달합니다. 헤더는 화면 상단에 고정(sticky)되고 메인 메뉴를 열면 화면 전체에 배경 딤이 깔리므로 예제를 별도 화면(iframe)에 띄웁니다. 예제는 1024px 폭 화면을 축소해 PC 레이아웃으로 보여 줍니다. ```vue ``` ## 모바일 1024px 미만 화면에서는 유틸리티 메뉴와 PC 메인 메뉴가 숨겨지고 전체메뉴 버튼이 표시됩니다. 전체메뉴 버튼의 `aria-controls`를 모바일 드로어 id(`KrdsMainMenu`의 `mobileId`, 기본값 `mobile-nav`)에 연결하고 `v-model:open`으로 드로어를 엽니다. 아래는 같은 예제를 문서 폭(1024px 미만) 그대로 띄운 것으로, 전체메뉴 버튼으로 드로어를 확인할 수 있습니다. ## API ## KrdsHeader ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | 추가 CSS 클래스 | | id | string | 'krds-header' | 헤더 ID | ### Slots | 이름 | 설명 | | --- | --- | | utility | 유틸리티 메뉴 슬롯 | | branding | 브랜딩 영역 슬롯 (로고, 액션 버튼) | | navigation | 데스크탑 네비게이션 슬롯 — KrdsMainMenu 등 완성된 메뉴 요소를 그대로 전달 | | mobileNavigation | 모바일 네비게이션 슬롯 — KrdsMainMenu(variant="mobile") 등 완성된 드로어 요소를 그대로 전달 | ## KrdsMainMenu ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | items | MainMenuItem[] | [] | 메뉴 아이템 배열 | | variant | MainMenuVariant ('pc' \| 'mobile') | 'pc' | 렌더링 방식 | | ariaLabel | string | '메인 메뉴' | 메뉴 영역 레이블 | | open | boolean | false | 모바일 드로어 열림 상태 (v-model:open) | | mobileId | string | 'mobile-nav' | 모바일 드로어 요소 id (외부 트리거의 `aria-controls` 대상) | | backdrop | boolean | true | PC 메가 패널 배경 딤(backdrop) 사용 여부 | | closeLabel | string | '전체메뉴 닫기' | 모바일 드로어 닫기 버튼 레이블 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:open | [value: boolean] | 모바일 메뉴가 열리거나 닫힐 때 (v-model:open) | | menu-toggle | [index: number, expanded: boolean] | 1차 메뉴를 펼치거나 접을 때 (순서, 펼침 여부) | | item-click | [item: MainMenuAnyItem, mouseEvent: MouseEvent] | 메뉴 항목을 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | banner | PC 서브 패널 배너 영역 | | header | 모바일 드로어 헤더 영역 (유틸리티, 로그인, 검색 등) | | bottom | 모바일 드로어 하단 영역 | --- # 푸터 Footer 푸터는 화면을 구성하는 가장 마지막 요소로 헤더와 본문에서 원하는 정보를 찾지 못하였거나 사이트 구조 탐색 중에 길을 잃은 사용자들이 대면하게 되는 정보이다. 따라서 푸터에는 사용자가 서비스를 탐색할 수 있는 추가적인 수단, 문제를 해결하는 데 참고할 수 있는 유용한 링크가 제공되어야 한다. ## 기본 `top`, `logo`, `content`, `bottom` 슬롯에 KRDS 푸터 마크업을 그대로 전달합니다. 하단에는 운영기관 식별자(`KrdsIdentifier`)를 함께 둡니다. 푸터 레이아웃은 화면 폭 기준으로 바뀌므로 예제를 별도 화면(iframe)에 띄웁니다. 예제는 1024px 폭 화면을 축소해 PC 레이아웃으로 보여 줍니다. 768px 미만 화면에서는 모바일 레이아웃으로 바뀝니다. ```vue ``` ## API ## KrdsFooter ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | id | string | 'krds-footer' | Footer ID | ### Slots | 이름 | 설명 | | --- | --- | | top | 푸터 위 빠른 링크 영역 | | logo | 로고 | | content | 기관 정보와 링크 | | bottom | 하단 메뉴·저작권·운영기관 식별자 | ## KrdsIdentifier ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | logoLabel | string | 'KRDS - Korea Design System' | 로고 스크린리더 텍스트 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent] | 운영기관 식별자를 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 운영기관 안내 문구 | --- # 건너뛰기 링크 Skip link 건너뛰기 링크는 웹사이트에서 웹 페이지의 주요 콘텐츠 섹션의 탐색을 도와주는 페이지 내부 링크이다. 키보드나 가상 초점을 이용하여 콘텐츠를 탐색하는 사용자는 건너뛰기 링크를 이용하여 대부분의 페이지에서 반복되는 콘텐츠 영역을 건너뛰고 주요 콘텐츠로 빠르게 이동할 수 있다. ## 기본 페이지 최상단에 배치합니다. 링크는 포커스를 받기 전까지 화면에서 숨겨져 있다가, 포커스를 받으면 화면 맨 위에 고정되어 표시되므로 예제를 별도 화면(iframe)에 띄웁니다. 미리보기 안으로 Tab 키를 눌러 포커스를 옮겨 확인하세요. ```vue ``` ## 여러 링크 `links`로 여러 링크를 하나의 래퍼(`#krds-skip-link`) 안에 렌더링합니다. 컴포넌트를 여러 개 나란히 두면 `id`가 중복되므로 `links`를 사용합니다. ```vue ``` ## API ## KrdsSkipLink ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | 추가 CSS 클래스 | | id | string | 'krds-skip-link' | 요소 ID | | href | string | - | 건너뛸 대상 요소의 ID | | links | { href: string; label: string; }[] | - | 여러 건너뛰기 링크 (하나의 래퍼 안에 렌더링, 지정 시 href·기본 슬롯 대신 사용) | ### Slots | 이름 | 설명 | | --- | --- | | default | 링크 문구 (links를 쓰지 않을 때) | --- # 메인 메뉴 Main menu 메인 메뉴는 서비스 전체의 구조를 보여주고 주요 화면으로 이동할 수 있게 하는 메뉴이다. 일반적으로 헤더 영역에 위치하며, 데스크탑에서는 메가 메뉴 형태로, 모바일에서는 드로어 형태로 제공된다. `variant` 속성으로 두 형태를 전환합니다. PC 메가 메뉴는 원본 KRDS처럼 패널을 열면 페이지 전체에 배경 딤(`backdrop`)을 깝니다. 메뉴가 딤 위에 보이려면 헤더(`#krds-header`, `KrdsHeader`) 안에 두어야 하며, 헤더 밖에서 쓰면 `:backdrop="false"`로 끕니다. ## PC 메가 메뉴 PC 메가 메뉴는 1024px 이상 화면에서만 표시됩니다. 미리보기는 헤더 밖에 두므로 `:backdrop="false"`로 배경 딤을 끄고, PC 레이아웃 그대로 보이도록 1024px 폭으로 표시합니다(가로 스크롤). 헤더 안에서 쓰는 예는 [헤더](./header)를 참고하세요. ```vue ``` ## PC 2depth 없는 메뉴 2depth 목록 없이 마지막 뎁스 링크만 나열하는 경우 `single-list` 레이아웃으로 렌더링됩니다. `items`만 지정하면 됩니다. ```vue ``` ## 모바일 드로어 메뉴 모바일 드로어는 `v-model:open`으로 제어합니다. 외부 트리거 버튼에 `aria-controls`로 `mobileId`를 연결하고 `aria-expanded`를 함께 관리합니다. 2depth의 `items`는 3depth로, 3depth의 `items`는 전체 화면 4depth 패널로 렌더링됩니다. 드로어는 화면 전체를 덮는 고정 위치 요소이고 1024px 이상 화면에서는 표시되지 않으므로, 예제를 별도 화면(iframe)에 띄웁니다. ```vue ``` ## API ## KrdsMainMenu ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | items | MainMenuItem[] | [] | 메뉴 아이템 배열 | | variant | MainMenuVariant ('pc' \| 'mobile') | 'pc' | 렌더링 방식 | | ariaLabel | string | '메인 메뉴' | 메뉴 영역 레이블 | | open | boolean | false | 모바일 드로어 열림 상태 (v-model:open) | | mobileId | string | 'mobile-nav' | 모바일 드로어 요소 id (외부 트리거의 `aria-controls` 대상) | | backdrop | boolean | true | PC 메가 패널 배경 딤(backdrop) 사용 여부 | | closeLabel | string | '전체메뉴 닫기' | 모바일 드로어 닫기 버튼 레이블 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:open | [value: boolean] | 모바일 메뉴가 열리거나 닫힐 때 (v-model:open) | | menu-toggle | [index: number, expanded: boolean] | 1차 메뉴를 펼치거나 접을 때 (순서, 펼침 여부) | | item-click | [item: MainMenuAnyItem, mouseEvent: MouseEvent] | 메뉴 항목을 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | banner | PC 서브 패널 배너 영역 | | header | 모바일 드로어 헤더 영역 (유틸리티, 로그인, 검색 등) | | bottom | 모바일 드로어 하단 영역 | --- # 브레드크럼 Breadcrumb 브레드크럼은 탐색 계층 구조를 표시하여 사용자가 현재 위치를 파악하고 계층 구조의 수준을 이동할 수 있게 해준다. 브레드크럼을 통해 사용자는 탐색 중인 화면의 상위 수준 화면으로 이동할 수 있다. ## 기본 `items`의 첫 항목은 홈 아이콘과 함께 표시되고(`showHomeIcon`), 마지막 항목은 현재 페이지(`aria-current="page"`)로 표시됩니다. ```vue ``` ## API ## KrdsBreadcrumb ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | id | string | - | 엘리먼트 ID | | ariaLabel | string | '현재 경로' | 접근성 라벨 | | showHomeIcon | boolean | true | 홈 아이콘 표시 여부 | | items (필수) | BreadcrumbItem[] | - | 브레드크럼 아이템 배열 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | item-click | [item: BreadcrumbItem, event: MouseEvent] | 경로 항목을 클릭했을 때 | --- # 사이드 메뉴 Side navigation 사이드 메뉴는 서브 화면 내에서의 이동을 위해 사용하는 메뉴이다. 일반적으로 본문 영역의 좌측에 사이드바 형태로 제공된다. 메인 메뉴보다 훨씬 좁고 깊은 페이지 구조 탐색에 사용되기 때문에 링크의 개수가 많고 복잡하게 표현되기 쉽다. ## 기본 `v-model`로 메뉴 아이템 배열을 전달합니다. 2Depth의 `subItems`는 펼침 목록으로, 3Depth의 `subItems`는 4Depth 팝업으로 렌더링되며 `expanded`로 초기 펼침 상태를 지정합니다. 4Depth 팝업을 열면 팝업 제목으로 초점이 옮겨 가고, 제목을 눌러 닫으면 팝업을 연 버튼으로 초점이 돌아옵니다. Tab으로 팝업을 벗어나거나 팝업 밖을 누르면 팝업이 닫히고, 초점은 옮겨 간 곳에 그대로 둡니다. ```vue ``` ## 2Depth 링크 `subItems`가 없는 2Depth 항목은 링크로 렌더링되고, `onClick`으로 클릭 동작을 지정할 수 있습니다. ```vue ``` ## 여러 개 배치 한 페이지에 여러 개를 두어도 내부 id는 겹치지 않습니다. `aria-label`로 각 메뉴를 구분합니다. ```vue ``` ## API ## KrdsSideNavigation ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | modelValue | SideNavItem[] | [] | 메뉴 아이템 배열 | | title (필수) | string | - | 네비게이션 제목 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: SideNavItem[]] | 메뉴를 펼치거나 접어 항목 상태가 바뀔 때 (v-model) | --- # 콘텐츠 내 탐색 In-page navigation 콘텐츠 내 탐색은 사용자가 본문의 구조를 훑어보고 원하는 콘텐츠로 빠르게 이동할 수 있도록 하는 탐색 수단이다. 화면을 스크롤 할 때 특정 위치에 고정되어 콘텐츠의 목차 역할을 하는 동시에 사용자가 페이지 내 탐색에서 특정 항목을 클릭하면 연결된 섹션으로 스크롤 된다. ## 기본 화면에 고정되고 창 스크롤에 맞춰 현재 섹션을 표시하므로 예제를 별도 화면(iframe)에 띄웁니다. 768px 이상 화면에서는 본문 오른쪽에 고정되고 그보다 좁으면 본문 위에 표시됩니다. 이 예제는 800px 폭 화면을 축소해 보여 줍니다. KRDS 레이아웃(`#container.krds-in-page-navigation-type > .inner.in-between > .contents`) 안에 배치해야 합니다. ```vue ``` ## API ## KrdsInPageNavigation ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | caption | string | '이 페이지의 구성' | 네비게이션 캡션 | | title | string | - | 네비게이션 제목 | | items | NavigationItem[] | [] | 네비게이션 아이템 목록 | | autoActive | boolean | true | 스크롤에 따른 자동 활성화 여부 | | headerTopSelector | string | '#krds-masthead' | 헤더 상단 영역 선택자 (기본값: '#krds-masthead') | | headerInnerSelector | string | '#krds-header .header-in' | 헤더 내부 영역 선택자 (기본값: '#krds-header .header-in') | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | itemClick | [item: NavigationItem, event: MouseEvent \| KeyboardEvent] | 탐색 항목을 클릭하거나 키보드로 선택했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | action | - | --- # 페이지네이션 Pagination 페이지네이션은 많은 양의 콘텐츠를 탐색하기 쉽도록 여러 화면에 나누고, 분할된 화면을 탐색하는 데 사용되는 요소이다. ## 기본 `v-model`로 현재 페이지를, `max`로 전체 페이지 수를 지정합니다. `aria-label`(기본 '페이지 내비게이션')로 이름 붙인 내비게이션 영역(`nav`)이라, 한 페이지에 내비게이션이 여럿이어도 화면낭독기가 구분합니다. 페이지가 `pageRange`보다 많으면 첫 페이지와 마지막 페이지 사이를 생략 표시로 줄입니다. ```vue ``` ## API ## KrdsPagination ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | id | string | - | 엘리먼트 ID | | ariaLabel | string | '페이지 내비게이션' | 내비게이션 영역 이름 (nav의 aria-label) | | modelValue | number | 1 | 현재 페이지 번호 (v-model) | | min | number | DEFAULT_MIN | 최소 페이지 번호 (기본값: 1, 최소값: 1) | | pageRange | number | DEFAULT_PAGE_RANGE | 표시할 페이지 범위 | | max (필수) | number | - | 최대 페이지 번호 (전체 페이지 수) | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: number] | 페이지를 바꿀 때 (페이지 번호, v-model) | --- # 구조화 목록 Structured list 구조화 목록은 유사하거나 관련된 콘텐츠 집합을 표현하기 위한 형식으로 목록에 제공된 데이터에 대한 상세 정보 탐색 수단 또는 관련 기능 실행 수단으로 활용된다. 사용자가 콘텐츠를 효율적으로 탐색하고 다음 행동을 빠르게 결정할 수 있도록 목록 내 정보는 상세 페이지에서 제공되는 복잡한 콘텐츠 중 핵심적이거나 흥미를 끌 수 있는 정보를 논리적 흐름에 따라 조직화하여 명확한 위계 구조를 반영해 제공해야 한다. ## 기본 `cardTop`, `cardBody`, `cardBtm`, `cardBtn` 슬롯으로 카드의 각 영역을 채웁니다. 내용을 넣은 슬롯의 영역만 렌더됩니다. ```vue ``` ## 뱃지만 있는 구조 ```vue ``` ## 표형 같은 목록을 표로 보여 주는 형태입니다(원본 KRDS v1.1.0). 목록 위 도구 막대(`.search-list-top`)에 전체선택·일괄 작업 버튼과 목록 표시 개수·정렬 기준을 두고, 아래에 표와 페이지네이션을 둡니다. 정렬 기준은 PC에서 버튼, 모바일에서 셀렉트로 바뀝니다. 표는 `KrdsTable`의 [셀 슬롯](/components/table#셀-슬롯)으로 행마다 체크박스와 다운로드 버튼을 넣고, 도구 막대의 체크박스·버튼·셀렉트와 페이지네이션도 컴포넌트로 조합합니다. 전체선택은 지금 페이지의 행 기준입니다. 넓은 화면을 전제로 한 형태라 예제를 1200px 폭의 별도 화면(iframe)에 띄웁니다. ```vue ``` ## API ## KrdsStructuredList ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | full | boolean | true | 전체 타입 여부 | ### Slots | 이름 | 설명 | | --- | --- | | cardTop | - | | cardBody | - | | cardBtm | - | | cardBtn | - | --- # 긴급 공지 Critical alerts 긴급 공지는 본문 상단에 강조되어 표시되는 배너로 사용자에게 긴급하거나 중요한 정보를 전달하는 데 사용된다. 모든 공공 디지털 서비스에서 동일한 긴급 공지 컴포넌트를 사용함으로써 사용자는 긴급한 정보를 일관되고 예측 가능한 방식으로 찾고 이해할 수 있다. ## 기본 `link-href`를 지정하면 링크가 표시됩니다. 링크 텍스트(`link-text`)는 768px 미만 화면에서 숨겨지고 화살표 아이콘만 남습니다. 화면낭독기는 화면 폭과 관계없이 링크 텍스트를 링크 이름으로 읽습니다. ```vue ``` ## 타입 `type`에 따라 배지 문구가 `danger`는 긴급, `ok`는 안전, `info`는 안내로 표시됩니다. ```vue ``` ## API ## KrdsCriticalAlerts ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | type | AlertType ('danger' \| 'ok' \| 'info') | 'info' | 알림 타입 | | linkHref | string | - | 링크 URL | | linkText | string | '자세히 보기' | 링크 텍스트 | | message (필수) | string | - | 알림 메시지 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | link-click | [event: MouseEvent] | 공지 링크를 클릭했을 때 | --- # 디스클로저 Disclosure 디스클로저는 특정한 정보/컨트롤/섹션에 관련된 부가적인 정보를 표시하거나 숨기는 데 사용되는 요소이다. 디스클로저 하위 콘텐츠 섹션은 기본으로 축소된 상태로 제공되며 사용자가 요청하는 경우에 확장되어 자세한 정보가 표시된다. 이는 사용자의 인지적 부담을 감소시키고 정보를 빠르게 훑어보는 데 도움이 된다. ## 기본 `v-model`로 펼침 상태를 제어합니다. 접혀 있는 동안 콘텐츠 영역은 `inert`로 포커스와 보조기기 대상에서 제외됩니다. ```vue ``` ## API ## KrdsDisclosure ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | modelValue | boolean | false | 확장 상태 (v-model) | | title (필수) | string | - | 디스클로저 제목 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: boolean] | 펼침 상태가 바뀔 때 (v-model) | ### Slots | 이름 | 설명 | | --- | --- | | default | 펼쳤을 때 보이는 내용 | --- # 모달 Modal 모달은 대화창의 한 종류로 기본 창에 종속된 요소이다. 기본 창과 겹쳐져 가장 상단에 표시되며, 이때 기본 창은 비활성 상태로 전환되어 상호작용이 불가능하므로 사용자는 모달에서의 단일한 과업 또는 메시지에 집중할 수 있다. ## 기본 `v-model`로 열림 상태를 제어합니다. 열리면 모달 안으로 포커스가 이동하고 Tab 키 포커스가 모달 안에서 순환하며, Esc 키나 배경 클릭으로 닫으면 연 버튼으로 포커스가 돌아갑니다. ```vue ``` ## 사이즈 ```vue ``` ## 배경 없음 ```vue ``` ## 풀팝업 ```vue ``` ## 바텀시트 ```vue ``` ## Persistent 중요한 결정을 받아야 할 때 배경 클릭과 Esc 키로 닫히지 않게 합니다. ```vue ``` ## API ## KrdsModal ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | backdrop | boolean | true | 배경 딤(backdrop) 표시 여부 | | modelValue | boolean | false | 모달 표시 여부 (v-model) | | full | boolean | false | 전체 화면 모달 여부 | | modalId | string | - | 모달 엘리먼트 ID | | size | KrdsModalSize ('small' \| 'medium' \| 'large') | 'medium' | 모달 크기 | | bottomSheet | boolean | false | 하단 시트형 모달 여부 | | persistent | boolean | false | 배경 클릭·Esc 키로 닫히지 않는 지속형 모달 여부 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: boolean] | 모달이 열리거나 닫힐 때 (v-model) | ### Slots | 이름 | 설명 | | --- | --- | | title | - | | default | - | | footer | - | --- # 배지 Badge 컴포넌트에 대한 빠른 인지와 탐색을 돕기 위해 컴포넌트 근처에 표시되는 작은 문자 또는 숫자 데이터이다. 컴포넌트의 분류 체계, 구조화된 정보, 상태 정보, 기타 메타 데이터를 표시할 수 있으며 사용자의 주의를 끌기 위해 색상을 활용할 수 있다. ## 기본 속성을 지정하지 않으면 `type="outline"`, `color="primary"`, `size="large"`로 표시됩니다. ```vue ``` ## 기본 전체 `type`(`outline`, `bg`, `bg-light`)과 `color`의 조합입니다. 행마다 `size`를 `large`, `medium`, `small`로 달리했습니다. ```vue ``` ## 넘버 배지 ```vue ``` ## API ## KrdsBadge ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | number | boolean | false | 넘버 여부 | | class | KrdsClassValue | - | CSS 클래스 | | type | "outline" \| "bg" \| "bg-light" | 'outline' | 배지 타입 | | size | Size ('xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge') | 'large' | 배지 크기 | | color | ColorVariant ('primary' \| 'secondary' \| 'gray' \| 'point' \| 'danger' \| 'warning' \| 'success' \| 'information' \| 'disabled') | 'primary' | 배지 컬러 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent] | 배지를 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 배지 글자 | --- # 아코디언 Accordion 아코디언은 한 페이지에서 관련 있는 여러 콘텐츠 섹션을 확인할 수 있도록 하는 컴포넌트로 콘텐츠 섹션의 헤더 목록이 수직으로 쌓여 있는 형태로 표현된다. 일반적으로 헤더 목록은 컨트롤 요소로 활용되며 사용자는 필요에 따라 헤더를 선택하여 하위 콘텐츠 섹션을 표시하거나 숨길 수 있다. ## 기본 `KrdsAccordionGroup` 안에 `KrdsAccordionItem`을 둡니다. 열린 항목의 `id`를 `open-item`으로 내려 주고 `toggle` 이벤트로 받은 `id`로 갱신합니다. 예제처럼 같은 `id`를 다시 받으면 닫도록 하면 한 번에 한 항목만 열립니다. `id`는 항목 요소의 id와 `accordion-header-{id}`, `accordion-collapse-{id}`에 그대로 쓰이므로 페이지 안에서 고유해야 합니다. ```vue ``` ## 라인 `type-line`을 지정하면 라인형으로 표시됩니다. 제목과 본문은 `title`, `content` 속성 대신 같은 이름의 슬롯으로도 넣을 수 있습니다. ```vue ``` ## API ## KrdsAccordionGroup ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | typeLine | boolean | false | 라인 타입 아코디언 여부 | ### Slots | 이름 | 설명 | | --- | --- | | default | 아코디언 항목 (KrdsAccordionItem) | ## KrdsAccordionItem ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | title | string | - | 헤더 텍스트 (title 슬롯으로 대체 가능) | | content | string | - | 본문 텍스트 (content 슬롯으로 대체 가능) | | openItem | string | - | 현재 열려 있는 아이템의 id | | id (필수) | string | - | 아이템 고유 식별자 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | toggle | [id: string] | 펼침·접힘 버튼을 눌렀을 때 (항목 id) | ### Slots | 이름 | 설명 | | --- | --- | | title | 제목 (title 속성 대신) | | content | 펼쳤을 때 보이는 내용 (content 속성 대신) | --- # 이미지 Image 이미지는 콘텐츠 양식 중 하나로 단일 이미지 또는 이미지 시퀀스로 표현될 수 있다. 이미지를 적절하게 사용하게 되면 사용자는 텍스트보다 효과적으로 정보를 인지할 수 있으며, 텍스트로 표현하기 어려운 정보를 전달할 수 있다. ## 기본 `alt`(대체 텍스트)는 필수입니다. 빠뜨리면 타입 검사(`vue-tsc`)에서 오류가 나고 개발 모드에서 경고가 뜹니다. 이미지가 전하는 정보를 구체적이고 간결하게 씁니다. 기본으로 `loading="lazy"`가 붙어 화면에 가까워질 때 불러오고, `width`·`height` 등 나머지 속성은 ``에 그대로 전달됩니다. 화면 폭보다 크면 비율을 유지한 채 줄어듭니다. ```vue ``` ## 설명 `caption`을 주면 `
`와 `
`으로 감싸 이미지 아래에 설명을 표시합니다. 출처 링크처럼 마크업이 필요하면 `#caption` 슬롯을 씁니다. 촬영자·출처 정보는 대체 텍스트가 아니라 설명에 넣습니다. ```vue ``` ## 장식 이미지 정보 없이 꾸밈용인 이미지는 `alt=""`로 비워 화면낭독기가 건너뛰게 합니다. ```vue ``` ## 접근성 - 앱이 개발 모드일 때 KRDS 이미지 접근성 가이드에 어긋나는 대체 텍스트를 콘솔에 경고합니다(Vue 경고, 배포 빌드에서는 출력하지 않음). - `'로고 이미지'`, `'강아지 사진'`처럼 끝에 이미지·사진·그림·그래픽 등 역할과 겹치는 말을 붙인 경우 - 대체 텍스트가 `caption`과 같은 경우 - 컴포넌트는 내용이 적절한지까지 확인하지 못합니다. 이미지와 인접한 글과 같은 내용, 이미지에 없는 정보는 넣지 않습니다. - 글자를 이미지로 만들지 말고 마크업 텍스트로 제공합니다. - `KrdsImage` 대신 ``를 직접 쓰는 곳까지 검사하려면 eslint-plugin-vuejs-accessibility의 [`alt-text` 규칙](https://vue-a11y.github.io/eslint-plugin-vuejs-accessibility/rules/alt-text.html)을 함께 씁니다. ## API ## KrdsImage ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | caption | string | - | 이미지 설명 (있으면 figure와 figcaption으로 감쌈) | | src (필수) | string | - | 이미지 주소 | | alt (필수) | string | - | 대체 텍스트 (필수, 장식용 이미지는 빈 문자열 '') | ### Slots | 이름 | 설명 | | --- | --- | | caption | 이미지 설명 (출처 링크 등 마크업이 필요할 때, caption 대신) | --- # 캐러셀 Carousel 캐러셀은 하나의 영역에서 여러 개의 콘텐츠를 순차적으로 번갈아 보여주는 컴포넌트이다. 한정된 공간에 여러 콘텐츠를 노출할 수 있으나 첫 번째 슬라이드 외에는 주목도가 크게 떨어지므로, 중요한 정보는 캐러셀에만 담지 않는 것이 좋다. 슬라이드는 기본 슬롯으로 전달하며 최상위 노드 하나가 슬라이드 한 장이 된다. 자동 재생 시에는 사용자가 즉시 정지할 수 있도록 재생/정지 버튼을 함께 노출한다. ## 기본 (비주얼 배너형) ```vue ``` ## 배너형 배너형은 인디케이터 안에 분수형 페이지네이션과 이전/다음·더 보기 버튼을 배치합니다. ```vue ``` ## 자동 재생 자동 재생 중에는 정지 버튼이 노출되며, 정지하면 재생 버튼으로 바뀝니다. 마우스 오버나 키보드 포커스가 캐러셀 안에 있는 동안에는 자동 재생이 멈춥니다. ```vue ``` ## 순환 없음 `loop`를 끄면 처음과 마지막 슬라이드에서 이전/다음 버튼이 비활성화됩니다. ```vue ``` ## 분수형 페이지네이션 페이지네이션 방식은 형태와 무관하게 `pagination` 속성으로 바꿀 수 있습니다. ```vue ``` ## API ## KrdsCarousel ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | id | string | - | 엘리먼트 ID | | navigation | boolean | true | 이전/다음 버튼 표시 여부 (기본값: true) | | variant | KrdsCarouselVariant ('visual' \| 'banner') | 'visual' | 캐러셀 형태 (기본값: visual) | | ariaLabel | string | '캐러셀' | 캐러셀 영역 접근성 라벨 | | activeIndex | number | - | 현재 슬라이드 인덱스 (v-model:activeIndex) | | loop | boolean | true | 처음/마지막 슬라이드에서 순환 이동 여부 (기본값: true) | | autoplay | boolean | false | 자동 재생 여부. true면 재생/정지 버튼을 노출하고 즉시 재생을 시작한다 (기본값: false) | | autoplayDelay | number | DEFAULT_AUTOPLAY_DELAY | 자동 재생 간격 (ms, 기본값: 2500) | | pauseOnHover | boolean | true | 마우스 오버 시 자동 재생 일시 정지 여부 (기본값: true). 포커스 진입 시에는 값과 무관하게 항상 정지한다 | | speed | number | DEFAULT_SPEED | 슬라이드 전환 속도 (ms, 기본값: 400) | | spaceBetween | number | - | 슬라이드 사이 간격 (px, 기본값: visual 0 / banner 16) | | pagination | KrdsCarouselPaginationType ('bullets' \| 'fraction' \| 'none') | - | 페이지네이션 표시 방식 (기본값: visual bullets / banner fraction) | | moreHref | string | - | 더 보기 링크 URL. 지정하면 더 보기 버튼을 표시한다 | | prevLabel | string | '이전' | 이전 버튼 라벨 | | nextLabel | string | '다음' | 다음 버튼 라벨 | | playLabel | string | '슬라이드 재생' | 재생 버튼 라벨 | | stopLabel | string | '슬라이드 멈춤' | 정지 버튼 라벨 | | moreLabel | string | '더 보기' | 더 보기 버튼 라벨 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | change | [value: number] | 슬라이드가 바뀌었을 때 (새 순서) | | play | [] | 자동 재생을 시작했을 때 | | update:activeIndex | [value: number] | 현재 슬라이드 순서가 바뀔 때 (v-model:active-index) | | stop | [] | 자동 재생을 멈췄을 때 | | more-click | [event: MouseEvent] | 더 보기 버튼을 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 슬라이드 (자식 요소 하나가 한 장) | --- # 탭 Tab 탭은 버튼을 눌러 상호배타적인 여러 개의 콘텐츠 섹션을 전환할 수 있는 컴포넌트이다. 탭 버튼 목록과 콘텐츠 패널이 수직으로 쌓여 있는 형태로 표현되며, 사용자는 탭을 선택하여 해당 콘텐츠 섹션을 표시할 수 있다. ## 기본 `tabs`의 각 항목 `id`와 같은 이름의 슬롯에 패널 내용을 넣습니다. 처음에는 비활성화되지 않은 첫 번째 탭이 선택되고, 선택된 탭에는 스크린 리더용 "선택됨" 텍스트(`selectedText`)가 붙습니다. 좌우 방향키로 탭 버튼 사이에서 포커스를 옮길 수 있습니다. ```vue ``` ## 버튼형 ```vue ``` ## 풀사이즈 ```vue ``` ## 비활성화 항목에 `disabled: true`를 주면 해당 탭을 선택할 수 없습니다. ```vue ``` ## 외부 제어 `v-model`로 선택된 탭의 `id`를 제어합니다. 탭이 바뀌면 `change` 이벤트도 발생합니다. ```vue ``` ## API ## KrdsTabs ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | variant | KrdsTabsVariant ('line' \| 'fill') | 'line' | 탭 스타일 변형 | | modelValue | string | - | 활성 탭 id (v-model) | | full | boolean | false | 풀사이즈 레이아웃 여부 | | selectedText | string | '선택됨' | 선택된 탭의 스크린 리더 대체 텍스트 | | tabs (필수) | KrdsTabItem[] | - | 탭 아이템 목록 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | change | [id: string] | 탭을 바꿨을 때 (탭 id) | | update:modelValue | [id: string] | 선택한 탭 id가 바뀔 때 (v-model) | --- # 표 Table 표는 데이터를 하나 이상의 행과 열로 조직화하여 표현하는 형식으로 사용자가 빠르게 많은 양의 정보를 확인하고 비교할 수 있도록 도와준다. 기본적으로 대화형 요소가 아니기 때문에 열 제목에 데이터를 정렬하기 위한 컨트롤 요소가 포함된 상황 외에 행 전체나 데이터 셀이 대화형으로 작동하지 않는다. ## 기본 테이블 `columns`로 열을, `rows`로 행 데이터를 정의합니다. 각 행의 첫 번째 셀은 행 제목(`th scope="row"`)으로 렌더되고, `headerStyle`의 `width`는 `colgroup`의 열 너비로도 쓰입니다. KRDS 표 스타일은 `class`에 `data`가 있을 때 적용되므로 원본 KRDS 마크업처럼 `col data`를 지정합니다. `caption`은 화면에 보이지 않고 스크린 리더로 읽히므로 표의 구성을 설명하는 문장으로 씁니다. ```vue ``` ## 행 클릭 `row-click` 리스너가 있을 때만 행이 포커스를 받고(`tabindex="0"`) 클릭이나 Enter·Space 키로 선택됩니다. 리스너가 없으면 행은 대화형으로 동작하지 않습니다. ```vue ``` ## 스타일 & 클래스 기능 열마다 헤더 셀에는 `headerStyle`·`headerClasses`를, 바디 셀에는 `style`·`classes`를 지정합니다. 바디 셀의 `style`·`classes`는 행 데이터를 받는 함수로도 줄 수 있습니다. `align`을 지정하면 헤더와 바디 셀에 `text-` 클래스가 붙습니다. 클래스의 스타일은 앱의 CSS에서 정의합니다. ```vue ``` ## 셀 슬롯 배지·버튼·체크박스처럼 글자가 아닌 내용은 열 이름(`name`)으로 슬롯을 받아 그립니다. `#cell-`은 본문 셀 내용을 바꾸고 `{ row, column, value, index }`를 받습니다(`value`는 `field`로 꺼낸 값). `#header-`은 헤더 셀 내용을 바꿔 화면에 숨긴 열 제목 등에 씁니다. 셀 태그(첫 열은 `th scope="row"`)와 `style`·`classes`는 그대로 유지되고, 슬롯으로만 그리는 열은 `field`를 생략합니다. 버튼처럼 같은 이름이 행마다 반복되면 숨김 텍스트로 어느 행의 버튼인지 알려 줍니다. ```vue ``` ## 빈 데이터 (기본) `rows`가 비어 있으면 모든 열을 합친 셀에 "데이터가 없습니다."를 표시합니다. ```vue ``` ## 빈 데이터 (커스텀 슬롯) `no-data` 슬롯으로 빈 상태 내용을 바꿉니다. ```vue ``` ## API ## KrdsTable ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | caption | string | - | 테이블 캡션 | | columns (필수) | TableColumn[] | - | 테이블 열 정의 | | rows (필수) | TableRow[] | - | 테이블 행 데이터 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | row-click | [row: TableRow, index: number] | 행을 클릭했을 때 (행, 순서) | ### Slots | 이름 | 설명 | | --- | --- | | no-data | 행이 없을 때 표시할 내용 | ### 열 이름 슬롯 열 이름(`name`)마다 받는 슬롯입니다. 이름이 열 정의에 따라 정해져 위 Slots 표에는 나오지 않습니다. | 이름 | 인자 | 설명 | | --------------- | ----------------------------------------------------------------------- | ------------------------------------------------ | | `cell-` | `{ row: TableRow, column: TableColumn, value: unknown, index: number }` | 본문 셀 내용. 셀 태그와 `style`·`classes`는 유지 | | `header-` | `{ column: TableColumn }` | 헤더 셀 내용 (예: 화면에 숨긴 열 제목) | --- # 텍스트 목록 Text list 텍스트 목록은 계층 구조가 있는 텍스트 블록을 읽기 쉽게 구성한 것이다. ## 기본 (대시) `type`으로 `ul`·`ol` 요소를, `variant`로 글머리 스타일을 정합니다. 항목(`li`) 안에 `KrdsTextList`를 넣어 3단계까지 중첩합니다. ```vue ``` ## 순서 있는 목록 `variant="ordered"`는 번호를 자동으로 붙이지 않으므로 항목마다 ``으로 번호를 직접 씁니다. ```vue ``` ## API ## KrdsTextList ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | type | "ol" \| "ul" | 'ul' | 리스트 타입 | | variant | "decimal" \| "dash" \| "hollow" \| "ordered" | 'dash' | 스타일 변형 | ### Slots | 이름 | 설명 | | --- | --- | | default | 목록 항목 | --- # 링크 Link 링크는 다른 서비스/애플리케이션, 한 서비스 내의 다른 화면, 한 화면 내의 다른 섹션 등으로 이동하는 데 사용되는 탐색 요소이다. ## 기본 `target="_blank"`이면 `rel="noopener noreferrer"`가 자동으로 붙습니다. 새 창으로 열리는 링크는 `title`로 그 사실을 알립니다. ```vue ``` ## 모든 링크 변형 ```vue ``` ## API ## KrdsLink ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | link | boolean | true | Link 클래스 적용 여부 | | title | string | - | 링크 제목 (접근성) | | href | string | '#!' | 링크 URL | | size | KrdsLinkSize ('small' \| 'medium' \| 'large') | - | 링크 크기 | | target | string | - | 링크 대상 (_blank, _self 등) | | basic | boolean | false | Basic 링크 여부 (본문 텍스트 컬러) | | pure | boolean | false | Pure 링크 여부 (가상클래스 상태 시 컬러 유지) | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent] | 링크를 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 링크 내용 | --- # 버튼 Button 버튼은 어떤 기능이나 동작을 실행하거나 기능을 사용하기 위한 상태로 변경하는 요소이다. 사용자가 서비스를 이용하는 과정에서 어떤 행동이 중요한지에 따라 관련된 버튼이 다양한 스타일로 표현된다. ## 계층 `variant`로 버튼의 중요도를 표현합니다. 화면의 주요 행동에는 `primary`를 한 번만 사용합니다. ```vue ``` ## 사이즈 ```vue ``` ## 아이콘 버튼 텍스트 앞이나 뒤에 아이콘을 둘 수 있습니다. 아이콘 크기는 버튼 크기에 맞춰집니다. ```vue ``` ## 텍스트 버튼 ```vue ``` ## 아이콘만 있는 버튼 보이는 텍스트가 없으므로 `sr-only` 텍스트로 버튼 이름을 반드시 제공합니다. ```vue ``` ## API ## KrdsButton ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | type | "button" \| "reset" \| "submit" | 'button' | 버튼 타입 | | variant | Variant ('primary' \| 'secondary' \| 'tertiary') | 'primary' | 버튼 변형 | | size | Size ('xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge') | - | 버튼 크기 | | disabled | boolean | false | 비활성화 여부 | | pure | boolean | false | Pure 버튼 여부 (가상클래스 상태 시 컬러 유지) | | icon | boolean | false | 아이콘 전용 버튼 | | border | boolean | false | 테두리 스타일 (아이콘 버튼용) | | text | boolean | false | 텍스트 버튼 스타일 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent] | 버튼을 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 버튼 내용 | --- # 플로팅 버튼 Floating action button 플로팅 버튼은 사용자가 화면에서 가장 자주 사용하고 중요한 작업에 단일 또는 다중으로 사용한다. 페이지가 스크롤될 때에도 화면 우측 하단에 계속 표현한다. ## 단일형 아이콘과 레이블로 하나의 주요 작업을 보여 줍니다. `href`를 주면 링크, 없으면 버튼으로 렌더링하고 `click` 이벤트를 보냅니다. `hide-label`을 주면 아이콘만 보이고 레이블은 화면낭독기용으로 남습니다. 화면 오른쪽 아래에 고정되므로 예제를 별도 화면(iframe)에 띄웁니다. ```vue ``` ## 확장형 `items`를 주면 확장형이 됩니다. + 버튼을 누르면 가림막과 함께 항목이 펼쳐지고, X 버튼·가림막·Esc 키로 닫습니다. 항목을 누르면 목록을 닫고 초점을 + 버튼으로 돌려준 뒤 `select` 이벤트(항목, 순서, 클릭 이벤트)를 보냅니다. 같은 페이지의 대상(`#id`)으로 이동하는 링크는 이동한 위치에서 키보드 탐색을 이어 가도록 초점을 놓습니다. 링크 항목은 `event.preventDefault()`로 라우터 이동에 쓸 수 있고, `external`을 주면 새 창으로 엽니다. ```vue ``` ## 사용 지침 - 화면 오른쪽 아래에 배치하고, 화면의 모든 요소 위에 둡니다. - 플로팅 버튼이 2개 이상 필요하면 확장형을 쓰고, 항목은 3개 이하로 구성합니다. - 확장형의 깊이는 2수준 이하로만 사용합니다. - 자주 쓰는 행동이 여러 개이거나 지도·캘린더처럼 제스처 조작이 많은 화면에는 쓰지 않습니다. ## API ## KrdsFloatingButton ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | items | KrdsFloatingButtonItem[] | - | 확장형 항목 (지정하면 확장형, 3개 이하 권장) | | href | string | - | 단일형 버튼의 링크 주소 | | icon | string | 'ico-plus' | 단일형 버튼의 아이콘 클래스 | | external | boolean | false | 단일형 링크를 새 창으로 열기 ('새 창 열림' 안내 포함) | | hideLabel | boolean | false | 단일형 레이블을 화면에서 숨김 (아이콘만 표시, 화면낭독기는 읽음) | | label (필수) | string | - | 단일형 버튼의 레이블, 확장형은 확장 버튼의 이름 (화면에는 숨김) | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent] | 단일형 버튼 클릭 | | select | [item: KrdsFloatingButtonItem, index: number, event: MouseEvent] | 확장형 항목 선택 (링크 항목은 event.preventDefault()로 라우터 이동 가능) | --- # 라디오 버튼 Radio button 라디오 버튼은 사용자가 여러 개의 옵션 중 하나만 선택할 수 있도록 하는 경우에 사용한다. 즉, 라디오 버튼 옵션의 선택은 상호배타적이므로 한 개의 옵션을 선택하면 다른 옵션은 자동으로 선택 해제된다. ## 기본 같은 그룹의 라디오는 같은 `name`과 `v-model`을 쓰고, `modelValue`가 `value`와 같은 라디오가 선택됩니다. `description` 슬롯으로 부가 설명을 넣을 수 있고, `KrdsCheckArea`의 `column`으로 세로로 배치합니다. ```vue ``` ## API ## KrdsRadio ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | name | string | - | 폼 필드 이름 | | id | string | - | HTML ID | | modelValue | string \| number \| boolean | - | 모델 값 | | size | "medium" \| "large" | 'medium' | 크기 | | disabled | boolean | false | 비활성화 여부 | | chip | boolean | false | Chip 스타일 여부 | | value (필수) | string \| number \| boolean | - | 라디오 값 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: string \| number \| boolean] | 이 항목을 선택할 때 (항목 value, v-model) | ### Slots | 이름 | 설명 | | --- | --- | | default | - | | description | - | ## KrdsCheckArea ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | 추가 클래스 | | column | boolean | false | 세로(컬럼) 배치 여부 | ### Slots | 이름 | 설명 | | --- | --- | | default | 체크박스·라디오 버튼 묶음 | --- # 체크박스 Checkbox 체크박스는 사용자가 여러 개의 옵션 중 한 개 이상의 값을 선택할 수 있도록 하는 경우에 사용한다. 즉, 체크박스 옵션의 선택은 상호배타적이므로 한 개의 옵션을 선택하는 것은 다른 옵션의 선택에 영향을 미치지 않는다. ## 기본 `v-model`로 선택 상태(`boolean`)를 연결합니다. `description` 슬롯으로 부가 설명을 넣을 수 있고, `KrdsCheckArea`의 `column`으로 세로로 배치합니다. ```vue ``` ## 사이즈 ```vue ``` ## Chip `chip`을 지정하면 칩 모양으로 표시됩니다. 칩 스타일에서는 `description` 슬롯이 표시되지 않습니다. ```vue ``` ## API ## KrdsCheckbox ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | id | string | - | HTML ID | | modelValue | boolean | false | 모델 값 | | size | "medium" \| "large" | 'medium' | 크기 | | disabled | boolean | false | 비활성화 여부 | | chip | boolean | false | Chip 스타일 여부 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: boolean] | 체크 상태가 바뀔 때 (v-model) | ### Slots | 이름 | 설명 | | --- | --- | | default | - | | description | - | ## KrdsCheckArea ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | 추가 클래스 | | column | boolean | false | 세로(컬럼) 배치 여부 | ### Slots | 이름 | 설명 | | --- | --- | | default | 체크박스·라디오 버튼 묶음 | --- # 셀렉트 Select 셀렉트는 사용자에게 여러 개의 옵션 목록을 팝업으로 제공하여 그 중 한 개의 값을 선택할 수 있도록 하는 경우에 사용한다. ## 기본 `KrdsFormGroup`·`KrdsFormLabel`·`KrdsFormHint`와 함께 써서 레이블과 도움말을 연결합니다. ```vue ``` ## 사이즈 ```vue ``` ## 정렬 스타일 목록의 정렬 기준처럼 보이는 레이블 없이 쓰는 셀렉트입니다. `title`로 이름을 제공합니다. ```vue ``` ## 에러 상태 ```vue ``` ## API ## KrdsSelect ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | sort | boolean | false | 정렬 스타일 여부 | | name | string | - | 폼 필드 이름 | | title | string | - | 타이틀 | | id | string | - | HTML ID | | modelValue | string \| number \| null | null | 선택된 값 | | size | Size ('xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge') | 'medium' | 선택 크기 | | disabled | boolean | false | 비활성화 여부 | | options | SelectOption[] | [] | 옵션 목록 | | placeholder | string | '선택' | 플레이스홀더 | | readonly | boolean | false | 읽기 전용 여부 | | state | "default" \| "error" \| "success" \| "information" | 'default' | 입력 상태 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | blur | [event: FocusEvent] | 초점을 잃었을 때 | | focus | [event: FocusEvent] | 초점을 받았을 때 | | update:modelValue | [value: string \| number \| null] | 선택한 값이 바뀔 때 (v-model) | ### Slots | 이름 | 설명 | | --- | --- | | default | 직접 넣는 option 요소 (options 속성과 함께 쓸 수 있음) | --- # 태그 Tag 태그는 키워드 또는 레이블을 사용하여 콘텐츠를 분류하는 수단이다. 콘텐츠 항목에 직접 관련 분류 체계, 데이터 속성을 표시하거나, 목록에서 특정 분류 체계, 데이터 속성을 가진 항목이 선택되었음을 보여주기 위한 태그 그룹으로 사용된다. ## 기본 링크가 아닌 태그에는 삭제 버튼이 함께 표시되며, 누르면 `remove` 이벤트가 발생합니다. ```vue ``` ## 사이즈 크기는 `KrdsTagGroup`의 `size`로 지정합니다. ```vue ``` ## 링크 태그 `link`를 지정하면 삭제 버튼 없이 `href`로 이동하는 링크로 렌더링됩니다. ```vue ``` ## 슬롯 사용 `remove` 이벤트에서 목록을 갱신해 태그를 삭제합니다. ```vue ``` ## API ## KrdsTag ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | link | boolean | false | 링크 태그 여부 | | href | string | '#' | 링크 URL (link가 true일 때 사용) | | target | string | - | 링크 타겟 (link가 true일 때 사용) | | rel | string | - | 링크 관계 (link가 true일 때 사용) | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | remove | [event: MouseEvent] | 삭제 버튼을 클릭했을 때 | ### Slots | 이름 | 설명 | | --- | --- | | default | 태그 글자 | ## KrdsTagGroup ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | size | KrdsTagGroupSize ('small' \| 'medium' \| 'large') | 'medium' | 태그 그룹 크기 | ### Slots | 이름 | 설명 | | --- | --- | | default | 태그 (KrdsTag) | --- # 토글 스위치 Toggle switch 토글은 상호 배타적인 두 가지 상태를 전환하는 데 사용되는 요소이다. ## 기본 `v-model`로 켜짐 상태(`boolean`)를 연결하고, `label`로 스위치 이름을 표시합니다. ```vue ``` ## 크기 ```vue ``` ## API ## KrdsToggleSwitch ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | name | string | - | 폼 필드 이름 | | label | string | - | 스위치 라벨 | | id | string | - | HTML ID | | required | boolean | false | 필수 입력 여부 | | modelValue | boolean | false | 모델 값 | | size | "medium" \| "large" | 'medium' | 크기 | | disabled | boolean | false | 비활성화 여부 | | readonly | boolean | false | 읽기 전용 여부 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | change | [value: boolean] | 켜거나 껐을 때 | | update:modelValue | [value: boolean] | 켜짐 상태가 바뀔 때 (v-model) | --- # 단계 표시기 Step indicator 단계 표시기는 서비스 이용을 위해 사용자가 거쳐야 하는 일련의 단계를 시각화하여 표현한 것으로 진행 상태에 대한 피드백을 사용자에게 전달한다. ## 기본 `modelValue`에 현재 단계의 인덱스(0부터 시작)를 지정합니다. 그보다 앞의 단계는 완료(`done`), 뒤의 단계는 대기(`pending`) 상태로 표시됩니다. 단계 표시기는 진행 상태만 보여 주므로(단계를 눌러 이동하지 않음), 이전/다음 버튼 등에서 `modelValue`를 바꿔 단계를 옮깁니다. API 표의 `update:modelValue` 이벤트는 기존 코드 호환용으로 남아 있으며 보내지 않습니다. ```vue ``` ## 상태 지정 `KrdsStep`의 `status`로 단계의 상태를 직접 지정합니다. `status`는 `modelValue`로 계산한 상태보다 우선합니다. ```vue ``` ## 페이지 타이틀과 함께 ```vue ``` ## API ## KrdsStepIndicator ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | modelValue | number | 0 | 현재 단계 인덱스 (0부터 시작). 앞 단계는 완료, 뒤 단계는 대기로 표시 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: number] | 보내지 않음: 단계 표시기는 진행 상태만 보여 주므로 v-model 값이 바뀌지 않습니다 (기존 코드 호환용, 다음 주요 버전에서 제거) | ### Slots | 이름 | 설명 | | --- | --- | | default | 단계 (KrdsStep) | ## KrdsStep ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | status | "done" \| "active" \| "pending" | - | 단계 상태 (지정하지 않으면 KrdsStepIndicator가 순서에 따라 정함) | | title (필수) | string | - | 단계 제목 | | step (필수) | string \| number | - | 단계 번호 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | click | [event: MouseEvent, step: string \| number] | 단계를 클릭했을 때 (단계 번호) | ### Slots | 이름 | 설명 | | --- | --- | | default | 단계 제목 아래 추가 내용 | --- # 스피너 Spinner 스피너는 화면이나 요소의 다양한 처리 상태를 시각적으로 표시한 것으로 화면 전체나 일부 요소에 접근하기 위해 일정 시간 동안 대기해야 함을 사용자에게 안내한다. ## 기본 스피너는 부모 요소의 너비와 높이를 채우고 가운데에 표시됩니다. `role="status"`와 화면 낭독기용 "로딩 중" 텍스트가 함께 렌더링됩니다. ```vue ``` ## 라벨 포함 `label`로 스피너 옆에 안내 텍스트를 표시합니다. ```vue ``` ## 입력 필드 로딩 입력 필드와 스피너를 `.form-spinner`로 감싸면 스피너가 입력 필드 오른쪽 안에 표시됩니다. `KrdsInput`의 `loading`을 지정해도 같은 구조로 렌더링됩니다. ```vue ``` ## API ## KrdsSpinner ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | label | string | - | 로딩 안내 텍스트 | --- # 패널 Panel 패널은 본문 콘텐츠의 섹션이나 일부 요소에 대한 개념/용어 설명, 옵션의 구성, 이용 방법 등과 관련된 정보나 도움말, 따라하기 콘텐츠를 제공하는 사이드 패널이다. ## 기본 `v-model`로 펼침 상태를 제어합니다. 도움말 버튼과 패널이 화면 오른쪽에 고정(`position: fixed`)되므로 예제를 별도 화면(iframe)에 띄웁니다. 예제는 1024px 폭 화면을 축소해 보여 줍니다. 1024px 미만 화면에서는 패널이 화면 폭에서 3rem을 뺀 너비로 열리고 뒤 배경이 어두워집니다. ```vue ``` ## 도움 패널 기본 슬롯에 `KrdsTabs`를 넣어 도움 탭과 따라하기 탭을 구성합니다. ```vue ``` ## 따라하기 패널 `KrdsTabs`의 `v-model`을 `tutorial`로 지정해 따라하기 탭이 먼저 보이게 합니다. ```vue ``` ## API ## KrdsPanel ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | modelValue | boolean | false | 도움말 패널 펼침 상태 (v-model) | | headerTopSelector | string | '#krds-masthead' | 헤더 상단 영역 선택자 (기본값: '#krds-masthead', KrdsInPageNavigation과 같음) | | headerInnerSelector | string | '#krds-header .header-in' | 헤더 내부 영역 선택자 (기본값: '#krds-header .header-in', KrdsInPageNavigation과 같음) | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [value: boolean] | 도움 패널을 펼치거나 접을 때 (v-model) | ### Slots | 이름 | 설명 | | --- | --- | | default | 도움 패널 내용 | ## KrdsTabs ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | variant | KrdsTabsVariant ('line' \| 'fill') | 'line' | 탭 스타일 변형 | | modelValue | string | - | 활성 탭 id (v-model) | | full | boolean | false | 풀사이즈 레이아웃 여부 | | selectedText | string | '선택됨' | 선택된 탭의 스크린 리더 대체 텍스트 | | tabs (필수) | KrdsTabItem[] | - | 탭 아이템 목록 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | change | [id: string] | 탭을 바꿨을 때 (탭 id) | | update:modelValue | [id: string] | 선택한 탭 id가 바뀔 때 (v-model) | --- # 맥락적 도움말 Contextual help 컴포넌트 주변에 배치되어 해당 컴포넌트의 상태나 관련된 상세 정보를 제공하는 컴포넌트이다. 맥락적 도움말은 정보 아이콘이나 도움 아이콘 버튼을 통해 사용자가 요청하는 경우에만 화면에 표시된다. ## 기본 아이콘 버튼을 누르면 도움말이 열리고 그 안의 첫 번째 링크나 버튼으로 포커스가 이동합니다. 닫기 버튼, Esc 키, 바깥 클릭으로 닫고, 닫기 버튼과 Esc 키로 닫으면 포커스가 아이콘 버튼으로 돌아옵니다. 도움말은 제목으로 이름 붙인 대화 상자(`role="dialog"`)라 화면낭독기가 제목과 함께 읽습니다. ```vue ``` ## 위치 `position`으로 도움말이 열리는 위치를 지정합니다. 기본값은 `top left`입니다. ```vue ``` ## 도움말 아이콘 `help-icon`을 지정하면 정보 아이콘 대신 도움(물음표) 아이콘을 표시합니다. ```vue ``` ## API ## KrdsContextualHelp ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | tooltipTitle | string | '도움말 제목' | 툴팁 제목 | | helpIcon | boolean | false | 도움말 아이콘 사용 여부 (false 면 툴팁 아이콘) | | position | ContextualHelpPosition ('top left' \| 'top center' \| 'top right' \| 'bottom left' \| 'bottom center' \| 'bottom right') | 'top left' | 툴팁 노출 위치 | ### Slots | 이름 | 설명 | | --- | --- | | default | 도움말 내용 | --- # 코치마크 Coach mark 코치마크는 사용자에게 새로 도입된 기능을 안내하거나, 여러 단계를 거쳐 수행해야 하는 복잡한 과업을 사용자가 보다 쉽게 완료할 수 있도록 세부 수행 단계별로 고맥락적 도움말을 제공하는 컴포넌트이다. ## 기본 단계마다 `KrdsCoachMark`를 두고 같은 `v-model`을 연결합니다. `v-model` 값이 `active-step`과 같은 코치마크에만 말풍선이 표시되며, 다음으로·이전으로 버튼이 `v-model`을 바꾸고 그만보기 버튼은 `close` 이벤트를 보냅니다. 말풍선은 대상 요소 위쪽에 표시되므로 위에 여백을 둡니다. ```vue ``` ## API ## KrdsCoachMark ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | style | string \| Record | - | 인라인 스타일 | | modelValue | number \| null | null | 현재 노출 중인 단계 (v-model) | | coachMarkClass | string \| string[] | '' | 코치마크 래퍼에 추가할 클래스 | | stepsData (필수) | StepsData[] | - | 전체 단계 데이터 | | activeStep (필수) | number | - | 이 코치마크가 담당하는 단계 번호 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | close | [] | 닫기 버튼으로 닫을 때 | | update:modelValue | [value: number \| null] | 이전·다음 버튼으로 단계가 바뀔 때 (v-model) | ### Slots | 이름 | 설명 | | --- | --- | | coach-mark-content | 코치마크 말풍선 아래에 함께 보여 줄 내용 | --- # 툴팁 Tooltip 툴팁은 요소나 본문 텍스트에 제공되는 짧은 부가 설명이다. 설명이 필요한 대상 또는 별도의 활성화 버튼에 마우스를 올리거나 초점을 이동했을 때 설명 텍스트가 표시된다. ## 기본 `type`으로 트리거 버튼 모양(`default`, `icon`, `button`)을 정합니다. 툴팁은 버튼 옆에 표시되고 Esc 키나 창 스크롤로 닫힙니다. ```vue ``` ## 세로 배치 (vertical) `vertical`을 지정하면 툴팁이 버튼 위나 아래에 표시됩니다. ```vue ``` ## 박스형 (box) `box`를 지정하면 여러 줄 설명에 맞는 박스형 툴팁이 버튼 위나 아래에 표시됩니다. ```vue ``` ## API ## KrdsTooltip ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | type | TooltipType ('default' \| 'icon' \| 'button') | 'default' | 트리거 버튼 타입 | | disabled | boolean | false | 비활성화 여부 | | vertical | boolean | false | 세로 방향 배치 여부 | | box | boolean | false | 박스형 여부 | | tooltipContent (필수) | string | - | 툴팁 본문 | ### Slots | 이름 | 설명 | | --- | --- | | default | 툴팁을 여는 버튼 내용 | --- # 음성 지원 TTS TTS(Text-to-Speech)는 텍스트를 음성으로 변환하여 읽어주는 기능을 제공하는 버튼 컴포넌트이다. Web Speech API를 사용하며, 볼륨 아이콘과 재생 아이콘 두 가지 타입을 지원한다. ## 기본 버튼을 누르면 `text`를 한국어(`ko-KR`)로 읽고, 읽는 동안 정지 아이콘으로 바뀌어 다시 누르면 멈춥니다. ```vue ``` ## 아이콘만 `label`이 없으면 아이콘만 표시되므로 `aria-label`로 버튼 이름을 제공합니다. ```vue ``` ## 크기 ```vue ``` ## 아이콘 타입 ```vue ``` ## 비활성화 ```vue ``` ## API ## KrdsTts ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | label | string | - | 레이블 텍스트 (미지정 시 아이콘만 표시) | | size | TtsSize ('xsmall' \| 'small' \| 'medium') | 'medium' | 버튼 크기 | | disabled | boolean | false | 비활성화 여부 | | icon | TtsIcon ('volume' \| 'play') | 'volume' | 아이콘 타입 | | text (필수) | string | - | 읽어줄 텍스트 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | error | [error: Error] | 음성 합성을 지원하지 않거나 읽기에 실패했을 때 | | pause | [] | 일시 정지했을 때 | | play | [text: string] | 읽기를 시작했을 때 (읽는 문장) | | end | [] | 읽기가 끝났을 때 | --- # 날짜 입력 필드 Date input 날짜 입력 필드는 사용자가 특정 날짜 또는 기간을 입력하거나 선택하는 데 사용되는 요소이다. ## 기본 달력 버튼을 누르면 달력이 열리고 초점이 달력으로 이동합니다. 원본 KRDS처럼 입력 필드 위쪽에 여는 것이 기본이고, 화면에서 위쪽 공간이 달력 높이보다 좁고 아래쪽이 더 넓으면 아래쪽에 엽니다. 날짜를 고른 뒤 **확인**을 누르면 `YYYY.MM.DD` 형식으로 입력되고, 두 날짜를 차례로 고르면 `YYYY.MM.DD ~ YYYY.MM.DD` 기간으로 입력됩니다. Esc나 **취소**, 달력 바깥 클릭으로 닫힙니다. Esc·**취소**·**확인**으로 닫으면 초점이 달력 버튼으로 돌아오고, 바깥을 누르면 누른 곳으로 간 초점을 그대로 둡니다. 연·월 목록을 Esc로 닫으면 초점이 연·월 버튼으로 돌아옵니다. ```vue ``` ## 비활성화 입력과 달력 열기가 모두 막힙니다. ```vue ``` ## 읽기 전용 직접 입력은 막히지만 달력 버튼은 그대로 사용할 수 있습니다. ```vue ``` ## 일정·휴일 표시 `initialYear`·`initialMonth`로 달력을 처음 열 때 보여 줄 달을 정합니다. `holidays`의 날짜는 일요일처럼 휴일로, `eventDates`의 날짜는 일정이 있는 날로 표시됩니다. 날짜는 `YYYY.MM.DD` 형식으로 지정합니다. ```vue ``` ## 여러 개 배치 달력을 열면 열려 있던 다른 달력은 닫힙니다. ```vue ``` ## body에 렌더 (teleport) 달력은 원본 KRDS처럼 입력 필드 바로 뒤에 렌더되므로, `overflow`로 잘리는 컨테이너(스크롤 영역, 표 등) 안에서는 달력이 잘립니다. `teleport`를 지정하면 달력을 `body`에 렌더하고 입력 필드 자리에 맞춰 위치를 잡으며, 스크롤·화면 크기가 바뀌면 위치를 다시 계산합니다. - 달력이 문서 끝에 렌더되므로 달력 안에서 Tab으로 빠져나가면 입력 필드 다음 요소가 아니라 문서 끝으로 이동합니다. - 모달(`KrdsModal`) 안에서는 쓰지 마세요. 모달은 `aria-modal`이라 모달 밖으로 렌더된 달력에 스크린리더가 접근할 수 없고, 달력이 모달 아래에 깔립니다. ```vue ``` ## API ## KrdsDateInput ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | name | string | - | 폼 필드 이름 | | id | string | - | HTML ID | | required | boolean | false | 필수 입력 여부 | | modelValue | string | - | 선택된 날짜 값 | | size | Size ('xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge') | 'medium' | 입력 크기 | | disabled | boolean | false | 비활성화 여부 | | placeholder | string | 'YYYY.MM.DD' | 플레이스홀더 | | readonly | boolean | false | 읽기 전용 여부 | | autofocus | boolean | false | 자동 포커스 | | eventDates | string[] | [] | 일정이 있는 날짜 배열 (YYYY.MM.DD 형식) | | holidays | string[] | [] | 휴일 날짜 배열 (YYYY.MM.DD 형식) | | initialYear | number | - | 초기 표시 년도 (기본: 현재 년도) | | initialMonth | number | - | 초기 표시 월 (기본: 현재 월) | | teleport | boolean | false | 달력을 body에 렌더 (overflow로 잘리는 컨테이너 안에서 사용. 모달 안에서는 쓰지 않음) | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | input | [event: Event] | 입력할 때 (네이티브 input) | | blur | [event: FocusEvent] | 초점을 잃었을 때 | | change | [event: Event] | 값이 확정됐을 때 (네이티브 change) | | focus | [event: FocusEvent] | 초점을 받았을 때 | | update:modelValue | [value: string] | 날짜를 입력하거나 달력에서 고를 때 (v-model) | --- # 텍스트 영역 Textarea 텍스트 영역은 사용자가 키보드로 글자, 숫자, 기호 등이 조합된 여러 줄의 텍스트를 입력하는 경우에 사용하는 요소이다. ## 기본 입력한 글자 수가 오른쪽 아래에 표시됩니다(`showCount`, 기본값 `true`). `maxlength`를 지정하면 최대 글자 수도 함께 표시됩니다. ```vue ``` ## API ## KrdsTextarea ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | name | string | - | 폼 필드 이름 | | resize | "none" \| "vertical" \| "both" \| "horizontal" | 'vertical' | 리사이즈 가능 여부 | | id | string | - | HTML ID | | required | boolean | false | 필수 입력 여부 | | modelValue | string | '' | 입력값 | | size | Size ('xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge') | - | 입력 크기 | | disabled | boolean | false | 비활성화 여부 | | rows | number | 4 | 행 수 | | placeholder | string | - | 플레이스홀더 | | readonly | boolean | false | 읽기 전용 여부 | | autofocus | boolean | false | 자동 포커스 | | maxlength | number | - | 최대 글자 수 | | minlength | number | - | 최소 글자 수 | | cols | number | - | 열 수 | | showCount | boolean | true | 글자 수 표시 여부 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | input | [event: Event] | 입력할 때 (네이티브 input) | | blur | [event: FocusEvent] | 초점을 잃었을 때 | | change | [event: Event] | 값이 확정됐을 때 (네이티브 change) | | focus | [event: FocusEvent] | 초점을 받았을 때 | | keydown | [event: KeyboardEvent] | 키를 눌렀을 때 | | keyup | [event: KeyboardEvent] | 키를 뗐을 때 | | update:modelValue | [value: string] | 입력값이 바뀔 때 (v-model) | --- # 텍스트 입력 필드 Text input 텍스트 입력 필드는 사용자가 키보드로 글자, 숫자, 기호 등이 조합된 한 줄의 짧은 텍스트를 입력하는 경우에 사용하는 요소이다. ## 기본 `KrdsFormGroup`·`KrdsFormLabel`·`KrdsFormHint`와 함께 써서 레이블과 도움말을 붙입니다. `readonly`·`disabled`로 읽기 전용과 비활성화 상태를 만듭니다. ```vue ``` ## 상태 `state`를 `error`·`success`·`information`으로 지정하고 아래 `KrdsFormHint`의 `type`도 같은 값으로 맞춥니다. `error`일 때는 입력 필드 테두리도 에러 색으로 바뀝니다. ```vue ``` ## 사이즈 ```vue ``` ## 로딩 `loading`을 지정하면 입력 필드 안에 스피너가 표시됩니다. 이때 기본 슬롯(아이콘 버튼)은 렌더링되지 않습니다. ```vue ``` ## 아이콘 버튼 `icon`을 지정하고 기본 슬롯에 버튼을 넣으면 입력 필드 안쪽에 버튼이 배치됩니다. 보이는 텍스트가 없으므로 `sr-only` 텍스트로 버튼 이름을 제공합니다. 비밀번호 보기 전환이나 내용 삭제 같은 버튼 동작은 컴포넌트가 처리하지 않으므로 직접 구현합니다. 버튼이 여러 개면 `KrdsButtonGroup`으로 묶습니다 (KRDS `.btn-group`, 입력 필드 안 전용). ```vue ``` ## API ## KrdsInput ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | name | string | - | 폼 필드 이름 | | id | string | - | HTML ID | | type | InputType ('text' \| 'password' \| 'email' \| 'number' \| 'tel' \| 'url' \| 'search') | 'text' | 입력 타입 | | required | boolean | false | 필수 입력 여부 | | modelValue | string \| number | - | 입력값 | | min | number | - | 최소값 (number 타입용) | | max | number | - | 최대값 (number 타입용) | | size | Size ('xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge') | - | 입력 크기 | | disabled | boolean | false | 비활성화 여부 | | loading | boolean | false | 로딩 상태 | | icon | boolean | false | 아이콘 (있을 때 btn-ico-wrap 클래스 적용) | | placeholder | string | - | 플레이스홀더 | | readonly | boolean | false | 읽기 전용 여부 | | state | "default" \| "error" \| "success" \| "information" | 'default' | 입력 상태 | | step | number | - | 단계값 (number 타입용) | | autofocus | boolean | false | 자동 포커스 | | maxlength | number | - | 최대 글자 수 | | minlength | number | - | 최소 글자 수 | | autocomplete | string | - | 자동완성 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | input | [event: Event] | 입력할 때 (네이티브 input) | | blur | [event: FocusEvent] | 초점을 잃었을 때 | | change | [event: Event] | 값이 확정됐을 때 (네이티브 change) | | focus | [event: FocusEvent] | 초점을 받았을 때 | | keydown | [event: KeyboardEvent] | 키를 눌렀을 때 | | keyup | [event: KeyboardEvent] | 키를 뗐을 때 | | update:modelValue | [value: string \| number] | 입력값이 바뀔 때 (v-model) | ### Slots | 이름 | 설명 | | --- | --- | | default | 입력 필드 안쪽 버튼 (icon 속성과 함께, 여러 개면 KrdsButtonGroup) | ## KrdsButtonGroup ### Props 없음 ### Slots | 이름 | 설명 | | --- | --- | | default | 입력 필드 안에 넣을 버튼들 | --- # 파일 업로드 File upload 파일 업로드는 하나 이상의 디바이스의 로컬 파일을 선택하고 첨부하는 데 사용하는 입력 컴포넌트이다. ## 기본 `v-model`에 파일 목록(`FileInfo[]`)을 바인딩합니다. 컴포넌트는 파일을 서버로 보내지 않습니다. 추가된 파일은 `pending` 상태로 목록에 들어가므로 실제 업로드와 상태 변경은 직접 처리합니다. ```vue ``` ## 파일 상태별 표시 `FileInfo`의 `status`에 따라 표시가 달라집니다. `uploading`은 스피너, `completed`는 완료 아이콘, `pending`은 삭제 버튼, `error`는 `errorMessage`를 표시합니다. `downloadUrl`이 있으면 다운로드·바로보기 버튼이 표시되고, 누르면 `download`·`preview` 이벤트가 발생합니다. ```vue ``` ## 파일 선택 동작 **파일선택** 버튼이나 업로드 영역으로 끌어다 놓아 파일을 추가합니다. `maxFileSize`(기본 20MB) 이상인 파일은 `error` 상태로 추가되고 개수에서 빠집니다. `maxFiles`(기본 10개)에 이르면 더 추가되지 않습니다. ```vue ``` ## 단일 파일 `multiple`을 `false`로 지정하면 새로 선택한 파일이 기존 파일을 대신합니다. ```vue ``` ## 이미지 파일만 `accept`에 허용할 확장자나 MIME 타입을 지정합니다. 끌어다 놓은 파일이 형식에 맞지 않으면 `error` 상태로 추가됩니다. ```vue ``` ## 비활성화 ```vue ``` ## 읽기 전용 업로드 영역과 삭제 버튼 없이 파일 목록만 표시합니다. ```vue ``` ## API ## KrdsFileUpload ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | class | KrdsClassValue | - | CSS 클래스 | | name | string | - | 폼 필드 이름 | | style | string \| Record | - | 인라인 스타일 | | title | string | '타이틀영역' | 제목 | | id | string | - | HTML ID | | required | boolean | false | 필수 입력 여부 | | modelValue | FileInfo[] | [] | 파일 목록 | | size | Size ('xsmall' \| 'small' \| 'medium' \| 'large' \| 'xlarge') | 'medium' | 입력 크기 | | disabled | boolean | false | 비활성화 여부 | | description | string | '컨텐츠 영역' | 설명 텍스트 | | placeholder | string | '첨부할 파일을 여기에 끌어다 놓거나, 파일 선택 버튼을 눌러 파일을 직접 선택해주세요.' | 플레이스홀더 텍스트 | | readonly | boolean | false | 읽기 전용 여부 | | accept | string | - | 허용되는 파일 타입 (예: '.jpg,.png,.pdf') | | maxFiles | number | 10 | 최대 파일 개수 | | maxFileSize | number | 20 * 1024 * 1024 // 20MB | 최대 파일 크기 (bytes) | | multiple | boolean | true | 다중 파일 선택 여부 | | dragAndDrop | boolean | true | 드래그 앤 드롭 활성화 여부 | | showPreview | boolean | true | 미리보기 표시 여부 | | showDownload | boolean | true | 다운로드 버튼 표시 여부 | | showPreviewButton | boolean | true | 바로보기 버튼 표시 여부 | | showClearAll | boolean | true | 전체 삭제 버튼 표시 여부 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | update:modelValue | [files: FileInfo[]] | 파일을 추가·삭제해 목록이 바뀔 때 (v-model) | | file-added | [file: FileInfo] | 파일을 추가했을 때 | | file-removed | [fileId: string] | 파일을 삭제했을 때 (파일 id) | | file-error | [file: FileInfo, error: string] | 추가한 파일이 검사(크기·형식 등)에 실패했을 때 (오류 메시지) | | upload-start | [file: FileInfo] | 보내지 않음 (기존 코드 호환용 선언), 업로드는 사용하는 쪽에서 처리 | | upload-progress | [file: FileInfo, progress: number] | 보내지 않음 (기존 코드 호환용 선언), 업로드는 사용하는 쪽에서 처리 | | upload-complete | [file: FileInfo] | 보내지 않음 (기존 코드 호환용 선언), 업로드는 사용하는 쪽에서 처리 | | upload-error | [file: FileInfo, error: string] | 보내지 않음 (기존 코드 호환용 선언), 업로드는 사용하는 쪽에서 처리 | | clear-all | [] | 전체 삭제 버튼을 눌렀을 때 | | download | [file: FileInfo] | 파일의 다운로드 버튼을 눌렀을 때 | | preview | [file: FileInfo] | 파일의 미리보기 버튼을 눌렀을 때 | --- # 언어 변경 Language switcher 언어 변경은 서비스의 콘텐츠를 표시할 언어를 변경하거나 별도의 외국어 서비스로 이동하는 데 사용되는 요소이다. 한국어가 익숙하지 않은 사용자가 콘텐츠 표시 언어를 변경할 수 있는 수단을 발견하지 못한다면 서비스를 이용할 수 없게 되므로, 디지털 정부서비스로 직관적이고 일관된 방식으로 언어 변경을 제공하는 것이 매우 중요하다. ## 기본 선택한 언어 코드가 `v-model`에 담깁니다. `prev-item` 슬롯으로 목록 위에 현재 언어를 표시할 수 있습니다. ```vue ``` ## 외부 페이지 이동 `type="external"`이면 각 언어가 `url`로 새 창에서 이동하는 링크가 됩니다. ```vue ``` ## API ## KrdsLanguageSwitcher ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | type | "default" \| "external" | 'default' | 동작 타입 (default: 언어 선택, external: 외부 페이지 이동) | | modelValue | string | '' | 선택된 언어 코드 (v-model) | | dropPosition | DropdownPosition ('left' \| 'center' \| 'right') | 'center' | 드롭다운 정렬 위치 | | languageList (필수) | LanguageData[] | - | 언어 목록 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | close | [] | 언어 목록이 닫힐 때 | | update:modelValue | [value: string] | 언어를 골랐을 때 (언어 코드, v-model) | ### Slots | 이름 | 설명 | | --- | --- | | default | 언어 버튼 문구 (예: Language) | | prev-item | 언어 목록 위에 넣을 내용 | --- # 화면 크기 조정 Resize 화면 크기 조정은 텍스트를 포함하여 화면에 표시되는 정보를 확대하거나 축소하는 데 사용되는 요소이다. 사용자에 따라 읽을 수 있는 텍스트의 크기, 조작할 수 있는 요소의 크기는 다르다. 디바이스나 사용자 에이전트가 지원하는 여러 가지 설정 기능을 활용하면 사용자가 선호하는 방식으로 콘텐츠의 표시 방식을 수정할 수 있다. 그러나 화면 크기 조정 기능을 필요로 하는 사용자는 관련 기능을 찾아 설정하는 데 어려움을 겪을 가능성이 높으므로 서비스 자체적으로 화면 크기 조정 기능을 제공하고 접근하기 쉽게 만드는 것이 중요하다. ## 기본 크기를 고르면 `document.body.style.zoom`을 0.9~1.5배로 바꿔 화면 전체를 확대·축소하므로 예제를 별도 화면(iframe)에 띄웁니다. 초기화 버튼은 보통(1배)으로 되돌립니다. ```vue ``` ## v-model `v-model`로 고른 크기(`sm` 작게 · `md` 보통 · `lg` 조금 크게 · `xlg` 크게 · `xxlg` 가장 크게)를 주고받습니다. 처음 값을 주면 그 크기로 시작하고, 고른 값을 저장해 두었다가 다음 방문 때 다시 넘기면 사용자가 고른 크기를 유지할 수 있습니다. ```vue ``` ## API ## KrdsResize ### Props | 이름 | 타입 | 기본값 | 설명 | | --- | --- | --- | --- | | modelValue | KrdsResizeScale ('sm' \| 'md' \| 'lg' \| 'xlg' \| 'xxlg') | - | 선택한 화면 크기 (v-model). 지정하면 그 크기로 화면을 확대·축소한다 | ### Events | 이름 | 인자 | 설명 | | --- | --- | --- | | close | [] | 크기 목록이 닫힐 때 | | update:modelValue | [value: KrdsResizeScale] | 화면 크기를 골랐을 때 (v-model) | --- # 접근 가능한 미디어 Accessible multimedia 미디어 콘텐츠에 설명이 필요한 경우에 사용하는 컴포넌트이다. 정지된 이미지에 설명을 제공할 때에는 숨김 콘텐츠를, 오디오/비디오/멀티미디어 콘텐츠에 설명을 제공할 때는 접근 가능한 미디어 컴포넌트를 사용한다. ## 동영상 `src`·`title`(필수)을 주면 브라우저 기본 재생기(`