@xfilecom/front-core 0.2.26 → 0.2.28
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 +46 -13
- package/dist/base.css +205 -70
- package/dist/components/atoms/Badge.d.ts +1 -1
- package/dist/components/atoms/Card.d.ts +3 -1
- package/dist/components/atoms/Card.js +2 -2
- package/dist/components/atoms/Paper.d.ts +16 -0
- package/dist/components/atoms/Paper.js +13 -0
- package/dist/components/atoms/Text.d.ts +1 -0
- package/dist/components/atoms/Text.js +1 -0
- package/dist/components/atoms/index.d.ts +1 -0
- package/dist/components/atoms/index.js +3 -1
- package/dist/generatedVersion.d.ts +1 -1
- package/dist/generatedVersion.js +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +7 -1
- package/dist/tokens.css +80 -60
- package/docs/COMPONENTS.md +111 -0
- package/docs/DESIGN_SYSTEM.md +32 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,29 +1,62 @@
|
|
|
1
1
|
# @xfilecom/front-core
|
|
2
2
|
|
|
3
|
-
Design tokens (`tokens.css`), atomic layout
|
|
3
|
+
Design tokens (`tokens.css`), atomic layout (`base.css`), browser-only React components. **Nest / 서버 의존 없음.**
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 문서 (상세)
|
|
6
|
+
|
|
7
|
+
| 문서 | 내용 |
|
|
8
|
+
|------|------|
|
|
9
|
+
| [docs/DESIGN_SYSTEM.md](./docs/DESIGN_SYSTEM.md) | MUI Paper / react-native-paper 등과 **개념 매핑**, elevation·역할 색 |
|
|
10
|
+
| [docs/COMPONENTS.md](./docs/COMPONENTS.md) | 컴포넌트별 **소스 경로**, props 요약, **복붙 예제 코드** |
|
|
11
|
+
|
|
12
|
+
npm 패키지에 `docs/`가 포함되므로, 설치 후 `node_modules/@xfilecom/front-core/docs/`에서도 동일 파일을 볼 수 있다.
|
|
13
|
+
|
|
14
|
+
## CSS 로드 순서
|
|
6
15
|
|
|
7
16
|
1. `@xfilecom/front-core/tokens.css`
|
|
8
17
|
2. `@xfilecom/front-core/base.css`
|
|
9
|
-
3. (
|
|
18
|
+
3. (선택) 앱 `xfc-theme.css`에서 `--xfc-*` 덮어쓰기
|
|
19
|
+
4. (선택) 레이아웃 `app.css`
|
|
20
|
+
|
|
21
|
+
**다크:** `tokens.css` — `html.dark` / `data-theme="dark"`.
|
|
22
|
+
|
|
23
|
+
**배경:** `body` 기본은 옅은 액센트 그라데이션. 단색만 쓰려면 `body { background-image: none; }`.
|
|
24
|
+
|
|
25
|
+
## React import
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import {
|
|
29
|
+
Paper,
|
|
30
|
+
Card,
|
|
31
|
+
Button,
|
|
32
|
+
Text,
|
|
33
|
+
Dialog,
|
|
34
|
+
} from '@xfilecom/front-core';
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
서브패스: `@xfilecom/front-core/atoms`, `@xfilecom/front-core/overlays`.
|
|
10
38
|
|
|
11
|
-
|
|
39
|
+
## Paper (표면)
|
|
12
40
|
|
|
13
|
-
|
|
41
|
+
MUI `Paper` / RN `Surface`에 대응하는 얇은 래퍼:
|
|
14
42
|
|
|
15
|
-
|
|
16
|
-
|
|
43
|
+
```tsx
|
|
44
|
+
<Paper elevation={2} style={{ padding: 'var(--xfc-space-lg)' }}>
|
|
45
|
+
…
|
|
46
|
+
</Paper>
|
|
47
|
+
<Paper variant="outlined" style={{ padding: 16 }}>…</Paper>
|
|
48
|
+
```
|
|
17
49
|
|
|
18
|
-
##
|
|
50
|
+
## 기본 문자열·a11y
|
|
19
51
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
52
|
+
- 기본 UI 문구는 **영어** (토스트 Dismiss, Confirm OK/Cancel). 한국어는 props로 덮어쓴다.
|
|
53
|
+
- Dialog / BottomSheet: 스크롤 잠금, Escape, 포커스 트랩 (`useFocusTrap`).
|
|
54
|
+
- Toast: `error` → `role="alert"`, 그 외 `role="status"`.
|
|
22
55
|
|
|
23
56
|
## Version
|
|
24
57
|
|
|
25
|
-
`
|
|
58
|
+
`npm run build` 시 `package.json`의 `version`이 `src/generatedVersion.ts`에 반영된다.
|
|
26
59
|
|
|
27
|
-
##
|
|
60
|
+
## 폼
|
|
28
61
|
|
|
29
|
-
`Input`, `Textarea`, `Select`, `Checkbox`, `Field` —
|
|
62
|
+
`Input`, `Textarea`, `Select`, `Checkbox`, `Field` — 자세한 예는 [COMPONENTS.md](./docs/COMPONENTS.md).
|
package/dist/base.css
CHANGED
|
@@ -23,8 +23,11 @@ body {
|
|
|
23
23
|
font-size: var(--xfc-text-body);
|
|
24
24
|
line-height: var(--xfc-leading-normal);
|
|
25
25
|
color: var(--xfc-fg);
|
|
26
|
-
background: var(--xfc-bg);
|
|
26
|
+
background-color: var(--xfc-bg);
|
|
27
|
+
background-image: radial-gradient(ellipse 120% 80% at 50% -20%, var(--xfc-accent-soft), transparent 55%);
|
|
28
|
+
background-attachment: fixed;
|
|
27
29
|
-webkit-font-smoothing: antialiased;
|
|
30
|
+
text-rendering: optimizeLegibility;
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
a {
|
|
@@ -46,9 +49,10 @@ a:hover {
|
|
|
46
49
|
|
|
47
50
|
.xfc-text--title {
|
|
48
51
|
font-size: var(--xfc-text-display);
|
|
49
|
-
font-weight:
|
|
52
|
+
font-weight: 800;
|
|
50
53
|
line-height: var(--xfc-leading-tight);
|
|
51
|
-
letter-spacing: -0.
|
|
54
|
+
letter-spacing: -0.035em;
|
|
55
|
+
font-feature-settings: 'ss01' on, 'cv01' on;
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
.xfc-text--appbar {
|
|
@@ -75,6 +79,15 @@ a:hover {
|
|
|
75
79
|
font-size: var(--xfc-text-body);
|
|
76
80
|
}
|
|
77
81
|
|
|
82
|
+
/** 본문보다 한 단계 큰 리드 문단 (히어로·카피) */
|
|
83
|
+
.xfc-text--lead {
|
|
84
|
+
font-size: 1.125rem;
|
|
85
|
+
font-weight: 500;
|
|
86
|
+
line-height: 1.6;
|
|
87
|
+
color: var(--xfc-fg-label);
|
|
88
|
+
letter-spacing: -0.01em;
|
|
89
|
+
}
|
|
90
|
+
|
|
78
91
|
.xfc-text--small {
|
|
79
92
|
font-size: var(--xfc-text-small);
|
|
80
93
|
}
|
|
@@ -175,51 +188,114 @@ a:hover {
|
|
|
175
188
|
.xfc-card {
|
|
176
189
|
background: var(--xfc-bg-elevated);
|
|
177
190
|
color: var(--xfc-fg);
|
|
178
|
-
border: 1px solid var(--xfc-border);
|
|
179
|
-
border-radius: var(--xfc-radius-
|
|
191
|
+
border: 1px solid color-mix(in srgb, var(--xfc-border) 88%, var(--xfc-fg) 6%);
|
|
192
|
+
border-radius: var(--xfc-radius-lg);
|
|
180
193
|
box-shadow: var(--xfc-card-shadow);
|
|
181
194
|
}
|
|
182
195
|
|
|
196
|
+
/** 클릭·링크 카드만 — 정적 패널에는 붙이지 말 것 */
|
|
197
|
+
.xfc-card--interactive {
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
transition:
|
|
200
|
+
box-shadow 0.2s ease,
|
|
201
|
+
border-color 0.2s ease,
|
|
202
|
+
transform 0.2s ease;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@media (hover: hover) {
|
|
206
|
+
.xfc-card--interactive:hover {
|
|
207
|
+
border-color: color-mix(in srgb, var(--xfc-border-strong) 75%, var(--xfc-accent) 10%);
|
|
208
|
+
box-shadow: var(--xfc-shadow-md);
|
|
209
|
+
transform: translateY(-1px);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.xfc-card--interactive:active {
|
|
213
|
+
transform: translateY(0);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
183
217
|
.xfc-card__header {
|
|
184
|
-
padding: var(--xfc-space-
|
|
218
|
+
padding: var(--xfc-space-xl) var(--xfc-space-xl) var(--xfc-space-md);
|
|
185
219
|
border-bottom: 1px solid var(--xfc-border);
|
|
186
220
|
font-size: var(--xfc-text-section);
|
|
187
221
|
font-weight: 700;
|
|
222
|
+
letter-spacing: -0.02em;
|
|
188
223
|
color: var(--xfc-fg-strong);
|
|
189
224
|
}
|
|
190
225
|
|
|
191
226
|
.xfc-card__body {
|
|
192
227
|
min-width: 0;
|
|
193
|
-
padding: var(--xfc-space-
|
|
228
|
+
padding: var(--xfc-space-xl);
|
|
194
229
|
}
|
|
195
230
|
|
|
196
231
|
.xfc-card__footer {
|
|
197
|
-
padding: 0 var(--xfc-space-
|
|
232
|
+
padding: 0 var(--xfc-space-xl) var(--xfc-space-xl);
|
|
198
233
|
border-top: 1px solid var(--xfc-border);
|
|
199
234
|
padding-top: var(--xfc-space-md);
|
|
200
235
|
}
|
|
201
236
|
|
|
202
|
-
/* ——
|
|
237
|
+
/* —— Paper / Surface (MUI Paper · RN Paper Surface 스타일 elevation) —— */
|
|
238
|
+
|
|
239
|
+
.xfc-paper {
|
|
240
|
+
box-sizing: border-box;
|
|
241
|
+
background: var(--xfc-bg-elevated);
|
|
242
|
+
color: var(--xfc-fg);
|
|
243
|
+
border-radius: var(--xfc-radius-md);
|
|
244
|
+
border: 1px solid transparent;
|
|
245
|
+
transition:
|
|
246
|
+
box-shadow 0.2s ease,
|
|
247
|
+
border-color 0.2s ease;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.xfc-paper--elevation-0 {
|
|
251
|
+
box-shadow: none;
|
|
252
|
+
border-color: var(--xfc-border);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.xfc-paper--elevation-1 {
|
|
256
|
+
box-shadow: var(--xfc-shadow-xs);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.xfc-paper--elevation-2 {
|
|
260
|
+
box-shadow: var(--xfc-shadow-sm);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.xfc-paper--elevation-3 {
|
|
264
|
+
box-shadow: var(--xfc-shadow-md);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.xfc-paper--elevation-4 {
|
|
268
|
+
box-shadow: var(--xfc-shadow-lg);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.xfc-paper--outlined {
|
|
272
|
+
box-shadow: none;
|
|
273
|
+
border-color: var(--xfc-border-strong);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* —— Buttons —— */
|
|
203
277
|
|
|
204
278
|
.xfc-btn {
|
|
205
279
|
display: inline-flex;
|
|
206
280
|
align-items: center;
|
|
207
281
|
justify-content: center;
|
|
208
|
-
gap: var(--xfc-space-
|
|
209
|
-
min-height:
|
|
210
|
-
padding: 0 var(--xfc-space-lg);
|
|
282
|
+
gap: var(--xfc-space-sm);
|
|
283
|
+
min-height: 40px;
|
|
284
|
+
padding: 0 calc(var(--xfc-space-lg) + 2px);
|
|
211
285
|
font: inherit;
|
|
212
286
|
font-size: var(--xfc-text-body);
|
|
213
|
-
font-weight:
|
|
287
|
+
font-weight: 600;
|
|
288
|
+
letter-spacing: -0.01em;
|
|
214
289
|
line-height: 1;
|
|
215
|
-
border-radius: var(--xfc-radius-
|
|
290
|
+
border-radius: var(--xfc-radius-sm);
|
|
216
291
|
border: 1px solid transparent;
|
|
217
292
|
cursor: pointer;
|
|
218
293
|
transition:
|
|
219
|
-
background 0.
|
|
220
|
-
color 0.
|
|
221
|
-
border-color 0.
|
|
222
|
-
box-shadow 0.
|
|
294
|
+
background 0.18s ease,
|
|
295
|
+
color 0.18s ease,
|
|
296
|
+
border-color 0.18s ease,
|
|
297
|
+
box-shadow 0.18s ease,
|
|
298
|
+
transform 0.18s ease;
|
|
223
299
|
}
|
|
224
300
|
|
|
225
301
|
.xfc-btn:focus-visible {
|
|
@@ -228,8 +304,10 @@ a:hover {
|
|
|
228
304
|
}
|
|
229
305
|
|
|
230
306
|
.xfc-btn:disabled {
|
|
231
|
-
opacity: 0.
|
|
307
|
+
opacity: 0.48;
|
|
232
308
|
cursor: not-allowed;
|
|
309
|
+
transform: none;
|
|
310
|
+
box-shadow: none;
|
|
233
311
|
}
|
|
234
312
|
|
|
235
313
|
.xfc-btn--loading {
|
|
@@ -250,52 +328,75 @@ a:hover {
|
|
|
250
328
|
.xfc-btn--primary {
|
|
251
329
|
background: var(--xfc-accent);
|
|
252
330
|
color: var(--xfc-accent-fg);
|
|
331
|
+
box-shadow:
|
|
332
|
+
var(--xfc-shadow-xs),
|
|
333
|
+
0 2px 12px color-mix(in srgb, var(--xfc-accent) 32%, transparent);
|
|
253
334
|
}
|
|
254
335
|
|
|
255
336
|
.xfc-btn--primary:hover:not(:disabled) {
|
|
256
337
|
background: var(--xfc-accent-hover);
|
|
338
|
+
box-shadow:
|
|
339
|
+
var(--xfc-shadow-sm),
|
|
340
|
+
0 4px 20px color-mix(in srgb, var(--xfc-accent) 38%, transparent);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
@media (hover: hover) {
|
|
344
|
+
.xfc-btn--primary:hover:not(:disabled) {
|
|
345
|
+
transform: translateY(-1px);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.xfc-btn--primary:active:not(:disabled) {
|
|
349
|
+
transform: translateY(0);
|
|
350
|
+
}
|
|
257
351
|
}
|
|
258
352
|
|
|
259
353
|
.xfc-btn--secondary {
|
|
260
354
|
background: var(--xfc-bg-elevated);
|
|
261
355
|
color: var(--xfc-fg);
|
|
262
356
|
border-color: var(--xfc-border-strong);
|
|
357
|
+
box-shadow: var(--xfc-shadow-xs);
|
|
263
358
|
}
|
|
264
359
|
|
|
265
360
|
.xfc-btn--secondary:hover:not(:disabled) {
|
|
266
|
-
border-color: var(--xfc-
|
|
361
|
+
border-color: color-mix(in srgb, var(--xfc-accent) 35%, var(--xfc-border-strong));
|
|
362
|
+
background: color-mix(in srgb, var(--xfc-bg-muted) 40%, var(--xfc-bg-elevated));
|
|
267
363
|
}
|
|
268
364
|
|
|
269
365
|
.xfc-btn--outline {
|
|
270
|
-
background:
|
|
366
|
+
background: transparent;
|
|
271
367
|
color: var(--xfc-accent);
|
|
272
|
-
border-color: var(--xfc-accent);
|
|
368
|
+
border-color: color-mix(in srgb, var(--xfc-accent) 45%, var(--xfc-border-strong));
|
|
369
|
+
box-shadow: none;
|
|
273
370
|
}
|
|
274
371
|
|
|
275
372
|
.xfc-btn--outline:hover:not(:disabled) {
|
|
276
|
-
background:
|
|
373
|
+
background: var(--xfc-accent-soft);
|
|
374
|
+
border-color: var(--xfc-accent);
|
|
277
375
|
}
|
|
278
376
|
|
|
279
377
|
.xfc-btn--muted {
|
|
280
|
-
background: var(--xfc-bg-
|
|
378
|
+
background: color-mix(in srgb, var(--xfc-bg-muted) 65%, var(--xfc-bg-elevated));
|
|
281
379
|
color: var(--xfc-fg-muted);
|
|
282
|
-
border-color:
|
|
380
|
+
border-color: var(--xfc-border);
|
|
381
|
+
box-shadow: none;
|
|
283
382
|
}
|
|
284
383
|
|
|
285
384
|
.xfc-btn--muted:hover:not(:disabled) {
|
|
286
|
-
|
|
385
|
+
background: var(--xfc-bg-muted);
|
|
386
|
+
color: var(--xfc-fg-label);
|
|
287
387
|
}
|
|
288
388
|
|
|
289
389
|
.xfc-btn--ghost {
|
|
290
390
|
background: transparent;
|
|
291
391
|
color: var(--xfc-accent);
|
|
392
|
+
box-shadow: none;
|
|
292
393
|
}
|
|
293
394
|
|
|
294
395
|
.xfc-btn--ghost:hover:not(:disabled) {
|
|
295
|
-
background:
|
|
396
|
+
background: var(--xfc-accent-soft);
|
|
296
397
|
}
|
|
297
398
|
|
|
298
|
-
/* —— Inputs
|
|
399
|
+
/* —— Inputs —— */
|
|
299
400
|
|
|
300
401
|
.xfc-input {
|
|
301
402
|
display: block;
|
|
@@ -307,26 +408,32 @@ a:hover {
|
|
|
307
408
|
color: var(--xfc-fg);
|
|
308
409
|
background: var(--xfc-bg-elevated);
|
|
309
410
|
border: 1px solid var(--xfc-border-strong);
|
|
310
|
-
border-radius: var(--xfc-radius-
|
|
411
|
+
border-radius: var(--xfc-radius-sm);
|
|
311
412
|
box-shadow: var(--xfc-input-shadow);
|
|
312
413
|
transition:
|
|
313
|
-
border-color 0.
|
|
314
|
-
box-shadow 0.
|
|
414
|
+
border-color 0.18s ease,
|
|
415
|
+
box-shadow 0.18s ease,
|
|
416
|
+
background-color 0.18s ease;
|
|
315
417
|
}
|
|
316
418
|
|
|
317
419
|
.xfc-input::placeholder {
|
|
318
420
|
color: var(--xfc-fg-placeholder);
|
|
319
421
|
}
|
|
320
422
|
|
|
423
|
+
.xfc-input:hover:not(:disabled):not(:focus) {
|
|
424
|
+
border-color: color-mix(in srgb, var(--xfc-border-strong) 70%, var(--xfc-fg-muted) 30%);
|
|
425
|
+
}
|
|
426
|
+
|
|
321
427
|
.xfc-input:focus {
|
|
322
428
|
outline: none;
|
|
323
429
|
border-color: var(--xfc-accent);
|
|
324
|
-
box-shadow: var(--xfc-
|
|
430
|
+
box-shadow: var(--xfc-shadow-sm), var(--xfc-focus-ring);
|
|
325
431
|
}
|
|
326
432
|
|
|
327
433
|
.xfc-input:disabled {
|
|
328
|
-
opacity: 0.
|
|
434
|
+
opacity: 0.55;
|
|
329
435
|
cursor: not-allowed;
|
|
436
|
+
background: var(--xfc-bg-muted);
|
|
330
437
|
}
|
|
331
438
|
|
|
332
439
|
.xfc-input--invalid {
|
|
@@ -335,7 +442,7 @@ a:hover {
|
|
|
335
442
|
|
|
336
443
|
.xfc-input--invalid:focus {
|
|
337
444
|
border-color: var(--xfc-danger);
|
|
338
|
-
box-shadow: var(--xfc-
|
|
445
|
+
box-shadow: var(--xfc-shadow-xs), 0 0 0 3px color-mix(in srgb, var(--xfc-danger) 22%, transparent);
|
|
339
446
|
}
|
|
340
447
|
|
|
341
448
|
.xfc-input-description {
|
|
@@ -410,31 +517,44 @@ a:hover {
|
|
|
410
517
|
.xfc-badge {
|
|
411
518
|
display: inline-flex;
|
|
412
519
|
align-items: center;
|
|
413
|
-
padding:
|
|
520
|
+
padding: 4px 10px;
|
|
414
521
|
font-size: var(--xfc-text-small);
|
|
415
522
|
font-weight: 600;
|
|
416
|
-
line-height: 1.
|
|
417
|
-
|
|
523
|
+
line-height: 1.25;
|
|
524
|
+
letter-spacing: 0.01em;
|
|
525
|
+
border-radius: var(--xfc-radius-full);
|
|
526
|
+
border: 1px solid transparent;
|
|
527
|
+
box-shadow: var(--xfc-shadow-xs);
|
|
418
528
|
}
|
|
419
529
|
|
|
420
530
|
.xfc-badge--neutral {
|
|
421
|
-
background: var(--xfc-
|
|
422
|
-
color: var(--xfc-fg);
|
|
531
|
+
background: color-mix(in srgb, var(--xfc-bg-muted) 55%, var(--xfc-bg-elevated));
|
|
532
|
+
color: var(--xfc-fg-label);
|
|
533
|
+
border-color: var(--xfc-border);
|
|
423
534
|
}
|
|
424
535
|
|
|
425
536
|
.xfc-badge--accent {
|
|
426
|
-
background: color-mix(in srgb, var(--xfc-accent)
|
|
427
|
-
color: var(--xfc-accent
|
|
537
|
+
background: color-mix(in srgb, var(--xfc-accent) 16%, var(--xfc-bg-elevated));
|
|
538
|
+
color: var(--xfc-accent);
|
|
539
|
+
border-color: color-mix(in srgb, var(--xfc-accent) 28%, transparent);
|
|
428
540
|
}
|
|
429
541
|
|
|
430
542
|
.xfc-badge--success {
|
|
431
|
-
background: var(--xfc-success-bg);
|
|
543
|
+
background: color-mix(in srgb, var(--xfc-success) 12%, var(--xfc-success-bg));
|
|
432
544
|
color: var(--xfc-success);
|
|
545
|
+
border-color: color-mix(in srgb, var(--xfc-success) 22%, transparent);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
.xfc-badge--warn {
|
|
549
|
+
background: color-mix(in srgb, var(--xfc-warning) 14%, var(--xfc-warning-bg));
|
|
550
|
+
color: color-mix(in srgb, var(--xfc-warning) 85%, #000);
|
|
551
|
+
border-color: color-mix(in srgb, var(--xfc-warning) 25%, transparent);
|
|
433
552
|
}
|
|
434
553
|
|
|
435
554
|
.xfc-badge--danger {
|
|
436
|
-
background: color-mix(in srgb, var(--xfc-danger)
|
|
555
|
+
background: color-mix(in srgb, var(--xfc-danger) 12%, var(--xfc-bg-elevated));
|
|
437
556
|
color: var(--xfc-danger);
|
|
557
|
+
border-color: color-mix(in srgb, var(--xfc-danger) 22%, transparent);
|
|
438
558
|
}
|
|
439
559
|
|
|
440
560
|
span.xfc-badge[aria-disabled='true'] {
|
|
@@ -479,17 +599,18 @@ button.xfc-badge[aria-disabled='true'] {
|
|
|
479
599
|
}
|
|
480
600
|
|
|
481
601
|
.xfc-loading-overlay-spinner {
|
|
482
|
-
width:
|
|
483
|
-
height:
|
|
484
|
-
border:
|
|
602
|
+
width: 52px;
|
|
603
|
+
height: 52px;
|
|
604
|
+
border: 3px solid color-mix(in srgb, var(--xfc-accent) 18%, transparent);
|
|
485
605
|
border-top-color: var(--xfc-accent);
|
|
606
|
+
border-right-color: color-mix(in srgb, var(--xfc-accent) 45%, transparent);
|
|
486
607
|
border-radius: 50%;
|
|
487
|
-
animation: xfc-loading-overlay-spin 0.
|
|
608
|
+
animation: xfc-loading-overlay-spin 0.72s linear infinite;
|
|
488
609
|
flex-shrink: 0;
|
|
489
610
|
box-shadow:
|
|
490
|
-
0 0 0
|
|
491
|
-
0
|
|
492
|
-
|
|
611
|
+
0 0 0 1px rgba(255, 255, 255, 0.5),
|
|
612
|
+
0 8px 32px color-mix(in srgb, var(--xfc-accent) 22%, transparent),
|
|
613
|
+
var(--xfc-shadow-md);
|
|
493
614
|
}
|
|
494
615
|
|
|
495
616
|
.xfc-loading-overlay-title {
|
|
@@ -564,32 +685,38 @@ button.xfc-badge[aria-disabled='true'] {
|
|
|
564
685
|
box-sizing: border-box;
|
|
565
686
|
align-items: flex-start;
|
|
566
687
|
justify-content: flex-start;
|
|
567
|
-
gap: var(--xfc-space-
|
|
568
|
-
padding: var(--xfc-space-lg);
|
|
688
|
+
gap: var(--xfc-space-md);
|
|
689
|
+
padding: var(--xfc-space-lg) var(--xfc-space-xl);
|
|
569
690
|
border-radius: var(--xfc-toast-radius);
|
|
570
691
|
color: #fff;
|
|
571
692
|
font-family: var(--xfc-font-sans);
|
|
572
693
|
font-size: var(--xfc-text-body);
|
|
573
|
-
font-weight:
|
|
574
|
-
line-height: 1.
|
|
694
|
+
font-weight: 500;
|
|
695
|
+
line-height: 1.35;
|
|
696
|
+
letter-spacing: -0.01em;
|
|
697
|
+
border: var(--xfc-toast-border);
|
|
575
698
|
box-shadow: var(--xfc-toast-shadow);
|
|
576
|
-
|
|
699
|
+
backdrop-filter: blur(8px);
|
|
700
|
+
-webkit-backdrop-filter: blur(8px);
|
|
701
|
+
transition:
|
|
702
|
+
opacity 0.2s ease,
|
|
703
|
+
transform 0.2s ease;
|
|
577
704
|
}
|
|
578
705
|
|
|
579
706
|
.xfc-toast--info {
|
|
580
|
-
background: var(--xfc-toast-info-bg);
|
|
707
|
+
background: linear-gradient(155deg, rgba(255, 255, 255, 0.12) 0%, transparent 42%), var(--xfc-toast-info-bg);
|
|
581
708
|
}
|
|
582
709
|
|
|
583
710
|
.xfc-toast--success {
|
|
584
|
-
background: var(--xfc-toast-success-bg);
|
|
711
|
+
background: linear-gradient(155deg, rgba(255, 255, 255, 0.14) 0%, transparent 40%), var(--xfc-toast-success-bg);
|
|
585
712
|
}
|
|
586
713
|
|
|
587
714
|
.xfc-toast--warn {
|
|
588
|
-
background: var(--xfc-toast-warn-bg);
|
|
715
|
+
background: linear-gradient(155deg, rgba(255, 255, 255, 0.12) 0%, transparent 40%), var(--xfc-toast-warn-bg);
|
|
589
716
|
}
|
|
590
717
|
|
|
591
718
|
.xfc-toast--error {
|
|
592
|
-
background: var(--xfc-toast-error-bg);
|
|
719
|
+
background: linear-gradient(155deg, rgba(255, 255, 255, 0.12) 0%, transparent 40%), var(--xfc-toast-error-bg);
|
|
593
720
|
}
|
|
594
721
|
|
|
595
722
|
.xfc-toast__icon {
|
|
@@ -662,11 +789,13 @@ button.xfc-badge[aria-disabled='true'] {
|
|
|
662
789
|
align-items: center;
|
|
663
790
|
justify-content: space-between;
|
|
664
791
|
gap: var(--xfc-space-sm);
|
|
665
|
-
padding: var(--xfc-space-md) var(--xfc-space-
|
|
666
|
-
background: var(--xfc-danger);
|
|
792
|
+
padding: var(--xfc-space-md) var(--xfc-space-xl);
|
|
793
|
+
background: linear-gradient(135deg, color-mix(in srgb, var(--xfc-danger) 92%, #fff) 0%, var(--xfc-danger) 100%);
|
|
667
794
|
color: var(--xfc-accent-fg);
|
|
668
|
-
border-radius: var(--xfc-radius-
|
|
795
|
+
border-radius: var(--xfc-radius-lg);
|
|
669
796
|
font-size: var(--xfc-text-small);
|
|
797
|
+
font-weight: 600;
|
|
798
|
+
border: 1px solid color-mix(in srgb, var(--xfc-danger) 55%, #fff);
|
|
670
799
|
box-shadow: var(--xfc-toast-shadow);
|
|
671
800
|
}
|
|
672
801
|
|
|
@@ -744,8 +873,10 @@ button.xfc-badge[aria-disabled='true'] {
|
|
|
744
873
|
justify-content: center;
|
|
745
874
|
padding: var(--xfc-space-lg);
|
|
746
875
|
box-sizing: border-box;
|
|
747
|
-
background: color-mix(in srgb, var(--xfc-fg)
|
|
748
|
-
|
|
876
|
+
background: color-mix(in srgb, var(--xfc-fg-strong) 48%, transparent);
|
|
877
|
+
backdrop-filter: blur(10px) saturate(1.05);
|
|
878
|
+
-webkit-backdrop-filter: blur(10px) saturate(1.05);
|
|
879
|
+
animation: xfc-dialog-backdrop-in 0.2s ease-out;
|
|
749
880
|
}
|
|
750
881
|
|
|
751
882
|
.xfc-dialog-backdrop--bottom {
|
|
@@ -762,15 +893,13 @@ button.xfc-badge[aria-disabled='true'] {
|
|
|
762
893
|
overflow: auto;
|
|
763
894
|
box-sizing: border-box;
|
|
764
895
|
padding: var(--xfc-space-xl);
|
|
765
|
-
border-radius: var(--xfc-radius-
|
|
896
|
+
border-radius: var(--xfc-radius-lg);
|
|
766
897
|
background: var(--xfc-bg-elevated);
|
|
767
898
|
color: var(--xfc-fg);
|
|
768
|
-
border: 1px solid var(--xfc-border);
|
|
769
|
-
box-shadow:
|
|
770
|
-
0 24px 48px color-mix(in srgb, var(--xfc-fg) 12%, transparent),
|
|
771
|
-
var(--xfc-card-shadow);
|
|
899
|
+
border: 1px solid color-mix(in srgb, var(--xfc-border) 88%, var(--xfc-accent) 10%);
|
|
900
|
+
box-shadow: var(--xfc-shadow-lg);
|
|
772
901
|
font-family: var(--xfc-font-sans);
|
|
773
|
-
animation: xfc-dialog-panel-in 0.
|
|
902
|
+
animation: xfc-dialog-panel-in 0.24s cubic-bezier(0.22, 1, 0.36, 1);
|
|
774
903
|
}
|
|
775
904
|
|
|
776
905
|
.xfc-dialog-panel__title-row {
|
|
@@ -916,4 +1045,10 @@ button.xfc-btn.xfc-btn--primary.xfc-confirm-dialog__confirm--danger:hover:not(:d
|
|
|
916
1045
|
.xfc-bottom-sheet-panel {
|
|
917
1046
|
animation: none;
|
|
918
1047
|
}
|
|
1048
|
+
|
|
1049
|
+
.xfc-btn--primary:hover:not(:disabled),
|
|
1050
|
+
.xfc-card--interactive:hover,
|
|
1051
|
+
.xfc-card--interactive:active {
|
|
1052
|
+
transform: none;
|
|
1053
|
+
}
|
|
919
1054
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HTMLAttributes, MouseEventHandler, ReactNode } from 'react';
|
|
2
2
|
export type BadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, 'onClick'> & {
|
|
3
|
-
tone?: 'neutral' | 'accent' | 'success' | 'danger';
|
|
3
|
+
tone?: 'neutral' | 'accent' | 'success' | 'warn' | 'danger';
|
|
4
4
|
children?: ReactNode;
|
|
5
5
|
/** 앞쪽 아이콘·이모지 등 */
|
|
6
6
|
icon?: ReactNode;
|
|
@@ -5,5 +5,7 @@ export type CardProps = HTMLAttributes<HTMLDivElement> & {
|
|
|
5
5
|
title?: ReactNode;
|
|
6
6
|
/** 하단 푸터 슬롯 */
|
|
7
7
|
footer?: ReactNode;
|
|
8
|
+
/** true면 호버 시 살짝 떠오르는 인터랙션 (클릭 카드·타일용) */
|
|
9
|
+
interactive?: boolean;
|
|
8
10
|
};
|
|
9
|
-
export declare function Card({ className, children, title, footer, ...rest }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function Card({ className, children, title, footer, interactive, ...rest }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Card = Card;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
function Card({ className = '', children, title, footer, ...rest }) {
|
|
6
|
-
const cls = ['xfc-card', className].filter(Boolean).join(' ');
|
|
5
|
+
function Card({ className = '', children, title, footer, interactive, ...rest }) {
|
|
6
|
+
const cls = ['xfc-card', interactive ? 'xfc-card--interactive' : '', className].filter(Boolean).join(' ');
|
|
7
7
|
const structured = title != null || footer != null;
|
|
8
8
|
return ((0, jsx_runtime_1.jsxs)("div", { className: cls, ...rest, children: [title != null ? (0, jsx_runtime_1.jsx)("div", { className: "xfc-card__header", children: title }) : null, structured ? (0, jsx_runtime_1.jsx)("div", { className: "xfc-card__body", children: children }) : children, footer != null ? (0, jsx_runtime_1.jsx)("div", { className: "xfc-card__footer", children: footer }) : null] }));
|
|
9
9
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export type PaperProps = HTMLAttributes<HTMLDivElement> & {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
/**
|
|
5
|
+
* Material-style elevation: 0은 평면+보더, 1…4는 섀도 강도 증가.
|
|
6
|
+
* `variant="outlined"`일 때는 무시되고 보더만 씀.
|
|
7
|
+
*/
|
|
8
|
+
elevation?: 0 | 1 | 2 | 3 | 4;
|
|
9
|
+
/** filled = elevation 섀도, outlined = 보더만 */
|
|
10
|
+
variant?: 'filled' | 'outlined';
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* 콘텐츠를 올려놓는 표면 컴포넌트 (MUI `Paper` / RN Paper `Surface`에 가깝게).
|
|
14
|
+
* 스타일은 `base.css`의 `.xfc-paper*` — 토큰 `--xfc-shadow-*`와 연동.
|
|
15
|
+
*/
|
|
16
|
+
export declare function Paper({ elevation, variant, className, children, ...rest }: PaperProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Paper = Paper;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
/**
|
|
6
|
+
* 콘텐츠를 올려놓는 표면 컴포넌트 (MUI `Paper` / RN Paper `Surface`에 가깝게).
|
|
7
|
+
* 스타일은 `base.css`의 `.xfc-paper*` — 토큰 `--xfc-shadow-*`와 연동.
|
|
8
|
+
*/
|
|
9
|
+
function Paper({ elevation = 1, variant = 'filled', className = '', children, ...rest }) {
|
|
10
|
+
const elevClass = variant === 'outlined' ? 'xfc-paper--outlined' : `xfc-paper--elevation-${elevation}`;
|
|
11
|
+
const cls = ['xfc-paper', elevClass, className].filter(Boolean).join(' ');
|
|
12
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: cls, ...rest, children: children }));
|
|
13
|
+
}
|
|
@@ -4,6 +4,7 @@ declare const variantClass: {
|
|
|
4
4
|
readonly appbar: "xfc-text xfc-text--appbar";
|
|
5
5
|
readonly section: "xfc-text xfc-text--section";
|
|
6
6
|
readonly subtitle: "xfc-text xfc-text--subtitle";
|
|
7
|
+
readonly lead: "xfc-text xfc-text--lead";
|
|
7
8
|
readonly body: "xfc-text xfc-text--body";
|
|
8
9
|
readonly muted: "xfc-text xfc-text--body xfc-text--muted";
|
|
9
10
|
readonly small: "xfc-text xfc-text--small";
|
|
@@ -7,6 +7,7 @@ const variantClass = {
|
|
|
7
7
|
appbar: 'xfc-text xfc-text--appbar',
|
|
8
8
|
section: 'xfc-text xfc-text--section',
|
|
9
9
|
subtitle: 'xfc-text xfc-text--subtitle',
|
|
10
|
+
lead: 'xfc-text xfc-text--lead',
|
|
10
11
|
body: 'xfc-text xfc-text--body',
|
|
11
12
|
muted: 'xfc-text xfc-text--body xfc-text--muted',
|
|
12
13
|
small: 'xfc-text xfc-text--small',
|
|
@@ -13,6 +13,7 @@ export { Select, type SelectProps } from './Select';
|
|
|
13
13
|
export { Textarea, type TextareaProps } from './Textarea';
|
|
14
14
|
export { InlineErrorList, type InlineErrorEntry, type InlineErrorListProps, } from './InlineErrorList';
|
|
15
15
|
export { LoadingOverlay, type LoadingOverlayProps } from './LoadingOverlay';
|
|
16
|
+
export { Paper, type PaperProps } from './Paper';
|
|
16
17
|
export { Stack, type StackProps } from './Stack';
|
|
17
18
|
export { Toast, ToastList, ToastSeverityIcon, type ToastEntry, type ToastListProps, type ToastProps, type ToastSeverity, type ToastSeverityIconProps, } from './Toast';
|
|
18
19
|
export { Text, type TextProps, type TextVariant } from './Text';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Text = exports.ToastSeverityIcon = exports.ToastList = exports.Toast = exports.Stack = exports.LoadingOverlay = exports.InlineErrorList = exports.Textarea = exports.Select = exports.Input = exports.Field = exports.Checkbox = exports.Card = exports.Button = exports.Box = exports.Badge = void 0;
|
|
3
|
+
exports.Text = exports.ToastSeverityIcon = exports.ToastList = exports.Toast = exports.Stack = exports.Paper = exports.LoadingOverlay = exports.InlineErrorList = exports.Textarea = exports.Select = exports.Input = exports.Field = exports.Checkbox = exports.Card = exports.Button = exports.Box = exports.Badge = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Atomic UI — design tokens + base.css 의 `.xfc-*` 와 1:1.
|
|
6
6
|
* 패키지 루트는 `components/index.ts` → 여기서 동일 심볼을 재export.
|
|
@@ -27,6 +27,8 @@ var InlineErrorList_1 = require("./InlineErrorList");
|
|
|
27
27
|
Object.defineProperty(exports, "InlineErrorList", { enumerable: true, get: function () { return InlineErrorList_1.InlineErrorList; } });
|
|
28
28
|
var LoadingOverlay_1 = require("./LoadingOverlay");
|
|
29
29
|
Object.defineProperty(exports, "LoadingOverlay", { enumerable: true, get: function () { return LoadingOverlay_1.LoadingOverlay; } });
|
|
30
|
+
var Paper_1 = require("./Paper");
|
|
31
|
+
Object.defineProperty(exports, "Paper", { enumerable: true, get: function () { return Paper_1.Paper; } });
|
|
30
32
|
var Stack_1 = require("./Stack");
|
|
31
33
|
Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return Stack_1.Stack; } });
|
|
32
34
|
var Toast_1 = require("./Toast");
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Auto-generated by scripts/write-version.js — do not edit by hand */
|
|
2
|
-
export declare const XFRAME_FRONT_CORE_VERSION: "0.2.
|
|
2
|
+
export declare const XFRAME_FRONT_CORE_VERSION: "0.2.28";
|
package/dist/generatedVersion.js
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.XFRAME_FRONT_CORE_VERSION = void 0;
|
|
4
4
|
/** Auto-generated by scripts/write-version.js — do not edit by hand */
|
|
5
|
-
exports.XFRAME_FRONT_CORE_VERSION = "0.2.
|
|
5
|
+
exports.XFRAME_FRONT_CORE_VERSION = "0.2.28";
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,12 @@ export declare const tokenVars: {
|
|
|
24
24
|
readonly colorBorderStrong: "--xfc-border-strong";
|
|
25
25
|
readonly colorAccent: "--xfc-accent";
|
|
26
26
|
readonly colorAccentHover: "--xfc-accent-hover";
|
|
27
|
+
readonly colorAccentSoft: "--xfc-accent-soft";
|
|
27
28
|
readonly colorDanger: "--xfc-danger";
|
|
29
|
+
readonly shadowXs: "--xfc-shadow-xs";
|
|
30
|
+
readonly shadowSm: "--xfc-shadow-sm";
|
|
31
|
+
readonly shadowMd: "--xfc-shadow-md";
|
|
32
|
+
readonly shadowLg: "--xfc-shadow-lg";
|
|
28
33
|
readonly radiusXs: "--xfc-radius-xs";
|
|
29
34
|
readonly radiusSm: "--xfc-radius-sm";
|
|
30
35
|
readonly radiusMd: "--xfc-radius-md";
|
|
@@ -46,6 +51,6 @@ export declare const tokenVars: {
|
|
|
46
51
|
readonly toastWarnBg: "--xfc-toast-warn-bg";
|
|
47
52
|
readonly toastErrorBg: "--xfc-toast-error-bg";
|
|
48
53
|
};
|
|
49
|
-
export { Badge, BottomSheet, Box, Button, Card, Checkbox, ConfirmDialog, Dialog, Field, InlineErrorList, Input, LoadingOverlay, Select, Stack, Text, Textarea, Toast, ToastList, ToastSeverityIcon, type BadgeProps, type BottomSheetProps, type BoxProps, type ButtonProps, type CardProps, type CheckboxProps, type ConfirmDialogProps, type DialogProps, type FieldProps, type InlineErrorEntry, type InlineErrorListProps, type InputProps, type LoadingOverlayProps, type SelectProps, type StackProps, type TextProps, type TextVariant, type TextareaProps, type ToastEntry, type ToastListProps, type ToastProps, type ToastSeverity, type ToastSeverityIconProps, } from './components';
|
|
54
|
+
export { Badge, BottomSheet, Box, Button, Card, Checkbox, ConfirmDialog, Dialog, Field, InlineErrorList, Input, LoadingOverlay, Paper, Select, Stack, Text, Textarea, Toast, ToastList, ToastSeverityIcon, type BadgeProps, type BottomSheetProps, type BoxProps, type ButtonProps, type CardProps, type CheckboxProps, type ConfirmDialogProps, type DialogProps, type FieldProps, type InlineErrorEntry, type InlineErrorListProps, type InputProps, type LoadingOverlayProps, type PaperProps, type SelectProps, type StackProps, type TextProps, type TextVariant, type TextareaProps, type ToastEntry, type ToastListProps, type ToastProps, type ToastSeverity, type ToastSeverityIconProps, } from './components';
|
|
50
55
|
/** 커스텀 오버레이용 — `Dialog`/`BottomSheet`와 동일한 훅 */
|
|
51
56
|
export { useBodyScrollLock, useEscapeKey, useFocusTrap } from './components';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useFocusTrap = exports.useEscapeKey = exports.useBodyScrollLock = exports.ToastSeverityIcon = exports.ToastList = exports.Toast = exports.Textarea = exports.Text = exports.Stack = exports.Select = exports.LoadingOverlay = exports.Input = exports.InlineErrorList = exports.Field = exports.Dialog = exports.ConfirmDialog = exports.Checkbox = exports.Card = exports.Button = exports.Box = exports.BottomSheet = exports.Badge = exports.tokenVars = exports.XFRAME_FRONT_CORE_VERSION = void 0;
|
|
3
|
+
exports.useFocusTrap = exports.useEscapeKey = exports.useBodyScrollLock = exports.ToastSeverityIcon = exports.ToastList = exports.Toast = exports.Textarea = exports.Text = exports.Stack = exports.Select = exports.Paper = exports.LoadingOverlay = exports.Input = exports.InlineErrorList = exports.Field = exports.Dialog = exports.ConfirmDialog = exports.Checkbox = exports.Card = exports.Button = exports.Box = exports.BottomSheet = exports.Badge = exports.tokenVars = exports.XFRAME_FRONT_CORE_VERSION = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* @xfilecom/front-core — design tokens + atomic React components (browser-only).
|
|
6
6
|
*
|
|
@@ -28,7 +28,12 @@ exports.tokenVars = {
|
|
|
28
28
|
colorBorderStrong: '--xfc-border-strong',
|
|
29
29
|
colorAccent: '--xfc-accent',
|
|
30
30
|
colorAccentHover: '--xfc-accent-hover',
|
|
31
|
+
colorAccentSoft: '--xfc-accent-soft',
|
|
31
32
|
colorDanger: '--xfc-danger',
|
|
33
|
+
shadowXs: '--xfc-shadow-xs',
|
|
34
|
+
shadowSm: '--xfc-shadow-sm',
|
|
35
|
+
shadowMd: '--xfc-shadow-md',
|
|
36
|
+
shadowLg: '--xfc-shadow-lg',
|
|
32
37
|
radiusXs: '--xfc-radius-xs',
|
|
33
38
|
radiusSm: '--xfc-radius-sm',
|
|
34
39
|
radiusMd: '--xfc-radius-md',
|
|
@@ -63,6 +68,7 @@ Object.defineProperty(exports, "Field", { enumerable: true, get: function () { r
|
|
|
63
68
|
Object.defineProperty(exports, "InlineErrorList", { enumerable: true, get: function () { return components_1.InlineErrorList; } });
|
|
64
69
|
Object.defineProperty(exports, "Input", { enumerable: true, get: function () { return components_1.Input; } });
|
|
65
70
|
Object.defineProperty(exports, "LoadingOverlay", { enumerable: true, get: function () { return components_1.LoadingOverlay; } });
|
|
71
|
+
Object.defineProperty(exports, "Paper", { enumerable: true, get: function () { return components_1.Paper; } });
|
|
66
72
|
Object.defineProperty(exports, "Select", { enumerable: true, get: function () { return components_1.Select; } });
|
|
67
73
|
Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return components_1.Stack; } });
|
|
68
74
|
Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return components_1.Text; } });
|
package/dist/tokens.css
CHANGED
|
@@ -1,56 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Design tokens —
|
|
3
|
-
*
|
|
2
|
+
* Design tokens — 기본 테마 (라이트).
|
|
3
|
+
* 슬레이트 뉴트럴 + 인디고 액센트, 계층형 섀도·라디우스.
|
|
4
|
+
*
|
|
5
|
+
* Material 3 / MUI Paper / react-native-paper 와의 대응(개념):
|
|
6
|
+
* - 페이지 바탕: `--xfc-bg` ≈ surface / screen background
|
|
7
|
+
* - 카드·시트: `--xfc-bg-elevated` + `--xfc-shadow-*` ≈ elevated surface
|
|
8
|
+
* - `<Paper elevation={n}>` → `.xfc-paper--elevation-n` → `--xfc-shadow-xs|sm|md|lg`
|
|
9
|
+
* 자세한 비교: 패키지 `docs/DESIGN_SYSTEM.md`
|
|
4
10
|
*/
|
|
5
11
|
:root {
|
|
6
12
|
/* Surfaces */
|
|
7
|
-
--xfc-bg: #
|
|
13
|
+
--xfc-bg: #f4f5f8;
|
|
8
14
|
--xfc-bg-elevated: #ffffff;
|
|
9
|
-
--xfc-bg-muted: #
|
|
10
|
-
--xfc-bg-disabled: #
|
|
15
|
+
--xfc-bg-muted: #e8ebf2;
|
|
16
|
+
--xfc-bg-disabled: #dce0e8;
|
|
11
17
|
|
|
12
18
|
/* Text */
|
|
13
|
-
--xfc-fg: #
|
|
14
|
-
--xfc-fg-strong: #
|
|
15
|
-
--xfc-fg-label: #
|
|
16
|
-
--xfc-fg-muted: #
|
|
17
|
-
--xfc-fg-placeholder: #
|
|
18
|
-
--xfc-fg-icon: #
|
|
19
|
+
--xfc-fg: #1e293b;
|
|
20
|
+
--xfc-fg-strong: #0f172a;
|
|
21
|
+
--xfc-fg-label: #334155;
|
|
22
|
+
--xfc-fg-muted: #64748b;
|
|
23
|
+
--xfc-fg-placeholder: #94a3b8;
|
|
24
|
+
--xfc-fg-icon: #475569;
|
|
19
25
|
|
|
20
26
|
/* Lines */
|
|
21
|
-
--xfc-border: #
|
|
22
|
-
--xfc-border-strong: #
|
|
23
|
-
--xfc-border-header: #
|
|
27
|
+
--xfc-border: #e2e8f0;
|
|
28
|
+
--xfc-border-strong: #cbd5e1;
|
|
29
|
+
--xfc-border-header: #e2e8f0;
|
|
24
30
|
|
|
25
31
|
/* Brand */
|
|
26
|
-
--xfc-accent: #
|
|
27
|
-
--xfc-accent-hover: #
|
|
32
|
+
--xfc-accent: #4f46e5;
|
|
33
|
+
--xfc-accent-hover: #4338ca;
|
|
28
34
|
--xfc-accent-fg: #ffffff;
|
|
35
|
+
/** 포커스·글로우용 연한 틴트 */
|
|
36
|
+
--xfc-accent-soft: color-mix(in srgb, var(--xfc-accent) 14%, transparent);
|
|
29
37
|
|
|
30
38
|
/* Status */
|
|
31
|
-
--xfc-danger: #
|
|
39
|
+
--xfc-danger: #e11d48;
|
|
32
40
|
--xfc-success: #059669;
|
|
33
41
|
--xfc-success-bg: #d1fae5;
|
|
34
42
|
--xfc-warning: #d97706;
|
|
35
43
|
--xfc-warning-bg: #fef3c7;
|
|
36
44
|
|
|
37
|
-
/* Toasts (
|
|
38
|
-
--xfc-toast-info-bg: #
|
|
39
|
-
--xfc-toast-success-bg: #
|
|
40
|
-
--xfc-toast-warn-bg: #
|
|
41
|
-
--xfc-toast-error-bg: #
|
|
42
|
-
--xfc-toast-shadow: 0
|
|
43
|
-
--xfc-toast-radius:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
--xfc-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
--xfc-
|
|
51
|
-
|
|
52
|
-
--xfc-
|
|
53
|
-
--xfc-
|
|
45
|
+
/* Toasts (단색 — 그라데이션·글로우는 base.css 에서 보강) */
|
|
46
|
+
--xfc-toast-info-bg: #1e293b;
|
|
47
|
+
--xfc-toast-success-bg: #059669;
|
|
48
|
+
--xfc-toast-warn-bg: #d97706;
|
|
49
|
+
--xfc-toast-error-bg: #e11d48;
|
|
50
|
+
--xfc-toast-shadow: 0 10px 40px rgba(15, 23, 42, 0.18), 0 2px 8px rgba(15, 23, 42, 0.08);
|
|
51
|
+
--xfc-toast-radius: 12px;
|
|
52
|
+
--xfc-toast-border: 1px solid rgba(255, 255, 255, 0.14);
|
|
53
|
+
|
|
54
|
+
/* Layered shadows */
|
|
55
|
+
--xfc-shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
|
|
56
|
+
--xfc-shadow-sm: 0 2px 8px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
57
|
+
--xfc-shadow-md: 0 8px 24px rgba(15, 23, 42, 0.08), 0 2px 6px rgba(15, 23, 42, 0.04);
|
|
58
|
+
--xfc-shadow-lg: 0 24px 48px rgba(15, 23, 42, 0.12), 0 8px 16px rgba(15, 23, 42, 0.06);
|
|
59
|
+
|
|
60
|
+
--xfc-input-shadow: var(--xfc-shadow-xs);
|
|
61
|
+
--xfc-card-shadow: var(--xfc-shadow-sm);
|
|
62
|
+
|
|
63
|
+
/* Radius */
|
|
64
|
+
--xfc-radius-xs: 8px;
|
|
65
|
+
--xfc-radius-sm: 10px;
|
|
66
|
+
--xfc-radius-md: 14px;
|
|
67
|
+
--xfc-radius-lg: 18px;
|
|
54
68
|
--xfc-radius-full: 9999px;
|
|
55
69
|
|
|
56
70
|
/* Space */
|
|
@@ -61,7 +75,7 @@
|
|
|
61
75
|
--xfc-space-xl: 24px;
|
|
62
76
|
--xfc-space-2xl: 32px;
|
|
63
77
|
|
|
64
|
-
/* Typography
|
|
78
|
+
/* Typography */
|
|
65
79
|
--xfc-font-sans: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui,
|
|
66
80
|
Roboto, 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif;
|
|
67
81
|
--xfc-font-mono: ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, monospace;
|
|
@@ -74,44 +88,44 @@
|
|
|
74
88
|
--xfc-text-input: 0.9375rem;
|
|
75
89
|
|
|
76
90
|
--xfc-leading-tight: 1.25;
|
|
77
|
-
--xfc-leading-normal: 1.
|
|
91
|
+
--xfc-leading-normal: 1.55;
|
|
78
92
|
--xfc-leading-label: 22px;
|
|
79
93
|
--xfc-leading-menu: 50px;
|
|
80
94
|
|
|
81
95
|
/* Focus */
|
|
82
|
-
--xfc-focus-ring: 0 0 0 3px color-mix(in srgb, var(--xfc-accent)
|
|
96
|
+
--xfc-focus-ring: 0 0 0 3px color-mix(in srgb, var(--xfc-accent) 32%, transparent);
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
/**
|
|
86
|
-
* Dark theme (opt-in): `<html class="dark">` or `data-theme="dark"
|
|
87
|
-
* 동일한 변수 이름만 덮어쓴다 — 앱은 토큰 참조를 바꿀 필요 없음.
|
|
100
|
+
* Dark theme (opt-in): `<html class="dark">` or `data-theme="dark"`.
|
|
88
101
|
*/
|
|
89
102
|
html.dark,
|
|
90
103
|
:root[data-theme='dark'],
|
|
91
104
|
html[data-theme='dark'] {
|
|
92
105
|
color-scheme: dark;
|
|
93
106
|
|
|
94
|
-
--xfc-bg: #
|
|
95
|
-
--xfc-bg-elevated: #
|
|
96
|
-
--xfc-bg-muted: #
|
|
97
|
-
--xfc-bg-disabled: #
|
|
107
|
+
--xfc-bg: #0c0f14;
|
|
108
|
+
--xfc-bg-elevated: #151b24;
|
|
109
|
+
--xfc-bg-muted: #1a222d;
|
|
110
|
+
--xfc-bg-disabled: #2d3a4a;
|
|
98
111
|
|
|
99
|
-
--xfc-fg: #
|
|
100
|
-
--xfc-fg-strong: #
|
|
101
|
-
--xfc-fg-label: #
|
|
102
|
-
--xfc-fg-muted: #
|
|
103
|
-
--xfc-fg-placeholder: #
|
|
112
|
+
--xfc-fg: #e2e8f0;
|
|
113
|
+
--xfc-fg-strong: #f8fafc;
|
|
114
|
+
--xfc-fg-label: #cbd5e1;
|
|
115
|
+
--xfc-fg-muted: #94a3b8;
|
|
116
|
+
--xfc-fg-placeholder: #64748b;
|
|
104
117
|
--xfc-fg-icon: #a8b8c8;
|
|
105
118
|
|
|
106
|
-
--xfc-border: #
|
|
107
|
-
--xfc-border-strong: #
|
|
108
|
-
--xfc-border-header: #
|
|
119
|
+
--xfc-border: #2d3a4a;
|
|
120
|
+
--xfc-border-strong: #3d4f66;
|
|
121
|
+
--xfc-border-header: #334155;
|
|
109
122
|
|
|
110
|
-
--xfc-accent: #
|
|
111
|
-
--xfc-accent-hover: #
|
|
112
|
-
--xfc-accent-fg: #
|
|
123
|
+
--xfc-accent: #818cf8;
|
|
124
|
+
--xfc-accent-hover: #a5b4fc;
|
|
125
|
+
--xfc-accent-fg: #0f172a;
|
|
126
|
+
--xfc-accent-soft: color-mix(in srgb, var(--xfc-accent) 18%, transparent);
|
|
113
127
|
|
|
114
|
-
--xfc-danger: #
|
|
128
|
+
--xfc-danger: #fb7185;
|
|
115
129
|
--xfc-success: #34d399;
|
|
116
130
|
--xfc-success-bg: #064e3b;
|
|
117
131
|
--xfc-warning: #fbbf24;
|
|
@@ -120,11 +134,17 @@ html[data-theme='dark'] {
|
|
|
120
134
|
--xfc-toast-info-bg: #1e293b;
|
|
121
135
|
--xfc-toast-success-bg: #047857;
|
|
122
136
|
--xfc-toast-warn-bg: #b45309;
|
|
123
|
-
--xfc-toast-error-bg: #
|
|
124
|
-
--xfc-toast-shadow: 0
|
|
137
|
+
--xfc-toast-error-bg: #be123c;
|
|
138
|
+
--xfc-toast-shadow: 0 12px 40px rgba(0, 0, 0, 0.45), 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
139
|
+
--xfc-toast-border: 1px solid rgba(255, 255, 255, 0.08);
|
|
140
|
+
|
|
141
|
+
--xfc-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35);
|
|
142
|
+
--xfc-shadow-sm: 0 4px 16px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
143
|
+
--xfc-shadow-md: 0 12px 32px rgba(0, 0, 0, 0.35), 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
144
|
+
--xfc-shadow-lg: 0 28px 56px rgba(0, 0, 0, 0.45), 0 12px 24px rgba(0, 0, 0, 0.25);
|
|
125
145
|
|
|
126
|
-
--xfc-input-shadow:
|
|
127
|
-
--xfc-card-shadow:
|
|
146
|
+
--xfc-input-shadow: var(--xfc-shadow-xs);
|
|
147
|
+
--xfc-card-shadow: var(--xfc-shadow-sm);
|
|
128
148
|
|
|
129
|
-
--xfc-focus-ring: 0 0 0 3px color-mix(in srgb, var(--xfc-accent)
|
|
149
|
+
--xfc-focus-ring: 0 0 0 3px color-mix(in srgb, var(--xfc-accent) 40%, transparent);
|
|
130
150
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Components reference
|
|
2
|
+
|
|
3
|
+
소스는 모두 `packages/front-core/src/` 기준. 빌드 산출물은 `dist/`에 동일 구조로 복사된다.
|
|
4
|
+
|
|
5
|
+
## 레이아웃·표면
|
|
6
|
+
|
|
7
|
+
| 컴포넌트 | 소스 | 요약 |
|
|
8
|
+
|----------|------|------|
|
|
9
|
+
| `Paper` | [atoms/Paper.tsx](../src/components/atoms/Paper.tsx) | `elevation` 0~4, `variant` filled \| outlined |
|
|
10
|
+
| `Card` | [atoms/Card.tsx](../src/components/atoms/Card.tsx) | `title`, `footer`, `interactive` |
|
|
11
|
+
| `Box` | [atoms/Box.tsx](../src/components/atoms/Box.tsx) | `as`, `padding` |
|
|
12
|
+
| `Stack` | [atoms/Stack.tsx](../src/components/atoms/Stack.tsx) | flex gap·align·justify |
|
|
13
|
+
|
|
14
|
+
### Paper
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { Paper, Stack, Text } from '@xfilecom/front-core';
|
|
18
|
+
|
|
19
|
+
<Paper elevation={2} style={{ padding: 'var(--xfc-space-lg)' }}>
|
|
20
|
+
<Text variant="body">Elevation 2 surface</Text>
|
|
21
|
+
</Paper>
|
|
22
|
+
|
|
23
|
+
<Paper variant="outlined" style={{ padding: 'var(--xfc-space-md)' }}>
|
|
24
|
+
Border only
|
|
25
|
+
</Paper>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Card
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { Card, Button } from '@xfilecom/front-core';
|
|
32
|
+
|
|
33
|
+
<Card
|
|
34
|
+
title="제목"
|
|
35
|
+
footer={<Button variant="primary">확인</Button>}
|
|
36
|
+
>
|
|
37
|
+
본문
|
|
38
|
+
</Card>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 타이포
|
|
42
|
+
|
|
43
|
+
| 컴포넌트 | 소스 |
|
|
44
|
+
|----------|------|
|
|
45
|
+
| `Text` | [atoms/Text.tsx](../src/components/atoms/Text.tsx) |
|
|
46
|
+
|
|
47
|
+
`variant`: `title` | `appbar` | `section` | `subtitle` | `lead` | `body` | `muted` | `small` | `label` | `labelBlock` | `accent`
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<Text variant="section">섹션 제목</Text>
|
|
51
|
+
<Text variant="lead">리드 문단</Text>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 액션
|
|
55
|
+
|
|
56
|
+
| 컴포넌트 | 소스 |
|
|
57
|
+
|----------|------|
|
|
58
|
+
| `Button` | [atoms/Button.tsx](../src/components/atoms/Button.tsx) |
|
|
59
|
+
| `Badge` | [atoms/Badge.tsx](../src/components/atoms/Badge.tsx) |
|
|
60
|
+
|
|
61
|
+
`Button` variants: `primary` | `secondary` | `outline` | `muted` | `ghost`
|
|
62
|
+
`Badge` tone: `neutral` | `accent` | `success` | `warn` | `danger`
|
|
63
|
+
|
|
64
|
+
## 폼
|
|
65
|
+
|
|
66
|
+
| 컴포넌트 | 소스 |
|
|
67
|
+
|----------|------|
|
|
68
|
+
| `Input` | [atoms/Input.tsx](../src/components/atoms/Input.tsx) |
|
|
69
|
+
| `Textarea` | [atoms/Textarea.tsx](../src/components/atoms/Textarea.tsx) |
|
|
70
|
+
| `Select` | [atoms/Select.tsx](../src/components/atoms/Select.tsx) |
|
|
71
|
+
| `Checkbox` | [atoms/Checkbox.tsx](../src/components/atoms/Checkbox.tsx) |
|
|
72
|
+
| `Field` | [atoms/Field.tsx](../src/components/atoms/Field.tsx) |
|
|
73
|
+
|
|
74
|
+
`Field`는 **단일** 자식에 `id` / `aria-describedby` / `aria-invalid`를 병합한다. `htmlFor`와 자식 `id`를 일치시킨다.
|
|
75
|
+
|
|
76
|
+
## 피드백
|
|
77
|
+
|
|
78
|
+
| 컴포넌트 | 소스 |
|
|
79
|
+
|----------|------|
|
|
80
|
+
| `Toast` / `ToastList` | [atoms/Toast.tsx](../src/components/atoms/Toast.tsx) |
|
|
81
|
+
| `ToastSeverityIcon` | 동일 파일 |
|
|
82
|
+
| `InlineErrorList` | [atoms/InlineErrorList.tsx](../src/components/atoms/InlineErrorList.tsx) |
|
|
83
|
+
| `LoadingOverlay` | [atoms/LoadingOverlay.tsx](../src/components/atoms/LoadingOverlay.tsx) |
|
|
84
|
+
|
|
85
|
+
`ToastList`의 `ToastEntry`에 `dismissible?: boolean`으로 행마다 닫기 버튼을 제어한다.
|
|
86
|
+
|
|
87
|
+
## 오버레이
|
|
88
|
+
|
|
89
|
+
| 컴포넌트 | 소스 |
|
|
90
|
+
|----------|------|
|
|
91
|
+
| `Dialog` | [overlays/Dialog.tsx](../src/components/overlays/Dialog.tsx) |
|
|
92
|
+
| `ConfirmDialog` | [overlays/ConfirmDialog.tsx](../src/components/overlays/ConfirmDialog.tsx) |
|
|
93
|
+
| `BottomSheet` | [overlays/BottomSheet.tsx](../src/components/overlays/BottomSheet.tsx) |
|
|
94
|
+
|
|
95
|
+
커스텀 모달에 동일한 스크롤 잠금·포커스 트랩을 쓰려면 [overlayHooks.ts](../src/components/overlays/overlayHooks.ts)의 `useFocusTrap`, `useBodyScrollLock`, `useEscapeKey`를 루트에서 import 한다.
|
|
96
|
+
|
|
97
|
+
## CSS
|
|
98
|
+
|
|
99
|
+
| 파일 | 용도 |
|
|
100
|
+
|------|------|
|
|
101
|
+
| [tokens.css](../src/tokens.css) | `:root` 변수, 다크 프리셋 |
|
|
102
|
+
| [base.css](../src/base.css) | `.xfc-*` atoms 스타일 |
|
|
103
|
+
|
|
104
|
+
## TypeScript
|
|
105
|
+
|
|
106
|
+
`tokenVars`로 CSS 변수 이름을 문자열 상수로 참조할 수 있다. ([index.ts](../src/index.ts))
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { tokenVars } from '@xfilecom/front-core';
|
|
110
|
+
document.body.style.setProperty(tokenVars.colorAccent, '#143c38');
|
|
111
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# xframe design system vs Paper-style UI kits
|
|
2
|
+
|
|
3
|
+
`@xfilecom/front-core`는 **브라우저 전용**이며 React Native(`react-native-paper`)나 MUI(`@mui/material`)와 동일한 패키지는 아니다. 대신 **같은 UX 패턴**(표면·높이·토큰)을 웹 CSS 변수 + 얇은 React atoms로 옮긴다.
|
|
4
|
+
|
|
5
|
+
## 한눈에 비교
|
|
6
|
+
|
|
7
|
+
| 개념 | MUI (`Paper`) | react-native-paper (`Surface`) | front-core |
|
|
8
|
+
|------|---------------|---------------------------------|------------|
|
|
9
|
+
| 표면/카드 | `Paper` + `elevation` | `Surface` + `elevation` | [`Paper`](../src/components/atoms/Paper.tsx) `elevation={0…4}` |
|
|
10
|
+
| 구조형 카드 | `Card` | `Card` | [`Card`](../src/components/atoms/Card.tsx) (title/footer 슬롯) |
|
|
11
|
+
| 버튼 | `Button` | `Button` | [`Button`](../src/components/atoms/Button.tsx) variants |
|
|
12
|
+
| 다이얼로그 | `Dialog` | `Portal`+`Dialog` | [`Dialog`](../src/components/overlays/Dialog.tsx) |
|
|
13
|
+
| 스낵바/토스트 | `Snackbar` | `Snackbar` | [`Toast`](../src/components/atoms/Toast.tsx) / [`ToastList`](../src/components/atoms/Toast.tsx) |
|
|
14
|
+
| 테마 | `ThemeProvider` | `PaperProvider` | `:root` / `html.dark` **CSS 변수** + 선택적 `xfc-theme.css` |
|
|
15
|
+
|
|
16
|
+
## Elevation (높이)
|
|
17
|
+
|
|
18
|
+
- **MUI**: 그림자 깊이가 elevation 숫자에 대응.
|
|
19
|
+
- **front-core**: `Paper`의 `elevation` 0~4가 `--xfc-shadow-xs` … `--xfc-shadow-lg`에 매핑된다. `variant="outlined"`는 그림자 없이 테두리만 (`outlined` variant).
|
|
20
|
+
|
|
21
|
+
## 색 (Color roles)
|
|
22
|
+
|
|
23
|
+
Material 3의 *primary / on-primary / surface* 같은 **역할 이름**은 npm 타입으로 강제하지 않고, `--xfc-accent`, `--xfc-bg-elevated`, `--xfc-fg` 등 **토큰 이름**으로 맞춘다. 다크 모드는 `html.dark` 또는 `data-theme="dark"` 한 번에 같은 변수를 덮어쓴다.
|
|
24
|
+
|
|
25
|
+
## 언제 MUI / RN Paper를 쓰고 언제 front-core를 쓰나
|
|
26
|
+
|
|
27
|
+
- **이미 MUI 생태계**를 쓰는 앱 → MUI 유지.
|
|
28
|
+
- **xframe 스캐폴드**, 번들·의존성을 가볍게, Nest와 무관한 **순수 웹 atoms** → `front-core`.
|
|
29
|
+
|
|
30
|
+
## 다음 문서
|
|
31
|
+
|
|
32
|
+
- [COMPONENTS.md](./COMPONENTS.md) — 컴포넌트별 props·소스 경로·예제 코드
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xfilecom/front-core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
4
4
|
"description": "Shared design tokens, base CSS, and atomic React components (browser-only; no Nest dependency)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
|
-
"dist"
|
|
24
|
+
"dist",
|
|
25
|
+
"docs",
|
|
26
|
+
"README.md"
|
|
25
27
|
],
|
|
26
28
|
"scripts": {
|
|
27
29
|
"prepublishOnly": "npm run build",
|