@sitecore-content-sdk/react 2.2.1 → 2.3.0-beta.atoms.20260721120640

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.
Files changed (77) hide show
  1. package/dist/cjs/atoms/catalog-serializer.js +43 -0
  2. package/dist/cjs/atoms/create-ncc.js +75 -0
  3. package/dist/cjs/atoms/define-atoms-catalog.js +44 -0
  4. package/dist/cjs/atoms/define-atoms-registry.js +36 -0
  5. package/dist/cjs/atoms/field-schemas.js +88 -0
  6. package/dist/cjs/atoms/index.js +35 -0
  7. package/dist/cjs/atoms/re-exports.js +24 -0
  8. package/dist/cjs/atoms/schema-utils.js +19 -0
  9. package/dist/cjs/atoms/types.js +2 -0
  10. package/dist/cjs/components/DesignLibrary/DesignLibrary.js +8 -2
  11. package/dist/cjs/components/DesignLibrary/DesignLibraryLowCodeComponent.js +109 -0
  12. package/dist/cjs/components/DesignLibrary/StudioComponentServerWrapper.js +93 -0
  13. package/dist/cjs/components/DesignLibrary/StudioComponentWrapper.js +62 -0
  14. package/dist/cjs/components/DesignLibrary/index.js +3 -1
  15. package/dist/cjs/components/Placeholder/placeholder-utils.js +14 -3
  16. package/dist/cjs/components/SitecoreProvider.js +4 -2
  17. package/dist/cjs/index.js +14 -2
  18. package/dist/esm/atoms/catalog-serializer.js +40 -0
  19. package/dist/esm/atoms/create-ncc.js +39 -0
  20. package/dist/esm/atoms/define-atoms-catalog.js +41 -0
  21. package/dist/esm/atoms/define-atoms-registry.js +33 -0
  22. package/dist/esm/atoms/field-schemas.js +79 -0
  23. package/dist/esm/atoms/index.js +7 -0
  24. package/dist/esm/atoms/re-exports.js +21 -0
  25. package/dist/esm/atoms/schema-utils.js +16 -0
  26. package/dist/esm/atoms/types.js +1 -0
  27. package/dist/esm/components/DesignLibrary/DesignLibrary.js +8 -2
  28. package/dist/esm/components/DesignLibrary/DesignLibraryLowCodeComponent.js +71 -0
  29. package/dist/esm/components/DesignLibrary/StudioComponentServerWrapper.js +86 -0
  30. package/dist/esm/components/DesignLibrary/StudioComponentWrapper.js +25 -0
  31. package/dist/esm/components/DesignLibrary/index.js +1 -0
  32. package/dist/esm/components/Image.js +1 -1
  33. package/dist/esm/components/Link.js +1 -1
  34. package/dist/esm/components/Placeholder/placeholder-utils.js +14 -3
  35. package/dist/esm/components/SitecoreProvider.js +4 -2
  36. package/dist/esm/index.js +3 -2
  37. package/package.json +9 -7
  38. package/types/atoms/catalog-serializer.d.ts +11 -0
  39. package/types/atoms/catalog-serializer.d.ts.map +1 -0
  40. package/types/atoms/create-ncc.d.ts +24 -0
  41. package/types/atoms/create-ncc.d.ts.map +1 -0
  42. package/types/atoms/define-atoms-catalog.d.ts +65 -0
  43. package/types/atoms/define-atoms-catalog.d.ts.map +1 -0
  44. package/types/atoms/define-atoms-registry.d.ts +33 -0
  45. package/types/atoms/define-atoms-registry.d.ts.map +1 -0
  46. package/types/atoms/field-schemas.d.ts +120 -0
  47. package/types/atoms/field-schemas.d.ts.map +1 -0
  48. package/types/atoms/index.d.ts +9 -0
  49. package/types/atoms/index.d.ts.map +1 -0
  50. package/types/atoms/re-exports.d.ts +22 -0
  51. package/types/atoms/re-exports.d.ts.map +1 -0
  52. package/types/atoms/schema-utils.d.ts +20 -0
  53. package/types/atoms/schema-utils.d.ts.map +1 -0
  54. package/types/atoms/types.d.ts +78 -0
  55. package/types/atoms/types.d.ts.map +1 -0
  56. package/types/components/DesignLibrary/DesignLibrary.d.ts.map +1 -1
  57. package/types/components/DesignLibrary/DesignLibraryLowCodeComponent.d.ts +13 -0
  58. package/types/components/DesignLibrary/DesignLibraryLowCodeComponent.d.ts.map +1 -0
  59. package/types/components/DesignLibrary/StudioComponentServerWrapper.d.ts +33 -0
  60. package/types/components/DesignLibrary/StudioComponentServerWrapper.d.ts.map +1 -0
  61. package/types/components/DesignLibrary/StudioComponentWrapper.d.ts +25 -0
  62. package/types/components/DesignLibrary/StudioComponentWrapper.d.ts.map +1 -0
  63. package/types/components/DesignLibrary/index.d.ts +1 -0
  64. package/types/components/DesignLibrary/index.d.ts.map +1 -1
  65. package/types/components/Image.d.ts +37 -1
  66. package/types/components/Image.d.ts.map +1 -1
  67. package/types/components/Link.d.ts +24 -1
  68. package/types/components/Link.d.ts.map +1 -1
  69. package/types/components/Placeholder/placeholder-utils.d.ts.map +1 -1
  70. package/types/components/RichText.d.ts +8 -1
  71. package/types/components/RichText.d.ts.map +1 -1
  72. package/types/components/SitecoreProvider.d.ts +11 -0
  73. package/types/components/SitecoreProvider.d.ts.map +1 -1
  74. package/types/components/Text.d.ts +8 -1
  75. package/types/components/Text.d.ts.map +1 -1
  76. package/types/index.d.ts +7 -6
  77. package/types/index.d.ts.map +1 -1
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ 'use client';
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.StudioComponentWrapper = void 0;
38
+ const react_1 = __importStar(require("react"));
39
+ const atoms_1 = require("../../atoms");
40
+ const SitecoreProvider_1 = require("../SitecoreProvider");
41
+ /**
42
+ * Client component that renders a pre-fetched Studio (NCC) component layout.
43
+ *
44
+ * Expects `document` to be provided (fetched server-side by
45
+ * `StudioComponentServerWrapper`, from Design Library document updates, or any other
46
+ * preview path that supplies a layout `Document`). Renders `null` when no layout
47
+ * is available.
48
+ * @param {StudioComponentWrapperProps} props component props
49
+ * @internal
50
+ */
51
+ const StudioComponentWrapper = ({ document, fields, params, }) => {
52
+ const { atomsConfig } = (0, SitecoreProvider_1.useSitecore)();
53
+ const NCComponent = (0, react_1.useMemo)(() => {
54
+ if (!document || !atomsConfig)
55
+ return null;
56
+ return (0, atoms_1.createNCC)(document, atomsConfig.registry);
57
+ }, [document, atomsConfig]);
58
+ if (!NCComponent)
59
+ return null;
60
+ return react_1.default.createElement(NCComponent, { fields: fields, params: params });
61
+ };
62
+ exports.StudioComponentWrapper = StudioComponentWrapper;
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.noopLoadImportMap = exports.DesignLibraryErrorBoundary = exports.DesignLibrary = void 0;
3
+ exports.noopLoadImportMap = exports.DesignLibraryErrorBoundary = exports.DesignLibraryLowCodeComponent = exports.DesignLibrary = void 0;
4
4
  var DesignLibrary_1 = require("./DesignLibrary");
