@akinon/pz-theme 2.0.35-rc.0 → 2.0.35

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 (39) hide show
  1. package/CHANGELOG.md +12 -28
  2. package/package.json +4 -3
  3. package/src/__tests__/theme-contract.test.ts +130 -0
  4. package/src/blocks/__tests__/text-block.test.tsx +8 -1
  5. package/src/blocks/__tests__/video-block.test.tsx +14 -7
  6. package/src/blocks/counter-block.tsx +44 -56
  7. package/src/blocks/group-block.tsx +23 -22
  8. package/src/blocks/hotspot-block.tsx +171 -80
  9. package/src/blocks/input-block.tsx +15 -17
  10. package/src/blocks/link-block.tsx +18 -21
  11. package/src/blocks/slider-block.tsx +15 -12
  12. package/src/components/with-designer-features.tsx +2 -0
  13. package/src/editor-bridge.ts +160 -0
  14. package/src/hooks/use-designer-features.tsx +30 -37
  15. package/src/placeholder-registry.ts +5 -7
  16. package/src/sections/__tests__/countdown-campaign-banner-section.test.tsx +8 -4
  17. package/src/sections/__tests__/coupon-banner-section.test.tsx +4 -2
  18. package/src/sections/before-after-section.tsx +189 -134
  19. package/src/sections/contact-form-section.tsx +185 -60
  20. package/src/sections/countdown-campaign-banner-section.tsx +73 -27
  21. package/src/sections/coupon-banner-section.tsx +152 -48
  22. package/src/sections/featured-product-spotlight-section.tsx +67 -66
  23. package/src/sections/find-in-store-section.tsx +37 -25
  24. package/src/sections/hover-showcase-section.tsx +221 -89
  25. package/src/sections/image-hotspot-section.tsx +208 -94
  26. package/src/sections/installment-options-section.tsx +268 -259
  27. package/src/sections/notification-banner-section.tsx +111 -25
  28. package/src/sections/order-tracking-lookup-section.tsx +272 -247
  29. package/src/sections/posts-slider-section.tsx +17 -16
  30. package/src/sections/pre-order-launch-banner-section.tsx +31 -50
  31. package/src/sections/section-wrapper.tsx +9 -10
  32. package/src/sections/shipping-threshold-progress-section.tsx +72 -29
  33. package/src/sections/stats-counter-section.tsx +68 -30
  34. package/src/sections/tabs-section.tsx +124 -147
  35. package/src/theme-placeholder-client.tsx +11 -14
  36. package/src/theme-placeholder-wrapper.tsx +42 -51
  37. package/src/theme-section.tsx +27 -34
  38. package/src/utils/__tests__/transform-styles.test.ts +97 -0
  39. package/src/utils/index.ts +9 -0
@@ -15,6 +15,8 @@ import {
15
15
  } from '../utils';
16
16
  import { Section } from '../theme-section';
17
17
 
18
+ import { postToEditor } from '../editor-bridge';
19
+ import { PreviewToEditorMessageType } from '@akinon/theme-contract';
18
20
  interface CouponBannerSectionProps {
19
21
  section: Section;
20
22
  currentBreakpoint?: string;
@@ -98,7 +100,11 @@ const resolveCouponBannerRole = (
98
100
  block: Pick<Block, 'properties'>,
99
101
  breakpoint: string
100
102
  ): string => {
101
- const value = getResponsiveValue(block.properties?.couponBannerRole, breakpoint, '');
103
+ const value = getResponsiveValue(
104
+ block.properties?.couponBannerRole,
105
+ breakpoint,
106
+ ''
107
+ );
102
108
  return typeof value === 'string' ? value : '';
103
109
  };
104
110
 
@@ -204,22 +210,29 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
204
210
  (block) => !resolveCouponBannerRole(block, currentBreakpoint)
205
211
  );
206
212
  const couponLabelBlock = foregroundBlocks.find(
207
- (block) => resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-label'
213
+ (block) =>
214
+ resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-label'
208
215
  );
209
216
  const couponCodeBoxBlock = foregroundBlocks.find(
210
- (block) => resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-code-box'
217
+ (block) =>
218
+ resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-code-box'
211
219
  );
212
220
  const couponCodeTextBlock = foregroundBlocks.find(
213
- (block) => resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-code-text'
221
+ (block) =>
222
+ resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-code-text'
214
223
  );
