@liquidcommerce/elements-sdk 2.6.0-beta.37 → 2.6.0-beta.39

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.
@@ -0,0 +1,311 @@
1
+ # Product List
2
+
3
+ The product list component displays a filterable, searchable grid of products with infinite scroll pagination. Ideal for category pages, search results, and "shop all" experiences where customers browse and discover products.
4
+
5
+ ## Overview
6
+
7
+ The product list element provides:
8
+ - Responsive product grid layout
9
+ - Rich filtering (14 filter types)
10
+ - Search functionality
11
+ - Infinite scroll pagination
12
+ - Address-aware inventory (reloads on location change)
13
+ - Add to cart from product cards
14
+ - Product links with tracking
15
+ - Automatic GTM integration
16
+
17
+ Clicking a product can open a modal/drawer or navigate to a detail page - your choice.
18
+
19
+ ---
20
+
21
+ ## Declarative Setup (HTML Attributes)
22
+
23
+ Add a product list to any page with data attributes.
24
+
25
+ ### Basic Setup
26
+
27
+ ```html
28
+ <div data-liquid-commerce-elements-products-list
29
+ data-rows="3"
30
+ data-columns="4"
31
+ data-filters="price,brands,categories"
32
+ data-product-url="/product/{upc}">
33
+ </div>
34
+
35
+ <script
36
+ defer
37
+ type="text/javascript"
38
+ data-liquid-commerce-elements
39
+ data-token="YOUR_API_KEY"
40
+ data-env="production"
41
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
42
+ ></script>
43
+ ```
44
+
45
+ ### Configuration Attributes
46
+
47
+ | Attribute | Type | Default | Description |
48
+ |-----------|------|---------|-------------|
49
+ | `data-liquid-commerce-elements-products-list` | - | - | Enables product list |
50
+ | `data-rows` | 1-10 | 3 | Number of rows per page |
51
+ | `data-columns` | 1-4 | 4 | Number of columns in grid |
52
+ | `data-filters` | string | - | Comma-separated filter types |
53
+ | `data-product-url` | string | - | Product page URL template |
54
+
55
+ ### Product URL Template
56
+
57
+ Use `{upc}` or `{grouping}` as placeholders:
58
+
59
+ ```html
60
+ <!-- Using UPC -->
61
+ <div data-product-url="/product/{upc}" ...></div>
62
+
63
+ <!-- Using Salsify grouping -->
64
+ <div data-product-url="/products/{grouping}" ...></div>
65
+ ```
66
+
67
+ ### Available Filters
68
+
69
+ | Filter | Description |
70
+ |--------|-------------|
71
+ | `engraving` | Engravable/personalizable products |
72
+ | `presale` | Pre-order products |
73
+ | `fulfillment` | Delivery type (shipping, on-demand) |
74
+ | `price` | Price range slider |
75
+ | `brands` | Brand multi-select |
76
+ | `categories` | Category multi-select |
77
+ | `flavor` | Flavor profiles |
78
+ | `region` | Geographic regions |
79
+ | `variety` | Product varieties |
80
+ | `vintage` | Vintage years |
81
+ | `country` | Country of origin |
82
+ | `appellation` | Wine appellations |
83
+ | `materials` | Product materials |
84
+ | `sizes` | Size options |
85
+
86
+ ### Separate Search and Filters
87
+
88
+ Place search and filters in different containers:
89
+
90
+ ```html
91
+ <div id="search-bar"></div>
92
+ <div id="filter-sidebar"></div>
93
+ <div id="product-grid" data-liquid-commerce-elements-products-list
94
+ data-search-container="search-bar"
95
+ data-filters-container="filter-sidebar"
96
+ data-rows="4"
97
+ data-columns="3"
98
+ data-filters="price,brands,categories,variety">
99
+ </div>
100
+ ```
101
+
102
+ | Attribute | Description |
103
+ |-----------|-------------|
104
+ | `data-search-container` | Container ID for search input |
105
+ | `data-filters-container` | Container ID for filter panel |
106
+
107
+ ---
108
+
109
+ ## Programmatic Setup (JavaScript API)
110
+
111
+ Inject product list components programmatically.
112
+
113
+ ### Product List Grid
114
+
115
+ ```javascript
116
+ const client = await Elements('YOUR_API_KEY', { env: 'production' });
117
+
118
+ await client.injectProductList({
119
+ containerId: 'product-list-container',
120
+ rows: 3,
121
+ columns: 4,
122
+ filters: ['price', 'brands', 'categories', 'variety'],
123
+ productUrl: '/product/{upc}'
124
+ });
125
+ ```
126
+
127
+ ### Parameters
128
+
129
+ | Parameter | Type | Required | Description |
130
+ |-----------|------|----------|-------------|
131
+ | `containerId` | string | Yes | Container element ID |
132
+ | `rows` | number | No | Rows per page (1-10, default: 3) |
133
+ | `columns` | number | No | Columns in grid (1-4, default: 4) |
134
+ | `filters` | string[] | No | Filter types to enable |
135
+ | `productUrl` | string | No | Product page URL template |
136
+
137
+ ### Search Component
138
+
139
+ Inject a standalone search input:
140
+
141
+ ```javascript
142
+ await client.injectProductListSearch({
143
+ containerId: 'search-container'
144
+ });
145
+ ```
146
+
147
+ ### Filters Component
148
+
149
+ Inject a standalone filter panel:
150
+
151
+ ```javascript
152
+ await client.injectProductListFilters({
153
+ containerId: 'filters-container',
154
+ filters: ['price', 'brands', 'categories', 'variety']
155
+ });
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Actions
161
+
162
+ Product list-specific actions are coming soon. For now, individual products in the list use standard [product actions](./actions.md#product-actions).
163
+
164
+ ---
165
+
166
+ ## Events
167
+
168
+ The product list emits standard product events for interactions with individual items.
169
+
170
+ ### Product Events in List
171
+
172
+ When customers interact with products in the list, these events fire:
173
+
174
+ | Event | Description |
175
+ |-------|-------------|
176
+ | `product_loaded` | Product card data fetched |
177
+ | `product_add_to_cart` | Item added from product card |
178
+
179
+ ### GTM Events
180
+
181
+ The product list automatically tracks:
182
+
183
+ | GTM Event | Trigger |
184
+ |-----------|---------|
185
+ | `view_item_list` | Products displayed |
186
+ | `select_item` | Product clicked |
187
+ | `add_to_cart` | Added from card |
188
+
189
+ ### Example: Track Product Clicks
190
+
191
+ ```javascript
192
+ window.addEventListener('lce:actions.product_loaded', (event) => {
193
+ // A product in the list was loaded
194
+ const { name, brand, identifier } = event.detail.data;
195
+ console.log('Product displayed:', name);
196
+ });
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Features
202
+
203
+ ### Infinite Scroll
204
+
205
+ Products load automatically as customers scroll. No pagination buttons needed.
206
+
207
+ ### Smart Filters
208
+
209
+ Filters show only relevant options based on current inventory. If no products match a filter option, it's hidden.
210
+
211
+ ### Address-Aware
212
+
213
+ The product list automatically reloads when the customer changes their delivery address, showing:
214
+ - Updated availability
215
+ - Location-specific pricing
216
+ - Relevant fulfillment options
217
+
218
+ ### Loading States
219
+
220
+ The component shows skeleton loading states while fetching products, providing smooth user experience.
221
+
222
+ ---
223
+
224
+ ## Use Cases
225
+
226
+ ### Category Page
227
+
228
+ ```html
229
+ <div class="page-layout">
230
+ <aside id="sidebar-filters"></aside>
231
+ <main>
232
+ <div id="search-area"></div>
233
+ <div id="products"
234
+ data-liquid-commerce-elements-products-list
235
+ data-search-container="search-area"
236
+ data-filters-container="sidebar-filters"
237
+ data-rows="4"
238
+ data-columns="3"
239
+ data-filters="price,brands,categories,flavor,variety"
240
+ data-product-url="/shop/{grouping}">
241
+ </div>
242
+ </main>
243
+ </div>
244
+ ```
245
+
246
+ ### Simple Product Grid
247
+
248
+ ```html
249
+ <div data-liquid-commerce-elements-products-list
250
+ data-rows="2"
251
+ data-columns="4"
252
+ data-product-url="/product/{upc}">
253
+ </div>
254
+ ```
255
+
256
+ No filters, just a browsable product grid.
257
+
258
+ ### Search Results Page
259
+
260
+ ```javascript
261
+ await client.injectProductList({
262
+ containerId: 'search-results',
263
+ rows: 5,
264
+ columns: 4,
265
+ filters: ['fulfillment', 'price', 'brands'],
266
+ productUrl: '/product/{upc}'
267
+ });
268
+
269
+ await client.injectProductListSearch({
270
+ containerId: 'search-box'
271
+ });
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Customization
277
+
278
+ Style the product list through theme configuration.
279
+
280
+ ```javascript
281
+ const client = await Elements('YOUR_API_KEY', {
282
+ customTheme: {
283
+ // Product card styling applies to list items
284
+ product: {
285
+ // Theme options
286
+ }
287
+ }
288
+ });
289
+ ```
290
+
291
+ ### Display Modes
292
+
293
+ Product cards in the list can open in:
294
+ - **Modal** - Product details overlay
295
+ - **Drawer** - Slide-out panel
296
+ - **Navigate** - Go to product page (via `productUrl`)
297
+
298
+ See [theming.md](./theming.md) for product list theme options including:
299
+ - Card layout
300
+ - Grid spacing
301
+ - Filter panel styling
302
+ - Display mode configuration
303
+
304
+ ---
305
+
306
+ ## See Also
307
+
308
+ - [Product](./product.md) - Individual product component
309
+ - [Actions Reference](./actions.md) - All available actions
310
+ - [Events Reference](./events.md) - All available events
311
+ - [Theming Guide](./theming.md) - Customization options
@@ -0,0 +1,250 @@
1
+ # Product
2
+
3
+ The product element is the heart of the SDK - it displays product information, handles size and variant selection, shows real-time pricing based on delivery location, and lets customers add items to their cart.
4
+
5
+ ## Overview
6
+
7
+ The product element renders a complete product card with:
8
+ - Product imagery and details
9
+ - Size/variant selection
10
+ - Real-time pricing based on delivery address
11
+ - Fulfillment options (shipping vs on-demand delivery)
12
+ - Quantity controls
13
+ - Add to cart functionality
14
+ - Personalization/engraving options (when available)
15
+
16
+ The component automatically adapts to the customer's delivery address, showing only available fulfillment options and location-specific pricing.
17
+
18
+ ---
19
+
20
+ ## Declarative Setup (HTML Attributes)
21
+
22
+ Add products to your page without writing JavaScript. Choose the method that fits your use case.
23
+
24
+ ### Method 1: Direct Attributes
25
+
26
+ Best for static pages with known products. Add products directly in the script tag:
27
+
28
+ ```html
29
+ <div id="product-1"></div>
30
+ <div id="product-2"></div>
31
+
32
+ <script
33
+ defer
34
+ type="text/javascript"
35
+ data-liquid-commerce-elements
36
+ data-token="YOUR_API_KEY"
37
+ data-env="production"
38
+ data-container-1="product-1"
39
+ data-product-1="00619947000020"
40
+ data-container-2="product-2"
41
+ data-product-2="00832889005513"
42
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
43
+ ></script>
44
+ ```
45
+
46
+ The pattern is `data-container-N` paired with `data-product-N` where N is any number.
47
+
48
+ ### Method 2: JSON Configuration
49
+
50
+ Best for CMS platforms and dynamic content. Configure products via a JSON script block:
51
+
52
+ ```html
53
+ <div id="product-1"></div>
54
+ <div id="product-2"></div>
55
+
56
+ <script data-liquid-commerce-elements-products type="application/json">
57
+ [
58
+ { "containerId": "product-1", "identifier": "00619947000020" },
59
+ { "containerId": "product-2", "identifier": "00832889005513" }
60
+ ]
61
+ </script>
62
+
63
+ <script
64
+ defer
65
+ type="text/javascript"
66
+ data-liquid-commerce-elements
67
+ data-token="YOUR_API_KEY"
68
+ data-env="production"
69
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
70
+ ></script>
71
+ ```
72
+
73
+ This approach works well with templating engines and server-side rendering.
74
+
75
+ ### Method 3: Annotated Elements
76
+
77
+ Best for product grids and lists. Mark any div with a data attribute:
78
+
79
+ ```html
80
+ <div class="product-grid">
81
+ <div data-lce-product="00619947000020"></div>
82
+ <div data-lce-product="00832889005513"></div>
83
+ <div data-lce-product="00851468007252"></div>
84
+ </div>
85
+
86
+ <script
87
+ defer
88
+ type="text/javascript"
89
+ data-liquid-commerce-elements
90
+ data-token="YOUR_API_KEY"
91
+ data-env="production"
92
+ src="https://assets-elements.liquidcommerce.us/all/elements.js"
93
+ ></script>
94
+ ```
95
+
96
+ The SDK automatically finds and initializes all elements with `data-lce-product`.
97
+
98
+ ---
99
+
100
+ ## Programmatic Setup (JavaScript API)
101
+
102
+ For full control, inject products using the client API.
103
+
104
+ ### Basic Injection
105
+
106
+ ```javascript
107
+ const client = await Elements('YOUR_API_KEY', { env: 'production' });
108
+
109
+ const components = await client.injectProductElement([
110
+ { containerId: 'pdp-1', identifier: '00619947000020' },
111
+ { containerId: 'pdp-2', identifier: '00832889005513' }
112
+ ]);
113
+ ```
114
+
115
+ ### Parameters
116
+
117
+ | Parameter | Type | Required | Description |
118
+ |-----------|------|----------|-------------|
119
+ | `containerId` | string | Yes | ID of the container element |
120
+ | `identifier` | string | Yes | Product UPC, ID, or Salsify grouping ID |
121
+
122
+ ### Return Value
123
+
124
+ Returns `IInjectedComponent[]` - an array of component wrappers with these methods:
125
+
126
+ ```javascript
127
+ // Get the container element
128
+ const element = components[0].getElement();
129
+
130
+ // Get the component type
131
+ const type = components[0].getType(); // 'product'
132
+
133
+ // Force a re-render
134
+ components[0].rerender();
135
+ ```
136
+
137
+ ### Dynamic Product Loading
138
+
139
+ Load products dynamically based on user actions:
140
+
141
+ ```javascript
142
+ // Load product when user clicks a button
143
+ document.querySelector('#load-product').addEventListener('click', async () => {
144
+ await client.injectProductElement([
145
+ { containerId: 'dynamic-product', identifier: selectedProductId }
146
+ ]);
147
+ });
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Actions
153
+
154
+ Control and query product state programmatically.
155
+
156
+ ### Get Product Details
157
+
158
+ Retrieve the current state of a displayed product:
159
+
160
+ ```javascript
161
+ const details = window.elements.actions.product.getDetails('00619947000020');
162
+
163
+ // Returns product data including:
164
+ // - name, brand, category
165
+ // - selectedSizeId, selectedFulfillmentType
166
+ // - availability status
167
+ // - pricing information
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Events
173
+
174
+ Listen to product interactions and state changes.
175
+
176
+ ### Subscribing to Events
177
+
178
+ ```javascript
179
+ window.addEventListener('lce:actions.product_loaded', (event) => {
180
+ const { data, metadata } = event.detail;
181
+ console.log('Product loaded:', data.name);
182
+ });
183
+ ```
184
+
185
+ ### Available Events
186
+
187
+ | Event | Description | Key Data |
188
+ |-------|-------------|----------|
189
+ | `product_loaded` | Product data fetched and displayed | Full product details |
190
+ | `product_add_to_cart` | Customer added product to cart | identifier, fulfillmentId, quantity |
191
+ | `product_quantity_increase` | Quantity increased | identifier, quantity, previousQuantity |
192
+ | `product_quantity_decrease` | Quantity decreased | identifier, quantity, previousQuantity |
193
+ | `product_size_changed` | Size selection changed | identifier, selectedSizeId, previousSizeId |
194
+ | `product_fulfillment_type_changed` | Shipping/on-demand changed | identifier, selectedFulfillmentType |
195
+ | `product_fulfillment_changed` | Retailer selection changed | identifier, selectedFulfillmentId |
196
+
197
+ ### Example: Track Add to Cart
198
+
199
+ ```javascript
200
+ window.addEventListener('lce:actions.product_add_to_cart', (event) => {
201
+ const { identifier, quantity, fulfillmentId } = event.detail.data;
202
+
203
+ // Send to analytics
204
+ analytics.track('Product Added', {
205
+ productId: identifier,
206
+ quantity: quantity,
207
+ fulfillment: fulfillmentId
208
+ });
209
+ });
210
+ ```
211
+
212
+ ---
213
+
214
+ ## Customization
215
+
216
+ Style product components through the theme configuration.
217
+
218
+ ### Basic Theming
219
+
220
+ ```javascript
221
+ const client = await Elements('YOUR_API_KEY', {
222
+ customTheme: {
223
+ global: {
224
+ theme: {
225
+ primaryColor: '#007bff',
226
+ buttonCornerRadius: '8px'
227
+ }
228
+ },
229
+ product: {
230
+ // Product-specific theme options
231
+ }
232
+ }
233
+ });
234
+ ```
235
+
236
+ ### Product Theme Options
237
+
238
+ See [theming.md](./theming.md) for the complete list of product theme options including:
239
+ - Layout configuration
240
+ - Color overrides
241
+ - Typography settings
242
+ - Spacing and sizing
243
+
244
+ ---
245
+
246
+ ## See Also
247
+
248
+ - [Actions Reference](./actions.md) - All available actions
249
+ - [Events Reference](./events.md) - All available events
250
+ - [Theming Guide](./theming.md) - Customization options