@xfilecom/front-core 0.2.27 → 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 +44 -15
- package/dist/base.css +39 -0
- package/dist/components/atoms/Paper.d.ts +16 -0
- package/dist/components/atoms/Paper.js +13 -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 +1 -1
- package/dist/index.js +2 -1
- package/dist/tokens.css +6 -0
- package/docs/COMPONENTS.md +111 -0
- package/docs/DESIGN_SYSTEM.md +32 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,33 +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
|
|
10
26
|
|
|
11
|
-
|
|
27
|
+
```tsx
|
|
28
|
+
import {
|
|
29
|
+
Paper,
|
|
30
|
+
Card,
|
|
31
|
+
Button,
|
|
32
|
+
Text,
|
|
33
|
+
Dialog,
|
|
34
|
+
} from '@xfilecom/front-core';
|
|
35
|
+
```
|
|
12
36
|
|
|
13
|
-
|
|
37
|
+
서브패스: `@xfilecom/front-core/atoms`, `@xfilecom/front-core/overlays`.
|
|
14
38
|
|
|
15
|
-
|
|
39
|
+
## Paper (표면)
|
|
16
40
|
|
|
17
|
-
|
|
41
|
+
MUI `Paper` / RN `Surface`에 대응하는 얇은 래퍼:
|
|
18
42
|
|
|
19
|
-
|
|
20
|
-
|
|
43
|
+
```tsx
|
|
44
|
+
<Paper elevation={2} style={{ padding: 'var(--xfc-space-lg)' }}>
|
|
45
|
+
…
|
|
46
|
+
</Paper>
|
|
47
|
+
<Paper variant="outlined" style={{ padding: 16 }}>…</Paper>
|
|
48
|
+
```
|
|
21
49
|
|
|
22
|
-
##
|
|
50
|
+
## 기본 문자열·a11y
|
|
23
51
|
|
|
24
|
-
-
|
|
25
|
-
-
|
|
52
|
+
- 기본 UI 문구는 **영어** (토스트 Dismiss, Confirm OK/Cancel). 한국어는 props로 덮어쓴다.
|
|
53
|
+
- Dialog / BottomSheet: 스크롤 잠금, Escape, 포커스 트랩 (`useFocusTrap`).
|
|
54
|
+
- Toast: `error` → `role="alert"`, 그 외 `role="status"`.
|
|
26
55
|
|
|
27
56
|
## Version
|
|
28
57
|
|
|
29
|
-
`
|
|
58
|
+
`npm run build` 시 `package.json`의 `version`이 `src/generatedVersion.ts`에 반영된다.
|
|
30
59
|
|
|
31
|
-
##
|
|
60
|
+
## 폼
|
|
32
61
|
|
|
33
|
-
`Input`, `Textarea`, `Select`, `Checkbox`, `Field` —
|
|
62
|
+
`Input`, `Textarea`, `Select`, `Checkbox`, `Field` — 자세한 예는 [COMPONENTS.md](./docs/COMPONENTS.md).
|
package/dist/base.css
CHANGED
|
@@ -234,6 +234,45 @@ a:hover {
|
|
|
234
234
|
padding-top: var(--xfc-space-md);
|
|
235
235
|
}
|
|
236
236
|
|
|
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
|
+
|
|
237
276
|
/* —— Buttons —— */
|
|
238
277
|
|
|
239
278
|
.xfc-btn {
|
|
@@ -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
|
+
}
|
|
@@ -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
|
@@ -51,6 +51,6 @@ export declare const tokenVars: {
|
|
|
51
51
|
readonly toastWarnBg: "--xfc-toast-warn-bg";
|
|
52
52
|
readonly toastErrorBg: "--xfc-toast-error-bg";
|
|
53
53
|
};
|
|
54
|
-
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';
|
|
55
55
|
/** 커스텀 오버레이용 — `Dialog`/`BottomSheet`와 동일한 훅 */
|
|
56
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
|
*
|
|
@@ -68,6 +68,7 @@ Object.defineProperty(exports, "Field", { enumerable: true, get: function () { r
|
|
|
68
68
|
Object.defineProperty(exports, "InlineErrorList", { enumerable: true, get: function () { return components_1.InlineErrorList; } });
|
|
69
69
|
Object.defineProperty(exports, "Input", { enumerable: true, get: function () { return components_1.Input; } });
|
|
70
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; } });
|
|
71
72
|
Object.defineProperty(exports, "Select", { enumerable: true, get: function () { return components_1.Select; } });
|
|
72
73
|
Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return components_1.Stack; } });
|
|
73
74
|
Object.defineProperty(exports, "Text", { enumerable: true, get: function () { return components_1.Text; } });
|
package/dist/tokens.css
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Design tokens — 기본 테마 (라이트).
|
|
3
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 */
|
|
@@ -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",
|