npm package: @shopkit/builder
Description: Page builder for creating dynamic storefronts with configurable widgets and layouts
Latest version: 0.1.3

# @shopkit/builder

Configuration-driven page builder for creating dynamic storefronts with widgets and layouts.

## Features

- **Configuration-Driven**: Define pages with JSON configuration (PageConfig)
- **Widget System**: Modular, reusable widget components
- **Data Sources**: Automatic data fetching from commerce backends
- **Responsive Design**: Built-in breakpoint system for responsive layouts
- **Theme Integration**: Seamless integration with `@shopkit/core` theme system
- **SSR Support**: Full server-side rendering compatibility with Next.js

## Installation

```bash
npm install @shopkit/builder
# or
bun add @shopkit/builder
```

### Peer Dependencies

```bash
npm install react react-dom next
```

## Quick Start

```typescript
import { createPageBuilder, WidgetRegistry, DATA_SOURCE_TYPES } from '@shopkit/builder';

// 1. Create widget registry
const widgetRegistry = new WidgetRegistry();
widgetRegistry.register('hero', HeroWidget);
widgetRegistry.register('product-grid', ProductGridWidget);

// 2. Create page builder
const pageBuilder = createPageBuilder({
  widgets: widgetRegistry,
  commerceClient: myShopifyClient,
  themeLoader: myThemeLoader,
  templateLoader: myTemplateLoader,
});

// 3. Render a page
const content = await pageBuilder.renderPage({
  merchantName: 'my-store',
  routeContext: { templateName: 'home', path: '/' },
});
```

## Core Concepts

### PageConfig

The central configuration object that defines a page's structure:

```typescript
import type { PageConfig, SectionConfig, WidgetConfig } from '@shopkit/builder';

const homePageConfig: PageConfig = {
  id: 'home',
  name: 'Home Page',
  dataSources: {
    featuredProducts: {
      type: DATA_SOURCE_TYPES.PRODUCTS,
      params: { first: 8 },
      required: true,
    },
  },
  sections: [
    {
      id: 'hero-section',
      name: 'Hero',
      settings: { layout: 'full', padding: { top: '0', bottom: '0' } },
      widgets: [
        {
          id: 'hero-1',
          type: 'hero',
          settings: {
            title: 'Welcome to Our Store',
            subtitle: 'Discover amazing products',
            ctaText: 'Shop Now',
            ctaLink: '/collections/all',
          },
        },
      ],
    },
    {
      id: 'products-section',
      name: 'Featured Products',
      settings: { layout: 'page' },
      widgets: [
        {
          id: 'products-1',
          type: 'product-grid',
          dataSourceKey: 'featuredProducts',
          settings: { columns: 4 },
        },
      ],
    },
  ],
};
```

### Data Source Types

Built-in data source types for fetching commerce data:

```typescript
import { DATA_SOURCE_TYPES } from '@shopkit/builder';

// Available types:
DATA_SOURCE_TYPES.PRODUCT                    // Single product by handle/ID
DATA_SOURCE_TYPES.PRODUCTS                   // Multiple products with pagination
DATA_SOURCE_TYPES.PRODUCTS_BY_HANDLES        // Products by specific handles
DATA_SOURCE_TYPES.COLLECTION                 // Single collection
DATA_SOURCE_TYPES.COLLECTIONS                // Multiple collections
DATA_SOURCE_TYPES.COLLECTION_PAGE_WITH_FILTERS  // Collection with faceted filters
DATA_SOURCE_TYPES.PRODUCT_RECOMMENDATIONS    // Product recommendations
DATA_SOURCE_TYPES.STATIC                     // Static data (no fetching)
```

### Widget Registry

Register widgets for use in page configurations:

```typescript
import { WidgetRegistry } from '@shopkit/builder';

const registry = new WidgetRegistry();

// Register a widget
registry.register('product-card', ProductCardWidget);

// Check if widget exists
registry.has('product-card'); // true

// Get a widget
const Widget = registry.get('product-card');
```

## Interfaces

The builder uses dependency injection. Implement these interfaces for your commerce platform:

### ICommerceClient

```typescript
import type { ICommerceClient } from '@shopkit/builder';

const shopifyClient: ICommerceClient = {
  getProduct: async (handle) => { /* ... */ },
  getProducts: async (params) => { /* ... */ },
  getCollection: async (handle) => { /* ... */ },
  getCollections: async (params) => { /* ... */ },
  // ...
};
```

### IThemeLoader

```typescript
import type { IThemeLoader } from '@shopkit/builder';

const themeLoader: IThemeLoader = {
  loadTheme: async (merchantName, role) => { /* ... */ },
};
```

### ITemplateLoader

```typescript
import type { ITemplateLoader } from '@shopkit/builder';

const templateLoader: ITemplateLoader = {
  loadTemplate: async (merchantName, templateName) => { /* ... */ },
  listTemplates: async (merchantName) => { /* ... */ },
};
```

## Presets

Use presets for common configurations:

### File System Preset

```typescript
import { createFileSystemPageBuilder } from '@shopkit/builder';

const pageBuilder = await createFileSystemPageBuilder({
  basePath: './src/themes',
  widgets: myWidgetRegistry,
  commerceClient: myCommerceClient,
});
```

## Subpath Exports

```typescript
// Main exports
import { createPageBuilder, PageConfig, WidgetRegistry } from '@shopkit/builder';

// React hooks
import { usePageBuilder } from '@shopkit/builder/hooks';
```

## Type Reference

### PageConfig

```typescript
interface PageConfig {
  id: string;
  name: string;
  dataSources?: Record<string, DataSourceConfig>;
  sections: SectionConfig[];
}
```

### SectionConfig

```typescript
interface SectionConfig {
  id: string;
  name: string;
  settings: SectionSettings;
  widgets: WidgetConfig[];
}
```

### WidgetConfig

```typescript
interface WidgetConfig {
  id: string;
  type: string;
  settings: Record<string, unknown>;
  dataSourceKey?: string;
  responsive?: WidgetResponsiveConfig;
}
```

### DataSourceConfig

```typescript
interface DataSourceConfig {
  type: DataSourceType | string;
  params: Record<string, any>;
  required: boolean;
}
```

## Layout Options

Built-in layout constants:

```typescript
import {
  SECTION_TYPES,
  SECTION_LAYOUT_OPTIONS,
  SECTION_ALIGNMENT_OPTIONS,
  ASPECT_RATIO_OPTIONS,
  TEXT_ALIGNMENT_OPTIONS,
  CARD_STYLE_OPTIONS,
} from '@shopkit/builder';
```

## Responsive Breakpoints

Default breakpoints for responsive design:

```typescript
import { DEFAULT_BREAKPOINTS } from '@shopkit/builder';

// { sm: 640, md: 768, lg: 1024, xl: 1280, '2xl': 1536 }
```

## Integration with @shopkit/core

The builder integrates seamlessly with the theme system:

```typescript
import { createPageBuilder } from '@shopkit/builder';
import { createThemeRegistry } from '@shopkit/core/theme';

const themeRegistry = createThemeRegistry({
  basePath: './src/themes',
});

const pageBuilder = createPageBuilder({
  widgets: widgetRegistry,
  commerceClient: shopifyClient,
  themeLoader: themeRegistry,
  templateLoader: templateLoader,
});
```

## License

MIT