5
5
  Object.defineProperty(exports, "DesignLibrary", { enumerable: true, get: function () { return DesignLibrary_1.DesignLibrary; } });
6
+ var DesignLibraryLowCodeComponent_1 = require("./DesignLibraryLowCodeComponent");
7
+ Object.defineProperty(exports, "DesignLibraryLowCodeComponent", { enumerable: true, get: function () { return DesignLibraryLowCodeComponent_1.DesignLibraryLowCodeComponent; } });
6
8
  var DesignLibraryErrorBoundary_1 = require("./DesignLibraryErrorBoundary");
7
9
  Object.defineProperty(exports, "DesignLibraryErrorBoundary", { enumerable: true, get: function () { return DesignLibraryErrorBoundary_1.DesignLibraryErrorBoundary; } });
8
10
  var loadImportMap_1 = require("./loadImportMap");
@@ -12,6 +12,7 @@ const layout_1 = require("@sitecore-content-sdk/content/layout");
12
12
  const content_1 = require("@sitecore-content-sdk/content");
13
13
  const HiddenRendering_1 = require("../HiddenRendering");
14
14
  const FEaaS_1 = require("../FEaaS");
15
+ const StudioComponentServerWrapper_1 = require("../DesignLibrary/StudioComponentServerWrapper");
15
16
  /**
16
17
  * Get the renderings for the specified placeholder from the rendering layout data.
17
18
  * @param {ComponentRendering | RouteData } rendering rendering data
@@ -109,7 +110,7 @@ function getChildComponentProps(placeholderProps, componentRendering) {
109
110
  * @returns {ContentSDKComponet | null} component implementation or null if no component map is provided
110
111
  */
111
112
  const getComponentForRendering = (renderingDefinition, placeholderName, componentMap, hiddenRenderingComponent, missingComponentComponent) => {
112
- var _a, _b;
113
+ var _a, _b, _c;
113
114
  const logUnknownComponentError = (variant) => {
114
115
  console.error(`Placeholder ${placeholderName} contains unknown component ${renderingDefinition.componentName}${variant ? ` (${variant})` : ''}. Ensure that a React component exists for it, and that it is registered in your component-map file.`);
115
116
  };
@@ -127,6 +128,16 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
127
128
  componentType: 'universal',
128
129
  };
129
130
  }
131
+ if ((_a = renderingDefinition.params) === null || _a === void 0 ? void 0 : _a.ComponentRef) {
132
+ return {
133
+ component: (props) => {
134
+ var _a;
135
+ return (react_1.default.createElement(StudioComponentServerWrapper_1.StudioComponentServerWrapper, { componentRef: props.rendering.params.ComponentRef, fieldNames: (_a = props.rendering.params) === null || _a === void 0 ? void 0 : _a.fieldNames, fields: props.fields, params: props.params }));
136
+ },
137
+ isEmpty: false,
138
+ componentType: 'server',
139
+ };
140
+ }
130
141
  let component = null;
131
142
  if (!componentMap || componentMap.size === 0) {
132
143
  console.warn(`No components were available in component map to service request for component ${renderingDefinition}`);
@@ -175,7 +186,7 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
175
186
  };
176
187
  }
177
188
  // Render SXA Rendering Variant if available
