@xfilecom/front-core 0.2.29 → 0.2.31

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.
Files changed (39) hide show
  1. package/README.md +9 -0
  2. package/dist/generatedVersion.d.ts +1 -1
  3. package/dist/generatedVersion.js +1 -1
  4. package/dist/showcase/DesignSystemShowcase.d.ts +2 -0
  5. package/dist/showcase/DesignSystemShowcase.js +19 -0
  6. package/dist/showcase/ShowcaseContext.d.ts +48 -0
  7. package/dist/showcase/ShowcaseContext.js +117 -0
  8. package/dist/showcase/components/CodeBlock.d.ts +7 -0
  9. package/dist/showcase/components/CodeBlock.js +11 -0
  10. package/dist/showcase/components/SectionTitle.d.ts +4 -0
  11. package/dist/showcase/components/SectionTitle.js +8 -0
  12. package/dist/showcase/components/ShowcaseChrome.d.ts +2 -0
  13. package/dist/showcase/components/ShowcaseChrome.js +25 -0
  14. package/dist/showcase/components/ShowcaseDemo.d.ts +10 -0
  15. package/dist/showcase/components/ShowcaseDemo.js +9 -0
  16. package/dist/showcase/components/icons.d.ts +2 -0
  17. package/dist/showcase/components/icons.js +11 -0
  18. package/dist/showcase/index.d.ts +4 -0
  19. package/dist/showcase/index.js +10 -0
  20. package/dist/showcase/nav.d.ts +26 -0
  21. package/dist/showcase/nav.js +13 -0
  22. package/dist/showcase/sections/ActionsSection.d.ts +1 -0
  23. package/dist/showcase/sections/ActionsSection.js +24 -0
  24. package/dist/showcase/sections/FeedbackSection.d.ts +1 -0
  25. package/dist/showcase/sections/FeedbackSection.js +17 -0
  26. package/dist/showcase/sections/FormsSection.d.ts +1 -0
  27. package/dist/showcase/sections/FormsSection.js +20 -0
  28. package/dist/showcase/sections/LayoutSection.d.ts +1 -0
  29. package/dist/showcase/sections/LayoutSection.js +19 -0
  30. package/dist/showcase/sections/OverlaysSection.d.ts +1 -0
  31. package/dist/showcase/sections/OverlaysSection.js +25 -0
  32. package/dist/showcase/sections/OverviewSection.d.ts +1 -0
  33. package/dist/showcase/sections/OverviewSection.js +17 -0
  34. package/dist/showcase/sections/SurfacesSection.d.ts +1 -0
  35. package/dist/showcase/sections/SurfacesSection.js +38 -0
  36. package/dist/showcase/sections/TypographySection.d.ts +1 -0
  37. package/dist/showcase/sections/TypographySection.js +24 -0
  38. package/dist/showcase.css +235 -0
  39. package/package.json +8 -3
