@leechanyong/ispark-ui 0.5.9 → 0.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +160 -160
- package/LICENSE +21 -21
- package/README.md +124 -124
- package/dist/icons/svg/arrow-right.svg +3 -3
- package/dist/icons/svg/check.svg +3 -3
- package/dist/icons/svg/close.svg +4 -4
- package/dist/icons/svg/eye-off.svg +6 -6
- package/dist/icons/svg/eye.svg +4 -4
- package/dist/index.d.ts +93 -0
- package/dist/ispark-ui.cjs +44 -44
- package/dist/ispark-ui.css +1 -1
- package/dist/ispark-ui.js +3295 -3060
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,160 +1,160 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
본 프로젝트는 [Keep a Changelog](https://keepachangelog.com/ko/) 형식과 [Semantic Versioning](https://semver.org/lang/ko/)을 따릅니다.
|
|
4
|
-
|
|
5
|
-
## [0.5.0] - 2026-05-07
|
|
6
|
-
|
|
7
|
-
### Added — UiModal 신규 컴포넌트
|
|
8
|
-
- **`UiModal`** — radix-vue Dialog 기반 center 모달 폼 필드. 31회 사용처 핵심 Tier.
|
|
9
|
-
- **a11y 자동**: radix-vue가 포커스 트랩 / ESC / role=dialog / aria-labelledby 처리.
|
|
10
|
-
- **size 토큰**: sm(400) / md(560·기본) / lg(800) / xl(1080) — `min(px, calc(100vw - 40px))` 반응형 자동 축소 (별도 미디어쿼리 없음).
|
|
11
|
-
- **3-슬롯 구조**: `header` (title prop fallback) / default(body) / `footer`. header slot 명시 시 default header 자동 비활성.
|
|
12
|
-
- **`title`** prop — DialogTitle 자동 연결.
|
|
13
|
-
- **`showClose`** (default true) — 우상단 X 버튼.
|
|
14
|
-
- **`showOverlay`** (default true) — 어두운 배경.
|
|
15
|
-
- **`closeOnOverlayClick`** / **`closeOnEscape`** (default true) — radix-vue 이벤트 preventDefault로 차단.
|
|
16
|
-
- **`showFullscreen`** (default false) — 헤더에 expand/collapse 토글 버튼. fullscreen 시 size 토큰 무시 + viewport 100% + border-radius 0. 닫힐 때 자동 reset.
|
|
17
|
-
- **`customClass`** / **`maxWidth`** — 추가 클래스 / size 토큰 override.
|
|
18
|
-
- 본문 길 때 `max-height: calc(100vh - 40px)` + `overflow-y: auto` (모달 내부 스크롤).
|
|
19
|
-
- overlay/content fade+scale 애니메이션 (`animation-fill-mode: forwards` 적용 — 닫힘 깜빡임 없음).
|
|
20
|
-
|
|
21
|
-
### Storybook
|
|
22
|
-
- 10 시나리오 — `Default` / `WithTitle` / `Sizes` (sm/md/lg/xl 시각 비교) / `NoCloseButton` / `WithFooter` (저장/취소 액션) / `CustomMaxWidth` (720px override) / `CustomHeaderSlot` (아바타+이름) / `NoOverlay` / `StrictNoEscape` (ESC/overlay 무시) / `Fullscreen` (토글 검증).
|
|
23
|
-
|
|
24
|
-
### Tests
|
|
25
|
-
- 자동 테스트 60 → 64 (UiModal 4개, 1개 it.skip — closeOnEscape는 jsdom radix-vue 한계로 Storybook play 검증).
|
|
26
|
-
|
|
27
|
-
### 마이그레이션 (v0.4.x → v0.5.0)
|
|
28
|
-
- breaking 없음.
|
|
29
|
-
- `radix-vue` peerDependency는 v0.4.0(UiSelect)에서 이미 추가됨 — 추가 설치 불필요.
|
|
30
|
-
- 원본 `team_agent_front`의 `position='right'` 사이드 모달은 미포함 — 추후 `UiDrawer` 별도 컴포넌트로.
|
|
31
|
-
|
|
32
|
-
## [0.4.0] - 2026-05-07
|
|
33
|
-
|
|
34
|
-
### Added — UiSelect 신규 컴포넌트
|
|
35
|
-
- **`UiSelect`** — radix-vue 기반 단일 선택 드롭다운 폼 필드. 32회 사용처 핵심 Tier.
|
|
36
|
-
- 폼 필드 풀세트: `label` / `labelHidden` / `required` / `error` / `errorMessage` / `desc` (UiInput과 동일 인터페이스).
|
|
37
|
-
- **a11y 자동**: `aria-required` / `aria-invalid` / `aria-describedby` 자동 연결, errorMessage는 `role="alert"`. radix-vue가 키보드 내비게이션 / 포커스 트랩 / ESC 닫기 처리.
|
|
38
|
-
- **size 토큰**: `sm`(28px) / `md`(32px·기본) / `lg`(40px) / `auth`(44px) — UiInput과 동일 토큰 → 검색바·필터에서 자동 정렬.
|
|
39
|
-
- **shape 토큰**: `rounded`(기본 6px) / `pill`(완전 라운드).
|
|
40
|
-
- **option.disabled** 지원 — radix-vue Item에 그대로 전달, `[data-disabled]` CSS로 흐림 처리.
|
|
41
|
-
- **빈 문자열 value 처리** — radix-vue가 `value=""` 미허용 → 내부 `__ui_select_empty__` 토큰으로 round-trip.
|
|
42
|
-
- **dev 검증** (`import.meta.env.DEV`) — 빈 옵션 / `required + label` 누락 / 중복 `option.value` 시 콘솔 경고.
|
|
43
|
-
- **`focus()` 외부 메서드** — `defineExpose`로 노출.
|
|
44
|
-
- Trigger는 scoped, Portal Content는 global SCSS로 분리 (radix-vue Portal 특성).
|
|
45
|
-
- **`SelectOption`** 타입 export — `{ label, value, disabled? }`.
|
|
46
|
-
|
|
47
|
-
### Storybook
|
|
48
|
-
- 11 시나리오 — `Default` (옵션 클릭 + change emit) / `WithLabel` / `Required` / `Error` / `ErrorMessage` (aria-invalid + describedby) / `Desc` (aria-describedby) / `Disabled` / `DisabledOption` (data-disabled) / `Sizes` (sm/md/lg/auth 정렬) / `Shapes` (rounded/pill) / `LongList` (30개 + 240px max-height 스크롤).
|
|
49
|
-
|
|
50
|
-
### Tests
|
|
51
|
-
- 자동 테스트 39 → 60개 (UiSelect 5개 추가, 1개 it.skip — emit round-trip은 jsdom Portal 한계로 Storybook play에서 검증).
|
|
52
|
-
|
|
53
|
-
### Changed
|
|
54
|
-
- `peerDependencies`에 `radix-vue ^1.9.0` 추가 — UiSelect 사용 시 사용자가 함께 설치 필요.
|
|
55
|
-
|
|
56
|
-
### 마이그레이션 (v0.3.x → v0.4.0)
|
|
57
|
-
- breaking 없음.
|
|
58
|
-
- UiSelect 사용 프로젝트는 `npm i radix-vue` 추가 필요 (peerDependencies).
|
|
59
|
-
|
|
60
|
-
## [0.3.0] - 2026-05-06
|
|
61
|
-
|
|
62
|
-
### Added — UiInput a11y/UX 1순위 누락 보강
|
|
63
|
-
- **`label`** prop + **label slot** + 자동 `id` 연결 — `<label for>` ↔ `<input id>` 매핑을 컴포넌트가 자동 처리. `id` 미지정 시 Vue 3.5 `useId`로 인스턴스별 unique id 생성 (SSR 안전).
|
|
64
|
-
- **`labelHidden`** prop — DOM에는 있지만 시각 숨김 (스크린리더만 인지). search input 등에서 placeholder 단독 노출 시.
|
|
65
|
-
- **`required`** prop과 결합 시 label 옆 빨간 별표(`*`) 자동 표시 (`aria-hidden`).
|
|
66
|
-
- **`error`** prop — input 빨간 테두리 + `aria-invalid="true"` 자동.
|
|
67
|
-
- **`errorMessage`** prop — 비어있지 않으면 `error: true` 자동 + `<p role="alert">` 빨간 텍스트로 desc 자리에 표시. input의 `aria-describedby`로 자동 연결 (desc보다 우선).
|
|
68
|
-
- **`type='url'`** 추가 — 기존 5종(text/search/password/email/tel)에 더해 6종.
|
|
69
|
-
- aria-invalid: 외부에서 attrs로 명시한 값도 존중 (내부 error 상태 우선).
|
|
70
|
-
|
|
71
|
-
### Storybook
|
|
72
|
-
- `WithLabel` 신규 스토리 — label / required / labelHidden 데모.
|
|
73
|
-
- `ErrorState` 신규 스토리 — error / errorMessage / 메시지 없는 error만 데모.
|
|
74
|
-
- `Types` 스토리에 `url` 추가.
|
|
75
|
-
- Playground argTypes에 label/labelHidden/error/errorMessage/required 추가, transform이 v-model 코드에 포함.
|
|
76
|
-
|
|
77
|
-
### Tests
|
|
78
|
-
- 자동 테스트 29 → 39개 (label 자동 id, required *, labelHidden, error/aria-invalid, errorMessage role=alert + describedby 우선순위, type=url 등).
|
|
79
|
-
|
|
80
|
-
### 마이그레이션 (v0.2.x → v0.3.0)
|
|
81
|
-
- breaking 없음. 기존 prop 시그니처 그대로.
|
|
82
|
-
- 기존 `<UiInput desc="...">` 사용처는 변동 없음. `errorMessage` 사용 시에만 desc가 자동으로 hidden.
|
|
83
|
-
|
|
84
|
-
## [0.2.0] - 2026-05-06
|
|
85
|
-
|
|
86
|
-
### Added
|
|
87
|
-
- **공용 디자인 토큰 시스템** — `src/styles/tokens/_size.scss`, `_shape.scss`. 폼/액션 컴포넌트가 공유하므로 `<UiInput size="md">` + `<UiButton size="md">`가 검색바에서 자동 정렬.
|
|
88
|
-
- `$size-{xs,sm,md,lg,auth}-{height,icon,font,padding-x}` 변수.
|
|
89
|
-
- `$shape-{rounded,pill,circle}` 변수.
|
|
90
|
-
- `$sizes`, `$shapes` SCSS map (반복 처리용).
|
|
91
|
-
- **TS 타입 export** — `SIZES`, `INPUT_SIZES`, `SHAPES` 키 배열 + `Size`, `InputSize`, `Shape` 타입을 라이브러리 entry에서 export.
|
|
92
|
-
|
|
93
|
-
### UiButton v0.2.0
|
|
94
|
-
- **size 4단계** — `xs`(24px) 추가 (기존 sm/md/lg 유지).
|
|
95
|
-
- **`shape`** 신규 prop — `rounded` / `pill` / `circle`. circle은 iconOnly 전용.
|
|
96
|
-
- **`iconSize`** 신규 prop — 미지정 시 size 따라가고, 명시 시 override.
|
|
97
|
-
- **`as="a"` + `target="_blank"`** 시 `rel="noopener noreferrer"` 자동 부여 (보안).
|
|
98
|
-
- **type prop에서 `'reset'` 제거** — 사용처 0건. `'button' | 'submit'`만 유지.
|
|
99
|
-
- 슬롯 아이콘 사이즈를 컴포넌트 size에 맞춰 자동 적용 (`:deep()` + `:not([class*='size-'])`).
|
|
100
|
-
- shape="circle" + iconOnly=false 조합 시 dev 경고.
|
|
101
|
-
- 자동 테스트 8 → 17개.
|
|
102
|
-
|
|
103
|
-
### UiInput v0.2.0 + v0.2.1 fix
|
|
104
|
-
- **size 4단계** sm/md/lg/auth — 모두 공용 토큰 사용.
|
|
105
|
-
- padding-x 토큰화 — 기존 모든 size 10px 통일에서 sm 10/md 12/lg 16/auth 10 차등.
|
|
106
|
-
- **`shape`** 신규 prop — `rounded` / `pill` (검색바). circle은 입력에 어색하여 제외.
|
|
107
|
-
- **`iconSize`** 신규 prop — UiButton과 동일 패턴.
|
|
108
|
-
- **`required`**, **`autocomplete`**, **`searchAriaLabel`** 신규 prop.
|
|
109
|
-
- **IME composition 안전 처리** — `compositionupdate` 직접 sanitize 제거. `compositionstart/end` + `isComposing` 플래그로 한글 자음 분리/stale value/중복 emit 방지.
|
|
110
|
-
- **blur clamp+step 순서 수정** — step 반올림 후 min/max 재-clamp. 예: min=0 max=1 step=0.6 value=1 → 1.2 emit되던 버그 → 1로 정정.
|
|
111
|
-
- **a11y 강화**:
|
|
112
|
-
- `inheritAttrs: false` + `useAttrs`로 native attrs(`aria-*`, `data-*`, `role` 등)를 input에 forward (wrapper 누수 차단).
|
|
113
|
-
- `desc` → input의 `aria-describedby`로 자동 연결 (Vue 3.5 `useId` 사용, SSR 안전).
|
|
114
|
-
- 검색 아이콘 `<span @click>` → `<button type="button" :disabled>` (키보드 접근).
|
|
115
|
-
- `type="search"` 시 input에 `role="searchbox"` 부여.
|
|
116
|
-
- **inputmode 분기**: `numberOnly` 단독이면 `numeric`, `allowDecimal`/`allowNegative` 시 `decimal`.
|
|
117
|
-
- **타입 정합 강화**: `update:modelValue` 타입을 `string` → `string | number`로 확장. `modelValue`가 number면 number로 emit.
|
|
118
|
-
- enter / search emit 시 `props.modelValue` 대신 DOM의 `input.value` 사용 (stale 방지).
|
|
119
|
-
- `decimals` validation — 0 이상 정수 외엔 무시 + dev 경고.
|
|
120
|
-
- `min/max/step` + `numberOnly=false` 조합 시 dev 경고.
|
|
121
|
-
- autofill 흰 배경 강제 모든 size 적용 (기존 auth-only).
|
|
122
|
-
- 자동 테스트 10 → 29개.
|
|
123
|
-
|
|
124
|
-
### Storybook 개선
|
|
125
|
-
- **Playground source.transform 도입** — Controls 변경 시 Show Code 실시간 동기. 기본값과 다른 prop만 출력. iconLeft/iconRight/label 데모 control은 slot 패턴으로 변환.
|
|
126
|
-
- argTypes에 `mapping` 사용으로 `'(자동)'`/`'(없음)'` 라벨이 reactive prop change 보장.
|
|
127
|
-
- UiButton: AllShapes 신규 / AllSizes 4단계 / AsLink target=\_blank 데모.
|
|
128
|
-
- UiInput: AllShapes 신규 / Playground transform 적용.
|
|
129
|
-
- 모든 props에 JSDoc — Storybook Controls 패널 설명 자동 추출.
|
|
130
|
-
|
|
131
|
-
### Migration notes
|
|
132
|
-
- `UiButton type="reset"` 제거 — 사용처 0건이라 사실상 무영향.
|
|
133
|
-
- `UiInput` md/lg 사용처는 padding-x가 좌우 4-6px씩 늘어남 — 검색바 톤 개선.
|
|
134
|
-
- emit 타입 `string | number`로 확장 — number prop을 쓰던 부모는 자동 number 수신.
|
|
135
|
-
|
|
136
|
-
## [Unreleased]
|
|
137
|
-
|
|
138
|
-
### Changed
|
|
139
|
-
- **scope `@box3101` → `@leechanyong`** 으로 변경 (GitHub은 box3101, npmjs는 leechanyong username). 패키지 import 경로 변경됨.
|
|
140
|
-
- **registry: GitHub Packages → npmjs.com** 으로 전환. 진짜 anonymous install 가능 (`.npmrc` 설정 불필요).
|
|
141
|
-
- GitHub Actions 워크플로우: `NPM_TOKEN` 시크릿 사용.
|
|
142
|
-
- README 설치 가이드 1줄로 단순화 (`npm install @leechanyong/ispark-ui`).
|
|
143
|
-
- **public 전환** — repo + package 모두 public.
|
|
144
|
-
- 라이센스 `UNLICENSED` → **`MIT`** 변경. `LICENSE` 파일 추가.
|
|
145
|
-
|
|
146
|
-
## [0.1.0] - 2026-04-28
|
|
147
|
-
|
|
148
|
-
### Added
|
|
149
|
-
- 초기 라이브러리 셋업 (Vue 3 + Vite + Storybook + Vitest)
|
|
150
|
-
- **UiButton** 컴포넌트
|
|
151
|
-
- variant 4종: `primary` / `secondary` / `ghost` / `danger`
|
|
152
|
-
- size 3종: `sm` (28px) / `md` (32px) / `lg` (40px)
|
|
153
|
-
- states: `disabled` / `loading` (스피너 사이즈 자동) / `fullWidth` / `iconOnly`
|
|
154
|
-
- polymorphic: `as="button" | "a"` (링크로 사용 가능)
|
|
155
|
-
- 안전성: `type="button"` 기본값, `as="a"` + `disabled` 시 `aria-disabled` + `tabindex=-1`
|
|
156
|
-
- 접근성: `iconOnly` + `ariaLabel` 강제 (dev 콘솔 경고)
|
|
157
|
-
- 외부 메서드: `defineExpose({ focus, blur, el })`
|
|
158
|
-
- 디자인 토큰 시스템 — CSS 변수로 런타임 테마 오버라이드 가능
|
|
159
|
-
- 아이콘 시스템 — 10종 SVG (plus/edit/trashcan/close/search/check/arrow-right/download/chevron-down/refresh), base64 인라인으로 self-contained
|
|
160
|
-
- 자동 테스트 8개 (vitest) + Storybook 8 stories + autodocs
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
본 프로젝트는 [Keep a Changelog](https://keepachangelog.com/ko/) 형식과 [Semantic Versioning](https://semver.org/lang/ko/)을 따릅니다.
|
|
4
|
+
|
|
5
|
+
## [0.5.0] - 2026-05-07
|
|
6
|
+
|
|
7
|
+
### Added — UiModal 신규 컴포넌트
|
|
8
|
+
- **`UiModal`** — radix-vue Dialog 기반 center 모달 폼 필드. 31회 사용처 핵심 Tier.
|
|
9
|
+
- **a11y 자동**: radix-vue가 포커스 트랩 / ESC / role=dialog / aria-labelledby 처리.
|
|
10
|
+
- **size 토큰**: sm(400) / md(560·기본) / lg(800) / xl(1080) — `min(px, calc(100vw - 40px))` 반응형 자동 축소 (별도 미디어쿼리 없음).
|
|
11
|
+
- **3-슬롯 구조**: `header` (title prop fallback) / default(body) / `footer`. header slot 명시 시 default header 자동 비활성.
|
|
12
|
+
- **`title`** prop — DialogTitle 자동 연결.
|
|
13
|
+
- **`showClose`** (default true) — 우상단 X 버튼.
|
|
14
|
+
- **`showOverlay`** (default true) — 어두운 배경.
|
|
15
|
+
- **`closeOnOverlayClick`** / **`closeOnEscape`** (default true) — radix-vue 이벤트 preventDefault로 차단.
|
|
16
|
+
- **`showFullscreen`** (default false) — 헤더에 expand/collapse 토글 버튼. fullscreen 시 size 토큰 무시 + viewport 100% + border-radius 0. 닫힐 때 자동 reset.
|
|
17
|
+
- **`customClass`** / **`maxWidth`** — 추가 클래스 / size 토큰 override.
|
|
18
|
+
- 본문 길 때 `max-height: calc(100vh - 40px)` + `overflow-y: auto` (모달 내부 스크롤).
|
|
19
|
+
- overlay/content fade+scale 애니메이션 (`animation-fill-mode: forwards` 적용 — 닫힘 깜빡임 없음).
|
|
20
|
+
|
|
21
|
+
### Storybook
|
|
22
|
+
- 10 시나리오 — `Default` / `WithTitle` / `Sizes` (sm/md/lg/xl 시각 비교) / `NoCloseButton` / `WithFooter` (저장/취소 액션) / `CustomMaxWidth` (720px override) / `CustomHeaderSlot` (아바타+이름) / `NoOverlay` / `StrictNoEscape` (ESC/overlay 무시) / `Fullscreen` (토글 검증).
|
|
23
|
+
|
|
24
|
+
### Tests
|
|
25
|
+
- 자동 테스트 60 → 64 (UiModal 4개, 1개 it.skip — closeOnEscape는 jsdom radix-vue 한계로 Storybook play 검증).
|
|
26
|
+
|
|
27
|
+
### 마이그레이션 (v0.4.x → v0.5.0)
|
|
28
|
+
- breaking 없음.
|
|
29
|
+
- `radix-vue` peerDependency는 v0.4.0(UiSelect)에서 이미 추가됨 — 추가 설치 불필요.
|
|
30
|
+
- 원본 `team_agent_front`의 `position='right'` 사이드 모달은 미포함 — 추후 `UiDrawer` 별도 컴포넌트로.
|
|
31
|
+
|
|
32
|
+
## [0.4.0] - 2026-05-07
|
|
33
|
+
|
|
34
|
+
### Added — UiSelect 신규 컴포넌트
|
|
35
|
+
- **`UiSelect`** — radix-vue 기반 단일 선택 드롭다운 폼 필드. 32회 사용처 핵심 Tier.
|
|
36
|
+
- 폼 필드 풀세트: `label` / `labelHidden` / `required` / `error` / `errorMessage` / `desc` (UiInput과 동일 인터페이스).
|
|
37
|
+
- **a11y 자동**: `aria-required` / `aria-invalid` / `aria-describedby` 자동 연결, errorMessage는 `role="alert"`. radix-vue가 키보드 내비게이션 / 포커스 트랩 / ESC 닫기 처리.
|
|
38
|
+
- **size 토큰**: `sm`(28px) / `md`(32px·기본) / `lg`(40px) / `auth`(44px) — UiInput과 동일 토큰 → 검색바·필터에서 자동 정렬.
|
|
39
|
+
- **shape 토큰**: `rounded`(기본 6px) / `pill`(완전 라운드).
|
|
40
|
+
- **option.disabled** 지원 — radix-vue Item에 그대로 전달, `[data-disabled]` CSS로 흐림 처리.
|
|
41
|
+
- **빈 문자열 value 처리** — radix-vue가 `value=""` 미허용 → 내부 `__ui_select_empty__` 토큰으로 round-trip.
|
|
42
|
+
- **dev 검증** (`import.meta.env.DEV`) — 빈 옵션 / `required + label` 누락 / 중복 `option.value` 시 콘솔 경고.
|
|
43
|
+
- **`focus()` 외부 메서드** — `defineExpose`로 노출.
|
|
44
|
+
- Trigger는 scoped, Portal Content는 global SCSS로 분리 (radix-vue Portal 특성).
|
|
45
|
+
- **`SelectOption`** 타입 export — `{ label, value, disabled? }`.
|
|
46
|
+
|
|
47
|
+
### Storybook
|
|
48
|
+
- 11 시나리오 — `Default` (옵션 클릭 + change emit) / `WithLabel` / `Required` / `Error` / `ErrorMessage` (aria-invalid + describedby) / `Desc` (aria-describedby) / `Disabled` / `DisabledOption` (data-disabled) / `Sizes` (sm/md/lg/auth 정렬) / `Shapes` (rounded/pill) / `LongList` (30개 + 240px max-height 스크롤).
|
|
49
|
+
|
|
50
|
+
### Tests
|
|
51
|
+
- 자동 테스트 39 → 60개 (UiSelect 5개 추가, 1개 it.skip — emit round-trip은 jsdom Portal 한계로 Storybook play에서 검증).
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
- `peerDependencies`에 `radix-vue ^1.9.0` 추가 — UiSelect 사용 시 사용자가 함께 설치 필요.
|
|
55
|
+
|
|
56
|
+
### 마이그레이션 (v0.3.x → v0.4.0)
|
|
57
|
+
- breaking 없음.
|
|
58
|
+
- UiSelect 사용 프로젝트는 `npm i radix-vue` 추가 필요 (peerDependencies).
|
|
59
|
+
|
|
60
|
+
## [0.3.0] - 2026-05-06
|
|
61
|
+
|
|
62
|
+
### Added — UiInput a11y/UX 1순위 누락 보강
|
|
63
|
+
- **`label`** prop + **label slot** + 자동 `id` 연결 — `<label for>` ↔ `<input id>` 매핑을 컴포넌트가 자동 처리. `id` 미지정 시 Vue 3.5 `useId`로 인스턴스별 unique id 생성 (SSR 안전).
|
|
64
|
+
- **`labelHidden`** prop — DOM에는 있지만 시각 숨김 (스크린리더만 인지). search input 등에서 placeholder 단독 노출 시.
|
|
65
|
+
- **`required`** prop과 결합 시 label 옆 빨간 별표(`*`) 자동 표시 (`aria-hidden`).
|
|
66
|
+
- **`error`** prop — input 빨간 테두리 + `aria-invalid="true"` 자동.
|
|
67
|
+
- **`errorMessage`** prop — 비어있지 않으면 `error: true` 자동 + `<p role="alert">` 빨간 텍스트로 desc 자리에 표시. input의 `aria-describedby`로 자동 연결 (desc보다 우선).
|
|
68
|
+
- **`type='url'`** 추가 — 기존 5종(text/search/password/email/tel)에 더해 6종.
|
|
69
|
+
- aria-invalid: 외부에서 attrs로 명시한 값도 존중 (내부 error 상태 우선).
|
|
70
|
+
|
|
71
|
+
### Storybook
|
|
72
|
+
- `WithLabel` 신규 스토리 — label / required / labelHidden 데모.
|
|
73
|
+
- `ErrorState` 신규 스토리 — error / errorMessage / 메시지 없는 error만 데모.
|
|
74
|
+
- `Types` 스토리에 `url` 추가.
|
|
75
|
+
- Playground argTypes에 label/labelHidden/error/errorMessage/required 추가, transform이 v-model 코드에 포함.
|
|
76
|
+
|
|
77
|
+
### Tests
|
|
78
|
+
- 자동 테스트 29 → 39개 (label 자동 id, required *, labelHidden, error/aria-invalid, errorMessage role=alert + describedby 우선순위, type=url 등).
|
|
79
|
+
|
|
80
|
+
### 마이그레이션 (v0.2.x → v0.3.0)
|
|
81
|
+
- breaking 없음. 기존 prop 시그니처 그대로.
|
|
82
|
+
- 기존 `<UiInput desc="...">` 사용처는 변동 없음. `errorMessage` 사용 시에만 desc가 자동으로 hidden.
|
|
83
|
+
|
|
84
|
+
## [0.2.0] - 2026-05-06
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
- **공용 디자인 토큰 시스템** — `src/styles/tokens/_size.scss`, `_shape.scss`. 폼/액션 컴포넌트가 공유하므로 `<UiInput size="md">` + `<UiButton size="md">`가 검색바에서 자동 정렬.
|
|
88
|
+
- `$size-{xs,sm,md,lg,auth}-{height,icon,font,padding-x}` 변수.
|
|
89
|
+
- `$shape-{rounded,pill,circle}` 변수.
|
|
90
|
+
- `$sizes`, `$shapes` SCSS map (반복 처리용).
|
|
91
|
+
- **TS 타입 export** — `SIZES`, `INPUT_SIZES`, `SHAPES` 키 배열 + `Size`, `InputSize`, `Shape` 타입을 라이브러리 entry에서 export.
|
|
92
|
+
|
|
93
|
+
### UiButton v0.2.0
|
|
94
|
+
- **size 4단계** — `xs`(24px) 추가 (기존 sm/md/lg 유지).
|
|
95
|
+
- **`shape`** 신규 prop — `rounded` / `pill` / `circle`. circle은 iconOnly 전용.
|
|
96
|
+
- **`iconSize`** 신규 prop — 미지정 시 size 따라가고, 명시 시 override.
|
|
97
|
+
- **`as="a"` + `target="_blank"`** 시 `rel="noopener noreferrer"` 자동 부여 (보안).
|
|
98
|
+
- **type prop에서 `'reset'` 제거** — 사용처 0건. `'button' | 'submit'`만 유지.
|
|
99
|
+
- 슬롯 아이콘 사이즈를 컴포넌트 size에 맞춰 자동 적용 (`:deep()` + `:not([class*='size-'])`).
|
|
100
|
+
- shape="circle" + iconOnly=false 조합 시 dev 경고.
|
|
101
|
+
- 자동 테스트 8 → 17개.
|
|
102
|
+
|
|
103
|
+
### UiInput v0.2.0 + v0.2.1 fix
|
|
104
|
+
- **size 4단계** sm/md/lg/auth — 모두 공용 토큰 사용.
|
|
105
|
+
- padding-x 토큰화 — 기존 모든 size 10px 통일에서 sm 10/md 12/lg 16/auth 10 차등.
|
|
106
|
+
- **`shape`** 신규 prop — `rounded` / `pill` (검색바). circle은 입력에 어색하여 제외.
|
|
107
|
+
- **`iconSize`** 신규 prop — UiButton과 동일 패턴.
|
|
108
|
+
- **`required`**, **`autocomplete`**, **`searchAriaLabel`** 신규 prop.
|
|
109
|
+
- **IME composition 안전 처리** — `compositionupdate` 직접 sanitize 제거. `compositionstart/end` + `isComposing` 플래그로 한글 자음 분리/stale value/중복 emit 방지.
|
|
110
|
+
- **blur clamp+step 순서 수정** — step 반올림 후 min/max 재-clamp. 예: min=0 max=1 step=0.6 value=1 → 1.2 emit되던 버그 → 1로 정정.
|
|
111
|
+
- **a11y 강화**:
|
|
112
|
+
- `inheritAttrs: false` + `useAttrs`로 native attrs(`aria-*`, `data-*`, `role` 등)를 input에 forward (wrapper 누수 차단).
|
|
113
|
+
- `desc` → input의 `aria-describedby`로 자동 연결 (Vue 3.5 `useId` 사용, SSR 안전).
|
|
114
|
+
- 검색 아이콘 `<span @click>` → `<button type="button" :disabled>` (키보드 접근).
|
|
115
|
+
- `type="search"` 시 input에 `role="searchbox"` 부여.
|
|
116
|
+
- **inputmode 분기**: `numberOnly` 단독이면 `numeric`, `allowDecimal`/`allowNegative` 시 `decimal`.
|
|
117
|
+
- **타입 정합 강화**: `update:modelValue` 타입을 `string` → `string | number`로 확장. `modelValue`가 number면 number로 emit.
|
|
118
|
+
- enter / search emit 시 `props.modelValue` 대신 DOM의 `input.value` 사용 (stale 방지).
|
|
119
|
+
- `decimals` validation — 0 이상 정수 외엔 무시 + dev 경고.
|
|
120
|
+
- `min/max/step` + `numberOnly=false` 조합 시 dev 경고.
|
|
121
|
+
- autofill 흰 배경 강제 모든 size 적용 (기존 auth-only).
|
|
122
|
+
- 자동 테스트 10 → 29개.
|
|
123
|
+
|
|
124
|
+
### Storybook 개선
|
|
125
|
+
- **Playground source.transform 도입** — Controls 변경 시 Show Code 실시간 동기. 기본값과 다른 prop만 출력. iconLeft/iconRight/label 데모 control은 slot 패턴으로 변환.
|
|
126
|
+
- argTypes에 `mapping` 사용으로 `'(자동)'`/`'(없음)'` 라벨이 reactive prop change 보장.
|
|
127
|
+
- UiButton: AllShapes 신규 / AllSizes 4단계 / AsLink target=\_blank 데모.
|
|
128
|
+
- UiInput: AllShapes 신규 / Playground transform 적용.
|
|
129
|
+
- 모든 props에 JSDoc — Storybook Controls 패널 설명 자동 추출.
|
|
130
|
+
|
|
131
|
+
### Migration notes
|
|
132
|
+
- `UiButton type="reset"` 제거 — 사용처 0건이라 사실상 무영향.
|
|
133
|
+
- `UiInput` md/lg 사용처는 padding-x가 좌우 4-6px씩 늘어남 — 검색바 톤 개선.
|
|
134
|
+
- emit 타입 `string | number`로 확장 — number prop을 쓰던 부모는 자동 number 수신.
|
|
135
|
+
|
|
136
|
+
## [Unreleased]
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
- **scope `@box3101` → `@leechanyong`** 으로 변경 (GitHub은 box3101, npmjs는 leechanyong username). 패키지 import 경로 변경됨.
|
|
140
|
+
- **registry: GitHub Packages → npmjs.com** 으로 전환. 진짜 anonymous install 가능 (`.npmrc` 설정 불필요).
|
|
141
|
+
- GitHub Actions 워크플로우: `NPM_TOKEN` 시크릿 사용.
|
|
142
|
+
- README 설치 가이드 1줄로 단순화 (`npm install @leechanyong/ispark-ui`).
|
|
143
|
+
- **public 전환** — repo + package 모두 public.
|
|
144
|
+
- 라이센스 `UNLICENSED` → **`MIT`** 변경. `LICENSE` 파일 추가.
|
|
145
|
+
|
|
146
|
+
## [0.1.0] - 2026-04-28
|
|
147
|
+
|
|
148
|
+
### Added
|
|
149
|
+
- 초기 라이브러리 셋업 (Vue 3 + Vite + Storybook + Vitest)
|
|
150
|
+
- **UiButton** 컴포넌트
|
|
151
|
+
- variant 4종: `primary` / `secondary` / `ghost` / `danger`
|
|
152
|
+
- size 3종: `sm` (28px) / `md` (32px) / `lg` (40px)
|
|
153
|
+
- states: `disabled` / `loading` (스피너 사이즈 자동) / `fullWidth` / `iconOnly`
|
|
154
|
+
- polymorphic: `as="button" | "a"` (링크로 사용 가능)
|
|
155
|
+
- 안전성: `type="button"` 기본값, `as="a"` + `disabled` 시 `aria-disabled` + `tabindex=-1`
|
|
156
|
+
- 접근성: `iconOnly` + `ariaLabel` 강제 (dev 콘솔 경고)
|
|
157
|
+
- 외부 메서드: `defineExpose({ focus, blur, el })`
|
|
158
|
+
- 디자인 토큰 시스템 — CSS 변수로 런타임 테마 오버라이드 가능
|
|
159
|
+
- 아이콘 시스템 — 10종 SVG (plus/edit/trashcan/close/search/check/arrow-right/download/chevron-down/refresh), base64 인라인으로 self-contained
|
|
160
|
+
- 자동 테스트 8개 (vitest) + Storybook 8 stories + autodocs
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 box3101 <tony.at.cp@gmail.com>
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 box3101 <tony.at.cp@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
# @leechanyong/ispark-ui
|
|
2
|
-
|
|
3
|
-
Vue 3 + Vite + Storybook 기반 디자인 시스템 UI 라이브러리.
|
|
4
|
-
|
|
5
|
-
> ⚠️ **테스트 단계 (v0.1.x)** — API가 자주 바뀔 수 있습니다. 프로덕션에서 사용 시 버전 고정 권장.
|
|
6
|
-
|
|
7
|
-
## 설치
|
|
8
|
-
|
|
9
|
-
### Git URL 직접 설치 (현재 권장 — 인증 불필요)
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
# 최신 main 브랜치
|
|
13
|
-
npm install git+https://github.com/box3101/ispark-ui.git
|
|
14
|
-
|
|
15
|
-
# 또는 특정 태그 (안정 버전 고정)
|
|
16
|
-
npm install git+https://github.com/box3101/ispark-ui.git#v0.1.4
|
|
17
|
-
|
|
18
|
-
# package.json에 명시
|
|
19
|
-
# "@leechanyong/ispark-ui": "github:box3101/ispark-ui#v0.1.4"
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
설치 시 자동으로 빌드(`prepare` 훅)되어 바로 사용 가능합니다.
|
|
23
|
-
|
|
24
|
-
### npm registry 설치 (예정 — 미정)
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
# 향후 npmjs.com 또는 GitHub Packages publish 후 가능
|
|
28
|
-
npm install @leechanyong/ispark-ui
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## 사용
|
|
32
|
-
|
|
33
|
-
### 컴포넌트 import
|
|
34
|
-
|
|
35
|
-
```vue
|
|
36
|
-
<script setup lang="ts">
|
|
37
|
-
import { UiButton } from '@leechanyong/ispark-ui'
|
|
38
|
-
import '@leechanyong/ispark-ui/style.css' // 글로벌 스타일 1회 import (앱 진입점에서)
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<template>
|
|
42
|
-
<UiButton variant="primary" @click="handleSave">저장</UiButton>
|
|
43
|
-
</template>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 글로벌 스타일은 앱 진입점에서 1회만
|
|
47
|
-
|
|
48
|
-
```ts
|
|
49
|
-
// main.ts (Vue) 또는 app.vue (Nuxt)
|
|
50
|
-
import '@leechanyong/ispark-ui/style.css'
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
이 1줄로 다음이 한 번에 적용됩니다:
|
|
54
|
-
- CSS 변수 (`--color-primary` 등 — 테마 오버라이드 가능)
|
|
55
|
-
- 아이콘 클래스 (`.icon-plus`, `.icon-edit` 등 — 10종 base64 인라인)
|
|
56
|
-
- 기본 reset
|
|
57
|
-
|
|
58
|
-
## 컴포넌트
|
|
59
|
-
|
|
60
|
-
### UiButton
|
|
61
|
-
|
|
62
|
-
```vue
|
|
63
|
-
<UiButton variant="primary" size="md" @click="...">저장</UiButton>
|
|
64
|
-
|
|
65
|
-
<!-- variant: primary | secondary | ghost | danger -->
|
|
66
|
-
<!-- size: sm(28px) | md(32px) | lg(40px) -->
|
|
67
|
-
|
|
68
|
-
<!-- 아이콘 -->
|
|
69
|
-
<UiButton variant="primary">
|
|
70
|
-
<template #icon-left><i class="icon-plus size-16" /></template>
|
|
71
|
-
Agent 추가
|
|
72
|
-
</UiButton>
|
|
73
|
-
|
|
74
|
-
<!-- 아이콘만 (ariaLabel 필수) -->
|
|
75
|
-
<UiButton variant="ghost" iconOnly aria-label="삭제">
|
|
76
|
-
<template #icon-left><i class="icon-trashcan size-16" /></template>
|
|
77
|
-
</UiButton>
|
|
78
|
-
|
|
79
|
-
<!-- 링크로 -->
|
|
80
|
-
<UiButton as="a" href="/agent/list" variant="secondary">목록 보기</UiButton>
|
|
81
|
-
|
|
82
|
-
<!-- 외부 ref -->
|
|
83
|
-
<script setup>
|
|
84
|
-
import { ref } from 'vue'
|
|
85
|
-
const btnRef = ref()
|
|
86
|
-
btnRef.value.focus() // defineExpose된 메서드
|
|
87
|
-
</script>
|
|
88
|
-
<UiButton ref="btnRef">포커스 대상</UiButton>
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
전체 props는 Storybook 문서를 참고하세요.
|
|
92
|
-
|
|
93
|
-
## 테마 오버라이드
|
|
94
|
-
|
|
95
|
-
CSS 변수만 덮으면 됩니다:
|
|
96
|
-
|
|
97
|
-
```css
|
|
98
|
-
/* 소비측 앱의 글로벌 CSS */
|
|
99
|
-
:root {
|
|
100
|
-
--color-primary: #ff7518; /* 오렌지 테마로 */
|
|
101
|
-
--color-primary-hover: #e5660f;
|
|
102
|
-
--color-primary-dark: #c73e07;
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## 개발 환경
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
npm install
|
|
110
|
-
npm run storybook # Storybook (포트 6006)
|
|
111
|
-
npm test # Vitest
|
|
112
|
-
npm run build # 라이브러리 빌드 (dist/)
|
|
113
|
-
npm run build:icons # SVG → base64 inline 재생성 (아이콘 추가 시)
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
## 아이콘 추가하기
|
|
117
|
-
|
|
118
|
-
1. `public/icons/svg/{name}.svg` 에 SVG 추가
|
|
119
|
-
2. `npm run build:icons` 실행
|
|
120
|
-
3. `<i class="icon-{name} size-16" />` 로 사용
|
|
121
|
-
|
|
122
|
-
## 라이센스
|
|
123
|
-
|
|
124
|
-
MIT — 자유롭게 사용·수정·배포 가능.
|
|
1
|
+
# @leechanyong/ispark-ui
|
|
2
|
+
|
|
3
|
+
Vue 3 + Vite + Storybook 기반 디자인 시스템 UI 라이브러리.
|
|
4
|
+
|
|
5
|
+
> ⚠️ **테스트 단계 (v0.1.x)** — API가 자주 바뀔 수 있습니다. 프로덕션에서 사용 시 버전 고정 권장.
|
|
6
|
+
|
|
7
|
+
## 설치
|
|
8
|
+
|
|
9
|
+
### Git URL 직접 설치 (현재 권장 — 인증 불필요)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 최신 main 브랜치
|
|
13
|
+
npm install git+https://github.com/box3101/ispark-ui.git
|
|
14
|
+
|
|
15
|
+
# 또는 특정 태그 (안정 버전 고정)
|
|
16
|
+
npm install git+https://github.com/box3101/ispark-ui.git#v0.1.4
|
|
17
|
+
|
|
18
|
+
# package.json에 명시
|
|
19
|
+
# "@leechanyong/ispark-ui": "github:box3101/ispark-ui#v0.1.4"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
설치 시 자동으로 빌드(`prepare` 훅)되어 바로 사용 가능합니다.
|
|
23
|
+
|
|
24
|
+
### npm registry 설치 (예정 — 미정)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 향후 npmjs.com 또는 GitHub Packages publish 후 가능
|
|
28
|
+
npm install @leechanyong/ispark-ui
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 사용
|
|
32
|
+
|
|
33
|
+
### 컴포넌트 import
|
|
34
|
+
|
|
35
|
+
```vue
|
|
36
|
+
<script setup lang="ts">
|
|
37
|
+
import { UiButton } from '@leechanyong/ispark-ui'
|
|
38
|
+
import '@leechanyong/ispark-ui/style.css' // 글로벌 스타일 1회 import (앱 진입점에서)
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<UiButton variant="primary" @click="handleSave">저장</UiButton>
|
|
43
|
+
</template>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 글로벌 스타일은 앱 진입점에서 1회만
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
// main.ts (Vue) 또는 app.vue (Nuxt)
|
|
50
|
+
import '@leechanyong/ispark-ui/style.css'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
이 1줄로 다음이 한 번에 적용됩니다:
|
|
54
|
+
- CSS 변수 (`--color-primary` 등 — 테마 오버라이드 가능)
|
|
55
|
+
- 아이콘 클래스 (`.icon-plus`, `.icon-edit` 등 — 10종 base64 인라인)
|
|
56
|
+
- 기본 reset
|
|
57
|
+
|
|
58
|
+
## 컴포넌트
|
|
59
|
+
|
|
60
|
+
### UiButton
|
|
61
|
+
|
|
62
|
+
```vue
|
|
63
|
+
<UiButton variant="primary" size="md" @click="...">저장</UiButton>
|
|
64
|
+
|
|
65
|
+
<!-- variant: primary | secondary | ghost | danger -->
|
|
66
|
+
<!-- size: sm(28px) | md(32px) | lg(40px) -->
|
|
67
|
+
|
|
68
|
+
<!-- 아이콘 -->
|
|
69
|
+
<UiButton variant="primary">
|
|
70
|
+
<template #icon-left><i class="icon-plus size-16" /></template>
|
|
71
|
+
Agent 추가
|
|
72
|
+
</UiButton>
|
|
73
|
+
|
|
74
|
+
<!-- 아이콘만 (ariaLabel 필수) -->
|
|
75
|
+
<UiButton variant="ghost" iconOnly aria-label="삭제">
|
|
76
|
+
<template #icon-left><i class="icon-trashcan size-16" /></template>
|
|
77
|
+
</UiButton>
|
|
78
|
+
|
|
79
|
+
<!-- 링크로 -->
|
|
80
|
+
<UiButton as="a" href="/agent/list" variant="secondary">목록 보기</UiButton>
|
|
81
|
+
|
|
82
|
+
<!-- 외부 ref -->
|
|
83
|
+
<script setup>
|
|
84
|
+
import { ref } from 'vue'
|
|
85
|
+
const btnRef = ref()
|
|
86
|
+
btnRef.value.focus() // defineExpose된 메서드
|
|
87
|
+
</script>
|
|
88
|
+
<UiButton ref="btnRef">포커스 대상</UiButton>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
전체 props는 Storybook 문서를 참고하세요.
|
|
92
|
+
|
|
93
|
+
## 테마 오버라이드
|
|
94
|
+
|
|
95
|
+
CSS 변수만 덮으면 됩니다:
|
|
96
|
+
|
|
97
|
+
```css
|
|
98
|
+
/* 소비측 앱의 글로벌 CSS */
|
|
99
|
+
:root {
|
|
100
|
+
--color-primary: #ff7518; /* 오렌지 테마로 */
|
|
101
|
+
--color-primary-hover: #e5660f;
|
|
102
|
+
--color-primary-dark: #c73e07;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 개발 환경
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm install
|
|
110
|
+
npm run storybook # Storybook (포트 6006)
|
|
111
|
+
npm test # Vitest
|
|
112
|
+
npm run build # 라이브러리 빌드 (dist/)
|
|
113
|
+
npm run build:icons # SVG → base64 inline 재생성 (아이콘 추가 시)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 아이콘 추가하기
|
|
117
|
+
|
|
118
|
+
1. `public/icons/svg/{name}.svg` 에 SVG 추가
|
|
119
|
+
2. `npm run build:icons` 실행
|
|
120
|
+
3. `<i class="icon-{name} size-16" />` 로 사용
|
|
121
|
+
|
|
122
|
+
## 라이센스
|
|
123
|
+
|
|
124
|
+
MIT — 자유롭게 사용·수정·배포 가능.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
<svg width="16" height="20" viewBox="0 0 16 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.80292 15.157C4.99996 15.3759 5.33718 15.3937 5.55613 15.1966L10.8895 10.3968C11.0018 10.2957 11.066 10.1516 11.066 10.0004C11.066 9.84923 11.0019 9.70515 10.8895 9.604L5.55615 4.80367C5.33722 4.60662 4.99999 4.62436 4.80294 4.84329C4.60589 5.06222 4.62363 5.39945 4.84256 5.5965L9.73544 10.0004L4.84258 14.4038C4.62364 14.6008 4.60588 14.938 4.80292 15.157Z" fill="#000"/>
|
|
3
|
-
</svg>
|
|
1
|
+
<svg width="16" height="20" viewBox="0 0 16 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.80292 15.157C4.99996 15.3759 5.33718 15.3937 5.55613 15.1966L10.8895 10.3968C11.0018 10.2957 11.066 10.1516 11.066 10.0004C11.066 9.84923 11.0019 9.70515 10.8895 9.604L5.55615 4.80367C5.33722 4.60662 4.99999 4.62436 4.80294 4.84329C4.60589 5.06222 4.62363 5.39945 4.84256 5.5965L9.73544 10.0004L4.84258 14.4038C4.62364 14.6008 4.60588 14.938 4.80292 15.157Z" fill="#000"/>
|
|
3
|
+
</svg>
|
package/dist/icons/svg/check.svg
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path d="M19.5459 5.15741C20.0111 4.68577 20.7708 4.68073 21.2428 5.14569C21.7144 5.61085 21.7195 6.37061 21.2545 6.84256L9.43263 18.8426C9.2072 19.0712 8.89943 19.1999 8.57833 19.2C8.25699 19.2 7.94839 19.0715 7.72286 18.8426L2.74591 13.7894C2.28086 13.3174 2.28574 12.5577 2.75763 12.0926C3.2297 11.6275 3.98937 11.6335 4.4545 12.1055L8.57716 16.289L19.5459 5.15741Z" fill="#5C6677"/>
|
|
3
|
-
</svg>
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M19.5459 5.15741C20.0111 4.68577 20.7708 4.68073 21.2428 5.14569C21.7144 5.61085 21.7195 6.37061 21.2545 6.84256L9.43263 18.8426C9.2072 19.0712 8.89943 19.1999 8.57833 19.2C8.25699 19.2 7.94839 19.0715 7.72286 18.8426L2.74591 13.7894C2.28086 13.3174 2.28574 12.5577 2.75763 12.0926C3.2297 11.6275 3.98937 11.6335 4.4545 12.1055L8.57716 16.289L19.5459 5.15741Z" fill="#5C6677"/>
|
|
3
|
+
</svg>
|