178
- const exportName = (_a = renderingDefinition.params) === null || _a === void 0 ? void 0 : _a.FieldNames;
189
+ const exportName = (_b = renderingDefinition.params) === null || _b === void 0 ? void 0 : _b.FieldNames;
179
190
  const renderedComponent = exportName && exportName !== sharedTypes_1.DEFAULT_EXPORT_NAME
180
191
  ? component[exportName]
181
192
  : component.default ||
@@ -189,7 +200,7 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
189
200
  componentType: 'universal',
190
201
  };
191
202
  }
192
- const dynamic = !!((_b = renderedComponent.render) === null || _b === void 0 ? void 0 : _b.preload) ||
203
+ const dynamic = !!((_c = renderedComponent.render) === null || _c === void 0 ? void 0 : _c.preload) ||
193
204
  renderingDefinition.componentName === FEaaS_1.BYOC_WRAPPER_RENDERING_NAME;
194
205
  // all dynamic elements will have a separate render prop
195
206
  return {
@@ -56,12 +56,13 @@ exports.ImportMapReactContext = react_1.default.createContext(undefined);
56
56
  * @param {SitecoreProviderProps['page']} props.page - The page data.
57
57
  * @param {SitecoreProviderProps['componentMap']} props.componentMap - The component map.
58
58
  * @param {SitecoreProviderProps['loadImportMap']} props.loadImportMap - Optional function to load the import map for Design Library variant generation. When omitted, an empty import map is used (ex: code generation is disabled).
59
+ * @param {SitecoreProviderProps['atomsConfig']} props.atomsConfig - Atoms config (catalog + registry) for rendering low-code components.
59
60
  * @param {React.ReactNode} props.children - The children to render.
60
61
  * @returns {React.ReactNode} The SitecoreProvider component.
61
62
  * @public
62
63
  */
63
64
  const SitecoreProvider = (props) => {
64
- const { api, page: propsPage, componentMap, loadImportMap = loadImportMap_1.noopLoadImportMap, children } = props;
65
+ const { api, page: propsPage, componentMap, loadImportMap = loadImportMap_1.noopLoadImportMap, atomsConfig, children, } = props;
65
66
  const [page, setPageInternal] = (0, react_1.useState)(propsPage);
66
67
  // Memoize setPage callback
67
68
  const setPage = (0, react_1.useCallback)((value) => {
@@ -80,7 +81,8 @@ const SitecoreProvider = (props) => {
80
81
  api,
81
82
  componentMap,
82
83
  loadImportMap,
83
- }), [page, setPage, api, componentMap, loadImportMap]);
84
+ atomsConfig,
85
+ }), [page, setPage, api, componentMap, loadImportMap, atomsConfig]);
84
86
  return (react_1.default.createElement(exports.SitecoreProviderReactContext.Provider, { value: contextValue }, children));
85
87
  };
86
88
  exports.SitecoreProvider = SitecoreProvider;
package/dist/cjs/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withDatasourceCheck = exports.withSitecore = exports.withEditorChromes = exports.ErrorComponent = exports.useSitecore = exports.SitecoreProviderReactContext = exports.SitecoreProvider = exports.File = exports.Link = exports.noopLoadImportMap = exports.DesignLibraryErrorBoundary = exports.DesignLibrary = exports.BYOCServerWrapper = exports.FEaaSServerWrapper = exports.FEaaSClientWrapper = exports.FEaaSWrapper = exports.BYOCClientWrapper = exports.BYOCWrapper = exports.fetchBYOCComponentServerProps = exports.BYOCComponent = exports.fetchFEaaSComponentServerProps = exports.FEaaSComponent = exports.DateField = exports.Text = exports.RichText = exports.Image = exports.renderEmptyPlaceholder = exports.PlaceholderMetadata = exports.AppPlaceholder = exports.Placeholder = exports.Form = exports.mediaApi = exports.ErrorPage = exports.GraphQLRequestClient = exports.DefaultRetryStrategy = exports.DictionaryService = exports.EditMode = exports.getFieldValue = exports.getChildPlaceholder = exports.LayoutService = exports.LayoutServicePageState = exports.getDesignLibraryStylesheetLinks = exports.getContentStylesheetLink = exports.resetEditorChromes = exports.isEditorActive = exports.NativeDataFetcher = exports.MemoryCacheClient = exports.ClientError = exports.enableDebug = exports.constants = void 0;
4
- exports.SitePathService = exports.ClientEditingChromesUpdate = exports.DefaultEmptyFieldEditingComponentImage = exports.DefaultEmptyFieldEditingComponentText = exports.EditingScripts = exports.withPlaceholder = exports.withAppPlaceholder = exports.withEmptyFieldEditingComponent = exports.withFieldMetadata = void 0;
3
+ exports.withSitecore = exports.withEditorChromes = exports.ErrorComponent = exports.useSitecore = exports.SitecoreProviderReactContext = exports.SitecoreProvider = exports.File = exports.Link = exports.noopLoadImportMap = exports.DesignLibraryErrorBoundary = exports.DesignLibraryLowCodeComponent = exports.DesignLibrary = exports.BYOCServerWrapper = exports.FEaaSServerWrapper = exports.FEaaSClientWrapper = exports.FEaaSWrapper = exports.BYOCClientWrapper = exports.BYOCWrapper = exports.fetchBYOCComponentServerProps = exports.BYOCComponent = exports.fetchFEaaSComponentServerProps = exports.FEaaSComponent = exports.DateField = exports.Text = exports.RichText = exports.Image = exports.renderEmptyPlaceholder = exports.PlaceholderMetadata = exports.AppPlaceholder = exports.Placeholder = exports.Form = exports.mediaApi = exports.ErrorPage = exports.GraphQLRequestClient = exports.DefaultRetryStrategy = exports.DictionaryService = exports.EditMode = exports.getFieldValue = exports.getChildPlaceholder = exports.LayoutService = exports.LayoutServicePageState = exports.getDesignLibraryStylesheetLinks = exports.getContentStylesheetLink = exports.resetEditorChromes = exports.isEditorActive = exports.NativeDataFetcher = exports.MemoryCacheClient = exports.ClientError = exports.enableDebug = exports.constants = void 0;
4
+ exports.fileFieldSchema = exports.imageFieldSchema = exports.linkFieldSchema = exports.dateFieldSchema = exports.richTextFieldSchema = exports.textFieldSchema = exports.withPropMeta = exports.defineAtomsRegistry = exports.defineAtomsCatalog = exports.useBoundProp = exports.SitePathService = exports.ClientEditingChromesUpdate = exports.DefaultEmptyFieldEditingComponentImage = exports.DefaultEmptyFieldEditingComponentText = exports.EditingScripts = exports.withPlaceholder = exports.withAppPlaceholder = exports.withEmptyFieldEditingComponent = exports.withFieldMetadata = exports.withDatasourceCheck = void 0;
5
5
  var core_1 = require("@sitecore-content-sdk/core");
