@uniformdev/canvas-react 17.7.1-alpha.34 → 18.0.1-alpha.3

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/LICENSE.txt CHANGED
@@ -1,2 +1,2 @@
1
- © 2022 Uniform Systems, Inc. All Rights Reserved.
1
+ © 2023 Uniform Systems, Inc. All Rights Reserved.
2
2
  See details of Uniform Systems, Inc. Master Subscription Agreement here: https://uniform.dev/eula
package/dist/index.d.ts CHANGED
@@ -6,22 +6,22 @@ import React$1, { Key, ReactNode } from 'react';
6
6
  * TProps is the Canvas component's parameters object after
7
7
  * all enhancers have been applied.
8
8
  */
9
- declare type ComponentProps<TProps = unknown> = TProps & {
9
+ type ComponentProps<TProps = unknown> = TProps & {
10
10
  component: ComponentInstance;
11
11
  };
12
12
  /**
13
13
  * Function that maps a Canvas component instance to its React component to render it.
14
14
  * The resolver would commonly inspect the `type` and possibly `variant` of the component to decide.
15
15
  */
16
- declare type RenderComponentResolver = (component: ComponentInstance) => React.ComponentType<ComponentProps<any>> | null;
16
+ type RenderComponentResolver = (component: ComponentInstance) => React.ComponentType<ComponentProps<any>> | null;
17
17
  /** Function that renders Canvas system internals */
18
- declare type SystemRenderFunction = (component: ComponentInstance, key: Key, renderChild: (component: ComponentInstance, key: Key) => JSX.Element | null) => JSX.Element | null;
18
+ type SystemRenderFunction = (component: ComponentInstance, key: Key, renderChild: (component: ComponentInstance, key: Key) => JSX.Element | null) => JSX.Element | null;
19
19
  /** Configures rendering of system components (tests, pz) */
20
- declare type SystemRenderConfig = {
20
+ type SystemRenderConfig = {
21
21
  test: SystemRenderFunction;
22
22
  personalization: SystemRenderFunction;
23
23
  };
24
- declare type ComponentStore = {
24
+ type ComponentStore = {
25
25
  register: (options: {
26
26
  type: string;
27
27
  component: React.ComponentType<ComponentProps<any>>;
@@ -29,7 +29,7 @@ declare type ComponentStore = {
29
29
  get: (name: string) => React.ComponentType<ComponentProps<any>> | undefined;
30
30
  };
31
31
 
32
- declare type CompositionProps<TRenderProps = unknown> = {
32
+ type CompositionProps<TRenderProps = unknown> = {
33
33
  /** The root component in the composition */
34
34
  data: ComponentInstance;
35
35
  /** Resolves a React component to render a Canvas component, generally by inspecting type/variant */
@@ -48,7 +48,7 @@ declare type CompositionProps<TRenderProps = unknown> = {
48
48
  */
49
49
  behaviorTracking?: 'onLoad' | 'onView';
50
50
  };
51
- declare type CompositionContext = {
51
+ type CompositionContext = {
52
52
  /** The parent composition */
53
53
  composition: ComponentInstance;
54
54
  /** The current function to translate component data into React components */
@@ -71,12 +71,12 @@ declare function Composition<TRenderProps = unknown>({ data, resolveRenderer, ch
71
71
  **/
72
72
  declare function DefaultNotImplementedComponent(props: ComponentProps): JSX.Element | null;
73
73
 
74
- declare type CustomSlotChildRenderFunc = (options: {
74
+ type CustomSlotChildRenderFunc = (options: {
75
75
  child: ReactNode;
76
76
  component: ComponentInstance;
77
77
  key: Key;
78
78
  }) => JSX.Element;
79
- declare type SlotProps<TSlotNames extends string> = {
79
+ type SlotProps<TSlotNames extends string> = {
80
80
  /** Name of the slot to render */
81
81
  name: TSlotNames;
82
82
  /**
@@ -96,7 +96,7 @@ declare type SlotProps<TSlotNames extends string> = {
96
96
  /** Renders a named Slot within a Composition. */
97
97
  declare function Slot<TSlotNames extends string = string>({ name, resolveRenderer, children, emptyPlaceholder, }: SlotProps<TSlotNames>): JSX.Element | null;
98
98
 
99
- declare type UseCompositionEventEffectOptions = Omit<Partial<SubscribeToCompositionOptions>, 'callback'> & {
99
+ type UseCompositionEventEffectOptions = Omit<Partial<SubscribeToCompositionOptions>, 'callback'> & {
100
100
  enabled: boolean;
101
101
  effect: () => void;
102
102
  };
package/dist/index.esm.js CHANGED
@@ -1 +1,455 @@
1
- import{CANVAS_ENRICHMENT_TAG_PARAM as F}from"@uniformdev/canvas";import{Track as J,TrackFragment as X,useUniformContext as $}from"@uniformdev/context-react";import T,{createContext as j,useContext as K}from"react";function v(e){var n;let o=(n=e.parameters)!=null?n:{};return{...Object.keys(o).reduce((r,i)=>(r[i]=o[i].value,r),{}),...e.data,component:e}}var w=()=>{let e=new Map;return{register:({type:o,component:t})=>{e.set(o,t)},get:o=>e.get(o)}},S=e=>o=>e.store.get(o.type)||e.defaultComponent||null;var h=w(),ae=({type:e,component:o})=>{Array.isArray(e)?e.forEach(t=>{h.register({type:t,component:o})}):h.register({type:e,component:o})},me=S({store:h});import{CANVAS_PERSONALIZE_TYPE as M,CANVAS_TEST_TYPE as z,IN_CONTEXT_EDITOR_COMPONENT_START_ROLE as L,PLACEHOLDER_ID as B}from"@uniformdev/canvas";import C from"react";import{mapSlotToPersonalizedVariations as A,mapSlotToTestVariations as U}from"@uniformdev/canvas";import{Personalize as V,Test as D}from"@uniformdev/context-react";import*as P from"react";var x={test:(e,o,t)=>{var p,d,m,c,a;let n=e,r=(d=(p=n.slots)==null?void 0:p.test)!=null?d:[],i=(a=(c=(m=n.parameters)==null?void 0:m.test)==null?void 0:c.value)!=null?a:"Untitled Test",s=U(r);return P.createElement(D,{key:o,variations:s,name:i,component:l=>t(l,o)})},personalization:(e,o,t)=>{var i,s,p,d,m,c,a;let n=e,r=A((i=n==null?void 0:n.slots)==null?void 0:i.pz);return P.createElement(V,{key:o,variations:r,count:Number((d=(p=(s=n.parameters)==null?void 0:s.count)==null?void 0:p.value)!=null?d:1),name:(a=(c=(m=n.parameters)==null?void 0:m.trackingEventName)==null?void 0:c.value)!=null?a:"Untitled Personalization",component:l=>t(l,0)})}};function b({name:e,resolveRenderer:o,children:t,emptyPlaceholder:n}){var a;let r=E();if(!(r!=null&&r.composition))throw new Error("Slot must be rendered within a Composition");let{composition:i,resolveRenderer:s}=r;if(!i)throw new Error("Cannot use Slot without a Composition wrapper.");let p=(a=i.slots)==null?void 0:a[e];if(!p||!Array.isArray(p))return process.env.NODE_ENV==="development"&&console.warn(`[canvas-dev] slot '${e}' was rendered, but it was not defined on its component. This is expected if the slot is optional, otherwise it may indicate a typo. Component:`,i),null;let d=o!=null?o:s,m=x,c=p.map((l,u)=>{let f=g({component:l,resolveRenderer:d,resolveSystem:m,key:`inner-${u}`,indexInSlot:u,slotName:e,parentComponent:i,slotChildrenCount:p.length,emptyPlaceholder:n}),R=t?t({child:f,component:l,key:`wrapped-inner-${u}`}):f;return C.createElement(C.Fragment,{key:u},R)});return C.createElement(C.Fragment,void 0,c)}function g({component:e,resolveRenderer:o,resolveSystem:t,key:n=0,indexInSlot:r,slotName:i,parentComponent:s,slotChildrenCount:p,emptyPlaceholder:d}){var c,a,l;let m=o==null?void 0:o(e);if(e.type===z)return t.test(e,n,(u,f)=>g({component:u,resolveRenderer:o,resolveSystem:t,key:f}));if(e.type===M)return t.personalization(e,n,(u,f)=>g({component:u,resolveRenderer:o,resolveSystem:t,key:f}));if(m){let u=v(e),f=Boolean(e._id),R=e._id===B;return C.createElement(N,{key:n,data:e,resolveRenderer:o},f?C.createElement("script",{key:n,"data-role":L,"data-parent-id":s==null?void 0:s._id,"data-parent-type":s==null?void 0:s.type,"data-component-id":e._id,"data-slot-name":i!=null?i:"","data-component-index":r!=null?r:"","data-total-components":p!=null?p:"","data-component-name":e.type,"data-is-placeholder":R?"true":void 0,"data-component-title":(l=(a=(c=e.parameters)==null?void 0:c.title)==null?void 0:a.value)!=null?l:""}):null,R&&d!==void 0?d:C.createElement(m,{...u}),f?C.createElement("script",{"data-role":"component-end"}):null)}else process.env.NODE_ENV!=="production"&&console.warn(`[canvas] found component of type '${e.type}' which the resolveRenderer prop returned no component for. Nothing will be rendered. The resolveRenderer function may need to be extended to handle the new type.`,e);return null}var I=j(void 0);function E(){return K(I)}var Y=e=>h.get(e.type)||null;function N({data:e,resolveRenderer:o,children:t,behaviorTracking:n}){var c,a,l;let r=E(),i=$({throwOnMissingProvider:!1})!==void 0;if(!e)return process.env.NODE_ENV==="development"&&console.warn("[canvas-dev] Composition was rendered with no data, nothing will be output."),null;let s={composition:e,resolveRenderer:o||(r==null?void 0:r.resolveRenderer)||Y,behaviorTracking:(c=n!=null?n:r==null?void 0:r.behaviorTracking)!=null?c:"onView"},p=(l=(a=e.parameters)==null?void 0:a[F])==null?void 0:l.value,d=s.behaviorTracking==="onLoad"?X:J,m=G({children:t,data:e,hasParentLayout:Boolean(r)});return T.createElement(I.Provider,{value:s},i?T.createElement(d,{behavior:p},m):m)}function G({children:e,data:o,hasParentLayout:t}){var i;let n=e;if(!n&&!t){let s=h.get(o.type);s?n=T.createElement(s,v(o)):(Object.keys((i=o.slots)!=null?i:{}).length>1&&process.env.NODE_ENV==="development"&&console.warn(`[canvas-dev] All the slots in component '${o.type}' are rendered in no particular order. Use '<Slot name={slotName} />' to reliably render the slots.`),n=Object.keys(o.slots||{}).map(p=>T.createElement(b,{key:p,name:p})))}return typeof n=="function"?n(v(o)):n}import y from"react";function Ae(e){var t;let o=(t=e.component)==null?void 0:t.type;return o?y.createElement("div",{style:{borderLeft:"10px solid #e42535!important",padding:"0.01em 16px 16px",borderRadius:"16px",backgroundColor:"rgba(122, 215, 218, 0.3)",color:"#1d3557"}},y.createElement("h2",null,"Component: ",o),y.createElement("p",null,y.createElement("strong",null,o)," has no React implementation. It may need to be added to your"," ",y.createElement("code",null,"resolveRenderer()")," function."),y.createElement("details",null,y.createElement("summary",null,"Props"),y.createElement("pre",null,JSON.stringify(e,null,2)))):null}import{CANVAS_DRAFT_STATE as H,createEventBus as Q,subscribeToComposition as Z}from"@uniformdev/canvas";import{useEffect as q}from"react";function ze({enabled:e,projectId:o,compositionId:t,effect:n}){q(()=>{if(!e||!t||!o)return;let r;return(async()=>{let s=await Q();s&&(r=Z({eventBus:s,compositionId:t,compositionState:H,projectId:o,callback:n,event:"updated"}))})(),()=>{r&&r()}},[t,e,o,n])}import{createCanvasChannel as W,IN_CONTEXT_EDITOR_QUERY_STRING_PARAM as ee,isUpdateCompositionMessage as oe}from"@uniformdev/canvas";import{useEffect as _,useMemo as te,useState as ne}from"react";var O="uniform-canvas-preview-script",$e=({apiUrl:e})=>async o=>{let t=await fetch(e,{method:"post",body:JSON.stringify({composition:o.composition,hash:o.hash}),headers:{"Content-Type":"application/json"}}),n=await t.json();if(!t.ok)throw new Error("Error reading enhanced composition");return n.composition},je=({initialCompositionValue:e,enhance:o=t=>t.composition})=>{let[t,n]=ne(),r=te(()=>{var s;return k()?W({broadcastTo:[(s=window.opener)!=null?s:window.top],listenTo:[window]}):void 0},[]);return _(()=>{if(!r)return;let i=r.on("update-composition",async s=>{if(oe(s)){let p=await o(s);n(p)}});return()=>{i()}},[r,o]),_(()=>{if(!k()||document.getElementById(O))return;let s=document.createElement("script");s.id=O,s.src=re(),s.async=!0,document.head.appendChild(s)},[]),{composition:t!=null?t:e}};function re(){return`${window.document.referrer}files/canvas-in-context-embed/index.js`}function k(){if(typeof window=="undefined")return!1;let e=new URLSearchParams(window.location.search).has(ee),o=Boolean(window.document.referrer.match(/(^https:\/\/|\.)(uniform.app|uniform.wtf|localhost:\d{4})\//));return e&&o}export{N as Composition,Ae as DefaultNotImplementedComponent,b as Slot,h as componentStore,me as componentStoreResolver,$e as createApiEnhancer,w as createComponentStore,S as createComponentStoreResolver,ae as registerUniformComponent,E as useComposition,ze as useCompositionEventEffect,je as useContextualEditing};
1
+ // src/components/Composition.tsx
2
+ import { CANVAS_ENRICHMENT_TAG_PARAM } from "@uniformdev/canvas";
3
+ import { Track, TrackFragment, useUniformContext } from "@uniformdev/context-react";
4
+ import React3, { createContext, useContext } from "react";
5
+
6
+ // src/convertComponentToProps.ts
7
+ function convertComponentToProps(component) {
8
+ var _a;
9
+ const parameters = (_a = component.parameters) != null ? _a : {};
10
+ const renderComponentProps = {
11
+ ...Object.keys(parameters).reduce((acc, cur) => {
12
+ acc[cur] = parameters[cur].value;
13
+ return acc;
14
+ }, {}),
15
+ ...component.data,
16
+ component
17
+ };
18
+ return renderComponentProps;
19
+ }
20
+
21
+ // src/storeDefinition.ts
22
+ var createComponentStore = () => {
23
+ const components = /* @__PURE__ */ new Map();
24
+ return {
25
+ register: ({ type, component }) => {
26
+ components.set(type, component);
27
+ },
28
+ get: (name) => {
29
+ return components.get(name);
30
+ }
31
+ };
32
+ };
33
+ var createComponentStoreResolver = (options) => {
34
+ return (component) => {
35
+ const resolved = options.store.get(component.type);
36
+ return resolved || options.defaultComponent || null;
37
+ };
38
+ };
39
+
40
+ // src/store.ts
41
+ var componentStore = createComponentStore();
42
+ var registerUniformComponent = ({
43
+ type,
44
+ component
45
+ }) => {
46
+ if (Array.isArray(type)) {
47
+ type.forEach((t) => {
48
+ componentStore.register({
49
+ type: t,
50
+ component
51
+ });
52
+ });
53
+ } else {
54
+ componentStore.register({
55
+ type,
56
+ component
57
+ });
58
+ }
59
+ };
60
+ var componentStoreResolver = createComponentStoreResolver({
61
+ store: componentStore
62
+ });
63
+
64
+ // src/components/Slot.tsx
65
+ import {
66
+ CANVAS_LOCALE_TAG_PARAM,
67
+ CANVAS_PERSONALIZE_TYPE,
68
+ CANVAS_TEST_TYPE,
69
+ IN_CONTEXT_EDITOR_COMPONENT_START_ROLE,
70
+ PLACEHOLDER_ID
71
+ } from "@uniformdev/canvas";
72
+ import React2 from "react";
73
+
74
+ // src/defaultSystemComponentResolver.tsx
75
+ import {
76
+ mapSlotToPersonalizedVariations,
77
+ mapSlotToTestVariations
78
+ } from "@uniformdev/canvas";
79
+ import { Personalize, Test } from "@uniformdev/context-react";
80
+ import * as React from "react";
81
+ var defaultSystemComponentResolver = {
82
+ test: (component, key, renderChild) => {
83
+ var _a, _b, _c, _d, _e;
84
+ const testComponent = component;
85
+ const variants = (_b = (_a = testComponent.slots) == null ? void 0 : _a.test) != null ? _b : [];
86
+ const testName = (_e = (_d = (_c = testComponent.parameters) == null ? void 0 : _c.test) == null ? void 0 : _d.value) != null ? _e : "Untitled Test";
87
+ const finalVariants = mapSlotToTestVariations(variants);
88
+ return /* @__PURE__ */ React.createElement(
89
+ Test,
90
+ {
91
+ key,
92
+ variations: finalVariants,
93
+ name: testName,
94
+ component: (variation) => renderChild(variation, key)
95
+ }
96
+ );
97
+ },
98
+ personalization: (component, key, renderChild) => {
99
+ var _a, _b, _c, _d, _e, _f, _g;
100
+ const pzComponent = component;
101
+ const processedVariants = mapSlotToPersonalizedVariations((_a = pzComponent == null ? void 0 : pzComponent.slots) == null ? void 0 : _a.pz);
102
+ return /* @__PURE__ */ React.createElement(
103
+ Personalize,
104
+ {
105
+ key,
106
+ variations: processedVariants,
107
+ count: Number((_d = (_c = (_b = pzComponent.parameters) == null ? void 0 : _b.count) == null ? void 0 : _c.value) != null ? _d : 1),
108
+ name: (_g = (_f = (_e = pzComponent.parameters) == null ? void 0 : _e.trackingEventName) == null ? void 0 : _f.value) != null ? _g : "Untitled Personalization",
109
+ component: (variation) => renderChild(variation, 0)
110
+ }
111
+ );
112
+ }
113
+ };
114
+
115
+ // src/components/Slot.tsx
116
+ function Slot({
117
+ name,
118
+ resolveRenderer,
119
+ children,
120
+ emptyPlaceholder
121
+ }) {
122
+ var _a;
123
+ const compositionContext = useComposition();
124
+ if (!(compositionContext == null ? void 0 : compositionContext.composition)) {
125
+ throw new Error("Slot must be rendered within a Composition");
126
+ }
127
+ const { composition: layout, resolveRenderer: parentResolveRenderer } = compositionContext;
128
+ if (!layout) {
129
+ throw new Error("Cannot use Slot without a Composition wrapper.");
130
+ }
131
+ const slot = (_a = layout.slots) == null ? void 0 : _a[name];
132
+ if (!slot || !Array.isArray(slot)) {
133
+ if (process.env.NODE_ENV === "development") {
134
+ console.warn(
135
+ `[canvas-dev] slot '${name}' was rendered, but it was not defined on its component. This is expected if the slot is optional, otherwise it may indicate a typo. Component:`,
136
+ layout
137
+ );
138
+ }
139
+ return null;
140
+ }
141
+ const resolver = resolveRenderer != null ? resolveRenderer : parentResolveRenderer;
142
+ const systemResolver = defaultSystemComponentResolver;
143
+ const finalChildren = slot.map((component, index) => {
144
+ const child = renderComponent({
145
+ component,
146
+ resolveRenderer: resolver,
147
+ resolveSystem: systemResolver,
148
+ key: `inner-${index}`,
149
+ indexInSlot: index,
150
+ slotName: name,
151
+ parentComponent: layout,
152
+ slotChildrenCount: slot.length,
153
+ emptyPlaceholder
154
+ });
155
+ const elements = children ? children({ child, component, key: `wrapped-inner-${index}` }) : child;
156
+ return React2.createElement(React2.Fragment, { key: index }, elements);
157
+ });
158
+ return React2.createElement(React2.Fragment, void 0, finalChildren);
159
+ }
160
+ function renderComponent({
161
+ component,
162
+ resolveRenderer,
163
+ resolveSystem,
164
+ key = 0,
165
+ indexInSlot,
166
+ slotName,
167
+ parentComponent,
168
+ slotChildrenCount,
169
+ emptyPlaceholder
170
+ }) {
171
+ var _a, _b, _c, _d;
172
+ const RenderComponent = resolveRenderer == null ? void 0 : resolveRenderer(component);
173
+ if (component.type === CANVAS_TEST_TYPE) {
174
+ return resolveSystem.test(
175
+ component,
176
+ key,
177
+ (component2, key2) => renderComponent({ component: component2, resolveRenderer, resolveSystem, key: key2 })
178
+ );
179
+ } else if (component.type === CANVAS_PERSONALIZE_TYPE) {
180
+ return resolveSystem.personalization(
181
+ component,
182
+ key,
183
+ (component2, key2) => renderComponent({ component: component2, resolveRenderer, resolveSystem, key: key2 })
184
+ );
185
+ } else if (RenderComponent) {
186
+ const props = convertComponentToProps(component);
187
+ const shouldRenderContextualEditingTags = Boolean(component._id);
188
+ const isPlaceholder = component._id === PLACEHOLDER_ID;
189
+ return /* @__PURE__ */ React2.createElement(Composition, { key, data: component, resolveRenderer }, !shouldRenderContextualEditingTags ? null : /* @__PURE__ */ React2.createElement(
190
+ "script",
191
+ {
192
+ key,
193
+ "data-role": IN_CONTEXT_EDITOR_COMPONENT_START_ROLE,
194
+ "data-parent-id": parentComponent == null ? void 0 : parentComponent._id,
195
+ "data-parent-type": parentComponent == null ? void 0 : parentComponent.type,
196
+ "data-component-id": component._id,
197
+ "data-slot-name": slotName != null ? slotName : "",
198
+ "data-component-index": indexInSlot != null ? indexInSlot : "",
199
+ "data-total-components": slotChildrenCount != null ? slotChildrenCount : "",
200
+ "data-component-name": component.type,
201
+ "data-is-placeholder": isPlaceholder ? "true" : void 0,
202
+ "data-is-localized": ((_a = component.parameters) == null ? void 0 : _a[CANVAS_LOCALE_TAG_PARAM]) ? "true" : void 0,
203
+ "data-component-title": (_d = (_c = (_b = component.parameters) == null ? void 0 : _b.title) == null ? void 0 : _c.value) != null ? _d : ""
204
+ }
205
+ ), isPlaceholder && emptyPlaceholder !== void 0 ? emptyPlaceholder : /* @__PURE__ */ React2.createElement(RenderComponent, { ...props }), !shouldRenderContextualEditingTags ? null : /* @__PURE__ */ React2.createElement("script", { "data-role": "component-end" }));
206
+ } else if (process.env.NODE_ENV !== "production") {
207
+ console.warn(
208
+ `[canvas] found component of type '${component.type}' which the resolveRenderer prop returned no component for. Nothing will be rendered. The resolveRenderer function may need to be extended to handle the new type.`,
209
+ component
210
+ );
211
+ }
212
+ return null;
213
+ }
214
+
215
+ // src/components/Composition.tsx
216
+ var CompositionContext = createContext(void 0);
217
+ function useComposition() {
218
+ return useContext(CompositionContext);
219
+ }
220
+ var componentStoreResolver2 = (component) => {
221
+ const resolved = componentStore.get(component.type);
222
+ return resolved || null;
223
+ };
224
+ function Composition({
225
+ data,
226
+ resolveRenderer,
227
+ children,
228
+ behaviorTracking
229
+ }) {
230
+ var _a, _b, _c;
231
+ const parentLayout = useComposition();
232
+ const contextContextProviderPresent = useUniformContext({ throwOnMissingProvider: false }) !== void 0;
233
+ if (!data) {
234
+ if (process.env.NODE_ENV === "development") {
235
+ console.warn(`[canvas-dev] Composition was rendered with no data, nothing will be output.`);
236
+ }
237
+ return null;
238
+ }
239
+ const context = {
240
+ composition: data,
241
+ resolveRenderer: resolveRenderer || (parentLayout == null ? void 0 : parentLayout.resolveRenderer) || componentStoreResolver2,
242
+ behaviorTracking: (_a = behaviorTracking != null ? behaviorTracking : parentLayout == null ? void 0 : parentLayout.behaviorTracking) != null ? _a : "onView"
243
+ };
244
+ const enrichmentTags = (_c = (_b = data.parameters) == null ? void 0 : _b[CANVAS_ENRICHMENT_TAG_PARAM]) == null ? void 0 : _c.value;
245
+ const TrackComponent = context.behaviorTracking === "onLoad" ? TrackFragment : Track;
246
+ const resolvedChildren = resolveChildren({
247
+ children,
248
+ data,
249
+ hasParentLayout: Boolean(parentLayout)
250
+ });
251
+ return /* @__PURE__ */ React3.createElement(CompositionContext.Provider, { value: context }, contextContextProviderPresent ? /* @__PURE__ */ React3.createElement(TrackComponent, { behavior: enrichmentTags }, resolvedChildren) : resolvedChildren);
252
+ }
253
+ function resolveChildren({
254
+ children,
255
+ data,
256
+ hasParentLayout
257
+ }) {
258
+ var _a;
259
+ let compositionChildren = children;
260
+ if (!compositionChildren && !hasParentLayout) {
261
+ const rootComponent = componentStore.get(data.type);
262
+ if (rootComponent) {
263
+ compositionChildren = React3.createElement(rootComponent, convertComponentToProps(data));
264
+ } else {
265
+ if (Object.keys((_a = data.slots) != null ? _a : {}).length > 1 && process.env.NODE_ENV === "development") {
266
+ console.warn(
267
+ `[canvas-dev] All the slots in component '${data.type}' are rendered in no particular order. Use '<Slot name={slotName} />' to reliably render the slots.`
268
+ );
269
+ }
270
+ compositionChildren = Object.keys(data.slots || {}).map((slotName) => /* @__PURE__ */ React3.createElement(Slot, { key: slotName, name: slotName }));
271
+ }
272
+ }
273
+ const renderChildren = typeof compositionChildren === "function" ? compositionChildren(convertComponentToProps(data)) : compositionChildren;
274
+ return renderChildren;
275
+ }
276
+
277
+ // src/components/DefaultNotImplementedComponent.tsx
278
+ import { CANVAS_LOCALIZATION_TYPE } from "@uniformdev/canvas";
279
+ import React4 from "react";
280
+ var wrapperStyles = {
281
+ borderLeft: "4px solid #e42535",
282
+ padding: "16px",
283
+ fontSize: "16px",
284
+ borderRadius: "0 8px 8px 0",
285
+ margin: "8px",
286
+ backgroundColor: "rgba(255, 255, 255, 0.45)",
287
+ color: "#1d3557"
288
+ };
289
+ function DefaultNotImplementedComponent(props) {
290
+ var _a;
291
+ const componentType = (_a = props.component) == null ? void 0 : _a.type;
292
+ if (!componentType) {
293
+ return null;
294
+ }
295
+ if (componentType === CANVAS_LOCALIZATION_TYPE) {
296
+ return /* @__PURE__ */ React4.createElement("div", { style: wrapperStyles }, /* @__PURE__ */ React4.createElement("p", null, "Seems like localization is not enabled in your application. Please read our documentation on how to", " ", /* @__PURE__ */ React4.createElement(
297
+ "a",
298
+ {
299
+ href: "https://docs.uniform.app/guides/composition/localization#activate-front-end",
300
+ target: "_blank",
301
+ style: { fontWeight: "bolder", textDecoration: "underline" },
302
+ rel: "noreferrer"
303
+ },
304
+ "enable localization in your front-end application."
305
+ )));
306
+ }
307
+ return /* @__PURE__ */ React4.createElement("div", { style: wrapperStyles }, /* @__PURE__ */ React4.createElement("h2", null, "Component: ", /* @__PURE__ */ React4.createElement("code", null, componentType)), /* @__PURE__ */ React4.createElement("p", null, /* @__PURE__ */ React4.createElement("code", null, /* @__PURE__ */ React4.createElement("strong", null, componentType)), " ", "has no React implementation. It may need to be added to your ", /* @__PURE__ */ React4.createElement("code", null, "resolveRenderer()"), " function."), /* @__PURE__ */ React4.createElement("details", null, /* @__PURE__ */ React4.createElement("summary", { style: { cursor: "pointer" } }, "Props"), /* @__PURE__ */ React4.createElement("pre", null, JSON.stringify(props, null, 2))));
308
+ }
309
+
310
+ // src/hooks/useCompositionEventEffect.ts
311
+ import {
312
+ CANVAS_DRAFT_STATE,
313
+ createEventBus,
314
+ subscribeToComposition
315
+ } from "@uniformdev/canvas";
316
+ import { useEffect } from "react";
317
+ function useCompositionEventEffect({
318
+ enabled,
319
+ projectId,
320
+ compositionId,
321
+ effect
322
+ }) {
323
+ useEffect(() => {
324
+ if (!enabled || !compositionId || !projectId) {
325
+ return;
326
+ }
327
+ let goodbye = void 0;
328
+ const loadEffect = async () => {
329
+ const eventBus = await createEventBus();
330
+ if (eventBus) {
331
+ goodbye = subscribeToComposition({
332
+ eventBus,
333
+ compositionId,
334
+ compositionState: CANVAS_DRAFT_STATE,
335
+ projectId,
336
+ callback: effect,
337
+ event: "updated"
338
+ });
339
+ }
340
+ };
341
+ loadEffect();
342
+ return () => {
343
+ if (goodbye) {
344
+ goodbye();
345
+ }
346
+ };
347
+ }, [compositionId, enabled, projectId, effect]);
348
+ }
349
+
350
+ // src/hooks/useContextualEditing.ts
351
+ import {
352
+ createCanvasChannel,
353
+ IN_CONTEXT_EDITOR_QUERY_STRING_PARAM,
354
+ isUpdateCompositionMessage
355
+ } from "@uniformdev/canvas";
356
+ import { useEffect as useEffect2, useMemo, useState } from "react";
357
+ var previewScriptId = "uniform-canvas-preview-script";
358
+ var createApiEnhancer = ({ apiUrl }) => {
359
+ return async (message) => {
360
+ const response = await fetch(apiUrl, {
361
+ method: "post",
362
+ body: JSON.stringify({
363
+ composition: message.composition,
364
+ hash: message.hash
365
+ }),
366
+ headers: {
367
+ "Content-Type": "application/json"
368
+ }
369
+ });
370
+ const json = await response.json();
371
+ if (!response.ok) {
372
+ throw new Error("Error reading enhanced composition");
373
+ }
374
+ const body = json;
375
+ return body.composition;
376
+ };
377
+ };
378
+ var useContextualEditing = ({
379
+ initialCompositionValue,
380
+ enhance = (message) => message.composition
381
+ }) => {
382
+ const [contextualComposition, setContextualComposition] = useState();
383
+ const channel = useMemo(() => {
384
+ var _a;
385
+ if (!isInContextEditingMode()) {
386
+ return;
387
+ }
388
+ const channel2 = createCanvasChannel({
389
+ broadcastTo: [(_a = window.opener) != null ? _a : window.top],
390
+ listenTo: [window]
391
+ });
392
+ return channel2;
393
+ }, []);
394
+ useEffect2(() => {
395
+ if (!channel) {
396
+ return;
397
+ }
398
+ const unsubscribe = channel.on("update-composition", async (message) => {
399
+ if (isUpdateCompositionMessage(message)) {
400
+ const composition = await enhance(message);
401
+ setContextualComposition(composition);
402
+ }
403
+ });
404
+ return () => {
405
+ unsubscribe();
406
+ };
407
+ }, [channel, enhance]);
408
+ useEffect2(() => {
409
+ if (!isInContextEditingMode()) {
410
+ return;
411
+ }
412
+ const existingScript = document.getElementById(previewScriptId);
413
+ if (existingScript) {
414
+ return;
415
+ }
416
+ const script = document.createElement("script");
417
+ script.id = previewScriptId;
418
+ script.src = getCanvasInContextEmbedScriptUrl();
419
+ script.async = true;
420
+ document.head.appendChild(script);
421
+ }, []);
422
+ return {
423
+ composition: contextualComposition != null ? contextualComposition : initialCompositionValue
424
+ };
425
+ };
426
+ function getCanvasInContextEmbedScriptUrl() {
427
+ const scriptUrl = `${window.document.referrer}files/canvas-in-context-embed/index.js`;
428
+ return scriptUrl;
429
+ }
430
+ function isInContextEditingMode() {
431
+ if (typeof window === "undefined") {
432
+ return false;
433
+ }
434
+ const isOpenedByInContextEditor = new URLSearchParams(window.location.search).has(
435
+ IN_CONTEXT_EDITOR_QUERY_STRING_PARAM
436
+ );
437
+ const isAllowlistedReferrer = Boolean(
438
+ window.document.referrer.match(/(^https:\/\/|\.)(uniform.app|uniform.wtf|localhost:\d{4})\//)
439
+ );
440
+ return isOpenedByInContextEditor && isAllowlistedReferrer;
441
+ }
442
+ export {
443
+ Composition,
444
+ DefaultNotImplementedComponent,
445
+ Slot,
446
+ componentStore,
447
+ componentStoreResolver,
448
+ createApiEnhancer,
449
+ createComponentStore,
450
+ createComponentStoreResolver,
451
+ registerUniformComponent,
452
+ useComposition,
453
+ useCompositionEventEffect,
454
+ useContextualEditing
455
+ };