@se-studio/core-ui 0.1.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 ADDED
@@ -0,0 +1,121 @@
1
+ # @se-studio/core-ui
2
+
3
+ Shared React UI component library with Tailwind CSS v4 for SE Studio applications.
4
+
5
+ ## Features
6
+
7
+ - **React 19** - Built with the latest React
8
+ - **TypeScript** - Full type safety
9
+ - **Tailwind CSS v4** - Modern utility-first CSS framework
10
+ - **Tree-shakeable** - Import only what you need
11
+ - **Dual exports** - ESM and CJS support
12
+ - **Fully tested** - Comprehensive test coverage with Vitest
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pnpm add @se-studio/core-ui
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Importing Components
23
+
24
+ ```tsx
25
+ import { ResponsiveVisual } from '@se-studio/core-ui';
26
+ import type { IResponsiveVisual } from '@se-studio/core-data-types';
27
+
28
+ const visual: IResponsiveVisual = {
29
+ // ... your visual data
30
+ };
31
+
32
+ export default function MyPage() {
33
+ return <ResponsiveVisual visual={visual} />;
34
+ }
35
+ ```
36
+
37
+ ### Using Tailwind Configuration
38
+
39
+ Import the Tailwind configuration in your `tailwind.config.ts`:
40
+
41
+ ```typescript
42
+ import baseConfig from '@se-studio/core-ui/tailwind-config';
43
+ import type { Config } from 'tailwindcss';
44
+
45
+ const config: Config = {
46
+ ...baseConfig,
47
+ content: [
48
+ './src/**/*.{ts,tsx}',
49
+ './node_modules/@se-studio/core-ui/dist/**/*.{js,jsx}',
50
+ ],
51
+ // Add your customizations here
52
+ };
53
+
54
+ export default config;
55
+ ```
56
+
57
+ ### Importing Styles
58
+
59
+ In your Next.js app layout or root component:
60
+
61
+ ```tsx
62
+ import '@se-studio/core-ui/styles';
63
+ ```
64
+
65
+ ## Components
66
+
67
+ ### ResponsiveVisual
68
+
69
+ Renders responsive visual content (images, videos, animations) from Contentful.
70
+
71
+ **Props:**
72
+
73
+ - `visual` - `IResponsiveVisual` - The visual data from Contentful
74
+ - `className?` - `string` - Additional CSS classes
75
+ - `priority?` - `boolean` - Enable priority loading for above-the-fold images
76
+
77
+ **Example:**
78
+
79
+ ```tsx
80
+ import { ResponsiveVisual } from '@se-studio/core-ui';
81
+
82
+ <ResponsiveVisual
83
+ visual={responsiveVisualData}
84
+ className="w-full h-auto"
85
+ priority
86
+ />
87
+ ```
88
+
89
+ ## Development
90
+
91
+ ```bash
92
+ # Install dependencies
93
+ pnpm install
94
+
95
+ # Run tests
96
+ pnpm test
97
+
98
+ # Run tests in watch mode
99
+ pnpm test:watch
100
+
101
+ # Build the library
102
+ pnpm build
103
+
104
+ # Type check
105
+ pnpm type-check
106
+
107
+ # Lint
108
+ pnpm lint
109
+ ```
110
+
111
+ ## Custom Breakpoints
112
+
113
+ The library includes custom breakpoints optimized for modern responsive design:
114
+
115
+ - `tablet`: 768px
116
+ - `laptop`: 1024px
117
+ - `desktop`: 1440px
118
+
119
+ ## License
120
+
121
+ MIT
@@ -0,0 +1,2 @@
1
+ export { ClientMonitor } from './components/ClientMonitor.js';
2
+ export { Preview } from './components/Preview.js';
package/dist/client.js ADDED
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { ClientMonitor } from "./components/ClientMonitor.js";
3
+ import { Preview } from "./components/Preview.js";
4
+ export {
5
+ ClientMonitor,
6
+ Preview
7
+ };
8
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["'use client';\n\n// Client-only components that require browser APIs\nexport { ClientMonitor } from './components/ClientMonitor.js';\nexport { Preview } from './components/Preview.js';\n"],"mappings":";AAGA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;","names":[]}
@@ -0,0 +1,3 @@
1
+ declare const ClientMonitor: React.FC;
2
+
3
+ export { ClientMonitor };
@@ -0,0 +1,135 @@
1
+ "use client";
2
+ import { usePathname } from "next/navigation";
3
+ import { useEffect } from "react";
4
+ import { useDocumentVisible } from "../hooks/useDocumentVisible";
5
+ let _observer;
6
+ function handleVideo(video, isIntersecting) {
7
+ if (!isIntersecting) {
8
+ if (!video.paused) {
9
+ video.pause();
10
+ }
11
+ } else if (video.paused) {
12
+ video.play().then(() => {
13
+ video.controls = false;
14
+ }).catch(() => {
15
+ });
16
+ }
17
+ }
18
+ function handleAnimation(animation, isIntersecting) {
19
+ const currentState = animation.currentState;
20
+ if (!isIntersecting) {
21
+ if (currentState === "playing") {
22
+ animation.pause();
23
+ }
24
+ } else {
25
+ if (currentState === "paused") {
26
+ animation.play();
27
+ }
28
+ if (!currentState || currentState === "loading") {
29
+ if (animation.play) {
30
+ animation.play();
31
+ }
32
+ animation.autoplay = true;
33
+ }
34
+ }
35
+ }
36
+ function handleAnimatedSection(section, isIntersecting) {
37
+ section.dataset.visible = isIntersecting ? "true" : "false";
38
+ if (isIntersecting) {
39
+ if (!section.dataset.seen) {
40
+ section.dataset.seen = "true";
41
+ }
42
+ }
43
+ }
44
+ function intersectionHandler(entries) {
45
+ for (const entry of entries) {
46
+ const target = entry.target;
47
+ switch (target.localName) {
48
+ case "video":
49
+ handleVideo(target, entry.isIntersecting);
50
+ break;
51
+ case "lottie-player":
52
+ handleAnimation(target, entry.isIntersecting);
53
+ break;
54
+ default:
55
+ {
56
+ const element = target;
57
+ handleAnimatedSection(element, entry.isIntersecting);
58
+ }
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ function getObserver() {
64
+ if (!_observer) {
65
+ const observer = new IntersectionObserver(intersectionHandler, {
66
+ threshold: 0.2
67
+ });
68
+ _observer = observer;
69
+ }
70
+ return _observer;
71
+ }
72
+ function findAllVideos() {
73
+ const videos = document.getElementsByTagName("video");
74
+ const observer = getObserver();
75
+ for (const video of videos) {
76
+ video.controls = false;
77
+ video.muted = true;
78
+ observer.observe(video);
79
+ }
80
+ return () => {
81
+ for (const video of videos) {
82
+ observer.unobserve(video);
83
+ }
84
+ };
85
+ }
86
+ function findAllAnimations() {
87
+ const animations = document.getElementsByTagName("lottie-player");
88
+ const observer = getObserver();
89
+ for (const animation of animations) {
90
+ observer.observe(animation);
91
+ }
92
+ return () => {
93
+ for (const animation of animations) {
94
+ observer.unobserve(animation);
95
+ }
96
+ };
97
+ }
98
+ function findAllAnimatedSections() {
99
+ const sections = document.querySelectorAll("[data-component]");
100
+ const observer = getObserver();
101
+ for (const section of sections) {
102
+ observer.observe(section);
103
+ }
104
+ return () => {
105
+ for (const section of sections) {
106
+ observer.unobserve(section);
107
+ }
108
+ };
109
+ }
110
+ function findAll() {
111
+ const videoCleanup = findAllVideos();
112
+ const animationCleanup = findAllAnimations();
113
+ const animatedSectionCleanup = findAllAnimatedSections();
114
+ return () => {
115
+ videoCleanup();
116
+ animationCleanup();
117
+ animatedSectionCleanup();
118
+ };
119
+ }
120
+ const ClientMonitor = () => {
121
+ const isDocumentVisible = useDocumentVisible();
122
+ const pathname = usePathname();
123
+ useEffect(() => {
124
+ pathname;
125
+ if (isDocumentVisible) {
126
+ return findAll();
127
+ }
128
+ return void 0;
129
+ }, [pathname, isDocumentVisible]);
130
+ return null;
131
+ };
132
+ export {
133
+ ClientMonitor
134
+ };
135
+ //# sourceMappingURL=ClientMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/ClientMonitor.tsx"],"sourcesContent":["'use client';\nimport { usePathname } from 'next/navigation';\nimport { useEffect } from 'react';\nimport { useDocumentVisible } from '../hooks/useDocumentVisible';\n\nlet _observer: IntersectionObserver | undefined;\n\nfunction handleVideo(video: HTMLVideoElement, isIntersecting: boolean) {\n if (!isIntersecting) {\n if (!video.paused) {\n // console.log(\"pause video\", video.src);\n video.pause();\n }\n } else if (video.paused) {\n // console.log(\"play video\", video.src);\n video\n .play()\n .then(() => {\n video.controls = false;\n })\n .catch(() => {\n // console.log(\"failed to play\", error);\n // video.controls = true;\n });\n }\n}\n\ninterface ILottiePlayer extends HTMLElement {\n pause: () => void;\n play: () => void;\n autoplay: boolean;\n currentState: 'playing' | 'paused' | 'loading' | undefined;\n}\n\nfunction handleAnimation(animation: ILottiePlayer, isIntersecting: boolean) {\n const currentState = animation.currentState;\n // console.log('current state', currentState)\n if (!isIntersecting) {\n if (currentState === 'playing') {\n animation.pause();\n }\n } else {\n if (currentState === 'paused') {\n // console.log('play animation')\n animation.play();\n }\n if (!currentState || currentState === 'loading') {\n // console.log('set to autoplay')\n if (animation.play) {\n animation.play();\n }\n animation.autoplay = true;\n }\n }\n}\n\nfunction handleAnimatedSection(section: HTMLElement, isIntersecting: boolean) {\n section.dataset.visible = isIntersecting ? 'true' : 'false';\n if (isIntersecting) {\n if (!section.dataset.seen) {\n section.dataset.seen = 'true';\n }\n }\n}\n\nfunction intersectionHandler(entries: IntersectionObserverEntry[]) {\n for (const entry of entries) {\n // console.log(\"target\", entry.target.localName, entry.target);\n const target = entry.target;\n switch (target.localName) {\n case 'video':\n handleVideo(target as HTMLVideoElement, entry.isIntersecting);\n break;\n case 'lottie-player':\n handleAnimation(target as ILottiePlayer, entry.isIntersecting);\n break;\n default:\n {\n const element = target as HTMLElement;\n handleAnimatedSection(element, entry.isIntersecting);\n }\n break;\n }\n }\n}\n\nfunction getObserver() {\n if (!_observer) {\n const observer = new IntersectionObserver(intersectionHandler, {\n threshold: 0.2,\n });\n _observer = observer;\n }\n return _observer;\n}\n\nfunction findAllVideos() {\n const videos = document.getElementsByTagName('video');\n // console.log(\"got\", videos.length, \"videos\");\n const observer = getObserver();\n for (const video of videos) {\n video.controls = false;\n video.muted = true;\n // console.log(\n // `Video ${video.src} ready state ${video.readyState} ${video.paused}`,\n // );\n observer.observe(video);\n }\n return () => {\n // console.log(\"clear down video observer\");\n for (const video of videos) {\n observer.unobserve(video);\n }\n };\n}\n\nfunction findAllAnimations() {\n const animations = document.getElementsByTagName('lottie-player');\n // console.log(\"got\", animations.length, \"animations\");\n const observer = getObserver();\n for (const animation of animations) {\n observer.observe(animation);\n }\n return () => {\n // console.log(\"clear down animation observer\");\n for (const animation of animations) {\n observer.unobserve(animation);\n }\n };\n}\n\nfunction findAllAnimatedSections() {\n const sections = document.querySelectorAll('[data-component]');\n const observer = getObserver();\n for (const section of sections) {\n observer.observe(section);\n }\n return () => {\n // console.log(\"clear down animation observer\");\n for (const section of sections) {\n observer.unobserve(section);\n }\n };\n}\n\nfunction findAll() {\n const videoCleanup = findAllVideos();\n const animationCleanup = findAllAnimations();\n const animatedSectionCleanup = findAllAnimatedSections();\n return () => {\n videoCleanup();\n animationCleanup();\n animatedSectionCleanup();\n };\n}\n\nexport const ClientMonitor: React.FC = () => {\n const isDocumentVisible = useDocumentVisible();\n const pathname = usePathname();\n useEffect(() => {\n pathname;\n if (isDocumentVisible) {\n return findAll();\n }\n return undefined;\n }, [pathname, isDocumentVisible]);\n\n return null;\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,3 @@
1
+ declare const Preview: React.FC;
2
+
3
+ export { Preview };
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { ContentfulLivePreview } from "@contentful/live-preview";
3
+ import { useRouter } from "next/navigation";
4
+ import { useEffect, useLayoutEffect } from "react";
5
+ const Preview = () => {
6
+ const router = useRouter();
7
+ useLayoutEffect(() => {
8
+ ContentfulLivePreview.init({
9
+ locale: "en-US",
10
+ debugMode: true,
11
+ enableLiveUpdates: true,
12
+ enableInspectorMode: true
13
+ });
14
+ }, []);
15
+ useEffect(() => {
16
+ const checkLivePreview = (event) => {
17
+ if (typeof event.data !== "object" || !event.data || !("from" in event.data) || !("action" in event.data))
18
+ return;
19
+ if (event.data.from !== "live-preview") return;
20
+ if (event.data.action !== "ENTRY_SAVED") return;
21
+ router.refresh();
22
+ };
23
+ window.addEventListener("message", checkLivePreview);
24
+ return () => {
25
+ window.removeEventListener("message", checkLivePreview);
26
+ };
27
+ }, [router]);
28
+ return null;
29
+ };
30
+ export {
31
+ Preview
32
+ };
33
+ //# sourceMappingURL=Preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/Preview.tsx"],"sourcesContent":["'use client';\n\nimport { ContentfulLivePreview } from '@contentful/live-preview';\nimport { useRouter } from 'next/navigation';\nimport { useEffect, useLayoutEffect } from 'react';\n\nexport const Preview: React.FC = () => {\n const router = useRouter();\n useLayoutEffect(() => {\n ContentfulLivePreview.init({\n locale: 'en-US',\n debugMode: true,\n enableLiveUpdates: true,\n enableInspectorMode: true,\n });\n }, []);\n\n useEffect(() => {\n const checkLivePreview = (event: MessageEvent<unknown>) => {\n if (\n typeof event.data !== 'object' ||\n !event.data ||\n !('from' in event.data) ||\n !('action' in event.data)\n )\n return;\n if (event.data.from !== 'live-preview') return;\n if (event.data.action !== 'ENTRY_SAVED') return;\n router.refresh();\n };\n window.addEventListener('message', checkLivePreview);\n\n return () => {\n window.removeEventListener('message', checkLivePreview);\n };\n }, [router]);\n\n return null;\n};\n"],"mappings":";AAEA,SAAS,6BAA6B;AACtC,SAAS,iBAAiB;AAC1B,SAAS,WAAW,uBAAuB;AAEpC,MAAM,UAAoB,MAAM;AACrC,QAAM,SAAS,UAAU;AACzB,kBAAgB,MAAM;AACpB,0BAAsB,KAAK;AAAA,MACzB,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,mBAAmB;AAAA,MACnB,qBAAqB;AAAA,IACvB,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,UAAM,mBAAmB,CAAC,UAAiC;AACzD,UACE,OAAO,MAAM,SAAS,YACtB,CAAC,MAAM,QACP,EAAE,UAAU,MAAM,SAClB,EAAE,YAAY,MAAM;AAEpB;AACF,UAAI,MAAM,KAAK,SAAS,eAAgB;AACxC,UAAI,MAAM,KAAK,WAAW,cAAe;AACzC,aAAO,QAAQ;AAAA,IACjB;AACA,WAAO,iBAAiB,WAAW,gBAAgB;AAEnD,WAAO,MAAM;AACX,aAAO,oBAAoB,WAAW,gBAAgB;AAAA,IACxD;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;","names":[]}
@@ -0,0 +1,3 @@
1
+ declare function useDocumentVisible(initialState?: boolean): boolean;
2
+
3
+ export { useDocumentVisible };
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { useEffect, useState } from "react";
3
+ function useDocumentVisible(initialState = true) {
4
+ const [isVisible, setIsVisible] = useState(initialState);
5
+ useEffect(() => {
6
+ const handler = () => {
7
+ setIsVisible(document.visibilityState === "visible");
8
+ };
9
+ document.addEventListener("visibilitychange", handler, true);
10
+ handler();
11
+ return () => {
12
+ document.removeEventListener("visibilitychange", handler, true);
13
+ };
14
+ }, []);
15
+ return isVisible;
16
+ }
17
+ export {
18
+ useDocumentVisible
19
+ };
20
+ //# sourceMappingURL=useDocumentVisible.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/useDocumentVisible.ts"],"sourcesContent":["'use client';\nimport { useEffect, useState } from 'react';\n\nexport function useDocumentVisible(initialState = true) {\n const [isVisible, setIsVisible] = useState(initialState);\n useEffect(() => {\n const handler = () => {\n setIsVisible(document.visibilityState === 'visible');\n };\n document.addEventListener('visibilitychange', handler, true);\n handler();\n return () => {\n document.removeEventListener('visibilitychange', handler, true);\n };\n }, []);\n return isVisible;\n}\n"],"mappings":";AACA,SAAS,WAAW,gBAAgB;AAE7B,SAAS,mBAAmB,eAAe,MAAM;AACtD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,YAAY;AACvD,YAAU,MAAM;AACd,UAAM,UAAU,MAAM;AACpB,mBAAa,SAAS,oBAAoB,SAAS;AAAA,IACrD;AACA,aAAS,iBAAiB,oBAAoB,SAAS,IAAI;AAC3D,YAAQ;AACR,WAAO,MAAM;AACX,eAAS,oBAAoB,oBAAoB,SAAS,IAAI;AAAA,IAChE;AAAA,EACF,GAAG,CAAC,CAAC;AACL,SAAO;AACT;","names":[]}
@@ -0,0 +1,172 @@
1
+ import { BaseCmsConfig, IContentContext, IVisual, PageContent, IPageContext, IVisualSizes, IAnalyticsContext, IVisualCommon } from '@se-studio/core-data-types';
2
+ import { React as React$2 } from 'next/dist/server/route-modules/app-page/vendored/rsc/entrypoints';
3
+ import React$1, { PropsWithChildren, CSSProperties, HTMLAttributes } from 'react';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import { Document } from '@contentful/rich-text-types';
6
+
7
+ type CollectionMap<TConfig extends BaseCmsConfig> = Record<TConfig['CollectionType'], React$1.FC<{
8
+ information: TConfig['Collection'];
9
+ contentContext: IContentContext<TConfig>;
10
+ rendererConfig: CmsRendererConfig<TConfig>;
11
+ }>>;
12
+ declare function CmsCollection<TConfig extends BaseCmsConfig>({ information, contentContext, rendererConfig, }: {
13
+ information: TConfig['Collection'];
14
+ contentContext: IContentContext<TConfig>;
15
+ rendererConfig: CmsRendererConfig<TConfig>;
16
+ }): react_jsx_runtime.JSX.Element;
17
+
18
+ type ComponentMap<TConfig extends BaseCmsConfig> = Record<TConfig['ComponentType'], React$1.FC<{
19
+ information: TConfig['Component'];
20
+ contentContext: IContentContext<TConfig>;
21
+ rendererConfig: CmsRendererConfig<TConfig>;
22
+ }>>;
23
+ declare function CmsComponent<TConfig extends BaseCmsConfig>({ information, contentContext, rendererConfig, }: {
24
+ information: TConfig['Component'];
25
+ contentContext: IContentContext<TConfig>;
26
+ rendererConfig: CmsRendererConfig<TConfig>;
27
+ }): react_jsx_runtime.JSX.Element;
28
+
29
+ type ExternalComponentRenderer<TConfig extends BaseCmsConfig> = React$1.FC<{
30
+ information: TConfig['ExternalComponent'];
31
+ contentContext: IContentContext<TConfig>;
32
+ }>;
33
+ type ExternalComponentMap<TConfig extends BaseCmsConfig> = Partial<Record<TConfig['ExternalComponentType'], ExternalComponentRenderer<TConfig>>>;
34
+ type VisualComponentRenderer<TConfig extends BaseCmsConfig> = React$1.FC<{
35
+ information: IVisual;
36
+ contentContext: IContentContext<TConfig>;
37
+ }>;
38
+ type InternalLinkRenderer<TConfig extends BaseCmsConfig> = React$1.FC<{
39
+ information: Extract<PageContent<TConfig>, {
40
+ type: 'Internal link';
41
+ }>;
42
+ contentContext: IContentContext<TConfig>;
43
+ }>;
44
+ declare function CmsContent<TConfig extends BaseCmsConfig>({ pageContext, contents, rendererConfig, }: {
45
+ pageContext: IPageContext<TConfig>;
46
+ contents?: ReadonlyArray<PageContent<TConfig>>;
47
+ rendererConfig: CmsRendererConfig<TConfig>;
48
+ }): react_jsx_runtime.JSX.Element | null;
49
+
50
+ interface CmsRendererConfig<TConfig extends BaseCmsConfig> {
51
+ componentMap: ComponentMap<TConfig>;
52
+ collectionMap: CollectionMap<TConfig>;
53
+ externalComponentMap: ExternalComponentMap<TConfig>;
54
+ visualComponentRenderer: VisualComponentRenderer<TConfig>;
55
+ internalLinkRenderer: InternalLinkRenderer<TConfig>;
56
+ showUnknownTypeErrors: boolean;
57
+ showRenderErrors: boolean;
58
+ defaultComponentRenderer: React$2.FC<{
59
+ information: TConfig['Component'];
60
+ contentContext: IContentContext<TConfig>;
61
+ rendererConfig: CmsRendererConfig<TConfig>;
62
+ }>;
63
+ defaultCollectionRenderer: React$2.FC<{
64
+ information: TConfig['Collection'];
65
+ contentContext: IContentContext<TConfig>;
66
+ rendererConfig: CmsRendererConfig<TConfig>;
67
+ }>;
68
+ basicLinkRenderer: React$2.FC<PropsWithChildren<{
69
+ href?: string;
70
+ }>>;
71
+ embeddedContentRenderer: React$2.FC<{
72
+ information: TConfig['PageContent'];
73
+ contentContext: IContentContext<TConfig>;
74
+ rendererConfig: CmsRendererConfig<TConfig>;
75
+ }>;
76
+ }
77
+ declare function createCmsRendererConfig<TConfig extends BaseCmsConfig>(config: CmsRendererConfig<TConfig>): CmsRendererConfig<TConfig>;
78
+ type PartialCmsRendererConfig<TConfig extends BaseCmsConfig> = {
79
+ [K in keyof CmsRendererConfig<TConfig>]?: CmsRendererConfig<TConfig>[K];
80
+ };
81
+ declare function mergeCmsRendererConfig<TConfig extends BaseCmsConfig>(base: CmsRendererConfig<TConfig>, overrides: PartialCmsRendererConfig<TConfig>): CmsRendererConfig<TConfig>;
82
+
83
+ type IVisualProps = {
84
+ className?: string;
85
+ style?: Omit<CSSProperties, 'objectFit' | 'objectPosition'>;
86
+ autoPlay?: boolean;
87
+ loop?: boolean;
88
+ loopDelay?: number;
89
+ muted?: boolean;
90
+ controls?: boolean;
91
+ loading?: 'eager' | 'lazy' | undefined;
92
+ priority?: boolean;
93
+ fetchPriority?: 'high' | 'low' | undefined;
94
+ visualSizes?: IVisualSizes;
95
+ fullPlayer?: boolean;
96
+ analyticsContext?: IAnalyticsContext;
97
+ componentLabel?: string | null;
98
+ };
99
+ declare function calculateCropDetails(details: Omit<IVisualCommon, 'id' | 'type' | 'name' | 'nameAsCaption'>): Pick<CSSProperties, 'objectFit' | 'objectPosition'>;
100
+ declare function calculateImagePriority(index: number): {
101
+ priority: boolean;
102
+ fetchPriority: 'high' | 'low' | undefined;
103
+ } | undefined;
104
+ declare function calculateImageWidthStyleVariable(visual?: IVisual, baseWidth?: number | null): CSSProperties | undefined;
105
+
106
+ declare const Visual: React$1.FC<{
107
+ visual: IVisual;
108
+ } & IVisualProps>;
109
+
110
+ type ArrayToUnion<T extends ReadonlyArray<unknown>> = T[number];
111
+ interface ComponentConfig<TConfig extends BaseCmsConfig = BaseCmsConfig, TAdditional = Record<string, unknown>> {
112
+ componentProps: ReadonlyArray<keyof TConfig['Component']>;
113
+ contextProps: ReadonlyArray<keyof IPageContext<TConfig>>;
114
+ additionalProps?: TAdditional;
115
+ }
116
+ interface CollectionConfig<TConfig extends BaseCmsConfig = BaseCmsConfig, TAdditional = Record<string, unknown>> {
117
+ collectionProps: ReadonlyArray<keyof TConfig['Collection']>;
118
+ contextProps: ReadonlyArray<keyof IPageContext<TConfig>>;
119
+ additionalProps?: TAdditional;
120
+ }
121
+ type ComponentPropsFromConfig<TConfig extends BaseCmsConfig, T extends ComponentConfig<TConfig>> = T['componentProps'] extends ReadonlyArray<keyof TConfig['Component']> ? Pick<TConfig['Component'], ArrayToUnion<T['componentProps']>> : never;
122
+ type CollectionPropsFromConfig<TConfig extends BaseCmsConfig, T extends CollectionConfig<TConfig>> = T['collectionProps'] extends ReadonlyArray<keyof TConfig['Collection']> ? Pick<TConfig['Collection'], ArrayToUnion<T['collectionProps']>> : never;
123
+ type ContextPropsFromConfig<TConfig extends BaseCmsConfig, T extends ComponentConfig<TConfig> | CollectionConfig<TConfig>> = Pick<IPageContext<TConfig>, ArrayToUnion<T['contextProps']>>;
124
+ type GeneratePropsFromComponentConfig<TConfig extends BaseCmsConfig, T extends ComponentConfig<TConfig>> = ComponentPropsFromConfig<TConfig, T> & ContextPropsFromConfig<TConfig, T> & (T['additionalProps'] extends Record<string, unknown> ? T['additionalProps'] : Record<string, never>);
125
+ type GeneratePropsFromCollectionConfig<TConfig extends BaseCmsConfig, T extends CollectionConfig<TConfig>> = CollectionPropsFromConfig<TConfig, T> & ContextPropsFromConfig<TConfig, T> & (T['additionalProps'] extends Record<string, unknown> ? T['additionalProps'] : Record<string, never>);
126
+ declare function extractPropsFromComponentConfig<TConfig extends BaseCmsConfig, T extends ComponentConfig<TConfig>>(config: T, component: TConfig['Component'], context?: IPageContext<TConfig>): GeneratePropsFromComponentConfig<TConfig, T>;
127
+ declare function extractPropsFromCollectionConfig<TConfig extends BaseCmsConfig, T extends CollectionConfig<TConfig>>(config: T, collection: TConfig['Collection'], context?: IPageContext<TConfig>): GeneratePropsFromCollectionConfig<TConfig, T>;
128
+
129
+ interface IEmbeddableComponentContext<TConfig extends BaseCmsConfig = BaseCmsConfig, T extends TConfig['Component'] = TConfig['Component']> {
130
+ information: T;
131
+ parentIndex: number;
132
+ parentId: string;
133
+ pageContext: IPageContext<TConfig>;
134
+ }
135
+ interface IEmbeddableCollectionContext<TConfig extends BaseCmsConfig = BaseCmsConfig, T extends TConfig['Collection'] = TConfig['Collection']> {
136
+ information: T;
137
+ parentIndex: number;
138
+ parentId: string;
139
+ pageContext: IPageContext<TConfig>;
140
+ }
141
+
142
+ declare function BuildEmbedFromComponentConfig<TConfig extends BaseCmsConfig, TProps extends Record<string, unknown>, TComponentConfig extends ComponentConfig<TConfig>>(Component: React$1.FC<TProps>, componentConfig: TComponentConfig): React$1.FC<IEmbeddableComponentContext<TConfig>>;
143
+ declare function BuildEmbedFromCollectionConfig<TConfig extends BaseCmsConfig, TProps extends Record<string, unknown>, TCollectionConfig extends CollectionConfig<TConfig>>(Collection: React$1.FC<TProps>, collectionConfig: TCollectionConfig): React$1.FC<IEmbeddableCollectionContext<TConfig>>;
144
+
145
+ type EmbeddableComponentMap<TConfig extends BaseCmsConfig> = Partial<Record<TConfig['ComponentType'], React$1.FC<IEmbeddableComponentContext<TConfig>>>>;
146
+ type EmbeddableCollectionMap<TConfig extends BaseCmsConfig> = Partial<Record<TConfig['CollectionType'], React$1.FC<IEmbeddableCollectionContext<TConfig>>>>;
147
+ declare function isComponentEmbeddable<TConfig extends BaseCmsConfig>(componentType: TConfig['ComponentType'], embeddableMap: EmbeddableComponentMap<TConfig>): boolean;
148
+ declare function isCollectionEmbeddable<TConfig extends BaseCmsConfig>(collectionType: TConfig['CollectionType'], embeddableMap: EmbeddableCollectionMap<TConfig>): boolean;
149
+
150
+ type RTFProps<TConfig extends BaseCmsConfig> = {
151
+ content: Document;
152
+ rendererConfig: CmsRendererConfig<TConfig>;
153
+ contentContext: IContentContext<TConfig>;
154
+ } & Omit<HTMLAttributes<HTMLElement>, 'content'>;
155
+ declare function RTF<TConfig extends BaseCmsConfig>({ content, className, style, rendererConfig, contentContext, ...other }: RTFProps<TConfig>): react_jsx_runtime.JSX.Element;
156
+
157
+ declare const DEFAULT_ALLOWED_UNUSED: Set<string>;
158
+ type UnusedType = Record<string, unknown>;
159
+ declare const UnusedChecker: React.FC<PropsWithChildren<{
160
+ componentName: string;
161
+ unused: UnusedType;
162
+ allowedToBeUnused?: Set<string>;
163
+ showWarnings?: boolean;
164
+ }>>;
165
+
166
+ declare const UnsupportedWarning: React.FC<PropsWithChildren<{
167
+ className?: string;
168
+ style?: CSSProperties;
169
+ showWarnings?: boolean;
170
+ }>>;
171
+
172
+ export { type ArrayToUnion, BuildEmbedFromCollectionConfig, BuildEmbedFromComponentConfig, CmsCollection, CmsComponent, CmsContent, type CmsRendererConfig, type CollectionConfig, type CollectionMap, type CollectionPropsFromConfig, type ComponentConfig, type ComponentMap, type ComponentPropsFromConfig, type ContextPropsFromConfig, DEFAULT_ALLOWED_UNUSED, type EmbeddableCollectionMap, type EmbeddableComponentMap, type ExternalComponentMap, type ExternalComponentRenderer, type GeneratePropsFromCollectionConfig, type GeneratePropsFromComponentConfig, type IEmbeddableCollectionContext, type IEmbeddableComponentContext, type IVisualProps, type InternalLinkRenderer, type PartialCmsRendererConfig, RTF, UnsupportedWarning, UnusedChecker, Visual, type VisualComponentRenderer, calculateCropDetails, calculateImagePriority, calculateImageWidthStyleVariable, createCmsRendererConfig, extractPropsFromCollectionConfig, extractPropsFromComponentConfig, isCollectionEmbeddable, isComponentEmbeddable, mergeCmsRendererConfig };