6
6
  Object.defineProperty(exports, "constants", { enumerable: true, get: function () { return core_1.constants; } });
7
7
  Object.defineProperty(exports, "enableDebug", { enumerable: true, get: function () { return core_1.enableDebug; } });
@@ -56,6 +56,7 @@ Object.defineProperty(exports, "FEaaSServerWrapper", { enumerable: true, get: fu
56
56
  Object.defineProperty(exports, "BYOCServerWrapper", { enumerable: true, get: function () { return FEaaS_1.BYOCServerWrapper; } });
57
57
  var DesignLibrary_1 = require("./components/DesignLibrary");
58
58
  Object.defineProperty(exports, "DesignLibrary", { enumerable: true, get: function () { return DesignLibrary_1.DesignLibrary; } });
59
+ Object.defineProperty(exports, "DesignLibraryLowCodeComponent", { enumerable: true, get: function () { return DesignLibrary_1.DesignLibraryLowCodeComponent; } });
59
60
  Object.defineProperty(exports, "DesignLibraryErrorBoundary", { enumerable: true, get: function () { return DesignLibrary_1.DesignLibraryErrorBoundary; } });
60
61
  Object.defineProperty(exports, "noopLoadImportMap", { enumerable: true, get: function () { return DesignLibrary_1.noopLoadImportMap; } });
61
62
  var Link_1 = require("./components/Link");
@@ -91,3 +92,14 @@ var ClientEditingChromesUpdate_1 = require("./components/ClientEditingChromesUpd
91
92
  Object.defineProperty(exports, "ClientEditingChromesUpdate", { enumerable: true, get: function () { return ClientEditingChromesUpdate_1.ClientEditingChromesUpdate; } });
92
93
  var site_1 = require("@sitecore-content-sdk/content/site");
93
94
  Object.defineProperty(exports, "SitePathService", { enumerable: true, get: function () { return site_1.SitePathService; } });
95
+ var atoms_1 = require("./atoms");
96
+ Object.defineProperty(exports, "useBoundProp", { enumerable: true, get: function () { return atoms_1.useBoundProp; } });
97
+ Object.defineProperty(exports, "defineAtomsCatalog", { enumerable: true, get: function () { return atoms_1.defineAtomsCatalog; } });
98
+ Object.defineProperty(exports, "defineAtomsRegistry", { enumerable: true, get: function () { return atoms_1.defineAtomsRegistry; } });
99
+ Object.defineProperty(exports, "withPropMeta", { enumerable: true, get: function () { return atoms_1.withPropMeta; } });
100
+ Object.defineProperty(exports, "textFieldSchema", { enumerable: true, get: function () { return atoms_1.textFieldSchema; } });
101
+ Object.defineProperty(exports, "richTextFieldSchema", { enumerable: true, get: function () { return atoms_1.richTextFieldSchema; } });
102
+ Object.defineProperty(exports, "dateFieldSchema", { enumerable: true, get: function () { return atoms_1.dateFieldSchema; } });
103
+ Object.defineProperty(exports, "linkFieldSchema", { enumerable: true, get: function () { return atoms_1.linkFieldSchema; } });
104
+ Object.defineProperty(exports, "imageFieldSchema", { enumerable: true, get: function () { return atoms_1.imageFieldSchema; } });
105
+ Object.defineProperty(exports, "fileFieldSchema", { enumerable: true, get: function () { return atoms_1.fileFieldSchema; } });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Serialize a json-render Catalog into the payload shape expected by Design Studio.
3
+ * @param { Catalog<any, AtomsCatalogInput> } catalog - The json-render Catalog to serialize
4
+ * @returns Serialized catalog for the Design Library event
5
+ * @internal
6
+ */
7
+ export function serializeCatalog(catalog) {
8
+ const { version, components, actions } = catalog.data;
9
+ const serializedComponents = Object.entries(components).map(([name, component]) => {
10
+ var _a;
11
+ const serializedComponent = {
12
+ name,
13
+ propsSchema: component.props.toJSONSchema(),
14
+ description: component.description,
15
+ slots: (_a = component.slots) !== null && _a !== void 0 ? _a : ['default'],
16
+ allowedChildren: component.allowedChildren,
17
+ allowedParents: component.allowedParents,
18
+ example: component.example,
19
+ };
20
+ if (component.version)
21
+ serializedComponent.version = component.version;
22
+ return serializedComponent;
23
+ });
24
+ const serializedActions = Object.entries(actions).map(([name, action]) => {
25
+ const serializedAction = {
26
+ name,
27
+ description: action.description,
28
+ };
29
+ if (action.params)
30
+ serializedAction.paramsSchema = action.params.toJSONSchema();
31
+ return serializedAction;
32
+ });
33
+ const serializedCatalog = {
34
+ components: serializedComponents,
35
+ actions: serializedActions,
36
+ };
37
+ if (version)
38
+ serializedCatalog.version = version;
39
+ return serializedCatalog;
40
+ }
@@ -0,0 +1,39 @@
1
+ 'use client';
2
+ import React, { useEffect, useState } from 'react';
3
+ import { Renderer, StateProvider, ActionProvider, VisibilityProvider, ValidationProvider, } from '@json-render/react';
4
+ import { createStateStore } from '@json-render/react';
5
+ import { useSitecore } from '../components/SitecoreProvider';
6
+ /**
7
+ * Creates a React functional component that renders the given Component Layout document
8
+ * using json-render's Renderer. The document's flat element map is passed as a spec.
9
+ * @param {Document} doc - Component Layout document (flat spec format)
10
+ * @param {DefineRegistryResult} registryResult - The registry from defineAtomsRegistry
11
+ * @returns {FC<NCCProps>} FC that accepts runtime props merged into spec state
12
+ * @internal
13
+ */
14
+ export function createNCC(doc, registryResult) {
15
+ var _a;
16
+ const { registry, handlers } = registryResult;
17
+ const initialState = Object.assign({}, ((_a = doc.state) !== null && _a !== void 0 ? _a : {}));
18
+ const Generated = ({ fields, params }) => {
19
+ const { atomsConfig } = useSitecore();
20
+ const [store] = useState(() => createStateStore(Object.assign(Object.assign({}, initialState), { fields,
21
+ params })));
22
+ useEffect(() => {
23
+ const snapshot = store.getSnapshot();
24
+ store.update({
25
+ fields: Object.assign(Object.assign({}, snapshot.fields), fields),
26
+ params: Object.assign(Object.assign({}, snapshot.params), params),
27
+ });
28
+ }, [fields, params, store]);
29
+ const [resolvedHandlers] = useState(() => handlers(() => (updater) => store.update(updater(store.getSnapshot())), () => store.getSnapshot()));
30
+ return (React.createElement("div", { className: `component ${(params === null || params === void 0 ? void 0 : params.styles) || ''}`, id: (params === null || params === void 0 ? void 0 : params.RenderingIdentifier) || '' },
31
+ React.createElement(StateProvider, { store: store },
32
+ React.createElement(VisibilityProvider, null,
33
+ React.createElement(ActionProvider, { handlers: resolvedHandlers, navigate: atomsConfig === null || atomsConfig === void 0 ? void 0 : atomsConfig.navigate },
34
+ React.createElement(ValidationProvider, null,
35
+ React.createElement(Renderer, { spec: doc, registry: registry })))))));
36
+ };
37
+ Generated.displayName = doc.name;
38
+ return Generated;
39
+ }
@@ -0,0 +1,41 @@
1
+ import { defineCatalog } from '@json-render/core';
2
+ import { schema } from '@json-render/react';
3
+ /**
4
+ * Define an atoms catalog from component and action definitions.
5
+ *
6
+ * Pass component/action definitions exactly as json-render expects them.
7
+ * The returned catalog carries full type information so `defineAtomsRegistry`
8
+ * can infer props per component.
9
+ * @param {T} input - Catalog input with `components` and optionally `actions`
10
+ * @returns A typed json-render Catalog
11
+ * @example
12
+ * ```ts
13
+ * import { z } from 'zod';
14
+ * import { defineAtomsCatalog } from '@sitecore-content-sdk/react';
15
+ *
16
+ * const catalog = defineAtomsCatalog({
17
+ * components: {
18
+ * Button: {
19
+ * props: z.object({ label: z.string(), variant: z.enum(['primary', 'secondary']) }),
20
+ * description: 'A clickable button',
21
+ * slots: ['default'],
22
+ * },
23
+ * Card: {
24
+ * props: z.object({ title: z.string() }),
25
+ * description: 'A content card',
26
+ * slots: ['default'],
27
+ * },
28
+ * },
29
+ * actions: {
30
+ * submit: {
31
+ * params: z.object({ formId: z.string() }),
32
+ * description: 'Submit a form',
33
+ * },
34
+ * },
35
+ * });
36
+ * ```
37
+ * @public
38
+ */
39
+ export function defineAtomsCatalog(input) {
40
+ return defineCatalog(schema, input);
41
+ }
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ import { defineRegistry } from '@json-render/react';
3
+ /**
4
+ * Define an atoms registry that maps catalog definitions to React implementations.
5
+ *
6
+ * Each component receives `{ props, children, emit, on, bindings, loading }`
7
+ * @param catalog - The catalog created by defineAtomsCatalog
8
+ * @param options - Component and action implementations
9
+ * @returns Registry result with component registry and action handlers
10
+ * @example
11
+ *
12
+ * ```tsx
13
+ * import { defineAtomsRegistry } from '@sitecore-content-sdk/react';
14
+ *
15
+ * const { registry, handlers, executeAction } = defineAtomsRegistry(catalog, {
16
+ * components: {
17
+ * Button: ({ props, children, emit }) => (
18
+ * <button onClick={() => emit('press')}>{props.label}{children}</button>
19
+ * ),
20
+ * Card: ({ props, children }) => (
21
+ * <div className="card"><h2>{props.title}</h2>{children}</div>
22
+ * ),
23
+ * },
24
+ * actions: {
25
+ * submit: async (params) => {
26
+ * await fetch('/api/submit', { method: 'POST', body: JSON.stringify(params) });
27
+ * },
28
+ * },
29
+ * });
30
+ * ```
31
+ * @public
32
+ */
33
+ export const defineAtomsRegistry = defineRegistry;
@@ -0,0 +1,79 @@
1
+ /** Zod schemas for Sitecore field types, for use in defineAtomsCatalog prop definitions. */
2
+ import { z } from 'zod';
3
+ import { withPropMeta } from './schema-utils';
4
+ /**
5
+ * Zod schema for a Sitecore Single-Line Text.
6
+ * Mirrors the Sitecore Text component (`Text.tsx` in `@sitecore-content-sdk/react`).
7
+ * @param {z.ZodRawShape} [extra] - Optional additional shape to merge into the schema.
8
+ * @returns A ZodObject with `value?: string | number` and DS control/fieldType hints attached.
9
+ * @public
10
+ */
11
+ export const textFieldSchema = (extra) => withPropMeta(z.object(Object.assign({ value: z.union([z.string(), z.number()]).optional() }, extra)), { control: 'Single-Line Text', fieldType: 'Text' });
12
+ /**
13
+ * Zod schema for a Sitecore Rich Text field.
14
+ * Mirrors the Sitecore Rich Text component (`RichText.tsx` in `@sitecore-content-sdk/react`).
15
+ * @param {z.ZodRawShape} [extra] - Optional additional shape to merge into the schema.
16
+ * @returns A ZodObject with `value?: string` and DS control/fieldType hints attached.
17
+ * @public
18
+ */
19
+ export const richTextFieldSchema = (extra) => withPropMeta(z.object(Object.assign({ value: z.string().optional() }, extra)), { control: 'Rich Text', fieldType: 'RichText' });
20
+ /**
21
+ * Zod schema for a Sitecore Date field.
22
+ * Mirrors the field shape used in the Date component (`Date.tsx` in `@sitecore-content-sdk/react`).
23
+ * @param {z.ZodRawShape} [extra] - Optional additional shape to merge into the schema.
24
+ * @returns A ZodObject with `value?: string` and DS control/fieldType hints attached.
25
+ * @public
26
+ */
27
+ export const dateFieldSchema = (extra) => withPropMeta(z.object(Object.assign({ value: z.string().optional() }, extra)), { control: 'Date', fieldType: 'Date' });
28
+ /**
29
+ * Zod schema for a Sitecore Link field.
30
+ * Mirrors the Sitecore Link component (`Link.tsx` in `@sitecore-content-sdk/react`).
31
+ * The inner value object uses `z.looseObject` to allow arbitrary Sitecore-added attributes,
32
+ * matching the `[attributeName: string]: unknown` index signature on `LinkFieldValue`.
33
+ * @param {z.ZodRawShape} [extra] - Optional additional shape to merge into the outer schema.
34
+ * @returns A ZodObject with `value: LinkFieldValue` and DS control/fieldType hints attached.
35
+ * @public
36
+ */
37
+ export const linkFieldSchema = (extra) => withPropMeta(z.object(Object.assign({ value: z.looseObject({
38
+ href: z.string().optional(),
39
+ className: z.string().optional(),
40
+ class: z.string().optional(),
41
+ title: z.string().optional(),
42
+ target: z.string().optional(),
43
+ text: z.string().optional(),
44
+ anchor: z.string().optional(),
45
+ querystring: z.string().optional(),
46
+ linktype: z.string().optional(),
47
+ }) }, extra)), { control: 'Link', fieldType: 'Link' });
48
+ /**
49
+ * Zod schema for a Sitecore Image field.
50
+ * Mirrors the Sitecore Image component (`Image.tsx` in `@sitecore-content-sdk/react`).
51
+ * The inner value object uses `z.looseObject` to allow arbitrary HTML attributes,
52
+ * matching the `[attributeName: string]: unknown` index signature on `ImageFieldValue`.
53
+ * @param {z.ZodRawShape} [extra] - Optional additional shape to merge into the outer schema.
54
+ * @returns A ZodObject with `value?: ImageFieldValue` and DS control/fieldType hints attached.
55
+ * @public
56
+ */
57
+ export const imageFieldSchema = (extra) => withPropMeta(z.object(Object.assign({ value: z
58
+ .looseObject({
59
+ src: z.string().optional(),
60
+ alt: z.string().optional(),
61
+ width: z.union([z.string(), z.number()]).optional(),
62
+ height: z.union([z.string(), z.number()]).optional(),
63
+ class: z.string().optional(),
64
+ })
65
+ .optional() }, extra)), { control: 'Image', fieldType: 'Image' });
66
+ /**
67
+ * Zod schema for a Sitecore File field.
68
+ * Mirrors the Sitecore File component (`File.tsx` in `@sitecore-content-sdk/react`).
69
+ * The inner value object uses `z.looseObject` to allow arbitrary extra properties,
70
+ * matching the `[propName: string]: unknown` index signature on `FileFieldValue`.
71
+ * @param {z.ZodRawShape} [extra] - Optional additional shape to merge into the outer schema.
72
+ * @returns A ZodObject with `value: FileFieldValue` and DS control/fieldType hints attached.
73
+ * @public
74
+ */
75
+ export const fileFieldSchema = (extra) => withPropMeta(z.object(Object.assign({ value: z.looseObject({
76
+ src: z.string().optional(),
77
+ title: z.string().optional(),
78
+ displayName: z.string().optional(),
79
+ }) }, extra)), { control: 'File', fieldType: 'File' });
@@ -0,0 +1,7 @@
1
+ export { defineAtomsCatalog } from './define-atoms-catalog';
2
+ export { defineAtomsRegistry } from './define-atoms-registry';
3
+ export { serializeCatalog } from './catalog-serializer';
4
+ export { withPropMeta } from './schema-utils';
5
+ export { textFieldSchema, richTextFieldSchema, dateFieldSchema, linkFieldSchema, imageFieldSchema, fileFieldSchema, } from './field-schemas';
6
+ export { createNCC } from './create-ncc';
7
+ export * from './re-exports';
@@ -0,0 +1,21 @@
1
+ import { useBoundProp as useBoundPropInternal } from '@json-render/react';
2
+ /**
3
+ * Hook for two-way bound props. Returns `[value, setValue]` where:
4
+ *
5
+ * - `value` is the already-resolved prop value (passed through from render props)
6
+ * - `setValue` writes back to the bound state path (no-op if not bound)
7
+ *
8
+ * Designed to work with the `bindings` map that the renderer provides when
9
+ * a prop uses `{ $bindState: "/path" }` or `{ $bindItem: "field" }`.
10
+ * @example
11
+ * ```tsx
12
+ * import { useBoundProp } from '@sitecore-content-sdk/react';
13
+ *
14
+ * const Input: ComponentRenderer = ({ props, bindings }) => {
15
+ * const [value, setValue] = useBoundProp<string>(props.value, bindings?.value);
16
+ * return <input value={value ?? ""} onChange={(e) => setValue(e.target.value)} />;
17
+ * };
18
+ * ```
19
+ * @public
20
+ */
21
+ export const useBoundProp = useBoundPropInternal;
@@ -0,0 +1,16 @@
1
+ const META_KEY = 'meta';
2
+ /**
3
+ * Attach editor hint (e.g. control type, fieldType) to a prop schema. Metadata is stored under a key that
4
+ * survives JSON Schema conversion for Design Studio.
5
+ * @param {import('zod').ZodType} schema - Zod type for the prop
6
+ * @param {PropMeta} meta - Editor metadata (e.g. control, fieldType)
7
+ * @returns The same Zod type with meta attached (or schema unchanged if .meta is not callable)
8
+ * @public
9
+ */
10
+ export function withPropMeta(schema, meta) {
11
+ const s = schema;
12
+ if (typeof s.meta === 'function') {
13
+ return s.meta({ [META_KEY]: meta });
14
+ }
15
+ return schema;
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -10,6 +10,8 @@ import { useSitecore } from '../../components/SitecoreProvider';
10
10
  import { Placeholder, PlaceholderMetadata } from '../Placeholder';
11
11
  import { DesignLibraryErrorBoundary } from './DesignLibraryErrorBoundary';
12
12
  import { ErrorComponent } from '../ErrorBoundary';
13
+ import { serializeCatalog } from '../../atoms';
14
+ import { getDesignLibraryAtomsCatalogEvent } from '@sitecore-content-sdk/content/atoms';
13
15
  let { getDesignLibraryImportMapEvent, getDesignLibraryComponentPropsEvent, addComponentPreviewHandler, sendErrorEvent, } = codegen;
14
16
  let { postToDesignLibrary } = editing;
15
17
  export const __mockDependencies = (mocks) => {
@@ -33,7 +35,7 @@ export const __mockDependencies = (mocks) => {
33
35
  */
34
36
  export const DesignLibrary = () => {
35
37
  var _a, _b;
36
- const { page, loadImportMap } = useSitecore();
38
+ const { page, loadImportMap, atomsConfig } = useSitecore();
37
39
  const route = page.layout.sitecore.route;
38
40
  const rendering = (_a = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER]) === null || _a === void 0 ? void 0 : _a[0];
39
41
  const uid = rendering === null || rendering === void 0 ? void 0 : rendering.uid;
@@ -106,6 +108,10 @@ export const DesignLibrary = () => {
106
108
  });
107
109
  const importMapEvent = getDesignLibraryImportMapEvent(uid, importMap);
108
110
  postToDesignLibrary(importMapEvent);
111
+ if (atomsConfig === null || atomsConfig === void 0 ? void 0 : atomsConfig.catalog) {
112
+ const catalogPayload = serializeCatalog(atomsConfig.catalog);
113
+ postToDesignLibrary(getDesignLibraryAtomsCatalogEvent(catalogPayload));
114
+ }
109
115
  const propsEvent = getDesignLibraryComponentPropsEvent(uid, propsState.fields, propsState.params);
110
116
  postToDesignLibrary(propsEvent);
111
117
  })();
@@ -114,7 +120,7 @@ export const DesignLibrary = () => {
114
120
  cancelled = true;
115
121
  unsubscribe && unsubscribe();
116
122
  };
117
- }, [isDesignLibrary, isVariantGeneration, uid, loadImportMap, propsState]);
123
+ }, [isDesignLibrary, isVariantGeneration, uid, loadImportMap, propsState, atomsConfig]);
118
124
  return (React.createElement("main", null, isGeneratedComponentActive ? (React.createElement(DesignLibraryErrorBoundary, { uid: uid, renderKey: renderKey },
119
125
  React.createElement(PlaceholderMetadata, { rendering: rendering },
120
126
  React.createElement(Component, { fields: propsState.fields, params: propsState.params, key: renderKey })))) : (React.createElement("div", { id: EDITING_COMPONENT_ID }, route && (React.createElement(Placeholder, { name: EDITING_COMPONENT_PLACEHOLDER, rendering: route, key: renderKey }))))));
