@akinon/pz-theme 2.0.143-rc.0 → 2.0.143
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 +8 -35
- package/package.json +4 -4
- package/src/__tests__/designer-live-rows.test.tsx +257 -0
- package/src/blocks/__tests__/favorite-button-icons.test.tsx +102 -0
- package/src/blocks/__tests__/listing-price-note.test.ts +47 -0
- package/src/blocks/favorite-button-block.tsx +36 -15
- package/src/blocks/group-block.tsx +52 -1
- package/src/blocks/image-block.tsx +26 -2
- package/src/blocks/listing-context.ts +5 -2
- package/src/blocks/listing-row.ts +64 -4
- package/src/blocks/product-grid-block.tsx +83 -3
- package/src/components/card-list-slider.tsx +374 -0
- package/src/components/card-list-views.tsx +278 -0
- package/src/components/card-zoom.tsx +53 -0
- package/src/components/with-designer-features.tsx +18 -0
- package/src/theme-block.tsx +11 -0
- package/src/theme-placeholder-wrapper.tsx +52 -7
- package/src/utils/__tests__/card-media.test.tsx +789 -0
- package/src/utils/__tests__/card-views.test.tsx +332 -0
- package/src/utils/__tests__/swatch-colors.test.ts +145 -0
- package/src/utils/card-media.ts +331 -0
- package/src/utils/iterator-utils.ts +10 -3
- package/src/utils/live-rows.ts +169 -34
- package/src/utils/property-switches.ts +248 -2
- package/src/utils/swatch-colors.ts +81 -0
|
@@ -15,6 +15,10 @@ import {
|
|
|
15
15
|
HOVER_SCOPE_ATTRIBUTE,
|
|
16
16
|
REVEAL_ON_HOVER_ATTRIBUTE
|
|
17
17
|
} from '../utils/property-switches';
|
|
18
|
+
import {
|
|
19
|
+
HIDE_IN_CARD_VIEW_ATTRIBUTE,
|
|
20
|
+
HIDE_IN_CARD_VIEW_PROPERTY
|
|
21
|
+
} from '../utils/card-media';
|
|
18
22
|
|
|
19
23
|
/** Elements that already act on Enter/Space themselves. */
|
|
20
24
|
export const NATIVE_KEYBOARD_CONTROLS =
|
|
@@ -159,6 +163,17 @@ export function WithDesignerFeatures({
|
|
|
159
163
|
|
|
160
164
|
// In designer mode, keep hidden blocks mounted (prevents remount-driven side effects)
|
|
161
165
|
// but visually hide them.
|
|
166
|
+
// A part of a card that one of the listing's grid views leaves out — the
|
|
167
|
+
// Product Card's caption in the picture-only archive (utils/card-media).
|
|
168
|
+
// On the wrapper, which carries the part's box, so nothing of it remains.
|
|
169
|
+
const hideInCardViewRaw = getResponsiveValue(
|
|
170
|
+
block.properties?.[HIDE_IN_CARD_VIEW_PROPERTY],
|
|
171
|
+
currentBreakpoint,
|
|
172
|
+
''
|
|
173
|
+
);
|
|
174
|
+
const hideInCardView =
|
|
175
|
+
typeof hideInCardViewRaw === 'string' ? hideInCardViewRaw.trim() : '';
|
|
176
|
+
|
|
162
177
|
const mergedStyle: React.CSSProperties = {
|
|
163
178
|
...(style || {}),
|
|
164
179
|
...(isDesigner && block.hidden ? { display: 'none' } : null),
|
|
@@ -173,6 +188,9 @@ export function WithDesignerFeatures({
|
|
|
173
188
|
data-block-id={block.styleSourceId || block.id}
|
|
174
189
|
{...(block.hoverScope ? { [HOVER_SCOPE_ATTRIBUTE]: '' } : null)}
|
|
175
190
|
{...(block.revealOnHover ? { [REVEAL_ON_HOVER_ATTRIBUTE]: '' } : null)}
|
|
191
|
+
{...(hideInCardView
|
|
192
|
+
? { [HIDE_IN_CARD_VIEW_ATTRIBUTE]: hideInCardView }
|
|
193
|
+
: null)}
|
|
176
194
|
className={clsx(
|
|
177
195
|
'relative',
|
|
178
196
|
className,
|
package/src/theme-block.tsx
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
isPublishWindowVisible
|
|
15
15
|
} from './utils';
|
|
16
16
|
import { devWarn } from './utils/dev-warn';
|
|
17
|
+
import type { CardsSliderSettings, CardViewSettings } from './utils/card-media';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Narrows what a designer typed into something usable as a document-wide id.
|
|
@@ -70,6 +71,16 @@ export interface Block {
|
|
|
70
71
|
*/
|
|
71
72
|
revealOnHover?: boolean;
|
|
72
73
|
hoverScope?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Written by the same pass, never authored (utils/card-media.ts): the card's
|
|
76
|
+
* picture zooms in on hover, and this repeat lays the cards it holds out as
|
|
77
|
+
* a slider. Absent on every block no setting reaches, which is every block
|
|
78
|
+
* of an unconfigured list.
|
|
79
|
+
*/
|
|
80
|
+
cardZoom?: boolean;
|
|
81
|
+
cardsSlider?: CardsSliderSettings;
|
|
82
|
+
/** The listing's grid view this repeat is drawn in, and its toggles when offered. */
|
|
83
|
+
cardsViews?: CardViewSettings;
|
|
73
84
|
/**
|
|
74
85
|
* Properties this clone resolved for itself from its row. One generated rule
|
|
75
86
|
* serves every clone, so these are the values that have to be inlined on the
|
|
@@ -36,7 +36,9 @@ import {
|
|
|
36
36
|
import { isPublishWindowVisible } from './utils/publish-window';
|
|
37
37
|
import {
|
|
38
38
|
collectionBindingKey,
|
|
39
|
+
collectionPreviewWidget,
|
|
39
40
|
fetchDesignerLiveRows,
|
|
41
|
+
fetchDesignerPreviewRows,
|
|
40
42
|
hangDesignerDataSource,
|
|
41
43
|
liveRowsEntryKey,
|
|
42
44
|
LiveRowsStore,
|
|
@@ -799,7 +801,8 @@ export default function ThemePlaceholderWrapper({
|
|
|
799
801
|
dataSource: hangDesignerDataSource(
|
|
800
802
|
section,
|
|
801
803
|
dataSource || section.dataSource,
|
|
802
|
-
liveRowsRef.current
|
|
804
|
+
liveRowsRef.current,
|
|
805
|
+
{ previous: section.dataSource }
|
|
803
806
|
)
|
|
804
807
|
};
|
|
805
808
|
}
|
|
@@ -814,11 +817,45 @@ export default function ThemePlaceholderWrapper({
|
|
|
814
817
|
// preview (whose blob path writes no live rows), or the server could not
|
|
815
818
|
// resolve them — asks the storefront for them once. Until they arrive the
|
|
816
819
|
// picked snapshot stays on the canvas: it is the same collection.
|
|
820
|
+
//
|
|
821
|
+
// An unsaved pick asks for its binding's preview widget instead, once per
|
|
822
|
+
// binding, when the editor prepared one: those are the rows the section
|
|
823
|
+
// will show once published, where the snapshot is Omnitron's catalogue.
|
|
817
824
|
useEffect(() => {
|
|
818
825
|
if (!isDesigner) return;
|
|
819
826
|
|
|
820
827
|
sections.forEach((section) => {
|
|
821
|
-
if (
|
|
828
|
+
if (!section.id) return;
|
|
829
|
+
|
|
830
|
+
if (section.dataSourceSaved !== true) {
|
|
831
|
+
// The editor's record, not the one the section is drawn with: while
|
|
832
|
+
// its preview rows are asked for, the section keeps the source it
|
|
833
|
+
// showed before (see hangDesignerDataSource).
|
|
834
|
+
const record =
|
|
835
|
+
dataSources?.find(
|
|
836
|
+
(ds: { id?: string }) => ds.id === section.dataSourceId
|
|
837
|
+
) ?? section.dataSource;
|
|
838
|
+
const previewWidget = collectionPreviewWidget(record);
|
|
839
|
+
if (
|
|
840
|
+
!previewWidget ||
|
|
841
|
+
liveRowsRef.current.has(previewWidget) ||
|
|
842
|
+
liveRowsAttemptedRef.current.has(previewWidget)
|
|
843
|
+
) {
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
liveRowsAttemptedRef.current.add(previewWidget);
|
|
848
|
+
|
|
849
|
+
fetchDesignerPreviewRows(previewWidget).then((answer) => {
|
|
850
|
+
if (!liveRowsMountedRef.current) return;
|
|
851
|
+
|
|
852
|
+
// Held as `null` when it gave nothing: the section stops holding
|
|
853
|
+
// its previous rows and falls back to the snapshot.
|
|
854
|
+
liveRowsRef.current.set(previewWidget, answer);
|
|
855
|
+
setLiveRowsRevision((revision) => revision + 1);
|
|
856
|
+
});
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
822
859
|
|
|
823
860
|
const bindingKey = collectionBindingKey(section.dataSource);
|
|
824
861
|
if (!bindingKey) return;
|
|
@@ -844,8 +881,9 @@ export default function ThemePlaceholderWrapper({
|
|
|
844
881
|
});
|
|
845
882
|
});
|
|
846
883
|
// `sections` already follows `dataSources`: every change to the records is
|
|
847
|
-
// hung over the sections before this runs
|
|
848
|
-
|
|
884
|
+
// hung over the sections before this runs — except a record held back
|
|
885
|
+
// while its preview rows are asked for, which is read from `dataSources`.
|
|
886
|
+
}, [sections, dataSources, isDesigner]);
|
|
849
887
|
|
|
850
888
|
useEffect(() => {
|
|
851
889
|
if (typeof window === 'undefined') {
|
|
@@ -940,7 +978,7 @@ export default function ThemePlaceholderWrapper({
|
|
|
940
978
|
|
|
941
979
|
// In editor mode: Complete override with theme editor's data
|
|
942
980
|
// This allows unsaved sections to render with editor's product data
|
|
943
|
-
setSections(() => {
|
|
981
|
+
setSections((previousSections) => {
|
|
944
982
|
return placeholder.sections.map((incomingSection: any) => {
|
|
945
983
|
let dataSource = null;
|
|
946
984
|
if (incomingSection.dataSourceId && theme.dataSources) {
|
|
@@ -963,11 +1001,18 @@ export default function ThemePlaceholderWrapper({
|
|
|
963
1001
|
? { ...incomingSection.properties }
|
|
964
1002
|
: {},
|
|
965
1003
|
// Live rows only for a pick the editor reports as
|
|
966
|
-
// saved; otherwise the
|
|
1004
|
+
// saved; otherwise the preview widget's rows or the
|
|
1005
|
+
// picked snapshot — and what the section showed so
|
|
1006
|
+
// far while the preview widget is asked.
|
|
967
1007
|
dataSource: hangDesignerDataSource(
|
|
968
1008
|
incomingSection,
|
|
969
1009
|
dataSource || null,
|
|
970
|
-
liveRowsRef.current
|
|
1010
|
+
liveRowsRef.current,
|
|
1011
|
+
{
|
|
1012
|
+
previous: previousSections.find(
|
|
1013
|
+
(section) => section.id === incomingSection.id
|
|
1014
|
+
)?.dataSource
|
|
1015
|
+
}
|
|
971
1016
|
)
|
|
972
1017
|
};
|
|
973
1018
|
});
|