@uniformdev/canvas-react 18.35.1-alpha.12 → 18.35.1-alpha.16

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.ts CHANGED
@@ -69,18 +69,137 @@ type UniformComponentContextValue = {
69
69
  declare function useUniformCurrentComponent(): UniformComponentContextValue;
70
70
  /**
71
71
  * Allows the rendering of a Canvas component instance (root or not), and its children if it has any.
72
- * Note that the actual rendering happens inside `<UniformSlot />`, this component only provides the services needed to achieve that.
72
+ * Note that the actual rendering happens inside `<Slot />`, this component only provides the services needed to achieve that.
73
73
  * This component is used internally by `<UniformComposition />`, which you should use in most cases.
74
74
  */
75
75
  declare function UniformComponent<TRenderProps = unknown>({ data, resolveRenderer, children, behaviorTracking, }: UniformComponentProps<TRenderProps>): JSX.Element | null;
76
76
 
77
+ /** @deprecated use `createUniformApiEnhancer` instead */
78
+ declare const createApiEnhancer: ({ apiUrl }: {
79
+ apiUrl: string;
80
+ }) => (message: UpdateCompositionMessage) => Promise<{
81
+ type: string;
82
+ parameters?: {
83
+ [key: string]: {
84
+ value: unknown;
85
+ type: string;
86
+ connectedData?: {
87
+ pointer: string;
88
+ syntax: "jptr";
89
+ } | undefined;
90
+ };
91
+ } | undefined;
92
+ variant?: string | undefined;
93
+ projectMapNodes?: {
94
+ id: string;
95
+ path: string;
96
+ projectMapId: string;
97
+ }[] | undefined;
98
+ slots?: {
99
+ [key: string]: {
100
+ type: string;
101
+ parameters?: {
102
+ [key: string]: {
103
+ value: unknown;
104
+ type: string;
105
+ connectedData?: {
106
+ pointer: string;
107
+ syntax: "jptr";
108
+ } | undefined;
109
+ };
110
+ } | undefined;
111
+ variant?: string | undefined;
112
+ slots?: {
113
+ [key: string]: any[];
114
+ } | undefined;
115
+ _id?: string | undefined;
116
+ _pattern?: string | undefined;
117
+ _dataResources?: {
118
+ [key: string]: {
119
+ type: string;
120
+ isPatternParameter?: boolean | undefined;
121
+ ignorePatternParameterDefault?: boolean | undefined;
122
+ variables?: {
123
+ [key: string]: string;
124
+ } | undefined;
125
+ };
126
+ } | undefined;
127
+ _patternDataResources?: {
128
+ [key: string]: {
129
+ type: string;
130
+ isPatternParameter?: boolean | undefined;
131
+ ignorePatternParameterDefault?: boolean | undefined;
132
+ variables?: {
133
+ [key: string]: string;
134
+ } | undefined;
135
+ };
136
+ } | undefined;
137
+ _patternError?: "NOTFOUND" | "CYCLIC" | undefined;
138
+ _overrides?: {
139
+ [key: string]: {
140
+ parameters?: {
141
+ [key: string]: {
142
+ value: unknown;
143
+ type: string;
144
+ connectedData?: {
145
+ pointer: string;
146
+ syntax: "jptr";
147
+ } | undefined;
148
+ };
149
+ } | undefined;
150
+ variant?: string | undefined;
151
+ };
152
+ } | undefined;
153
+ _overridability?: {
154
+ parameters?: {
155
+ [key: string]: "yes" | "no";
156
+ } | undefined;
157
+ variants?: boolean | undefined;
158
+ } | undefined;
159
+ }[];
160
+ } | undefined;
161
+ _id: string;
162
+ _slug?: string | null | undefined;
163
+ _name: string;
164
+ _dataResources?: {
165
+ [key: string]: {
166
+ type: string;
167
+ isPatternParameter?: boolean | undefined;
168
+ ignorePatternParameterDefault?: boolean | undefined;
169
+ variables?: {
170
+ [key: string]: string;
171
+ } | undefined;
172
+ };
173
+ } | undefined;
174
+ _overrides?: {
175
+ [key: string]: {
176
+ parameters?: {
177
+ [key: string]: {
178
+ value: unknown;
179
+ type: string;
180
+ connectedData?: {
181
+ pointer: string;
182
+ syntax: "jptr";
183
+ } | undefined;
184
+ };
185
+ } | undefined;
186
+ variant?: string | undefined;
187
+ };
188
+ } | undefined;
189
+ _overridability?: {
190
+ parameters?: {
191
+ [key: string]: "yes" | "no";
192
+ } | undefined;
193
+ variants?: boolean | undefined;
194
+ } | undefined;
195
+ }>;
77
196
  type UseUniformContextualEditingProps = {
78
197
  initialCompositionValue?: RootComponentInstance;
79
198
  /**
80
199
  * A function to enhance the composition after receiving it from Canvas editor.
81
200
  * WARNING: This enhancer will run on the client side. Make sure you're not exposing any secrets. You can use `createApiEnhancer` to create an enhancer based on an API route.
82
201
  */
83
- enhance?: (composition: UpdateCompositionMessage) => RootComponentInstance | Promise<RootComponentInstance>;
202
+ enhance?: ({ composition, hash, }: Pick<UpdateCompositionMessage, 'composition' | 'hash'>) => RootComponentInstance | Promise<RootComponentInstance>;
84
203
  };
85
204
  /**
86
205
  * Adds contextual editing capability to a Uniform app.
@@ -205,6 +324,128 @@ declare const useUniformContextualEditing: ({ initialCompositionValue, enhance,
205
324
  } | undefined;
206
325
  isContextualEditing: boolean;
207
326
  };
327
+ /** @deprecated use useUniformContextualEditing instead */
328
+ declare const useContextualEditing: ({ initialCompositionValue, enhance, }: UseUniformContextualEditingProps) => {
329
+ composition: {
330
+ type: string;
331
+ parameters?: {
332
+ [key: string]: {
333
+ value: unknown;
334
+ type: string;
335
+ connectedData?: {
336
+ pointer: string;
337
+ syntax: "jptr";
338
+ } | undefined;
339
+ };
340
+ } | undefined;
341
+ variant?: string | undefined;
342
+ projectMapNodes?: {
343
+ id: string;
344
+ path: string;
345
+ projectMapId: string;
346
+ }[] | undefined;
347
+ slots?: {
348
+ [key: string]: {
349
+ type: string;
350
+ parameters?: {
351
+ [key: string]: {
352
+ value: unknown;
353
+ type: string;
354
+ connectedData?: {
355
+ pointer: string;
356
+ syntax: "jptr";
357
+ } | undefined;
358
+ };
359
+ } | undefined;
360
+ variant?: string | undefined;
361
+ slots?: {
362
+ [key: string]: any[];
363
+ } | undefined;
364
+ _id?: string | undefined;
365
+ _pattern?: string | undefined;
366
+ _dataResources?: {
367
+ [key: string]: {
368
+ type: string;
369
+ isPatternParameter?: boolean | undefined;
370
+ ignorePatternParameterDefault?: boolean | undefined;
371
+ variables?: {
372
+ [key: string]: string;
373
+ } | undefined;
374
+ };
375
+ } | undefined;
376
+ _patternDataResources?: {
377
+ [key: string]: {
378
+ type: string;
379
+ isPatternParameter?: boolean | undefined;
380
+ ignorePatternParameterDefault?: boolean | undefined;
381
+ variables?: {
382
+ [key: string]: string;
383
+ } | undefined;
384
+ };
385
+ } | undefined;
386
+ _patternError?: "NOTFOUND" | "CYCLIC" | undefined;
387
+ _overrides?: {
388
+ [key: string]: {
389
+ parameters?: {
390
+ [key: string]: {
391
+ value: unknown;
392
+ type: string;
393
+ connectedData?: {
394
+ pointer: string;
395
+ syntax: "jptr";
396
+ } | undefined;
397
+ };
398
+ } | undefined;
399
+ variant?: string | undefined;
400
+ };
401
+ } | undefined;
402
+ _overridability?: {
403
+ parameters?: {
404
+ [key: string]: "yes" | "no";
405
+ } | undefined;
406
+ variants?: boolean | undefined;
407
+ } | undefined;
408
+ }[];
409
+ } | undefined;
410
+ _id: string;
411
+ _slug?: string | null | undefined;
412
+ _name: string;
413
+ _dataResources?: {
414
+ [key: string]: {
415
+ type: string;
416
+ isPatternParameter?: boolean | undefined;
417
+ ignorePatternParameterDefault?: boolean | undefined;
418
+ variables?: {
419
+ [key: string]: string;
420
+ } | undefined;
421
+ };
422
+ } | undefined;
423
+ _overrides?: {
424
+ [key: string]: {
425
+ parameters?: {
426
+ [key: string]: {
427
+ value: unknown;
428
+ type: string;
429
+ connectedData?: {
430
+ pointer: string;
431
+ syntax: "jptr";
432
+ } | undefined;
433
+ };
434
+ } | undefined;
435
+ variant?: string | undefined;
436
+ };
437
+ } | undefined;
438
+ _overridability?: {
439
+ parameters?: {
440
+ [key: string]: "yes" | "no";
441
+ } | undefined;
442
+ variants?: boolean | undefined;
443
+ } | undefined;
444
+ } | undefined;
445
+ isContextualEditing: boolean;
446
+ };
447
+ /** @deprecated use UseUniformContextualEditingProps instead */
448
+ type UseContextualEditingProps = UseUniformContextualEditingProps;
208
449
 
209
450
  type UniformCompositionProps<TRenderProps = unknown> = UniformComponentProps<TRenderProps> & {
210
451
  /** The composition data */
@@ -227,6 +468,12 @@ declare function useUniformCurrentComposition(): UniformCompositionContextValue;
227
468
  * It also takes care of enabling [Contextual Editing](https://docs.uniform.app/capabilities/composition/contextual-editing).
228
469
  */
229
470
  declare function UniformComposition<TRenderProps = unknown>({ data, behaviorTracking, children, resolveRenderer, contextualEditingEnhancer, }: UniformCompositionProps<TRenderProps>): JSX.Element;
471
+ /** @deprecated use `useUniformCurrentComposition` instead */
472
+ declare const useComposition: typeof useUniformCurrentComposition;
473
+ /** @deprecated use `UniformComposition` instead */
474
+ declare const Composition: typeof UniformComposition;
475
+ /** @deprecated use `UniformCompositionProps` instead */
476
+ type CompositionProps<TRenderProps = unknown> = UniformCompositionProps<TRenderProps>;
230
477
 
231
478
  type CustomSlotChildRenderFunc = (options: {
232
479
  child: ReactNode;
@@ -252,6 +499,32 @@ type UniformSlotProps<TSlotNames extends string> = {
252
499
  };
253
500
  /** Renders a named Slot within a Composition. */
254
501
  declare function UniformSlot<TSlotNames extends string = string>({ name, resolveRenderer, children, emptyPlaceholder, }: UniformSlotProps<TSlotNames>): JSX.Element | null;
502
+ /** @deprecated use `UniformSlotProps` instead */
503
+ type SlotProps<TSlotNames extends string> = UniformSlotProps<TSlotNames>;
504
+ /** @deprecated use `UniformSlot` instead */
505
+ declare const Slot: typeof UniformSlot;
506
+
507
+ type ParameterTextValue = string | undefined;
508
+ type UniformTextProps = {
509
+ /**
510
+ * The name of the HTML tag to render.
511
+ * @default "span"
512
+ */
513
+ as?: React$1.ElementType;
514
+ /** The ID of the parameter. */
515
+ parameterId: string;
516
+ /**
517
+ * When set to true, it adds `whiteSpace: 'pre-wrap'` to the styles of the root element to allow the rendering of line breaks.
518
+ * @default false
519
+ */
520
+ isMultiline?: boolean;
521
+ /**
522
+ * A function to customize the rendering of the parameter value. Useful to format the value before rendering it.
523
+ * @default "(value) => value"
524
+ */
525
+ render?: (value: ParameterTextValue) => React$1.ReactNode;
526
+ } & Omit<React$1.HTMLAttributes<HTMLSpanElement>, 'children'>;
527
+ declare const UniformText: ({ as: Tag, parameterId, isMultiline, render, ...props }: UniformTextProps) => JSX.Element;
255
528
 
256
529
  type UseCompositionEventEffectOptions = Omit<Partial<SubscribeToCompositionOptions>, 'callback'> & {
257
530
  enabled: boolean;
@@ -276,4 +549,4 @@ declare const createComponentStoreResolver: (options: {
276
549
  defaultComponent?: React$1.ComponentType<ComponentProps<any>>;
277
550
  }) => RenderComponentResolver;
278
551
 
279
- export { ComponentProps, ComponentStore, DefaultNotImplementedComponent, NOT_IMPLEMENTED_COMPONENT, RenderComponentResolver, SystemRenderConfig, SystemRenderFunction, UniformComponent, UniformComponentContextValue, UniformComponentProps, UniformComposition, UniformCompositionProps, UniformSlot, UniformSlotProps, UseCompositionEventEffectOptions, UseUniformContextualEditingProps, componentStore, componentStoreResolver, createComponentStore, createComponentStoreResolver, registerUniformComponent, useCompositionEventEffect, useUniformContextualEditing, useUniformCurrentComponent, useUniformCurrentComposition };
552
+ export { ComponentProps, ComponentStore, Composition, CompositionProps, DefaultNotImplementedComponent, NOT_IMPLEMENTED_COMPONENT, RenderComponentResolver, Slot, SlotProps, SystemRenderConfig, SystemRenderFunction, UniformComponent, UniformComponentContextValue, UniformComponentProps, UniformComposition, UniformCompositionProps, UniformSlot, UniformSlotProps, UniformText, UniformTextProps, UseCompositionEventEffectOptions, UseContextualEditingProps, UseUniformContextualEditingProps, componentStore, componentStoreResolver, createApiEnhancer, createComponentStore, createComponentStoreResolver, registerUniformComponent, useComposition, useCompositionEventEffect, useContextualEditing, useUniformContextualEditing, useUniformCurrentComponent, useUniformCurrentComposition };
package/dist/index.esm.js CHANGED
@@ -64,7 +64,8 @@ var createComponentStore = () => {
64
64
  components.set(getTypeWithVariant(type, variantId), component);
65
65
  },
66
66
  get: (type, variantId) => {
67
- return components.get(getTypeWithVariant(type, variantId));
67
+ var _a;
68
+ return (_a = components.get(getTypeWithVariant(type, variantId))) != null ? _a : components.get(getTypeWithVariant(type));
68
69
  }
69
70
  };
70
71
  };
@@ -162,9 +163,10 @@ import {
162
163
  EMPTY_COMPOSITION,
163
164
  IN_CONTEXT_EDITOR_EMBED_SCRIPT_ID,
164
165
  IN_CONTEXT_EDITOR_QUERY_STRING_PARAM,
165
- isUpdateCompositionMessage
166
+ isUpdateCompositionInternalMessage
166
167
  } from "@uniformdev/canvas";
167
168
  import { useEffect, useMemo, useState } from "react";
169
+ var createApiEnhancer = createUniformApiEnhancer;
168
170
  var registeredCompositionIds = /* @__PURE__ */ new Set();
169
171
  var useUniformContextualEditing = ({
170
172
  initialCompositionValue,
@@ -190,8 +192,8 @@ var useUniformContextualEditing = ({
190
192
  if (!channel || registeredCompositionIds.has(initialCompositionValue == null ? void 0 : initialCompositionValue._id)) {
191
193
  return;
192
194
  }
193
- const unsubscribeFromCompositionUpdates = channel.on("update-composition", async (message) => {
194
- if (!isUpdateCompositionMessage(message)) {
195
+ const unsubscribeFromCompositionUpdates = channel.on("update-composition-internal", async (message) => {
196
+ if (!isUpdateCompositionInternalMessage(message)) {
195
197
  return;
196
198
  }
197
199
  const enhancedComposition = await enhance(message);
@@ -243,6 +245,7 @@ function isInContextEditingMode() {
243
245
  );
244
246
  return isOpenedByInContextEditor && isAllowlistedReferrer;
245
247
  }
248
+ var useContextualEditing = useUniformContextualEditing;
246
249
 
247
250
  // src/components/UniformComposition.tsx
248
251
  var UniformCompositionContext = createContext({
@@ -279,6 +282,8 @@ function UniformComposition({
279
282
  ))
280
283
  );
281
284
  }
285
+ var useComposition = useUniformCurrentComposition;
286
+ var Composition = UniformComposition;
282
287
 
283
288
  // src/components/ContextualEditingComponentWrapper.tsx
284
289
  function ContextualEditingComponentWrapper({
@@ -365,7 +370,7 @@ function renderComponent({
365
370
  }) {
366
371
  const RenderComponent = resolveRenderer == null ? void 0 : resolveRenderer(component);
367
372
  if (component.type === CANVAS_TEST_TYPE) {
368
- return resolveSystem.test(
373
+ const testComponent = resolveSystem.test(
369
374
  component,
370
375
  key,
371
376
  (variantComponent, key2) => {
@@ -384,8 +389,20 @@ function renderComponent({
384
389
  });
385
390
  }
386
391
  );
392
+ return /* @__PURE__ */ React5.createElement(
393
+ ContextualEditingComponentWrapper,
394
+ {
395
+ component,
396
+ parentComponent,
397
+ slotName,
398
+ indexInSlot,
399
+ slotChildrenCount,
400
+ emptyPlaceholder
401
+ },
402
+ testComponent
403
+ );
387
404
  } else if (component.type === CANVAS_PERSONALIZE_TYPE) {
388
- return resolveSystem.personalization(
405
+ const personalizationComponent = resolveSystem.personalization(
389
406
  component,
390
407
  key,
391
408
  (variantComponent, key2) => {
@@ -404,6 +421,18 @@ function renderComponent({
404
421
  });
405
422
  }
406
423
  );
424
+ return /* @__PURE__ */ React5.createElement(
425
+ ContextualEditingComponentWrapper,
426
+ {
427
+ component,
428
+ parentComponent,
429
+ slotName,
430
+ indexInSlot,
431
+ slotChildrenCount,
432
+ emptyPlaceholder
433
+ },
434
+ personalizationComponent
435
+ );
407
436
  } else if (RenderComponent) {
408
437
  const props = convertComponentToProps(component);
409
438
  return /* @__PURE__ */ React5.createElement(UniformComponent, { key, data: component, resolveRenderer }, /* @__PURE__ */ React5.createElement(
@@ -427,6 +456,7 @@ function renderComponent({
427
456
  }
428
457
  return null;
429
458
  }
459
+ var Slot = UniformSlot;
430
460
 
431
461
  // src/components/UniformComponent.tsx
432
462
  var UniformComponentContext = createContext2({});
@@ -480,7 +510,7 @@ function resolveChildren({
480
510
  } else {
481
511
  if (Object.keys((_a = data.slots) != null ? _a : {}).length > 1 && process.env.NODE_ENV === "development") {
482
512
  console.warn(
483
- `[canvas-dev] All the slots in component '${data.type}' are rendered in no particular order. Use '<UniformSlot name={slotName} />' to reliably render the slots.`
513
+ `[canvas-dev] All the slots in component '${data.type}' are rendered in no particular order. Use '<Slot name={slotName} />' to reliably render the slots.`
484
514
  );
485
515
  }
486
516
  children = Object.keys(data.slots || {}).map((slotName) => /* @__PURE__ */ React6.createElement(UniformSlot, { key: slotName, name: slotName }));
@@ -490,6 +520,55 @@ function resolveChildren({
490
520
  return renderChildren;
491
521
  }
492
522
 
523
+ // src/components/UniformText.tsx
524
+ import React7, { useCallback, useMemo as useMemo2, useRef, useState as useState2 } from "react";
525
+ var UniformText = ({
526
+ as: Tag = "span",
527
+ parameterId,
528
+ isMultiline = false,
529
+ render = (value) => value,
530
+ ...props
531
+ }) => {
532
+ const { data: componentData } = useUniformCurrentComponent();
533
+ const { isContextualEditing } = useUniformCurrentComposition();
534
+ const elementRef = useRef(null);
535
+ const [isFocused, setIsFocused] = useState2(false);
536
+ const value = useMemo2(() => {
537
+ var _a;
538
+ return (_a = componentData == null ? void 0 : componentData.parameters) == null ? void 0 : _a[parameterId].value;
539
+ }, [componentData, parameterId]);
540
+ const isEditable = useMemo2(() => {
541
+ var _a, _b, _c;
542
+ return (_c = (_b = ((_a = componentData == null ? void 0 : componentData.parameters) == null ? void 0 : _a[parameterId])._contextualEditing) == null ? void 0 : _b.isEditable) != null ? _c : false;
543
+ }, [componentData, parameterId]);
544
+ const handleOnFocus = useCallback(() => {
545
+ setIsFocused(true);
546
+ }, [setIsFocused]);
547
+ const handleOnBlur = useCallback(() => {
548
+ setIsFocused(false);
549
+ }, [setIsFocused]);
550
+ const shouldSkipCustomRendering = useMemo2(() => isFocused && isEditable, [isFocused, isEditable]);
551
+ if (!isContextualEditing) {
552
+ return /* @__PURE__ */ React7.createElement(Tag, { style: isMultiline ? { whiteSpace: "pre-wrap" } : {}, ...props }, render(value));
553
+ }
554
+ return /* @__PURE__ */ React7.createElement(
555
+ Tag,
556
+ {
557
+ ...props,
558
+ ref: elementRef,
559
+ "data-uniform-component-id": componentData == null ? void 0 : componentData._id,
560
+ "data-uniform-parameter-id": parameterId,
561
+ "data-uniform-parameter-type": "text",
562
+ style: isMultiline ? { whiteSpace: "pre-wrap" } : {},
563
+ contentEditable: isEditable,
564
+ suppressContentEditableWarning: true,
565
+ onFocus: handleOnFocus,
566
+ onBlur: handleOnBlur
567
+ },
568
+ shouldSkipCustomRendering ? value : render(value)
569
+ );
570
+ };
571
+
493
572
  // src/hooks/useCompositionEventEffect.ts
494
573
  import {
495
574
  CANVAS_DRAFT_STATE,
@@ -530,18 +609,24 @@ function useCompositionEventEffect({
530
609
  }, [compositionId, enabled, projectId, effect]);
531
610
  }
532
611
  export {
612
+ Composition,
533
613
  DefaultNotImplementedComponent,
534
614
  NOT_IMPLEMENTED_COMPONENT,
615
+ Slot,
535
616
  UniformComponent,
536
617
  UniformComposition,
537
618
  UniformSlot,
619
+ UniformText,
538
620
  componentStore,
539
621
  componentStoreResolver,
622
+ createApiEnhancer,
540
623
  createComponentStore,
541
624
  createComponentStoreResolver,
542
625
  createUniformApiEnhancer,
543
626
  registerUniformComponent,
627
+ useComposition,
544
628
  useCompositionEventEffect,
629
+ useContextualEditing,
545
630
  useUniformContextualEditing,
546
631
  useUniformCurrentComponent,
547
632
  useUniformCurrentComposition
package/dist/index.js CHANGED
@@ -30,18 +30,24 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ Composition: () => Composition,
33
34
  DefaultNotImplementedComponent: () => DefaultNotImplementedComponent,
34
35
  NOT_IMPLEMENTED_COMPONENT: () => NOT_IMPLEMENTED_COMPONENT,
36
+ Slot: () => Slot,
35
37
  UniformComponent: () => UniformComponent,
36
38
  UniformComposition: () => UniformComposition,
37
39
  UniformSlot: () => UniformSlot,
40
+ UniformText: () => UniformText,
38
41
  componentStore: () => componentStore,
39
42
  componentStoreResolver: () => componentStoreResolver,
43
+ createApiEnhancer: () => createApiEnhancer,
40
44
  createComponentStore: () => createComponentStore,
41
45
  createComponentStoreResolver: () => createComponentStoreResolver,
42
46
  createUniformApiEnhancer: () => import_canvas3.createUniformApiEnhancer,
43
47
  registerUniformComponent: () => registerUniformComponent,
48
+ useComposition: () => useComposition,
44
49
  useCompositionEventEffect: () => useCompositionEventEffect,
50
+ useContextualEditing: () => useContextualEditing,
45
51
  useUniformContextualEditing: () => useUniformContextualEditing,
46
52
  useUniformCurrentComponent: () => useUniformCurrentComponent,
47
53
  useUniformCurrentComposition: () => useUniformCurrentComposition
@@ -112,7 +118,8 @@ var createComponentStore = () => {
112
118
  components.set(getTypeWithVariant(type, variantId), component);
113
119
  },
114
120
  get: (type, variantId) => {
115
- return components.get(getTypeWithVariant(type, variantId));
121
+ var _a;
122
+ return (_a = components.get(getTypeWithVariant(type, variantId))) != null ? _a : components.get(getTypeWithVariant(type));
116
123
  }
117
124
  };
118
125
  };
@@ -193,6 +200,7 @@ var import_react3 = __toESM(require("react"));
193
200
  // src/hooks/useUniformContextualEditing.ts
194
201
  var import_canvas3 = require("@uniformdev/canvas");
195
202
  var import_react2 = require("react");
203
+ var createApiEnhancer = import_canvas3.createUniformApiEnhancer;
196
204
  var registeredCompositionIds = /* @__PURE__ */ new Set();
197
205
  var useUniformContextualEditing = ({
198
206
  initialCompositionValue,
@@ -218,8 +226,8 @@ var useUniformContextualEditing = ({
218
226
  if (!channel || registeredCompositionIds.has(initialCompositionValue == null ? void 0 : initialCompositionValue._id)) {
219
227
  return;
220
228
  }
221
- const unsubscribeFromCompositionUpdates = channel.on("update-composition", async (message) => {
222
- if (!(0, import_canvas3.isUpdateCompositionMessage)(message)) {
229
+ const unsubscribeFromCompositionUpdates = channel.on("update-composition-internal", async (message) => {
230
+ if (!(0, import_canvas3.isUpdateCompositionInternalMessage)(message)) {
223
231
  return;
224
232
  }
225
233
  const enhancedComposition = await enhance(message);
@@ -271,6 +279,7 @@ function isInContextEditingMode() {
271
279
  );
272
280
  return isOpenedByInContextEditor && isAllowlistedReferrer;
273
281
  }
282
+ var useContextualEditing = useUniformContextualEditing;
274
283
 
275
284
  // src/components/UniformComposition.tsx
276
285
  var UniformCompositionContext = (0, import_react3.createContext)({
@@ -307,6 +316,8 @@ function UniformComposition({
307
316
  ))
308
317
  );
309
318
  }
319
+ var useComposition = useUniformCurrentComposition;
320
+ var Composition = UniformComposition;
310
321
 
311
322
  // src/components/ContextualEditingComponentWrapper.tsx
312
323
  function ContextualEditingComponentWrapper({
@@ -393,7 +404,7 @@ function renderComponent({
393
404
  }) {
394
405
  const RenderComponent = resolveRenderer == null ? void 0 : resolveRenderer(component);
395
406
  if (component.type === import_canvas5.CANVAS_TEST_TYPE) {
396
- return resolveSystem.test(
407
+ const testComponent = resolveSystem.test(
397
408
  component,
398
409
  key,
399
410
  (variantComponent, key2) => {
@@ -412,8 +423,20 @@ function renderComponent({
412
423
  });
413
424
  }
414
425
  );
426
+ return /* @__PURE__ */ import_react5.default.createElement(
427
+ ContextualEditingComponentWrapper,
428
+ {
429
+ component,
430
+ parentComponent,
431
+ slotName,
432
+ indexInSlot,
433
+ slotChildrenCount,
434
+ emptyPlaceholder
435
+ },
436
+ testComponent
437
+ );
415
438
  } else if (component.type === import_canvas5.CANVAS_PERSONALIZE_TYPE) {
416
- return resolveSystem.personalization(
439
+ const personalizationComponent = resolveSystem.personalization(
417
440
  component,
418
441
  key,
419
442
  (variantComponent, key2) => {
@@ -432,6 +455,18 @@ function renderComponent({
432
455
  });
433
456
  }
434
457
  );
458
+ return /* @__PURE__ */ import_react5.default.createElement(
459
+ ContextualEditingComponentWrapper,
460
+ {
461
+ component,
462
+ parentComponent,
463
+ slotName,
464
+ indexInSlot,
465
+ slotChildrenCount,
466
+ emptyPlaceholder
467
+ },
468
+ personalizationComponent
469
+ );
435
470
  } else if (RenderComponent) {
436
471
  const props = convertComponentToProps(component);
437
472
  return /* @__PURE__ */ import_react5.default.createElement(UniformComponent, { key, data: component, resolveRenderer }, /* @__PURE__ */ import_react5.default.createElement(
@@ -455,6 +490,7 @@ function renderComponent({
455
490
  }
456
491
  return null;
457
492
  }
493
+ var Slot = UniformSlot;
458
494
 
459
495
  // src/components/UniformComponent.tsx
460
496
  var UniformComponentContext = (0, import_react6.createContext)({});
@@ -508,7 +544,7 @@ function resolveChildren({
508
544
  } else {
509
545
  if (Object.keys((_a = data.slots) != null ? _a : {}).length > 1 && process.env.NODE_ENV === "development") {
510
546
  console.warn(
511
- `[canvas-dev] All the slots in component '${data.type}' are rendered in no particular order. Use '<UniformSlot name={slotName} />' to reliably render the slots.`
547
+ `[canvas-dev] All the slots in component '${data.type}' are rendered in no particular order. Use '<Slot name={slotName} />' to reliably render the slots.`
512
548
  );
513
549
  }
514
550
  children = Object.keys(data.slots || {}).map((slotName) => /* @__PURE__ */ import_react6.default.createElement(UniformSlot, { key: slotName, name: slotName }));
@@ -518,16 +554,65 @@ function resolveChildren({
518
554
  return renderChildren;
519
555
  }
520
556
 
557
+ // src/components/UniformText.tsx
558
+ var import_react7 = __toESM(require("react"));
559
+ var UniformText = ({
560
+ as: Tag = "span",
561
+ parameterId,
562
+ isMultiline = false,
563
+ render = (value) => value,
564
+ ...props
565
+ }) => {
566
+ const { data: componentData } = useUniformCurrentComponent();
567
+ const { isContextualEditing } = useUniformCurrentComposition();
568
+ const elementRef = (0, import_react7.useRef)(null);
569
+ const [isFocused, setIsFocused] = (0, import_react7.useState)(false);
570
+ const value = (0, import_react7.useMemo)(() => {
571
+ var _a;
572
+ return (_a = componentData == null ? void 0 : componentData.parameters) == null ? void 0 : _a[parameterId].value;
573
+ }, [componentData, parameterId]);
574
+ const isEditable = (0, import_react7.useMemo)(() => {
575
+ var _a, _b, _c;
576
+ return (_c = (_b = ((_a = componentData == null ? void 0 : componentData.parameters) == null ? void 0 : _a[parameterId])._contextualEditing) == null ? void 0 : _b.isEditable) != null ? _c : false;
577
+ }, [componentData, parameterId]);
578
+ const handleOnFocus = (0, import_react7.useCallback)(() => {
579
+ setIsFocused(true);
580
+ }, [setIsFocused]);
581
+ const handleOnBlur = (0, import_react7.useCallback)(() => {
582
+ setIsFocused(false);
583
+ }, [setIsFocused]);
584
+ const shouldSkipCustomRendering = (0, import_react7.useMemo)(() => isFocused && isEditable, [isFocused, isEditable]);
585
+ if (!isContextualEditing) {
586
+ return /* @__PURE__ */ import_react7.default.createElement(Tag, { style: isMultiline ? { whiteSpace: "pre-wrap" } : {}, ...props }, render(value));
587
+ }
588
+ return /* @__PURE__ */ import_react7.default.createElement(
589
+ Tag,
590
+ {
591
+ ...props,
592
+ ref: elementRef,
593
+ "data-uniform-component-id": componentData == null ? void 0 : componentData._id,
594
+ "data-uniform-parameter-id": parameterId,
595
+ "data-uniform-parameter-type": "text",
596
+ style: isMultiline ? { whiteSpace: "pre-wrap" } : {},
597
+ contentEditable: isEditable,
598
+ suppressContentEditableWarning: true,
599
+ onFocus: handleOnFocus,
600
+ onBlur: handleOnBlur
601
+ },
602
+ shouldSkipCustomRendering ? value : render(value)
603
+ );
604
+ };
605
+
521
606
  // src/hooks/useCompositionEventEffect.ts
522
607
  var import_canvas7 = require("@uniformdev/canvas");
523
- var import_react7 = require("react");
608
+ var import_react8 = require("react");
524
609
  function useCompositionEventEffect({
525
610
  enabled,
526
611
  projectId,
527
612
  compositionId,
528
613
  effect
529
614
  }) {
530
- (0, import_react7.useEffect)(() => {
615
+ (0, import_react8.useEffect)(() => {
531
616
  if (!enabled || !compositionId || !projectId) {
532
617
  return;
533
618
  }
@@ -555,18 +640,24 @@ function useCompositionEventEffect({
555
640
  }
556
641
  // Annotate the CommonJS export names for ESM import in node:
557
642
  0 && (module.exports = {
643
+ Composition,
558
644
  DefaultNotImplementedComponent,
559
645
  NOT_IMPLEMENTED_COMPONENT,
646
+ Slot,
560
647
  UniformComponent,
561
648
  UniformComposition,
562
649
  UniformSlot,
650
+ UniformText,
563
651
  componentStore,
564
652
  componentStoreResolver,
653
+ createApiEnhancer,
565
654
  createComponentStore,
566
655
  createComponentStoreResolver,
567
656
  createUniformApiEnhancer,
568
657
  registerUniformComponent,
658
+ useComposition,
569
659
  useCompositionEventEffect,
660
+ useContextualEditing,
570
661
  useUniformContextualEditing,
571
662
  useUniformCurrentComponent,
572
663
  useUniformCurrentComposition
package/dist/index.mjs CHANGED
@@ -64,7 +64,8 @@ var createComponentStore = () => {
64
64
  components.set(getTypeWithVariant(type, variantId), component);
65
65
  },
66
66
  get: (type, variantId) => {
67
- return components.get(getTypeWithVariant(type, variantId));
67
+ var _a;
68
+ return (_a = components.get(getTypeWithVariant(type, variantId))) != null ? _a : components.get(getTypeWithVariant(type));
68
69
  }
69
70
  };
70
71
  };
@@ -162,9 +163,10 @@ import {
162
163
  EMPTY_COMPOSITION,
163
164
  IN_CONTEXT_EDITOR_EMBED_SCRIPT_ID,
164
165
  IN_CONTEXT_EDITOR_QUERY_STRING_PARAM,
165
- isUpdateCompositionMessage
166
+ isUpdateCompositionInternalMessage
166
167
  } from "@uniformdev/canvas";
167
168
  import { useEffect, useMemo, useState } from "react";
169
+ var createApiEnhancer = createUniformApiEnhancer;
168
170
  var registeredCompositionIds = /* @__PURE__ */ new Set();
169
171
  var useUniformContextualEditing = ({
170
172
  initialCompositionValue,
@@ -190,8 +192,8 @@ var useUniformContextualEditing = ({
190
192
  if (!channel || registeredCompositionIds.has(initialCompositionValue == null ? void 0 : initialCompositionValue._id)) {
191
193
  return;
192
194
  }
193
- const unsubscribeFromCompositionUpdates = channel.on("update-composition", async (message) => {
194
- if (!isUpdateCompositionMessage(message)) {
195
+ const unsubscribeFromCompositionUpdates = channel.on("update-composition-internal", async (message) => {
196
+ if (!isUpdateCompositionInternalMessage(message)) {
195
197
  return;
196
198
  }
197
199
  const enhancedComposition = await enhance(message);
@@ -243,6 +245,7 @@ function isInContextEditingMode() {
243
245
  );
244
246
  return isOpenedByInContextEditor && isAllowlistedReferrer;
245
247
  }
248
+ var useContextualEditing = useUniformContextualEditing;
246
249
 
247
250
  // src/components/UniformComposition.tsx
248
251
  var UniformCompositionContext = createContext({
@@ -279,6 +282,8 @@ function UniformComposition({
279
282
  ))
280
283
  );
281
284
  }
285
+ var useComposition = useUniformCurrentComposition;
286
+ var Composition = UniformComposition;
282
287
 
283
288
  // src/components/ContextualEditingComponentWrapper.tsx
284
289
  function ContextualEditingComponentWrapper({
@@ -365,7 +370,7 @@ function renderComponent({
365
370
  }) {
366
371
  const RenderComponent = resolveRenderer == null ? void 0 : resolveRenderer(component);
367
372
  if (component.type === CANVAS_TEST_TYPE) {
368
- return resolveSystem.test(
373
+ const testComponent = resolveSystem.test(
369
374
  component,
370
375
  key,
371
376
  (variantComponent, key2) => {
@@ -384,8 +389,20 @@ function renderComponent({
384
389
  });
385
390
  }
386
391
  );
392
+ return /* @__PURE__ */ React5.createElement(
393
+ ContextualEditingComponentWrapper,
394
+ {
395
+ component,
396
+ parentComponent,
397
+ slotName,
398
+ indexInSlot,
399
+ slotChildrenCount,
400
+ emptyPlaceholder
401
+ },
402
+ testComponent
403
+ );
387
404
  } else if (component.type === CANVAS_PERSONALIZE_TYPE) {
388
- return resolveSystem.personalization(
405
+ const personalizationComponent = resolveSystem.personalization(
389
406
  component,
390
407
  key,
391
408
  (variantComponent, key2) => {
@@ -404,6 +421,18 @@ function renderComponent({
404
421
  });
405
422
  }
406
423
  );
424
+ return /* @__PURE__ */ React5.createElement(
425
+ ContextualEditingComponentWrapper,
426
+ {
427
+ component,
428
+ parentComponent,
429
+ slotName,
430
+ indexInSlot,
431
+ slotChildrenCount,
432
+ emptyPlaceholder
433
+ },
434
+ personalizationComponent
435
+ );
407
436
  } else if (RenderComponent) {
408
437
  const props = convertComponentToProps(component);
409
438
  return /* @__PURE__ */ React5.createElement(UniformComponent, { key, data: component, resolveRenderer }, /* @__PURE__ */ React5.createElement(
@@ -427,6 +456,7 @@ function renderComponent({
427
456
  }
428
457
  return null;
429
458
  }
459
+ var Slot = UniformSlot;
430
460
 
431
461
  // src/components/UniformComponent.tsx
432
462
  var UniformComponentContext = createContext2({});
@@ -480,7 +510,7 @@ function resolveChildren({
480
510
  } else {
481
511
  if (Object.keys((_a = data.slots) != null ? _a : {}).length > 1 && process.env.NODE_ENV === "development") {
482
512
  console.warn(
483
- `[canvas-dev] All the slots in component '${data.type}' are rendered in no particular order. Use '<UniformSlot name={slotName} />' to reliably render the slots.`
513
+ `[canvas-dev] All the slots in component '${data.type}' are rendered in no particular order. Use '<Slot name={slotName} />' to reliably render the slots.`
484
514
  );
485
515
  }
486
516
  children = Object.keys(data.slots || {}).map((slotName) => /* @__PURE__ */ React6.createElement(UniformSlot, { key: slotName, name: slotName }));
@@ -490,6 +520,55 @@ function resolveChildren({
490
520
  return renderChildren;
491
521
  }
492
522
 
523
+ // src/components/UniformText.tsx
524
+ import React7, { useCallback, useMemo as useMemo2, useRef, useState as useState2 } from "react";
525
+ var UniformText = ({
526
+ as: Tag = "span",
527
+ parameterId,
528
+ isMultiline = false,
529
+ render = (value) => value,
530
+ ...props
531
+ }) => {
532
+ const { data: componentData } = useUniformCurrentComponent();
533
+ const { isContextualEditing } = useUniformCurrentComposition();
534
+ const elementRef = useRef(null);
535
+ const [isFocused, setIsFocused] = useState2(false);
536
+ const value = useMemo2(() => {
537
+ var _a;
538
+ return (_a = componentData == null ? void 0 : componentData.parameters) == null ? void 0 : _a[parameterId].value;
539
+ }, [componentData, parameterId]);
540
+ const isEditable = useMemo2(() => {
541
+ var _a, _b, _c;
542
+ return (_c = (_b = ((_a = componentData == null ? void 0 : componentData.parameters) == null ? void 0 : _a[parameterId])._contextualEditing) == null ? void 0 : _b.isEditable) != null ? _c : false;
543
+ }, [componentData, parameterId]);
544
+ const handleOnFocus = useCallback(() => {
545
+ setIsFocused(true);
546
+ }, [setIsFocused]);
547
+ const handleOnBlur = useCallback(() => {
548
+ setIsFocused(false);
549
+ }, [setIsFocused]);
550
+ const shouldSkipCustomRendering = useMemo2(() => isFocused && isEditable, [isFocused, isEditable]);
551
+ if (!isContextualEditing) {
552
+ return /* @__PURE__ */ React7.createElement(Tag, { style: isMultiline ? { whiteSpace: "pre-wrap" } : {}, ...props }, render(value));
553
+ }
554
+ return /* @__PURE__ */ React7.createElement(
555
+ Tag,
556
+ {
557
+ ...props,
558
+ ref: elementRef,
559
+ "data-uniform-component-id": componentData == null ? void 0 : componentData._id,
560
+ "data-uniform-parameter-id": parameterId,
561
+ "data-uniform-parameter-type": "text",
562
+ style: isMultiline ? { whiteSpace: "pre-wrap" } : {},
563
+ contentEditable: isEditable,
564
+ suppressContentEditableWarning: true,
565
+ onFocus: handleOnFocus,
566
+ onBlur: handleOnBlur
567
+ },
568
+ shouldSkipCustomRendering ? value : render(value)
569
+ );
570
+ };
571
+
493
572
  // src/hooks/useCompositionEventEffect.ts
494
573
  import {
495
574
  CANVAS_DRAFT_STATE,
@@ -530,18 +609,24 @@ function useCompositionEventEffect({
530
609
  }, [compositionId, enabled, projectId, effect]);
531
610
  }
532
611
  export {
612
+ Composition,
533
613
  DefaultNotImplementedComponent,
534
614
  NOT_IMPLEMENTED_COMPONENT,
615
+ Slot,
535
616
  UniformComponent,
536
617
  UniformComposition,
537
618
  UniformSlot,
619
+ UniformText,
538
620
  componentStore,
539
621
  componentStoreResolver,
622
+ createApiEnhancer,
540
623
  createComponentStore,
541
624
  createComponentStoreResolver,
542
625
  createUniformApiEnhancer,
543
626
  registerUniformComponent,
627
+ useComposition,
544
628
  useCompositionEventEffect,
629
+ useContextualEditing,
545
630
  useUniformContextualEditing,
546
631
  useUniformCurrentComponent,
547
632
  useUniformCurrentComposition
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniformdev/canvas-react",
3
- "version": "18.35.1-alpha.12+d5e86f567",
3
+ "version": "18.35.1-alpha.16+3d99d8fd6",
4
4
  "description": "React SDK for Uniform Canvas",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "main": "./dist/index.js",
@@ -24,9 +24,9 @@
24
24
  "document": "api-extractor run --local"
25
25
  },
26
26
  "dependencies": {
27
- "@uniformdev/canvas": "18.35.1-alpha.12+d5e86f567",
28
- "@uniformdev/context": "18.35.1-alpha.12+d5e86f567",
29
- "@uniformdev/context-react": "18.35.1-alpha.12+d5e86f567"
27
+ "@uniformdev/canvas": "18.35.1-alpha.16+3d99d8fd6",
28
+ "@uniformdev/context": "18.35.1-alpha.16+3d99d8fd6",
29
+ "@uniformdev/context-react": "18.35.1-alpha.16+3d99d8fd6"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": ">= 16 || 17 || 18",
@@ -43,5 +43,5 @@
43
43
  "publishConfig": {
44
44
  "access": "public"
45
45
  },
46
- "gitHead": "d5e86f5673575aecfcf517e684922871315f279b"
46
+ "gitHead": "3d99d8fd68048310f8f6dc56a1d18e61c35c9765"
47
47
  }