@j-solution/components 1.4.2 → 1.4.3
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/README.md +412 -412
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,413 +1,413 @@
|
|
|
1
|
-
# J-Component
|
|
2
|
-
|
|
3
|
-
> Vue.js 3 기반 Atomic Design 패턴 컴포넌트 라이브러리
|
|
4
|
-
|
|
5
|
-
## 📋 프로젝트 개요
|
|
6
|
-
|
|
7
|
-
J-Component는 Vue.js 3와 TypeScript를 기반으로 한 재사용 가능한 UI 컴포넌트 라이브러리입니다. shadcn/ui 디자인 시스템과 Atomic Design 패턴을 적용하여 일관성 있고 확장 가능한 컴포넌트를 제공합니다.
|
|
8
|
-
|
|
9
|
-
## 🚀 현재 버전: v1.4.
|
|
10
|
-
|
|
11
|
-
**최신 업데이트 (2026년 2월 5일)**
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
|
|
15
|
-
[전체 릴리즈 노트 보기](./RELEASE_NOTES.md)
|
|
16
|
-
|
|
17
|
-
## 🛠️ 기술 스택
|
|
18
|
-
|
|
19
|
-
### 핵심 프레임워크
|
|
20
|
-
- **Vue.js 3.5** - 프론트엔드 프레임워크
|
|
21
|
-
- **TypeScript 5.9** - 타입 시스템
|
|
22
|
-
- **Vite 7** - 빌드 도구
|
|
23
|
-
|
|
24
|
-
### UI & 스타일링
|
|
25
|
-
- **TailwindCSS 3.4** - 유틸리티 CSS 프레임워크
|
|
26
|
-
- **shadcn/ui** - 디자인 시스템 (radix-vue 기반)
|
|
27
|
-
- **Lucide Icons** - 아이콘 라이브러리
|
|
28
|
-
|
|
29
|
-
### 개발 도구
|
|
30
|
-
- **Storybook 9** - 컴포넌트 문서화 및 테스트
|
|
31
|
-
- Docs 탭: 다양한 폼 스키마/도메인 예시 자동 미리보기 지원
|
|
32
|
-
- 테마 셀렉터: 5가지 tweakcn 테마 지원 (Default, Slate, Rose, Blue, Green)
|
|
33
|
-
- 다크모드 토글: 라이트/다크 모드 실시간 전환
|
|
34
|
-
- **ESLint 9** - 코드 품질 검사
|
|
35
|
-
- **Prettier** - 코드 포맷팅
|
|
36
|
-
|
|
37
|
-
## 📁 프로젝트 구조
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
jwms-portal-frontend/
|
|
41
|
-
├── src/
|
|
42
|
-
│ ├── components/ # Atomic Design Components
|
|
43
|
-
│ │ ├── atoms/ # 기본 UI 요소 (JButton, JInput, JIcon 등)
|
|
44
|
-
│ │ ├── molecules/ # atoms의 조합 (JFormField, JCard, JAlert 등)
|
|
45
|
-
│ │ ├── organisms/ # molecules의 조합 (JModal, JDynamicTabs, JDynamicForm 등)
|
|
46
|
-
│ │ ├── shadcn/ # shadcn 컴포넌트 래핑
|
|
47
|
-
│ │ └── templates/ # 페이지 레이아웃
|
|
48
|
-
│ ├── stories/ # Storybook 스토리
|
|
49
|
-
│ ├── types/ # TypeScript 타입 정의
|
|
50
|
-
│ ├── composables/ # Vue Composition Functions
|
|
51
|
-
│ └── services/ # API 서비스
|
|
52
|
-
├── docs/ # 컴포넌트 사용 가이드
|
|
53
|
-
└── dist/ # 빌드 결과물
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## 🚀 시작하기
|
|
57
|
-
|
|
58
|
-
### 설치
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
# 저장소 클론
|
|
62
|
-
git clone <repository-url>
|
|
63
|
-
cd J-Component
|
|
64
|
-
|
|
65
|
-
# 의존성 설치
|
|
66
|
-
cd jwms-portal-frontend
|
|
67
|
-
npm install
|
|
68
|
-
# 또는
|
|
69
|
-
pnpm install
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### 개발 서버 실행
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# 개발 서버 시작 (http://localhost:5173)
|
|
76
|
-
npm run dev
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Storybook 실행
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
# Storybook 시작 (http://localhost:6006)
|
|
83
|
-
npm run storybook
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**Storybook 기능:**
|
|
87
|
-
- 다양한 폼 레이아웃/스키마(검색, 개인정보, 섹션, Wizard 등)와 Args/Docs 자동 문서 예시 확인 가능
|
|
88
|
-
- 툴바에서 테마 선택 (Default, Slate, Rose, Blue, Green)
|
|
89
|
-
- 다크모드 토글로 라이트/다크 모드 전환
|
|
90
|
-
|
|
91
|
-
### 빌드
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
# 프로덕션 빌드
|
|
95
|
-
npm run build
|
|
96
|
-
|
|
97
|
-
# 빌드 결과 미리보기
|
|
98
|
-
npm run preview
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## 📚 주요 컴포넌트
|
|
102
|
-
|
|
103
|
-
### Atoms (기본 요소)
|
|
104
|
-
- **JButton** - 버튼 컴포넌트
|
|
105
|
-
- **JInput** - 입력 필드
|
|
106
|
-
- **JIcon** - 아이콘 컴포넌트
|
|
107
|
-
- **JLabel** - 라벨 컴포넌트
|
|
108
|
-
- **JBadge** - 배지 컴포넌트
|
|
109
|
-
- **JProgress** - 진행률 표시
|
|
110
|
-
- **JSpinner** - 로딩 스피너
|
|
111
|
-
- **JGrid** - AG Grid 기반 데이터 그리드 컴포넌트 (Enterprise 기능 지원: 그룹핑, 피벗, Excel 내보내기)
|
|
112
|
-
|
|
113
|
-
### Molecules (조합 요소)
|
|
114
|
-
- **JFormField** - 폼 필드 래퍼
|
|
115
|
-
- **JCard** - 카드 컴포넌트
|
|
116
|
-
- **JAlert** - 알림 컴포넌트
|
|
117
|
-
- **JAccordion** - 아코디언 컴포넌트
|
|
118
|
-
- **JContextMenu** - 컨텍스트 메뉴
|
|
119
|
-
- **JSearchAddr** - 주소 검색 컴포넌트
|
|
120
|
-
- **JTabs** - 탭 컴포넌트 (탭 전환 이벤트 처리 개선, component 속성 활용 지원)
|
|
121
|
-
- **JButtonGroup** - 버튼 그룹 컴포넌트 (구분선 자동 표시 지원)
|
|
122
|
-
- **JTitlebar** - 타이틀바 컴포넌트 (제목, 설명, 팝오버 기능)
|
|
123
|
-
|
|
124
|
-
### Organisms (복합 요소)
|
|
125
|
-
- **JModal** - 모달 컴포넌트 (size prop 지원: sm, md, lg, xl, 2xl, full)
|
|
126
|
-
- **JDynamicTabs** - 동적 탭 관리
|
|
127
|
-
- **JDynamicForm** - 스키마 기반 동적 폼(기본/섹션/다단계, Docs 탭/다양한 예시 참조)
|
|
128
|
-
- **JFormModal** - JDynamicForm 기반 동적 폼 모달 컴포넌트 (size prop 지원)
|
|
129
|
-
- **JSearchPanel** - JDynamicForm 기반 재사용 가능한 검색 패널 (Collapsible, 조건 요약, 초기화 기능 지원)
|
|
130
|
-
- **JSidebarAdvanced** - 고급 사이드바 (검색, 즐겨찾기, 다단계 메뉴 지원)
|
|
131
|
-
- **JSidebarSimple** - 간단한 사이드바 (다단계 메뉴, 검색 지원)
|
|
132
|
-
|
|
133
|
-
### Templates (레이아웃)
|
|
134
|
-
- **JLayoutAdvanced** - 고급 레이아웃 (JHeader + JSidebarAdvanced + JDynamicTabs 조합)
|
|
135
|
-
- **JLayoutSimple** - 간단한 레이아웃 (JHeader + JSidebarSimple + JPageContainer 조합)
|
|
136
|
-
|
|
137
|
-
## 📖 사용 예시
|
|
138
|
-
|
|
139
|
-
> 💡 **컴포넌트 사용 가이드**: [사용 가이드](./docs/USAGE_GUIDE.md)에서 JDynamicTabs 경로 기반 컴포넌트 로딩 방법 등 상세 가이드를 확인하세요.
|
|
140
|
-
|
|
141
|
-
### NPM 패키지 사용 (권장)
|
|
142
|
-
|
|
143
|
-
```vue
|
|
144
|
-
<template>
|
|
145
|
-
<div class="p-4">
|
|
146
|
-
<JButton variant="primary" @click="handleClick">
|
|
147
|
-
클릭하세요
|
|
148
|
-
</JButton>
|
|
149
|
-
|
|
150
|
-
<JFormField label="이름" required>
|
|
151
|
-
<JInput v-model="name" placeholder="이름을 입력하세요" />
|
|
152
|
-
</JFormField>
|
|
153
|
-
|
|
154
|
-
<JAlert type="info" title="알림">
|
|
155
|
-
이것은 정보 알림입니다.
|
|
156
|
-
</JAlert>
|
|
157
|
-
</div>
|
|
158
|
-
</template>
|
|
159
|
-
|
|
160
|
-
<script setup>
|
|
161
|
-
import { ref } from 'vue'
|
|
162
|
-
import { JButton, JFormField, JInput, JAlert } from '@j-solution/components'
|
|
163
|
-
// CSS는 자동으로 포함됩니다 - 별도 import 불필요
|
|
164
|
-
|
|
165
|
-
const name = ref('')
|
|
166
|
-
|
|
167
|
-
const handleClick = () => {
|
|
168
|
-
console.log('버튼 클릭됨')
|
|
169
|
-
}
|
|
170
|
-
</script>
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
> 💡 **참고**: NPM 패키지는 패키지 진입점에서 CSS가 자동으로 import되므로, 컴포넌트만 import하면 스타일이 자동으로 적용됩니다.
|
|
174
|
-
|
|
175
|
-
### Standard 방식 사용 (파일 복사)
|
|
176
|
-
|
|
177
|
-
```vue
|
|
178
|
-
<template>
|
|
179
|
-
<div class="p-4">
|
|
180
|
-
<JButton variant="primary" @click="handleClick">
|
|
181
|
-
클릭하세요
|
|
182
|
-
</JButton>
|
|
183
|
-
|
|
184
|
-
<JFormField label="이름" required>
|
|
185
|
-
<JInput v-model="name" placeholder="이름을 입력하세요" />
|
|
186
|
-
</JFormField>
|
|
187
|
-
|
|
188
|
-
<JAlert type="info" title="알림">
|
|
189
|
-
이것은 정보 알림입니다.
|
|
190
|
-
</JAlert>
|
|
191
|
-
</div>
|
|
192
|
-
</template>
|
|
193
|
-
|
|
194
|
-
<script setup>
|
|
195
|
-
import { ref } from 'vue'
|
|
196
|
-
import { JButton, JFormField, JInput, JAlert } from '@/components'
|
|
197
|
-
|
|
198
|
-
const name = ref('')
|
|
199
|
-
|
|
200
|
-
const handleClick = () => {
|
|
201
|
-
console.log('버튼 클릭됨')
|
|
202
|
-
}
|
|
203
|
-
</script>
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### 주소 검색 컴포넌트
|
|
207
|
-
|
|
208
|
-
```vue
|
|
209
|
-
<template>
|
|
210
|
-
<JSearchAddr
|
|
211
|
-
v-model="address"
|
|
212
|
-
@select="handleAddressSelect"
|
|
213
|
-
placeholder="주소를 검색하세요"
|
|
214
|
-
/>
|
|
215
|
-
</template>
|
|
216
|
-
|
|
217
|
-
<script setup>
|
|
218
|
-
import { ref } from 'vue'
|
|
219
|
-
import { JSearchAddr } from '@/components/molecules'
|
|
220
|
-
|
|
221
|
-
const address = ref('')
|
|
222
|
-
|
|
223
|
-
const handleAddressSelect = (selectedAddress) => {
|
|
224
|
-
console.log('선택된 주소:', selectedAddress)
|
|
225
|
-
}
|
|
226
|
-
</script>
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
## 📚 문서 가이드
|
|
230
|
-
|
|
231
|
-
> **모든 문서는 이 README.md를 기준으로 연결되어 있습니다.**
|
|
232
|
-
|
|
233
|
-
### 📖 주요 문서
|
|
234
|
-
|
|
235
|
-
| 문서 | 설명 | 대상 |
|
|
236
|
-
|------|------|------|
|
|
237
|
-
| **[설치 가이드](./docs/INSTALLATION_GUIDE.md)** | 처음 설치하는 방법 | Standard 방식, NPM 방식 설치 가이드 |
|
|
238
|
-
| **[업데이트 가이드](./docs/UPDATE_GUIDE.md)** | 버전 업데이트 방법 | Standard 방식, NPM 방식 업데이트 가이드 |
|
|
239
|
-
| **[사용 가이드](./docs/USAGE_GUIDE.md)** | 컴포넌트 사용 방법 | 컴포넌트 목록, 사용 예시, 권장사항 |
|
|
240
|
-
| **[릴리즈 노트](./RELEASE_NOTES.md)** | 버전별 변경사항 | 모든 버전의 변경 이력 |
|
|
241
|
-
|
|
242
|
-
### 📦 패키지 문서
|
|
243
|
-
|
|
244
|
-
패키지에 포함된 문서들 (원본: `docs/` 디렉토리):
|
|
245
|
-
|
|
246
|
-
- **`packages/v{version}/README.md`**: 패키지 소개 및 설치 방법
|
|
247
|
-
- **`packages/v{version}/USAGE_GUIDE.md`**: 컴포넌트 사용 가이드
|
|
248
|
-
- **`packages/v{version}/UPDATE_GUIDE.md`**: 버전 업데이트 가이드
|
|
249
|
-
|
|
250
|
-
> 💡 **참고**: 패키지 문서는 `docs/` 디렉토리의 원본을 기반으로 패키징 시 자동으로 포함됩니다.
|
|
251
|
-
|
|
252
|
-
### 🗺️ 문서 구조
|
|
253
|
-
|
|
254
|
-
```
|
|
255
|
-
J-Component/
|
|
256
|
-
├── README.md # 메인 문서 (이 파일)
|
|
257
|
-
├── RELEASE_NOTES.md # 릴리즈 노트
|
|
258
|
-
├── docs/ # 문서 원본
|
|
259
|
-
│ ├── INSTALLATION_GUIDE.md # 설치 가이드
|
|
260
|
-
│ ├── UPDATE_GUIDE.md # 업데이트 가이드
|
|
261
|
-
│ └── USAGE_GUIDE.md # 사용 가이드
|
|
262
|
-
└── packages/ # 배포 패키지
|
|
263
|
-
└── v{version}/
|
|
264
|
-
├── README.md # (docs에서 복사)
|
|
265
|
-
├── USAGE_GUIDE.md # (docs에서 복사)
|
|
266
|
-
└── UPDATE_GUIDE.md # (docs에서 복사)
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
## 📦 컴포넌트 패키징 및 배포
|
|
272
|
-
|
|
273
|
-
> **⚠️ 중요**: 패키지를 생성하거나 버전을 업데이트하기 전에 **반드시** 다음 문서를 참조하세요:
|
|
274
|
-
> - **상세 가이드**: [`jwms-portal-frontend/PACKAGING.md`](./jwms-portal-frontend/PACKAGING.md)
|
|
275
|
-
> - **빠른 참조**: [`PACKAGING_GUIDE.md`](./PACKAGING_GUIDE.md)
|
|
276
|
-
|
|
277
|
-
J-Component는 **두 가지 배포 방식**을 지원합니다:
|
|
278
|
-
|
|
279
|
-
### 🚀 통합 패키징 (권장)
|
|
280
|
-
|
|
281
|
-
**하나의 명령어로 두 가지 방식 모두 생성:**
|
|
282
|
-
|
|
283
|
-
```bash
|
|
284
|
-
cd jwms-portal-frontend
|
|
285
|
-
npm run package
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
이 명령어는 다음을 자동으로 실행합니다:
|
|
289
|
-
1. **Standard 방식**: `packages/v{version}/` 디렉토리에 파일 복사 방식 패키지 생성
|
|
290
|
-
2. **NPM 방식**: `dist/npm/` 디렉토리에 npm 패키지 생성
|
|
291
|
-
|
|
292
|
-
### 1) Standard 방식 (파일 복사)
|
|
293
|
-
|
|
294
|
-
- **출력 위치**: `packages/v{version}/`
|
|
295
|
-
- **사용 방법**: 타겟 프로젝트에 파일을 직접 복사하여 사용
|
|
296
|
-
- **특징**:
|
|
297
|
-
- 기존 프로젝트 구조와 동일
|
|
298
|
-
- Git에 커밋 가능 (버전별 스냅샷)
|
|
299
|
-
- `packages/latest/standard/`에 최신 버전 포인터 제공
|
|
300
|
-
|
|
301
|
-
### 2) NPM 방식 (npm 패키지)
|
|
302
|
-
|
|
303
|
-
- **출력 위치**: `dist/npm/`
|
|
304
|
-
- **사용 방법**:
|
|
305
|
-
- 로컬 테스트: `npm install file:../path/to/dist/npm`
|
|
306
|
-
- npm 레지스트리: `npm install @j-solution/components` (배포 후)
|
|
307
|
-
- **특징**:
|
|
308
|
-
- ES Module + CommonJS + TypeScript 타입 정의 포함
|
|
309
|
-
- 가상 모듈 자동 인라인 처리
|
|
310
|
-
- `dist` 디렉토리는 `.gitignore`에 포함 (빌드 시 자동 생성)
|
|
311
|
-
|
|
312
|
-
#### NPM 패키지 배포
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
# 로컬에서 빌드 및 배포
|
|
316
|
-
cd jwms-portal-frontend/dist/npm
|
|
317
|
-
npm publish --access public
|
|
318
|
-
# 또는
|
|
319
|
-
pnpm publish --access public
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
#### 자동 배포 (GitHub Actions)
|
|
323
|
-
- GitHub에서 Release를 생성하면 자동으로 npm 레지스트리에 배포
|
|
324
|
-
- `.github/workflows/publish-npm.yml` 워크플로우 자동 실행
|
|
325
|
-
- `NPM_TOKEN` 시크릿 필요
|
|
326
|
-
|
|
327
|
-
### ⚠️ 중요 사항
|
|
328
|
-
|
|
329
|
-
- **v1.0.0부터 namespaced 방식 지원 중단**
|
|
330
|
-
- 기존: standard, namespaced, npm (3가지)
|
|
331
|
-
- 현재: standard, npm (2가지)
|
|
332
|
-
- namespaced 방식은 npm 방식으로 대체됨
|
|
333
|
-
|
|
334
|
-
### 개별 패키징
|
|
335
|
-
|
|
336
|
-
필요한 경우 개별로 실행할 수 있습니다:
|
|
337
|
-
|
|
338
|
-
```bash
|
|
339
|
-
# Standard 방식만
|
|
340
|
-
npm run package:standard
|
|
341
|
-
|
|
342
|
-
# NPM 방식만
|
|
343
|
-
npm run package:npm
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
자세한 내용: [PACKAGING.md](./jwms-portal-frontend/PACKAGING.md)
|
|
347
|
-
|
|
348
|
-
> 💡 **설치 및 업데이트 방법**: [설치 가이드](./docs/INSTALLATION_GUIDE.md) 및 [업데이트 가이드](./docs/UPDATE_GUIDE.md)를 참고하세요.
|
|
349
|
-
|
|
350
|
-
### 패키지 다운로드
|
|
351
|
-
|
|
352
|
-
패키지 폴더만 다운로드하는 방법 (전체 리포지토리 클론 불필요):
|
|
353
|
-
|
|
354
|
-
**⭐ 추천: Git Sparse Checkout** (패키지 폴더만 다운로드):
|
|
355
|
-
```bash
|
|
356
|
-
# Public 리포지토리
|
|
357
|
-
git clone --depth 1 --filter=blob:none --sparse <repository-url>
|
|
358
|
-
cd J-Component
|
|
359
|
-
git sparse-checkout set packages/v1.0.0
|
|
360
|
-
# 또는 packages/latest/standard
|
|
361
|
-
|
|
362
|
-
# Private 리포지토리 (인증 필요)
|
|
363
|
-
git clone --depth 1 --filter=blob:none --sparse git@github.com:<username>/<repository>.git
|
|
364
|
-
cd J-Component
|
|
365
|
-
git sparse-checkout set packages/v1.0.0
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
**다른 방법들**:
|
|
369
|
-
- GitHub 웹 인터페이스에서 특정 디렉토리 ZIP 다운로드
|
|
370
|
-
- GitHub API 사용
|
|
371
|
-
- Git Submodule 사용
|
|
372
|
-
|
|
373
|
-
> **📝 참고**: 각 패키지의 `README.md`에 상세한 다운로드 방법이 안내되어 있습니다.
|
|
374
|
-
|
|
375
|
-
## 🔧 개발 가이드
|
|
376
|
-
|
|
377
|
-
### 컴포넌트 작성 규칙
|
|
378
|
-
|
|
379
|
-
1. **Atomic Design 패턴** 준수
|
|
380
|
-
2. **TypeScript** 타입 정의 필수
|
|
381
|
-
3. **Props** 인터페이스 정의
|
|
382
|
-
4. **Storybook** 스토리 작성
|
|
383
|
-
5. **Tailwind CSS** 스타일링
|
|
384
|
-
|
|
385
|
-
### 컴포넌트 템플릿
|
|
386
|
-
|
|
387
|
-
```vue
|
|
388
|
-
<template>
|
|
389
|
-
<div class="j-component">
|
|
390
|
-
<!-- 컴포넌트 내용 -->
|
|
391
|
-
</div>
|
|
392
|
-
</template>
|
|
393
|
-
|
|
394
|
-
<script setup lang="ts">
|
|
395
|
-
interface Props {
|
|
396
|
-
variant?: 'primary' | 'secondary'
|
|
397
|
-
size?: 'sm' | 'md' | 'lg'
|
|
398
|
-
disabled?: boolean
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
interface Emits {
|
|
402
|
-
(e: 'click', value: string): void
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
406
|
-
variant: 'primary',
|
|
407
|
-
size: 'md',
|
|
408
|
-
disabled: false
|
|
409
|
-
})
|
|
410
|
-
|
|
411
|
-
const emit = defineEmits<Emits>()
|
|
412
|
-
</script>
|
|
1
|
+
# J-Component
|
|
2
|
+
|
|
3
|
+
> Vue.js 3 기반 Atomic Design 패턴 컴포넌트 라이브러리
|
|
4
|
+
|
|
5
|
+
## 📋 프로젝트 개요
|
|
6
|
+
|
|
7
|
+
J-Component는 Vue.js 3와 TypeScript를 기반으로 한 재사용 가능한 UI 컴포넌트 라이브러리입니다. shadcn/ui 디자인 시스템과 Atomic Design 패턴을 적용하여 일관성 있고 확장 가능한 컴포넌트를 제공합니다.
|
|
8
|
+
|
|
9
|
+
## 🚀 현재 버전: v1.4.2
|
|
10
|
+
|
|
11
|
+
**최신 업데이트 (2026년 2월 5일)**
|
|
12
|
+
- **JCombo 빈 문자열 버그 수정**: `value: ''` 옵션 클릭 시 선택되지 않던 버그 수정
|
|
13
|
+
- **JGrid 이벤트 추가**: `rowClicked`, `cellClicked`, `selectionChanged` 등 이벤트 emit 지원
|
|
14
|
+
|
|
15
|
+
[전체 릴리즈 노트 보기](./RELEASE_NOTES.md)
|
|
16
|
+
|
|
17
|
+
## 🛠️ 기술 스택
|
|
18
|
+
|
|
19
|
+
### 핵심 프레임워크
|
|
20
|
+
- **Vue.js 3.5** - 프론트엔드 프레임워크
|
|
21
|
+
- **TypeScript 5.9** - 타입 시스템
|
|
22
|
+
- **Vite 7** - 빌드 도구
|
|
23
|
+
|
|
24
|
+
### UI & 스타일링
|
|
25
|
+
- **TailwindCSS 3.4** - 유틸리티 CSS 프레임워크
|
|
26
|
+
- **shadcn/ui** - 디자인 시스템 (radix-vue 기반)
|
|
27
|
+
- **Lucide Icons** - 아이콘 라이브러리
|
|
28
|
+
|
|
29
|
+
### 개발 도구
|
|
30
|
+
- **Storybook 9** - 컴포넌트 문서화 및 테스트
|
|
31
|
+
- Docs 탭: 다양한 폼 스키마/도메인 예시 자동 미리보기 지원
|
|
32
|
+
- 테마 셀렉터: 5가지 tweakcn 테마 지원 (Default, Slate, Rose, Blue, Green)
|
|
33
|
+
- 다크모드 토글: 라이트/다크 모드 실시간 전환
|
|
34
|
+
- **ESLint 9** - 코드 품질 검사
|
|
35
|
+
- **Prettier** - 코드 포맷팅
|
|
36
|
+
|
|
37
|
+
## 📁 프로젝트 구조
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
jwms-portal-frontend/
|
|
41
|
+
├── src/
|
|
42
|
+
│ ├── components/ # Atomic Design Components
|
|
43
|
+
│ │ ├── atoms/ # 기본 UI 요소 (JButton, JInput, JIcon 등)
|
|
44
|
+
│ │ ├── molecules/ # atoms의 조합 (JFormField, JCard, JAlert 등)
|
|
45
|
+
│ │ ├── organisms/ # molecules의 조합 (JModal, JDynamicTabs, JDynamicForm 등)
|
|
46
|
+
│ │ ├── shadcn/ # shadcn 컴포넌트 래핑
|
|
47
|
+
│ │ └── templates/ # 페이지 레이아웃
|
|
48
|
+
│ ├── stories/ # Storybook 스토리
|
|
49
|
+
│ ├── types/ # TypeScript 타입 정의
|
|
50
|
+
│ ├── composables/ # Vue Composition Functions
|
|
51
|
+
│ └── services/ # API 서비스
|
|
52
|
+
├── docs/ # 컴포넌트 사용 가이드
|
|
53
|
+
└── dist/ # 빌드 결과물
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 🚀 시작하기
|
|
57
|
+
|
|
58
|
+
### 설치
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# 저장소 클론
|
|
62
|
+
git clone <repository-url>
|
|
63
|
+
cd J-Component
|
|
64
|
+
|
|
65
|
+
# 의존성 설치
|
|
66
|
+
cd jwms-portal-frontend
|
|
67
|
+
npm install
|
|
68
|
+
# 또는
|
|
69
|
+
pnpm install
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 개발 서버 실행
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 개발 서버 시작 (http://localhost:5173)
|
|
76
|
+
npm run dev
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Storybook 실행
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Storybook 시작 (http://localhost:6006)
|
|
83
|
+
npm run storybook
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Storybook 기능:**
|
|
87
|
+
- 다양한 폼 레이아웃/스키마(검색, 개인정보, 섹션, Wizard 등)와 Args/Docs 자동 문서 예시 확인 가능
|
|
88
|
+
- 툴바에서 테마 선택 (Default, Slate, Rose, Blue, Green)
|
|
89
|
+
- 다크모드 토글로 라이트/다크 모드 전환
|
|
90
|
+
|
|
91
|
+
### 빌드
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# 프로덕션 빌드
|
|
95
|
+
npm run build
|
|
96
|
+
|
|
97
|
+
# 빌드 결과 미리보기
|
|
98
|
+
npm run preview
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 📚 주요 컴포넌트
|
|
102
|
+
|
|
103
|
+
### Atoms (기본 요소)
|
|
104
|
+
- **JButton** - 버튼 컴포넌트
|
|
105
|
+
- **JInput** - 입력 필드
|
|
106
|
+
- **JIcon** - 아이콘 컴포넌트
|
|
107
|
+
- **JLabel** - 라벨 컴포넌트
|
|
108
|
+
- **JBadge** - 배지 컴포넌트
|
|
109
|
+
- **JProgress** - 진행률 표시
|
|
110
|
+
- **JSpinner** - 로딩 스피너
|
|
111
|
+
- **JGrid** - AG Grid 기반 데이터 그리드 컴포넌트 (Enterprise 기능 지원: 그룹핑, 피벗, Excel 내보내기)
|
|
112
|
+
|
|
113
|
+
### Molecules (조합 요소)
|
|
114
|
+
- **JFormField** - 폼 필드 래퍼
|
|
115
|
+
- **JCard** - 카드 컴포넌트
|
|
116
|
+
- **JAlert** - 알림 컴포넌트
|
|
117
|
+
- **JAccordion** - 아코디언 컴포넌트
|
|
118
|
+
- **JContextMenu** - 컨텍스트 메뉴
|
|
119
|
+
- **JSearchAddr** - 주소 검색 컴포넌트
|
|
120
|
+
- **JTabs** - 탭 컴포넌트 (탭 전환 이벤트 처리 개선, component 속성 활용 지원)
|
|
121
|
+
- **JButtonGroup** - 버튼 그룹 컴포넌트 (구분선 자동 표시 지원)
|
|
122
|
+
- **JTitlebar** - 타이틀바 컴포넌트 (제목, 설명, 팝오버 기능)
|
|
123
|
+
|
|
124
|
+
### Organisms (복합 요소)
|
|
125
|
+
- **JModal** - 모달 컴포넌트 (size prop 지원: sm, md, lg, xl, 2xl, full)
|
|
126
|
+
- **JDynamicTabs** - 동적 탭 관리
|
|
127
|
+
- **JDynamicForm** - 스키마 기반 동적 폼(기본/섹션/다단계, Docs 탭/다양한 예시 참조)
|
|
128
|
+
- **JFormModal** - JDynamicForm 기반 동적 폼 모달 컴포넌트 (size prop 지원)
|
|
129
|
+
- **JSearchPanel** - JDynamicForm 기반 재사용 가능한 검색 패널 (Collapsible, 조건 요약, 초기화 기능 지원)
|
|
130
|
+
- **JSidebarAdvanced** - 고급 사이드바 (검색, 즐겨찾기, 다단계 메뉴 지원)
|
|
131
|
+
- **JSidebarSimple** - 간단한 사이드바 (다단계 메뉴, 검색 지원)
|
|
132
|
+
|
|
133
|
+
### Templates (레이아웃)
|
|
134
|
+
- **JLayoutAdvanced** - 고급 레이아웃 (JHeader + JSidebarAdvanced + JDynamicTabs 조합)
|
|
135
|
+
- **JLayoutSimple** - 간단한 레이아웃 (JHeader + JSidebarSimple + JPageContainer 조합)
|
|
136
|
+
|
|
137
|
+
## 📖 사용 예시
|
|
138
|
+
|
|
139
|
+
> 💡 **컴포넌트 사용 가이드**: [사용 가이드](./docs/USAGE_GUIDE.md)에서 JDynamicTabs 경로 기반 컴포넌트 로딩 방법 등 상세 가이드를 확인하세요.
|
|
140
|
+
|
|
141
|
+
### NPM 패키지 사용 (권장)
|
|
142
|
+
|
|
143
|
+
```vue
|
|
144
|
+
<template>
|
|
145
|
+
<div class="p-4">
|
|
146
|
+
<JButton variant="primary" @click="handleClick">
|
|
147
|
+
클릭하세요
|
|
148
|
+
</JButton>
|
|
149
|
+
|
|
150
|
+
<JFormField label="이름" required>
|
|
151
|
+
<JInput v-model="name" placeholder="이름을 입력하세요" />
|
|
152
|
+
</JFormField>
|
|
153
|
+
|
|
154
|
+
<JAlert type="info" title="알림">
|
|
155
|
+
이것은 정보 알림입니다.
|
|
156
|
+
</JAlert>
|
|
157
|
+
</div>
|
|
158
|
+
</template>
|
|
159
|
+
|
|
160
|
+
<script setup>
|
|
161
|
+
import { ref } from 'vue'
|
|
162
|
+
import { JButton, JFormField, JInput, JAlert } from '@j-solution/components'
|
|
163
|
+
// CSS는 자동으로 포함됩니다 - 별도 import 불필요
|
|
164
|
+
|
|
165
|
+
const name = ref('')
|
|
166
|
+
|
|
167
|
+
const handleClick = () => {
|
|
168
|
+
console.log('버튼 클릭됨')
|
|
169
|
+
}
|
|
170
|
+
</script>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
> 💡 **참고**: NPM 패키지는 패키지 진입점에서 CSS가 자동으로 import되므로, 컴포넌트만 import하면 스타일이 자동으로 적용됩니다.
|
|
174
|
+
|
|
175
|
+
### Standard 방식 사용 (파일 복사)
|
|
176
|
+
|
|
177
|
+
```vue
|
|
178
|
+
<template>
|
|
179
|
+
<div class="p-4">
|
|
180
|
+
<JButton variant="primary" @click="handleClick">
|
|
181
|
+
클릭하세요
|
|
182
|
+
</JButton>
|
|
183
|
+
|
|
184
|
+
<JFormField label="이름" required>
|
|
185
|
+
<JInput v-model="name" placeholder="이름을 입력하세요" />
|
|
186
|
+
</JFormField>
|
|
187
|
+
|
|
188
|
+
<JAlert type="info" title="알림">
|
|
189
|
+
이것은 정보 알림입니다.
|
|
190
|
+
</JAlert>
|
|
191
|
+
</div>
|
|
192
|
+
</template>
|
|
193
|
+
|
|
194
|
+
<script setup>
|
|
195
|
+
import { ref } from 'vue'
|
|
196
|
+
import { JButton, JFormField, JInput, JAlert } from '@/components'
|
|
197
|
+
|
|
198
|
+
const name = ref('')
|
|
199
|
+
|
|
200
|
+
const handleClick = () => {
|
|
201
|
+
console.log('버튼 클릭됨')
|
|
202
|
+
}
|
|
203
|
+
</script>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 주소 검색 컴포넌트
|
|
207
|
+
|
|
208
|
+
```vue
|
|
209
|
+
<template>
|
|
210
|
+
<JSearchAddr
|
|
211
|
+
v-model="address"
|
|
212
|
+
@select="handleAddressSelect"
|
|
213
|
+
placeholder="주소를 검색하세요"
|
|
214
|
+
/>
|
|
215
|
+
</template>
|
|
216
|
+
|
|
217
|
+
<script setup>
|
|
218
|
+
import { ref } from 'vue'
|
|
219
|
+
import { JSearchAddr } from '@/components/molecules'
|
|
220
|
+
|
|
221
|
+
const address = ref('')
|
|
222
|
+
|
|
223
|
+
const handleAddressSelect = (selectedAddress) => {
|
|
224
|
+
console.log('선택된 주소:', selectedAddress)
|
|
225
|
+
}
|
|
226
|
+
</script>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## 📚 문서 가이드
|
|
230
|
+
|
|
231
|
+
> **모든 문서는 이 README.md를 기준으로 연결되어 있습니다.**
|
|
232
|
+
|
|
233
|
+
### 📖 주요 문서
|
|
234
|
+
|
|
235
|
+
| 문서 | 설명 | 대상 |
|
|
236
|
+
|------|------|------|
|
|
237
|
+
| **[설치 가이드](./docs/INSTALLATION_GUIDE.md)** | 처음 설치하는 방법 | Standard 방식, NPM 방식 설치 가이드 |
|
|
238
|
+
| **[업데이트 가이드](./docs/UPDATE_GUIDE.md)** | 버전 업데이트 방법 | Standard 방식, NPM 방식 업데이트 가이드 |
|
|
239
|
+
| **[사용 가이드](./docs/USAGE_GUIDE.md)** | 컴포넌트 사용 방법 | 컴포넌트 목록, 사용 예시, 권장사항 |
|
|
240
|
+
| **[릴리즈 노트](./RELEASE_NOTES.md)** | 버전별 변경사항 | 모든 버전의 변경 이력 |
|
|
241
|
+
|
|
242
|
+
### 📦 패키지 문서
|
|
243
|
+
|
|
244
|
+
패키지에 포함된 문서들 (원본: `docs/` 디렉토리):
|
|
245
|
+
|
|
246
|
+
- **`packages/v{version}/README.md`**: 패키지 소개 및 설치 방법
|
|
247
|
+
- **`packages/v{version}/USAGE_GUIDE.md`**: 컴포넌트 사용 가이드
|
|
248
|
+
- **`packages/v{version}/UPDATE_GUIDE.md`**: 버전 업데이트 가이드
|
|
249
|
+
|
|
250
|
+
> 💡 **참고**: 패키지 문서는 `docs/` 디렉토리의 원본을 기반으로 패키징 시 자동으로 포함됩니다.
|
|
251
|
+
|
|
252
|
+
### 🗺️ 문서 구조
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
J-Component/
|
|
256
|
+
├── README.md # 메인 문서 (이 파일)
|
|
257
|
+
├── RELEASE_NOTES.md # 릴리즈 노트
|
|
258
|
+
├── docs/ # 문서 원본
|
|
259
|
+
│ ├── INSTALLATION_GUIDE.md # 설치 가이드
|
|
260
|
+
│ ├── UPDATE_GUIDE.md # 업데이트 가이드
|
|
261
|
+
│ └── USAGE_GUIDE.md # 사용 가이드
|
|
262
|
+
└── packages/ # 배포 패키지
|
|
263
|
+
└── v{version}/
|
|
264
|
+
├── README.md # (docs에서 복사)
|
|
265
|
+
├── USAGE_GUIDE.md # (docs에서 복사)
|
|
266
|
+
└── UPDATE_GUIDE.md # (docs에서 복사)
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 📦 컴포넌트 패키징 및 배포
|
|
272
|
+
|
|
273
|
+
> **⚠️ 중요**: 패키지를 생성하거나 버전을 업데이트하기 전에 **반드시** 다음 문서를 참조하세요:
|
|
274
|
+
> - **상세 가이드**: [`jwms-portal-frontend/PACKAGING.md`](./jwms-portal-frontend/PACKAGING.md)
|
|
275
|
+
> - **빠른 참조**: [`PACKAGING_GUIDE.md`](./PACKAGING_GUIDE.md)
|
|
276
|
+
|
|
277
|
+
J-Component는 **두 가지 배포 방식**을 지원합니다:
|
|
278
|
+
|
|
279
|
+
### 🚀 통합 패키징 (권장)
|
|
280
|
+
|
|
281
|
+
**하나의 명령어로 두 가지 방식 모두 생성:**
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
cd jwms-portal-frontend
|
|
285
|
+
npm run package
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
이 명령어는 다음을 자동으로 실행합니다:
|
|
289
|
+
1. **Standard 방식**: `packages/v{version}/` 디렉토리에 파일 복사 방식 패키지 생성
|
|
290
|
+
2. **NPM 방식**: `dist/npm/` 디렉토리에 npm 패키지 생성
|
|
291
|
+
|
|
292
|
+
### 1) Standard 방식 (파일 복사)
|
|
293
|
+
|
|
294
|
+
- **출력 위치**: `packages/v{version}/`
|
|
295
|
+
- **사용 방법**: 타겟 프로젝트에 파일을 직접 복사하여 사용
|
|
296
|
+
- **특징**:
|
|
297
|
+
- 기존 프로젝트 구조와 동일
|
|
298
|
+
- Git에 커밋 가능 (버전별 스냅샷)
|
|
299
|
+
- `packages/latest/standard/`에 최신 버전 포인터 제공
|
|
300
|
+
|
|
301
|
+
### 2) NPM 방식 (npm 패키지)
|
|
302
|
+
|
|
303
|
+
- **출력 위치**: `dist/npm/`
|
|
304
|
+
- **사용 방법**:
|
|
305
|
+
- 로컬 테스트: `npm install file:../path/to/dist/npm`
|
|
306
|
+
- npm 레지스트리: `npm install @j-solution/components` (배포 후)
|
|
307
|
+
- **특징**:
|
|
308
|
+
- ES Module + CommonJS + TypeScript 타입 정의 포함
|
|
309
|
+
- 가상 모듈 자동 인라인 처리
|
|
310
|
+
- `dist` 디렉토리는 `.gitignore`에 포함 (빌드 시 자동 생성)
|
|
311
|
+
|
|
312
|
+
#### NPM 패키지 배포
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
# 로컬에서 빌드 및 배포
|
|
316
|
+
cd jwms-portal-frontend/dist/npm
|
|
317
|
+
npm publish --access public
|
|
318
|
+
# 또는
|
|
319
|
+
pnpm publish --access public
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
#### 자동 배포 (GitHub Actions)
|
|
323
|
+
- GitHub에서 Release를 생성하면 자동으로 npm 레지스트리에 배포
|
|
324
|
+
- `.github/workflows/publish-npm.yml` 워크플로우 자동 실행
|
|
325
|
+
- `NPM_TOKEN` 시크릿 필요
|
|
326
|
+
|
|
327
|
+
### ⚠️ 중요 사항
|
|
328
|
+
|
|
329
|
+
- **v1.0.0부터 namespaced 방식 지원 중단**
|
|
330
|
+
- 기존: standard, namespaced, npm (3가지)
|
|
331
|
+
- 현재: standard, npm (2가지)
|
|
332
|
+
- namespaced 방식은 npm 방식으로 대체됨
|
|
333
|
+
|
|
334
|
+
### 개별 패키징
|
|
335
|
+
|
|
336
|
+
필요한 경우 개별로 실행할 수 있습니다:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# Standard 방식만
|
|
340
|
+
npm run package:standard
|
|
341
|
+
|
|
342
|
+
# NPM 방식만
|
|
343
|
+
npm run package:npm
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
자세한 내용: [PACKAGING.md](./jwms-portal-frontend/PACKAGING.md)
|
|
347
|
+
|
|
348
|
+
> 💡 **설치 및 업데이트 방법**: [설치 가이드](./docs/INSTALLATION_GUIDE.md) 및 [업데이트 가이드](./docs/UPDATE_GUIDE.md)를 참고하세요.
|
|
349
|
+
|
|
350
|
+
### 패키지 다운로드
|
|
351
|
+
|
|
352
|
+
패키지 폴더만 다운로드하는 방법 (전체 리포지토리 클론 불필요):
|
|
353
|
+
|
|
354
|
+
**⭐ 추천: Git Sparse Checkout** (패키지 폴더만 다운로드):
|
|
355
|
+
```bash
|
|
356
|
+
# Public 리포지토리
|
|
357
|
+
git clone --depth 1 --filter=blob:none --sparse <repository-url>
|
|
358
|
+
cd J-Component
|
|
359
|
+
git sparse-checkout set packages/v1.0.0
|
|
360
|
+
# 또는 packages/latest/standard
|
|
361
|
+
|
|
362
|
+
# Private 리포지토리 (인증 필요)
|
|
363
|
+
git clone --depth 1 --filter=blob:none --sparse git@github.com:<username>/<repository>.git
|
|
364
|
+
cd J-Component
|
|
365
|
+
git sparse-checkout set packages/v1.0.0
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**다른 방법들**:
|
|
369
|
+
- GitHub 웹 인터페이스에서 특정 디렉토리 ZIP 다운로드
|
|
370
|
+
- GitHub API 사용
|
|
371
|
+
- Git Submodule 사용
|
|
372
|
+
|
|
373
|
+
> **📝 참고**: 각 패키지의 `README.md`에 상세한 다운로드 방법이 안내되어 있습니다.
|
|
374
|
+
|
|
375
|
+
## 🔧 개발 가이드
|
|
376
|
+
|
|
377
|
+
### 컴포넌트 작성 규칙
|
|
378
|
+
|
|
379
|
+
1. **Atomic Design 패턴** 준수
|
|
380
|
+
2. **TypeScript** 타입 정의 필수
|
|
381
|
+
3. **Props** 인터페이스 정의
|
|
382
|
+
4. **Storybook** 스토리 작성
|
|
383
|
+
5. **Tailwind CSS** 스타일링
|
|
384
|
+
|
|
385
|
+
### 컴포넌트 템플릿
|
|
386
|
+
|
|
387
|
+
```vue
|
|
388
|
+
<template>
|
|
389
|
+
<div class="j-component">
|
|
390
|
+
<!-- 컴포넌트 내용 -->
|
|
391
|
+
</div>
|
|
392
|
+
</template>
|
|
393
|
+
|
|
394
|
+
<script setup lang="ts">
|
|
395
|
+
interface Props {
|
|
396
|
+
variant?: 'primary' | 'secondary'
|
|
397
|
+
size?: 'sm' | 'md' | 'lg'
|
|
398
|
+
disabled?: boolean
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
interface Emits {
|
|
402
|
+
(e: 'click', value: string): void
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
406
|
+
variant: 'primary',
|
|
407
|
+
size: 'md',
|
|
408
|
+
disabled: false
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
const emit = defineEmits<Emits>()
|
|
412
|
+
</script>
|
|
413
413
|
```
|