@roottale/cms-renderer-next 0.51.1 → 0.53.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/CHANGELOG.md +96 -0
- package/README.md +54 -4
- package/dist/{chunk-U2IM6OCQ.js → chunk-HM5VP7SR.js} +1 -1
- package/dist/{chunk-U2IM6OCQ.js.map → chunk-HM5VP7SR.js.map} +1 -1
- package/dist/chunk-KSPPYX22.js +14 -0
- package/dist/chunk-KSPPYX22.js.map +1 -0
- package/dist/cms-public.css +46 -0
- package/dist/routes.d.ts +25 -1
- package/dist/routes.js +72 -14
- package/dist/routes.js.map +1 -1
- package/dist/section-runtime.d.ts +46 -0
- package/dist/section-runtime.js +9 -0
- package/dist/server.d.ts +5 -3
- package/dist/server.js +1679 -34
- package/dist/server.js.map +1 -1
- package/package.json +7 -23
- package/dist/before-after-client.d.ts +0 -15
- package/dist/before-after-client.js +0 -8
- package/dist/chunk-27RT6B3O.js +0 -93
- package/dist/chunk-27RT6B3O.js.map +0 -1
- package/dist/chunk-2QU4JU46.js +0 -3927
- package/dist/chunk-2QU4JU46.js.map +0 -1
- package/dist/chunk-4RQ3SEDL.js +0 -106
- package/dist/chunk-4RQ3SEDL.js.map +0 -1
- package/dist/chunk-6GQCFFHU.js +0 -540
- package/dist/chunk-6GQCFFHU.js.map +0 -1
- package/dist/chunk-H46JUIHZ.js +0 -79
- package/dist/chunk-H46JUIHZ.js.map +0 -1
- package/dist/chunk-K62RR4UQ.js +0 -53
- package/dist/chunk-K62RR4UQ.js.map +0 -1
- package/dist/chunk-LEHHSI6G.js +0 -64
- package/dist/chunk-LEHHSI6G.js.map +0 -1
- package/dist/chunk-QYNEOFL7.js +0 -418
- package/dist/chunk-QYNEOFL7.js.map +0 -1
- package/dist/chunk-U5AKACPN.js +0 -113
- package/dist/chunk-U5AKACPN.js.map +0 -1
- package/dist/chunk-UM37DOIK.js +0 -961
- package/dist/chunk-UM37DOIK.js.map +0 -1
- package/dist/chunk-YLSQAT6B.js +0 -59
- package/dist/chunk-YLSQAT6B.js.map +0 -1
- package/dist/chunk-ZL2NA3QT.js +0 -313
- package/dist/chunk-ZL2NA3QT.js.map +0 -1
- package/dist/concerns-client.d.ts +0 -12
- package/dist/concerns-client.js +0 -8
- package/dist/concerns-client.js.map +0 -1
- package/dist/contact-map-client.d.ts +0 -27
- package/dist/contact-map-client.js +0 -8
- package/dist/contact-map-client.js.map +0 -1
- package/dist/expertise-client.d.ts +0 -16
- package/dist/expertise-client.js +0 -9
- package/dist/expertise-client.js.map +0 -1
- package/dist/hero-carousel-client.d.ts +0 -52
- package/dist/hero-carousel-client.js +0 -9
- package/dist/hero-carousel-client.js.map +0 -1
- package/dist/seo-checks.d.ts +0 -87
- package/dist/seo-checks.js +0 -27
- package/dist/seo-checks.js.map +0 -1
- package/dist/site-config-BvUyDx_f.d.ts +0 -3961
- package/dist/spaces-client.d.ts +0 -10
- package/dist/spaces-client.js +0 -8
- package/dist/spaces-client.js.map +0 -1
- package/dist/team-expanding-stage-client.d.ts +0 -35
- package/dist/team-expanding-stage-client.js +0 -8
- package/dist/team-expanding-stage-client.js.map +0 -1
- package/dist/templates.css +0 -4145
- package/dist/templates.d.ts +0 -171
- package/dist/templates.js +0 -291
- package/dist/templates.js.map +0 -1
- package/dist/theme-css-vars-CD3jcEkp.d.ts +0 -7
- package/dist/ui-react-motion-client.d.ts +0 -76
- package/dist/ui-react-motion-client.js +0 -16
- package/dist/ui-react-motion-client.js.map +0 -1
- package/dist/validate.d.ts +0 -104
- package/dist/validate.js +0 -1204
- package/dist/validate.js.map +0 -1
- /package/dist/{before-after-client.js.map → section-runtime.js.map} +0 -0
package/dist/templates.d.ts
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { C as ConcernsSection, E as ExpertiseSection, S as SpacesSection, H as HeroSection, R as RichTextSection, a as ServicesSection, F as FooterSection, b as FaqSection, c as CtaBannerSection, d as TrustSection, e as TestimonialsSection, T as TeamSection, f as ContactSection, g as HoursSection, P as PricingSection, h as ProcessSection, B as BeforeAfterSection, i as SiteConfig, j as SiteConfigInput } from './site-config-BvUyDx_f.js';
|
|
2
|
-
export { k as BUILTIN_SECTION_SCHEMAS, l as BUILTIN_SECTION_TYPES, m as BeforeAfterSectionSchema, n as BlogListSection, o as BlogListSectionSchema, p as ConcernsSectionSchema, q as ContactSectionSchema, r as CtaBannerSectionSchema, s as CustomSection, t as CustomSectionSchema, u as ExpertiseSectionSchema, v as FaqSectionSchema, w as FooterSectionSchema, x as HeroSectionSchema, y as HoursSectionSchema, L as LeadFormSection, z as LeadFormSectionSchema, N as NavItem, A as NavItemSchema, D as PricingSectionSchema, G as ProcessSectionSchema, I as RichTextSectionSchema, J as SECTION_VARIANTS, K as Section, M as SectionCta, O as SectionInput, Q as SectionSchema, U as ServicesSectionSchema, V as SiteConfigSchema, W as SpacesSectionSchema, X as TeamSectionSchema, Y as TestimonialsSectionSchema, Z as TrustSectionSchema, _ as defineSiteConfig, $ as parseSiteConfig } from './site-config-BvUyDx_f.js';
|
|
3
|
-
export { R as RootTaleCssVars, t as themeToCssVars } from './theme-css-vars-CD3jcEkp.js';
|
|
4
|
-
import { ReactElement, CSSProperties, ReactNode } from 'react';
|
|
5
|
-
import { CmsPostContent } from '@roottale/cms-client/server';
|
|
6
|
-
import 'zod';
|
|
7
|
-
import '@roottale/ui-react/theme';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* `SiteConfig` 계약 버전 (ADR-0086 D2 — 팩 ↔ renderer 호환성 계약).
|
|
11
|
-
*
|
|
12
|
-
* `site-config.ts` 는 이미 SIZE_OK 상한 근처(canonical SectionSchema
|
|
13
|
-
* registry)라 버전 해석 로직은 별도 모듈에 두고 `site-config.ts` 에서
|
|
14
|
-
* re-export 한다.
|
|
15
|
-
*
|
|
16
|
-
* 팩 manifest(`packages/assembly/src/pack-manifest.ts`)의
|
|
17
|
-
* `siteConfigVersion` 필드가 이 버전과 비교 대상 — 팩이 요구하는 버전이
|
|
18
|
-
* renderer 가 실제로 해석하는 버전보다 높으면 조립 전 fail-fast 해야 한다.
|
|
19
|
-
*/
|
|
20
|
-
/** 현재 `SiteConfig` 스키마 버전. 계약 필드 추가 등 breaking 변경 시에만 올린다. */
|
|
21
|
-
declare const SITE_CONFIG_SCHEMA_VERSION = 1;
|
|
22
|
-
/**
|
|
23
|
-
* `config.schemaVersion` 해석 헬퍼 — 필드 미지정(기존 고객
|
|
24
|
-
* `site.config.ts`, `schemaVersion` 도입 이전 작성분)은 버전 1 로 해석한다
|
|
25
|
-
* (하위 호환, ADR-0086 D2). 현재 버전 상수가 아니라 리터럴 1 — 후일
|
|
26
|
-
* `SITE_CONFIG_SCHEMA_VERSION` 이 올라도 미지정 config 는 계속 1 이다.
|
|
27
|
-
*/
|
|
28
|
-
declare function resolveSiteConfigSchemaVersion(config: {
|
|
29
|
-
schemaVersion?: number;
|
|
30
|
-
}): number;
|
|
31
|
-
|
|
32
|
-
declare function TemplateExpertise(section: ExpertiseSection): ReactElement;
|
|
33
|
-
declare function TemplateSpaces(section: SpacesSection): ReactElement;
|
|
34
|
-
declare function TemplateConcerns(section: ConcernsSection): ReactElement;
|
|
35
|
-
|
|
36
|
-
/** 빌트인 `hero`. variant: split(기본) / image / minimal / carousel. */
|
|
37
|
-
declare function TemplateHero(section: HeroSection): ReactElement;
|
|
38
|
-
|
|
39
|
-
declare function TemplateRichText(section: RichTextSection): ReactElement;
|
|
40
|
-
|
|
41
|
-
declare function TemplateServices(section: ServicesSection): ReactElement;
|
|
42
|
-
|
|
43
|
-
declare function TemplateFooter(section: FooterSection): ReactElement;
|
|
44
|
-
|
|
45
|
-
/** 빌트인 `faq`. `<details>` 0 JS + FAQPage JSON-LD (기본 on). */
|
|
46
|
-
declare function TemplateFaq(section: FaqSection): ReactElement;
|
|
47
|
-
|
|
48
|
-
/** 빌트인 `cta-banner`. variant: default(기본) / photo-overlay. */
|
|
49
|
-
declare function TemplateCtaBanner(section: CtaBannerSection): ReactElement;
|
|
50
|
-
|
|
51
|
-
declare function TemplateTrust(section: TrustSection): ReactElement;
|
|
52
|
-
|
|
53
|
-
declare function TemplateTestimonials(section: TestimonialsSection): ReactElement;
|
|
54
|
-
|
|
55
|
-
declare function TemplateTeam(section: TeamSection): ReactElement;
|
|
56
|
-
|
|
57
|
-
declare function TemplateContact(section: ContactSection): ReactElement;
|
|
58
|
-
|
|
59
|
-
declare function TemplateHours(section: HoursSection): ReactElement;
|
|
60
|
-
|
|
61
|
-
declare function TemplatePricing(section: PricingSection): ReactElement;
|
|
62
|
-
|
|
63
|
-
declare function TemplateProcess(section: ProcessSection): ReactElement;
|
|
64
|
-
|
|
65
|
-
declare function TemplateBeforeAfter(section: BeforeAfterSection): ReactElement;
|
|
66
|
-
|
|
67
|
-
declare function sectionThemeStyle(theme: Record<string, string> | undefined): CSSProperties | undefined;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* `SiteRenderer` — `SiteConfig.pages[path]` 섹션 배열을 registry 로 렌더.
|
|
71
|
-
*
|
|
72
|
-
* ADR-0040 P2 + P0.5 RFC §①:
|
|
73
|
-
* - 빌트인 registry + 클라 주입 `customSections` 머지. **빌트인이 우선** —
|
|
74
|
-
* 클라가 빌트인 type 을 가로채 계약이 갈라지는 것 방지 (고유 섹션은 고유
|
|
75
|
-
* type 으로).
|
|
76
|
-
* - **render-prop 금지**: 임의 JSX escape hatch 는 customSections registry 로만.
|
|
77
|
-
* - **admin preview parity**: admin draft/preview 도 동일 `SiteRenderer` + 동일
|
|
78
|
-
* 빌트인 registry 를 탄다. customSections 는 클라 repo 자산 — preview 에선
|
|
79
|
-
* 미주입 → `unknownSection: "placeholder"` 로 skeleton 표시.
|
|
80
|
-
* - cms-bound 섹션(blog-list/lead-form)은 `RootTaleBlogList`/`RootTaleLeadForm`
|
|
81
|
-
* 위임 (단방향: templates → renderer 코어).
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
/** customSections registry 컴포넌트 계약 (RFC §①). */
|
|
85
|
-
type SectionComponent = (p: {
|
|
86
|
-
id?: string;
|
|
87
|
-
props: Record<string, unknown>;
|
|
88
|
-
variant?: string;
|
|
89
|
-
theme?: Record<string, string>;
|
|
90
|
-
}) => ReactNode;
|
|
91
|
-
interface SiteRendererProps {
|
|
92
|
-
/** `defineSiteConfig()` 결과 또는 raw config (내부에서 검증). */
|
|
93
|
-
config: SiteConfig | SiteConfigInput;
|
|
94
|
-
/** 현재 페이지 경로 — `config.pages` 의 key ("/", "/services", …). */
|
|
95
|
-
path: string;
|
|
96
|
-
/** cms-bound 섹션(blog-list/lead-form 의 theme fetch) 위임용. 서버 전용. */
|
|
97
|
-
apiKey: string;
|
|
98
|
-
/** self-host 등 API base override (`ROOTTALE_API_BASE`). */
|
|
99
|
-
baseUrl?: string;
|
|
100
|
-
/** 클라 repo 고유 섹션 registry (escape hatch). 빌트인 type 은 가로챌 수 없음. */
|
|
101
|
-
customSections?: Record<string, SectionComponent>;
|
|
102
|
-
/**
|
|
103
|
-
* registry 에 없는 type 처리. 기본 "warn-dev" = dev 에서 경고 박스, prod 에서
|
|
104
|
-
* 생략. admin preview 는 "placeholder" (customSections 미주입 환경).
|
|
105
|
-
*/
|
|
106
|
-
unknownSection?: "warn-dev" | "placeholder" | "ignore";
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* 한 페이지의 섹션 배열을 순서대로 렌더.
|
|
110
|
-
*
|
|
111
|
-
* ```tsx
|
|
112
|
-
* // app/services/page.tsx
|
|
113
|
-
* import config from "@/site.config";
|
|
114
|
-
* import { SiteRenderer } from "@roottale/cms-renderer-next/templates";
|
|
115
|
-
*
|
|
116
|
-
* export default function ServicesPage() {
|
|
117
|
-
* return (
|
|
118
|
-
* <SiteRenderer config={config} path="/services"
|
|
119
|
-
* apiKey={process.env.ROOTTALE_API_KEY!} />
|
|
120
|
-
* );
|
|
121
|
-
* }
|
|
122
|
-
* ```
|
|
123
|
-
*/
|
|
124
|
-
declare function SiteRenderer(props: SiteRendererProps): ReactElement;
|
|
125
|
-
|
|
126
|
-
declare function registerSectionTemplates(): void;
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* 섹션 렌더러 주입 지점 — ADR-0040 P2 단방향 계약(코어 ◄ templates).
|
|
130
|
-
*
|
|
131
|
-
* 본문(tiptap) 안의 `section` 노드는 `templates/` 의 컴포넌트로 그려야 하는데,
|
|
132
|
-
* 코어가 `templates/` 를 직접 import 하면 P3+ `site-kit` 분리 시 순환·번들
|
|
133
|
-
* 오염이 된다(dependency-cruiser `no-renderer-core-to-templates`). 그래서 코어는
|
|
134
|
-
* "섹션을 그리는 함수" 의 자리만 비워두고, `@roottale/cms-renderer-next/templates`
|
|
135
|
-
* 를 import 하는 쪽에서 채운다(그 배럴이 로드 시 자동 등록).
|
|
136
|
-
*
|
|
137
|
-
* 등록 없이 `section` 노드를 만나면 dev 경고 후 skip — 미지 섹션 타입을 만났을
|
|
138
|
-
* 때와 같은 fail-soft 동작이다.
|
|
139
|
-
*/
|
|
140
|
-
|
|
141
|
-
/** 발행 API 호출에 필요한 최소 컨텍스트(공개 키 + 베이스 URL). */
|
|
142
|
-
type CmsBoundContext = {
|
|
143
|
-
apiKey: string;
|
|
144
|
-
baseUrl?: string;
|
|
145
|
-
};
|
|
146
|
-
type BlogListProps = {
|
|
147
|
-
apiKey: string;
|
|
148
|
-
baseUrl?: string;
|
|
149
|
-
limit?: number;
|
|
150
|
-
emptyMessage?: string;
|
|
151
|
-
postHref?: (post: CmsPostContent) => string;
|
|
152
|
-
};
|
|
153
|
-
type SectionRenderContext = {
|
|
154
|
-
cms: CmsBoundContext | null;
|
|
155
|
-
renderBlogList: (props: BlogListProps) => ReactNode;
|
|
156
|
-
isDev: () => boolean;
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* `section` 노드 → 템플릿 컴포넌트 매핑. ADR-0040 P2 단방향 계약에 따라 코어가
|
|
161
|
-
* 아니라 templates 계층에 산다 — 코어(`section-render-context.ts`)는 이 함수의
|
|
162
|
-
* 자리만 비워두고, templates 배럴이 로드되며 주입한다.
|
|
163
|
-
*/
|
|
164
|
-
|
|
165
|
-
type TiptapNode = {
|
|
166
|
-
type?: string;
|
|
167
|
-
attrs?: Record<string, unknown>;
|
|
168
|
-
};
|
|
169
|
-
declare function renderSectionNode(node: TiptapNode, key: number, context: SectionRenderContext): ReactElement | null;
|
|
170
|
-
|
|
171
|
-
export { BeforeAfterSection, ConcernsSection, ContactSection, CtaBannerSection, ExpertiseSection, FaqSection, FooterSection, HeroSection, HoursSection, PricingSection, ProcessSection, RichTextSection, SITE_CONFIG_SCHEMA_VERSION, type SectionComponent, ServicesSection, SiteConfig, SiteConfigInput, SiteRenderer, type SiteRendererProps, SpacesSection, TeamSection, TemplateBeforeAfter, TemplateConcerns, TemplateContact, TemplateCtaBanner, TemplateExpertise, TemplateFaq, TemplateFooter, TemplateHero, TemplateHours, TemplatePricing, TemplateProcess, TemplateRichText, TemplateServices, TemplateSpaces, TemplateTeam, TemplateTestimonials, TemplateTrust, TestimonialsSection, TrustSection, registerSectionTemplates, renderSectionNode, resolveSiteConfigSchemaVersion, sectionThemeStyle };
|
package/dist/templates.js
DELETED
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RootTaleBlogList,
|
|
3
|
-
RootTaleLeadForm,
|
|
4
|
-
TemplateBeforeAfter,
|
|
5
|
-
TemplateConcerns,
|
|
6
|
-
TemplateContact,
|
|
7
|
-
TemplateCtaBanner,
|
|
8
|
-
TemplateExpertise,
|
|
9
|
-
TemplateFaq,
|
|
10
|
-
TemplateFooter,
|
|
11
|
-
TemplateHero,
|
|
12
|
-
TemplateHours,
|
|
13
|
-
TemplatePricing,
|
|
14
|
-
TemplateProcess,
|
|
15
|
-
TemplateRichText,
|
|
16
|
-
TemplateServices,
|
|
17
|
-
TemplateSpaces,
|
|
18
|
-
TemplateTeam,
|
|
19
|
-
TemplateTestimonials,
|
|
20
|
-
TemplateTrust,
|
|
21
|
-
registerSectionTemplates,
|
|
22
|
-
renderSectionNode,
|
|
23
|
-
sectionThemeStyle,
|
|
24
|
-
themeToCssVars
|
|
25
|
-
} from "./chunk-2QU4JU46.js";
|
|
26
|
-
import "./chunk-VG6UUF4D.js";
|
|
27
|
-
import "./chunk-QYNEOFL7.js";
|
|
28
|
-
import "./chunk-U5AKACPN.js";
|
|
29
|
-
import "./chunk-LEHHSI6G.js";
|
|
30
|
-
import "./chunk-27RT6B3O.js";
|
|
31
|
-
import "./chunk-YLSQAT6B.js";
|
|
32
|
-
import "./chunk-4RQ3SEDL.js";
|
|
33
|
-
import "./chunk-K62RR4UQ.js";
|
|
34
|
-
import "./chunk-H46JUIHZ.js";
|
|
35
|
-
import "./chunk-ZL2NA3QT.js";
|
|
36
|
-
import "./chunk-U2IM6OCQ.js";
|
|
37
|
-
import {
|
|
38
|
-
BUILTIN_SECTION_SCHEMAS,
|
|
39
|
-
BUILTIN_SECTION_TYPES,
|
|
40
|
-
BeforeAfterSectionSchema,
|
|
41
|
-
BlogListSectionSchema,
|
|
42
|
-
ConcernsSectionSchema,
|
|
43
|
-
ContactSectionSchema,
|
|
44
|
-
CtaBannerSectionSchema,
|
|
45
|
-
CustomSectionSchema,
|
|
46
|
-
ExpertiseSectionSchema,
|
|
47
|
-
FaqSectionSchema,
|
|
48
|
-
FooterSectionSchema,
|
|
49
|
-
HeroSectionSchema,
|
|
50
|
-
HoursSectionSchema,
|
|
51
|
-
LeadFormSectionSchema,
|
|
52
|
-
NavItemSchema,
|
|
53
|
-
PricingSectionSchema,
|
|
54
|
-
ProcessSectionSchema,
|
|
55
|
-
RichTextSectionSchema,
|
|
56
|
-
SECTION_VARIANTS,
|
|
57
|
-
SITE_CONFIG_SCHEMA_VERSION,
|
|
58
|
-
SectionSchema,
|
|
59
|
-
ServicesSectionSchema,
|
|
60
|
-
SiteConfigSchema,
|
|
61
|
-
SpacesSectionSchema,
|
|
62
|
-
TeamSectionSchema,
|
|
63
|
-
TestimonialsSectionSchema,
|
|
64
|
-
TrustSectionSchema,
|
|
65
|
-
defineSiteConfig,
|
|
66
|
-
parseSiteConfig,
|
|
67
|
-
resolveSiteConfigSchemaVersion
|
|
68
|
-
} from "./chunk-UM37DOIK.js";
|
|
69
|
-
|
|
70
|
-
// src/templates/SiteRenderer.tsx
|
|
71
|
-
import {
|
|
72
|
-
Fragment
|
|
73
|
-
} from "react";
|
|
74
|
-
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
75
|
-
function isDev() {
|
|
76
|
-
const env = globalThis.process?.env ?? {};
|
|
77
|
-
return env.NODE_ENV !== "production";
|
|
78
|
-
}
|
|
79
|
-
function UnknownSection({
|
|
80
|
-
type,
|
|
81
|
-
mode
|
|
82
|
-
}) {
|
|
83
|
-
if (mode === "ignore") return null;
|
|
84
|
-
if (mode === "placeholder") {
|
|
85
|
-
return /* @__PURE__ */ jsx(
|
|
86
|
-
"section",
|
|
87
|
-
{
|
|
88
|
-
"data-roottale-tpl": "placeholder",
|
|
89
|
-
className: "rt-tpl-section rt-tpl-placeholder",
|
|
90
|
-
"aria-hidden": true,
|
|
91
|
-
children: /* @__PURE__ */ jsx("div", { className: "rt-tpl-container", children: /* @__PURE__ */ jsx("div", { className: "rt-tpl-placeholder-box", children: type }) })
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
if (!isDev()) return null;
|
|
96
|
-
const style = {
|
|
97
|
-
padding: "1rem",
|
|
98
|
-
border: "1px dashed #c00",
|
|
99
|
-
color: "#c00"
|
|
100
|
-
};
|
|
101
|
-
return /* @__PURE__ */ jsxs("div", { style, children: [
|
|
102
|
-
"\uC54C \uC218 \uC5C6\uB294 \uC139\uC158 type: ",
|
|
103
|
-
/* @__PURE__ */ jsx("code", { children: type }),
|
|
104
|
-
" \u2014 SiteRenderer \uC758 customSections \uC5D0 \uB4F1\uB85D\uD558\uC138\uC694."
|
|
105
|
-
] });
|
|
106
|
-
}
|
|
107
|
-
function renderBuiltin(section, ctx) {
|
|
108
|
-
switch (section.type) {
|
|
109
|
-
case "hero":
|
|
110
|
-
return /* @__PURE__ */ jsx(TemplateHero, { ...section });
|
|
111
|
-
case "rich-text":
|
|
112
|
-
return /* @__PURE__ */ jsx(TemplateRichText, { ...section });
|
|
113
|
-
case "services":
|
|
114
|
-
return /* @__PURE__ */ jsx(TemplateServices, { ...section });
|
|
115
|
-
case "faq":
|
|
116
|
-
return /* @__PURE__ */ jsx(TemplateFaq, { ...section });
|
|
117
|
-
case "footer":
|
|
118
|
-
return /* @__PURE__ */ jsx(TemplateFooter, { ...section });
|
|
119
|
-
case "cta-banner":
|
|
120
|
-
return /* @__PURE__ */ jsx(TemplateCtaBanner, { ...section });
|
|
121
|
-
case "blog-list": {
|
|
122
|
-
const s = section;
|
|
123
|
-
const base = s.props.blogBasePath ?? "/blog";
|
|
124
|
-
return /* @__PURE__ */ jsx(
|
|
125
|
-
"section",
|
|
126
|
-
{
|
|
127
|
-
"data-roottale-tpl": "blog-list",
|
|
128
|
-
"data-roottale-cms": "list",
|
|
129
|
-
id: s.id,
|
|
130
|
-
className: "rt-tpl-section rt-tpl-blog-list",
|
|
131
|
-
style: sectionThemeStyle(s.theme),
|
|
132
|
-
children: /* @__PURE__ */ jsxs("div", { className: "rt-tpl-container", children: [
|
|
133
|
-
s.props.heading ? /* @__PURE__ */ jsx("h2", { className: "rt-tpl-heading", children: s.props.heading }) : null,
|
|
134
|
-
/* @__PURE__ */ jsx(
|
|
135
|
-
RootTaleBlogList,
|
|
136
|
-
{
|
|
137
|
-
apiKey: ctx.apiKey,
|
|
138
|
-
baseUrl: ctx.baseUrl,
|
|
139
|
-
limit: s.props.limit,
|
|
140
|
-
emptyMessage: s.props.emptyMessage,
|
|
141
|
-
postHref: (post) => `${base}/${post.slug}`
|
|
142
|
-
}
|
|
143
|
-
)
|
|
144
|
-
] })
|
|
145
|
-
}
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
case "lead-form": {
|
|
149
|
-
const s = section;
|
|
150
|
-
return /* @__PURE__ */ jsx(
|
|
151
|
-
"section",
|
|
152
|
-
{
|
|
153
|
-
"data-roottale-tpl": "lead-form",
|
|
154
|
-
"data-roottale-cms": "lead-form",
|
|
155
|
-
id: s.id,
|
|
156
|
-
className: "rt-tpl-section rt-tpl-lead-form",
|
|
157
|
-
style: sectionThemeStyle(s.theme),
|
|
158
|
-
children: /* @__PURE__ */ jsx("div", { className: "rt-tpl-container", children: /* @__PURE__ */ jsx(
|
|
159
|
-
RootTaleLeadForm,
|
|
160
|
-
{
|
|
161
|
-
action: s.props.action,
|
|
162
|
-
vertical: s.props.vertical,
|
|
163
|
-
heading: s.props.heading,
|
|
164
|
-
description: s.props.description,
|
|
165
|
-
submitLabel: s.props.submitLabel
|
|
166
|
-
}
|
|
167
|
-
) })
|
|
168
|
-
}
|
|
169
|
-
);
|
|
170
|
-
}
|
|
171
|
-
case "trust":
|
|
172
|
-
return /* @__PURE__ */ jsx(TemplateTrust, { ...section });
|
|
173
|
-
case "contact":
|
|
174
|
-
return /* @__PURE__ */ jsx(TemplateContact, { ...section });
|
|
175
|
-
case "hours":
|
|
176
|
-
return /* @__PURE__ */ jsx(TemplateHours, { ...section });
|
|
177
|
-
case "pricing":
|
|
178
|
-
return /* @__PURE__ */ jsx(TemplatePricing, { ...section });
|
|
179
|
-
case "process":
|
|
180
|
-
return /* @__PURE__ */ jsx(TemplateProcess, { ...section });
|
|
181
|
-
case "before-after":
|
|
182
|
-
return /* @__PURE__ */ jsx(TemplateBeforeAfter, { ...section });
|
|
183
|
-
case "testimonials":
|
|
184
|
-
return /* @__PURE__ */ jsx(TemplateTestimonials, { ...section });
|
|
185
|
-
case "expertise":
|
|
186
|
-
return /* @__PURE__ */ jsx(TemplateExpertise, { ...section });
|
|
187
|
-
case "spaces":
|
|
188
|
-
return /* @__PURE__ */ jsx(TemplateSpaces, { ...section });
|
|
189
|
-
case "concerns":
|
|
190
|
-
return /* @__PURE__ */ jsx(TemplateConcerns, { ...section });
|
|
191
|
-
case "team":
|
|
192
|
-
return /* @__PURE__ */ jsx(TemplateTeam, { ...section });
|
|
193
|
-
default:
|
|
194
|
-
return void 0;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
function SiteRenderer(props) {
|
|
198
|
-
const {
|
|
199
|
-
path,
|
|
200
|
-
apiKey,
|
|
201
|
-
baseUrl,
|
|
202
|
-
customSections = {},
|
|
203
|
-
unknownSection = "warn-dev"
|
|
204
|
-
} = props;
|
|
205
|
-
const config = parseSiteConfig(props.config);
|
|
206
|
-
const sections = config.pages[path] ?? [];
|
|
207
|
-
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
208
|
-
sections.length === 0 ? /* @__PURE__ */ jsx(
|
|
209
|
-
UnknownSection,
|
|
210
|
-
{
|
|
211
|
-
type: `pages["${path}"] (\uC139\uC158 0\uAC1C)`,
|
|
212
|
-
mode: unknownSection
|
|
213
|
-
}
|
|
214
|
-
) : null,
|
|
215
|
-
sections.map((section, i) => {
|
|
216
|
-
const key = section.id ?? `${section.type}-${i}`;
|
|
217
|
-
const builtin = renderBuiltin(section, { apiKey, baseUrl });
|
|
218
|
-
if (builtin !== void 0) {
|
|
219
|
-
return /* @__PURE__ */ jsx(Fragment, { children: builtin }, key);
|
|
220
|
-
}
|
|
221
|
-
const Custom = customSections[section.type];
|
|
222
|
-
if (Custom) {
|
|
223
|
-
return /* @__PURE__ */ jsx(Fragment, { children: Custom({
|
|
224
|
-
id: section.id,
|
|
225
|
-
props: section.props,
|
|
226
|
-
variant: section.variant,
|
|
227
|
-
theme: section.theme
|
|
228
|
-
}) }, key);
|
|
229
|
-
}
|
|
230
|
-
return /* @__PURE__ */ jsx(UnknownSection, { type: section.type, mode: unknownSection }, key);
|
|
231
|
-
})
|
|
232
|
-
] });
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// src/templates/index.ts
|
|
236
|
-
registerSectionTemplates();
|
|
237
|
-
export {
|
|
238
|
-
BUILTIN_SECTION_SCHEMAS,
|
|
239
|
-
BUILTIN_SECTION_TYPES,
|
|
240
|
-
BeforeAfterSectionSchema,
|
|
241
|
-
BlogListSectionSchema,
|
|
242
|
-
ConcernsSectionSchema,
|
|
243
|
-
ContactSectionSchema,
|
|
244
|
-
CtaBannerSectionSchema,
|
|
245
|
-
CustomSectionSchema,
|
|
246
|
-
ExpertiseSectionSchema,
|
|
247
|
-
FaqSectionSchema,
|
|
248
|
-
FooterSectionSchema,
|
|
249
|
-
HeroSectionSchema,
|
|
250
|
-
HoursSectionSchema,
|
|
251
|
-
LeadFormSectionSchema,
|
|
252
|
-
NavItemSchema,
|
|
253
|
-
PricingSectionSchema,
|
|
254
|
-
ProcessSectionSchema,
|
|
255
|
-
RichTextSectionSchema,
|
|
256
|
-
SECTION_VARIANTS,
|
|
257
|
-
SITE_CONFIG_SCHEMA_VERSION,
|
|
258
|
-
SectionSchema,
|
|
259
|
-
ServicesSectionSchema,
|
|
260
|
-
SiteConfigSchema,
|
|
261
|
-
SiteRenderer,
|
|
262
|
-
SpacesSectionSchema,
|
|
263
|
-
TeamSectionSchema,
|
|
264
|
-
TemplateBeforeAfter,
|
|
265
|
-
TemplateConcerns,
|
|
266
|
-
TemplateContact,
|
|
267
|
-
TemplateCtaBanner,
|
|
268
|
-
TemplateExpertise,
|
|
269
|
-
TemplateFaq,
|
|
270
|
-
TemplateFooter,
|
|
271
|
-
TemplateHero,
|
|
272
|
-
TemplateHours,
|
|
273
|
-
TemplatePricing,
|
|
274
|
-
TemplateProcess,
|
|
275
|
-
TemplateRichText,
|
|
276
|
-
TemplateServices,
|
|
277
|
-
TemplateSpaces,
|
|
278
|
-
TemplateTeam,
|
|
279
|
-
TemplateTestimonials,
|
|
280
|
-
TemplateTrust,
|
|
281
|
-
TestimonialsSectionSchema,
|
|
282
|
-
TrustSectionSchema,
|
|
283
|
-
defineSiteConfig,
|
|
284
|
-
parseSiteConfig,
|
|
285
|
-
registerSectionTemplates,
|
|
286
|
-
renderSectionNode,
|
|
287
|
-
resolveSiteConfigSchemaVersion,
|
|
288
|
-
sectionThemeStyle,
|
|
289
|
-
themeToCssVars
|
|
290
|
-
};
|
|
291
|
-
//# sourceMappingURL=templates.js.map
|
package/dist/templates.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/templates/SiteRenderer.tsx","../src/templates/index.ts"],"sourcesContent":["/**\n * `SiteRenderer` — `SiteConfig.pages[path]` 섹션 배열을 registry 로 렌더.\n *\n * ADR-0040 P2 + P0.5 RFC §①:\n * - 빌트인 registry + 클라 주입 `customSections` 머지. **빌트인이 우선** —\n * 클라가 빌트인 type 을 가로채 계약이 갈라지는 것 방지 (고유 섹션은 고유\n * type 으로).\n * - **render-prop 금지**: 임의 JSX escape hatch 는 customSections registry 로만.\n * - **admin preview parity**: admin draft/preview 도 동일 `SiteRenderer` + 동일\n * 빌트인 registry 를 탄다. customSections 는 클라 repo 자산 — preview 에선\n * 미주입 → `unknownSection: \"placeholder\"` 로 skeleton 표시.\n * - cms-bound 섹션(blog-list/lead-form)은 `RootTaleBlogList`/`RootTaleLeadForm`\n * 위임 (단방향: templates → renderer 코어).\n */\nimport {\n Fragment,\n type CSSProperties,\n type ReactElement,\n type ReactNode,\n} from \"react\";\n\nimport { RootTaleLeadForm } from \"../LeadForm.js\";\nimport { RootTaleBlogList } from \"../server.js\";\nimport {\n TemplateConcerns,\n TemplateExpertise,\n TemplateSpaces,\n} from \"./professional-sections.js\";\nimport {\n TemplateBeforeAfter,\n TemplateContact,\n TemplateCtaBanner,\n TemplateFaq,\n TemplateFooter,\n TemplateHero,\n TemplateHours,\n TemplatePricing,\n TemplateProcess,\n TemplateRichText,\n TemplateServices,\n TemplateTeam,\n TemplateTestimonials,\n TemplateTrust,\n sectionThemeStyle,\n} from \"./sections.js\";\nimport {\n type BeforeAfterSection,\n type BlogListSection,\n type ConcernsSection,\n type ContactSection,\n type CtaBannerSection,\n type ExpertiseSection,\n type FaqSection,\n type FooterSection,\n type HeroSection,\n type HoursSection,\n type LeadFormSection,\n type PricingSection,\n type ProcessSection,\n type RichTextSection,\n type Section,\n type ServicesSection,\n type SpacesSection,\n type SiteConfig,\n type SiteConfigInput,\n type TeamSection,\n type TestimonialsSection,\n type TrustSection,\n parseSiteConfig,\n} from \"./site-config.js\";\n\n/** customSections registry 컴포넌트 계약 (RFC §①). */\nexport type SectionComponent = (p: {\n id?: string;\n props: Record<string, unknown>;\n variant?: string;\n theme?: Record<string, string>;\n}) => ReactNode;\n\nexport interface SiteRendererProps {\n /** `defineSiteConfig()` 결과 또는 raw config (내부에서 검증). */\n config: SiteConfig | SiteConfigInput;\n /** 현재 페이지 경로 — `config.pages` 의 key (\"/\", \"/services\", …). */\n path: string;\n /** cms-bound 섹션(blog-list/lead-form 의 theme fetch) 위임용. 서버 전용. */\n apiKey: string;\n /** self-host 등 API base override (`ROOTTALE_API_BASE`). */\n baseUrl?: string;\n /** 클라 repo 고유 섹션 registry (escape hatch). 빌트인 type 은 가로챌 수 없음. */\n customSections?: Record<string, SectionComponent>;\n /**\n * registry 에 없는 type 처리. 기본 \"warn-dev\" = dev 에서 경고 박스, prod 에서\n * 생략. admin preview 는 \"placeholder\" (customSections 미주입 환경).\n */\n unknownSection?: \"warn-dev\" | \"placeholder\" | \"ignore\";\n}\n\nfunction isDev(): boolean {\n // dts 빌드는 node types 없이 돈다 — process 는 globalThis 경유로 안전 접근.\n const env =\n (globalThis as { process?: { env?: Record<string, string | undefined> } })\n .process?.env ?? {};\n return env.NODE_ENV !== \"production\";\n}\n\nfunction UnknownSection({\n type,\n mode,\n}: {\n type: string;\n mode: \"warn-dev\" | \"placeholder\" | \"ignore\";\n}): ReactElement | null {\n if (mode === \"ignore\") return null;\n if (mode === \"placeholder\") {\n return (\n <section\n data-roottale-tpl=\"placeholder\"\n className=\"rt-tpl-section rt-tpl-placeholder\"\n aria-hidden\n >\n <div className=\"rt-tpl-container\">\n <div className=\"rt-tpl-placeholder-box\">{type}</div>\n </div>\n </section>\n );\n }\n if (!isDev()) return null;\n const style: CSSProperties = {\n padding: \"1rem\",\n border: \"1px dashed #c00\",\n color: \"#c00\",\n };\n return (\n <div style={style}>\n 알 수 없는 섹션 type: <code>{type}</code> — SiteRenderer 의 customSections\n 에 등록하세요.\n </div>\n );\n}\n\nfunction renderBuiltin(\n section: Section,\n ctx: { apiKey: string; baseUrl?: string },\n): ReactNode | undefined {\n switch (section.type) {\n case \"hero\":\n return <TemplateHero {...(section as HeroSection)} />;\n case \"rich-text\":\n return <TemplateRichText {...(section as RichTextSection)} />;\n case \"services\":\n return <TemplateServices {...(section as ServicesSection)} />;\n case \"faq\":\n return <TemplateFaq {...(section as FaqSection)} />;\n case \"footer\":\n return <TemplateFooter {...(section as FooterSection)} />;\n case \"cta-banner\":\n return <TemplateCtaBanner {...(section as CtaBannerSection)} />;\n case \"blog-list\": {\n const s = section as BlogListSection;\n const base = s.props.blogBasePath ?? \"/blog\";\n return (\n <section\n data-roottale-tpl=\"blog-list\"\n data-roottale-cms=\"list\"\n id={s.id}\n className=\"rt-tpl-section rt-tpl-blog-list\"\n style={sectionThemeStyle(s.theme)}\n >\n <div className=\"rt-tpl-container\">\n {s.props.heading ? (\n <h2 className=\"rt-tpl-heading\">{s.props.heading}</h2>\n ) : null}\n <RootTaleBlogList\n apiKey={ctx.apiKey}\n baseUrl={ctx.baseUrl}\n limit={s.props.limit}\n emptyMessage={s.props.emptyMessage}\n postHref={(post) => `${base}/${post.slug}`}\n />\n </div>\n </section>\n );\n }\n case \"lead-form\": {\n const s = section as LeadFormSection;\n return (\n <section\n data-roottale-tpl=\"lead-form\"\n data-roottale-cms=\"lead-form\"\n id={s.id}\n className=\"rt-tpl-section rt-tpl-lead-form\"\n style={sectionThemeStyle(s.theme)}\n >\n <div className=\"rt-tpl-container\">\n <RootTaleLeadForm\n action={s.props.action}\n vertical={s.props.vertical}\n heading={s.props.heading}\n description={s.props.description}\n submitLabel={s.props.submitLabel}\n />\n </div>\n </section>\n );\n }\n case \"trust\":\n return <TemplateTrust {...(section as TrustSection)} />;\n case \"contact\":\n return <TemplateContact {...(section as ContactSection)} />;\n case \"hours\":\n return <TemplateHours {...(section as HoursSection)} />;\n case \"pricing\":\n return <TemplatePricing {...(section as PricingSection)} />;\n case \"process\":\n return <TemplateProcess {...(section as ProcessSection)} />;\n case \"before-after\":\n return <TemplateBeforeAfter {...(section as BeforeAfterSection)} />;\n case \"testimonials\":\n return <TemplateTestimonials {...(section as TestimonialsSection)} />;\n case \"expertise\":\n return <TemplateExpertise {...(section as ExpertiseSection)} />;\n case \"spaces\":\n return <TemplateSpaces {...(section as SpacesSection)} />;\n case \"concerns\":\n return <TemplateConcerns {...(section as ConcernsSection)} />;\n case \"team\":\n return <TemplateTeam {...(section as TeamSection)} />;\n default:\n return undefined;\n }\n}\n\n/**\n * 한 페이지의 섹션 배열을 순서대로 렌더.\n *\n * ```tsx\n * // app/services/page.tsx\n * import config from \"@/site.config\";\n * import { SiteRenderer } from \"@roottale/cms-renderer-next/templates\";\n *\n * export default function ServicesPage() {\n * return (\n * <SiteRenderer config={config} path=\"/services\"\n * apiKey={process.env.ROOTTALE_API_KEY!} />\n * );\n * }\n * ```\n */\nexport function SiteRenderer(props: SiteRendererProps): ReactElement {\n const {\n path,\n apiKey,\n baseUrl,\n customSections = {},\n unknownSection = \"warn-dev\",\n } = props;\n const config = parseSiteConfig(props.config);\n const sections = config.pages[path] ?? [];\n return (\n <>\n {sections.length === 0 ? (\n <UnknownSection\n type={`pages[\"${path}\"] (섹션 0개)`}\n mode={unknownSection}\n />\n ) : null}\n {sections.map((section, i) => {\n const key = section.id ?? `${section.type}-${i}`;\n const builtin = renderBuiltin(section, { apiKey, baseUrl });\n if (builtin !== undefined) {\n return <Fragment key={key}>{builtin}</Fragment>;\n }\n const Custom = customSections[section.type];\n if (Custom) {\n return (\n <Fragment key={key}>\n {Custom({\n id: section.id,\n props: section.props as Record<string, unknown>,\n variant: section.variant,\n theme: section.theme,\n })}\n </Fragment>\n );\n }\n return (\n <UnknownSection key={key} type={section.type} mode={unknownSection} />\n );\n })}\n </>\n );\n}\n","/**\n * `@roottale/cms-renderer-next/templates` — config-driven 사이트 템플릿\n * (ADR-0040 P2, P0.5 RFC §①).\n *\n * canonical `SiteConfig`(zod) + MUI-free 섹션 템플릿 + `SiteRenderer`.\n * CSS 는 root layout 에서 명시적으로:\n * `import \"@roottale/cms-renderer-next/templates/styles\";`\n * (cms-public.css 와 동일하게 side-effect import 하지 않음 — `<head>` 삽입\n * 순서 계약은 RFC §③: tokens → emotion → cms styles/templates → globals.)\n *\n * 별 패키지(`@roottale/site-kit`) 분리는 RFC §② 기준 충족 시 P3+ — 그때까지\n * 본 서브패스가 유일 진입점.\n */\nexport {\n BUILTIN_SECTION_SCHEMAS,\n BUILTIN_SECTION_TYPES,\n SITE_CONFIG_SCHEMA_VERSION,\n resolveSiteConfigSchemaVersion,\n BeforeAfterSectionSchema,\n BlogListSectionSchema,\n ContactSectionSchema,\n ConcernsSectionSchema,\n CtaBannerSectionSchema,\n CustomSectionSchema,\n ExpertiseSectionSchema,\n FaqSectionSchema,\n FooterSectionSchema,\n HeroSectionSchema,\n HoursSectionSchema,\n LeadFormSectionSchema,\n NavItemSchema,\n PricingSectionSchema,\n ProcessSectionSchema,\n RichTextSectionSchema,\n SECTION_VARIANTS,\n SectionSchema,\n ServicesSectionSchema,\n SiteConfigSchema,\n SpacesSectionSchema,\n TeamSectionSchema,\n TestimonialsSectionSchema,\n TrustSectionSchema,\n defineSiteConfig,\n parseSiteConfig,\n type BeforeAfterSection,\n type BlogListSection,\n type ContactSection,\n type ConcernsSection,\n type CtaBannerSection,\n type CustomSection,\n type ExpertiseSection,\n type FaqSection,\n type FooterSection,\n type HeroSection,\n type HoursSection,\n type LeadFormSection,\n type NavItem,\n type PricingSection,\n type ProcessSection,\n type RichTextSection,\n type Section,\n type SectionCta,\n type SectionInput,\n type ServicesSection,\n type SiteConfig,\n type SiteConfigInput,\n type SpacesSection,\n type TeamSection,\n type TestimonialsSection,\n type TrustSection,\n} from \"./site-config.js\";\n\nexport { themeToCssVars, type RootTaleCssVars } from \"../theme-css-vars.js\";\n\nexport {\n TemplateConcerns,\n TemplateExpertise,\n TemplateSpaces,\n} from \"./professional-sections.js\";\n\nexport {\n TemplateBeforeAfter,\n TemplateContact,\n TemplateCtaBanner,\n TemplateFaq,\n TemplateFooter,\n TemplateHero,\n TemplateHours,\n TemplatePricing,\n TemplateProcess,\n TemplateRichText,\n TemplateServices,\n TemplateTeam,\n TemplateTestimonials,\n TemplateTrust,\n sectionThemeStyle,\n} from \"./sections.js\";\n\nexport {\n SiteRenderer,\n type SectionComponent,\n type SiteRendererProps,\n} from \"./SiteRenderer.js\";\n\n/**\n * 이 배럴만 쓰는 경로(SiteRenderer 등)에서도 본문 `section` 노드가 그려지도록\n * 로드 시 등록한다. `/server` 진입점도 같은 등록을 하므로 중복 호출이지만\n * 같은 함수를 다시 넣을 뿐이라 무해하다.\n */\nimport { registerSectionTemplates } from \"./register.js\";\n\nregisterSectionTemplates();\n\nexport { registerSectionTemplates };\nexport { renderSectionNode } from \"./render-section-node.js\";\n"],"mappings":"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","names":["Fragment"]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { RootTaleTheme } from '@roottale/cms-client/server';
|
|
2
|
-
import { RootTaleThemeStyle } from '@roottale/ui-react/theme';
|
|
3
|
-
|
|
4
|
-
type RootTaleCssVars = RootTaleThemeStyle;
|
|
5
|
-
declare function themeToCssVars(theme: RootTaleTheme | null): RootTaleCssVars | null;
|
|
6
|
-
|
|
7
|
-
export { type RootTaleCssVars as R, themeToCssVars as t };
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode, CSSProperties } from 'react';
|
|
3
|
-
export { CountUpStat } from '@roottale/ui-react/count-up-stat';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 공유 모션 variants — C5(생성물 손 복사 금지)의 정신을 따라 모든 `scroll`/`motion`
|
|
7
|
-
* 프리미티브가 이 한 파일에서 variants 를 파생한다. 각 컴포넌트가 hidden/visible
|
|
8
|
-
* keyframe 객체를 손으로 복사하지 않는다(ds-rule-pack.md C5).
|
|
9
|
-
*
|
|
10
|
-
* 타이밍 출처(C1 — 임의값 대신 토큰 참조):
|
|
11
|
-
* - `ENTRANCE_EASE` = DTCG `--ease-out`(packages/tokens/src/motion.dtcg.json:
|
|
12
|
-
* `cubic-bezier(0, 0, 0.2, 1)`)과 동일 곡선. 등장(entrance)에 쓰는 표준 감속.
|
|
13
|
-
* - `ENTRANCE_DURATION`(0.5s)·`STAGGER_STEP`(0.08s) = 앰비언트 등장 스케일.
|
|
14
|
-
* motion.dtcg 의 100~200ms 는 INP 예산이 걸린 마이크로 인터랙션
|
|
15
|
-
* (hover/focus/button)용 cap 이며(M5), 스크롤 진입 리빌은 입력 지연(INP)
|
|
16
|
-
* 경로가 아니라 그 cap 대상이 아니다 — 별도 앰비언트 스케일로 문서화한다.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
type EntranceVariant = "fade-up" | "fade" | "scale-in";
|
|
20
|
-
|
|
21
|
-
type AnimateTag = "div" | "section" | "article" | "li" | "span";
|
|
22
|
-
interface AnimateOnScrollProps {
|
|
23
|
-
readonly children?: ReactNode;
|
|
24
|
-
readonly className?: string;
|
|
25
|
-
readonly style?: CSSProperties;
|
|
26
|
-
/** 진입 애니메이션 종류(구조 상이). 기본 `fade-up`. */
|
|
27
|
-
readonly variant?: EntranceVariant;
|
|
28
|
-
/** 렌더할 시맨틱 엘리먼트(래퍼 div 추가 없이 그 자리를 대체). 기본 `div`. */
|
|
29
|
-
readonly as?: AnimateTag;
|
|
30
|
-
/** 한 번만 트리거(재진입 시 재생 안 함). 기본 true. */
|
|
31
|
-
readonly once?: boolean;
|
|
32
|
-
/** whileInView viewport root margin. 기본 `-80px`. */
|
|
33
|
-
readonly margin?: string;
|
|
34
|
-
}
|
|
35
|
-
declare function AnimateOnScroll({ children, className, style, variant, as, once, margin, }: AnimateOnScrollProps): react_jsx_runtime.JSX.Element;
|
|
36
|
-
|
|
37
|
-
interface MarqueeProps {
|
|
38
|
-
readonly children?: ReactNode;
|
|
39
|
-
readonly className?: string;
|
|
40
|
-
/** 한 바퀴(자식 1벌 폭) 이동에 걸리는 시간(초). 기본 24. */
|
|
41
|
-
readonly speedSec?: number;
|
|
42
|
-
/** 항목 간격(CSS length). 기본 `2rem`(구조 간격 — 브랜드 토큰 아님). */
|
|
43
|
-
readonly gap?: string;
|
|
44
|
-
/** hover 시 일시정지. 기본 true. */
|
|
45
|
-
readonly pauseOnHover?: boolean;
|
|
46
|
-
/** 스크린리더용 그룹 레이블. */
|
|
47
|
-
readonly ariaLabel?: string;
|
|
48
|
-
/** 이동 방향. 기본 `left`(기존 동작 불변). `right` 는 반대 방향 이중 마퀴 패턴용. */
|
|
49
|
-
readonly direction?: "left" | "right";
|
|
50
|
-
}
|
|
51
|
-
declare function Marquee({ children, className, speedSec, gap, pauseOnHover, ariaLabel, direction, }: MarqueeProps): react_jsx_runtime.JSX.Element;
|
|
52
|
-
|
|
53
|
-
type GroupTag = "div" | "ul" | "ol" | "section";
|
|
54
|
-
type ItemTag = "div" | "li" | "article";
|
|
55
|
-
interface StaggerGroupProps {
|
|
56
|
-
readonly children?: ReactNode;
|
|
57
|
-
readonly className?: string;
|
|
58
|
-
readonly style?: CSSProperties;
|
|
59
|
-
/** 렌더할 시맨틱 컨테이너 엘리먼트. 기본 `div`. */
|
|
60
|
-
readonly as?: GroupTag;
|
|
61
|
-
/** 자식 순차 지연(초). 기본 0.08. */
|
|
62
|
-
readonly staggerChildren?: number;
|
|
63
|
-
readonly once?: boolean;
|
|
64
|
-
readonly margin?: string;
|
|
65
|
-
}
|
|
66
|
-
declare function StaggerGroup({ children, className, style, as, staggerChildren, once, margin, }: StaggerGroupProps): react_jsx_runtime.JSX.Element;
|
|
67
|
-
interface StaggerItemProps {
|
|
68
|
-
readonly children?: ReactNode;
|
|
69
|
-
readonly className?: string;
|
|
70
|
-
readonly style?: CSSProperties;
|
|
71
|
-
/** 렌더할 시맨틱 아이템 엘리먼트. 기본 `div`. */
|
|
72
|
-
readonly as?: ItemTag;
|
|
73
|
-
}
|
|
74
|
-
declare function StaggerItem({ children, className, style, as }: StaggerItemProps): react_jsx_runtime.JSX.Element;
|
|
75
|
-
|
|
76
|
-
export { AnimateOnScroll, Marquee, StaggerGroup, StaggerItem };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import {
|
|
3
|
-
AnimateOnScroll,
|
|
4
|
-
CountUpStat,
|
|
5
|
-
Marquee,
|
|
6
|
-
StaggerGroup,
|
|
7
|
-
StaggerItem
|
|
8
|
-
} from "./chunk-ZL2NA3QT.js";
|
|
9
|
-
export {
|
|
10
|
-
AnimateOnScroll,
|
|
11
|
-
CountUpStat,
|
|
12
|
-
Marquee,
|
|
13
|
-
StaggerGroup,
|
|
14
|
-
StaggerItem
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=ui-react-motion-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|