@shoppexio/builder-runtime 0.1.1 → 0.1.2
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 +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/layout.d.ts +3 -8
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +2 -10
- package/dist/preview-fixtures.d.ts +16 -0
- package/dist/preview-fixtures.d.ts.map +1 -0
- package/dist/preview-fixtures.js +40 -0
- package/dist/product-page.d.ts +13 -0
- package/dist/product-page.d.ts.map +1 -0
- package/dist/product-page.js +18 -0
- package/dist/react.d.ts +31 -2
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +122 -42
- package/dist/search-bar-settings.d.ts +33 -0
- package/dist/search-bar-settings.d.ts.map +1 -0
- package/dist/search-bar-settings.js +99 -0
- package/dist/standard-product-blocks.d.ts +48 -0
- package/dist/standard-product-blocks.d.ts.map +1 -0
- package/dist/standard-product-blocks.js +45 -0
- package/dist/standard-product-page.d.ts +69 -0
- package/dist/standard-product-page.d.ts.map +1 -0
- package/dist/standard-product-page.js +89 -0
- package/dist/storefront-google-fonts.d.ts +2 -0
- package/dist/storefront-google-fonts.d.ts.map +1 -0
- package/dist/storefront-google-fonts.js +28 -0
- package/package.json +3 -3
- package/src/builder-runtime.test.ts +33 -0
- package/src/index.ts +4 -0
- package/src/layout.ts +11 -21
- package/src/preview-fixtures.ts +56 -0
- package/src/product-page.test.ts +37 -0
- package/src/product-page.ts +32 -0
- package/src/react-runtime.test.tsx +42 -0
- package/src/react.tsx +214 -45
- package/src/search-bar-settings.test.ts +72 -0
- package/src/search-bar-settings.ts +176 -0
- package/src/standard-product-blocks.test.tsx +93 -0
- package/src/standard-product-blocks.tsx +121 -0
- package/src/standard-product-page.test.ts +171 -0
- package/src/standard-product-page.ts +169 -0
- package/src/storefront-google-fonts.test.ts +31 -0
- package/src/storefront-google-fonts.ts +43 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
export * from './preview-fixtures.js';
|
|
2
|
+
export * from './product-page.js';
|
|
3
|
+
export * from './standard-product-page.js';
|
|
1
4
|
export * from './attributes.js';
|
|
2
5
|
export * from './content.js';
|
|
3
6
|
export * from './css-vars.js';
|
|
4
7
|
export * from './layout.js';
|
|
5
8
|
export * from './react.js';
|
|
9
|
+
export * from './storefront-google-fonts.js';
|
|
6
10
|
export * from './style-slots.js';
|
|
7
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
export * from './preview-fixtures.js';
|
|
2
|
+
export * from './product-page.js';
|
|
3
|
+
export * from './standard-product-page.js';
|
|
1
4
|
export * from './attributes.js';
|
|
2
5
|
export * from './content.js';
|
|
3
6
|
export * from './css-vars.js';
|
|
4
7
|
export * from './layout.js';
|
|
5
8
|
export * from './react.js';
|
|
9
|
+
export * from './storefront-google-fonts.js';
|
|
6
10
|
export * from './style-slots.js';
|
package/dist/layout.d.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { getThemePageBlockOrderFromManifest as resolveThemePageBlockOrder, type BlockInstance, type BuilderSettings, type PageLayout, type ThemeManifest, type ThemePageBlockOrderPage } from '@shoppex/builder-contracts';
|
|
2
2
|
export type ThemePageBlockOrderManifest = {
|
|
3
|
-
pages?: Record<string,
|
|
4
|
-
allowedBlocks?: string[];
|
|
5
|
-
defaultBlocks?: Array<{
|
|
6
|
-
type?: string;
|
|
7
|
-
}>;
|
|
8
|
-
}>;
|
|
3
|
+
pages?: Record<string, ThemePageBlockOrderPage>;
|
|
9
4
|
};
|
|
5
|
+
export { resolveThemePageBlockOrder as getThemePageBlockOrderFromManifest };
|
|
10
6
|
export declare function getPageLayout(settings: BuilderSettings, pageId: string): PageLayout;
|
|
11
7
|
export declare function getPageBlocks(settings: BuilderSettings, pageId: string): BlockInstance[];
|
|
12
8
|
export declare function getVisiblePageBlocks(settings: BuilderSettings, pageId: string): BlockInstance[];
|
|
13
9
|
export declare function getBlockById(settings: BuilderSettings, pageId: string, blockId: string): BlockInstance | null;
|
|
14
10
|
export declare function getAllowedBlockTypes(manifest: ThemeManifest, pageId: string): string[];
|
|
15
|
-
export declare function getThemePageBlockOrderFromManifest(manifest: ThemePageBlockOrderManifest, pageId: string): string[];
|
|
16
11
|
export declare function canAddBlock(settings: BuilderSettings, manifest: ThemeManifest, pageId: string, blockType: string): boolean;
|
|
17
12
|
export declare function resolveBlockSettings(block: BlockInstance, manifest: ThemeManifest): Record<string, unknown>;
|
|
18
13
|
//# sourceMappingURL=layout.d.ts.map
|
package/dist/layout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,IAAI,0BAA0B,EAChE,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC7B,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;CACjD,CAAC;AAEF,OAAO,EAAE,0BAA0B,IAAI,kCAAkC,EAAE,CAAC;AAE5E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAEnF;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAExF;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAE/F;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAE7G;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEtF;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAc1H;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgB3G"}
|
package/dist/layout.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getThemePageBlockOrderFromManifest as resolveThemePageBlockOrder, } from '@shoppex/builder-contracts';
|
|
2
|
+
export { resolveThemePageBlockOrder as getThemePageBlockOrderFromManifest };
|
|
1
3
|
export function getPageLayout(settings, pageId) {
|
|
2
4
|
return settings.theme.layout[pageId] ?? { blocks: [] };
|
|
3
5
|
}
|
|
@@ -13,16 +15,6 @@ export function getBlockById(settings, pageId, blockId) {
|
|
|
13
15
|
export function getAllowedBlockTypes(manifest, pageId) {
|
|
14
16
|
return manifest.pages[pageId]?.allowedBlocks ?? [];
|
|
15
17
|
}
|
|
16
|
-
export function getThemePageBlockOrderFromManifest(manifest, pageId) {
|
|
17
|
-
const page = manifest.pages?.[pageId];
|
|
18
|
-
if (!page) {
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
const defaultBlockTypes = (page.defaultBlocks ?? [])
|
|
22
|
-
.map((block) => block.type)
|
|
23
|
-
.filter((blockType) => typeof blockType === 'string' && blockType.length > 0);
|
|
24
|
-
return defaultBlockTypes.length > 0 ? defaultBlockTypes : page.allowedBlocks ?? [];
|
|
25
|
-
}
|
|
26
18
|
export function canAddBlock(settings, manifest, pageId, blockType) {
|
|
27
19
|
const page = manifest.pages[pageId];
|
|
28
20
|
const blockDefinition = manifest.blocks[blockType];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type BuilderPreviewReview = {
|
|
2
|
+
id: string;
|
|
3
|
+
author: string | null;
|
|
4
|
+
comment: string | null;
|
|
5
|
+
rating: number | null;
|
|
6
|
+
created_at: string;
|
|
7
|
+
is_automated?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type BuilderPreviewFaqItem = {
|
|
10
|
+
question: string;
|
|
11
|
+
answer: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const BUILDER_PREVIEW_REVIEWS: BuilderPreviewReview[];
|
|
14
|
+
export declare function getBuilderPreviewReviewFixtures<T = BuilderPreviewReview>(): T[];
|
|
15
|
+
export declare const BUILDER_PREVIEW_FAQ_ITEMS: BuilderPreviewFaqItem[];
|
|
16
|
+
//# sourceMappingURL=preview-fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-fixtures.d.ts","sourceRoot":"","sources":["../src/preview-fixtures.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,oBAAoB,EAsBzD,CAAC;AAEF,wBAAgB,+BAA+B,CAAC,CAAC,GAAG,oBAAoB,KAAK,CAAC,EAAE,CAE/E;AAED,eAAO,MAAM,yBAAyB,EAAE,qBAAqB,EAa5D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const BUILDER_PREVIEW_REVIEWS = [
|
|
2
|
+
{
|
|
3
|
+
id: 'preview-review-1',
|
|
4
|
+
author: 'Alex M.',
|
|
5
|
+
comment: 'Instant delivery and clear instructions. Would buy again.',
|
|
6
|
+
rating: 5,
|
|
7
|
+
created_at: '2026-04-12T10:00:00.000Z',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: 'preview-review-2',
|
|
11
|
+
author: 'Jamie R.',
|
|
12
|
+
comment: 'Support answered quickly when I had a setup question.',
|
|
13
|
+
rating: 5,
|
|
14
|
+
created_at: '2026-04-03T14:30:00.000Z',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: 'preview-review-3',
|
|
18
|
+
author: 'Taylor S.',
|
|
19
|
+
comment: 'Smooth checkout experience and exactly what was advertised.',
|
|
20
|
+
rating: 4,
|
|
21
|
+
created_at: '2026-03-22T09:15:00.000Z',
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
export function getBuilderPreviewReviewFixtures() {
|
|
25
|
+
return BUILDER_PREVIEW_REVIEWS;
|
|
26
|
+
}
|
|
27
|
+
export const BUILDER_PREVIEW_FAQ_ITEMS = [
|
|
28
|
+
{
|
|
29
|
+
question: 'How fast is delivery?',
|
|
30
|
+
answer: 'Most digital products are delivered instantly after payment confirmation.',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
question: 'Which payment methods do you accept?',
|
|
34
|
+
answer: 'Available payment methods depend on your shop configuration and region.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
question: 'How do I get support?',
|
|
38
|
+
answer: 'Use the contact page or your customer portal for order-related help.',
|
|
39
|
+
},
|
|
40
|
+
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BlockInstance } from '@shoppex/builder-contracts';
|
|
2
|
+
export declare function getBuilderBlockSettingText(block: Pick<BlockInstance, 'settings'>, key: string): string | null;
|
|
3
|
+
export declare function getLayoutPageBlockAttributes(pageId: string, block: Pick<BlockInstance, 'id' | 'type'>): {
|
|
4
|
+
'data-page-id': string;
|
|
5
|
+
};
|
|
6
|
+
export declare function getProductPageBlockAttributes(block: Pick<BlockInstance, 'id' | 'type'>): {
|
|
7
|
+
'data-page-id': string;
|
|
8
|
+
};
|
|
9
|
+
/** @deprecated Use getBuilderBlockSettingText */
|
|
10
|
+
export declare const getProductBlockText: typeof getBuilderBlockSettingText;
|
|
11
|
+
/** @deprecated Use getProductPageBlockAttributes */
|
|
12
|
+
export declare const getBuilderProductBlockAttributes: typeof getProductPageBlockAttributes;
|
|
13
|
+
//# sourceMappingURL=product-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-page.d.ts","sourceRoot":"","sources":["../src/product-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,EACtC,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,MAAM,CAAC;;EAM1C;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,MAAM,CAAC;;EAG1C;AAED,iDAAiD;AACjD,eAAO,MAAM,mBAAmB,mCAA6B,CAAC;AAE9D,oDAAoD;AACpD,eAAO,MAAM,gCAAgC,sCAAgC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { builderBlock } from './attributes.js';
|
|
2
|
+
export function getBuilderBlockSettingText(block, key) {
|
|
3
|
+
const value = block.settings[key];
|
|
4
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;
|
|
5
|
+
}
|
|
6
|
+
export function getLayoutPageBlockAttributes(pageId, block) {
|
|
7
|
+
return {
|
|
8
|
+
'data-page-id': pageId,
|
|
9
|
+
...builderBlock(block.id, block.type),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function getProductPageBlockAttributes(block) {
|
|
13
|
+
return getLayoutPageBlockAttributes('product', block);
|
|
14
|
+
}
|
|
15
|
+
/** @deprecated Use getBuilderBlockSettingText */
|
|
16
|
+
export const getProductBlockText = getBuilderBlockSettingText;
|
|
17
|
+
/** @deprecated Use getProductPageBlockAttributes */
|
|
18
|
+
export const getBuilderProductBlockAttributes = getProductPageBlockAttributes;
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BlockInstance, BuilderSettings, Breakpoint, StyleSlotId } from '@shoppex/builder-contracts';
|
|
2
|
-
import { type ComponentType, type ElementType, type ReactNode } from 'react';
|
|
2
|
+
import { type ComponentPropsWithoutRef, type ComponentType, type ElementType, type ReactNode } from 'react';
|
|
3
|
+
import { type BuilderAttributeMap } from './attributes.js';
|
|
3
4
|
type BuilderRuntimeContextValue = {
|
|
4
5
|
settings: BuilderSettings;
|
|
5
6
|
};
|
|
@@ -75,11 +76,39 @@ export declare function useVisibleBuilderPageBlocks(pageId: string): {
|
|
|
75
76
|
style_overrides?: Partial<Record<StyleSlotId, import("@shoppex/builder-contracts").StyleSlotValue>> | undefined;
|
|
76
77
|
}[];
|
|
77
78
|
export declare function useThemePageBlocks(pageId: string, defaultOrder: string[]): BlockInstance[];
|
|
79
|
+
export declare function useThemePageBlockAttributes(pageId: string, defaultOrder: string[]): BuilderAttributeMap;
|
|
80
|
+
type DedicatedBuilderPageProps<T extends ElementType> = {
|
|
81
|
+
pageId: string;
|
|
82
|
+
defaultBlockOrder: string[];
|
|
83
|
+
as?: T;
|
|
84
|
+
children: ReactNode;
|
|
85
|
+
} & Omit<ComponentPropsWithoutRef<T>, 'as' | 'children'>;
|
|
86
|
+
export declare function DedicatedBuilderPage<T extends ElementType = 'section'>({ pageId, defaultBlockOrder, as, children, ...rest }: DedicatedBuilderPageProps<T>): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
87
|
+
export declare function useBuilderPreviewReviews<T>(input: {
|
|
88
|
+
reviews: T[];
|
|
89
|
+
isLoading: boolean;
|
|
90
|
+
error: unknown;
|
|
91
|
+
fixtures?: T[];
|
|
92
|
+
}): {
|
|
93
|
+
reviews: T[];
|
|
94
|
+
isLoading: boolean;
|
|
95
|
+
error: unknown;
|
|
96
|
+
isUsingFixtures: boolean;
|
|
97
|
+
};
|
|
78
98
|
export declare function useBuilderStyleSlot(slotId: StyleSlotId, input?: {
|
|
79
99
|
breakpoint?: Breakpoint;
|
|
80
100
|
fallback?: unknown;
|
|
81
101
|
}): unknown;
|
|
82
102
|
export declare function useBuilderCss(selector?: string): string;
|
|
103
|
+
export declare function useSearchBarSettings(input: {
|
|
104
|
+
variant: 'hero' | 'navigation';
|
|
105
|
+
headerSettings?: Record<string, unknown>;
|
|
106
|
+
}): import("./search-bar-settings.js").ResolvedSearchBarSettings;
|
|
107
|
+
export { buildSearchShellStyle, getNavigationHeaderSettings, resolveSearchBarSettings, } from './search-bar-settings.js';
|
|
108
|
+
export declare function isBuilderPreviewRuntime(): boolean;
|
|
83
109
|
export declare function resolvePreviewReloadTarget(location: Pick<Location, 'search' | 'hash'>, sessionPath: unknown): string | null;
|
|
84
|
-
export {};
|
|
110
|
+
export { getBuilderBlockSettingText, getBuilderProductBlockAttributes, getLayoutPageBlockAttributes, getProductBlockText, getProductPageBlockAttributes, } from './product-page.js';
|
|
111
|
+
export { createStandardProductBlockRegistry, splitStandardProductPageBlocks, buildStandardProductInfoTabs, resolveStandardBuyBoxLabels, resolveStandardDetailsLabels, resolveStandardRelatedProductsTitle, resolveScopedBlockSettingText, STANDARD_PRODUCT_BLOCK_TYPES, STANDARD_PRODUCT_PRIMARY_BLOCK_TYPES, STANDARD_PRODUCT_SECONDARY_BLOCK_TYPES, } from './standard-product-blocks.js';
|
|
112
|
+
export type { StandardBuyBoxLabels, StandardDetailsLabels, StandardProductBlockRegistryData, StandardProductBlockRegistryOptions, StandardProductBlockRegistrySlots, StandardProductBlockType, StandardProductSettingScope, StandardProductTabSpec, } from './standard-product-blocks.js';
|
|
113
|
+
export { getBuilderPreviewReviewFixtures } from './preview-fixtures.js';
|
|
85
114
|
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAoB,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
|
package/dist/react.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { BuilderSettingsSchema, PreviewMessageSchema, createEmptyBuilderSettings, migrateLegacyBuilderSettings, } from '@shoppex/builder-contracts';
|
|
2
|
+
import { BuilderSettingsSchema, PreviewMessageSchema, createEmptyBuilderSettings, isTrustedPreviewParentOrigin, migrateLegacyBuilderSettings, normalizeDedicatedPageId, } from '@shoppex/builder-contracts';
|
|
3
3
|
import { createElement, createContext, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
4
4
|
import { getBlockSettingValue, getBuilderContentList, getBuilderContentRecord, getBuilderContentString, getBuilderContentValue, } from './content.js';
|
|
5
|
+
import { BUILDER_PREVIEW_REVIEWS } from './preview-fixtures.js';
|
|
5
6
|
import { createBuilderCss } from './css-vars.js';
|
|
7
|
+
import { builderBlock } from './attributes.js';
|
|
6
8
|
import { getPageBlocks, getPageLayout, getVisiblePageBlocks } from './layout.js';
|
|
9
|
+
import { getNavigationHeaderSettings, resolveSearchBarSettings, } from './search-bar-settings.js';
|
|
7
10
|
import { resolveStyleSlotValue } from './style-slots.js';
|
|
8
11
|
const BUILDER_SETTINGS_WINDOW_KEY = '__SHOPPEX_BUILDER_SETTINGS__';
|
|
9
12
|
const BUILDER_STATE_EVENT_NAME = 'shoppex:builder-state';
|
|
@@ -155,6 +158,7 @@ export function BuilderRuntimePreviewProvider({ initialSettings, children, }) {
|
|
|
155
158
|
message: normalized.message,
|
|
156
159
|
...(normalized.stack ? { stack: normalized.stack } : {}),
|
|
157
160
|
source,
|
|
161
|
+
phase: 'runtime',
|
|
158
162
|
diagnostics: {
|
|
159
163
|
name: normalized.name,
|
|
160
164
|
href: window.location.href,
|
|
@@ -295,13 +299,48 @@ export function useVisibleBuilderPageBlocks(pageId) {
|
|
|
295
299
|
}
|
|
296
300
|
export function useThemePageBlocks(pageId, defaultOrder) {
|
|
297
301
|
const { settings } = useBuilderRuntime();
|
|
302
|
+
const canonicalPageId = normalizeDedicatedPageId(pageId);
|
|
298
303
|
return useMemo(() => {
|
|
299
|
-
const page = settings.theme.layout[
|
|
304
|
+
const page = settings.theme.layout[canonicalPageId];
|
|
300
305
|
if (page) {
|
|
301
306
|
return page.blocks.filter((block) => block.visible);
|
|
302
307
|
}
|
|
303
308
|
return defaultOrder.map((type) => ({ id: type, type, visible: true, settings: {} }));
|
|
304
|
-
}, [
|
|
309
|
+
}, [canonicalPageId, defaultOrder, settings.theme.layout]);
|
|
310
|
+
}
|
|
311
|
+
export function useThemePageBlockAttributes(pageId, defaultOrder) {
|
|
312
|
+
const canonicalPageId = normalizeDedicatedPageId(pageId);
|
|
313
|
+
const blocks = useThemePageBlocks(pageId, defaultOrder);
|
|
314
|
+
const block = blocks[0];
|
|
315
|
+
return useMemo(() => ({
|
|
316
|
+
'data-page-id': canonicalPageId,
|
|
317
|
+
...(block ? builderBlock(block.id, block.type) : {}),
|
|
318
|
+
}), [block, canonicalPageId]);
|
|
319
|
+
}
|
|
320
|
+
export function DedicatedBuilderPage({ pageId, defaultBlockOrder, as, children, ...rest }) {
|
|
321
|
+
const attrs = useThemePageBlockAttributes(pageId, defaultBlockOrder);
|
|
322
|
+
const Component = (as ?? 'section');
|
|
323
|
+
return createElement(Component, { ...attrs, ...rest }, children);
|
|
324
|
+
}
|
|
325
|
+
export function useBuilderPreviewReviews(input) {
|
|
326
|
+
const fixtures = input.fixtures ?? BUILDER_PREVIEW_REVIEWS;
|
|
327
|
+
const shouldUseFixtures = isBuilderPreviewRuntime() && Boolean(input.error);
|
|
328
|
+
return useMemo(() => {
|
|
329
|
+
if (!shouldUseFixtures) {
|
|
330
|
+
return {
|
|
331
|
+
reviews: input.reviews,
|
|
332
|
+
isLoading: input.isLoading,
|
|
333
|
+
error: input.error,
|
|
334
|
+
isUsingFixtures: false,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
reviews: fixtures,
|
|
339
|
+
isLoading: false,
|
|
340
|
+
error: null,
|
|
341
|
+
isUsingFixtures: true,
|
|
342
|
+
};
|
|
343
|
+
}, [fixtures, input.error, input.isLoading, input.reviews, shouldUseFixtures]);
|
|
305
344
|
}
|
|
306
345
|
export function useBuilderStyleSlot(slotId, input = {}) {
|
|
307
346
|
return resolveStyleSlotValue(useBuilderRuntime().settings, slotId, input);
|
|
@@ -333,7 +372,42 @@ function getNestedBuilderSetting(record, path) {
|
|
|
333
372
|
}
|
|
334
373
|
return current;
|
|
335
374
|
}
|
|
336
|
-
function
|
|
375
|
+
export function useSearchBarSettings(input) {
|
|
376
|
+
const runtime = useBuilderRuntime();
|
|
377
|
+
const headerSettings = useMemo(() => input.headerSettings ?? getNavigationHeaderSettings(runtime.settings), [input.headerSettings, runtime.settings]);
|
|
378
|
+
const heroPlaceholder = useBuilderContentValue('hero.search.placeholder');
|
|
379
|
+
const heroBackground = useBuilderContentValue('hero.search.background');
|
|
380
|
+
const heroBorderColor = useBuilderContentValue('hero.search.borderColor');
|
|
381
|
+
const heroBorderRadius = useBuilderContentValue('hero.search.borderRadius');
|
|
382
|
+
const heroMaxWidth = useBuilderContentValue('hero.search.maxWidth');
|
|
383
|
+
const heroShowShortcut = useBuilderContentValue('hero.search.showShortcut');
|
|
384
|
+
const heroShow = useBuilderContentValue('hero.search.show');
|
|
385
|
+
return useMemo(() => resolveSearchBarSettings({
|
|
386
|
+
variant: input.variant,
|
|
387
|
+
headerSettings,
|
|
388
|
+
heroValues: {
|
|
389
|
+
'hero.search.placeholder': heroPlaceholder,
|
|
390
|
+
'hero.search.background': heroBackground,
|
|
391
|
+
'hero.search.borderColor': heroBorderColor,
|
|
392
|
+
'hero.search.borderRadius': heroBorderRadius,
|
|
393
|
+
'hero.search.maxWidth': heroMaxWidth,
|
|
394
|
+
'hero.search.showShortcut': heroShowShortcut,
|
|
395
|
+
'hero.search.show': heroShow,
|
|
396
|
+
},
|
|
397
|
+
}), [
|
|
398
|
+
headerSettings,
|
|
399
|
+
heroBackground,
|
|
400
|
+
heroBorderColor,
|
|
401
|
+
heroBorderRadius,
|
|
402
|
+
heroMaxWidth,
|
|
403
|
+
heroPlaceholder,
|
|
404
|
+
heroShow,
|
|
405
|
+
heroShowShortcut,
|
|
406
|
+
input.variant,
|
|
407
|
+
]);
|
|
408
|
+
}
|
|
409
|
+
export { buildSearchShellStyle, getNavigationHeaderSettings, resolveSearchBarSettings, } from './search-bar-settings.js';
|
|
410
|
+
export function isBuilderPreviewRuntime() {
|
|
337
411
|
if (typeof window === 'undefined') {
|
|
338
412
|
return false;
|
|
339
413
|
}
|
|
@@ -423,7 +497,7 @@ function isTrustedBuilderPreviewEmbed(location, parentOrigin) {
|
|
|
423
497
|
return false;
|
|
424
498
|
if (!hasBuilderPreviewMode(location))
|
|
425
499
|
return false;
|
|
426
|
-
return
|
|
500
|
+
return isTrustedPreviewParentOrigin(parentOrigin);
|
|
427
501
|
}
|
|
428
502
|
function hasBuilderPreviewMode(location) {
|
|
429
503
|
const searchParams = new URLSearchParams(location.search);
|
|
@@ -431,23 +505,6 @@ function hasBuilderPreviewMode(location) {
|
|
|
431
505
|
|| searchParams.get('shoppex-preview-mode') === 'builder'
|
|
432
506
|
|| searchParams.get('shoppex-preview') === 'builder');
|
|
433
507
|
}
|
|
434
|
-
function isTrustedBuilderPreviewParentOrigin(origin) {
|
|
435
|
-
try {
|
|
436
|
-
const parsed = new URL(origin);
|
|
437
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
438
|
-
return (hostname === 'dashboard.shoppex.io'
|
|
439
|
-
|| hostname === 'dashboard.shoppex.test'
|
|
440
|
-
|| hostname === 'localhost'
|
|
441
|
-
|| hostname === '127.0.0.1'
|
|
442
|
-
|| hostname === '::1'
|
|
443
|
-
|| hostname.endsWith('.localhost')
|
|
444
|
-
|| hostname.endsWith('.vercel.app')
|
|
445
|
-
|| hostname.endsWith('.vercel.run'));
|
|
446
|
-
}
|
|
447
|
-
catch {
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
508
|
function selectBuilderElement(blockId) {
|
|
452
509
|
document
|
|
453
510
|
.querySelectorAll(BUILDER_SELECTED_SELECTOR)
|
|
@@ -458,7 +515,9 @@ function selectBuilderElement(blockId) {
|
|
|
458
515
|
if (!target)
|
|
459
516
|
return;
|
|
460
517
|
target.setAttribute('data-builder-selected', 'true');
|
|
461
|
-
target.
|
|
518
|
+
const pageId = target.getAttribute('data-page-id');
|
|
519
|
+
const scrollBlock = pageId === 'footer' ? 'end' : pageId === 'navigation' ? 'start' : 'nearest';
|
|
520
|
+
target.scrollIntoView({ behavior: 'smooth', block: scrollBlock });
|
|
462
521
|
}
|
|
463
522
|
function createBuilderSelection(blockElement, target) {
|
|
464
523
|
const contentElement = target.closest(BUILDER_CONTENT_SELECTOR);
|
|
@@ -641,7 +700,8 @@ function installBuilderPreviewHoverInspector() {
|
|
|
641
700
|
window.removeEventListener('mouseout', handleMouseOut, true);
|
|
642
701
|
};
|
|
643
702
|
}
|
|
644
|
-
const INSERTER_HOVER_BAND_PX =
|
|
703
|
+
const INSERTER_HOVER_BAND_PX = 28;
|
|
704
|
+
const INSERTER_CLEAR_DELAY_MS = 150;
|
|
645
705
|
/**
|
|
646
706
|
* Direct-manipulation bridge: tracks the bounding rect of the selected
|
|
647
707
|
* block (for the floating toolbar), the inter-block gap currently
|
|
@@ -731,26 +791,43 @@ function installBuilderDirectManipulation(postMessage, getRevision) {
|
|
|
731
791
|
// a tracked block stack. We don't try to be clever about which gap;
|
|
732
792
|
// every direct ancestor with a list of `[data-builder-block]` children
|
|
733
793
|
// contributes one gap per pair.
|
|
794
|
+
let inserterClearTimer = null;
|
|
734
795
|
const postInserter = (index, rect) => {
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
796
|
+
const emitInserter = () => {
|
|
797
|
+
const key = index === null || !rect
|
|
798
|
+
? '__none__'
|
|
799
|
+
: `${index}|${rect.top}|${rect.left}|${rect.width}|${rect.height}`;
|
|
800
|
+
if (key === lastInserterKey)
|
|
801
|
+
return;
|
|
802
|
+
lastInserterKey = key;
|
|
803
|
+
postMessage({
|
|
804
|
+
type: 'INSERTER_HOVER',
|
|
805
|
+
revision: getRevision(),
|
|
806
|
+
index,
|
|
807
|
+
rect: rect === null
|
|
808
|
+
? null
|
|
809
|
+
: {
|
|
810
|
+
top: rect.top,
|
|
811
|
+
left: rect.left,
|
|
812
|
+
width: rect.width,
|
|
813
|
+
height: rect.height,
|
|
814
|
+
},
|
|
815
|
+
});
|
|
816
|
+
};
|
|
817
|
+
if (index !== null && rect !== null) {
|
|
818
|
+
if (inserterClearTimer !== null) {
|
|
819
|
+
window.clearTimeout(inserterClearTimer);
|
|
820
|
+
inserterClearTimer = null;
|
|
821
|
+
}
|
|
822
|
+
emitInserter();
|
|
739
823
|
return;
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
: {
|
|
748
|
-
top: rect.top,
|
|
749
|
-
left: rect.left,
|
|
750
|
-
width: rect.width,
|
|
751
|
-
height: rect.height,
|
|
752
|
-
},
|
|
753
|
-
});
|
|
824
|
+
}
|
|
825
|
+
if (inserterClearTimer !== null)
|
|
826
|
+
return;
|
|
827
|
+
inserterClearTimer = window.setTimeout(() => {
|
|
828
|
+
inserterClearTimer = null;
|
|
829
|
+
emitInserter();
|
|
830
|
+
}, INSERTER_CLEAR_DELAY_MS);
|
|
754
831
|
};
|
|
755
832
|
const handleMouseMove = (event) => {
|
|
756
833
|
const blocks = Array.from(document.querySelectorAll(BUILDER_BLOCK_SELECTOR)).filter((el) => {
|
|
@@ -885,3 +962,6 @@ function installBuilderDirectManipulation(postMessage, getRevision) {
|
|
|
885
962
|
window.removeEventListener('mousedown', handleMouseDown, true);
|
|
886
963
|
};
|
|
887
964
|
}
|
|
965
|
+
export { getBuilderBlockSettingText, getBuilderProductBlockAttributes, getLayoutPageBlockAttributes, getProductBlockText, getProductPageBlockAttributes, } from './product-page.js';
|
|
966
|
+
export { createStandardProductBlockRegistry, splitStandardProductPageBlocks, buildStandardProductInfoTabs, resolveStandardBuyBoxLabels, resolveStandardDetailsLabels, resolveStandardRelatedProductsTitle, resolveScopedBlockSettingText, STANDARD_PRODUCT_BLOCK_TYPES, STANDARD_PRODUCT_PRIMARY_BLOCK_TYPES, STANDARD_PRODUCT_SECONDARY_BLOCK_TYPES, } from './standard-product-blocks.js';
|
|
967
|
+
export { getBuilderPreviewReviewFixtures } from './preview-fixtures.js';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BuilderSettings } from '@shoppex/builder-contracts';
|
|
2
|
+
export declare const SEARCH_BAR_MAX_WIDTH: Record<string, string>;
|
|
3
|
+
export type ResolvedSearchBarSettings = {
|
|
4
|
+
placeholder: string;
|
|
5
|
+
backgroundColor?: string;
|
|
6
|
+
borderColor?: string;
|
|
7
|
+
borderRadiusPx?: number;
|
|
8
|
+
maxWidth: string;
|
|
9
|
+
showShortcut: boolean;
|
|
10
|
+
showInHero: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare function getNavigationHeaderSettings(settings: BuilderSettings): Record<string, unknown>;
|
|
13
|
+
export declare function readSetting(sources: Array<Record<string, unknown> | undefined>, path: string): unknown;
|
|
14
|
+
export declare function isValidHexColor(value: unknown): value is string;
|
|
15
|
+
export declare function normalizeHexColor(value: string): string;
|
|
16
|
+
export declare function resolveSearchColor(value: unknown): string | undefined;
|
|
17
|
+
export declare function resolveSearchBorderRadius(value: unknown): number | undefined;
|
|
18
|
+
export declare function resolveSearchMaxWidth(value: unknown, fallback?: string): string;
|
|
19
|
+
export declare function resolveSearchBoolean(value: unknown, fallback: boolean): boolean;
|
|
20
|
+
export declare function resolveSearchPlaceholder(value: unknown, fallback: string): string;
|
|
21
|
+
export declare function resolveSearchBarSettings(input: {
|
|
22
|
+
variant: 'hero' | 'navigation';
|
|
23
|
+
heroValues: Record<string, unknown>;
|
|
24
|
+
headerSettings: Record<string, unknown>;
|
|
25
|
+
}): ResolvedSearchBarSettings;
|
|
26
|
+
export declare function buildSearchShellStyle(settings: Pick<ResolvedSearchBarSettings, 'backgroundColor' | 'borderColor' | 'borderRadiusPx'>): {
|
|
27
|
+
backgroundColor?: string;
|
|
28
|
+
borderColor?: string;
|
|
29
|
+
borderWidth?: string;
|
|
30
|
+
borderStyle?: 'solid';
|
|
31
|
+
borderRadius?: string;
|
|
32
|
+
} | undefined;
|
|
33
|
+
//# sourceMappingURL=search-bar-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-bar-settings.d.ts","sourceRoot":"","sources":["../src/search-bar-settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAKvD,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,eAAe,GACxB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,EACnD,IAAI,EAAE,MAAM,GACX,OAAO,CAUT;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAG/D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGrE;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAO,GAAG,MAAM,CAK7E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAG/E;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,OAAO,EAAE,MAAM,GAAG,YAAY,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC,GAAG,yBAAyB,CAwD5B;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,IAAI,CACZ,yBAAyB,EACzB,iBAAiB,GAAG,aAAa,GAAG,gBAAgB,CACrD,GACA;IACD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,SAAS,CAoBZ"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export const SEARCH_BAR_MAX_WIDTH = {
|
|
2
|
+
sm: '20rem',
|
|
3
|
+
md: '28rem',
|
|
4
|
+
lg: '36rem',
|
|
5
|
+
full: '100%',
|
|
6
|
+
};
|
|
7
|
+
export function getNavigationHeaderSettings(settings) {
|
|
8
|
+
const block = settings.theme.layout.navigation?.blocks.find((candidate) => candidate.type === 'header');
|
|
9
|
+
return block?.settings ?? {};
|
|
10
|
+
}
|
|
11
|
+
export function readSetting(sources, path) {
|
|
12
|
+
for (const source of sources) {
|
|
13
|
+
if (!source)
|
|
14
|
+
continue;
|
|
15
|
+
if (!Object.prototype.hasOwnProperty.call(source, path))
|
|
16
|
+
continue;
|
|
17
|
+
const value = source[path];
|
|
18
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
export function isValidHexColor(value) {
|
|
25
|
+
if (typeof value !== 'string' || !value.trim())
|
|
26
|
+
return false;
|
|
27
|
+
return /^#?[a-f\d]{3}(?:[a-f\d]{3})?(?:[a-f\d]{2})?$/i.test(value.trim());
|
|
28
|
+
}
|
|
29
|
+
export function normalizeHexColor(value) {
|
|
30
|
+
const trimmed = value.trim();
|
|
31
|
+
return trimmed.startsWith('#') ? trimmed : `#${trimmed}`;
|
|
32
|
+
}
|
|
33
|
+
export function resolveSearchColor(value) {
|
|
34
|
+
if (!isValidHexColor(value))
|
|
35
|
+
return undefined;
|
|
36
|
+
return normalizeHexColor(value);
|
|
37
|
+
}
|
|
38
|
+
export function resolveSearchBorderRadius(value) {
|
|
39
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
40
|
+
return undefined;
|
|
41
|
+
return Math.max(0, Math.round(value));
|
|
42
|
+
}
|
|
43
|
+
export function resolveSearchMaxWidth(value, fallback = 'md') {
|
|
44
|
+
if (typeof value === 'string' && value in SEARCH_BAR_MAX_WIDTH) {
|
|
45
|
+
return SEARCH_BAR_MAX_WIDTH[value];
|
|
46
|
+
}
|
|
47
|
+
return SEARCH_BAR_MAX_WIDTH[fallback] ?? SEARCH_BAR_MAX_WIDTH.md;
|
|
48
|
+
}
|
|
49
|
+
export function resolveSearchBoolean(value, fallback) {
|
|
50
|
+
if (typeof value === 'boolean')
|
|
51
|
+
return value;
|
|
52
|
+
return fallback;
|
|
53
|
+
}
|
|
54
|
+
export function resolveSearchPlaceholder(value, fallback) {
|
|
55
|
+
return typeof value === 'string' && value.trim() ? value : fallback;
|
|
56
|
+
}
|
|
57
|
+
export function resolveSearchBarSettings(input) {
|
|
58
|
+
const navSources = [input.headerSettings];
|
|
59
|
+
const heroSources = [input.heroValues, input.headerSettings];
|
|
60
|
+
if (input.variant === 'hero') {
|
|
61
|
+
return {
|
|
62
|
+
placeholder: resolveSearchPlaceholder(readSetting(heroSources, 'hero.search.placeholder') ??
|
|
63
|
+
readSetting(navSources, 'navigation.search.placeholder'), 'Search products…'),
|
|
64
|
+
backgroundColor: resolveSearchColor(readSetting(heroSources, 'hero.search.background') ??
|
|
65
|
+
readSetting(navSources, 'navigation.search.background')),
|
|
66
|
+
borderColor: resolveSearchColor(readSetting(heroSources, 'hero.search.borderColor') ??
|
|
67
|
+
readSetting(navSources, 'navigation.search.borderColor')),
|
|
68
|
+
borderRadiusPx: resolveSearchBorderRadius(readSetting(heroSources, 'hero.search.borderRadius') ??
|
|
69
|
+
readSetting(navSources, 'navigation.search.borderRadius')),
|
|
70
|
+
maxWidth: resolveSearchMaxWidth(readSetting(heroSources, 'hero.search.maxWidth'), 'md'),
|
|
71
|
+
showShortcut: resolveSearchBoolean(readSetting(heroSources, 'hero.search.showShortcut'), true),
|
|
72
|
+
showInHero: resolveSearchBoolean(readSetting(heroSources, 'hero.search.show'), true),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
placeholder: resolveSearchPlaceholder(readSetting(navSources, 'navigation.search.placeholder'), 'Search products…'),
|
|
77
|
+
backgroundColor: resolveSearchColor(readSetting(navSources, 'navigation.search.background')),
|
|
78
|
+
borderColor: resolveSearchColor(readSetting(navSources, 'navigation.search.borderColor')),
|
|
79
|
+
borderRadiusPx: resolveSearchBorderRadius(readSetting(navSources, 'navigation.search.borderRadius')),
|
|
80
|
+
maxWidth: SEARCH_BAR_MAX_WIDTH.md,
|
|
81
|
+
showShortcut: true,
|
|
82
|
+
showInHero: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function buildSearchShellStyle(settings) {
|
|
86
|
+
const style = {};
|
|
87
|
+
if (settings.backgroundColor) {
|
|
88
|
+
style.backgroundColor = settings.backgroundColor;
|
|
89
|
+
}
|
|
90
|
+
if (settings.borderColor) {
|
|
91
|
+
style.borderColor = settings.borderColor;
|
|
92
|
+
style.borderWidth = '1px';
|
|
93
|
+
style.borderStyle = 'solid';
|
|
94
|
+
}
|
|
95
|
+
if (settings.borderRadiusPx !== undefined) {
|
|
96
|
+
style.borderRadius = `${settings.borderRadiusPx}px`;
|
|
97
|
+
}
|
|
98
|
+
return Object.keys(style).length > 0 ? style : undefined;
|
|
99
|
+
}
|