@akinon/projectzero 2.0.0-beta.20 → 2.0.0-beta.21

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 (138) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/app-template/CHANGELOG.md +138 -0
  3. package/app-template/next.config.mjs +0 -1
  4. package/app-template/package.json +31 -30
  5. package/app-template/src/app/[pz]/[...prettyurl]/page.tsx +2 -2
  6. package/app-template/src/app/[pz]/account/layout.tsx +2 -1
  7. package/app-template/src/app/{[commerce]/[locale]/[currency] → [pz]}/blog/[slug]/page.tsx +4 -2
  8. package/app-template/src/app/[pz]/category/[pk]/page.tsx +11 -1
  9. package/app-template/src/app/[pz]/group-product/[pk]/page.tsx +2 -2
  10. package/app-template/src/app/[pz]/layout.tsx +3 -1
  11. package/app-template/src/app/[pz]/list/page.tsx +11 -1
  12. package/app-template/src/app/[pz]/page.tsx +13 -35
  13. package/app-template/src/app/[pz]/pages/[slug]/page.tsx +19 -0
  14. package/app-template/src/app/[pz]/product/[pk]/page.tsx +2 -2
  15. package/app-template/src/app/api/barcode-search/route.ts +1 -1
  16. package/app-template/src/app/api/cache/route.ts +1 -1
  17. package/app-template/src/app/api/image-proxy/route.ts +1 -1
  18. package/app-template/src/app/api/logout/route.ts +1 -1
  19. package/app-template/src/app/api/product-categories/route.ts +1 -1
  20. package/app-template/src/app/api/similar-product-list/route.ts +1 -1
  21. package/app-template/src/app/api/similar-products/route.ts +1 -1
  22. package/app-template/src/app/api/virtual-try-on/route.ts +1 -1
  23. package/app-template/src/app/api/web-vitals/route.ts +1 -1
  24. package/app-template/src/components/quantity-selector.tsx +16 -4
  25. package/app-template/src/components/widget-content.tsx +3 -3
  26. package/app-template/src/routes/index.ts +6 -6
  27. package/app-template/src/utils/__tests__/theme-page-context.test.ts +145 -0
  28. package/app-template/src/utils/theme-page-context.ts +309 -0
  29. package/app-template/src/views/basket/basket-item.tsx +107 -691
  30. package/app-template/src/views/basket/index.ts +0 -2
  31. package/app-template/src/views/basket/summary.tsx +75 -496
  32. package/app-template/src/views/breadcrumb.tsx +38 -13
  33. package/app-template/src/views/category/category-header.tsx +66 -289
  34. package/app-template/src/views/category/category-info.tsx +24 -173
  35. package/app-template/src/views/category/filters/index.tsx +48 -208
  36. package/app-template/src/views/category/layout.tsx +5 -7
  37. package/app-template/src/views/checkout/index.tsx +0 -5
  38. package/app-template/src/views/checkout/steps/payment/index.tsx +2 -5
  39. package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +1 -72
  40. package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +40 -171
  41. package/app-template/src/views/checkout/steps/shipping/address-box.tsx +12 -74
  42. package/app-template/src/views/checkout/steps/shipping/addresses.tsx +45 -128
  43. package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +27 -232
  44. package/app-template/src/views/checkout/summary.tsx +29 -303
  45. package/app-template/src/views/footer.tsx +13 -415
  46. package/app-template/src/views/guest-login/index.tsx +1 -1
  47. package/app-template/src/views/header/action-menu.tsx +45 -277
  48. package/app-template/src/views/header/band.tsx +21 -6
  49. package/app-template/src/views/header/index.tsx +47 -109
  50. package/app-template/src/views/header/mini-basket.tsx +45 -820
  51. package/app-template/src/views/header/navbar.tsx +111 -178
  52. package/app-template/src/views/header/search/index.tsx +32 -71
  53. package/app-template/src/views/header/search/results.tsx +65 -127
  54. package/app-template/src/views/product/accordion-wrapper.tsx +43 -135
  55. package/app-template/src/views/product/index.ts +1 -1
  56. package/app-template/src/views/product/layout.tsx +7 -2
  57. package/app-template/src/views/product/misc-buttons.tsx +25 -339
  58. package/app-template/src/views/product/product-actions.tsx +8 -137
  59. package/app-template/src/views/product/product-info.tsx +31 -69
  60. package/app-template/src/views/product/product-share.tsx +8 -11
  61. package/app-template/src/views/product/slider.tsx +79 -117
  62. package/app-template/src/views/product-item/index.tsx +46 -119
  63. package/app-template/src/widgets/footer-social.tsx +16 -47
  64. package/app-template/src/widgets/footer-subscription/index.tsx +17 -183
  65. package/dist/commands/plugins.js +23 -2
  66. package/package.json +1 -1
  67. package/app-template/src/app/[commerce]/[locale]/[currency]/pages/[slug]/page.tsx +0 -15
  68. package/app-template/src/views/basket/basket-summary-context.tsx +0 -560
  69. package/app-template/src/views/basket/designer-context.tsx +0 -617
  70. package/app-template/src/views/breadcrumb/breadcrumb-client.tsx +0 -190
  71. package/app-template/src/views/breadcrumb/breadcrumb-registrar.tsx +0 -286
  72. package/app-template/src/views/breadcrumb/constants.ts +0 -15
  73. package/app-template/src/views/breadcrumb/index.tsx +0 -127
  74. package/app-template/src/views/category/native-widget-context.tsx +0 -257
  75. package/app-template/src/views/category/product-list-registrar.tsx +0 -665
  76. package/app-template/src/views/checkout/checkout-address-registrar.tsx +0 -254
  77. package/app-template/src/views/checkout/checkout-buttons-registrar.tsx +0 -183
  78. package/app-template/src/views/checkout/checkout-delivery-method-registrar.tsx +0 -259
  79. package/app-template/src/views/checkout/checkout-payment-options-registrar.tsx +0 -253
  80. package/app-template/src/views/checkout/checkout-summary-registrar.tsx +0 -183
  81. package/app-template/src/views/checkout/constants.ts +0 -5
  82. package/app-template/src/views/checkout/steps/payment/options/masterpass-rest.tsx +0 -15
  83. package/app-template/src/views/checkout/steps/payment/options/saved-card.tsx +0 -18
  84. package/app-template/src/views/footer/footer-app-banner-context.tsx +0 -326
  85. package/app-template/src/views/footer/footer-bottom-context.tsx +0 -215
  86. package/app-template/src/views/footer/footer-bottom-wrapper.tsx +0 -74
  87. package/app-template/src/views/footer/footer-layout-constants.ts +0 -35
  88. package/app-template/src/views/footer/footer-layout-registrar.tsx +0 -342
  89. package/app-template/src/views/footer/footer-layout-switcher.tsx +0 -110
  90. package/app-template/src/views/footer/footer-menu-context.tsx +0 -211
  91. package/app-template/src/views/footer/footer-native-widgets.tsx +0 -60
  92. package/app-template/src/views/footer/footer-social-context.tsx +0 -254
  93. package/app-template/src/views/footer/footer-subscription-context.tsx +0 -210
  94. package/app-template/src/views/footer/footer-utils.ts +0 -43
  95. package/app-template/src/views/footer/footer-value-props-context.tsx +0 -326
  96. package/app-template/src/views/footer/logo-settings.ts +0 -183
  97. package/app-template/src/views/footer/native-widget-config.ts +0 -262
  98. package/app-template/src/views/footer/subscription-settings.ts +0 -122
  99. package/app-template/src/views/footer/use-footer-logo.ts +0 -162
  100. package/app-template/src/views/header/designer-context.tsx +0 -261
  101. package/app-template/src/views/header/header-announcement-registrar.tsx +0 -267
  102. package/app-template/src/views/header/header-client-wrapper.tsx +0 -496
  103. package/app-template/src/views/header/header-content.tsx +0 -1026
  104. package/app-template/src/views/header/header-currency-registrar.tsx +0 -348
  105. package/app-template/src/views/header/header-icons-context.tsx +0 -262
  106. package/app-template/src/views/header/header-language-registrar.tsx +0 -348
  107. package/app-template/src/views/header/header-layout-context.tsx +0 -143
  108. package/app-template/src/views/header/header-layout-registrar.tsx +0 -658
  109. package/app-template/src/views/header/header-logo-context.tsx +0 -228
  110. package/app-template/src/views/header/header-logo.tsx +0 -118
  111. package/app-template/src/views/header/header-mini-basket-context.tsx +0 -524
  112. package/app-template/src/views/header/header-search-registrar.tsx +0 -511
  113. package/app-template/src/views/header/header-text-slider-registrar.tsx +0 -382
  114. package/app-template/src/views/header/inline-search.tsx +0 -262
  115. package/app-template/src/views/header/navbar-menu-context.tsx +0 -219
  116. package/app-template/src/views/header/search/search-input.tsx +0 -61
  117. package/app-template/src/views/header/server-settings-parser.ts +0 -1105
  118. package/app-template/src/views/header/use-header-icons.ts +0 -241
  119. package/app-template/src/views/header/use-header-logo.ts +0 -213
  120. package/app-template/src/views/header/use-navbar-menu.ts +0 -179
  121. package/app-template/src/views/product/accordion-section.tsx +0 -61
  122. package/app-template/src/views/product/custom-button-group.tsx +0 -69
  123. package/app-template/src/views/product/favorites-button-section.tsx +0 -69
  124. package/app-template/src/views/product/find-in-store-section.tsx +0 -60
  125. package/app-template/src/views/product/product-info-section.tsx +0 -140
  126. package/app-template/src/views/product/quantity-section.tsx +0 -73
  127. package/app-template/src/views/product/sale-tag.tsx +0 -10
  128. package/app-template/src/views/product/share-section.tsx +0 -357
  129. package/app-template/src/views/product/variants-section.tsx +0 -126
  130. package/app-template/src/views/product-detail/constants.ts +0 -272
  131. package/app-template/src/views/product-detail/index.ts +0 -10
  132. package/app-template/src/views/product-detail/product-detail-registrar.tsx +0 -616
  133. package/app-template/src/widgets/footer-app-banner.tsx +0 -444
  134. package/app-template/src/widgets/footer-bottom.tsx +0 -127
  135. package/app-template/src/widgets/footer-menu-compact.tsx +0 -238
  136. package/app-template/src/widgets/footer-menu-two.tsx +0 -298
  137. package/app-template/src/widgets/footer-social-client.tsx +0 -251
  138. package/app-template/src/widgets/footer-value-props.tsx +0 -201
