@yeongseoksong/framework 1.0.2 → 1.2.0
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 +121 -34
- package/dist/types/index.d.mts +8 -1
- package/dist/types/index.d.ts +8 -1
- package/dist/ui/{index.js → index.cjs} +885 -571
- package/dist/ui/index.d.mts +168 -52
- package/dist/ui/index.d.ts +168 -52
- package/dist/ui/index.mjs +759 -500
- package/dist/util/{index.js → index.cjs} +17 -2
- package/dist/util/index.d.mts +12 -1
- package/dist/util/index.d.ts +12 -1
- package/dist/util/index.mjs +14 -1
- package/package.json +27 -12
- /package/dist/types/{index.js → index.cjs} +0 -0
package/README.md
CHANGED
|
@@ -29,9 +29,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
29
29
|
return (
|
|
30
30
|
<html lang="ko">
|
|
31
31
|
<body>
|
|
32
|
-
<MantineProvider theme={theme}>
|
|
33
|
-
{children}
|
|
34
|
-
</MantineProvider>
|
|
32
|
+
<MantineProvider theme={theme}>{children}</MantineProvider>
|
|
35
33
|
</body>
|
|
36
34
|
</html>
|
|
37
35
|
)
|
|
@@ -69,11 +67,56 @@ import './env.mjs'
|
|
|
69
67
|
|
|
70
68
|
## 임포트 경로
|
|
71
69
|
|
|
72
|
-
| 경로
|
|
73
|
-
|
|
74
|
-
| `@yeongseoksong/framework/ui`
|
|
75
|
-
| `@yeongseoksong/framework/util`
|
|
76
|
-
| `@yeongseoksong/framework/types` | 공유 인터페이스
|
|
70
|
+
| 경로 | 내용 |
|
|
71
|
+
| -------------------------------- | --------------------------------------------- |
|
|
72
|
+
| `@yeongseoksong/framework/ui` | UI 컴포넌트 전체 + `theme` (`"use client"`) |
|
|
73
|
+
| `@yeongseoksong/framework/util` | `t()`, `COMPANY_NAME`, `LOGO_SRC`, `LOGO_ALT` |
|
|
74
|
+
| `@yeongseoksong/framework/types` | 공유 인터페이스 |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## ⚠️ Server Component에서는 flat export를 쓰세요
|
|
79
|
+
|
|
80
|
+
`ui` 번들 전체에 `"use client"`가 붙어 있습니다. 서버 컴포넌트가 이를 임포트하면 실제 객체가 아니라 **client reference proxy**를 받으므로, 네임스페이스를 dot 접근하면 `undefined`가 나옵니다.
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
// ❌ 서버 컴포넌트에서 실패
|
|
84
|
+
// Element type is invalid: expected a string ... got: undefined
|
|
85
|
+
import { SdText } from '@yeongseoksong/framework/ui'
|
|
86
|
+
;<SdText.Body>본문</SdText.Body>
|
|
87
|
+
|
|
88
|
+
// ✅ flat export 사용
|
|
89
|
+
import { SdTextBody } from '@yeongseoksong/framework/ui'
|
|
90
|
+
;<SdTextBody>본문</SdTextBody>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
모든 variant에 `Sd<네임스페이스><Variant>` 형태의 flat export가 준비되어 있습니다:
|
|
94
|
+
|
|
95
|
+
| 네임스페이스 | flat export |
|
|
96
|
+
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| `SdText` | `SdTextStrong` `SdTextBody` `SdTextSub` `SdTextEyebrow` `SdTextError` `SdTextHint` `SdTextNumeric` |
|
|
98
|
+
| `SdTitle` | `SdTitleDisplay` `SdTitleSection` `SdTitleCard` `SdTitleSub` |
|
|
99
|
+
| `SdButton` | `SdButtonPrimary` `SdButtonSecondary` `SdButtonOutline` `SdButtonGhost` `SdButtonWhite` `SdButtonSubmit` `SdButtonDelete` `SdButtonCancel` `SdButtonExcel` `SdButtonDownload` |
|
|
100
|
+
| `SdBadge` | `SdBadgeDefault` `SdBadgePrimary` `SdBadgeSuccess` `SdBadgeWarning` |
|
|
101
|
+
| `SdInput` | `SdInputText` `SdInputEmail` `SdInputPassword` `SdInputTextarea` `SdInputSelect` |
|
|
102
|
+
| `SdLink` | `SdLinkStrong` `SdLinkBody` `SdLinkSub` `SdLinkHint` |
|
|
103
|
+
| `SdQuote` | `SdQuotePlain` `SdQuoteCard` |
|
|
104
|
+
| `SdTable` | `SdTableSpec` |
|
|
105
|
+
| `SdTabs` | `SdTabsPills` `SdTabsUnderline` `SdTabsOutline` |
|
|
106
|
+
| `SdSkeleton` | `SdSkeletonCard` `SdSkeletonText` `SdSkeletonTitle` `SdSkeletonImage` `SdSkeletonAvatar` |
|
|
107
|
+
| `SdTextBox` | `SdTextBoxHero` `SdTextBoxSection` `SdTextBoxCard` `SdTextBoxSub` |
|
|
108
|
+
| `SdSteps` | `SdStepsBubble` `SdStepsCard` `SdStepsStrip` |
|
|
109
|
+
| `SdCta` | `SdCtaBanner` `SdCtaSubtle` `SdCtaInline` |
|
|
110
|
+
| `SdFaq` | `SdFaqDefault` `SdFaqFilled` `SdFaqWithHeader` |
|
|
111
|
+
| `SdPricingCard` | `SdPricingCardDefault` `SdPricingCardFeatured` `SdPricingCardGrid` |
|
|
112
|
+
| `SdTestimonial` | `SdTestimonialCard` `SdTestimonialStrip` `SdTestimonialGrid` |
|
|
113
|
+
| `SdSolution` | `SdSolutionFiltered` `SdSolutionList` |
|
|
114
|
+
| `SdSolutionCard` | `SdSolutionCardItem` `SdSolutionCardGrid` |
|
|
115
|
+
| `SdClients` | `SdClientsGrid` `SdClientsMarquee` |
|
|
116
|
+
| `SdMap` | `SdMapSingle` `SdMapTabs` |
|
|
117
|
+
| `SdErrorView` | `SdErrorViewPage` `SdErrorViewNotFound` |
|
|
118
|
+
|
|
119
|
+
**클라이언트 컴포넌트에서는 네임스페이스 형태(`SdText.Body`)를 그대로 써도 됩니다.** `SdModal`은 `opened`/`onClose` 상태가 필요해 애초에 클라이언트 전용이므로 flat export가 없습니다.
|
|
77
120
|
|
|
78
121
|
---
|
|
79
122
|
|
|
@@ -95,14 +138,32 @@ import { SdButton } from '@yeongseoksong/framework/ui'
|
|
|
95
138
|
|
|
96
139
|
// 다크 배경 위
|
|
97
140
|
<SdButton.White>시작하기</SdButton.White>
|
|
141
|
+
```
|
|
98
142
|
|
|
99
|
-
|
|
100
|
-
|
|
143
|
+
**표준 액션 버튼** — 라벨·색·아이콘이 고정되어 있습니다. `children`을 생략하면 기본 라벨이,
|
|
144
|
+
넘기면 그 값이 라벨로 쓰입니다.
|
|
101
145
|
|
|
102
|
-
|
|
103
|
-
|
|
146
|
+
```tsx
|
|
147
|
+
// 아이콘 + 기본 라벨이 자동으로 붙는다
|
|
148
|
+
<SdButton.Submit onClick={handleSubmit} /> {/* 종이비행기 + "전송" */}
|
|
149
|
+
<SdButton.Delete onClick={handleDelete} /> {/* 휴지통 + "삭제" */}
|
|
150
|
+
<SdButton.Cancel onClick={handleClose} /> {/* X + "취소" */}
|
|
151
|
+
<SdButton.Excel onClick={handleExport} /> {/* 스프레드시트 + "엑셀" */}
|
|
152
|
+
<SdButton.Download onClick={handleDownload} /> {/* 다운로드 + "다운로드" */}
|
|
153
|
+
|
|
154
|
+
// 라벨만 다르게 쓰고 싶으면 children으로 덮어쓴다
|
|
155
|
+
<SdButton.Submit>문의 보내기</SdButton.Submit>
|
|
156
|
+
<SdButton.Excel>엑셀 다운로드</SdButton.Excel>
|
|
104
157
|
```
|
|
105
158
|
|
|
159
|
+
| 변형 | 색 | 아이콘 | 기본 라벨 |
|
|
160
|
+
| ---------- | ---------------- | ------------ | --------- |
|
|
161
|
+
| `Submit` | primary (filled) | 종이비행기 | 전송 |
|
|
162
|
+
| `Delete` | red (filled) | 휴지통 | 삭제 |
|
|
163
|
+
| `Cancel` | slate (outline) | X | 취소 |
|
|
164
|
+
| `Excel` | green (outline) | 스프레드시트 | 엑셀 |
|
|
165
|
+
| `Download` | primary (light) | 다운로드 | 다운로드 |
|
|
166
|
+
|
|
106
167
|
### SdText / SdTitle
|
|
107
168
|
|
|
108
169
|
```tsx
|
|
@@ -322,6 +383,9 @@ import type { NavItem, CompanyInfo } from '@yeongseoksong/framework/types'
|
|
|
322
383
|
|
|
323
384
|
const navItems: NavItem[] = [
|
|
324
385
|
{ id: 1, order: 1, isShow: true, label: '소개', href: '/about' },
|
|
386
|
+
// parentId로 하위 항목을 매단다 (헤더 2단 메뉴 · 푸터 링크 컬럼 공용)
|
|
387
|
+
{ id: 11, order: 1, isShow: true, label: '회사소개', href: '/about/company', parentId: 1 },
|
|
388
|
+
{ id: 12, order: 2, isShow: true, label: '연혁', href: '/about/history', parentId: 1 },
|
|
325
389
|
{ id: 2, order: 2, isShow: true, label: '기능', href: '/features' },
|
|
326
390
|
{ id: 3, order: 3, isShow: true, label: '요금제', href: '/pricing' },
|
|
327
391
|
]
|
|
@@ -333,12 +397,35 @@ const company: CompanyInfo = {
|
|
|
333
397
|
tel: '02-0000-0000',
|
|
334
398
|
email: 'hello@example.com',
|
|
335
399
|
copyrightYear: 2024,
|
|
400
|
+
// 소셜 아이콘 — 없으면 하단 바에 렌더되지 않음
|
|
401
|
+
socials: [
|
|
402
|
+
{ platform: 'x', url: 'https://x.com/example' },
|
|
403
|
+
{ platform: 'youtube', url: 'https://youtube.com/@example' },
|
|
404
|
+
],
|
|
336
405
|
}
|
|
337
406
|
|
|
407
|
+
// 하단 바 정책 링크 (NavItem, highlight: true면 강조)
|
|
408
|
+
const policyLinks: NavItem[] = [
|
|
409
|
+
{ id: 1, order: 1, isShow: true, label: '이용약관', href: '/terms' },
|
|
410
|
+
{ id: 2, order: 2, isShow: true, label: '개인정보처리방침', href: '/privacy', highlight: true },
|
|
411
|
+
]
|
|
412
|
+
|
|
338
413
|
<SdHeader navItems={navItems} loginFlag />
|
|
339
|
-
<SdFooter
|
|
414
|
+
<SdFooter
|
|
415
|
+
company={company}
|
|
416
|
+
navItems={navItems}
|
|
417
|
+
policyLinks={policyLinks}
|
|
418
|
+
description="한 줄 브랜드 설명"
|
|
419
|
+
/>
|
|
340
420
|
```
|
|
341
421
|
|
|
422
|
+
`SdHeader`는 데스크톱에서 헤더에 마우스를 올리면(또는 Tab으로 포커스가 들어오면) 헤더가 아래로 확장되며
|
|
423
|
+
`parentId`로 묶인 하위 링크가 각 상위 항목 **바로 아래 컬럼**으로 동시에 노출됩니다. 하위 항목이 하나도 없으면 확장이 일어나지 않습니다.
|
|
424
|
+
상위 항목의 `href`를 비우면 링크 대신 그룹 제목으로 렌더됩니다. 모바일(`< sm`)에서는 버거 드로어의 중첩 아코디언으로 전환됩니다.
|
|
425
|
+
|
|
426
|
+
`navItems`는 같은 `parentId` 구조로 푸터 링크 컬럼도 만들고, 구분선 아래 하단 바에 카피라이트 · `policyLinks` · `company.socials` 아이콘이 놓입니다.
|
|
427
|
+
`socials.platform`은 `x | youtube | instagram | facebook | linkedin | github | blog`를 지원합니다.
|
|
428
|
+
|
|
342
429
|
### MainLayout
|
|
343
430
|
|
|
344
431
|
헤더 + 본문 + 푸터가 포함된 전체 레이아웃입니다.
|
|
@@ -362,7 +449,7 @@ export default function Page() {
|
|
|
362
449
|
```ts
|
|
363
450
|
import { t } from '@yeongseoksong/framework/util'
|
|
364
451
|
|
|
365
|
-
t('%c 서비스')
|
|
452
|
+
t('%c 서비스') // → '내 회사 서비스'
|
|
366
453
|
t('%c에 오신 것을 환영합니다') // → '내 회사에 오신 것을 환영합니다'
|
|
367
454
|
```
|
|
368
455
|
|
|
@@ -376,19 +463,19 @@ t('%c에 오신 것을 환영합니다') // → '내 회사에 오신 것을 환
|
|
|
376
463
|
|
|
377
464
|
```ts
|
|
378
465
|
import type {
|
|
379
|
-
NavItem,
|
|
380
|
-
HeroSlide,
|
|
381
|
-
FeatureItem,
|
|
382
|
-
TimelineEvent,
|
|
383
|
-
SolutionItem,
|
|
384
|
-
StepItem,
|
|
385
|
-
TestimonialItem,
|
|
386
|
-
PricingItem,
|
|
387
|
-
PricingFeature,
|
|
388
|
-
FaqItem,
|
|
389
|
-
ClientItem,
|
|
390
|
-
CompanyInfo,
|
|
391
|
-
CompanyAddress,
|
|
466
|
+
NavItem, // 네비게이션 메뉴
|
|
467
|
+
HeroSlide, // 히어로 캐러셀 슬라이드
|
|
468
|
+
FeatureItem, // 기능 카드
|
|
469
|
+
TimelineEvent, // 연혁 타임라인
|
|
470
|
+
SolutionItem, // 솔루션 카드
|
|
471
|
+
StepItem, // 단계별 안내
|
|
472
|
+
TestimonialItem, // 고객 후기
|
|
473
|
+
PricingItem, // 요금제 플랜
|
|
474
|
+
PricingFeature, // 요금제 항목
|
|
475
|
+
FaqItem, // FAQ
|
|
476
|
+
ClientItem, // 고객사 로고
|
|
477
|
+
CompanyInfo, // 회사 정보 전체
|
|
478
|
+
CompanyAddress, // 회사 주소
|
|
392
479
|
} from '@yeongseoksong/framework/types'
|
|
393
480
|
```
|
|
394
481
|
|
|
@@ -396,11 +483,11 @@ import type {
|
|
|
396
483
|
|
|
397
484
|
## 피어 의존성
|
|
398
485
|
|
|
399
|
-
| 패키지
|
|
400
|
-
|
|
401
|
-
| `@mantine/core`
|
|
402
|
-
| `@mantine/hooks`
|
|
486
|
+
| 패키지 | 버전 |
|
|
487
|
+
| ------------------- | ------ |
|
|
488
|
+
| `@mantine/core` | ^9.2.2 |
|
|
489
|
+
| `@mantine/hooks` | ^9.2.2 |
|
|
403
490
|
| `@mantine/carousel` | ^9.2.2 |
|
|
404
|
-
| `next`
|
|
405
|
-
| `react`
|
|
406
|
-
| `react-dom`
|
|
491
|
+
| `next` | 16.2.2 |
|
|
492
|
+
| `react` | 19.2.4 |
|
|
493
|
+
| `react-dom` | 19.2.4 |
|
package/dist/types/index.d.mts
CHANGED
|
@@ -37,6 +37,12 @@ interface CompanyAddress {
|
|
|
37
37
|
order: number;
|
|
38
38
|
embbedUrl?: string;
|
|
39
39
|
}
|
|
40
|
+
type SocialPlatform = 'x' | 'youtube' | 'instagram' | 'facebook' | 'linkedin' | 'github' | 'blog';
|
|
41
|
+
interface SocialItem {
|
|
42
|
+
platform: SocialPlatform;
|
|
43
|
+
url: string;
|
|
44
|
+
label?: string;
|
|
45
|
+
}
|
|
40
46
|
interface CompanyInfo {
|
|
41
47
|
name: string;
|
|
42
48
|
registrationNumber: string;
|
|
@@ -45,6 +51,7 @@ interface CompanyInfo {
|
|
|
45
51
|
fax?: string;
|
|
46
52
|
email: string;
|
|
47
53
|
copyrightYear: number;
|
|
54
|
+
socials?: SocialItem[];
|
|
48
55
|
}
|
|
49
56
|
interface TimelineEvent extends CommonInfo {
|
|
50
57
|
year: number;
|
|
@@ -95,4 +102,4 @@ interface SolutionItem extends CommonInfo {
|
|
|
95
102
|
icon?: ReactNode;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
|
-
export type { ClientItem, CommonInfo, CompanyAddress, CompanyInfo, FaqItem, FeatureItem, HeroCta, HeroSlide, NavItem, PricingFeature, PricingItem, SolutionItem, StepItem, TestimonialItem, TimelineEvent };
|
|
105
|
+
export type { ClientItem, CommonInfo, CompanyAddress, CompanyInfo, FaqItem, FeatureItem, HeroCta, HeroSlide, NavItem, PricingFeature, PricingItem, SocialItem, SocialPlatform, SolutionItem, StepItem, TestimonialItem, TimelineEvent };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -37,6 +37,12 @@ interface CompanyAddress {
|
|
|
37
37
|
order: number;
|
|
38
38
|
embbedUrl?: string;
|
|
39
39
|
}
|
|
40
|
+
type SocialPlatform = 'x' | 'youtube' | 'instagram' | 'facebook' | 'linkedin' | 'github' | 'blog';
|
|
41
|
+
interface SocialItem {
|
|
42
|
+
platform: SocialPlatform;
|
|
43
|
+
url: string;
|
|
44
|
+
label?: string;
|
|
45
|
+
}
|
|
40
46
|
interface CompanyInfo {
|
|
41
47
|
name: string;
|
|
42
48
|
registrationNumber: string;
|
|
@@ -45,6 +51,7 @@ interface CompanyInfo {
|
|
|
45
51
|
fax?: string;
|
|
46
52
|
email: string;
|
|
47
53
|
copyrightYear: number;
|
|
54
|
+
socials?: SocialItem[];
|
|
48
55
|
}
|
|
49
56
|
interface TimelineEvent extends CommonInfo {
|
|
50
57
|
year: number;
|
|
@@ -95,4 +102,4 @@ interface SolutionItem extends CommonInfo {
|
|
|
95
102
|
icon?: ReactNode;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
|
-
export type { ClientItem, CommonInfo, CompanyAddress, CompanyInfo, FaqItem, FeatureItem, HeroCta, HeroSlide, NavItem, PricingFeature, PricingItem, SolutionItem, StepItem, TestimonialItem, TimelineEvent };
|
|
105
|
+
export type { ClientItem, CommonInfo, CompanyAddress, CompanyInfo, FaqItem, FeatureItem, HeroCta, HeroSlide, NavItem, PricingFeature, PricingItem, SocialItem, SocialPlatform, SolutionItem, StepItem, TestimonialItem, TimelineEvent };
|