@@ -0,0 +1,71 @@
1
+ 'use client';
2
+ import React, { useEffect, useState } from 'react';
3
+ import { useSitecore } from '../SitecoreProvider';
4
+ import { serializeCatalog } from '../../atoms';
5
+ import { StudioComponentWrapper } from './StudioComponentWrapper';
6
+ import * as editing from '@sitecore-content-sdk/content/editing';
7
+ import * as atoms from '@sitecore-content-sdk/content/atoms';
8
+ import { DesignLibraryErrorBoundary } from '../..';
9
+ let { postToDesignLibrary, getDesignLibraryStatusEvent, DesignLibraryStatus } = editing;
10
+ let { addDocumentUpdateHandler, getDesignLibraryAtomsCatalogEvent, sendAtomsErrorEvent, addComponentPropsUpdateHandler, } = atoms;
11
+ export const __mockDependencies = (mocks) => {
12
+ if (mocks.postToDesignLibrary) {
13
+ postToDesignLibrary = mocks.postToDesignLibrary;
14
+ }
15
+ if (mocks.sendAtomsErrorEvent) {
16
+ sendAtomsErrorEvent = mocks.sendAtomsErrorEvent;
17
+ }
18
+ if (mocks.addDocumentUpdateHandler) {
19
+ addDocumentUpdateHandler = mocks.addDocumentUpdateHandler;
20
+ }
21
+ if (mocks.addComponentPropsUpdateHandler) {
22
+ addComponentPropsUpdateHandler = mocks.addComponentPropsUpdateHandler;
23
+ }
24
+ };
25
+ /**
26
+ * Design Library Low Code component.
27
+ *
28
+ * Facilitates the communication between the Design Studio and the Rendering Host when previewing a low code component built with the Atoms.
29
+ * - On mount, it serializes the atoms catalog and sends it to the Design Studio via the `atoms:catalog` event.
30
+ * - Receives Component model data updates via document update handler and renders the low code component
31
+ * via `StudioComponentWrapper` (same client path as Studio / NCC preview elsewhere).
32
+ * @internal
33
+ */
34
+ export const DesignLibraryLowCodeComponent = () => {
35
+ var _a;
36
+ const { atomsConfig } = useSitecore();
37
+ const [currentDocument, setCurrentDocument] = useState(null);
38
+ const [renderKey, setRenderKey] = useState(0);
39
+ const [fields, setFields] = useState();
40
+ const [params, setParams] = useState();
41
+ useEffect(() => {
42
+ postToDesignLibrary(getDesignLibraryStatusEvent(DesignLibraryStatus.READY, 'low-code-component'));
43
+ }, []);
44
+ useEffect(() => {
45
+ const unsubscribe = addComponentPropsUpdateHandler((updatedFields, updatedParams) => {
46
+ setFields(updatedFields);
47
+ setParams(updatedParams);
48
+ });
49
+ return () => unsubscribe();
50
+ }, []);
51
+ useEffect(() => {
52
+ if (!(atomsConfig === null || atomsConfig === void 0 ? void 0 : atomsConfig.catalog)) {
53
+ sendAtomsErrorEvent('No atoms catalog provided', 'atoms-missing');
54
+ return;
55
+ }
56
+ const payload = serializeCatalog(atomsConfig.catalog);
57
+ postToDesignLibrary(getDesignLibraryAtomsCatalogEvent(payload));
58
+ const unsubDocumentUpdate = addDocumentUpdateHandler((updatedDocument) => {
59
+ setCurrentDocument(updatedDocument);
60
+ setRenderKey((k) => k + 1);
61
+ });
62
+ return () => unsubDocumentUpdate();
63
+ }, [atomsConfig]);
64
+ useEffect(() => {
65
+ if (renderKey === 0)
66
+ return;
67
+ postToDesignLibrary(getDesignLibraryStatusEvent(DesignLibraryStatus.RENDERED, 'low-code-component'));
68
+ }, [renderKey]);
69
+ return (React.createElement(DesignLibraryErrorBoundary, { uid: (_a = currentDocument === null || currentDocument === void 0 ? void 0 : currentDocument.name) !== null && _a !== void 0 ? _a : 'design-library-low-code-component', renderKey: renderKey },
70
+ React.createElement(StudioComponentWrapper, { document: currentDocument, fields: fields, params: params })));
71
+ };