@akinon/pz-theme 2.0.35-beta.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.
- package/CHANGELOG.md +9 -3
- package/package.json +4 -3
- package/src/__tests__/theme-contract.test.ts +130 -0
- package/src/blocks/__tests__/text-block.test.tsx +8 -1
- package/src/blocks/__tests__/video-block.test.tsx +14 -7
- package/src/blocks/counter-block.tsx +44 -56
- package/src/blocks/group-block.tsx +23 -22
- package/src/blocks/hotspot-block.tsx +171 -80
- package/src/blocks/input-block.tsx +15 -17
- package/src/blocks/link-block.tsx +18 -21
- package/src/blocks/slider-block.tsx +15 -12
- package/src/components/with-designer-features.tsx +2 -0
- package/src/editor-bridge.ts +160 -0
- package/src/hooks/use-designer-features.tsx +30 -37
- package/src/placeholder-registry.ts +5 -7
- package/src/sections/__tests__/countdown-campaign-banner-section.test.tsx +8 -4
- package/src/sections/__tests__/coupon-banner-section.test.tsx +4 -2
- package/src/sections/before-after-section.tsx +189 -134
- package/src/sections/contact-form-section.tsx +185 -60
- package/src/sections/countdown-campaign-banner-section.tsx +73 -27
- package/src/sections/coupon-banner-section.tsx +152 -48
- package/src/sections/featured-product-spotlight-section.tsx +67 -66
- package/src/sections/find-in-store-section.tsx +37 -25
- package/src/sections/hover-showcase-section.tsx +221 -89
- package/src/sections/image-hotspot-section.tsx +208 -94
- package/src/sections/installment-options-section.tsx +268 -259
- package/src/sections/notification-banner-section.tsx +111 -25
- package/src/sections/order-tracking-lookup-section.tsx +272 -247
- package/src/sections/posts-slider-section.tsx +17 -16
- package/src/sections/pre-order-launch-banner-section.tsx +31 -50
- package/src/sections/section-wrapper.tsx +9 -10
- package/src/sections/shipping-threshold-progress-section.tsx +72 -29
- package/src/sections/stats-counter-section.tsx +68 -30
- package/src/sections/tabs-section.tsx +124 -147
- package/src/theme-placeholder-client.tsx +11 -14
- package/src/theme-placeholder-wrapper.tsx +42 -51
- package/src/theme-section.tsx +27 -34
- package/src/utils/__tests__/transform-styles.test.ts +97 -0
- 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(
|
|
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) =>
|
|
213
|
+
(block) =>
|
|
214
|
+
resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-label'
|
|
208
215
|
);
|
|
209
216
|
const couponCodeBoxBlock = foregroundBlocks.find(
|
|
210
|
-
(block) =>
|
|
217
|
+
(block) =>
|
|
218
|
+
resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-code-box'
|
|
211
219
|
);
|
|
212
220
|
const couponCodeTextBlock = foregroundBlocks.find(
|
|
213
|
-
(block) =>
|
|
221
|
+
(block) =>
|
|
222
|
+
resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-code-text'
|
|
214
223
|
);
|
|
215
224
|
const couponCopyButtonBlock = foregroundBlocks.find(
|
|
216
|
-
(block) =>
|
|
225
|
+
(block) =>
|
|
226
|
+
resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-copy-button'
|
|
217
227
|
);
|
|
218
228
|
const couponNoteBlock = foregroundBlocks.find(
|
|
219
|
-
(block) =>
|
|
229
|
+
(block) =>
|
|
230
|
+
resolveCouponBannerRole(block, currentBreakpoint) === 'coupon-note-text'
|
|
220
231
|
);
|
|
221
232
|
|
|
222
|
-
const firstButtonIndex = contentBlocks.findIndex(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
464
|
+
getResponsiveValue(
|
|
465
|
+
section.styles?.['copy-button-border-radius'],
|
|
466
|
+
currentBreakpoint,
|
|
467
|
+
'10px'
|
|
468
|
+
)
|
|
403
469
|
);
|
|
404
470
|
|
|
405
|
-
const postBlockAction = (
|
|
471
|
+
const postBlockAction = (
|
|
472
|
+
type: PreviewToEditorMessageType,
|
|
473
|
+
blockId: string,
|
|
474
|
+
label?: string
|
|
475
|
+
) => {
|
|
406
476
|
if (!window.parent) return;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
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={() =>
|
|
486
|
-
|
|
487
|
-
|
|
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(
|
|
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(
|
|
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={() =>
|
|
534
|
-
|
|
535
|
-
|
|
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(
|
|
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(
|
|
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">
|
|
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
|
|
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 || '')
|
|
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(
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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:
|
|
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(
|
|
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
|
|
283
|
+
((fallbackProductResponse?.product as
|
|
284
|
+
| Record<string, unknown>
|
|
285
|
+
| undefined) ??
|
|
272
286
|
undefined);
|
|
273
287
|
|
|
274
288
|
const activePrice =
|
|
275
|
-
(
|
|
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(
|
|
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
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
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(
|
|
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
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
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
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
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
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
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
|
>
|