@shopkit/builder 0.1.0
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/README.md +302 -0
- package/dist/hooks/index.d.mts +35 -0
- package/dist/hooks/index.d.ts +35 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.mjs +2 -0
- package/dist/index.d.mts +1338 -0
- package/dist/index.d.ts +1338 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/package.json +63 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1338 @@
|
|
|
1
|
+
import React, { ComponentType, ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Commerce Client Interface
|
|
5
|
+
*
|
|
6
|
+
* Consumers implement this interface to provide data fetching capabilities
|
|
7
|
+
* for the page builder. This abstraction allows the page builder to work
|
|
8
|
+
* with any commerce platform (Shopify, custom backends, etc.)
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Parameters for fetching a single product
|
|
12
|
+
*/
|
|
13
|
+
interface ProductQueryParams {
|
|
14
|
+
handle?: string;
|
|
15
|
+
id?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parameters for fetching multiple products
|
|
19
|
+
*/
|
|
20
|
+
interface ProductsQueryParams {
|
|
21
|
+
first?: number;
|
|
22
|
+
after?: string;
|
|
23
|
+
handles?: string[];
|
|
24
|
+
query?: string;
|
|
25
|
+
sortKey?: string;
|
|
26
|
+
reverse?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parameters for fetching a single collection
|
|
30
|
+
*/
|
|
31
|
+
interface CollectionQueryParams {
|
|
32
|
+
handle?: string;
|
|
33
|
+
id?: string;
|
|
34
|
+
productLimit?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parameters for fetching multiple collections
|
|
38
|
+
*/
|
|
39
|
+
interface CollectionsQueryParams {
|
|
40
|
+
first?: number;
|
|
41
|
+
after?: string;
|
|
42
|
+
query?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parameters for fetching collection with filters (faceted search)
|
|
46
|
+
*/
|
|
47
|
+
interface CollectionWithFiltersParams {
|
|
48
|
+
handle: string;
|
|
49
|
+
filters?: Array<Record<string, any>>;
|
|
50
|
+
sortKey?: string;
|
|
51
|
+
reverse?: boolean;
|
|
52
|
+
first?: number;
|
|
53
|
+
after?: string;
|
|
54
|
+
page?: number;
|
|
55
|
+
itemsPerPage?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parameters for fetching collection by handler
|
|
59
|
+
*/
|
|
60
|
+
interface CollectionsByHandlerParams {
|
|
61
|
+
handle: string;
|
|
62
|
+
productLimit?: number;
|
|
63
|
+
sort?: string;
|
|
64
|
+
filter?: Record<string, any>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Commerce Client Interface
|
|
68
|
+
*
|
|
69
|
+
* Required methods that must be implemented by consumers.
|
|
70
|
+
* Optional methods can be implemented for advanced features.
|
|
71
|
+
*/
|
|
72
|
+
interface ICommerceClient {
|
|
73
|
+
/**
|
|
74
|
+
* Fetch a single product by handle or ID
|
|
75
|
+
*/
|
|
76
|
+
getProduct(params: ProductQueryParams): Promise<any>;
|
|
77
|
+
/**
|
|
78
|
+
* Fetch multiple products with pagination and filtering
|
|
79
|
+
*/
|
|
80
|
+
getProducts(params: ProductsQueryParams): Promise<{
|
|
81
|
+
products: any[];
|
|
82
|
+
pageInfo?: any;
|
|
83
|
+
}>;
|
|
84
|
+
/**
|
|
85
|
+
* Fetch product recommendations for a given product
|
|
86
|
+
*/
|
|
87
|
+
getProductRecommendations(productIdOrHandle: string): Promise<any[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Fetch a single collection by handle or ID
|
|
90
|
+
*/
|
|
91
|
+
getCollection(params: CollectionQueryParams): Promise<any>;
|
|
92
|
+
/**
|
|
93
|
+
* Fetch multiple collections with pagination
|
|
94
|
+
*/
|
|
95
|
+
getCollections(params: CollectionsQueryParams): Promise<{
|
|
96
|
+
collections: any[];
|
|
97
|
+
pageInfo?: any;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Optional: Fetch collection with faceted filters
|
|
101
|
+
* Used for collection pages with filtering functionality
|
|
102
|
+
*/
|
|
103
|
+
getCollectionWithFilters?(params: CollectionWithFiltersParams): Promise<any>;
|
|
104
|
+
/**
|
|
105
|
+
* Optional: Fetch collection by handler with specific parameters
|
|
106
|
+
* Used for featured collections, category pages, etc.
|
|
107
|
+
*/
|
|
108
|
+
getCollectionsByHandler?(params: CollectionsByHandlerParams): Promise<any>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Page Builder Theme Types
|
|
113
|
+
*
|
|
114
|
+
* Local type definitions for theme-related functionality within the page builder.
|
|
115
|
+
* These types are intentionally defined here to maintain package independence.
|
|
116
|
+
*
|
|
117
|
+
* When the page builder is extracted as a standalone package, these types
|
|
118
|
+
* will be the contract that consumers must implement.
|
|
119
|
+
*
|
|
120
|
+
* NOTE: These types mirror @/lib/theme/types/theme.ts to maintain consistency.
|
|
121
|
+
* When updating these types, ensure the theme module types are kept in sync.
|
|
122
|
+
*
|
|
123
|
+
* @module lib/page-builder/types/theme
|
|
124
|
+
*/
|
|
125
|
+
/**
|
|
126
|
+
* Theme role - determines the state/purpose of a theme
|
|
127
|
+
*/
|
|
128
|
+
type ThemeRole = "live" | "draft" | "preview";
|
|
129
|
+
/**
|
|
130
|
+
* Theme configuration object
|
|
131
|
+
*
|
|
132
|
+
* Contains design tokens organized by category.
|
|
133
|
+
* All values are CSS-compatible strings or numbers.
|
|
134
|
+
*/
|
|
135
|
+
interface ThemeConfig {
|
|
136
|
+
/**
|
|
137
|
+
* Color palette (e.g., primary, secondary, background, text)
|
|
138
|
+
*/
|
|
139
|
+
colors?: Record<string, string>;
|
|
140
|
+
/**
|
|
141
|
+
* Typography settings (fonts, sizes, weights, line heights)
|
|
142
|
+
*/
|
|
143
|
+
typography?: Record<string, string | number>;
|
|
144
|
+
/**
|
|
145
|
+
* Spacing values (margins, paddings, gaps)
|
|
146
|
+
*/
|
|
147
|
+
spacing?: Record<string, string>;
|
|
148
|
+
/**
|
|
149
|
+
* Border radius values
|
|
150
|
+
*/
|
|
151
|
+
borderRadius?: Record<string, string>;
|
|
152
|
+
/**
|
|
153
|
+
* Box shadow definitions
|
|
154
|
+
*/
|
|
155
|
+
boxShadow?: Record<string, string>;
|
|
156
|
+
/**
|
|
157
|
+
* Transition settings (duration, timing)
|
|
158
|
+
*/
|
|
159
|
+
transition?: Record<string, string>;
|
|
160
|
+
/**
|
|
161
|
+
* Z-index layer definitions
|
|
162
|
+
*/
|
|
163
|
+
zIndex?: Record<string, number>;
|
|
164
|
+
/**
|
|
165
|
+
* Font weight definitions
|
|
166
|
+
*/
|
|
167
|
+
fontWeight?: Record<string, number>;
|
|
168
|
+
/**
|
|
169
|
+
* Width definitions
|
|
170
|
+
*/
|
|
171
|
+
width?: Record<string, string>;
|
|
172
|
+
/**
|
|
173
|
+
* Allow additional custom configuration sections
|
|
174
|
+
*/
|
|
175
|
+
[key: string]: Record<string, string | number> | undefined;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Complete theme object with metadata
|
|
179
|
+
*/
|
|
180
|
+
interface Theme {
|
|
181
|
+
/**
|
|
182
|
+
* Unique theme identifier
|
|
183
|
+
*/
|
|
184
|
+
id: string;
|
|
185
|
+
/**
|
|
186
|
+
* Human-readable theme name
|
|
187
|
+
*/
|
|
188
|
+
name: string;
|
|
189
|
+
/**
|
|
190
|
+
* Theme role (live, draft, preview)
|
|
191
|
+
*/
|
|
192
|
+
role: ThemeRole;
|
|
193
|
+
/**
|
|
194
|
+
* Theme configuration with all design tokens
|
|
195
|
+
*/
|
|
196
|
+
config: ThemeConfig;
|
|
197
|
+
/**
|
|
198
|
+
* Creation timestamp (ISO string)
|
|
199
|
+
*/
|
|
200
|
+
createdAt: string;
|
|
201
|
+
/**
|
|
202
|
+
* Last update timestamp (ISO string)
|
|
203
|
+
*/
|
|
204
|
+
updatedAt: string;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Theme Loader Interface
|
|
208
|
+
*
|
|
209
|
+
* Consumers implement this interface to provide theme loading capabilities.
|
|
210
|
+
* Themes can be loaded from file system, API, database, or any other source.
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const themeLoader: IThemeLoader = {
|
|
215
|
+
* async loadTheme(merchantName: string): Promise<Theme> {
|
|
216
|
+
* const data = await fetchThemeFromAPI(merchantName);
|
|
217
|
+
* return {
|
|
218
|
+
* id: data.id,
|
|
219
|
+
* name: data.name,
|
|
220
|
+
* role: data.role,
|
|
221
|
+
* config: data.config,
|
|
222
|
+
* createdAt: data.createdAt,
|
|
223
|
+
* updatedAt: data.updatedAt,
|
|
224
|
+
* };
|
|
225
|
+
* }
|
|
226
|
+
* };
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
interface IThemeLoader {
|
|
230
|
+
/**
|
|
231
|
+
* Load the active theme for a merchant
|
|
232
|
+
*
|
|
233
|
+
* @param merchantName - The merchant identifier
|
|
234
|
+
* @returns Promise resolving to the theme configuration
|
|
235
|
+
* @throws Error if theme cannot be loaded
|
|
236
|
+
*/
|
|
237
|
+
loadTheme(merchantName: string): Promise<Theme>;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Data Source Types
|
|
242
|
+
*
|
|
243
|
+
* Defines data source configuration for fetching commerce data.
|
|
244
|
+
*/
|
|
245
|
+
/**
|
|
246
|
+
* Data source types constant
|
|
247
|
+
* Defines all available data source types
|
|
248
|
+
*/
|
|
249
|
+
declare const DATA_SOURCE_TYPES: {
|
|
250
|
+
/** Single product by handle or ID */
|
|
251
|
+
readonly PRODUCT: "PRODUCT";
|
|
252
|
+
/** Multiple products with query/pagination */
|
|
253
|
+
readonly PRODUCTS: "PRODUCTS";
|
|
254
|
+
/** Multiple products by specific handles */
|
|
255
|
+
readonly PRODUCTS_BY_HANDLES: "PRODUCTS_BY_HANDLES";
|
|
256
|
+
/** Single collection by handle or ID */
|
|
257
|
+
readonly COLLECTION: "COLLECTION";
|
|
258
|
+
/** Multiple collections with pagination */
|
|
259
|
+
readonly COLLECTIONS: "COLLECTIONS";
|
|
260
|
+
/** Collection with faceted filters (for collection pages) */
|
|
261
|
+
readonly COLLECTION_PAGE_WITH_FILTERS: "COLLECTION_PAGE_WITH_FILTERS";
|
|
262
|
+
/** Collection by handler with custom params */
|
|
263
|
+
readonly COLLECTION_BY_HANDLES: "COLLECTION_BY_HANDLES";
|
|
264
|
+
/** Static data (no fetching required) */
|
|
265
|
+
readonly STATIC: "STATIC";
|
|
266
|
+
/** Product recommendations */
|
|
267
|
+
readonly PRODUCT_RECOMMENDATIONS: "PRODUCT_RECOMMENDATIONS";
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* Data source type union
|
|
271
|
+
*/
|
|
272
|
+
type DataSourceType = (typeof DATA_SOURCE_TYPES)[keyof typeof DATA_SOURCE_TYPES];
|
|
273
|
+
/**
|
|
274
|
+
* Data source configuration
|
|
275
|
+
*
|
|
276
|
+
* Defines how to fetch data for a page or widget.
|
|
277
|
+
*/
|
|
278
|
+
interface DataSourceConfig {
|
|
279
|
+
/**
|
|
280
|
+
* Type of data source
|
|
281
|
+
*/
|
|
282
|
+
type: DataSourceType | string;
|
|
283
|
+
/**
|
|
284
|
+
* Parameters for the data source
|
|
285
|
+
* Structure depends on the data source type
|
|
286
|
+
*/
|
|
287
|
+
params: Record<string, any>;
|
|
288
|
+
/**
|
|
289
|
+
* Whether this data source is required for page rendering
|
|
290
|
+
* If true, page will fail if data cannot be fetched
|
|
291
|
+
*/
|
|
292
|
+
required: boolean;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Page Configuration Types
|
|
297
|
+
*
|
|
298
|
+
* Defines the structure of page templates including sections and widgets.
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Spacing values for padding/margin
|
|
303
|
+
*/
|
|
304
|
+
interface Spacing {
|
|
305
|
+
top: number;
|
|
306
|
+
right: number;
|
|
307
|
+
bottom: number;
|
|
308
|
+
left: number;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Responsive spacing configuration
|
|
312
|
+
*/
|
|
313
|
+
interface ResponsiveSpacing {
|
|
314
|
+
padding?: Spacing;
|
|
315
|
+
margin?: Spacing;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Section settings configuration
|
|
319
|
+
*/
|
|
320
|
+
interface SectionSettings {
|
|
321
|
+
/**
|
|
322
|
+
* Layout mode
|
|
323
|
+
* - "page": Constrained to container width
|
|
324
|
+
* - "full": Full viewport width
|
|
325
|
+
*/
|
|
326
|
+
layout: "page" | "full";
|
|
327
|
+
/**
|
|
328
|
+
* Responsive settings per breakpoint
|
|
329
|
+
*/
|
|
330
|
+
responsive?: {
|
|
331
|
+
mobile?: ResponsiveSpacing;
|
|
332
|
+
tablet?: ResponsiveSpacing;
|
|
333
|
+
desktop?: ResponsiveSpacing;
|
|
334
|
+
wide?: ResponsiveSpacing;
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* Default padding (fallback)
|
|
338
|
+
*/
|
|
339
|
+
padding?: Spacing;
|
|
340
|
+
/**
|
|
341
|
+
* Default margin (fallback)
|
|
342
|
+
*/
|
|
343
|
+
margin?: Spacing;
|
|
344
|
+
/**
|
|
345
|
+
* Additional custom settings
|
|
346
|
+
*/
|
|
347
|
+
[key: string]: any;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Widget responsive configuration
|
|
351
|
+
*/
|
|
352
|
+
interface WidgetResponsiveConfig {
|
|
353
|
+
mobile?: Record<string, any>;
|
|
354
|
+
tablet?: Record<string, any>;
|
|
355
|
+
desktop?: Record<string, any>;
|
|
356
|
+
wide?: Record<string, any>;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Widget configuration
|
|
360
|
+
*
|
|
361
|
+
* Defines a single widget within a section.
|
|
362
|
+
*/
|
|
363
|
+
interface WidgetConfig {
|
|
364
|
+
/**
|
|
365
|
+
* Unique widget identifier
|
|
366
|
+
*/
|
|
367
|
+
id: string;
|
|
368
|
+
/**
|
|
369
|
+
* Human-readable widget name
|
|
370
|
+
*/
|
|
371
|
+
name: string;
|
|
372
|
+
/**
|
|
373
|
+
* Widget type - must match a registered widget in the registry
|
|
374
|
+
*/
|
|
375
|
+
type: string;
|
|
376
|
+
/**
|
|
377
|
+
* Reference to a data source key in the page's dataSources
|
|
378
|
+
*/
|
|
379
|
+
dataSourceKey?: string;
|
|
380
|
+
/**
|
|
381
|
+
* Widget settings/configuration
|
|
382
|
+
* Supports translation keys with "t:" prefix
|
|
383
|
+
*/
|
|
384
|
+
settings: Record<string, any>;
|
|
385
|
+
/**
|
|
386
|
+
* Responsive setting overrides per breakpoint
|
|
387
|
+
*/
|
|
388
|
+
responsive?: WidgetResponsiveConfig;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Section configuration
|
|
392
|
+
*
|
|
393
|
+
* Defines a section of a page containing widgets.
|
|
394
|
+
*/
|
|
395
|
+
interface SectionConfig {
|
|
396
|
+
/**
|
|
397
|
+
* Unique section identifier
|
|
398
|
+
*/
|
|
399
|
+
id: string;
|
|
400
|
+
/**
|
|
401
|
+
* Human-readable section name
|
|
402
|
+
*/
|
|
403
|
+
name: string;
|
|
404
|
+
/**
|
|
405
|
+
* Section type identifier
|
|
406
|
+
*/
|
|
407
|
+
type: string;
|
|
408
|
+
/**
|
|
409
|
+
* Section settings including layout and spacing
|
|
410
|
+
*/
|
|
411
|
+
settings: SectionSettings;
|
|
412
|
+
/**
|
|
413
|
+
* Widgets contained in this section
|
|
414
|
+
*/
|
|
415
|
+
widgets: WidgetConfig[];
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Page configuration
|
|
419
|
+
*
|
|
420
|
+
* The root configuration object defining a complete page template.
|
|
421
|
+
*/
|
|
422
|
+
interface PageConfig {
|
|
423
|
+
/**
|
|
424
|
+
* Unique page/template identifier
|
|
425
|
+
*/
|
|
426
|
+
id: string;
|
|
427
|
+
/**
|
|
428
|
+
* Data sources available to widgets on this page
|
|
429
|
+
* Key is the data source identifier, value is the configuration
|
|
430
|
+
*/
|
|
431
|
+
dataSources: Record<string, DataSourceConfig>;
|
|
432
|
+
/**
|
|
433
|
+
* Page sections in render order
|
|
434
|
+
*/
|
|
435
|
+
sections: SectionConfig[];
|
|
436
|
+
/**
|
|
437
|
+
* Theme overrides for this specific page
|
|
438
|
+
*/
|
|
439
|
+
theme?: Record<string, any>;
|
|
440
|
+
/**
|
|
441
|
+
* Responsive configuration for the page
|
|
442
|
+
*/
|
|
443
|
+
responsive?: any;
|
|
444
|
+
/**
|
|
445
|
+
* Custom breakpoint configuration
|
|
446
|
+
*/
|
|
447
|
+
breakpoints?: any;
|
|
448
|
+
/**
|
|
449
|
+
* Additional metadata
|
|
450
|
+
*/
|
|
451
|
+
[key: string]: any;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Template type alias
|
|
455
|
+
* A template is just a PageConfig
|
|
456
|
+
*/
|
|
457
|
+
type Template = PageConfig;
|
|
458
|
+
/**
|
|
459
|
+
* Page configuration helpers
|
|
460
|
+
*/
|
|
461
|
+
declare class PageConfigHelpers {
|
|
462
|
+
/**
|
|
463
|
+
* Get all data source keys used by widgets
|
|
464
|
+
*/
|
|
465
|
+
static getUsedDataSources(pageConfig: PageConfig): string[];
|
|
466
|
+
/**
|
|
467
|
+
* Find a widget by ID
|
|
468
|
+
*/
|
|
469
|
+
static findWidget(pageConfig: PageConfig, widgetId: string): WidgetConfig | null;
|
|
470
|
+
/**
|
|
471
|
+
* Find a section by ID
|
|
472
|
+
*/
|
|
473
|
+
static findSection(pageConfig: PageConfig, sectionId: string): SectionConfig | null;
|
|
474
|
+
/**
|
|
475
|
+
* Generate a unique ID with prefix
|
|
476
|
+
*/
|
|
477
|
+
static generateId(prefix: string): string;
|
|
478
|
+
/**
|
|
479
|
+
* Validate page configuration structure
|
|
480
|
+
*/
|
|
481
|
+
static validate(pageConfig: PageConfig): {
|
|
482
|
+
valid: boolean;
|
|
483
|
+
errors: string[];
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Schema definition for sections - used by the editor to generate forms
|
|
488
|
+
*/
|
|
489
|
+
interface SectionSchema {
|
|
490
|
+
/** Section type identifier */
|
|
491
|
+
type: string;
|
|
492
|
+
/** Display name for the editor */
|
|
493
|
+
name: string;
|
|
494
|
+
/** Description for the editor */
|
|
495
|
+
description?: string;
|
|
496
|
+
/** Settings schema for the section (editor-only, shape matches DynamicForm) */
|
|
497
|
+
settingsSchema: Record<string, {
|
|
498
|
+
type: "text" | "number" | "boolean" | "select" | "spacing" | "image" | "faq" | "richtext" | "objectArray" | "array";
|
|
499
|
+
label?: string;
|
|
500
|
+
default?: any;
|
|
501
|
+
options?: Array<{
|
|
502
|
+
value: any;
|
|
503
|
+
label: string;
|
|
504
|
+
}>;
|
|
505
|
+
min?: number;
|
|
506
|
+
max?: number;
|
|
507
|
+
step?: number;
|
|
508
|
+
unit?: string;
|
|
509
|
+
optional?: boolean;
|
|
510
|
+
fields?: string[];
|
|
511
|
+
placeholder?: string;
|
|
512
|
+
}>;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Schema definition for widgets - used by the editor to generate forms
|
|
516
|
+
*/
|
|
517
|
+
interface WidgetSchema {
|
|
518
|
+
/** Widget type identifier */
|
|
519
|
+
type: string;
|
|
520
|
+
/** Display name for the editor */
|
|
521
|
+
name: string;
|
|
522
|
+
/** Description for the editor */
|
|
523
|
+
description?: string;
|
|
524
|
+
/** Settings schema for the widget */
|
|
525
|
+
settingsSchema: Record<string, {
|
|
526
|
+
type: "text" | "number" | "boolean" | "select" | "spacing" | "object" | "array" | "objectArray" | "richtext";
|
|
527
|
+
label?: string;
|
|
528
|
+
default?: any;
|
|
529
|
+
options?: Array<{
|
|
530
|
+
value: any;
|
|
531
|
+
label: string;
|
|
532
|
+
}>;
|
|
533
|
+
min?: number;
|
|
534
|
+
max?: number;
|
|
535
|
+
unit?: string;
|
|
536
|
+
optional?: boolean;
|
|
537
|
+
properties?: Record<string, any>;
|
|
538
|
+
fields?: string[];
|
|
539
|
+
}>;
|
|
540
|
+
/** Whether this widget requires a data source */
|
|
541
|
+
requiresDataSource?: boolean;
|
|
542
|
+
/** Compatible data source types */
|
|
543
|
+
compatibleDataSources?: string[];
|
|
544
|
+
/** Responsive settings that can be overridden */
|
|
545
|
+
responsiveSettings?: string[];
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Registry types for the editor
|
|
549
|
+
*/
|
|
550
|
+
interface SectionRegistry {
|
|
551
|
+
[key: string]: SectionSchema;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Widget Registry for editor (different from IWidgetRegistry)
|
|
555
|
+
* Maps widget type names to their schemas
|
|
556
|
+
*/
|
|
557
|
+
interface WidgetSchemaRegistry {
|
|
558
|
+
[key: string]: WidgetSchema;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Template Loader Interface
|
|
563
|
+
*
|
|
564
|
+
* Consumers implement this interface to provide template loading capabilities.
|
|
565
|
+
* Templates can be loaded from file system, API, CMS, or any other source.
|
|
566
|
+
*/
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Template variant mapping configuration
|
|
570
|
+
* Maps API data fields to template variants
|
|
571
|
+
*/
|
|
572
|
+
interface TemplateVariantMapping {
|
|
573
|
+
/**
|
|
574
|
+
* The API field to check for variant determination
|
|
575
|
+
* Supports dot notation for nested fields (e.g., "collection.handle")
|
|
576
|
+
*/
|
|
577
|
+
apiField: string;
|
|
578
|
+
/**
|
|
579
|
+
* Map of API field values to template variant names
|
|
580
|
+
* Optional - if not provided, defaultVariant is used
|
|
581
|
+
*/
|
|
582
|
+
variantMap?: Record<string, string>;
|
|
583
|
+
/**
|
|
584
|
+
* Default variant to use if no match is found
|
|
585
|
+
*/
|
|
586
|
+
defaultVariant: string;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Template Variant Registry
|
|
590
|
+
* Registry of template variant mappings by template type
|
|
591
|
+
*/
|
|
592
|
+
interface TemplateVariantRegistry {
|
|
593
|
+
[templateType: string]: TemplateVariantMapping;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Variant Registry Result
|
|
597
|
+
* Wrapper for variant registry returned by loadVariantRegistry
|
|
598
|
+
*/
|
|
599
|
+
interface VariantRegistryResult {
|
|
600
|
+
variantRegistry: TemplateVariantRegistry;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Template Loader Interface
|
|
604
|
+
*
|
|
605
|
+
* Provides methods to load page templates and variant registries.
|
|
606
|
+
*/
|
|
607
|
+
interface ITemplateLoader {
|
|
608
|
+
/**
|
|
609
|
+
* Load a page template configuration
|
|
610
|
+
*
|
|
611
|
+
* @param merchantName - The merchant identifier
|
|
612
|
+
* @param templateName - The template type (e.g., "home", "product", "collection")
|
|
613
|
+
* @param variant - The template variant (e.g., "default", "featured")
|
|
614
|
+
* @returns Promise resolving to the page configuration
|
|
615
|
+
*/
|
|
616
|
+
loadTemplate(merchantName: string, templateName: string, variant: string): Promise<PageConfig>;
|
|
617
|
+
/**
|
|
618
|
+
* Load variant registry for automatic variant selection
|
|
619
|
+
* Optional - if not implemented, "default" variant is always used
|
|
620
|
+
*
|
|
621
|
+
* @param merchantName - The merchant identifier
|
|
622
|
+
* @returns Promise resolving to the variant registry wrapper or null
|
|
623
|
+
*/
|
|
624
|
+
loadVariantRegistry?(merchantName: string): Promise<VariantRegistryResult | null>;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Widget Registry Interface and Default Implementation
|
|
629
|
+
*
|
|
630
|
+
* The widget registry maps widget type strings to React components.
|
|
631
|
+
* Consumers can use the default WidgetRegistry class or provide their own implementation.
|
|
632
|
+
*/
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Widget registration entry
|
|
636
|
+
*/
|
|
637
|
+
interface WidgetRegistration {
|
|
638
|
+
type: string;
|
|
639
|
+
component: ComponentType<any>;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Widget Registry Interface
|
|
643
|
+
*
|
|
644
|
+
* Maps widget type strings to React components for rendering.
|
|
645
|
+
*/
|
|
646
|
+
interface IWidgetRegistry {
|
|
647
|
+
/**
|
|
648
|
+
* Register a single widget component
|
|
649
|
+
*
|
|
650
|
+
* @param type - The widget type identifier
|
|
651
|
+
* @param component - The React component to render
|
|
652
|
+
*/
|
|
653
|
+
register(type: string, component: ComponentType<any>): void;
|
|
654
|
+
/**
|
|
655
|
+
* Register multiple widget components at once
|
|
656
|
+
*
|
|
657
|
+
* @param widgets - Array of widget registrations
|
|
658
|
+
*/
|
|
659
|
+
registerAll(widgets: WidgetRegistration[]): void;
|
|
660
|
+
/**
|
|
661
|
+
* Get a widget component by type
|
|
662
|
+
*
|
|
663
|
+
* @param type - The widget type identifier
|
|
664
|
+
* @returns The React component or undefined if not found
|
|
665
|
+
*/
|
|
666
|
+
get(type: string): ComponentType<any> | undefined;
|
|
667
|
+
/**
|
|
668
|
+
* Check if a widget type is registered
|
|
669
|
+
*
|
|
670
|
+
* @param type - The widget type identifier
|
|
671
|
+
* @returns True if the widget is registered
|
|
672
|
+
*/
|
|
673
|
+
has(type: string): boolean;
|
|
674
|
+
/**
|
|
675
|
+
* Get all registered widget types
|
|
676
|
+
*
|
|
677
|
+
* @returns Array of registered widget type identifiers
|
|
678
|
+
*/
|
|
679
|
+
getRegisteredTypes(): string[];
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Default Widget Registry Implementation
|
|
683
|
+
*
|
|
684
|
+
* A simple Map-based implementation of the widget registry.
|
|
685
|
+
* Consumers can use this directly or provide their own implementation.
|
|
686
|
+
*/
|
|
687
|
+
declare class WidgetRegistry implements IWidgetRegistry {
|
|
688
|
+
private widgets;
|
|
689
|
+
/**
|
|
690
|
+
* Register a single widget component
|
|
691
|
+
*/
|
|
692
|
+
register(type: string, component: ComponentType<any>): void;
|
|
693
|
+
/**
|
|
694
|
+
* Register multiple widget components at once
|
|
695
|
+
*/
|
|
696
|
+
registerAll(widgets: WidgetRegistration[]): void;
|
|
697
|
+
/**
|
|
698
|
+
* Get a widget component by type
|
|
699
|
+
*/
|
|
700
|
+
get(type: string): ComponentType<any> | undefined;
|
|
701
|
+
/**
|
|
702
|
+
* Check if a widget type is registered
|
|
703
|
+
*/
|
|
704
|
+
has(type: string): boolean;
|
|
705
|
+
/**
|
|
706
|
+
* Get all registered widget types
|
|
707
|
+
*/
|
|
708
|
+
getRegisteredTypes(): string[];
|
|
709
|
+
/**
|
|
710
|
+
* Clear all registered widgets
|
|
711
|
+
*/
|
|
712
|
+
clear(): void;
|
|
713
|
+
/**
|
|
714
|
+
* Get the total count of registered widgets
|
|
715
|
+
*/
|
|
716
|
+
get size(): number;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Route Context Types
|
|
721
|
+
*
|
|
722
|
+
* Defines the context passed to the page builder for rendering.
|
|
723
|
+
*/
|
|
724
|
+
/**
|
|
725
|
+
* Viewport breakpoint type
|
|
726
|
+
*/
|
|
727
|
+
type Breakpoint = "mobile" | "tablet" | "desktop" | "wide";
|
|
728
|
+
/**
|
|
729
|
+
* Breakpoint configuration for responsive design
|
|
730
|
+
*/
|
|
731
|
+
interface BreakpointConfig {
|
|
732
|
+
mobile: {
|
|
733
|
+
max: number;
|
|
734
|
+
};
|
|
735
|
+
tablet: {
|
|
736
|
+
min: number;
|
|
737
|
+
max: number;
|
|
738
|
+
};
|
|
739
|
+
desktop: {
|
|
740
|
+
min: number;
|
|
741
|
+
max: number;
|
|
742
|
+
};
|
|
743
|
+
wide: {
|
|
744
|
+
min: number;
|
|
745
|
+
};
|
|
746
|
+
custom?: Record<string, {
|
|
747
|
+
min?: number;
|
|
748
|
+
max?: number;
|
|
749
|
+
}>;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Default breakpoints
|
|
753
|
+
*/
|
|
754
|
+
declare const DEFAULT_BREAKPOINTS: BreakpointConfig;
|
|
755
|
+
/**
|
|
756
|
+
* Viewport information
|
|
757
|
+
*/
|
|
758
|
+
interface ViewportInfo {
|
|
759
|
+
width: number;
|
|
760
|
+
height: number;
|
|
761
|
+
breakpoint: Breakpoint;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Route Context
|
|
765
|
+
*
|
|
766
|
+
* Contains all information about the current route being rendered.
|
|
767
|
+
*/
|
|
768
|
+
interface RouteContext {
|
|
769
|
+
/**
|
|
770
|
+
* Template name to use for rendering
|
|
771
|
+
* e.g., "home", "product", "collection"
|
|
772
|
+
*/
|
|
773
|
+
templateName: string;
|
|
774
|
+
/**
|
|
775
|
+
* Current page path
|
|
776
|
+
* e.g., "/", "/products/my-product", "/collections/featured"
|
|
777
|
+
*/
|
|
778
|
+
path: string;
|
|
779
|
+
/**
|
|
780
|
+
* URL path parameters
|
|
781
|
+
* e.g., { handle: "my-product" }
|
|
782
|
+
*/
|
|
783
|
+
params: Record<string, string>;
|
|
784
|
+
/**
|
|
785
|
+
* URL query parameters
|
|
786
|
+
* e.g., { sort: "price-asc", page: "2" }
|
|
787
|
+
*/
|
|
788
|
+
query?: Record<string, string | string[] | undefined>;
|
|
789
|
+
/**
|
|
790
|
+
* Product handle (for product pages)
|
|
791
|
+
*/
|
|
792
|
+
productHandle?: string;
|
|
793
|
+
/**
|
|
794
|
+
* Collection handle (for collection pages)
|
|
795
|
+
*/
|
|
796
|
+
collectionHandle?: string;
|
|
797
|
+
/**
|
|
798
|
+
* Current viewport information
|
|
799
|
+
*/
|
|
800
|
+
viewport?: ViewportInfo;
|
|
801
|
+
/**
|
|
802
|
+
* Whether to fetch template from API (for visual editor integration)
|
|
803
|
+
*/
|
|
804
|
+
fetchAPITemplate?: boolean;
|
|
805
|
+
/**
|
|
806
|
+
* Additional custom context data
|
|
807
|
+
*/
|
|
808
|
+
[key: string]: any;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Section Renderer Interface
|
|
813
|
+
*
|
|
814
|
+
* Defines the function type for rendering section wrappers.
|
|
815
|
+
* Consumers can provide custom section rendering logic for styling,
|
|
816
|
+
* responsive behavior, or special section types.
|
|
817
|
+
*/
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Context provided to section renderers
|
|
821
|
+
*/
|
|
822
|
+
interface SectionRenderContext {
|
|
823
|
+
/**
|
|
824
|
+
* Merged theme and page styles
|
|
825
|
+
*/
|
|
826
|
+
styles: Record<string, any>;
|
|
827
|
+
/**
|
|
828
|
+
* Current route context
|
|
829
|
+
*/
|
|
830
|
+
routeContext: RouteContext;
|
|
831
|
+
/**
|
|
832
|
+
* Current breakpoint (if detected)
|
|
833
|
+
*/
|
|
834
|
+
breakpoint?: "mobile" | "tablet" | "desktop" | "wide";
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Section Renderer Function Type
|
|
838
|
+
*
|
|
839
|
+
* A function that renders a section wrapper around its children widgets.
|
|
840
|
+
*
|
|
841
|
+
* @param section - The section configuration
|
|
842
|
+
* @param children - The rendered widget React nodes
|
|
843
|
+
* @param context - Additional context including styles and route info
|
|
844
|
+
* @returns A React node representing the rendered section
|
|
845
|
+
*/
|
|
846
|
+
type SectionRenderer = (section: SectionConfig, children: ReactNode[], context: SectionRenderContext) => ReactNode;
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Locale Type
|
|
850
|
+
*
|
|
851
|
+
* Defines supported locales for the page builder.
|
|
852
|
+
* Internalized to avoid external dependencies.
|
|
853
|
+
*/
|
|
854
|
+
/**
|
|
855
|
+
* Supported locale codes
|
|
856
|
+
*/
|
|
857
|
+
type Locale = "en" | "hi" | string;
|
|
858
|
+
/**
|
|
859
|
+
* Default locale
|
|
860
|
+
*/
|
|
861
|
+
declare const DEFAULT_LOCALE: Locale;
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Page Building Engine
|
|
865
|
+
*
|
|
866
|
+
* The main orchestrator that coordinates all other components to render a page.
|
|
867
|
+
* All dependencies are injected via constructor for complete encapsulation.
|
|
868
|
+
*/
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Render Page Parameters
|
|
872
|
+
*/
|
|
873
|
+
interface RenderPageParams {
|
|
874
|
+
/**
|
|
875
|
+
* Merchant identifier - REQUIRED, no fallback
|
|
876
|
+
*/
|
|
877
|
+
merchantName: string;
|
|
878
|
+
/**
|
|
879
|
+
* Route context with template name, path, params
|
|
880
|
+
*/
|
|
881
|
+
routeContext: RouteContext;
|
|
882
|
+
/**
|
|
883
|
+
* Locale for this render
|
|
884
|
+
*/
|
|
885
|
+
locale?: Locale;
|
|
886
|
+
/**
|
|
887
|
+
* Translation messages for i18n
|
|
888
|
+
*/
|
|
889
|
+
messages?: Record<string, any>;
|
|
890
|
+
/**
|
|
891
|
+
* Optional pre-loaded page config (skips template loading)
|
|
892
|
+
*/
|
|
893
|
+
pageConfig?: PageConfig;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* Page Builder Factory Function
|
|
898
|
+
*
|
|
899
|
+
* The single public API for creating a page builder instance.
|
|
900
|
+
* All dependencies are injected through the options parameter.
|
|
901
|
+
*/
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Options for creating a page builder instance
|
|
905
|
+
*/
|
|
906
|
+
interface PageBuilderOptions {
|
|
907
|
+
/**
|
|
908
|
+
* Commerce client for fetching products, collections, etc.
|
|
909
|
+
* REQUIRED - consumers must implement ICommerceClient
|
|
910
|
+
*/
|
|
911
|
+
commerceClient: ICommerceClient;
|
|
912
|
+
/**
|
|
913
|
+
* Theme loader for fetching merchant themes
|
|
914
|
+
* REQUIRED - consumers implement how themes are loaded
|
|
915
|
+
*/
|
|
916
|
+
themeLoader: IThemeLoader;
|
|
917
|
+
/**
|
|
918
|
+
* Template loader for fetching page templates
|
|
919
|
+
* REQUIRED - consumers implement how templates are loaded
|
|
920
|
+
*/
|
|
921
|
+
templateLoader: ITemplateLoader;
|
|
922
|
+
/**
|
|
923
|
+
* Widget registry with all registered widget components
|
|
924
|
+
* REQUIRED - consumers populate with their widgets
|
|
925
|
+
*/
|
|
926
|
+
widgetRegistry: IWidgetRegistry;
|
|
927
|
+
/**
|
|
928
|
+
* Custom section renderer component
|
|
929
|
+
* OPTIONAL - defaults to a basic <section> wrapper
|
|
930
|
+
*/
|
|
931
|
+
sectionRenderer?: SectionRenderer;
|
|
932
|
+
/**
|
|
933
|
+
* Default locale for the page builder
|
|
934
|
+
* OPTIONAL - defaults to 'en'
|
|
935
|
+
*/
|
|
936
|
+
defaultLocale?: Locale;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Validation result for page config
|
|
940
|
+
*/
|
|
941
|
+
interface ValidationResult {
|
|
942
|
+
valid: boolean;
|
|
943
|
+
errors: string[];
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Page Builder Interface
|
|
947
|
+
*
|
|
948
|
+
* The public interface returned by createPageBuilder()
|
|
949
|
+
*/
|
|
950
|
+
interface PageBuilder {
|
|
951
|
+
/**
|
|
952
|
+
* Render a page to React nodes
|
|
953
|
+
*/
|
|
954
|
+
renderPage(params: RenderPageParams): Promise<React.ReactNode>;
|
|
955
|
+
/**
|
|
956
|
+
* Clear internal caches
|
|
957
|
+
*/
|
|
958
|
+
clearCache(): void;
|
|
959
|
+
/**
|
|
960
|
+
* Validate a page configuration
|
|
961
|
+
*/
|
|
962
|
+
validateConfig(config: PageConfig): ValidationResult;
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Create a new page builder instance
|
|
966
|
+
*
|
|
967
|
+
* This is the main entry point for using the page builder.
|
|
968
|
+
* All dependencies are provided through the options parameter.
|
|
969
|
+
*
|
|
970
|
+
* @example
|
|
971
|
+
* ```typescript
|
|
972
|
+
* import { createPageBuilder, WidgetRegistry } from '@/lib/page-builder';
|
|
973
|
+
*
|
|
974
|
+
* // Create and populate widget registry
|
|
975
|
+
* const widgetRegistry = new WidgetRegistry();
|
|
976
|
+
* widgetRegistry.registerAll([
|
|
977
|
+
* { type: 'Header', component: HeaderWidget },
|
|
978
|
+
* { type: 'ProductCard', component: ProductCardWidget },
|
|
979
|
+
* ]);
|
|
980
|
+
*
|
|
981
|
+
* // Create page builder with all dependencies
|
|
982
|
+
* const pageBuilder = createPageBuilder({
|
|
983
|
+
* commerceClient: myCommerceClient,
|
|
984
|
+
* themeLoader: myThemeLoader,
|
|
985
|
+
* templateLoader: myTemplateLoader,
|
|
986
|
+
* widgetRegistry,
|
|
987
|
+
* defaultLocale: 'en',
|
|
988
|
+
* });
|
|
989
|
+
*
|
|
990
|
+
* // Use in pages
|
|
991
|
+
* const content = await pageBuilder.renderPage({
|
|
992
|
+
* merchantName: 'my-merchant',
|
|
993
|
+
* routeContext: {
|
|
994
|
+
* templateName: 'home',
|
|
995
|
+
* path: '/',
|
|
996
|
+
* params: {},
|
|
997
|
+
* },
|
|
998
|
+
* });
|
|
999
|
+
* ```
|
|
1000
|
+
*/
|
|
1001
|
+
declare function createPageBuilder(options: PageBuilderOptions): PageBuilder;
|
|
1002
|
+
|
|
1003
|
+
/**
|
|
1004
|
+
* Layout and Alignment Options
|
|
1005
|
+
*
|
|
1006
|
+
* Type-safe constants for layout and alignment values used in templates.
|
|
1007
|
+
* These constants are exported from the page-builder package for use in templates.
|
|
1008
|
+
*/
|
|
1009
|
+
/**
|
|
1010
|
+
* Section Types
|
|
1011
|
+
* Defines the semantic types of sections in a page layout.
|
|
1012
|
+
* Moved here from ui/layout/constants to centralize all template constants.
|
|
1013
|
+
*/
|
|
1014
|
+
declare const SECTION_TYPES: {
|
|
1015
|
+
readonly HEADER_SECTION: "HEADER_SECTION";
|
|
1016
|
+
readonly GRID_SECTION: "GRID_SECTION";
|
|
1017
|
+
readonly HERO_SECTION: "HERO_SECTION";
|
|
1018
|
+
readonly CONTENT_SECTION: "CONTENT_SECTION";
|
|
1019
|
+
readonly FOOTER_SECTION: "FOOTER_SECTION";
|
|
1020
|
+
};
|
|
1021
|
+
type SectionType = (typeof SECTION_TYPES)[keyof typeof SECTION_TYPES];
|
|
1022
|
+
/**
|
|
1023
|
+
* Section Layout Options
|
|
1024
|
+
* Extracted from section schema registry
|
|
1025
|
+
*/
|
|
1026
|
+
declare const SECTION_LAYOUT_OPTIONS: {
|
|
1027
|
+
readonly PAGE: "page";
|
|
1028
|
+
readonly FULL: "full";
|
|
1029
|
+
};
|
|
1030
|
+
/**
|
|
1031
|
+
* Section Alignment Options
|
|
1032
|
+
* Extracted from section schema registry
|
|
1033
|
+
*/
|
|
1034
|
+
declare const SECTION_ALIGNMENT_OPTIONS: {
|
|
1035
|
+
readonly LEFT: "left";
|
|
1036
|
+
readonly CENTER: "center";
|
|
1037
|
+
readonly RIGHT: "right";
|
|
1038
|
+
};
|
|
1039
|
+
/**
|
|
1040
|
+
* Widget Aspect Ratio Options
|
|
1041
|
+
* Extracted from widget schema registry
|
|
1042
|
+
*/
|
|
1043
|
+
declare const ASPECT_RATIO_OPTIONS: {
|
|
1044
|
+
readonly SQUARE: "1:1";
|
|
1045
|
+
readonly STANDARD: "4:3";
|
|
1046
|
+
readonly CLASSIC: "3:2";
|
|
1047
|
+
readonly WIDE: "16:9";
|
|
1048
|
+
};
|
|
1049
|
+
/**
|
|
1050
|
+
* Widget Text Alignment Options
|
|
1051
|
+
*/
|
|
1052
|
+
declare const TEXT_ALIGNMENT_OPTIONS: {
|
|
1053
|
+
readonly LEFT: "left";
|
|
1054
|
+
readonly CENTER: "center";
|
|
1055
|
+
readonly RIGHT: "right";
|
|
1056
|
+
};
|
|
1057
|
+
/**
|
|
1058
|
+
* Card Style Options
|
|
1059
|
+
*/
|
|
1060
|
+
declare const CARD_STYLE_OPTIONS: {
|
|
1061
|
+
readonly STANDARD: "standard";
|
|
1062
|
+
readonly COMPACT: "compact";
|
|
1063
|
+
readonly MINIMAL: "minimal";
|
|
1064
|
+
};
|
|
1065
|
+
/**
|
|
1066
|
+
* Type definitions for better type safety
|
|
1067
|
+
*/
|
|
1068
|
+
type SectionLayoutOption = (typeof SECTION_LAYOUT_OPTIONS)[keyof typeof SECTION_LAYOUT_OPTIONS];
|
|
1069
|
+
type SectionAlignmentOption = (typeof SECTION_ALIGNMENT_OPTIONS)[keyof typeof SECTION_ALIGNMENT_OPTIONS];
|
|
1070
|
+
type AspectRatioOption = (typeof ASPECT_RATIO_OPTIONS)[keyof typeof ASPECT_RATIO_OPTIONS];
|
|
1071
|
+
type TextAlignmentOption = (typeof TEXT_ALIGNMENT_OPTIONS)[keyof typeof TEXT_ALIGNMENT_OPTIONS];
|
|
1072
|
+
type CardStyleOption = (typeof CARD_STYLE_OPTIONS)[keyof typeof CARD_STYLE_OPTIONS];
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Widget Props Types
|
|
1076
|
+
*
|
|
1077
|
+
* Base prop types that all widgets receive from the page builder.
|
|
1078
|
+
*/
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* Base Widget Props
|
|
1082
|
+
*
|
|
1083
|
+
* All widgets receive these props from the page builder.
|
|
1084
|
+
* Widgets can extend this with their own specific data and settings types.
|
|
1085
|
+
*
|
|
1086
|
+
* @template TData - Type of data the widget receives (default: any)
|
|
1087
|
+
* @template TSettings - Type of settings the widget accepts (default: Record<string, any>)
|
|
1088
|
+
*/
|
|
1089
|
+
interface WidgetProps<TData = any, TSettings = Record<string, any>> {
|
|
1090
|
+
/**
|
|
1091
|
+
* Unique widget instance ID
|
|
1092
|
+
*/
|
|
1093
|
+
id: string;
|
|
1094
|
+
/**
|
|
1095
|
+
* Data fetched from the widget's data source
|
|
1096
|
+
*/
|
|
1097
|
+
data: TData;
|
|
1098
|
+
/**
|
|
1099
|
+
* Widget configuration settings
|
|
1100
|
+
* These come from the template and may include translated values
|
|
1101
|
+
*/
|
|
1102
|
+
settings: TSettings;
|
|
1103
|
+
/**
|
|
1104
|
+
* Current locale
|
|
1105
|
+
*/
|
|
1106
|
+
locale?: Locale;
|
|
1107
|
+
/**
|
|
1108
|
+
* Current route context
|
|
1109
|
+
*/
|
|
1110
|
+
routeContext?: RouteContext;
|
|
1111
|
+
/**
|
|
1112
|
+
* Optional CSS class name for additional styling
|
|
1113
|
+
*/
|
|
1114
|
+
className?: string;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* Default Section Wrapper Component
|
|
1119
|
+
*
|
|
1120
|
+
* A simple default section wrapper used when consumers don't provide
|
|
1121
|
+
* a custom section renderer.
|
|
1122
|
+
*/
|
|
1123
|
+
|
|
1124
|
+
/**
|
|
1125
|
+
* Default Section Wrapper
|
|
1126
|
+
*
|
|
1127
|
+
* Renders a section with responsive spacing and layout constraints.
|
|
1128
|
+
*/
|
|
1129
|
+
declare function DefaultSectionWrapper(section: SectionConfig, children: React.ReactNode[], context: SectionRenderContext): React.ReactNode;
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* File System Preset
|
|
1133
|
+
*
|
|
1134
|
+
* Pre-configured page builder for file-system based theme and template loading.
|
|
1135
|
+
* This preset is fully injectable - all dependencies must be provided by the consumer.
|
|
1136
|
+
*
|
|
1137
|
+
* ## Usage
|
|
1138
|
+
*
|
|
1139
|
+
* ```typescript
|
|
1140
|
+
* import { getPageBuilder } from "@/lib/page-builder/presets";
|
|
1141
|
+
* import { WIDGET_MANIFEST } from "@/widgets/.generated/manifest";
|
|
1142
|
+
* import { getCommerceClient } from "@/lib/data-layer";
|
|
1143
|
+
* import { SectionWrapper } from "@/ui/layout/SectionWrapper";
|
|
1144
|
+
*
|
|
1145
|
+
* // Initialize with required dependencies
|
|
1146
|
+
* const pageBuilder = getPageBuilder({
|
|
1147
|
+
* widgets: WIDGET_MANIFEST,
|
|
1148
|
+
* commerceClient: getCommerceClient(),
|
|
1149
|
+
* sectionRenderer: SectionWrapper,
|
|
1150
|
+
* themeLoader: { loadTheme: async (merchant) => import(`@/themes/${merchant}/theme.json`) },
|
|
1151
|
+
* templateLoader: { loadTemplate: async (merchant, template, variant) => ... },
|
|
1152
|
+
* });
|
|
1153
|
+
*
|
|
1154
|
+
* // Use in page
|
|
1155
|
+
* const content = await pageBuilder.renderPage({
|
|
1156
|
+
* merchantName: "wellversed",
|
|
1157
|
+
* routeContext: { templateName: "home", path: "/", params: {} },
|
|
1158
|
+
* });
|
|
1159
|
+
* ```
|
|
1160
|
+
*/
|
|
1161
|
+
|
|
1162
|
+
/**
|
|
1163
|
+
* Widget registration entry
|
|
1164
|
+
*/
|
|
1165
|
+
interface WidgetEntry {
|
|
1166
|
+
type: string;
|
|
1167
|
+
component: React.ComponentType<any>;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Options for creating a file-system based page builder
|
|
1171
|
+
*
|
|
1172
|
+
* All dependencies are injectable - no external imports are used internally.
|
|
1173
|
+
*/
|
|
1174
|
+
interface FileSystemPresetOptions {
|
|
1175
|
+
/**
|
|
1176
|
+
* Array of widget registrations.
|
|
1177
|
+
* REQUIRED - must be provided by consumer.
|
|
1178
|
+
*
|
|
1179
|
+
* @example
|
|
1180
|
+
* ```typescript
|
|
1181
|
+
* import { WIDGET_MANIFEST } from "@/widgets/.generated/manifest";
|
|
1182
|
+
* getPageBuilder({ widgets: WIDGET_MANIFEST, ... });
|
|
1183
|
+
* ```
|
|
1184
|
+
*/
|
|
1185
|
+
widgets: WidgetEntry[];
|
|
1186
|
+
/**
|
|
1187
|
+
* Commerce client for fetching products/collections.
|
|
1188
|
+
* REQUIRED - must be provided by consumer.
|
|
1189
|
+
*
|
|
1190
|
+
* @example
|
|
1191
|
+
* ```typescript
|
|
1192
|
+
* import { getCommerceClient } from "@/lib/data-layer";
|
|
1193
|
+
* getPageBuilder({ commerceClient: getCommerceClient(), ... });
|
|
1194
|
+
* ```
|
|
1195
|
+
*/
|
|
1196
|
+
commerceClient: ICommerceClient;
|
|
1197
|
+
/**
|
|
1198
|
+
* Theme loader for loading merchant themes.
|
|
1199
|
+
* REQUIRED - must be provided by consumer.
|
|
1200
|
+
*
|
|
1201
|
+
* @example
|
|
1202
|
+
* ```typescript
|
|
1203
|
+
* const themeLoader = {
|
|
1204
|
+
* loadTheme: async (merchant) => {
|
|
1205
|
+
* const mod = await import(`@/themes/${merchant}/theme.json`);
|
|
1206
|
+
* return { id: mod.default.id, name: mod.default.name, ... };
|
|
1207
|
+
* }
|
|
1208
|
+
* };
|
|
1209
|
+
* ```
|
|
1210
|
+
*/
|
|
1211
|
+
themeLoader: IThemeLoader;
|
|
1212
|
+
/**
|
|
1213
|
+
* Template loader for loading page templates.
|
|
1214
|
+
* REQUIRED - must be provided by consumer.
|
|
1215
|
+
*
|
|
1216
|
+
* @example
|
|
1217
|
+
* ```typescript
|
|
1218
|
+
* const templateLoader = {
|
|
1219
|
+
* loadTemplate: async (merchant, template, variant) => {
|
|
1220
|
+
* const mod = await import(`@/themes/${merchant}/templates/${template}/${variant}`);
|
|
1221
|
+
* return mod.template;
|
|
1222
|
+
* },
|
|
1223
|
+
* loadVariantRegistry: async (merchant) => {
|
|
1224
|
+
* try {
|
|
1225
|
+
* return await import(`@/themes/${merchant}/templates/variant-registry`);
|
|
1226
|
+
* } catch { return null; }
|
|
1227
|
+
* }
|
|
1228
|
+
* };
|
|
1229
|
+
* ```
|
|
1230
|
+
*/
|
|
1231
|
+
templateLoader: ITemplateLoader;
|
|
1232
|
+
/**
|
|
1233
|
+
* Custom section renderer function or component.
|
|
1234
|
+
* OPTIONAL - defaults to DefaultSectionWrapper.
|
|
1235
|
+
*
|
|
1236
|
+
* @example
|
|
1237
|
+
* ```typescript
|
|
1238
|
+
* import { SectionWrapper } from "@/ui/layout/SectionWrapper";
|
|
1239
|
+
*
|
|
1240
|
+
* // Wrap component as SectionRenderer function
|
|
1241
|
+
* const sectionRenderer = (section, children, context) =>
|
|
1242
|
+
* React.createElement(SectionWrapper, { section, styles: context.styles, children });
|
|
1243
|
+
* ```
|
|
1244
|
+
*/
|
|
1245
|
+
sectionRenderer?: SectionRenderer;
|
|
1246
|
+
/**
|
|
1247
|
+
* Default locale for translations.
|
|
1248
|
+
* OPTIONAL - defaults to "en".
|
|
1249
|
+
*/
|
|
1250
|
+
defaultLocale?: string;
|
|
1251
|
+
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Creates a new file-system based page builder instance
|
|
1254
|
+
*
|
|
1255
|
+
* Use this when you need a fresh instance (e.g., testing).
|
|
1256
|
+
* For most cases, use `getPageBuilder()` instead.
|
|
1257
|
+
*
|
|
1258
|
+
* @throws Error if required options are missing
|
|
1259
|
+
*/
|
|
1260
|
+
declare function createFileSystemPageBuilder(options: FileSystemPresetOptions): PageBuilder;
|
|
1261
|
+
/**
|
|
1262
|
+
* Gets the singleton page builder instance
|
|
1263
|
+
*
|
|
1264
|
+
* This is the recommended way to get a page builder in production.
|
|
1265
|
+
* The instance is created on first call and reused thereafter.
|
|
1266
|
+
*
|
|
1267
|
+
* NOTE: All dependencies must be provided on first call.
|
|
1268
|
+
* Subsequent calls can omit options (singleton is returned).
|
|
1269
|
+
*
|
|
1270
|
+
* @throws Error if required options are missing on first call
|
|
1271
|
+
*
|
|
1272
|
+
* @example
|
|
1273
|
+
* ```typescript
|
|
1274
|
+
* // First call - provide all dependencies
|
|
1275
|
+
* const pageBuilder = getPageBuilder({
|
|
1276
|
+
* widgets: WIDGET_MANIFEST,
|
|
1277
|
+
* commerceClient: getCommerceClient(),
|
|
1278
|
+
* themeLoader: myThemeLoader,
|
|
1279
|
+
* templateLoader: myTemplateLoader,
|
|
1280
|
+
* });
|
|
1281
|
+
*
|
|
1282
|
+
* // Subsequent calls - singleton returned
|
|
1283
|
+
* const same = getPageBuilder(); // Returns same instance
|
|
1284
|
+
* ```
|
|
1285
|
+
*/
|
|
1286
|
+
declare function getPageBuilder(options?: FileSystemPresetOptions): PageBuilder;
|
|
1287
|
+
/**
|
|
1288
|
+
* Resets the singleton instance
|
|
1289
|
+
*
|
|
1290
|
+
* Useful for testing or when you need to reinitialize with different options.
|
|
1291
|
+
*/
|
|
1292
|
+
declare function resetPageBuilder(): void;
|
|
1293
|
+
/**
|
|
1294
|
+
* Creates a section renderer from a React component
|
|
1295
|
+
*
|
|
1296
|
+
* Utility to wrap a SectionWrapper component as a SectionRenderer function.
|
|
1297
|
+
*
|
|
1298
|
+
* @example
|
|
1299
|
+
* ```typescript
|
|
1300
|
+
* import { SectionWrapper } from "@/ui/layout/SectionWrapper";
|
|
1301
|
+
*
|
|
1302
|
+
* getPageBuilder({
|
|
1303
|
+
* sectionRenderer: createSectionRendererFromComponent(SectionWrapper),
|
|
1304
|
+
* ...
|
|
1305
|
+
* });
|
|
1306
|
+
* ```
|
|
1307
|
+
*/
|
|
1308
|
+
declare function createSectionRendererFromComponent(Component: React.ComponentType<{
|
|
1309
|
+
section: SectionConfig;
|
|
1310
|
+
styles: Record<string, any>;
|
|
1311
|
+
children: React.ReactNode[];
|
|
1312
|
+
}>): SectionRenderer;
|
|
1313
|
+
/**
|
|
1314
|
+
* Creates a commerce client adapter
|
|
1315
|
+
*
|
|
1316
|
+
* Wraps an existing client to ensure it matches the ICommerceClient interface.
|
|
1317
|
+
*
|
|
1318
|
+
* @example
|
|
1319
|
+
* ```typescript
|
|
1320
|
+
* import { shopifyClient } from "@/lib/shopify";
|
|
1321
|
+
*
|
|
1322
|
+
* getPageBuilder({
|
|
1323
|
+
* commerceClient: createCommerceClientAdapter(shopifyClient),
|
|
1324
|
+
* ...
|
|
1325
|
+
* });
|
|
1326
|
+
* ```
|
|
1327
|
+
*/
|
|
1328
|
+
declare function createCommerceClientAdapter(client: {
|
|
1329
|
+
getProduct: (params: any) => Promise<any>;
|
|
1330
|
+
getProducts: (params: any) => Promise<any>;
|
|
1331
|
+
getProductRecommendations: (id: string) => Promise<any>;
|
|
1332
|
+
getCollection: (params: any) => Promise<any>;
|
|
1333
|
+
getCollections: (params: any) => Promise<any>;
|
|
1334
|
+
getCollectionWithFilters?: (params: any) => Promise<any>;
|
|
1335
|
+
getCollectionsByHandler?: (params: any) => Promise<any>;
|
|
1336
|
+
}): ICommerceClient;
|
|
1337
|
+
|
|
1338
|
+
export { ASPECT_RATIO_OPTIONS, type AspectRatioOption, type Breakpoint, type BreakpointConfig, CARD_STYLE_OPTIONS, type CardStyleOption, DATA_SOURCE_TYPES, DEFAULT_BREAKPOINTS, DEFAULT_LOCALE, type DataSourceConfig, type DataSourceType, DefaultSectionWrapper, type FileSystemPresetOptions, type ICommerceClient, type ITemplateLoader, type IThemeLoader, type IWidgetRegistry, type Locale, type PageBuilder, type PageBuilderOptions, type PageConfig, PageConfigHelpers, type RenderPageParams, type ResponsiveSpacing, type RouteContext, SECTION_ALIGNMENT_OPTIONS, SECTION_LAYOUT_OPTIONS, SECTION_TYPES, type SectionAlignmentOption, type SectionConfig, type SectionLayoutOption, type SectionRegistry, type SectionRenderContext, type SectionRenderer, type SectionSchema, type SectionSettings, type SectionType, type Spacing, TEXT_ALIGNMENT_OPTIONS, type Template, type TemplateVariantRegistry, type TextAlignmentOption, type Theme, type ThemeConfig, type ThemeRole, type ValidationResult, type VariantRegistryResult, type ViewportInfo, type WidgetConfig, type WidgetEntry, type WidgetProps, WidgetRegistry, type WidgetResponsiveConfig, type WidgetSchema, type WidgetSchemaRegistry, createCommerceClientAdapter, createFileSystemPageBuilder, createPageBuilder, createSectionRendererFromComponent, getPageBuilder, resetPageBuilder };
|