@commercetools-demo/puck-renderer 0.2.1 → 0.3.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/dist/index.d.mts CHANGED
@@ -44,9 +44,9 @@ interface PuckRendererProps {
44
44
  /** 'published' (default) or 'preview' (draft || published). */
45
45
  mode?: 'published' | 'preview';
46
46
  /**
47
- * Puck config — must match the config used in the editor.
47
+ * Puck config — must match the config used in the editor. Defaults to defaultPuckConfig.
48
48
  */
49
- config: PuckConfig;
49
+ config?: PuckConfig;
50
50
  /** Custom loading indicator. */
51
51
  loadingComponent?: ReactElement;
52
52
  /** Custom error display. */
package/dist/index.d.ts CHANGED
@@ -44,9 +44,9 @@ interface PuckRendererProps {
44
44
  /** 'published' (default) or 'preview' (draft || published). */
45
45
  mode?: 'published' | 'preview';
46
46
  /**
47
- * Puck config — must match the config used in the editor.
47
+ * Puck config — must match the config used in the editor. Defaults to defaultPuckConfig.
48
48
  */
49
- config: PuckConfig;
49
+ config?: PuckConfig;
50
50
  /** Custom loading indicator. */
51
51
  loadingComponent?: ReactElement;
52
52
  /** Custom error display. */
package/dist/index.js CHANGED
@@ -40,8 +40,13 @@ var PuckDataRenderer = ({
40
40
  // src/PuckRenderer.tsx
41
41
  var import_react = require("react");
42
42
  var import_puck_api = require("@commercetools-demo/puck-api");
43
+ var import_puck_editor = require("@commercetools-demo/puck-editor");
43
44
  var import_puck_api2 = require("@commercetools-demo/puck-api");
44
45
  var import_jsx_runtime2 = require("react/jsx-runtime");
46
+ var DEFAULT_CONFIG = {
47
+ ...import_puck_editor.defaultPuckConfig,
48
+ components: { ...import_puck_editor.defaultPuckConfig.components }
49
+ };
45
50
  var PuckRendererInner = ({
46
51
  type,
47
52
  pageKey,
@@ -71,7 +76,7 @@ var PuckRendererInner = ({
71
76
  const value = mode === "published" ? await (0, import_puck_api2.getPublishedPuckContentApi)(baseURL, projectKey, businessUnitKey, contentKey) : await (0, import_puck_api2.getPreviewPuckContentApi)(baseURL, projectKey, businessUnitKey, contentKey);
72
77
  puckData = value.data;
73
78
  } else if (query) {
74
- const value = await (0, import_puck_api2.queryPuckContentApi)(baseURL, projectKey, businessUnitKey, query, mode);
79
+ const value = await (0, import_puck_api2.queryPuckContentApi)(baseURL, projectKey, businessUnitKey, { query: `contentType = "${query}"` }, mode);
75
80
  puckData = value?.data ?? null;
76
81
  }
77
82
  if (!cancelled) {
@@ -86,7 +91,7 @@ var PuckRendererInner = ({
86
91
  if (pageKey) {
87
92
  pageValue = mode === "published" ? await (0, import_puck_api2.getPublishedPuckPageApi)(baseURL, projectKey, businessUnitKey, pageKey) : await (0, import_puck_api2.getPreviewPuckPageApi)(baseURL, projectKey, businessUnitKey, pageKey);
88
93
  } else if (slug) {
89
- pageValue = await (0, import_puck_api2.queryPuckPageApi)(baseURL, projectKey, businessUnitKey, slug, mode);
94
+ pageValue = await (0, import_puck_api2.queryPuckPageApi)(baseURL, projectKey, businessUnitKey, { query: `slug = "${slug}"` }, mode);
90
95
  }
91
96
  if (!cancelled) {
92
97
  if (pageValue) {
@@ -148,7 +153,7 @@ var PuckRenderer = ({
148
153
  contentKey,
149
154
  query,
150
155
  mode = "published",
151
- config,
156
+ config = DEFAULT_CONFIG,
152
157
  loadingComponent,
153
158
  errorComponent,
154
159
  className,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/PuckDataRenderer.tsx","../src/PuckRenderer.tsx"],"sourcesContent":["export { PuckDataRenderer } from './PuckDataRenderer';\nexport type { PuckDataRendererProps } from './PuckDataRenderer';\n\nexport { PuckRenderer } from './PuckRenderer';\nexport type { PuckRendererProps } from './PuckRenderer';\n","import React from 'react';\nimport { Render } from '@measured/puck';\nimport type { Config, Data } from '@measured/puck';\nimport type { PuckData, PuckConfig } from '@commercetools-demo/puck-types';\n\nexport interface PuckDataRendererProps {\n /** The Puck Data to render (from the API or SSR props). */\n data: PuckData;\n /**\n * The Puck Config that defines available components and their render functions.\n * Must match the config used in the editor to ensure consistent output.\n */\n config: PuckConfig;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * SSR-friendly renderer — no data fetching, renders whatever Data you pass in.\n * Wrap with PuckApiProvider only if you use it alongside API hooks.\n */\nexport const PuckDataRenderer: React.FC<PuckDataRendererProps> = ({\n data,\n config,\n className,\n style,\n}) => {\n return (\n <div className={className} style={style}>\n <Render config={config as Config} data={data as Data} />\n </div>\n );\n};\n","import React, { useEffect, useState, type ReactElement } from 'react';\nimport { PuckApiProvider, usePuckApiContext } from '@commercetools-demo/puck-api';\nimport {\n getPublishedPuckPageApi,\n getPreviewPuckPageApi,\n queryPuckPageApi,\n getPublishedPuckContentApi,\n getPreviewPuckContentApi,\n queryPuckContentApi,\n} from '@commercetools-demo/puck-api';\nimport type { PuckConfig, PuckData } from '@commercetools-demo/puck-types';\nimport { PuckDataRenderer } from './PuckDataRenderer';\n\n// ---------------------------------------------------------------------------\n// Inner component (needs PuckApiContext)\n// ---------------------------------------------------------------------------\n\ninterface PuckRendererInnerProps {\n type: 'page' | 'content';\n pageKey?: string;\n slug?: string;\n contentKey?: string;\n query?: string;\n mode: 'published' | 'preview';\n config: PuckConfig;\n loadingComponent?: ReactElement;\n errorComponent?: ReactElement;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst PuckRendererInner: React.FC<PuckRendererInnerProps> = ({\n type,\n pageKey,\n slug,\n contentKey,\n query,\n mode,\n config,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const { baseURL, projectKey, businessUnitKey } = usePuckApiContext();\n\n const [data, setData] = useState<PuckData | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n if (type === 'content') {\n let puckData: PuckData | null = null;\n\n if (contentKey) {\n const value =\n mode === 'published'\n ? await getPublishedPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey)\n : await getPreviewPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey);\n puckData = value.data;\n } else if (query) {\n const value = await queryPuckContentApi(baseURL, projectKey, businessUnitKey, query, mode);\n puckData = value?.data ?? null;\n }\n\n if (!cancelled) {\n if (puckData) {\n setData(puckData);\n } else {\n setError('Content not found');\n }\n }\n } else {\n // type === 'page'\n let pageValue = null;\n\n if (pageKey) {\n pageValue =\n mode === 'published'\n ? await getPublishedPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey)\n : await getPreviewPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey);\n } else if (slug) {\n pageValue = await queryPuckPageApi(baseURL, projectKey, businessUnitKey, slug, mode);\n }\n\n if (!cancelled) {\n if (pageValue) {\n setData(pageValue.puckData);\n } else {\n setError('Page not found');\n }\n }\n }\n } catch (err) {\n if (!cancelled) setError((err as Error).message);\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n\n void fetchData();\n return () => {\n cancelled = true;\n };\n }, [baseURL, projectKey, businessUnitKey, type, pageKey, slug, contentKey, query, mode]);\n\n if (loading) {\n return (\n loadingComponent ?? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '64px',\n color: '#6b7280',\n }}\n >\n Loading…\n </div>\n )\n );\n }\n\n if (error || !data) {\n return (\n errorComponent ?? (\n <div\n style={{\n padding: '32px',\n color: '#dc2626',\n background: '#fef2f2',\n borderRadius: '8px',\n }}\n >\n {error ?? 'Failed to load'}\n </div>\n )\n );\n }\n\n return <PuckDataRenderer data={data} config={config} className={className} style={style} />;\n};\n\n// ---------------------------------------------------------------------------\n// Public component\n// ---------------------------------------------------------------------------\n\nexport interface PuckRendererProps {\n /**\n * Whether to render a page or a content item. Defaults to 'page'.\n * - 'page': use pageKey or slug to fetch\n * - 'content': use contentKey or query (contentType) to fetch\n */\n type?: 'page' | 'content';\n\n /**\n * Service base URL. Can be omitted if a PuckApiProvider is already in the tree.\n */\n baseURL?: string;\n /** CommerceTools project key. Can be omitted if provider is in tree. */\n projectKey?: string;\n /** Business unit key. Can be omitted if provider is in tree. */\n businessUnitKey?: string;\n\n /** [type=page] Fetch by page key. */\n pageKey?: string;\n /** [type=page] OR fetch by slug (URL path). */\n slug?: string;\n\n /** [type=content] Fetch by content key. */\n contentKey?: string;\n /** [type=content] OR fetch by contentType query string. */\n query?: string;\n\n /** 'published' (default) or 'preview' (draft || published). */\n mode?: 'published' | 'preview';\n\n /**\n * Puck config — must match the config used in the editor.\n */\n config: PuckConfig;\n\n /** Custom loading indicator. */\n loadingComponent?: ReactElement;\n /** Custom error display. */\n errorComponent?: ReactElement;\n\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const PuckRenderer: React.FC<PuckRendererProps> = ({\n type = 'page',\n baseURL,\n projectKey,\n businessUnitKey,\n pageKey,\n slug,\n contentKey,\n query,\n mode = 'published',\n config,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const inner = (\n <PuckRendererInner\n type={type}\n pageKey={pageKey}\n slug={slug}\n contentKey={contentKey}\n query={query}\n mode={mode}\n config={config}\n loadingComponent={loadingComponent}\n errorComponent={errorComponent}\n className={className}\n style={style}\n />\n );\n\n if (baseURL && projectKey && businessUnitKey) {\n return (\n <PuckApiProvider\n baseURL={baseURL}\n projectKey={projectKey}\n businessUnitKey={businessUnitKey}\n >\n {inner}\n </PuckApiProvider>\n );\n }\n\n return inner;\n};\n"],"mappings":"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","names":["import_puck_api","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/PuckDataRenderer.tsx","../src/PuckRenderer.tsx"],"sourcesContent":["export { PuckDataRenderer } from './PuckDataRenderer';\nexport type { PuckDataRendererProps } from './PuckDataRenderer';\n\nexport { PuckRenderer } from './PuckRenderer';\nexport type { PuckRendererProps } from './PuckRenderer';\n","import React from 'react';\nimport { Render } from '@measured/puck';\nimport type { Config, Data } from '@measured/puck';\nimport type { PuckData, PuckConfig } from '@commercetools-demo/puck-types';\n\nexport interface PuckDataRendererProps {\n /** The Puck Data to render (from the API or SSR props). */\n data: PuckData;\n /**\n * The Puck Config that defines available components and their render functions.\n * Must match the config used in the editor to ensure consistent output.\n */\n config: PuckConfig;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * SSR-friendly renderer — no data fetching, renders whatever Data you pass in.\n * Wrap with PuckApiProvider only if you use it alongside API hooks.\n */\nexport const PuckDataRenderer: React.FC<PuckDataRendererProps> = ({\n data,\n config,\n className,\n style,\n}) => {\n return (\n <div className={className} style={style}>\n <Render config={config as Config} data={data as Data} />\n </div>\n );\n};\n","import React, { useEffect, useState, type ReactElement } from 'react';\nimport { PuckApiProvider, usePuckApiContext } from '@commercetools-demo/puck-api';\nimport { defaultPuckConfig } from '@commercetools-demo/puck-editor';\nimport {\n getPublishedPuckPageApi,\n getPreviewPuckPageApi,\n queryPuckPageApi,\n getPublishedPuckContentApi,\n getPreviewPuckContentApi,\n queryPuckContentApi,\n} from '@commercetools-demo/puck-api';\nimport type { PuckConfig, PuckData } from '@commercetools-demo/puck-types';\nimport { PuckDataRenderer } from './PuckDataRenderer';\n\nconst DEFAULT_CONFIG: PuckConfig = {\n ...defaultPuckConfig,\n components: { ...defaultPuckConfig.components },\n};\n\n// ---------------------------------------------------------------------------\n// Inner component (needs PuckApiContext)\n// ---------------------------------------------------------------------------\n\ninterface PuckRendererInnerProps {\n type: 'page' | 'content';\n pageKey?: string;\n slug?: string;\n contentKey?: string;\n query?: string;\n mode: 'published' | 'preview';\n config: PuckConfig;\n loadingComponent?: ReactElement;\n errorComponent?: ReactElement;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst PuckRendererInner: React.FC<PuckRendererInnerProps> = ({\n type,\n pageKey,\n slug,\n contentKey,\n query,\n mode,\n config,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const { baseURL, projectKey, businessUnitKey } = usePuckApiContext();\n\n const [data, setData] = useState<PuckData | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n if (type === 'content') {\n let puckData: PuckData | null = null;\n\n if (contentKey) {\n const value =\n mode === 'published'\n ? await getPublishedPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey)\n : await getPreviewPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey);\n puckData = value.data;\n } else if (query) {\n const value = await queryPuckContentApi(baseURL, projectKey, businessUnitKey, { query: `contentType = \"${query}\"` }, mode);\n puckData = value?.data ?? null;\n }\n\n if (!cancelled) {\n if (puckData) {\n setData(puckData);\n } else {\n setError('Content not found');\n }\n }\n } else {\n // type === 'page'\n let pageValue = null;\n\n if (pageKey) {\n pageValue =\n mode === 'published'\n ? await getPublishedPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey)\n : await getPreviewPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey);\n } else if (slug) {\n pageValue = await queryPuckPageApi(baseURL, projectKey, businessUnitKey, { query: `slug = \"${slug}\"` }, mode);\n }\n\n if (!cancelled) {\n if (pageValue) {\n setData(pageValue.puckData);\n } else {\n setError('Page not found');\n }\n }\n }\n } catch (err) {\n if (!cancelled) setError((err as Error).message);\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n\n void fetchData();\n return () => {\n cancelled = true;\n };\n }, [baseURL, projectKey, businessUnitKey, type, pageKey, slug, contentKey, query, mode]);\n\n if (loading) {\n return (\n loadingComponent ?? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '64px',\n color: '#6b7280',\n }}\n >\n Loading…\n </div>\n )\n );\n }\n\n if (error || !data) {\n return (\n errorComponent ?? (\n <div\n style={{\n padding: '32px',\n color: '#dc2626',\n background: '#fef2f2',\n borderRadius: '8px',\n }}\n >\n {error ?? 'Failed to load'}\n </div>\n )\n );\n }\n\n return <PuckDataRenderer data={data} config={config} className={className} style={style} />;\n};\n\n// ---------------------------------------------------------------------------\n// Public component\n// ---------------------------------------------------------------------------\n\nexport interface PuckRendererProps {\n /**\n * Whether to render a page or a content item. Defaults to 'page'.\n * - 'page': use pageKey or slug to fetch\n * - 'content': use contentKey or query (contentType) to fetch\n */\n type?: 'page' | 'content';\n\n /**\n * Service base URL. Can be omitted if a PuckApiProvider is already in the tree.\n */\n baseURL?: string;\n /** CommerceTools project key. Can be omitted if provider is in tree. */\n projectKey?: string;\n /** Business unit key. Can be omitted if provider is in tree. */\n businessUnitKey?: string;\n\n /** [type=page] Fetch by page key. */\n pageKey?: string;\n /** [type=page] OR fetch by slug (URL path). */\n slug?: string;\n\n /** [type=content] Fetch by content key. */\n contentKey?: string;\n /** [type=content] OR fetch by contentType query string. */\n query?: string;\n\n /** 'published' (default) or 'preview' (draft || published). */\n mode?: 'published' | 'preview';\n\n /**\n * Puck config — must match the config used in the editor. Defaults to defaultPuckConfig.\n */\n config?: PuckConfig;\n\n /** Custom loading indicator. */\n loadingComponent?: ReactElement;\n /** Custom error display. */\n errorComponent?: ReactElement;\n\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const PuckRenderer: React.FC<PuckRendererProps> = ({\n type = 'page',\n baseURL,\n projectKey,\n businessUnitKey,\n pageKey,\n slug,\n contentKey,\n query,\n mode = 'published',\n config = DEFAULT_CONFIG,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const inner = (\n <PuckRendererInner\n type={type}\n pageKey={pageKey}\n slug={slug}\n contentKey={contentKey}\n query={query}\n mode={mode}\n config={config}\n loadingComponent={loadingComponent}\n errorComponent={errorComponent}\n className={className}\n style={style}\n />\n );\n\n if (baseURL && projectKey && businessUnitKey) {\n return (\n <PuckApiProvider\n baseURL={baseURL}\n projectKey={projectKey}\n businessUnitKey={businessUnitKey}\n >\n {inner}\n </PuckApiProvider>\n );\n }\n\n return inner;\n};\n"],"mappings":"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","names":["import_puck_api","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -13,6 +13,7 @@ var PuckDataRenderer = ({
13
13
  // src/PuckRenderer.tsx
14
14
  import { useEffect, useState } from "react";
15
15
  import { PuckApiProvider, usePuckApiContext } from "@commercetools-demo/puck-api";
16
+ import { defaultPuckConfig } from "@commercetools-demo/puck-editor";
16
17
  import {
17
18
  getPublishedPuckPageApi,
18
19
  getPreviewPuckPageApi,
@@ -22,6 +23,10 @@ import {
22
23
  queryPuckContentApi
23
24
  } from "@commercetools-demo/puck-api";
24
25
  import { jsx as jsx2 } from "react/jsx-runtime";
26
+ var DEFAULT_CONFIG = {
27
+ ...defaultPuckConfig,
28
+ components: { ...defaultPuckConfig.components }
29
+ };
25
30
  var PuckRendererInner = ({
26
31
  type,
27
32
  pageKey,
@@ -51,7 +56,7 @@ var PuckRendererInner = ({
51
56
  const value = mode === "published" ? await getPublishedPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey) : await getPreviewPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey);
52
57
  puckData = value.data;
53
58
  } else if (query) {
54
- const value = await queryPuckContentApi(baseURL, projectKey, businessUnitKey, query, mode);
59
+ const value = await queryPuckContentApi(baseURL, projectKey, businessUnitKey, { query: `contentType = "${query}"` }, mode);
55
60
  puckData = value?.data ?? null;
56
61
  }
57
62
  if (!cancelled) {
@@ -66,7 +71,7 @@ var PuckRendererInner = ({
66
71
  if (pageKey) {
67
72
  pageValue = mode === "published" ? await getPublishedPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey) : await getPreviewPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey);
68
73
  } else if (slug) {
69
- pageValue = await queryPuckPageApi(baseURL, projectKey, businessUnitKey, slug, mode);
74
+ pageValue = await queryPuckPageApi(baseURL, projectKey, businessUnitKey, { query: `slug = "${slug}"` }, mode);
70
75
  }
71
76
  if (!cancelled) {
72
77
  if (pageValue) {
@@ -128,7 +133,7 @@ var PuckRenderer = ({
128
133
  contentKey,
129
134
  query,
130
135
  mode = "published",
131
- config,
136
+ config = DEFAULT_CONFIG,
132
137
  loadingComponent,
133
138
  errorComponent,
134
139
  className,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/PuckDataRenderer.tsx","../src/PuckRenderer.tsx"],"sourcesContent":["import React from 'react';\nimport { Render } from '@measured/puck';\nimport type { Config, Data } from '@measured/puck';\nimport type { PuckData, PuckConfig } from '@commercetools-demo/puck-types';\n\nexport interface PuckDataRendererProps {\n /** The Puck Data to render (from the API or SSR props). */\n data: PuckData;\n /**\n * The Puck Config that defines available components and their render functions.\n * Must match the config used in the editor to ensure consistent output.\n */\n config: PuckConfig;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * SSR-friendly renderer — no data fetching, renders whatever Data you pass in.\n * Wrap with PuckApiProvider only if you use it alongside API hooks.\n */\nexport const PuckDataRenderer: React.FC<PuckDataRendererProps> = ({\n data,\n config,\n className,\n style,\n}) => {\n return (\n <div className={className} style={style}>\n <Render config={config as Config} data={data as Data} />\n </div>\n );\n};\n","import React, { useEffect, useState, type ReactElement } from 'react';\nimport { PuckApiProvider, usePuckApiContext } from '@commercetools-demo/puck-api';\nimport {\n getPublishedPuckPageApi,\n getPreviewPuckPageApi,\n queryPuckPageApi,\n getPublishedPuckContentApi,\n getPreviewPuckContentApi,\n queryPuckContentApi,\n} from '@commercetools-demo/puck-api';\nimport type { PuckConfig, PuckData } from '@commercetools-demo/puck-types';\nimport { PuckDataRenderer } from './PuckDataRenderer';\n\n// ---------------------------------------------------------------------------\n// Inner component (needs PuckApiContext)\n// ---------------------------------------------------------------------------\n\ninterface PuckRendererInnerProps {\n type: 'page' | 'content';\n pageKey?: string;\n slug?: string;\n contentKey?: string;\n query?: string;\n mode: 'published' | 'preview';\n config: PuckConfig;\n loadingComponent?: ReactElement;\n errorComponent?: ReactElement;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst PuckRendererInner: React.FC<PuckRendererInnerProps> = ({\n type,\n pageKey,\n slug,\n contentKey,\n query,\n mode,\n config,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const { baseURL, projectKey, businessUnitKey } = usePuckApiContext();\n\n const [data, setData] = useState<PuckData | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n if (type === 'content') {\n let puckData: PuckData | null = null;\n\n if (contentKey) {\n const value =\n mode === 'published'\n ? await getPublishedPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey)\n : await getPreviewPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey);\n puckData = value.data;\n } else if (query) {\n const value = await queryPuckContentApi(baseURL, projectKey, businessUnitKey, query, mode);\n puckData = value?.data ?? null;\n }\n\n if (!cancelled) {\n if (puckData) {\n setData(puckData);\n } else {\n setError('Content not found');\n }\n }\n } else {\n // type === 'page'\n let pageValue = null;\n\n if (pageKey) {\n pageValue =\n mode === 'published'\n ? await getPublishedPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey)\n : await getPreviewPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey);\n } else if (slug) {\n pageValue = await queryPuckPageApi(baseURL, projectKey, businessUnitKey, slug, mode);\n }\n\n if (!cancelled) {\n if (pageValue) {\n setData(pageValue.puckData);\n } else {\n setError('Page not found');\n }\n }\n }\n } catch (err) {\n if (!cancelled) setError((err as Error).message);\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n\n void fetchData();\n return () => {\n cancelled = true;\n };\n }, [baseURL, projectKey, businessUnitKey, type, pageKey, slug, contentKey, query, mode]);\n\n if (loading) {\n return (\n loadingComponent ?? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '64px',\n color: '#6b7280',\n }}\n >\n Loading…\n </div>\n )\n );\n }\n\n if (error || !data) {\n return (\n errorComponent ?? (\n <div\n style={{\n padding: '32px',\n color: '#dc2626',\n background: '#fef2f2',\n borderRadius: '8px',\n }}\n >\n {error ?? 'Failed to load'}\n </div>\n )\n );\n }\n\n return <PuckDataRenderer data={data} config={config} className={className} style={style} />;\n};\n\n// ---------------------------------------------------------------------------\n// Public component\n// ---------------------------------------------------------------------------\n\nexport interface PuckRendererProps {\n /**\n * Whether to render a page or a content item. Defaults to 'page'.\n * - 'page': use pageKey or slug to fetch\n * - 'content': use contentKey or query (contentType) to fetch\n */\n type?: 'page' | 'content';\n\n /**\n * Service base URL. Can be omitted if a PuckApiProvider is already in the tree.\n */\n baseURL?: string;\n /** CommerceTools project key. Can be omitted if provider is in tree. */\n projectKey?: string;\n /** Business unit key. Can be omitted if provider is in tree. */\n businessUnitKey?: string;\n\n /** [type=page] Fetch by page key. */\n pageKey?: string;\n /** [type=page] OR fetch by slug (URL path). */\n slug?: string;\n\n /** [type=content] Fetch by content key. */\n contentKey?: string;\n /** [type=content] OR fetch by contentType query string. */\n query?: string;\n\n /** 'published' (default) or 'preview' (draft || published). */\n mode?: 'published' | 'preview';\n\n /**\n * Puck config — must match the config used in the editor.\n */\n config: PuckConfig;\n\n /** Custom loading indicator. */\n loadingComponent?: ReactElement;\n /** Custom error display. */\n errorComponent?: ReactElement;\n\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const PuckRenderer: React.FC<PuckRendererProps> = ({\n type = 'page',\n baseURL,\n projectKey,\n businessUnitKey,\n pageKey,\n slug,\n contentKey,\n query,\n mode = 'published',\n config,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const inner = (\n <PuckRendererInner\n type={type}\n pageKey={pageKey}\n slug={slug}\n contentKey={contentKey}\n query={query}\n mode={mode}\n config={config}\n loadingComponent={loadingComponent}\n errorComponent={errorComponent}\n className={className}\n style={style}\n />\n );\n\n if (baseURL && projectKey && businessUnitKey) {\n return (\n <PuckApiProvider\n baseURL={baseURL}\n projectKey={projectKey}\n businessUnitKey={businessUnitKey}\n >\n {inner}\n </PuckApiProvider>\n );\n }\n\n return inner;\n};\n"],"mappings":"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","names":["jsx"]}
1
+ {"version":3,"sources":["../src/PuckDataRenderer.tsx","../src/PuckRenderer.tsx"],"sourcesContent":["import React from 'react';\nimport { Render } from '@measured/puck';\nimport type { Config, Data } from '@measured/puck';\nimport type { PuckData, PuckConfig } from '@commercetools-demo/puck-types';\n\nexport interface PuckDataRendererProps {\n /** The Puck Data to render (from the API or SSR props). */\n data: PuckData;\n /**\n * The Puck Config that defines available components and their render functions.\n * Must match the config used in the editor to ensure consistent output.\n */\n config: PuckConfig;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * SSR-friendly renderer — no data fetching, renders whatever Data you pass in.\n * Wrap with PuckApiProvider only if you use it alongside API hooks.\n */\nexport const PuckDataRenderer: React.FC<PuckDataRendererProps> = ({\n data,\n config,\n className,\n style,\n}) => {\n return (\n <div className={className} style={style}>\n <Render config={config as Config} data={data as Data} />\n </div>\n );\n};\n","import React, { useEffect, useState, type ReactElement } from 'react';\nimport { PuckApiProvider, usePuckApiContext } from '@commercetools-demo/puck-api';\nimport { defaultPuckConfig } from '@commercetools-demo/puck-editor';\nimport {\n getPublishedPuckPageApi,\n getPreviewPuckPageApi,\n queryPuckPageApi,\n getPublishedPuckContentApi,\n getPreviewPuckContentApi,\n queryPuckContentApi,\n} from '@commercetools-demo/puck-api';\nimport type { PuckConfig, PuckData } from '@commercetools-demo/puck-types';\nimport { PuckDataRenderer } from './PuckDataRenderer';\n\nconst DEFAULT_CONFIG: PuckConfig = {\n ...defaultPuckConfig,\n components: { ...defaultPuckConfig.components },\n};\n\n// ---------------------------------------------------------------------------\n// Inner component (needs PuckApiContext)\n// ---------------------------------------------------------------------------\n\ninterface PuckRendererInnerProps {\n type: 'page' | 'content';\n pageKey?: string;\n slug?: string;\n contentKey?: string;\n query?: string;\n mode: 'published' | 'preview';\n config: PuckConfig;\n loadingComponent?: ReactElement;\n errorComponent?: ReactElement;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst PuckRendererInner: React.FC<PuckRendererInnerProps> = ({\n type,\n pageKey,\n slug,\n contentKey,\n query,\n mode,\n config,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const { baseURL, projectKey, businessUnitKey } = usePuckApiContext();\n\n const [data, setData] = useState<PuckData | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n if (type === 'content') {\n let puckData: PuckData | null = null;\n\n if (contentKey) {\n const value =\n mode === 'published'\n ? await getPublishedPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey)\n : await getPreviewPuckContentApi(baseURL, projectKey, businessUnitKey, contentKey);\n puckData = value.data;\n } else if (query) {\n const value = await queryPuckContentApi(baseURL, projectKey, businessUnitKey, { query: `contentType = \"${query}\"` }, mode);\n puckData = value?.data ?? null;\n }\n\n if (!cancelled) {\n if (puckData) {\n setData(puckData);\n } else {\n setError('Content not found');\n }\n }\n } else {\n // type === 'page'\n let pageValue = null;\n\n if (pageKey) {\n pageValue =\n mode === 'published'\n ? await getPublishedPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey)\n : await getPreviewPuckPageApi(baseURL, projectKey, businessUnitKey, pageKey);\n } else if (slug) {\n pageValue = await queryPuckPageApi(baseURL, projectKey, businessUnitKey, { query: `slug = \"${slug}\"` }, mode);\n }\n\n if (!cancelled) {\n if (pageValue) {\n setData(pageValue.puckData);\n } else {\n setError('Page not found');\n }\n }\n }\n } catch (err) {\n if (!cancelled) setError((err as Error).message);\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n\n void fetchData();\n return () => {\n cancelled = true;\n };\n }, [baseURL, projectKey, businessUnitKey, type, pageKey, slug, contentKey, query, mode]);\n\n if (loading) {\n return (\n loadingComponent ?? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '64px',\n color: '#6b7280',\n }}\n >\n Loading…\n </div>\n )\n );\n }\n\n if (error || !data) {\n return (\n errorComponent ?? (\n <div\n style={{\n padding: '32px',\n color: '#dc2626',\n background: '#fef2f2',\n borderRadius: '8px',\n }}\n >\n {error ?? 'Failed to load'}\n </div>\n )\n );\n }\n\n return <PuckDataRenderer data={data} config={config} className={className} style={style} />;\n};\n\n// ---------------------------------------------------------------------------\n// Public component\n// ---------------------------------------------------------------------------\n\nexport interface PuckRendererProps {\n /**\n * Whether to render a page or a content item. Defaults to 'page'.\n * - 'page': use pageKey or slug to fetch\n * - 'content': use contentKey or query (contentType) to fetch\n */\n type?: 'page' | 'content';\n\n /**\n * Service base URL. Can be omitted if a PuckApiProvider is already in the tree.\n */\n baseURL?: string;\n /** CommerceTools project key. Can be omitted if provider is in tree. */\n projectKey?: string;\n /** Business unit key. Can be omitted if provider is in tree. */\n businessUnitKey?: string;\n\n /** [type=page] Fetch by page key. */\n pageKey?: string;\n /** [type=page] OR fetch by slug (URL path). */\n slug?: string;\n\n /** [type=content] Fetch by content key. */\n contentKey?: string;\n /** [type=content] OR fetch by contentType query string. */\n query?: string;\n\n /** 'published' (default) or 'preview' (draft || published). */\n mode?: 'published' | 'preview';\n\n /**\n * Puck config — must match the config used in the editor. Defaults to defaultPuckConfig.\n */\n config?: PuckConfig;\n\n /** Custom loading indicator. */\n loadingComponent?: ReactElement;\n /** Custom error display. */\n errorComponent?: ReactElement;\n\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const PuckRenderer: React.FC<PuckRendererProps> = ({\n type = 'page',\n baseURL,\n projectKey,\n businessUnitKey,\n pageKey,\n slug,\n contentKey,\n query,\n mode = 'published',\n config = DEFAULT_CONFIG,\n loadingComponent,\n errorComponent,\n className,\n style,\n}) => {\n const inner = (\n <PuckRendererInner\n type={type}\n pageKey={pageKey}\n slug={slug}\n contentKey={contentKey}\n query={query}\n mode={mode}\n config={config}\n loadingComponent={loadingComponent}\n errorComponent={errorComponent}\n className={className}\n style={style}\n />\n );\n\n if (baseURL && projectKey && businessUnitKey) {\n return (\n <PuckApiProvider\n baseURL={baseURL}\n projectKey={projectKey}\n businessUnitKey={businessUnitKey}\n >\n {inner}\n </PuckApiProvider>\n );\n }\n\n return inner;\n};\n"],"mappings":"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","names":["jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools-demo/puck-renderer",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Lightweight Puck page renderer for storefronts",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -25,8 +25,9 @@
25
25
  "typecheck": "tsc --noEmit"
26
26
  },
27
27
  "dependencies": {
28
- "@commercetools-demo/puck-api": "^0.2.1",
29
- "@commercetools-demo/puck-types": "^0.2.1",
28
+ "@commercetools-demo/puck-api": "^0.3.0",
29
+ "@commercetools-demo/puck-editor": "^0.3.0",
30
+ "@commercetools-demo/puck-types": "^0.3.0",
30
31
  "@measured/puck": "^0.18.2"
31
32
  },
32
33
  "peerDependencies": {