@loword/loword-design-system 0.0.3 → 0.0.4

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 CHANGED
@@ -1,24 +1,93 @@
1
1
  # @loword/loword-design-system
2
2
 
3
- loword design system React 컴포넌트 패키지입니다.
3
+ [![npm version](https://img.shields.io/npm/v/@loword/loword-design-system.svg)](https://www.npmjs.com/package/@loword/loword-design-system)
4
+ [![license](https://img.shields.io/npm/l/@loword/loword-design-system.svg)](./LICENSE)
5
+
6
+ 로워드 디자인 시스템 — React 19 컴포넌트 패키지. Tailwind CSS v4 기반이며 NPM(ESM)으로 배포됩니다.
7
+
8
+ > 모든 공개 컴포넌트는 `LD` 접두사를 사용합니다 (예: `LDButton`, `LDModal`, `LDInput`).
9
+
10
+ ## 요구사항
11
+
12
+ - **React 19** / **React DOM 19** (peer dependency)
13
+ - **Tailwind CSS v4** — 스타일 적용을 위해 필요
14
+ - **Next.js 15** — 일부 컴포넌트(`LDTanstackTable`, `LDBreadCrumb`)는 `next/navigation`·`next/link`에 의존하므로 Next 환경에서만 동작 (optional)
4
15
 
5
16
  ## 설치
6
17
 
7
18
  ```bash
8
19
  npm install @loword/loword-design-system
20
+ # 또는
21
+ pnpm add @loword/loword-design-system
22
+ ```
23
+
24
+ 특정 컴포넌트(Editor, Carousel, Drawer, Table, Select, DatePicker 등)는 해당 기능의 라이브러리를 **optional peer dependency**로 사용합니다. 그 컴포넌트를 쓸 때만 함께 설치하세요 — 예: `@tiptap/*`(Editor), `embla-carousel-react`(Carousel), `vaul`(Drawer), `@radix-ui/*`(Modal/Popover/Tooltip/Select), `@tanstack/react-table`(Table), `react-day-picker`·`dayjs`(DatePicker), `react-hot-toast`(Toast).
25
+
26
+ ## 설정
27
+
28
+ 스타일시트를 앱 진입점에서 **한 번** import 합니다.
29
+
30
+ ```ts
31
+ import '@loword/loword-design-system/styles.css';
32
+ ```
33
+
34
+ ## 사용
35
+
36
+ ```tsx
37
+ import { LDButton } from '@loword/loword-design-system';
38
+
39
+ export default function Example() {
40
+ return (
41
+ <LDButton variant="solid" color="point" onClick={() => alert('clicked')}>
42
+ 확인
43
+ </LDButton>
44
+ );
45
+ }
46
+ ```
47
+
48
+ 명령형 API 예시:
49
+
50
+ ```tsx
51
+ import { openModal, Toast } from '@loword/loword-design-system';
52
+
53
+ const result = await openModal({ title: '삭제할까요?', /* ... */ });
54
+ Toast.success('저장되었습니다');
9
55
  ```
10
56
 
57
+ ### import 방식
58
+
11
59
  ```ts
12
- import { Button } from '@loword/loword-design-system';
13
- import '@loword/loword-design-system/styles.css'; // 스타일 1회 import
60
+ // 1) barrel 이름으로 가져오기
61
+ import { LDButton, LDModal, LDInput } from '@loword/loword-design-system';
62
+
63
+ // 2) 개별 경로 — 트리셰이킹/명시적 경로
64
+ import LDButton from '@loword/loword-design-system/components/LDButton/LDButton';
14
65
  ```
15
66
 
67
+ ## 컴포넌트
68
+
69
+ **기본/입력**: `LDButton` · `LDInput` · `LDCheckbox` · `LDCheckboxGroup` · `LDRadio` · `LDRadioGroup` · `LDSelect` · `LDMultiSelect` · `LDToggleButton` · `LDSlider` · `LDOTPInput` · `LDFileUploadBase`
70
+
71
+ **날짜/시간**: `LDCalendar` · `LDDataCalendar` · `LDDatePicker` · `LDDateRangePicker` · `LDTimePicker`
72
+
73
+ **레이아웃/표시**: `LDBadge` · `LDAvatar` · `LDDivider` · `LDCallout` · `LDSkeleton` · `LDSpinner` · `LDLoadingDots` · `LDScrollArea` · `LDBreadCrumb` · `LDMenuBar` · `LDLNBBase`
74
+
75
+ **오버레이/피드백/내비**: `LDModal` (+ `openModal`) · `LDDrawer` · `LDPopover` · `LDTooltip` · `LDToast` · `LDToaster`
76
+
77
+ **콘텐츠**: `LDEditor` · `LDViewer` · `LDCarousel` · `LDTable` · `LDTanstackTable` · `LDPagination`
78
+
79
+ **폼 연동 / 헬퍼** (LD 접두사 없음): `Form` · `NativeForm` · `FormField` · `FormErrorMessage` · `FormInput` · `FormSelect` · `FormMultiSelect` · `FormCheckbox` · `FormCheckboxGroup` · `FormRadioGroup` · `FormDatePicker` · `FormDateRangePicker` · `FormTimePicker` · `FormToggleButton` · `TableField` · `LucideIcon`
80
+
81
+ > 폼 래퍼(`Form*`, `TableField`)와 `LucideIcon`은 디자인 컴포넌트가 아니므로 원래 이름을 유지합니다.
82
+
16
83
  ## 빠른 시작 (개발)
17
84
 
18
85
  ```bash
19
86
  pnpm install # 의존성 설치
20
87
  pnpm storybook # Storybook 개발 서버 (port 6006)
21
88
  pnpm build # 프로덕션 빌드
89
+ pnpm check-types # 타입 체크
90
+ pnpm lint # 린트 (--max-warnings 0)
22
91
  ```
23
92
 
24
93
  ## 문서
@@ -29,3 +98,8 @@ pnpm build # 프로덕션 빌드
29
98
  - 스타일 체계 (디자인 토큰, `cn()`)
30
99
  - Storybook 스타일 제어 및 stories 생성 방법
31
100
  - Props 문서화 (JSDoc)
101
+ - **변경 이력**: [docs/CHANGELOG.md](./docs/CHANGELOG.md)
102
+
103
+ ## 라이선스
104
+
105
+ [MIT](./LICENSE)
@@ -6,7 +6,7 @@ import { useEditorState } from '@tiptap/react';
6
6
  import EditorBase, { useEditorContext } from './EditorBase.js';
7
7
  import { createEditorExtensions } from './extensions.js';
8
8
  import cn from '../../utils/cn.js';
9
- import Toast from '../Toast/Toast.js';
9
+ import LDToast from '../LDToast/LDToast.js';
10
10
  import { fileToBase64, getFileSizeUnit, isImage, validAllowedExtesions, validFileSize, validImageSize, } from '../../utils/file.js';
11
11
  import { FILE_EXTENSIONS, TOOLBAR_ALLOWED_EXTENSIONS, TOOLBAR_MAX_SIZE, } from '../../constants/file.js';
12
12
  const FONT_SIZES = [
@@ -76,15 +76,15 @@ const EditorToolbar = ({ handleImageUpload, }) => {
76
76
  const file = files[0];
77
77
  if (!validAllowedExtesions(file, TOOLBAR_ALLOWED_EXTENSIONS)) {
78
78
  const allowedFiles = TOOLBAR_ALLOWED_EXTENSIONS.map((item) => FILE_EXTENSIONS[item].toUpperCase()).join(', ');
79
- Toast.error(`지원하지 않는 파일 형식입니다. ${allowedFiles} 파일만 업로드 가능합니다.`);
79
+ LDToast.error(`지원하지 않는 파일 형식입니다. ${allowedFiles} 파일만 업로드 가능합니다.`);
80
80
  return;
81
81
  }
82
82
  if (!validFileSize(file, TOOLBAR_MAX_SIZE)) {
83
- Toast.error(`파일 크기가 너무 큽니다. ${getFileSizeUnit(TOOLBAR_MAX_SIZE)} 이하 파일을 선택해주세요.`);
83
+ LDToast.error(`파일 크기가 너무 큽니다. ${getFileSizeUnit(TOOLBAR_MAX_SIZE)} 이하 파일을 선택해주세요.`);
84
84
  return;
85
85
  }
86
86
  if (isImage(file.name) && !(await validImageSize(file))) {
87
- Toast.error('이미지 해상도가 너무 큽니다. 더 작은 이미지를 선택해주세요.');
87
+ LDToast.error('이미지 해상도가 너무 큽니다. 더 작은 이미지를 선택해주세요.');
88
88
  return;
89
89
  }
90
90
  try {
@@ -94,13 +94,13 @@ const EditorToolbar = ({ handleImageUpload, }) => {
94
94
  fileName,
95
95
  });
96
96
  if (!res) {
97
- Toast.error('이미지 업로드에 실패했습니다.');
97
+ LDToast.error('이미지 업로드에 실패했습니다.');
98
98
  return;
99
99
  }
100
100
  editor.commands.setImage({ src: res });
101
101
  }
102
102
  catch {
103
- Toast.error('파일 업로드 중 문제가 발생했습니다. 잠시 후 다시 시도해주세요.');
103
+ LDToast.error('파일 업로드 중 문제가 발생했습니다. 잠시 후 다시 시도해주세요.');
104
104
  }
105
105
  };
106
106
  if (!editor || !state)
@@ -0,0 +1,50 @@
1
+ import { Dispatch, type ReactNode, SetStateAction } from 'react';
2
+ import { TMimeType } from '../../constants/file.js';
3
+ import { type LDButtonProps } from '../../components/LDButton/LDButton.js';
4
+ import { IFile } from '../../utils/file.js';
5
+ interface FileUploadContextType {
6
+ recommendedSize?: {
7
+ width: number;
8
+ height: number;
9
+ };
10
+ maxSize: number;
11
+ allowedExtensions: TMimeType[];
12
+ fileList: IFile[];
13
+ setFileList: Dispatch<SetStateAction<IFile[]>>;
14
+ maxFileCount: number;
15
+ }
16
+ export declare const useFileUploadContext: () => FileUploadContextType;
17
+ interface RootProps {
18
+ recommendedSize?: {
19
+ width: number;
20
+ height: number;
21
+ };
22
+ maxSize: number;
23
+ allowedExtensions: TMimeType[];
24
+ fileList: IFile[] | [];
25
+ setFileList: Dispatch<SetStateAction<IFile[] | []>>;
26
+ maxFileCount?: number;
27
+ className?: string;
28
+ children?: ReactNode;
29
+ }
30
+ interface LDInputProps extends LDButtonProps<'button'> {
31
+ onChangeFile: ({ fileName, fileBase64, file, }: {
32
+ fileName: string;
33
+ fileBase64: string;
34
+ file: File;
35
+ }) => Promise<string | void>;
36
+ label?: string;
37
+ }
38
+ export declare const LDFileUploadBase: {
39
+ Root: ({ recommendedSize, maxSize, allowedExtensions, maxFileCount, fileList, setFileList, className, children, }: RootProps) => import("react/jsx-runtime").JSX.Element;
40
+ LDInput: ({ onChangeFile, label, ...props }: LDInputProps) => import("react/jsx-runtime").JSX.Element;
41
+ CardList: ({ emptyContent, className, }: {
42
+ emptyContent?: ReactNode;
43
+ className?: string;
44
+ }) => import("react/jsx-runtime").JSX.Element | null;
45
+ Description: ({ className }: {
46
+ className?: string;
47
+ }) => import("react/jsx-runtime").JSX.Element;
48
+ };
49
+ export default LDFileUploadBase;
50
+ //# sourceMappingURL=LDFileUploadBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LDFileUploadBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDFileUpload/LDFileUploadBase.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,QAAQ,EACR,KAAK,SAAS,EACd,cAAc,EAGf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAmB,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAiB,EACf,KAAK,aAAa,EACnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAGL,KAAK,EAKN,MAAM,kBAAkB,CAAC;AAG1B,UAAU,qBAAqB;IAC7B,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,SAAS,EAAE,CAAC;IAC/B,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,WAAW,EAAE,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC/C,YAAY,EAAE,MAAM,CAAC;CACtB;AAID,eAAO,MAAM,oBAAoB,6BAUhC,CAAC;AAEF,UAAU,SAAS;IACjB,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,SAAS,EAAE,CAAC;IAC/B,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACvB,WAAW,EAAE,QAAQ,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA8BD,UAAU,YAAa,SAAQ,aAAa,CAAC,QAAQ,CAAC;IACpD,YAAY,EAAE,CAAC,EACb,QAAQ,EACR,UAAU,EACV,IAAI,GACL,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,IAAI,CAAC;KACZ,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmJD,eAAO,MAAM,gBAAgB;uHAjL1B,SAAS;iDAoCT,YAAY;6CA2EZ;QACD,YAAY,CAAC,EAAE,SAAS,CAAC;QACzB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;iCA6CmC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;CAuBzD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,102 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { createContext, useContext, } from 'react';
4
+ import cn from '../../utils/cn.js';
5
+ import { FILE_EXTENSIONS } from '../../constants/file.js';
6
+ import LDButton from '../../components/LDButton/LDButton.js';
7
+ import { fileToBase64, getFileSizeUnit, isImage, validAllowedExtesions, validFileSize, validImageSize, } from '../../utils/file.js';
8
+ import LDToast from '../../components/LDToast/LDToast.js';
9
+ const FileUploadContext = createContext(null);
10
+ export const useFileUploadContext = () => {
11
+ const fileUploadContext = useContext(FileUploadContext);
12
+ if (!fileUploadContext) {
13
+ throw new Error('LDFileUploadBase 하위 컴포넌트는 Root 내부에서 사용해야 합니다.');
14
+ }
15
+ return fileUploadContext;
16
+ };
17
+ const Root = ({ recommendedSize, maxSize, allowedExtensions, maxFileCount, fileList, setFileList, className, children, }) => {
18
+ // const [file, setFile] = useState<IFile | null>(null);
19
+ return (_jsx(FileUploadContext.Provider, { value: {
20
+ recommendedSize,
21
+ maxSize,
22
+ allowedExtensions,
23
+ maxFileCount: maxFileCount ?? 1,
24
+ fileList,
25
+ setFileList,
26
+ }, children: _jsx("div", { className: cn('w-full', className), children: children }) }));
27
+ };
28
+ const LDInput = ({ onChangeFile, label = '파일 선택', ...props }) => {
29
+ const { allowedExtensions, maxSize, fileList, setFileList, maxFileCount } = useFileUploadContext();
30
+ const getFileError = async (file) => {
31
+ if (!validAllowedExtesions(file, allowedExtensions)) {
32
+ const allowed = allowedExtensions
33
+ .map((item) => FILE_EXTENSIONS[item].toUpperCase())
34
+ .join(', ');
35
+ return `지원하지 않는 파일 형식입니다. ${allowed} 파일만 업로드 가능합니다.`;
36
+ }
37
+ if (!validFileSize(file, maxSize)) {
38
+ return `파일 크기가 너무 큽니다. ${getFileSizeUnit(maxSize)} 이하 파일을 선택해주세요.`;
39
+ }
40
+ if (isImage(file.name) && !(await validImageSize(file))) {
41
+ return '이미지 해상도가 너무 큽니다. 더 작은 크기의 이미지를 선택해주세요.';
42
+ }
43
+ return null;
44
+ };
45
+ const handleFile = async (e) => {
46
+ const files = e.target.files;
47
+ if (!files)
48
+ return;
49
+ for (const file of files) {
50
+ const error = await getFileError(file);
51
+ if (error) {
52
+ LDToast.error(error);
53
+ return;
54
+ }
55
+ }
56
+ for (const file of files) {
57
+ try {
58
+ const data = await fileToBase64(file);
59
+ const src = await onChangeFile({ ...data, file });
60
+ if (src) {
61
+ setFileList((prev) => [...prev, { ...data, src }]);
62
+ }
63
+ }
64
+ catch (error) {
65
+ if (error instanceof Error) {
66
+ LDToast.error(error.message);
67
+ return;
68
+ }
69
+ LDToast.error('파일 업로드 중 문제가 발생했습니다. 잠시후 다시 시도해주세요.');
70
+ }
71
+ }
72
+ };
73
+ return (_jsxs(LDButton, { as: "label", ...props, children: [label, _jsx("input", { type: "file", multiple: maxFileCount > 1, onClick: (e) => (e.currentTarget.value = ''), onChange: (e) => handleFile(e), className: "sr-only" })] }));
74
+ };
75
+ const CardList = ({ emptyContent, className, }) => {
76
+ /*
77
+ 이미지인 경우
78
+ 이미지가 아닌 파일인 경우
79
+ */
80
+ const { fileList } = useFileUploadContext();
81
+ if (fileList.length <= 0)
82
+ return emptyContent ? _jsx(_Fragment, { children: emptyContent }) : null;
83
+ return (_jsxs(_Fragment, { children: [_jsx(_Fragment, { children: JSON.stringify(fileList, null, 2) }), _jsx(_Fragment, { children: 'length: ' + fileList.length }), _jsx("div", { className: cn('flex flex-row', className), children: fileList?.map((file, idx) => (_jsx("div", { className: "size-12 overflow-hidden", children: _jsx("img", { src: file?.src, alt: file?.fileName, className: "object-cover" }) }, `${file.fileName}_${idx}`))) })] }));
84
+ };
85
+ // const CardList = ({}) => {
86
+ // return <></>;
87
+ // };
88
+ const Description = ({ className }) => {
89
+ const { recommendedSize, maxSize, allowedExtensions } = useFileUploadContext();
90
+ const recommendedSizeText = recommendedSize &&
91
+ `권장 사이즈 ${recommendedSize.width}x${recommendedSize.height}, `;
92
+ const requiredText = `최대 크기 ${getFileSizeUnit(maxSize)}`;
93
+ const extensionsText = ` (${allowedExtensions.map((item) => FILE_EXTENSIONS[item]).join(', ')})`;
94
+ return (_jsxs("p", { className: cn('display14 text-neutral400 semibold', className), children: [recommendedSizeText, requiredText, extensionsText] }));
95
+ };
96
+ export const LDFileUploadBase = {
97
+ Root,
98
+ LDInput,
99
+ CardList,
100
+ Description,
101
+ };
102
+ export default LDFileUploadBase;
@@ -0,0 +1,82 @@
1
+ import type { ElementType, ReactNode } from 'react';
2
+ export interface INavTab {
3
+ label: string;
4
+ path: string;
5
+ icon?: ReactNode;
6
+ isNotScroll?: boolean;
7
+ }
8
+ export interface INavItem {
9
+ label: string;
10
+ tabs?: INavTab[];
11
+ noSlider?: boolean;
12
+ }
13
+ interface ProviderProps {
14
+ children: ReactNode;
15
+ isMobile: boolean;
16
+ items?: INavItem[];
17
+ pathname?: string;
18
+ defaultCollapsed?: boolean;
19
+ }
20
+ interface RootProps {
21
+ children: ReactNode;
22
+ className?: string;
23
+ }
24
+ interface TriggerProps {
25
+ className?: string;
26
+ }
27
+ interface HeaderProps {
28
+ name?: string;
29
+ email?: string;
30
+ profileImage?: string | null;
31
+ handleLogout?: () => void;
32
+ }
33
+ interface ContentProps {
34
+ children: ReactNode;
35
+ className?: string;
36
+ }
37
+ interface GroupProps {
38
+ children: ReactNode;
39
+ label?: string;
40
+ noSlider?: boolean;
41
+ }
42
+ interface MenuProps {
43
+ children: ReactNode;
44
+ label?: string;
45
+ noSlider?: boolean;
46
+ tabCount?: number;
47
+ }
48
+ interface MenuItemProps {
49
+ as?: ElementType;
50
+ href: string;
51
+ isActive?: boolean;
52
+ children: ReactNode;
53
+ icon?: ReactNode;
54
+ className?: string;
55
+ [key: string]: unknown;
56
+ }
57
+ interface MenuSubProps {
58
+ children: ReactNode;
59
+ className?: string;
60
+ }
61
+ interface MenuSubItemProps {
62
+ as?: ElementType;
63
+ href: string;
64
+ isActive?: boolean;
65
+ children: ReactNode;
66
+ className?: string;
67
+ [key: string]: unknown;
68
+ }
69
+ declare const LDLNBBase: {
70
+ Provider: ({ children, isMobile, items, pathname, defaultCollapsed, }: ProviderProps) => import("react/jsx-runtime").JSX.Element;
71
+ Root: ({ children, className }: RootProps) => import("react/jsx-runtime").JSX.Element;
72
+ Trigger: ({ className }: TriggerProps) => import("react/jsx-runtime").JSX.Element | null;
73
+ Header: ({ name, email, profileImage, handleLogout }: HeaderProps) => import("react/jsx-runtime").JSX.Element;
74
+ Content: ({ children, className }: ContentProps) => import("react/jsx-runtime").JSX.Element;
75
+ Group: ({ children, label, noSlider }: GroupProps) => import("react/jsx-runtime").JSX.Element;
76
+ Menu: ({ children, label, noSlider, tabCount }: MenuProps) => import("react/jsx-runtime").JSX.Element;
77
+ MenuItem: ({ as: Comp, href, isActive, children, icon, className, ...rest }: MenuItemProps) => import("react/jsx-runtime").JSX.Element;
78
+ MenuSub: ({ children, className }: MenuSubProps) => import("react/jsx-runtime").JSX.Element | null;
79
+ MenuSubItem: ({ as: Comp, href, isActive, children, className, ...rest }: MenuSubItemProps) => import("react/jsx-runtime").JSX.Element;
80
+ };
81
+ export default LDLNBBase;
82
+ //# sourceMappingURL=LDLNBBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LDLNBBase.d.ts","sourceRoot":"","sources":["../../../src/components/LDLNB/LDLNBBase.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAapD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0BD,UAAU,aAAa;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAyDD,UAAU,SAAS;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAqCD,UAAU,YAAY;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,UAAU,UAAU;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAqCD,UAAU,SAAS;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA6BD,UAAU,aAAa;IACrB,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAiCD,UAAU,YAAY;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD,UAAU,gBAAgB;IACxB,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA2BD,QAAA,MAAM,SAAS;2EA/UZ,aAAa;oCAsDuB,SAAS;6BA6BhB,YAAY;0DA+BiB,WAAW;uCAwC9B,YAAY;2CAsBR,UAAU;oDA0CG,SAAS;iFA6CjE,aAAa;uCA4B0B,YAAY;8EA0BnD,gBAAgB;CA6BlB,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,108 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { createContext, useContext, useEffect, useState } from 'react';
4
+ import { ChevronDown, PanelLeftClose, PanelLeftOpen, LogOut, } from 'lucide-react';
5
+ import cn from '../../utils/cn.js';
6
+ import { isActivePath } from '../../utils/utils.js';
7
+ import LDAvatar from '../LDAvatar/LDAvatar.js';
8
+ const LNBContext = createContext(null);
9
+ const useLNBContext = () => {
10
+ const ctx = useContext(LNBContext);
11
+ if (!ctx)
12
+ throw new Error('LDLNBBase 서브컴포넌트는 LDLNBBase.Provider 내부에서 사용해야 합니다.');
13
+ return ctx;
14
+ };
15
+ const Provider = ({ children, isMobile, items = [], pathname = '', defaultCollapsed = false, }) => {
16
+ const [collapsed, setCollapsed] = useState(defaultCollapsed);
17
+ const [openGroups, setOpenGroups] = useState([]);
18
+ const toggleCollapsed = () => setCollapsed((prev) => !prev);
19
+ const toggleGroup = (label) => {
20
+ setOpenGroups((prev) => prev.includes(label) ? prev.filter((g) => g !== label) : [...prev, label]);
21
+ };
22
+ const isGroupOpen = (label) => openGroups.includes(label);
23
+ useEffect(() => {
24
+ if (!isMobile)
25
+ return;
26
+ if (pathname === '/') {
27
+ setOpenGroups([]);
28
+ return;
29
+ }
30
+ const matchedLabel = items.find((item) => item.tabs?.some((tab) => isActivePath(pathname, tab.path)))?.label;
31
+ if (matchedLabel && !openGroups.includes(matchedLabel)) {
32
+ setOpenGroups((prev) => [...prev, matchedLabel]);
33
+ }
34
+ // 라우트(pathname) 변경 시에만 그룹 펼침을 동기화하려는 의도이므로 다른 의존성은 제외함.
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ }, [pathname]);
37
+ return (_jsx(LNBContext, { value: {
38
+ isMobile,
39
+ collapsed,
40
+ toggleCollapsed,
41
+ openGroups,
42
+ toggleGroup,
43
+ isGroupOpen,
44
+ }, children: children }));
45
+ };
46
+ const Root = ({ children, className }) => {
47
+ const { collapsed } = useLNBContext();
48
+ return (_jsx("div", { className: cn('relative mobile:w-full ld-transition', collapsed ? 'w-[60px]' : 'w-[300px]', className), children: _jsx("div", { className: cn('w-full h-full bg-mono50 mobile:bg-white', 'h-[calc(100vh-64px)] mobile:h-auto mobile:overflow-hidden', 'overflow-y-auto p-sm flex flex-col gap-md mobile:py-0 scrollbar-hide scrollbar-hover'), children: children }) }));
49
+ };
50
+ const Trigger = ({ className }) => {
51
+ const { isMobile, collapsed, toggleCollapsed } = useLNBContext();
52
+ const Icon = collapsed ? PanelLeftOpen : PanelLeftClose;
53
+ if (isMobile)
54
+ return null;
55
+ return (_jsx("button", { type: "button", onClick: toggleCollapsed, className: cn('absolute -right-10 top-0 z-10', 'flex items-center justify-center w-10 h-10', 'text-neutral500', 'hover:text-mono900 ld-transition cursor-pointer', className), "aria-label": collapsed ? '사이드바 펼치기' : '사이드바 접기', children: _jsx(Icon, { size: 16 }) }));
56
+ };
57
+ const Header = ({ name, email, profileImage, handleLogout }) => {
58
+ const { collapsed } = useLNBContext();
59
+ return (_jsxs("div", { className: cn('w-full flex gap-sm items-center rounded-[10px] ld-transition overflow-hidden', collapsed
60
+ ? 'p-xs justify-center border-transparent'
61
+ : 'p-md mobile:p-sm border border-neutral100'), children: [_jsx(LDAvatar, { size: "md", src: profileImage }), !collapsed && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-col gap-xs flex-1 min-w-0", children: [_jsx("span", { className: "display16 bold truncate", children: name ?? '' }), _jsx("span", { className: "display14 text-neutral500 truncate", children: email ?? '' })] }), handleLogout && (_jsx(LogOut, { size: 12, className: "cursor-pointer flex-shrink-0", onClick: handleLogout }))] }))] }));
62
+ };
63
+ const Content = ({ children, className }) => (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-full border-b border-neutral100" }), _jsx("div", { className: cn('flex flex-col gap-md mobile:overflow-y-auto mobile:h-[calc(62dvh-111px)]', className), children: children })] }));
64
+ const Group = ({ children, label, noSlider }) => {
65
+ const { isMobile, collapsed, toggleGroup, isGroupOpen } = useLNBContext();
66
+ const open = label ? isGroupOpen(label) : true;
67
+ return (_jsxs("div", { className: "flex flex-col gap-sm w-full items-start", children: [label && !collapsed && (_jsxs("div", { className: cn('w-full flex', isMobile && 'cursor-pointer justify-between'), onClick: () => !noSlider && isMobile && toggleGroup(label), children: [_jsx("span", { className: "display14 text-neutral500", children: label }), _jsx("div", { className: cn(isMobile &&
68
+ 'transition-transform duration-300 ease-out flex items-center justify-center w-5 h-5 flex-shrink-0', isMobile && open ? 'rotate-180' : 'rotate-0', !isMobile && 'hidden', noSlider && 'hidden'), children: _jsx(ChevronDown, { size: 14, className: "text-neutral500" }) })] })), children] }));
69
+ };
70
+ const Menu = ({ children, label, noSlider, tabCount = 0 }) => {
71
+ const { isMobile, isGroupOpen } = useLNBContext();
72
+ const open = label ? isGroupOpen(label) : true;
73
+ const visible = (label && open) || !label || noSlider;
74
+ return (_jsx("div", { className: cn('flex flex-col w-full gap-sm opacity-100', isMobile && 'overflow-hidden ld-transition', visible ? 'opacity-100' : isMobile && 'opacity-0'), style: {
75
+ height: isMobile
76
+ ? visible
77
+ ? `calc(40px * ${tabCount} + 10px * ${tabCount > 0 ? tabCount - 1 : 0})`
78
+ : '0'
79
+ : 'auto',
80
+ }, children: children }));
81
+ };
82
+ const MenuItem = ({ as: Comp = 'a', href, isActive, children, icon, className, ...rest }) => {
83
+ const { collapsed } = useLNBContext();
84
+ return (_jsxs(Comp, { href: href, className: cn('flex gap-sm w-full items-center p-sm display16 mobile:display14 bold mobile:medium', 'text-neutral500 cursor-pointer hover:bg-mono300 rounded-[5px] hover:text-mono900 ld-transition', collapsed && 'justify-center', isActive &&
85
+ 'bg-tintBlue text-blue400 hover:bg-tintBlue hover:text-blue400', className), ...rest, children: [icon && _jsx("span", { className: "flex-shrink-0", children: icon }), !collapsed && children] }));
86
+ };
87
+ const MenuSub = ({ children, className }) => {
88
+ const { collapsed } = useLNBContext();
89
+ if (collapsed)
90
+ return null;
91
+ return (_jsx("div", { className: cn('flex flex-col w-full gap-sm pl-sm', className), children: children }));
92
+ };
93
+ const MenuSubItem = ({ as: Comp = 'a', href, isActive, children, className, ...rest }) => (_jsx(Comp, { href: href, className: cn('flex gap-sm w-full items-center p-sm display14 medium', 'text-neutral500 cursor-pointer hover:bg-mono300 rounded-[5px] hover:text-mono900 ld-transition', isActive &&
94
+ 'bg-tintBlue text-blue400 hover:bg-tintBlue hover:text-blue400', className), ...rest, children: children }));
95
+ // ── Export ──
96
+ const LDLNBBase = {
97
+ Provider,
98
+ Root,
99
+ Trigger,
100
+ Header,
101
+ Content,
102
+ Group,
103
+ Menu,
104
+ MenuItem,
105
+ MenuSub,
106
+ MenuSubItem,
107
+ };
108
+ export default LDLNBBase;
@@ -0,0 +1,18 @@
1
+ export declare const LDToast: {
2
+ /** 성공 메시지를 표시합니다 */
3
+ success: (content: string) => string;
4
+ /** 에러 메시지를 표시합니다 */
5
+ error: (content: string) => string;
6
+ /** 일반 알림 메시지를 표시합니다 */
7
+ info: (content: string) => string;
8
+ /** 경고 메시지를 표시합니다 */
9
+ warning: (content: string) => string;
10
+ /** 로딩 상태 메시지를 표시합니다 */
11
+ loading: (content: string) => string;
12
+ /** 현재 표시 중인 토스트를 모두 닫습니다 */
13
+ dismiss: () => void;
14
+ /** 인사 메시지를 표시합니다 */
15
+ hello: (content: string) => string;
16
+ };
17
+ export default LDToast;
18
+ //# sourceMappingURL=LDToast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LDToast.d.ts","sourceRoot":"","sources":["../../../src/components/LDToast/LDToast.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO;IAClB,oBAAoB;uBACD,MAAM;IAIzB,oBAAoB;qBACH,MAAM;IAIvB,uBAAuB;oBACP,MAAM;IAItB,oBAAoB;uBACD,MAAM;IAUzB,uBAAuB;uBACJ,MAAM;IAIzB,4BAA4B;;IAE5B,oBAAoB;qBACH,MAAM;CAMxB,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import toast from 'react-hot-toast';
4
+ export const LDToast = {
5
+ /** 성공 메시지를 표시합니다 */
6
+ success: (content) => {
7
+ toast.dismiss();
8
+ return toast.success(content);
9
+ },
10
+ /** 에러 메시지를 표시합니다 */
11
+ error: (content) => {
12
+ toast.dismiss();
13
+ return toast.error(content);
14
+ },
15
+ /** 일반 알림 메시지를 표시합니다 */
16
+ info: (content) => {
17
+ toast.dismiss();
18
+ return toast(content);
19
+ },
20
+ /** 경고 메시지를 표시합니다 */
21
+ warning: (content) => {
22
+ toast.dismiss();
23
+ return toast(content, {
24
+ icon: (_jsx("div", { className: "flex justify-center items-center w-5 h-5 bg-yellow-400 rounded-full text-mono5", children: "!" })),
25
+ });
26
+ },
27
+ /** 로딩 상태 메시지를 표시합니다 */
28
+ loading: (content) => {
29
+ toast.dismiss();
30
+ return toast.loading(content);
31
+ },
32
+ /** 현재 표시 중인 토스트를 모두 닫습니다 */
33
+ dismiss: () => toast.dismiss(),
34
+ /** 인사 메시지를 표시합니다 */
35
+ hello: (content) => {
36
+ toast.dismiss();
37
+ return toast(content, {
38
+ icon: _jsx("div", { className: "flex justify-center items-center w-5 h-5", children: "\uD83D\uDC4B" }),
39
+ });
40
+ },
41
+ };
42
+ export default LDToast;
@@ -0,0 +1,7 @@
1
+ interface LDToasterProps {
2
+ position?: 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
3
+ duration?: number;
4
+ }
5
+ declare const LDToaster: ({ position, duration, }: LDToasterProps) => import("react/jsx-runtime").JSX.Element;
6
+ export default LDToaster;
7
+ //# sourceMappingURL=LDToaster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LDToaster.d.ts","sourceRoot":"","sources":["../../../src/components/LDToast/LDToaster.tsx"],"names":[],"mappings":"AAIA,UAAU,cAAc;IACtB,QAAQ,CAAC,EACL,UAAU,GACV,YAAY,GACZ,WAAW,GACX,aAAa,GACb,eAAe,GACf,cAAc,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,QAAA,MAAM,SAAS,GAAI,yBAGhB,cAAc,4CAEhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,7 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Toaster as HotToaster } from 'react-hot-toast';
4
+ const LDToaster = ({ position = 'top-center', duration = 2500, }) => {
5
+ return _jsx(HotToaster, { position: position, toastOptions: { duration } });
6
+ };
7
+ export default LDToaster;
package/dist/index.d.ts CHANGED
@@ -18,14 +18,14 @@ export { default as LDDivider, type LDDividerProps, } from './components/LDDivid
18
18
  export { default as LDDrawer } from './components/LDDrawer/LDDrawer.js';
19
19
  export { default as LDEditor } from './components/LDEditor/LDEditor.js';
20
20
  export { default as LDViewer } from './components/LDEditor/LDViewer.js';
21
- export { default as FileUploadBase } from './components/FileUpload/FileUploadBase.js';
21
+ export { default as LDFileUploadBase } from './components/LDFileUpload/LDFileUploadBase.js';
22
22
  export { Form, NativeForm } from './components/Form/Form.js';
23
23
  export { default as FormField } from './components/Form/FormField.js';
24
24
  export { default as FormErrorMessage } from './components/Form/FormErrorMessage.js';
25
25
  export { default as LucideIcon } from './components/Icon/LucideIcon.js';
26
26
  export { default as LDInput, type LDInputProps, } from './components/LDInput/LDInput.js';
27
27
  export { default as FormInput } from './components/LDInput/FormInput.js';
28
- export { default as LNBBase } from './components/LNB/LNBBase.js';
28
+ export { default as LDLNBBase } from './components/LDLNB/LDLNBBase.js';
29
29
  export { default as LDLoadingDots } from './components/LDLoadingDots/LDLoadingDots.js';
30
30
  export { default as LDMenuBar } from './components/LDMenuBar/LDMenuBar.js';
31
31
  export { default as LDModal } from './components/LDModal/LDModal.js';
@@ -49,8 +49,8 @@ export { default as LDTanstackTable } from './components/LDTable/LDTanstackTable
49
49
  export { default as TableField } from './components/LDTable/TableField.js';
50
50
  export { default as LDTimePicker } from './components/LDTimePicker/LDTimePicker.js';
51
51
  export { default as FormTimePicker } from './components/LDTimePicker/FormTimePicker.js';
52
- export { default as Toast } from './components/Toast/Toast.js';
53
- export { default as Toaster } from './components/Toast/Toaster.js';
52
+ export { default as LDToast } from './components/LDToast/LDToast.js';
53
+ export { default as LDToaster } from './components/LDToast/LDToaster.js';
54
54
  export { default as LDToggleButton, type LDToggleButtonProps, } from './components/LDToggleButton/LDToggleButton.js';
55
55
  export { default as FormToggleButton } from './components/LDToggleButton/FormToggleButton.js';
56
56
  export { default as LDTooltip } from './components/LDTooltip/LDTooltip.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -34,8 +34,8 @@ export { default as LDDrawer } from './components/LDDrawer/LDDrawer.js';
34
34
  // LDEditor
35
35
  export { default as LDEditor } from './components/LDEditor/LDEditor.js';
36
36
  export { default as LDViewer } from './components/LDEditor/LDViewer.js';
37
- // FileUpload (Base 레이어만 제공)
38
- export { default as FileUploadBase } from './components/FileUpload/FileUploadBase.js';
37
+ // LDFileUpload (Base 레이어만 제공)
38
+ export { default as LDFileUploadBase } from './components/LDFileUpload/LDFileUploadBase.js';
39
39
  // Form
40
40
  export { Form, NativeForm } from './components/Form/Form.js';
41
41
  export { default as FormField } from './components/Form/FormField.js';
@@ -45,8 +45,8 @@ export { default as LucideIcon } from './components/Icon/LucideIcon.js';
45
45
  // LDInput
46
46
  export { default as LDInput, } from './components/LDInput/LDInput.js';
47
47
  export { default as FormInput } from './components/LDInput/FormInput.js';
48
- // LNB (Base 레이어만 제공)
49
- export { default as LNBBase } from './components/LNB/LNBBase.js';
48
+ // LDLNB (Base 레이어만 제공)
49
+ export { default as LDLNBBase } from './components/LDLNB/LDLNBBase.js';
50
50
  // LDLoadingDots
51
51
  export { default as LDLoadingDots } from './components/LDLoadingDots/LDLoadingDots.js';
52
52
  // LDMenuBar
@@ -84,9 +84,9 @@ export { default as TableField } from './components/LDTable/TableField.js';
84
84
  // LDTimePicker
85
85
  export { default as LDTimePicker } from './components/LDTimePicker/LDTimePicker.js';
86
86
  export { default as FormTimePicker } from './components/LDTimePicker/FormTimePicker.js';
87
- // Toast
88
- export { default as Toast } from './components/Toast/Toast.js';
89
- export { default as Toaster } from './components/Toast/Toaster.js';
87
+ // LDToast
88
+ export { default as LDToast } from './components/LDToast/LDToast.js';
89
+ export { default as LDToaster } from './components/LDToast/LDToaster.js';
90
90
  // LDToggleButton
91
91
  export { default as LDToggleButton, } from './components/LDToggleButton/LDToggleButton.js';
92
92
  export { default as FormToggleButton } from './components/LDToggleButton/FormToggleButton.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loword/loword-design-system",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "로워드 디자인 시스템 컴포넌트 패키지(Tailwind v4)",
5
5
  "keywords": [
6
6
  "react",