215
224
  const couponCopyButtonBlock = foregroundBlocks.find(
216
- (block) => resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-copy-button'
225
+ (block) =>
226
+ resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-copy-button'
217
227
  );
218
228
  const couponNoteBlock = foregroundBlocks.find(
219
- (block) => resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-note-text'
229
+ (block) =>
230
+ resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-note-text'
220
231
  );
221
232
 
222
- const firstButtonIndex = contentBlocks.findIndex((block) => block.type === 'button');
233
+ const firstButtonIndex = contentBlocks.findIndex(
234
+ (block) => block.type === 'button'
235
+ );
223
236
 
224
237
  const leadingBlocks =
225
238
  firstButtonIndex >= 0
@@ -229,8 +242,11 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
229
242
  firstButtonIndex >= 0 ? contentBlocks.slice(firstButtonIndex) : [];
230
243
 
231
244
  const couponCode = String(
232
- getResponsiveValue(section.properties?.['coupon-code'], currentBreakpoint, 'SAVE20') ||
245
+ getResponsiveValue(
246
+ section.properties?.['coupon-code'],
247
+ currentBreakpoint,
233
248
  'SAVE20'
249
+ ) || 'SAVE20'
234
250
  ).trim();
235
251
  const couponNote = String(
236
252
  getResponsiveValue(
@@ -270,7 +286,10 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
270
286
 
271
287
  useEffect(() => {
272
288
  if (!isCopied) return;
273
- const timer = window.setTimeout(() => setIsCopied(false), copiedStateDuration);
289
+ const timer = window.setTimeout(
290
+ () => setIsCopied(false),
291
+ copiedStateDuration
292
+ );
274
293
  return () => window.clearTimeout(timer);
275
294
  }, [isCopied, copiedStateDuration]);
276
295
 
@@ -283,8 +302,8 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
283
302
  maxWidth === 'narrow'
284
303
  ? 'max-w-4xl'
285
304
  : maxWidth === 'none'
286
- ? ''
287
- : 'max-w-7xl';
305
+ ? ''
306
+ : 'max-w-7xl';
288
307
  const hasMaxWidth = maxWidth !== 'none';
289
308
  const rawSectionBorderRadius = getResponsiveValue(
290
309
  section.styles?.['border-radius'],
@@ -321,7 +340,11 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
321
340
  )
322
341
  );
323
342
 
324
- const sectionStyles = getCSSStyles(filteredStyles, themeSettings, currentBreakpoint);
343
+ const sectionStyles = getCSSStyles(
344
+ filteredStyles,
345
+ themeSettings,
346
+ currentBreakpoint
347
+ );
325
348
 
326
349
  const backgroundImageSrc = useMemo(() => {
327
350
  if (!backgroundBlock) return '';
@@ -333,14 +356,22 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
333
356
 
334
357
  const overlayColor = resolveThemeCssVariables(
335
358
  String(
336
- getResponsiveValue(section.styles?.['overlay-color'], currentBreakpoint, '#0f172a')
359
+ getResponsiveValue(
360
+ section.styles?.['overlay-color'],
361
+ currentBreakpoint,
362
+ '#0f172a'
363
+ )
337
364
  ),
338
365
  themeSettings
339
366
  );
340
367
  const overlayOpacity =
341
368
  clampNumber(
342
369
  parseNumber(
343
- getResponsiveValue(section.styles?.['overlay-opacity'], currentBreakpoint, 12),
370
+ getResponsiveValue(
371
+ section.styles?.['overlay-opacity'],
372
+ currentBreakpoint,
373
+ 12
374
+ ),
344
375
  12
345
376
  ),
346
377
  0,
@@ -349,27 +380,54 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
349
380
  const overlayBackground = applyAlphaToColor(overlayColor, overlayOpacity);
350
381
 
351
382
  const copyRowGap = clampNumber(
352
- parseNumber(getResponsiveValue(section.styles?.['copy-row-gap'], currentBreakpoint, 10), 10),
383
+ parseNumber(
384
+ getResponsiveValue(
385
+ section.styles?.['copy-row-gap'],
386
+ currentBreakpoint,
387
+ 10
388
+ ),
389
+ 10
390
+ ),
353
391
  0,
354
392
  32
355
393
  );
356
394
 
357
395
  const codeBackgroundColor = resolveThemeCssVariables(
358
396
  String(
359
- getResponsiveValue(section.styles?.['code-background-color'], currentBreakpoint, '#ffffff')
397
+ getResponsiveValue(
398
+ section.styles?.['code-background-color'],
399
+ currentBreakpoint,
400
+ '#ffffff'
401
+ )
360
402
  ),
361
403
  themeSettings
362
404
  );
363
405
  const codeTextColor = resolveThemeCssVariables(
364
- String(getResponsiveValue(section.styles?.['code-text-color'], currentBreakpoint, '#0f172a')),
406
+ String(
407
+ getResponsiveValue(
408
+ section.styles?.['code-text-color'],
409
+ currentBreakpoint,
410
+ '#0f172a'
411
+ )
412
+ ),
365
413
  themeSettings
366
414
  );
367
415
  const codeBorderColor = resolveThemeCssVariables(
368
- String(getResponsiveValue(section.styles?.['code-border-color'], currentBreakpoint, '#cbd5e1')),
416
+ String(
417
+ getResponsiveValue(
418
+ section.styles?.['code-border-color'],
419
+ currentBreakpoint,
420
+ '#cbd5e1'
421
+ )
422
+ ),
369
423
  themeSettings
370
424
  );
371
425
  const codeBorderRadius = String(
372
- getResponsiveValue(section.styles?.['code-border-radius'], currentBreakpoint, '10px')
426
+ getResponsiveValue(
427
+ section.styles?.['code-border-radius'],
428
+ currentBreakpoint,
429
+ '10px'
430
+ )
373
431
  );
374
432
 
375
433
  const copyButtonBackgroundColor = resolveThemeCssVariables(
@@ -384,7 +442,11 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
384
442
  );
385
443
  const copyButtonTextColor = resolveThemeCssVariables(
386
444
  String(
387
- getResponsiveValue(section.styles?.['copy-button-text-color'], currentBreakpoint, '#ffffff')
445
+ getResponsiveValue(
446
+ section.styles?.['copy-button-text-color'],
447
+ currentBreakpoint,
448
+ '#ffffff'
449
+ )
388
450
  ),
389
451
  themeSettings
390
452
  );
@@ -399,23 +461,28 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
399
461
  themeSettings
400
462
  );
401
463
  const copyButtonBorderRadius = String(
402
- getResponsiveValue(section.styles?.['copy-button-border-radius'], currentBreakpoint, '10px')
464
+ getResponsiveValue(
465
+ section.styles?.['copy-button-border-radius'],
466
+ currentBreakpoint,
467
+ '10px'
468
+ )
403
469
  );
404
470
 
405
- const postBlockAction = (type: string, blockId: string, label?: string) => {
471
+ const postBlockAction = (
472
+ type: PreviewToEditorMessageType,
473
+ blockId: string,
474
+ label?: string
475
+ ) => {
406
476
  if (!window.parent) return;
407
- window.parent.postMessage(
408
- {
409
- type,
410
- data: {
411
- placeholderId,
412
- sectionId: section.id,
413
- blockId,
414
- ...(label ? { label } : {})
415
- }
416
- },
417
- '*'
418
- );
477
+ postToEditor({
478
+ type,
479
+ data: {
480
+ placeholderId,
481
+ sectionId: section.id,
482
+ blockId,
483
+ ...(label ? { label } : {})
484
+ }
485
+ });
419
486
  };
420
487
 
421
488
  const renderBlock = (block: Block, keyOverride?: React.Key) => {
@@ -482,15 +549,30 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
482
549
  ...(options.style || {}),
483
550
  ...getCSSStyles(block.styles || {}, themeSettings, currentBreakpoint)
484
551
  }}
485
- onMoveUp={() => postBlockAction('MOVE_BLOCK_UP', block.styleSourceId || block.id)}
486
- onMoveDown={() => postBlockAction('MOVE_BLOCK_DOWN', block.styleSourceId || block.id)}
487
- onDuplicate={() => postBlockAction('DUPLICATE_BLOCK', block.styleSourceId || block.id)}
552
+ onMoveUp={() =>
553
+ postBlockAction('MOVE_BLOCK_UP', block.styleSourceId || block.id)
554
+ }
555
+ onMoveDown={() =>
556
+ postBlockAction('MOVE_BLOCK_DOWN', block.styleSourceId || block.id)
557
+ }
558
+ onDuplicate={() =>
559
+ postBlockAction('DUPLICATE_BLOCK', block.styleSourceId || block.id)
560
+ }
488
561
  onToggleVisibility={() =>
489
- postBlockAction('TOGGLE_BLOCK_VISIBILITY', block.styleSourceId || block.id)
562
+ postBlockAction(
563
+ 'TOGGLE_BLOCK_VISIBILITY',
564
+ block.styleSourceId || block.id
565
+ )
566
+ }
567
+ onDelete={() =>
568
+ postBlockAction('DELETE_BLOCK', block.styleSourceId || block.id)
490
569
  }
491
- onDelete={() => postBlockAction('DELETE_BLOCK', block.styleSourceId || block.id)}
492
570
  onRename={(newLabel) =>
493
- postBlockAction('RENAME_BLOCK', block.styleSourceId || block.id, newLabel)
571
+ postBlockAction(
572
+ 'RENAME_BLOCK',
573
+ block.styleSourceId || block.id,
574
+ newLabel
575
+ )
494
576
  }
495
577
  >
496
578
  {children}
@@ -530,15 +612,30 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
530
612
  currentBreakpoint={currentBreakpoint}
531
613
  className={options.wrapperClassName}
532
614
  style={options.wrapperStyle}
533
- onMoveUp={() => postBlockAction('MOVE_BLOCK_UP', block.styleSourceId || block.id)}
534
- onMoveDown={() => postBlockAction('MOVE_BLOCK_DOWN', block.styleSourceId || block.id)}
535
- onDuplicate={() => postBlockAction('DUPLICATE_BLOCK', block.styleSourceId || block.id)}
615
+ onMoveUp={() =>
616
+ postBlockAction('MOVE_BLOCK_UP', block.styleSourceId || block.id)
617
+ }
618
+ onMoveDown={() =>
619
+ postBlockAction('MOVE_BLOCK_DOWN', block.styleSourceId || block.id)
620
+ }
621
+ onDuplicate={() =>
622
+ postBlockAction('DUPLICATE_BLOCK', block.styleSourceId || block.id)
623
+ }
536
624
  onToggleVisibility={() =>
537
- postBlockAction('TOGGLE_BLOCK_VISIBILITY', block.styleSourceId || block.id)
625
+ postBlockAction(
626
+ 'TOGGLE_BLOCK_VISIBILITY',
627
+ block.styleSourceId || block.id
628
+ )
629
+ }
630
+ onDelete={() =>
631
+ postBlockAction('DELETE_BLOCK', block.styleSourceId || block.id)
538
632
  }
539
- onDelete={() => postBlockAction('DELETE_BLOCK', block.styleSourceId || block.id)}
540
633
  onRename={(newLabel) =>
541
- postBlockAction('RENAME_BLOCK', block.styleSourceId || block.id, newLabel)
634
+ postBlockAction(
635
+ 'RENAME_BLOCK',
636
+ block.styleSourceId || block.id,
637
+ newLabel
638
+ )
542
639
  }
543
640
  >
544
641
  {children}
@@ -601,7 +698,9 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
601
698
  }}
602
699
  >
603
700
  {hasBackgroundImage ? (
604
- <div className="absolute inset-0 z-0">{renderBlock(backgroundBlock)}</div>
701
+ <div className="absolute inset-0 z-0">
702
+ {renderBlock(backgroundBlock)}
703
+ </div>
605
704
  ) : (
606
705
  <div
607
706
  className="absolute inset-0 z-0"
@@ -622,7 +721,12 @@ const CouponBannerSection: React.FC<CouponBannerSectionProps> = ({
622
721
  isMobileLayout ? 'flex-col' : 'items-end justify-between'
623
722
  )}
624
723
  >
625
- <div className={clsx('flex min-w-0 flex-col gap-4', !isMobileLayout && 'max-w-3xl')}>
724
+ <div
725
+ className={clsx(
726
+ 'flex min-w-0 flex-col gap-4',
727
+ !isMobileLayout && 'max-w-3xl'
728
+ )}
729
+ >
626
730
  {leadingBlocks.map(renderBlock)}
627
731
  {trailingBlocks.map(renderBlock)}
628
732
  </div>
@@ -9,6 +9,7 @@ import { Section } from '../theme-section';
9
9
  import { safeDeepClone } from '../utils/safe-clone';
10
10
  import { getCSSStyles, getResponsiveValue } from '../utils';
11
11
 
12
+ import { postToEditor } from '../editor-bridge';
12
13
  interface FeaturedProductSpotlightSectionProps {
13
14
  section: Section;
14
15
  currentBreakpoint?: string;
@@ -106,7 +107,9 @@ const parsePositiveInt = (value: unknown): number | null => {
106
107
  };
107
108
 
108
109
  const normalizeCurrencyLabel = (currency: unknown): string => {
109
- const raw = String(currency || '').trim().toUpperCase();
110
+ const raw = String(currency || '')
111
+ .trim()
112
+ .toUpperCase();
110
113
  if (!raw) return 'TL';
111
114
 
112
115
  const map: Record<string, string> = {
@@ -192,7 +195,9 @@ const getDiscountBadgeText = (
192
195
  return null;
193
196
  }
194
197
 
195
- const percentage = Math.round(((retailPrice - currentPrice) / retailPrice) * 100);
198
+ const percentage = Math.round(
199
+ ((retailPrice - currentPrice) / retailPrice) * 100
200
+ );
196
201
  if (percentage <= 0) return null;
197
202
  return `Save ${percentage}%`;
198
203
  };
@@ -215,10 +220,10 @@ export default function FeaturedProductSpotlightSection({
215
220
  maxWidth === 'narrow'
216
221
  ? 'max-w-4xl'
217
222
  : maxWidth === 'normal'
218
- ? 'max-w-7xl'
219
- : maxWidth === 'full'
220
- ? 'w-full'
221
- : '';
223
+ ? 'max-w-7xl'
224
+ : maxWidth === 'full'
225
+ ? 'w-full'
226
+ : '';
222
227
  const hasMaxWidth = maxWidth !== 'none' && maxWidth !== 'full';
223
228
 
224
229
  const filteredStyles = Object.fromEntries(
@@ -242,7 +247,10 @@ export default function FeaturedProductSpotlightSection({
242
247
 
243
248
  return {
244
249
  ...baseStyles,
245
- flexDirection: currentBreakpoint === 'mobile' ? 'column-reverse' as const : 'row-reverse' as const
250
+ flexDirection:
251
+ currentBreakpoint === 'mobile'
252
+ ? ('column-reverse' as const)
253
+ : ('row-reverse' as const)
246
254
  };
247
255
  }, [
248
256
  currentBreakpoint,
@@ -256,7 +264,11 @@ export default function FeaturedProductSpotlightSection({
256
264
  [section, isDesigner]
257
265
  );
258
266
  const fallbackProductPk = parsePositiveInt(
259
- getResponsiveValue(section.properties?.['product-pk'], currentBreakpoint, '')
267
+ getResponsiveValue(
268
+ section.properties?.['product-pk'],
269
+ currentBreakpoint,
270
+ ''
271
+ )
260
272
  );
261
273
  // currentData (not data): data is sticky across args, so a cleared
262
274
  // product-pk would keep rendering the previously fetched product.
@@ -268,11 +280,13 @@ export default function FeaturedProductSpotlightSection({
268
280
  );
269
281
  const product =
270
282
  products[0] ||
271
- ((fallbackProductResponse?.product as Record<string, unknown> | undefined) ??
283
+ ((fallbackProductResponse?.product as
284
+ | Record<string, unknown>
285
+ | undefined) ??
272
286
  undefined);
273
287
 
274
288
  const activePrice =
275
- ((product?.active_price as Record<string, unknown> | undefined) || {});
289
+ (product?.active_price as Record<string, unknown> | undefined) || {};
276
290
  const currentPriceRaw = activePrice?.price ?? product?.price;
277
291
  const retailPriceRaw = activePrice?.retail_price ?? product?.retail_price;
278
292
  const currency =
@@ -290,7 +304,11 @@ export default function FeaturedProductSpotlightSection({
290
304
  retailPrice > currentPrice;
291
305
 
292
306
  const showBadge = parseBoolean(
293
- getResponsiveValue(section.properties?.['show-badge'], currentBreakpoint, true),
307
+ getResponsiveValue(
308
+ section.properties?.['show-badge'],
309
+ currentBreakpoint,
310
+ true
311
+ ),
294
312
  true
295
313
  );
296
314
  const showOldPrice = parseBoolean(
@@ -334,10 +352,10 @@ export default function FeaturedProductSpotlightSection({
334
352
 
335
353
  const nextBlock: Block = {
336
354
  ...block,
337
- properties: block.properties ? { ...block.properties } : block.properties,
338
- styles: block.styles
339
- ? safeDeepClone(block.styles)
340
- : block.styles,
355
+ properties: block.properties
356
+ ? { ...block.properties }
357
+ : block.properties,
358
+ styles: block.styles ? safeDeepClone(block.styles) : block.styles,
341
359
  blocks: undefined
342
360
  };
343
361
 
@@ -377,7 +395,10 @@ export default function FeaturedProductSpotlightSection({
377
395
  nextBlock.type === 'image' &&
378
396
  normalizedLabel.includes('thumbnail')
379
397
  ) {
380
- const fallbackImage = resolvePath(product, 'productimage_set[0].image');
398
+ const fallbackImage = resolvePath(
399
+ product,
400
+ 'productimage_set[0].image'
401
+ );
381
402
  if (fallbackImage !== undefined) {
382
403
  nextBlock.value = fallbackImage;
383
404
  }
@@ -421,73 +442,55 @@ export default function FeaturedProductSpotlightSection({
421
442
  currentBreakpoint={currentBreakpoint}
422
443
  onMoveUp={() => {
423
444
  if (window.parent) {
424
- window.parent.postMessage(
425
- {
426
- type: 'MOVE_BLOCK_UP',
427
- data: { placeholderId, sectionId: section.id, blockId: block.id }
428
- },
429
- '*'
430
- );
445
+ postToEditor({
446
+ type: 'MOVE_BLOCK_UP',
447
+ data: { placeholderId, sectionId: section.id, blockId: block.id }
448
+ });
431
449
  }
432
450
  }}
433
451
  onMoveDown={() => {
434
452
  if (window.parent) {
435
- window.parent.postMessage(
436
- {
437
- type: 'MOVE_BLOCK_DOWN',
438
- data: { placeholderId, sectionId: section.id, blockId: block.id }
439
- },
440
- '*'
441
- );
453
+ postToEditor({
454
+ type: 'MOVE_BLOCK_DOWN',
455
+ data: { placeholderId, sectionId: section.id, blockId: block.id }
456
+ });
442
457
  }
443
458
  }}
444
459
  onDuplicate={() => {
445
460
  if (window.parent) {
446
- window.parent.postMessage(
447
- {
448
- type: 'DUPLICATE_BLOCK',
449
- data: { placeholderId, sectionId: section.id, blockId: block.id }
450
- },
451
- '*'
452
- );
461
+ postToEditor({
462
+ type: 'DUPLICATE_BLOCK',
463
+ data: { placeholderId, sectionId: section.id, blockId: block.id }
464
+ });
453
465
  }
454
466
  }}
455
467
  onToggleVisibility={() => {
456
468
  if (window.parent) {
457
- window.parent.postMessage(
458
- {
459
- type: 'TOGGLE_BLOCK_VISIBILITY',
460
- data: { placeholderId, sectionId: section.id, blockId: block.id }
461
- },
462
- '*'
463
- );
469
+ postToEditor({
470
+ type: 'TOGGLE_BLOCK_VISIBILITY',
471
+ data: { placeholderId, sectionId: section.id, blockId: block.id }
472
+ });
464
473
  }
465
474
  }}
466
475
  onDelete={() => {
467
476
  if (window.parent) {
468
- window.parent.postMessage(
469
- {
470
- type: 'DELETE_BLOCK',
471
- data: { placeholderId, sectionId: section.id, blockId: block.id }
472
- },
473
- '*'
474
- );
477
+ postToEditor({
478
+ type: 'DELETE_BLOCK',
479
+ data: { placeholderId, sectionId: section.id, blockId: block.id }
480
+ });
475
481
  }
476
482
  }}
477
483
  onRename={(newLabel) => {
478
484
  if (window.parent) {
479
- window.parent.postMessage(
480
- {
481
- type: 'RENAME_BLOCK',
482
- data: {
483
- placeholderId,
484
- sectionId: section.id,
485
- blockId: block.id,
486
- label: newLabel
487
- }
488
- },
489
- '*'
490
- );
485
+ postToEditor({
486
+ type: 'RENAME_BLOCK',
487
+ data: {
488
+ placeholderId,
489
+ sectionId: section.id,
490
+ blockId: block.id,
491
+ label: newLabel
492
+ }
493
+ });
491
494
  }
492
495
  }}
493
496
  />
@@ -496,9 +499,7 @@ export default function FeaturedProductSpotlightSection({
496
499
  return (
497
500
  <div
498
501
  className={
499
- hasMaxWidth
500
- ? `mx-auto ${maxWidthClass}`
501
- : maxWidthClass || undefined
502
+ hasMaxWidth ? `mx-auto ${maxWidthClass}` : maxWidthClass || undefined
502
503
  }
503
504
  style={sectionStyles}
504
505
  >