package/README.md CHANGED
@@ -37,6 +37,15 @@ import {
37
37
 
38
38
  서브패스: `@xfilecom/front-core/atoms`, `@xfilecom/front-core/overlays`.
39
39
 
40
+ ## Showcase (라이브 갤러리)
41
+
42
+ `tokens.css`·`base.css`(·앱 테마) 다음에 스타일을 한 줄 더 넣고, 컴포넌트를 import 합니다.
43
+
44
+ ```tsx
45
+ import '@xfilecom/front-core/showcase.css';
46
+ import { DesignSystemShowcase } from '@xfilecom/front-core/showcase';
47
+ ```
48
+
40
49
  ## Paper (표면)
41
50
 
42
51
  MUI `Paper` / RN `Surface`에 대응하는 얇은 래퍼:
@@ -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.29";
2
+ export declare const XFRAME_FRONT_CORE_VERSION: "0.2.31";
@@ -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.29";
5
+ exports.XFRAME_FRONT_CORE_VERSION = "0.2.31";
@@ -0,0 +1,2 @@
1
+ /** front-core 문서형 갤러리 — 사이드 네비 + 섹션 + 라이브 데모 */
2
+ export declare function DesignSystemShowcase(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DesignSystemShowcase = DesignSystemShowcase;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const ShowcaseChrome_1 = require("./components/ShowcaseChrome");
6
+ const ShowcaseContext_1 = require("./ShowcaseContext");
7
+ const nav_1 = require("./nav");
8
+ const ActionsSection_1 = require("./sections/ActionsSection");
9
+ const FeedbackSection_1 = require("./sections/FeedbackSection");
10
+ const FormsSection_1 = require("./sections/FormsSection");
11
+ const LayoutSection_1 = require("./sections/LayoutSection");
12
+ const OverlaysSection_1 = require("./sections/OverlaysSection");
13
+ const OverviewSection_1 = require("./sections/OverviewSection");
14
+ const SurfacesSection_1 = require("./sections/SurfacesSection");
15
+ const TypographySection_1 = require("./sections/TypographySection");
16
+ /** front-core 문서형 갤러리 — 사이드 네비 + 섹션 + 라이브 데모 */
17
+ function DesignSystemShowcase() {
18
+ return ((0, jsx_runtime_1.jsxs)(ShowcaseContext_1.ShowcaseProvider, { children: [(0, jsx_runtime_1.jsx)(ShowcaseChrome_1.ShowcaseChrome, {}), (0, jsx_runtime_1.jsxs)("div", { className: "xfc-ds", children: [(0, jsx_runtime_1.jsxs)("nav", { className: "xfc-ds-nav", "aria-label": "\uB514\uC790\uC778 \uC2DC\uC2A4\uD15C \uC139\uC158", children: [(0, jsx_runtime_1.jsx)("p", { className: "xfc-ds-nav-title", children: "\uC139\uC158" }), (0, jsx_runtime_1.jsx)("ul", { className: "xfc-ds-nav-list", children: nav_1.SHOWCASE_NAV.map((item) => ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)("a", { className: "xfc-ds-nav-link", href: `#${item.id}`, children: item.label }) }, item.id))) })] }), (0, jsx_runtime_1.jsxs)("main", { className: "xfc-ds-main", children: [(0, jsx_runtime_1.jsx)(OverviewSection_1.OverviewSection, {}), (0, jsx_runtime_1.jsx)(SurfacesSection_1.SurfacesSection, {}), (0, jsx_runtime_1.jsx)(TypographySection_1.TypographySection, {}), (0, jsx_runtime_1.jsx)(ActionsSection_1.ActionsSection, {}), (0, jsx_runtime_1.jsx)(FormsSection_1.FormsSection, {}), (0, jsx_runtime_1.jsx)(LayoutSection_1.LayoutSection, {}), (0, jsx_runtime_1.jsx)(FeedbackSection_1.FeedbackSection, {}), (0, jsx_runtime_1.jsx)(OverlaysSection_1.OverlaysSection, {})] })] })] }));
19
+ }
@@ -0,0 +1,48 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { InlineErrorEntry } from '../components/atoms/InlineErrorList';
3
+ import { type ToastEntry, type ToastSeverity } from '../components/atoms/Toast';
4
+ export type ShowcaseContextValue = {
5
+ uid: string;
6
+ toasts: ToastEntry[];
7
+ errors: InlineErrorEntry[];
8
+ loading: boolean;
9
+ badgeClicks: number;
10
+ interactiveCardClicks: number;
11
+ btnLoading: boolean;
12
+ dialogOpen: boolean;
13
+ dialogRichOpen: boolean;
14
+ confirmOpen: boolean;
15
+ confirmDestructiveOpen: boolean;
16
+ confirmLoadingDemo: boolean;
17
+ confirmCustomOpen: boolean;
18
+ sheetOpen: boolean;
19
+ sheetRichOpen: boolean;
20
+ fieldBio: string;
21
+ fieldPlan: string;
22
+ fieldAgree: boolean;
23
+ setToasts: React.Dispatch<React.SetStateAction<ToastEntry[]>>;
24
+ setErrors: React.Dispatch<React.SetStateAction<InlineErrorEntry[]>>;
25
+ setLoading: React.Dispatch<React.SetStateAction<boolean>>;
26
+ setBadgeClicks: React.Dispatch<React.SetStateAction<number>>;
27
+ setInteractiveCardClicks: React.Dispatch<React.SetStateAction<number>>;
28
+ setBtnLoading: React.Dispatch<React.SetStateAction<boolean>>;
29
+ setDialogOpen: React.Dispatch<React.SetStateAction<boolean>>;
30
+ setDialogRichOpen: React.Dispatch<React.SetStateAction<boolean>>;
31
+ setConfirmOpen: React.Dispatch<React.SetStateAction<boolean>>;
32
+ setConfirmDestructiveOpen: React.Dispatch<React.SetStateAction<boolean>>;
33
+ setConfirmLoadingDemo: React.Dispatch<React.SetStateAction<boolean>>;
34
+ setConfirmCustomOpen: React.Dispatch<React.SetStateAction<boolean>>;
35
+ setSheetOpen: React.Dispatch<React.SetStateAction<boolean>>;
36
+ setSheetRichOpen: React.Dispatch<React.SetStateAction<boolean>>;
37
+ setFieldBio: React.Dispatch<React.SetStateAction<string>>;
38
+ setFieldPlan: React.Dispatch<React.SetStateAction<string>>;
39
+ setFieldAgree: React.Dispatch<React.SetStateAction<boolean>>;
40
+ pushToast: (severity: ToastSeverity) => void;
41
+ pushToastCustomIcon: () => void;
42
+ addError: () => void;
43
+ addErrorRich: () => void;
44
+ };
45
+ export declare function ShowcaseProvider({ children }: {
46
+ children: ReactNode;
47
+ }): import("react/jsx-runtime").JSX.Element;
48
+ export declare function useShowcase(): ShowcaseContextValue;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ShowcaseProvider = ShowcaseProvider;
4
+ exports.useShowcase = useShowcase;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const Toast_1 = require("../components/atoms/Toast");
8
+ const icons_1 = require("./components/icons");
9
+ const ShowcaseContext = (0, react_1.createContext)(null);
10
+ function ShowcaseProvider({ children }) {
11
+ const uid = (0, react_1.useId)();
12
+ const toastSeq = (0, react_1.useRef)(0);
13
+ const errorSeq = (0, react_1.useRef)(0);
14
+ const [toasts, setToasts] = (0, react_1.useState)([]);
15
+ const [errors, setErrors] = (0, react_1.useState)([]);
16
+ const [loading, setLoading] = (0, react_1.useState)(false);
17
+ const [badgeClicks, setBadgeClicks] = (0, react_1.useState)(0);
18
+ const [interactiveCardClicks, setInteractiveCardClicks] = (0, react_1.useState)(0);
19
+ const [btnLoading, setBtnLoading] = (0, react_1.useState)(false);
20
+ const [dialogOpen, setDialogOpen] = (0, react_1.useState)(false);
21
+ const [dialogRichOpen, setDialogRichOpen] = (0, react_1.useState)(false);
22
+ const [confirmOpen, setConfirmOpen] = (0, react_1.useState)(false);
23
+ const [confirmDestructiveOpen, setConfirmDestructiveOpen] = (0, react_1.useState)(false);
24
+ const [confirmLoadingDemo, setConfirmLoadingDemo] = (0, react_1.useState)(false);
25
+ const [confirmCustomOpen, setConfirmCustomOpen] = (0, react_1.useState)(false);
26
+ const [sheetOpen, setSheetOpen] = (0, react_1.useState)(false);
27
+ const [sheetRichOpen, setSheetRichOpen] = (0, react_1.useState)(false);
28
+ const [fieldBio, setFieldBio] = (0, react_1.useState)('');
29
+ const [fieldPlan, setFieldPlan] = (0, react_1.useState)('a');
30
+ const [fieldAgree, setFieldAgree] = (0, react_1.useState)(false);
31
+ const pushToast = (0, react_1.useCallback)((severity) => {
32
+ toastSeq.current += 1;
33
+ const id = `${uid}-t-${toastSeq.current}`;
34
+ setToasts((prev) => [...prev, { id, severity, message: `${severity} 메시지 예시` }]);
35
+ }, [uid]);
36
+ const pushToastCustomIcon = (0, react_1.useCallback)(() => {
37
+ toastSeq.current += 1;
38
+ const id = `${uid}-t-${toastSeq.current}`;
39
+ setToasts((prev) => [
40
+ ...prev,
41
+ {
42
+ id,
43
+ severity: 'success',
44
+ message: 'ToastEntry.icon 으로 별 아이콘',
45
+ icon: (0, jsx_runtime_1.jsx)(icons_1.StarIcon, {}),
46
+ },
47
+ ]);
48
+ }, [uid]);
49
+ const addError = (0, react_1.useCallback)(() => {
50
+ errorSeq.current += 1;
51
+ const id = `${uid}-e-${errorSeq.current}`;
52
+ setErrors((prev) => [...prev, { id, message: `샘플 에러 #${errorSeq.current}` }]);
53
+ }, [uid]);
54
+ const addErrorRich = (0, react_1.useCallback)(() => {
55
+ errorSeq.current += 1;
56
+ const id = `${uid}-e-${errorSeq.current}`;
57
+ setErrors((prev) => [
58
+ ...prev,
59
+ {
60
+ id,
61
+ message: '아이콘 + 행 클릭(콘솔)',
62
+ icon: (0, jsx_runtime_1.jsx)(Toast_1.ToastSeverityIcon, { severity: "error" }),
63
+ onClick: () => {
64
+ console.info('[showcase] inline error row click', id);
65
+ },
66
+ },
67
+ ]);
68
+ }, [uid]);
69
+ const value = {
70
+ uid,
71
+ toasts,
72
+ errors,
73
+ loading,
74
+ badgeClicks,
75
+ interactiveCardClicks,
76
+ btnLoading,
77
+ dialogOpen,
78
+ dialogRichOpen,
79
+ confirmOpen,
80
+ confirmDestructiveOpen,
81
+ confirmLoadingDemo,
82
+ confirmCustomOpen,
83
+ sheetOpen,
84
+ sheetRichOpen,
85
+ fieldBio,
86
+ fieldPlan,
87
+ fieldAgree,
88
+ setToasts,
89
+ setErrors,
90
+ setLoading,
91
+ setBadgeClicks,
92
+ setInteractiveCardClicks,
93
+ setBtnLoading,
94
+ setDialogOpen,
95
+ setDialogRichOpen,
96
+ setConfirmOpen,
97
+ setConfirmDestructiveOpen,
98
+ setConfirmLoadingDemo,
99
+ setConfirmCustomOpen,
100
+ setSheetOpen,
101
+ setSheetRichOpen,
102
+ setFieldBio,
103
+ setFieldPlan,
104
+ setFieldAgree,
105
+ pushToast,
106
+ pushToastCustomIcon,
107
+ addError,
108
+ addErrorRich,
109
+ };
110
+ return (0, jsx_runtime_1.jsx)(ShowcaseContext.Provider, { value: value, children: children });
111
+ }
112
+ function useShowcase() {
113
+ const v = (0, react_1.useContext)(ShowcaseContext);
114
+ if (!v)
115
+ throw new Error('ShowcaseProvider required');
116
+ return v;
117
+ }
@@ -0,0 +1,7 @@
1
+ /** 코드 스니펫 + 캡션 (문서형 갤러리) */
2
+ export declare function CodeBlock({ caption, code, className, variant, }: {
3
+ caption?: string;
4
+ code: string;
5
+ className?: string;
6
+ variant?: 'default' | 'embedded';
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CodeBlock = CodeBlock;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ /** 코드 스니펫 + 캡션 (문서형 갤러리) */
6
+ function CodeBlock({ caption, code, className = '', variant = 'default', }) {
7
+ const rootClass = ['xfc-ds-code-wrap', variant === 'embedded' ? 'xfc-ds-code-wrap--embedded' : '', className]
8
+ .filter(Boolean)
9
+ .join(' ');
10
+ return ((0, jsx_runtime_1.jsxs)("div", { className: rootClass, children: [caption ? (0, jsx_runtime_1.jsx)("p", { className: "xfc-ds-code-caption", children: caption }) : null, (0, jsx_runtime_1.jsx)("pre", { className: "xfc-ds-code", children: code.trim() })] }));
11
+ }
@@ -0,0 +1,4 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare function SectionTitle({ children }: {
3
+ children: ReactNode;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SectionTitle = SectionTitle;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const Text_1 = require("../../components/atoms/Text");
6
+ function SectionTitle({ children }) {
7
+ return ((0, jsx_runtime_1.jsx)("div", { className: "xfc-ds-section-head", children: (0, jsx_runtime_1.jsx)(Text_1.Text, { as: "h2", variant: "section", style: { margin: 0 }, children: children }) }));
8
+ }
@@ -0,0 +1,2 @@
1
+ /** 전역 오버레이·다이얼로그 (포털) */
2
+ export declare function ShowcaseChrome(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ShowcaseChrome = ShowcaseChrome;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const Button_1 = require("../../components/atoms/Button");
6
+ const InlineErrorList_1 = require("../../components/atoms/InlineErrorList");
7
+ const LoadingOverlay_1 = require("../../components/atoms/LoadingOverlay");
8
+ const Text_1 = require("../../components/atoms/Text");
9
+ const Toast_1 = require("../../components/atoms/Toast");
10
+ const BottomSheet_1 = require("../../components/overlays/BottomSheet");
11
+ const ConfirmDialog_1 = require("../../components/overlays/ConfirmDialog");
12
+ const Dialog_1 = require("../../components/overlays/Dialog");
13
+ const ShowcaseContext_1 = require("../ShowcaseContext");
14
+ const icons_1 = require("./icons");
15
+ /** 전역 오버레이·다이얼로그 (포털) */
16
+ function ShowcaseChrome() {
17
+ const s = (0, ShowcaseContext_1.useShowcase)();
18
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(InlineErrorList_1.InlineErrorList, { errors: s.errors, onDismiss: (id) => s.setErrors((e) => e.filter((x) => x.id !== id)), dismissAriaLabel: "\uBC30\uB108 \uB2EB\uAE30" }), (0, jsx_runtime_1.jsx)(Toast_1.ToastList, { toasts: s.toasts, onDismiss: (id) => s.setToasts((t) => t.filter((x) => x.id !== id)) }), (0, jsx_runtime_1.jsx)(LoadingOverlay_1.LoadingOverlay, { active: s.loading, title: "\uCC98\uB9AC \uC911", message: "\uB370\uC774\uD130\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4\u2026", ariaLabel: "\uB370\uC774\uD130 \uB85C\uB529 \uC911" }), (0, jsx_runtime_1.jsxs)(Dialog_1.Dialog, { open: s.dialogOpen, onOpenChange: s.setDialogOpen, title: "Dialog", description: "title / description / children \uC870\uD569. \uBC30\uACBD \uD074\uB9AD\u00B7Escape \uB85C \uB2EB\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { variant: "body", children: "children \uC5D0 \uD3FC\u00B7\uB9AC\uC2A4\uD2B8 \uB4F1 \uC790\uC720\uB86D\uAC8C \uB123\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4." }), (0, jsx_runtime_1.jsxs)("div", { className: "xfc-dialog-footer", children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "muted", onClick: () => s.setDialogOpen(false), children: "\uCDE8\uC18C" }), (0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "primary", onClick: () => s.setDialogOpen(false), children: "\uD655\uC778" })] })] }), (0, jsx_runtime_1.jsxs)(Dialog_1.Dialog, { open: s.dialogRichOpen, onOpenChange: s.setDialogRichOpen, title: "\uD5E4\uB354 \uCEE4\uC2A4\uD140", titleAdornment: (0, jsx_runtime_1.jsx)(Toast_1.ToastSeverityIcon, { severity: "info" }), headerExtra: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "ghost", type: "button", onClick: () => s.setDialogRichOpen(false), "aria-label": "\uB2EB\uAE30", children: "\u2715" }), description: "titleAdornment \u00B7 headerExtra \u2014 Dialog props \uB85C \uC870\uD569", children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { variant: "body", children: "bodyClassName \u00B7 descriptionClassName \uC73C\uB85C \uD328\uB110 \uC601\uC5ED \uD074\uB798\uC2A4\uB3C4 \uC870\uC815 \uAC00\uB2A5\uD569\uB2C8\uB2E4." }), (0, jsx_runtime_1.jsx)("div", { className: "xfc-dialog-footer", children: (0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "primary", onClick: () => s.setDialogRichOpen(false), children: "OK" }) })] }), (0, jsx_runtime_1.jsx)(ConfirmDialog_1.ConfirmDialog, { open: s.confirmOpen, onOpenChange: s.setConfirmOpen, title: "ConfirmDialog", message: "Default labels: OK / Cancel. Cancel runs onCancel then closes.", onConfirm: () => s.setConfirmOpen(false) }), (0, jsx_runtime_1.jsx)(ConfirmDialog_1.ConfirmDialog, { open: s.confirmDestructiveOpen, onOpenChange: s.setConfirmDestructiveOpen, title: "\uC704\uD5D8 \uC791\uC5C5", message: "destructive + \uBE68\uAC04 \uD655\uC778 \uBC84\uD2BC \uC608\uC2DC\uC785\uB2C8\uB2E4.", destructive: true, confirmLabel: "\uC0AD\uC81C", onConfirm: () => s.setConfirmDestructiveOpen(false) }), (0, jsx_runtime_1.jsx)(ConfirmDialog_1.ConfirmDialog, { open: s.confirmLoadingDemo, onOpenChange: s.setConfirmLoadingDemo, title: "\uB85C\uB529 \uC911 \uD655\uC778", message: "confirmLoading \uC2DC \uBC84\uD2BC\uC774 \uC7A0\uAE41\uB2C8\uB2E4.", confirmLoading: true, onConfirm: () => { } }), (0, jsx_runtime_1.jsx)(ConfirmDialog_1.ConfirmDialog, { open: s.confirmCustomOpen, onOpenChange: s.setConfirmCustomOpen, title: "\uBC84\uD2BC props \uD655\uC7A5", message: "confirmButtonProps / cancelButtonProps \uB85C icon\u00B7className \uB4F1 \uC804\uB2EC", confirmLabel: "\uC800\uC7A5", cancelLabel: "\uB2EB\uAE30", onConfirm: () => s.setConfirmCustomOpen(false), confirmButtonProps: {
19
+ icon: (0, jsx_runtime_1.jsx)(icons_1.CheckIcon, {}),
20
+ iconPosition: 'start',
21
+ }, cancelButtonProps: {
22
+ icon: (0, jsx_runtime_1.jsx)("span", { "aria-hidden": true, children: "\u2190" }),
23
+ iconPosition: 'start',
24
+ } }), (0, jsx_runtime_1.jsxs)(BottomSheet_1.BottomSheet, { open: s.sheetOpen, onOpenChange: s.setSheetOpen, title: "BottomSheet", showHandle: true, children: [(0, jsx_runtime_1.jsx)(Text_1.Text, { variant: "body", children: "\uD654\uBA74 \uD558\uB2E8\uC5D0\uC11C \uC62C\uB77C\uC624\uB294 \uD328\uB110\uC785\uB2C8\uB2E4." }), (0, jsx_runtime_1.jsx)("div", { style: { marginTop: 'var(--xfc-space-md)' }, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "primary", onClick: () => s.setSheetOpen(false), children: "\uB2EB\uAE30" }) })] }), (0, jsx_runtime_1.jsx)(BottomSheet_1.BottomSheet, { open: s.sheetRichOpen, onOpenChange: s.setSheetRichOpen, title: "\uC561\uC158 \uC2DC\uD2B8", subtitle: "subtitle \u00B7 headerExtra \uB85C \uC0C1\uB2E8 \uAD6C\uC131", headerExtra: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "ghost", type: "button", onClick: () => s.setSheetRichOpen(false), "aria-label": "\uB2EB\uAE30", children: "\uC644\uB8CC" }), showHandle: true, children: (0, jsx_runtime_1.jsx)(Text_1.Text, { variant: "body", children: "BottomSheet bodyClassName \uB4F1\uC73C\uB85C \uBCF8\uBB38 \uC601\uC5ED\uB3C4 \uC870\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4." }) })] }));
25
+ }
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from 'react';
2
+ export type ShowcaseDemoProps = {
3
+ title: string;
4
+ description?: ReactNode;
5
+ code: string;
6
+ codeCaption?: string;
7
+ children: ReactNode;
8
+ };
9
+ /** 데모 프리뷰 + 접이식 코드 보기 */
10
+ export declare function ShowcaseDemo({ title, description, code, codeCaption, children }: ShowcaseDemoProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ShowcaseDemo = ShowcaseDemo;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const CodeBlock_1 = require("./CodeBlock");
6
+ /** 데모 프리뷰 + 접이식 코드 보기 */
7
+ function ShowcaseDemo({ title, description, code, codeCaption, children }) {
8
+ return ((0, jsx_runtime_1.jsxs)("article", { className: "xfc-ds-demo", children: [(0, jsx_runtime_1.jsx)("header", { className: "xfc-ds-demo__header", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "xfc-ds-demo__title", children: title }), description ? (0, jsx_runtime_1.jsx)("div", { className: "xfc-ds-demo__desc", children: description }) : null] }) }), (0, jsx_runtime_1.jsx)("div", { className: "xfc-ds-demo__preview", children: children }), (0, jsx_runtime_1.jsxs)("details", { className: "xfc-ds-demo__details", children: [(0, jsx_runtime_1.jsx)("summary", { className: "xfc-ds-demo__summary", children: "\uCF54\uB4DC \uBCF4\uAE30" }), (0, jsx_runtime_1.jsx)("div", { className: "xfc-ds-demo__code", children: (0, jsx_runtime_1.jsx)(CodeBlock_1.CodeBlock, { caption: codeCaption, code: code, variant: "embedded" }) })] })] }));
9
+ }
@@ -0,0 +1,2 @@
1
+ export declare function StarIcon(): import("react/jsx-runtime").JSX.Element;
2
+ export declare function CheckIcon(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StarIcon = StarIcon;
4
+ exports.CheckIcon = CheckIcon;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ function StarIcon() {
7
+ return ((0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": true, style: { display: 'block' }, children: (0, jsx_runtime_1.jsx)("path", { fill: "currentColor", d: "m8 1.3 1.9 4.2 4.6.4-3.5 3.1 1 4.5L8 11.5l-4 2 1-4.5-3.5-3.1 4.6-.4L8 1.3z" }) }));
8
+ }
9
+ function CheckIcon() {
10
+ return ((0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", "aria-hidden": true, style: { display: 'block' }, children: (0, jsx_runtime_1.jsx)("path", { fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", d: "M3.5 8.5l3 3 6-7" }) }));
11
+ }
@@ -0,0 +1,4 @@
1
+ export { DesignSystemShowcase } from './DesignSystemShowcase';
2
+ export { ShowcaseProvider, useShowcase } from './ShowcaseContext';
3
+ export type { ShowcaseContextValue } from './ShowcaseContext';
4
+ export { SHOWCASE_NAV, type ShowcaseNavId } from './nav';
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SHOWCASE_NAV = exports.useShowcase = exports.ShowcaseProvider = exports.DesignSystemShowcase = void 0;
4
+ var DesignSystemShowcase_1 = require("./DesignSystemShowcase");
5
+ Object.defineProperty(exports, "DesignSystemShowcase", { enumerable: true, get: function () { return DesignSystemShowcase_1.DesignSystemShowcase; } });
6
+ var ShowcaseContext_1 = require("./ShowcaseContext");
7
+ Object.defineProperty(exports, "ShowcaseProvider", { enumerable: true, get: function () { return ShowcaseContext_1.ShowcaseProvider; } });
8
+ Object.defineProperty(exports, "useShowcase", { enumerable: true, get: function () { return ShowcaseContext_1.useShowcase; } });
9
+ var nav_1 = require("./nav");
10
+ Object.defineProperty(exports, "SHOWCASE_NAV", { enumerable: true, get: function () { return nav_1.SHOWCASE_NAV; } });
@@ -0,0 +1,26 @@
1
+ export declare const SHOWCASE_NAV: readonly [{
2
+ readonly id: "overview";
3
+ readonly label: "개요 · 문서";
4
+ }, {
5
+ readonly id: "surfaces";
6
+ readonly label: "Paper · Card";
7
+ }, {
8
+ readonly id: "typography";
9
+ readonly label: "Typography";
10
+ }, {
11
+ readonly id: "actions";
12
+ readonly label: "Button · Badge";
13
+ }, {
14
+ readonly id: "forms";
15
+ readonly label: "Forms";
16
+ }, {
17
+ readonly id: "layout";
18
+ readonly label: "Box · Stack";
19
+ }, {
20
+ readonly id: "feedback";
21
+ readonly label: "Toast · Errors";
22
+ }, {
23
+ readonly id: "overlays";
24
+ readonly label: "Dialogs";
25
+ }];
26
+ export type ShowcaseNavId = (typeof SHOWCASE_NAV)[number]['id'];
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SHOWCASE_NAV = void 0;
4
+ exports.SHOWCASE_NAV = [
5
+ { id: 'overview', label: '개요 · 문서' },
6
+ { id: 'surfaces', label: 'Paper · Card' },
7
+ { id: 'typography', label: 'Typography' },
8
+ { id: 'actions', label: 'Button · Badge' },
9
+ { id: 'forms', label: 'Forms' },
10
+ { id: 'layout', label: 'Box · Stack' },
11
+ { id: 'feedback', label: 'Toast · Errors' },
12
+ { id: 'overlays', label: 'Dialogs' },
13
+ ];
@@ -0,0 +1 @@
1
+ export declare function ActionsSection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionsSection = ActionsSection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const icons_1 = require("../components/icons");
7
+ const SectionTitle_1 = require("../components/SectionTitle");
8
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
9
+ const ShowcaseContext_1 = require("../ShowcaseContext");
10
+ function ActionsSection() {
11
+ const s = (0, ShowcaseContext_1.useShowcase)();
12
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "actions", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "Button \u00B7 Badge" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: [(0, jsx_runtime_1.jsx)("code", { children: "Badge" }), " \uD1A4\u00B7\uC544\uC774\uCF58\u00B7\uD074\uB9AD(\uBC84\uD2BC \uB80C\uB354), ", (0, jsx_runtime_1.jsx)("code", { children: "Button" }), " variant\u00B7\uB85C\uB529\u00B7\uC544\uC774\uCF58 \uC2AC\uB86F."] }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Badge \u2014 tone & state", description: "neutral \u00B7 accent \u00B7 success \u00B7 warn \u00B7 danger, icon, enabled=false", code: `<Badge tone="accent">accent</Badge>
13
+ <Badge tone="success" icon={<StarIcon />}>icon</Badge>
14
+ <Badge tone="neutral" enabled={false}>disabled look</Badge>
15
+ <Badge tone="accent" onClick={…}>button</Badge>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Badge, { tone: "neutral", children: "neutral" }), (0, jsx_runtime_1.jsx)(atoms_1.Badge, { tone: "accent", children: "accent" }), (0, jsx_runtime_1.jsx)(atoms_1.Badge, { tone: "success", children: "success" }), (0, jsx_runtime_1.jsx)(atoms_1.Badge, { tone: "warn", children: "warn" }), (0, jsx_runtime_1.jsx)(atoms_1.Badge, { tone: "danger", children: "danger" }), (0, jsx_runtime_1.jsx)(atoms_1.Badge, { tone: "accent", icon: (0, jsx_runtime_1.jsx)(icons_1.StarIcon, {}), children: "icon" }), (0, jsx_runtime_1.jsx)(atoms_1.Badge, { tone: "neutral", enabled: false, children: "enabled=false" }), (0, jsx_runtime_1.jsxs)(atoms_1.Badge, { tone: "accent", icon: (0, jsx_runtime_1.jsx)(icons_1.CheckIcon, {}), onClick: () => s.setBadgeClicks((c) => c + 1), children: ["\uD074\uB9AD ", s.badgeClicks] })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Button \u2014 variants", description: "primary, secondary, outline, muted, ghost, disabled", code: `<Button variant="primary">primary</Button>
16
+ <Button variant="outline">outline</Button>
17
+ <Button variant="primary" disabled>disabled</Button>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "primary", children: "primary" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "secondary", children: "secondary" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "outline", children: "outline" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "muted", children: "muted" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "ghost", children: "ghost" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "primary", disabled: true, children: "disabled" })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Button \u2014 icon & loading", description: "iconPosition, loading + aria-busy, enabled=false", code: `<Button variant="primary" icon={<Star />} iconPosition="start">앞</Button>
18
+ <Button variant="outline" icon={<Check />} iconPosition="end">뒤</Button>
19
+ <Button variant="secondary" loading={busy} onClick={…}>제출</Button>
20
+ <Button variant="primary" enabled={false}>enabled=false</Button>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "primary", icon: (0, jsx_runtime_1.jsx)(icons_1.StarIcon, {}), iconPosition: "start", children: "\uC544\uC774\uCF58 \uC55E" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "outline", icon: (0, jsx_runtime_1.jsx)(icons_1.CheckIcon, {}), iconPosition: "end", children: "\uC544\uC774\uCF58 \uB4A4" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "secondary", loading: s.btnLoading, onClick: () => {
21
+ s.setBtnLoading(true);
22
+ window.setTimeout(() => s.setBtnLoading(false), 1200);
23
+ }, children: "loading \uB370\uBAA8" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "primary", enabled: false, children: "enabled=false" })] }) })] }));
24
+ }
@@ -0,0 +1 @@
1
+ export declare function FeedbackSection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FeedbackSection = FeedbackSection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const SectionTitle_1 = require("../components/SectionTitle");
7
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
8
+ const ShowcaseContext_1 = require("../ShowcaseContext");
9
+ function FeedbackSection() {
10
+ const s = (0, ShowcaseContext_1.useShowcase)();
11
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "feedback", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "Toast \u00B7 Inline errors \u00B7 Loading" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: [(0, jsx_runtime_1.jsx)("code", { children: "ToastList" }), " / ", (0, jsx_runtime_1.jsx)("code", { children: "InlineErrorList" }), " / ", (0, jsx_runtime_1.jsx)("code", { children: "LoadingOverlay" }), " \uB294 \uD3EC\uD138 \uACE0\uC815 \uB808\uC774\uC5B4\uC785\uB2C8\uB2E4. \uC544\uB798\uC5D0\uC11C \uC815\uC801 UI\uC640 \uD2B8\uB9AC\uAC70\uB97C \uB098\uB215\uB2C8\uB2E4."] }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "ToastSeverityIcon", description: "info, success, warn, error", code: `<ToastSeverityIcon severity="info" />
12
+ <ToastSeverityIcon severity="success" />`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "lg", align: "center", style: { color: 'var(--xfc-fg)' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.ToastSeverityIcon, { severity: "info" }), (0, jsx_runtime_1.jsx)(atoms_1.ToastSeverityIcon, { severity: "success" }), (0, jsx_runtime_1.jsx)(atoms_1.ToastSeverityIcon, { severity: "warn" }), (0, jsx_runtime_1.jsx)(atoms_1.ToastSeverityIcon, { severity: "error" })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Toast (\uB2E8\uC77C \uD589)", description: "onDismiss, icon=null, dismissible=false", code: `<Toast severity="info" message="…" onDismiss={…} />
13
+ <Toast severity="warn" icon={null} onDismiss={…} />
14
+ <Toast severity="error" dismissible={false} />`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "sm", align: "stretch", children: [(0, jsx_runtime_1.jsx)(atoms_1.Toast, { severity: "info", message: "\uAE30\uBCF8 \uB2EB\uAE30 \uBC84\uD2BC", onDismiss: () => { } }), (0, jsx_runtime_1.jsx)(atoms_1.Toast, { severity: "warn", message: "\uC544\uC774\uCF58 \uC228\uAE40 (icon=null)", icon: null, onDismiss: () => { } }), (0, jsx_runtime_1.jsx)(atoms_1.Toast, { severity: "error", message: "\uB2EB\uAE30 \uC5C6\uC74C", dismissible: false })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "\uC804\uC5ED \uB808\uC774\uC5B4 \uD2B8\uB9AC\uAC70", description: "ToastList \u00B7 InlineErrorList \u00B7 LoadingOverlay \u2014 ShowcaseChrome \uC5D0 \uB9C8\uC6B4\uD2B8\uB41C \uC608\uC2DC", code: `<ToastList toasts={entries} onDismiss={remove} />
15
+ <InlineErrorList errors={…} onDismiss={…} />
16
+ <LoadingOverlay active={…} title="…" message="…" />`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "md", align: "stretch", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", style: { margin: '0 0 var(--xfc-space-sm)', color: 'var(--xfc-fg-muted)' }, children: "Toast" }), (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.pushToast('info'), children: "info" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.pushToast('success'), children: "success" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.pushToast('warn'), children: "warn" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.pushToast('error'), children: "error" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: s.pushToastCustomIcon, children: "\uCEE4\uC2A4\uD140 icon" })] })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", style: { margin: '0 0 var(--xfc-space-sm)', color: 'var(--xfc-fg-muted)' }, children: "Inline error \u00B7 Loading" }), (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "outline", onClick: s.addError, children: "\uC5D0\uB7EC \uBC30\uB108 \uCD94\uAC00" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "outline", onClick: s.addErrorRich, children: "\uC5D0\uB7EC (icon\u00B7onClick)" }), (0, jsx_runtime_1.jsxs)(atoms_1.Button, { type: "button", variant: "outline", onClick: () => s.setLoading((v) => !v), children: ["\uB85C\uB529 \uC624\uBC84\uB808\uC774 ", s.loading ? '끄기' : '켜기'] })] })] })] }) })] }));
17
+ }
@@ -0,0 +1 @@
1
+ export declare function FormsSection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FormsSection = FormsSection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const SectionTitle_1 = require("../components/SectionTitle");
7
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
8
+ const ShowcaseContext_1 = require("../ShowcaseContext");
9
+ function FormsSection() {
10
+ const s = (0, ShowcaseContext_1.useShowcase)();
11
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "forms", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "Forms" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: [(0, jsx_runtime_1.jsx)("code", { children: "Input" }), ", ", (0, jsx_runtime_1.jsx)("code", { children: "Field" }), " \uB798\uD551, ", (0, jsx_runtime_1.jsx)("code", { children: "Select" }), ", ", (0, jsx_runtime_1.jsx)("code", { children: "Checkbox" }), " \uC870\uD569 \uC608\uC2DC\uC785\uB2C8\uB2E4."] }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Input \u2014 states", description: "invalid + description, enabled=false, disabled", code: `<Input type="email" placeholder="you@example.com" />
12
+ <Input invalid description="형식을 확인하세요" />
13
+ <Input enabled={false} placeholder="enabled=false" />
14
+ <Input disabled placeholder="native disabled" />`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "md", align: "stretch", children: [(0, jsx_runtime_1.jsx)("label", { htmlFor: `${s.uid}-email`, children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { as: "span", variant: "labelBlock", children: "\uC774\uBA54\uC77C" }) }), (0, jsx_runtime_1.jsx)(atoms_1.Input, { id: `${s.uid}-email`, type: "email", placeholder: "you@example.com", autoComplete: "email" }), (0, jsx_runtime_1.jsx)(atoms_1.Input, { placeholder: "\uD615\uC2DD \uC624\uB958 \uC608\uC2DC", invalid: true, description: "invalid + description (aria-describedby \uC790\uB3D9)", defaultValue: "not-an-email" }), (0, jsx_runtime_1.jsx)(atoms_1.Input, { placeholder: "enabled=false", enabled: false }), (0, jsx_runtime_1.jsx)(atoms_1.Input, { placeholder: "\uBE44\uD65C\uC131(disabled)", disabled: true })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Field + Textarea", description: "label, hint, error, invalid \u2014 \uC81C\uC5B4 \uCEF4\uD3EC\uB10C\uD2B8\uB85C \uAE38\uC774 \uAC80\uC99D", code: `<Field htmlFor="bio" label="Bio" hint="Short" error={err} invalid={!!err}>
15
+ <Textarea id="bio" rows={3} value={v} onChange={…} />
16
+ </Field>`, children: (0, jsx_runtime_1.jsx)(atoms_1.Field, { htmlFor: `${s.uid}-field-bio`, label: "Bio", hint: "12\uC790 \uC774\uD558", error: s.fieldBio.length > 12 ? 'Keep it under 12 characters' : undefined, invalid: s.fieldBio.length > 12, children: (0, jsx_runtime_1.jsx)(atoms_1.Textarea, { id: `${s.uid}-field-bio`, rows: 3, placeholder: "Type here\u2026", value: s.fieldBio, onChange: (e) => s.setFieldBio(e.target.value) }) }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Select & Checkbox", description: "Field \uB85C Select \uB798\uD551, \uB2E8\uB3C5 Checkbox", code: `<Field htmlFor="plan" label="Plan">
17
+ <Select id="plan" value={v} onChange={…}>…</Select>
18
+ </Field>
19
+ <Checkbox label="I agree" checked={c} onChange={…} />`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "md", align: "stretch", children: [(0, jsx_runtime_1.jsx)(atoms_1.Field, { htmlFor: `${s.uid}-field-plan`, label: "Plan", children: (0, jsx_runtime_1.jsxs)(atoms_1.Select, { id: `${s.uid}-field-plan`, value: s.fieldPlan, onChange: (e) => s.setFieldPlan(e.target.value), children: [(0, jsx_runtime_1.jsx)("option", { value: "a", children: "Plan A" }), (0, jsx_runtime_1.jsx)("option", { value: "b", children: "Plan B" })] }) }), (0, jsx_runtime_1.jsx)(atoms_1.Checkbox, { label: "I agree to the terms", checked: s.fieldAgree, onChange: (e) => s.setFieldAgree(e.target.checked) })] }) })] }));
20
+ }
@@ -0,0 +1 @@
1
+ export declare function LayoutSection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LayoutSection = LayoutSection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const SectionTitle_1 = require("../components/SectionTitle");
7
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
8
+ function LayoutSection() {
9
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "layout", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "Box \u00B7 Stack" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: ["\uB808\uC774\uC544\uC6C3 \uD504\uB9AC\uBBF8\uD2F0\uBE0C \u2014 padding, ", (0, jsx_runtime_1.jsx)("code", { children: "as" }), ", flex gap\u00B7justify\u00B7wrap."] }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Box", description: "as \uB85C \uC2DC\uB9E8\uD2F1 \uD0DC\uADF8, padding \uD1A0\uD070", code: `<Box as="section" padding="md" aria-label="…">
10
+
11
+ </Box>
12
+ <Box padding="md">…</Box>`, children: (0, jsx_runtime_1.jsx)(atoms_1.Stack, { direction: "column", gap: "md", align: "stretch", children: (0, jsx_runtime_1.jsx)(atoms_1.Box, { as: "section", padding: "md", style: { border: '1px dashed var(--xfc-border-strong)', borderRadius: 'var(--xfc-radius-xs)' }, "aria-label": "\uC139\uC158 \uBC15\uC2A4 \uC608\uC2DC", children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", children: "Box as=\"section\" + padding=\"md\"" }) }) }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Stack \u2014 row justify", description: "direction=\"row\", justify=\"between\", align", code: `<Stack direction="row" justify="between" align="center" gap="md">
13
+ <Text variant="small">왼쪽</Text>
14
+ <Text variant="small">오른쪽</Text>
15
+ </Stack>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", justify: "between", align: "center", wrap: false, gap: "md", children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", children: "justify=\"between\"" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", children: "\uC624\uB978\uCABD \uC815\uB82C" })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Stack \u2014 gap & wrap", description: "align=\"stretch\", flexWrap \uC740 style \uB85C \uBCF4\uC644 \uAC00\uB2A5", code: `<Stack direction="row" gap="md" align="stretch" style={{ flexWrap: 'wrap' }}>
16
+ <Box padding="md">…</Box>
17
+ <Card style={{ flex: '1 1 140px' }}>…</Card>
18
+ </Stack>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "md", align: "stretch", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Box, { padding: "md", style: { border: '1px dashed var(--xfc-border-strong)', borderRadius: 'var(--xfc-radius-xs)' }, children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", children: "\uCCAB \uCE78" }) }), (0, jsx_runtime_1.jsx)(atoms_1.Card, { style: { flex: '1 1 140px', minWidth: 0 }, children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", children: "\uC911\uCCA9 Card (flex-grow)" }) })] }) })] }));
19
+ }
@@ -0,0 +1 @@
1
+ export declare function OverlaysSection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OverlaysSection = OverlaysSection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const SectionTitle_1 = require("../components/SectionTitle");
7
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
8
+ const ShowcaseContext_1 = require("../ShowcaseContext");
9
+ function OverlaysSection() {
10
+ const s = (0, ShowcaseContext_1.useShowcase)();
11
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "overlays", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "Dialog \u00B7 Confirm \u00B7 BottomSheet" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: [(0, jsx_runtime_1.jsx)("code", { children: "document.body" }), " \uD3EC\uD138 \u00B7 \uB192\uC740 z-index. \uD3EC\uCEE4\uC2A4 \uD2B8\uB7A9\u00B7\uBC30\uACBD \uCC98\uB9AC\uB294 base.css / overlay \uD6C5\uC744 \uB530\uB985\uB2C8\uB2E4."] }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Dialog", description: "\uAE30\uBCF8 \uD328\uB110 \u00B7 titleAdornment \u00B7 headerExtra", code: `<Dialog open={open} onOpenChange={setOpen} title="…" description="…">
12
+
13
+ </Dialog>
14
+ <Dialog titleAdornment={…} headerExtra={…} … />`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "sm", align: "stretch", children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", style: { margin: 0, color: 'var(--xfc-fg-muted)' }, children: "\uBC84\uD2BC\uC73C\uB85C \uC5F4\uAE30" }), (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setDialogOpen(true), children: "Dialog" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setDialogRichOpen(true), children: "Dialog (\uD5E4\uB354 \uCEE4\uC2A4\uD140)" })] })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "ConfirmDialog", description: "destructive, confirmLoading, confirmButtonProps", code: `<ConfirmDialog
15
+ open={open}
16
+ onOpenChange={setOpen}
17
+ title="삭제"
18
+ message="진행할까요?"
19
+ destructive
20
+ confirmLabel="삭제"
21
+ onConfirm={handleDelete}
22
+ />`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setConfirmOpen(true), children: "Confirm" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setConfirmDestructiveOpen(true), children: "destructive" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setConfirmLoadingDemo(true), children: "loading" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setConfirmCustomOpen(true), children: "\uBC84\uD2BC props" })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "BottomSheet", description: "showHandle, subtitle, headerExtra", code: `<BottomSheet open={open} onOpenChange={setOpen} title="…" showHandle>
23
+
24
+ </BottomSheet>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", gap: "sm", align: "center", style: { flexWrap: 'wrap' }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setSheetOpen(true), children: "BottomSheet" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { type: "button", variant: "secondary", onClick: () => s.setSheetRichOpen(true), children: "subtitle \u00B7 extra" })] }) })] }));
25
+ }
@@ -0,0 +1 @@
1
+ export declare function OverviewSection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OverviewSection = OverviewSection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const SectionTitle_1 = require("../components/SectionTitle");
7
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
8
+ function OverviewSection() {
9
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "overview", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "\uAC1C\uC694 \u00B7 \uBB38\uC11C" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: ["\uC774 \uAC24\uB7EC\uB9AC\uB294 ", (0, jsx_runtime_1.jsx)("strong", { children: "@xfilecom/front-core" }), "\uC758 \uD45C\uBA74\u00B7\uD1A0\uD070\u00B7\uC6D0\uC790 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD55C \uD654\uBA74\uC5D0\uC11C \uC0B4\uD3B4\uBCF4\uAE30 \uC704\uD55C \uCC38\uACE0\uC6A9 UI\uC785\uB2C8\uB2E4. \uD328\uD0A4\uC9C0\uC5D0 \uD3EC\uD568\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uC740 npm \uC124\uCE58 \uD6C4", ' ', (0, jsx_runtime_1.jsx)("code", { children: "node_modules/@xfilecom/front-core/docs/" }), "\uC5D0\uC11C\uB3C4 \uC5F4 \uC218 \uC788\uC2B5\uB2C8\uB2E4."] }), (0, jsx_runtime_1.jsxs)("div", { className: "xfc-ds-demo-grid xfc-ds-demo-grid--2", children: [(0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "CSS \uB85C\uB4DC \uC21C\uC11C", description: "\uC571 \uC5D4\uD2B8\uB9AC\uC5D0\uC11C design tokens \u2192 base \uB9AC\uC14B\u00B7\uC720\uD2F8 \u2192 (\uC120\uD0DD) \uC571/\uBE0C\uB79C\uB4DC \uD14C\uB9C8 \uC21C\uC73C\uB85C import \uD558\uC138\uC694.", code: `import '@xfilecom/front-core/tokens.css';
10
+ import '@xfilecom/front-core/base.css';
11
+ // 그 다음 앱 전용 테마·레이아웃 CSS`, children: (0, jsx_runtime_1.jsx)(atoms_1.Paper, { elevation: 1, style: { padding: 'var(--xfc-space-md)' }, children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", style: { margin: 0, color: 'var(--xfc-fg-muted)' }, children: "\uAD8C\uC7A5 \uC21C\uC11C: README \u2192 docs/DESIGN_SYSTEM.md \u2192 docs/COMPONENTS.md" }) }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "React \u2014 Paper \uD45C\uBA74", description: "\uBC94\uC6A9 \uD45C\uBA74 \uCEF4\uD3EC\uB10C\uD2B8\uB85C elevation\u00B7outlined variant \uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.", code: `import { Paper, Text } from '@xfilecom/front-core';
12
+
13
+ <Paper elevation={2} style={{ padding: 'var(--xfc-space-lg)' }}>
14
+ <Text variant="body">콘텐츠</Text>
15
+ </Paper>`, children: (0, jsx_runtime_1.jsx)(atoms_1.Paper, { elevation: 2, style: { padding: 'var(--xfc-space-lg)' }, children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "body", style: { margin: 0 }, children: "elevation \uACFC padding \uC744 \uC870\uD569\uD55C \uC608\uC2DC\uC785\uB2C8\uB2E4." }) }) })] }), (0, jsx_runtime_1.jsx)("div", { style: { marginTop: 'var(--xfc-space-lg)' }, children: (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "\uC18C\uC2A4 \uD0D0\uC0C9", description: "\uBAA8\uB178\uB808\uD3EC\uC5D0\uC11C\uB294 packages/front-core/src/components/atoms \uB4F1\uC5D0\uC11C props\u00B7\uAD6C\uD604\uC744 \uC9C1\uC811 \uD655\uC778\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.", code: `// 예: Button, Card, Dialog
16
+ import { Button } from '@xfilecom/front-core';`, children: (0, jsx_runtime_1.jsx)(atoms_1.Card, { children: (0, jsx_runtime_1.jsxs)(atoms_1.Text, { variant: "small", style: { margin: 0 }, children: ["TypeScript \uC0AC\uC6A9\uC790\uB294 \uC5D0\uB514\uD130\uC5D0\uC11C ", (0, jsx_runtime_1.jsx)("code", { children: "ButtonProps" }), " \uB4F1 \uD0C0\uC785 \uC815\uC758\uB85C \uBC14\uB85C \uC774\uB3D9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."] }) }) }) })] }));
17
+ }
@@ -0,0 +1 @@
1
+ export declare function SurfacesSection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SurfacesSection = SurfacesSection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const SectionTitle_1 = require("../components/SectionTitle");
7
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
8
+ const ShowcaseContext_1 = require("../ShowcaseContext");
9
+ function SurfacesSection() {
10
+ const s = (0, ShowcaseContext_1.useShowcase)();
11
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "surfaces", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "Paper \u00B7 Card" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: [(0, jsx_runtime_1.jsx)("code", { children: "Paper" }), "\uB294 \uBC94\uC6A9 \uD45C\uBA74(elevation). ", (0, jsx_runtime_1.jsx)("code", { children: "Card" }), "\uB294 \uD5E4\uB354\u00B7\uD478\uD130 \uC2AC\uB86F\uC774 \uC788\uB294 \uD328\uD134\uC785\uB2C8\uB2E4."] }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Paper \u2014 elevation 0\u20134", description: "\uADF8\uB9BC\uC790 \uB2E8\uACC4\uB97C \uB098\uB780\uD788 \uBE44\uAD50\uD569\uB2C8\uB2E4.", code: `import { Paper, Text } from '@xfilecom/front-core';
12
+
13
+ {[0, 1, 2, 3, 4].map((e) => (
14
+ <Paper key={e} elevation={e as 0 | 1 | 2 | 3 | 4} style={{ padding: 16 }}>
15
+ <Text variant="small">elevation {e}</Text>
16
+ </Paper>
17
+ ))}`, children: (0, jsx_runtime_1.jsx)("div", { className: "xfc-ds-paper-row", children: [0, 1, 2, 3, 4].map((e) => ((0, jsx_runtime_1.jsx)(atoms_1.Paper, { elevation: e, style: { padding: 'var(--xfc-space-md)', minWidth: 112 }, children: (0, jsx_runtime_1.jsxs)(atoms_1.Text, { variant: "small", style: { margin: 0 }, children: ["elevation ", e] }) }, e))) }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Paper \u2014 outlined", description: "\uADF8\uB9BC\uC790 \uB300\uC2E0 \uD14C\uB450\uB9AC\uB9CC \uC4F0\uB294 variant \uC785\uB2C8\uB2E4.", code: `<Paper variant="outlined" style={{ padding: 16 }}>…</Paper>`, children: (0, jsx_runtime_1.jsx)(atoms_1.Paper, { variant: "outlined", style: { padding: 'var(--xfc-space-md)', maxWidth: 240 }, children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", style: { margin: 0 }, children: "variant=\"outlined\"" }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "xfc-ds-demo-grid xfc-ds-demo-grid--2", style: { marginTop: 'var(--xfc-space-md)' }, children: [(0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Card \u2014 interactive", description: "\uD638\uBC84 \uC2DC \uC0B4\uC9DD \uB5A0\uC624\uB974\uB294 \uD074\uB9AD \uAC00\uB2A5 \uCE74\uB4DC(role=button, \uD0A4\uBCF4\uB4DC \uC9C0\uC6D0).", code: `<Card
18
+ interactive
19
+ role="button"
20
+ tabIndex={0}
21
+ onClick={…}
22
+ onKeyDown={(e) => {
23
+ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); … }
24
+ }}
25
+ >
26
+
27
+ </Card>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Card, { interactive: true, role: "button", tabIndex: 0, onClick: () => s.setInteractiveCardClicks((n) => n + 1), onKeyDown: (e) => {
28
+ if (e.key === 'Enter' || e.key === ' ') {
29
+ e.preventDefault();
30
+ s.setInteractiveCardClicks((n) => n + 1);
31
+ }
32
+ }, children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "section", style: { margin: '0 0 var(--xfc-space-sm)' }, children: "Interactive" }), (0, jsx_runtime_1.jsxs)(atoms_1.Text, { variant: "small", style: { margin: 0 }, children: ["\uD074\uB9AD ", s.interactiveCardClicks, "\uD68C"] })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Card \u2014 title / footer", description: "title\u00B7footer \uAC00 \uC788\uC73C\uBA74 \uBCF8\uBB38\uC774 \uCE74\uB4DC body \uC601\uC5ED\uC73C\uB85C \uAC10\uC2F8\uC9D1\uB2C8\uB2E4.", code: `<Card
33
+ title="제목"
34
+ footer={<Stack direction="row" justify="end" gap="sm">…</Stack>}
35
+ >
36
+ <Text variant="body">본문</Text>
37
+ </Card>`, children: (0, jsx_runtime_1.jsx)(atoms_1.Card, { title: "\uC124\uC815", footer: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "row", justify: "end", gap: "sm", align: "center", children: [(0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "ghost", type: "button", children: "\uCDE8\uC18C" }), (0, jsx_runtime_1.jsx)(atoms_1.Button, { variant: "primary", type: "button", children: "\uC800\uC7A5" })] }), children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "body", style: { margin: 0 }, children: "\uD478\uD130\uC5D0 \uC8FC\u00B7\uBCF4\uC870 \uC561\uC158\uC744 \uBC30\uCE58\uD558\uB294 \uC77C\uBC18\uC801\uC778 \uD328\uD134\uC785\uB2C8\uB2E4." }) }) })] })] }));
38
+ }
@@ -0,0 +1 @@
1
+ export declare function TypographySection(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TypographySection = TypographySection;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const atoms_1 = require("../../components/atoms");
6
+ const SectionTitle_1 = require("../components/SectionTitle");
7
+ const ShowcaseDemo_1 = require("../components/ShowcaseDemo");
8
+ function TypographySection() {
9
+ return ((0, jsx_runtime_1.jsxs)("section", { id: "typography", className: "xfc-ds-section", children: [(0, jsx_runtime_1.jsx)(SectionTitle_1.SectionTitle, { children: "Typography" }), (0, jsx_runtime_1.jsxs)("p", { className: "xfc-ds-section-lead", children: [(0, jsx_runtime_1.jsx)("code", { children: "Text" }), " \uCEF4\uD3EC\uB10C\uD2B8\uC758 variant\u00B7", (0, jsx_runtime_1.jsx)("code", { children: "as" }), "\u00B7", (0, jsx_runtime_1.jsx)("code", { children: "truncate" }), " \uC870\uD569\uC785\uB2C8\uB2E4."] }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Display & section scale", description: "title, appbar, section, subtitle, lead, body", code: `<Text variant="title">title</Text>
10
+ <Text variant="appbar">appbar</Text>
11
+ <Text variant="section">section</Text>
12
+ <Text variant="subtitle">subtitle</Text>
13
+ <Text variant="lead">lead</Text>
14
+ <Text variant="body">body</Text>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "sm", align: "stretch", children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "title", children: "title" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "appbar", children: "appbar" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "section", children: "section" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "subtitle", children: "subtitle" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "lead", children: "lead \u2014 \uB9AC\uB4DC/\uD788\uC5B4\uB85C \uBB38\uB2E8" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "body", children: "body \u2014 \uBCF8\uBB38" })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Supporting & accent", description: "muted, small, label, labelBlock, accent", code: `<Text variant="muted">muted</Text>
15
+ <Text variant="small">small</Text>
16
+ <Text variant="label">label (인라인 힌트)</Text>
17
+ <Text variant="labelBlock">labelBlock (폼 라벨)</Text>
18
+ <Text variant="accent">accent</Text>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "sm", align: "stretch", children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "muted", children: "muted" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "small", children: "small" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "label", children: "label \u2014 \uC778\uB77C\uC778 \uBCF4\uC870" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "labelBlock", children: "labelBlock \u2014 \uBE14\uB85D \uB77C\uBCA8" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "accent", children: "accent" })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "xfc-ds-demo-grid xfc-ds-demo-grid--2", style: { marginTop: 'var(--xfc-space-md)' }, children: [(0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Semantic element (as)", description: "\uAC19\uC740 \uC2A4\uD0C0\uC77C\uC744 \uB2E4\uB978 HTML \uD0DC\uADF8\uB85C \uB80C\uB354\uD569\uB2C8\uB2E4.", code: `<Text as="h3" variant="section">페이지 소제목</Text>
19
+ <Text as="span" variant="body">인라인 본문</Text>`, children: (0, jsx_runtime_1.jsxs)(atoms_1.Stack, { direction: "column", gap: "md", align: "stretch", children: [(0, jsx_runtime_1.jsx)(atoms_1.Text, { as: "h3", variant: "section", style: { margin: 0 }, children: "as=\"h3\" + section" }), (0, jsx_runtime_1.jsx)(atoms_1.Text, { as: "span", variant: "body", children: "as=\"span\" \uC778\uB77C\uC778" })] }) }), (0, jsx_runtime_1.jsx)(ShowcaseDemo_1.ShowcaseDemo, { title: "Truncate", description: "\uD55C \uC904 \uB9D0\uC904\uC784 \u2014 \uC804\uCCB4 \uBB38\uC790\uC5F4\uC740 title \uB85C \uD234\uD301\uC5D0.", code: `<div style={{ maxWidth: 200 }}>
20
+ <Text variant="body" truncate title="전체 텍스트">
21
+ 아주 긴 한 줄…
22
+ </Text>
23
+ </div>`, children: (0, jsx_runtime_1.jsx)("div", { style: { maxWidth: 200 }, children: (0, jsx_runtime_1.jsx)(atoms_1.Text, { variant: "body", truncate: true, title: "\uB9D0\uC904\uC784 \uC804\uCCB4\uB294 title \uC18D\uC131", children: "\uC544\uC8FC \uAE34 \uD55C \uC904 \uD14D\uC2A4\uD2B8\uB294 truncate \uB85C \uB9D0\uC904\uC784 \uCC98\uB9AC\uD569\uB2C8\uB2E4." }) }) })] })] }));
24
+ }
@@ -0,0 +1,235 @@
1
+ /**
2
+ * @xfilecom/front-core — 디자인 시스템 쇼케이스 (npm: @xfilecom/front-core/showcase.css)
3
+ */
4
+
5
+ .xfc-ds {
6
+ display: flex;
7
+ align-items: flex-start;
8
+ gap: var(--xfc-space-xl);
9
+ max-width: 1180px;
10
+ margin: 0 auto;
11
+ padding: 0 var(--xfc-space-lg) var(--xfc-space-2xl);
12
+ }
13
+
14
+ .xfc-ds-nav {
15
+ position: sticky;
16
+ top: var(--xfc-space-md);
17
+ flex: 0 0 200px;
18
+ max-height: calc(100dvh - var(--xfc-space-xl));
19
+ overflow: auto;
20
+ padding: var(--xfc-space-md);
21
+ border-radius: var(--xfc-radius-md);
22
+ background: var(--xfc-bg-elevated);
23
+ border: 1px solid var(--xfc-border);
24
+ box-shadow: var(--xfc-shadow-xs);
25
+ }
26
+
27
+ .xfc-ds-nav-title {
28
+ margin: 0 0 var(--xfc-space-sm);
29
+ font-size: var(--xfc-text-small);
30
+ font-weight: 700;
31
+ color: var(--xfc-fg-muted);
32
+ text-transform: uppercase;
33
+ letter-spacing: 0.06em;
34
+ }
35
+
36
+ .xfc-ds-nav-list {
37
+ margin: 0;
38
+ padding: 0;
39
+ list-style: none;
40
+ }
41
+
42
+ .xfc-ds-nav-list li {
43
+ margin: 0;
44
+ }
45
+
46
+ .xfc-ds-nav-link {
47
+ display: block;
48
+ padding: var(--xfc-space-xs) var(--xfc-space-sm);
49
+ margin: 2px 0;
50
+ font-size: var(--xfc-text-small);
51
+ font-weight: 500;
52
+ color: var(--xfc-fg-label);
53
+ text-decoration: none;
54
+ border-radius: var(--xfc-radius-xs);
55
+ transition: background 0.15s ease, color 0.15s ease;
56
+ }
57
+
58
+ .xfc-ds-nav-link:hover {
59
+ background: var(--xfc-accent-soft);
60
+ color: var(--xfc-accent);
61
+ }
62
+
63
+ .xfc-ds-main {
64
+ flex: 1 1 0;
65
+ min-width: 0;
66
+ }
67
+
68
+ .xfc-ds-section {
69
+ scroll-margin-top: var(--xfc-space-xl);
70
+ margin-bottom: var(--xfc-space-2xl);
71
+ }
72
+
73
+ .xfc-ds-section-head {
74
+ margin-bottom: var(--xfc-space-md);
75
+ padding-bottom: var(--xfc-space-sm);
76
+ border-bottom: 1px solid var(--xfc-border);
77
+ }
78
+
79
+ .xfc-ds-section-lead {
80
+ margin: 0 0 var(--xfc-space-lg);
81
+ font-size: var(--xfc-text-small);
82
+ line-height: 1.55;
83
+ color: var(--xfc-fg-muted);
84
+ max-width: 52rem;
85
+ }
86
+
87
+ .xfc-ds-demo-grid {
88
+ display: grid;
89
+ gap: var(--xfc-space-lg);
90
+ margin-top: var(--xfc-space-md);
91
+ }
92
+
93
+ @media (min-width: 720px) {
94
+ .xfc-ds-demo-grid--2 {
95
+ grid-template-columns: repeat(2, minmax(0, 1fr));
96
+ }
97
+ }
98
+
99
+ .xfc-ds-demo {
100
+ margin-bottom: var(--xfc-space-lg);
101
+ border: 1px solid var(--xfc-border);
102
+ border-radius: var(--xfc-radius-md);
103
+ background: var(--xfc-bg-elevated);
104
+ box-shadow: var(--xfc-shadow-xs);
105
+ overflow: hidden;
106
+ }
107
+
108
+ .xfc-ds-demo:last-child {
109
+ margin-bottom: 0;
110
+ }
111
+
112
+ .xfc-ds-demo__header {
113
+ padding: var(--xfc-space-md) var(--xfc-space-lg);
114
+ border-bottom: 1px solid var(--xfc-border);
115
+ background: linear-gradient(180deg, var(--xfc-bg-muted) 0%, var(--xfc-bg-elevated) 100%);
116
+ }
117
+
118
+ .xfc-ds-demo__title {
119
+ margin: 0;
120
+ font-size: var(--xfc-text-small);
121
+ font-weight: 700;
122
+ letter-spacing: 0.02em;
123
+ color: var(--xfc-fg-label);
124
+ }
125
+
126
+ .xfc-ds-demo__desc {
127
+ margin-top: var(--xfc-space-xs);
128
+ font-size: var(--xfc-text-small);
129
+ line-height: 1.5;
130
+ color: var(--xfc-fg-muted);
131
+ }
132
+
133
+ .xfc-ds-demo__preview {
134
+ padding: var(--xfc-space-lg);
135
+ background: var(--xfc-bg);
136
+ min-height: 3rem;
137
+ }
138
+
139
+ .xfc-ds-demo__details {
140
+ border-top: 1px solid var(--xfc-border);
141
+ }
142
+
143
+ .xfc-ds-demo__summary {
144
+ list-style: none;
145
+ cursor: pointer;
146
+ padding: var(--xfc-space-sm) var(--xfc-space-lg);
147
+ font-size: var(--xfc-text-small);
148
+ font-weight: 600;
149
+ color: var(--xfc-accent);
150
+ background: var(--xfc-bg-elevated);
151
+ transition: background 0.15s ease;
152
+ }
153
+
154
+ .xfc-ds-demo__summary::-webkit-details-marker {
155
+ display: none;
156
+ }
157
+
158
+ .xfc-ds-demo__summary::before {
159
+ content: '';
160
+ display: inline-block;
161
+ width: 0.35em;
162
+ height: 0.35em;
163
+ margin-right: var(--xfc-space-sm);
164
+ border-right: 2px solid currentColor;
165
+ border-bottom: 2px solid currentColor;
166
+ transform: rotate(-45deg);
167
+ vertical-align: 0.15em;
168
+ transition: transform 0.2s ease;
169
+ }
170
+
171
+ details[open] > .xfc-ds-demo__summary::before {
172
+ transform: rotate(45deg);
173
+ vertical-align: 0.05em;
174
+ }
175
+
176
+ .xfc-ds-demo__summary:hover {
177
+ background: var(--xfc-accent-soft);
178
+ }
179
+
180
+ .xfc-ds-demo__code {
181
+ padding: 0 var(--xfc-space-lg) var(--xfc-space-lg);
182
+ background: var(--xfc-bg-muted);
183
+ }
184
+
185
+ .xfc-ds-code-wrap--embedded .xfc-ds-code {
186
+ margin-top: var(--xfc-space-sm);
187
+ }
188
+
189
+ .xfc-ds-code-wrap .xfc-ds-code-caption {
190
+ margin-top: var(--xfc-space-sm);
191
+ }
192
+
193
+ .xfc-ds-code {
194
+ margin: var(--xfc-space-md) 0 0;
195
+ padding: var(--xfc-space-md) var(--xfc-space-lg);
196
+ font-family: var(--xfc-font-mono);
197
+ font-size: 0.8125rem;
198
+ line-height: 1.5;
199
+ color: var(--xfc-fg-label);
200
+ background: var(--xfc-bg-muted);
201
+ border: 1px solid var(--xfc-border);
202
+ border-radius: var(--xfc-radius-sm);
203
+ overflow-x: auto;
204
+ white-space: pre-wrap;
205
+ word-break: break-word;
206
+ }
207
+
208
+ .xfc-ds-code-caption {
209
+ margin: 0 0 var(--xfc-space-xs);
210
+ font-size: var(--xfc-text-small);
211
+ font-weight: 600;
212
+ color: var(--xfc-fg-muted);
213
+ }
214
+
215
+ .xfc-ds-paper-row {
216
+ display: flex;
217
+ flex-wrap: wrap;
218
+ gap: var(--xfc-space-md);
219
+ align-items: flex-start;
220
+ }
221
+
222
+ @media (max-width: 840px) {
223
+ .xfc-ds {
224
+ flex-direction: column;
225
+ padding-inline: var(--xfc-space-md);
226
+ }
227
+
228
+ .xfc-ds-nav {
229
+ position: relative;
230
+ top: 0;
231
+ flex: none;
232
+ width: 100%;
233
+ max-height: none;
234
+ }
235
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xfilecom/front-core",
3
- "version": "0.2.29",
3
+ "version": "0.2.31",
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",
@@ -18,7 +18,12 @@
18
18
  "./overlays": {
19
19
  "types": "./dist/components/overlays/index.d.ts",
20
20
  "default": "./dist/components/overlays/index.js"
21
- }
21
+ },
22
+ "./showcase": {
23
+ "types": "./dist/showcase/index.d.ts",
24
+ "default": "./dist/showcase/index.js"
25
+ },
26
+ "./showcase.css": "./dist/showcase.css"
22
27
  },
23
28
  "files": [
24
29
  "dist",
@@ -29,7 +34,7 @@
29
34
  "prepublishOnly": "npm run build",
30
35
  "build": "node scripts/write-version.js && npm run build:ts && npm run build:css",
31
36
  "build:ts": "tsc",
32
- "build:css": "cp src/tokens.css dist/tokens.css && cp src/base.css dist/base.css"
37
+ "build:css": "cp src/tokens.css dist/tokens.css && cp src/base.css dist/base.css && cp src/showcase/showcase.css dist/showcase.css"
33
38
  },
34
39
  "peerDependencies": {
35
40
  "react": ">=18.0.0",