@@ -1,326 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- createContext,
5
- useCallback,
6
- useContext,
7
- useEffect,
8
- useMemo,
9
- useRef,
10
- useState,
11
- type PropsWithChildren
12
- } from 'react';
13
- import { useExternalDesigner } from '@akinon/next/components/theme-editor/hooks/use-external-designer';
14
- import { useNativeWidgetData } from '@akinon/next/components/theme-editor/hooks/use-native-widget-data';
15
-
16
- import {
17
- FOOTER_PLACEHOLDER_ID,
18
- FOOTER_VALUE_PROPS_SECTION_ID,
19
- FOOTER_VALUE_PROPS_WIDGET_SLUG,
20
- FOOTER_VALUE_PROPS_LIST_BLOCK_ID,
21
- type FooterNativeWidgetBlock
22
- } from './native-widget-config';
23
-
24
- export { FOOTER_VALUE_PROPS_LIST_BLOCK_ID };
25
-
26
- export interface ValuePropItem {
27
- icon: string;
28
- title: string;
29
- description?: string;
30
- }
31
-
32
- type FooterValuePropsBlockState = FooterNativeWidgetBlock;
33
-
34
- interface FooterValuePropsContextValue {
35
- isDesigner: boolean;
36
- selectedSectionId: string | null;
37
- selectedBlockId: string | null;
38
- getBlock: (blockId: string) => FooterValuePropsBlockState | undefined;
39
- getSectionProperty: (key: string) => unknown;
40
- getSectionStyle: (key: string) => unknown;
41
- blockVersion: number;
42
- }
43
-
44
- const FooterValuePropsContext = createContext<FooterValuePropsContextValue>({
45
- isDesigner: false,
46
- selectedSectionId: null,
47
- selectedBlockId: null,
48
- getBlock: () => undefined,
49
- getSectionProperty: () => undefined,
50
- getSectionStyle: () => undefined,
51
- blockVersion: 0
52
- });
53
-
54
- const BLOCK_META = [
55
- {
56
- id: FOOTER_VALUE_PROPS_LIST_BLOCK_ID,
57
- type: 'value-props-list',
58
- label: 'Value Props List'
59
- }
60
- ];
61
-
62
- const DEFAULT_VALUE_PROPS: ValuePropItem[] = [
63
- { icon: 'home', title: 'Free Shipping', description: 'On orders over $50' },
64
- {
65
- icon: 'add',
66
- title: 'Secure Payment',
67
- description: '256-bit SSL encryption'
68
- },
69
- { icon: 'search', title: 'Easy Returns', description: '30-day return policy' }
70
- ];
71
-
72
- const toBlockState = (
73
- block: Partial<FooterNativeWidgetBlock>,
74
- defaultItems?: ValuePropItem[]
75
- ): FooterValuePropsBlockState => {
76
- const fallback = BLOCK_META.find((meta) => meta.id === block.id);
77
-
78
- const defaultProperties =
79
- block.id === FOOTER_VALUE_PROPS_LIST_BLOCK_ID && defaultItems?.length
80
- ? { items: defaultItems }
81
- : undefined;
82
-
83
- return {
84
- id: block.id ?? fallback?.id ?? '',
85
- type: block.type ?? fallback?.type,
86
- label: block.label ?? fallback?.label,
87
- styles: block.styles,
88
- properties: block.properties || defaultProperties,
89
- value: block.value
90
- } as FooterValuePropsBlockState;
91
- };
92
-
93
- const mapFromSnapshot = (
94
- blocks?: FooterNativeWidgetBlock[],
95
- defaultItems?: ValuePropItem[]
96
- ): Map<string, FooterValuePropsBlockState> => {
97
- const map = new Map<string, FooterValuePropsBlockState>();
98
- blocks?.forEach((block) => {
99
- map.set(block.id, toBlockState(block, defaultItems));
100
- });
101
-
102
- BLOCK_META.forEach((meta) => {
103
- if (!map.has(meta.id)) {
104
- map.set(meta.id, toBlockState(meta, defaultItems));
105
- } else if (
106
- meta.id === FOOTER_VALUE_PROPS_LIST_BLOCK_ID &&
107
- defaultItems?.length
108
- ) {
109
- const existing = map.get(meta.id);
110
- const existingItems = (
111
- existing?.properties as { items?: ValuePropItem[] }
112
- )?.items;
113
- if (!existingItems || existingItems.length === 0) {
114
- map.set(
115
- meta.id,
116
- toBlockState({
117
- ...existing,
118
- properties: { ...existing?.properties, items: defaultItems }
119
- })
120
- );
121
- }
122
- }
123
- });
124
-
125
- return map;
126
- };
127
-
128
- interface FooterValuePropsProviderProps {
129
- initialBlocks?: FooterNativeWidgetBlock[];
130
- initialProperties?: Record<string, unknown>;
131
- initialStyles?: Record<string, unknown>;
132
- defaultItems?: ValuePropItem[];
133
- }
134
-
135
- export function FooterValuePropsProvider({
136
- initialBlocks,
137
- initialProperties,
138
- initialStyles,
139
- defaultItems = DEFAULT_VALUE_PROPS,
140
- children
141
- }: PropsWithChildren<FooterValuePropsProviderProps>) {
142
- const designerState = useExternalDesigner({
143
- placeholderId: FOOTER_PLACEHOLDER_ID
144
- });
145
-
146
- const [blockMap, setBlockMap] = useState(() =>
147
- mapFromSnapshot(initialBlocks, defaultItems)
148
- );
149
- const blockMapRef = useRef(blockMap);
150
- const [blockVersion, setBlockVersion] = useState(0);
151
- const [sectionProperties, setSectionProperties] = useState<
152
- Record<string, unknown>
153
- >(initialProperties || {});
154
- const [sectionStyles, setSectionStyles] = useState<Record<string, unknown>>(
155
- initialStyles || {}
156
- );
157
-
158
- const isDesignerRef = useRef(false);
159
- const [isDesignerChecked, setIsDesignerChecked] = useState(false);
160
-
161
- useEffect(() => {
162
- if (typeof window === 'undefined') return;
163
- isDesignerRef.current = window.self !== window.top;
164
- setIsDesignerChecked(true);
165
- }, []);
166
-
167
- const isDesigner = isDesignerRef.current;
168
-
169
- const widgetData = useNativeWidgetData({
170
- widgetSlug: FOOTER_VALUE_PROPS_WIDGET_SLUG,
171
- sectionId: FOOTER_VALUE_PROPS_SECTION_ID,
172
- skip: !isDesignerChecked || isDesigner,
173
- blockMeta: BLOCK_META
174
- });
175
-
176
- const mergeBlocks = useCallback(
177
- (blocks: Partial<FooterNativeWidgetBlock>[] | undefined) => {
178
- if (!blocks?.length) return;
179
-
180
- setBlockMap((prev) => {
181
- const next = new Map(prev);
182
- blocks.forEach((block) => {
183
- if (!block.id) return;
184
- const existing = next.get(block.id);
185
-
186
- next.set(
187
- block.id,
188
- toBlockState({
189
- ...existing,
190
- ...block,
191
- styles:
192
- block.styles && Object.keys(block.styles).length > 0
193
- ? block.styles
194
- : existing?.styles,
195
- properties:
196
- block.properties && Object.keys(block.properties).length > 0
197
- ? block.properties
198
- : existing?.properties,
199
- value: block.value !== undefined ? block.value : existing?.value
200
- })
201
- );
202
- });
203
- blockMapRef.current = next;
204
- return next;
205
- });
206
- setBlockVersion((prev) => prev + 1);
207
- },
208
- []
209
- );
210
-
211
- useEffect(() => {
212
- if (!isDesignerChecked || isDesigner || widgetData.isLoading) return;
213
-
214
- if (
215
- widgetData.sectionProperties &&
216
- Object.keys(widgetData.sectionProperties).length > 0
217
- ) {
218
- setSectionProperties(widgetData.sectionProperties);
219
- }
220
- if (
221
- widgetData.sectionStyles &&
222
- Object.keys(widgetData.sectionStyles).length > 0
223
- ) {
224
- setSectionStyles(widgetData.sectionStyles);
225
- }
226
-
227
- const blocksToMerge: Partial<FooterNativeWidgetBlock>[] = [];
228
- widgetData.blocks.forEach((block) => {
229
- blocksToMerge.push(block as FooterNativeWidgetBlock);
230
- });
231
-
232
- if (blocksToMerge.length > 0) {
233
- mergeBlocks(blocksToMerge);
234
- }
235
- }, [
236
- isDesigner,
237
- isDesignerChecked,
238
- widgetData.isLoading,
239
- widgetData.blocks,
240
- widgetData.sectionProperties,
241
- widgetData.sectionStyles,
242
- mergeBlocks
243
- ]);
244
-
245
- useEffect(() => {
246
- const handleMessage = (event: MessageEvent) => {
247
- const { type, data } = event.data || {};
248
-
249
- if (
250
- (type === 'UPDATE_THEME' || type === 'LOAD_THEME') &&
251
- data?.theme?.placeholders
252
- ) {
253
- const placeholder = data.theme.placeholders.find(
254
- (p: { slug: string }) => p.slug === FOOTER_PLACEHOLDER_ID
255
- );
256
-
257
- const section = placeholder?.sections?.find(
258
- (s: { id: string }) => s.id === FOOTER_VALUE_PROPS_SECTION_ID
259
- );
260
-
261
- if (section) {
262
- mergeBlocks(section.blocks);
263
-
264
- if (section.properties) {
265
- setSectionProperties(section.properties);
266
- }
267
-
268
- if (section.styles) {
269
- setSectionStyles(section.styles);
270
- }
271
- }
272
- }
273
- };
274
-
275
- window.addEventListener('message', handleMessage);
276
- return () => window.removeEventListener('message', handleMessage);
277
- }, [mergeBlocks]);
278
-
279
- const getBlock = useCallback(
280
- (blockId: string) => blockMapRef.current.get(blockId),
281
- []
282
- );
283
-
284
- const getSectionProperty = useCallback(
285
- (key: string) => {
286
- const value = sectionProperties[key];
287
- if (typeof value === 'object' && value !== null && 'desktop' in value) {
288
- return (value as Record<string, unknown>).desktop;
289
- }
290
- return value;
291
- },
292
- [sectionProperties]
293
- );
294
-
295
- const getSectionStyle = useCallback(
296
- (key: string) => {
297
- const value = sectionStyles[key];
298
- if (typeof value === 'object' && value !== null && 'desktop' in value) {
299
- return (value as Record<string, unknown>).desktop;
300
- }
301
- return value;
302
- },
303
- [sectionStyles]
304
- );
305
-
306
- const contextValue = useMemo(
307
- () => ({
308
- ...designerState,
309
- getBlock,
310
- getSectionProperty,
311
- getSectionStyle,
312
- blockVersion
313
- }),
314
- [designerState, getBlock, getSectionProperty, getSectionStyle, blockVersion]
315
- );
316
-
317
- return (
318
- <FooterValuePropsContext.Provider value={contextValue}>
319
- {children}
320
- </FooterValuePropsContext.Provider>
321
- );
322
- }
323
-
324
- export function useFooterValuePropsDesigner() {
325
- return useContext(FooterValuePropsContext);
326
- }
@@ -1,183 +0,0 @@
1
- import type {
2
- FooterNativeWidgetBlock,
3
- FooterNativeWidgetSection
4
- } from './native-widget-config';
5
- import {
6
- FOOTER_PLACEHOLDER_ID,
7
- FOOTER_MENU_SECTION_ID,
8
- FOOTER_MENU_LOGO_BLOCK_ID,
9
- FOOTER_MENU_WIDGET_SLUG
10
- } from './native-widget-config';
11
-
12
- export interface FooterLogoSettings {
13
- src: string;
14
- width: number | string;
15
- height: number | string;
16
- maxWidth?: string | number;
17
- maxHeight?: string | number;
18
- objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down' | string;
19
- }
20
-
21
- const DEFAULT_LOGO_SRC = '/logo.svg';
22
- const DEFAULT_LOGO_WIDTH = 80;
23
- const DEFAULT_LOGO_HEIGHT = 20;
24
-
25
- export const defaultFooterLogoSettings: FooterLogoSettings = {
26
- src: DEFAULT_LOGO_SRC,
27
- width: DEFAULT_LOGO_WIDTH,
28
- height: DEFAULT_LOGO_HEIGHT,
29
- objectFit: 'contain'
30
- };
31
-
32
- type BlockLike = Pick<FooterNativeWidgetBlock, 'styles' | 'value'> & {
33
- styles?: Record<string, unknown>;
34
- value?: unknown;
35
- };
36
-
37
- type ResponsiveValue<T = unknown> =
38
- | T
39
- | {
40
- desktop?: T;
41
- mobile?: T;
42
- tablet?: T;
43
- };
44
-
45
- const getResponsiveValue = <T = unknown>(value: ResponsiveValue<T>) => {
46
- if (value && typeof value === 'object' && 'desktop' in value) {
47
- return value.desktop as T;
48
- }
49
- return value as T;
50
- };
51
-
52
- const readStyleValue = (
53
- styles: Record<string, unknown> | undefined,
54
- keys: string[]
55
- ) => {
56
- if (!styles) return undefined;
57
- for (const key of keys) {
58
- if (key in styles) return styles[key];
59
- }
60
- return undefined;
61
- };
62
-
63
- export function parseFooterLogoBlockPayload(
64
- block?: BlockLike
65
- ): Partial<FooterLogoSettings> {
66
- if (!block) return {};
67
-
68
- const overrides: Partial<FooterLogoSettings> = {};
69
-
70
- if (block.value !== undefined && block.value !== null) {
71
- const value = getResponsiveValue(block.value as ResponsiveValue<string>);
72
- if (typeof value === 'string' && value.trim().length > 0) {
73
- overrides.src = value;
74
- }
75
- }
76
-
77
- const styles = block.styles as Record<string, unknown> | undefined;
78
- if (styles) {
79
- const width = readStyleValue(styles, ['width']);
80
- if (width !== undefined) {
81
- overrides.width = getResponsiveValue(
82
- width as ResponsiveValue<string | number>
83
- );
84
- }
85
-
86
- const height = readStyleValue(styles, ['height']);
87
- if (height !== undefined) {
88
- overrides.height = getResponsiveValue(
89
- height as ResponsiveValue<string | number>
90
- );
91
- }
92
-
93
- const maxWidth = readStyleValue(styles, ['maxWidth', 'max-width']);
94
- if (maxWidth !== undefined) {
95
- overrides.maxWidth = getResponsiveValue(
96
- maxWidth as ResponsiveValue<string | number>
97
- );
98
- }
99
-
100
- const maxHeight = readStyleValue(styles, ['maxHeight', 'max-height']);
101
- if (maxHeight !== undefined) {
102
- overrides.maxHeight = getResponsiveValue(
103
- maxHeight as ResponsiveValue<string | number>
104
- );
105
- }
106
-
107
- const objectFit = readStyleValue(styles, ['objectFit', 'object-fit']);
108
- if (objectFit !== undefined) {
109
- overrides.objectFit = getResponsiveValue(
110
- objectFit as ResponsiveValue<string>
111
- ) as FooterLogoSettings['objectFit'];
112
- }
113
- }
114
-
115
- return overrides;
116
- }
117
-
118
- export function parseFooterLogoWidgetAttribute(
119
- attrData: unknown
120
- ): Partial<FooterLogoSettings> {
121
- if (!attrData) return {};
122
-
123
- let parsed: unknown = attrData;
124
- if (typeof attrData === 'string') {
125
- try {
126
- parsed = JSON.parse(attrData);
127
- } catch {
128
- return {};
129
- }
130
- } else if (
131
- typeof attrData === 'object' &&
132
- attrData !== null &&
133
- 'value' in (attrData as Record<string, unknown>)
134
- ) {
135
- const value = (attrData as { value?: unknown }).value;
136
- if (typeof value === 'string') {
137
- try {
138
- parsed = JSON.parse(value);
139
- } catch {
140
- parsed = value;
141
- }
142
- } else {
143
- parsed = value;
144
- }
145
- }
146
-
147
- if (!parsed || typeof parsed !== 'object') {
148
- return {};
149
- }
150
-
151
- return parseFooterLogoBlockPayload(parsed as BlockLike);
152
- }
153
-
154
- export function getFooterLogoInitialSettingsFromSections(
155
- sections: FooterNativeWidgetSection[],
156
- fallbackSrc?: string
157
- ): FooterLogoSettings {
158
- const footerMenuSection = sections.find(
159
- (section) => section.sectionId === FOOTER_MENU_SECTION_ID
160
- );
161
- const logoBlock = footerMenuSection?.blocks.find(
162
- (block) => block.id === FOOTER_MENU_LOGO_BLOCK_ID
163
- );
164
-
165
- const overrides = parseFooterLogoBlockPayload(logoBlock);
166
- const base: FooterLogoSettings = {
167
- ...defaultFooterLogoSettings,
168
- src: fallbackSrc || defaultFooterLogoSettings.src
169
- };
170
-
171
- return {
172
- ...base,
173
- ...overrides,
174
- src: overrides.src ?? base.src
175
- };
176
- }
177
-
178
- export {
179
- FOOTER_PLACEHOLDER_ID as FOOTER_LOGO_PLACEHOLDER_ID,
180
- FOOTER_MENU_SECTION_ID as FOOTER_LOGO_SECTION_ID,
181
- FOOTER_MENU_LOGO_BLOCK_ID as FOOTER_LOGO_BLOCK_ID,
182
- FOOTER_MENU_WIDGET_SLUG as FOOTER_LOGO_WIDGET_SLUG
183
- };