@liquidcommerce/elements-sdk 2.6.0-beta.38 → 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.
- package/README.md +156 -2731
- package/dist/index.checkout.esm.js +6747 -6747
- package/dist/index.esm.js +10658 -10658
- package/docs/actions.md +320 -0
- package/docs/address.md +242 -0
- package/docs/cart.md +387 -0
- package/docs/checkout.md +420 -0
- package/docs/{CONFIGURATION.md → configuration.md} +34 -14
- package/docs/events.md +181 -0
- package/docs/product-list.md +311 -0
- package/docs/product.md +250 -0
- package/docs/{THEMING.md → theming.md} +3 -2
- package/docs/{TROUBLESHOOTING.md → troubleshooting.md} +6 -6
- package/package.json +1 -1
- package/docs/ACTIONS.md +0 -1301
- package/docs/DOCUMENTATION_INDEX.md +0 -319
- package/docs/EVENTS.md +0 -798
- /package/docs/{BROWSER_SUPPORT.md → browser-support.md} +0 -0
- /package/docs/{PROXY.md → proxy.md} +0 -0
package/docs/events.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Events
|
|
2
|
+
|
|
3
|
+
Events tell you what's happening in real-time: when products load, items get added to cart, checkout completes, and more. Use them to trigger analytics, show custom notifications, sync with your backend, or build reactive UI.
|
|
4
|
+
|
|
5
|
+
## Subscribing to Events
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
window.addEventListener('lce:actions.EVENT_NAME', (event) => {
|
|
9
|
+
const data = event.detail.data;
|
|
10
|
+
const metadata = event.detail.metadata;
|
|
11
|
+
});
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Event Metadata
|
|
15
|
+
|
|
16
|
+
Every event includes metadata:
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
{
|
|
20
|
+
eventId: string, // Unique event ID
|
|
21
|
+
namespace: 'actions', // Event namespace
|
|
22
|
+
event: string, // Event name
|
|
23
|
+
originalEvent: string, // Full namespaced event
|
|
24
|
+
actionNamespace?: string, // 'address' | 'product' | 'cart' | 'checkout'
|
|
25
|
+
timestamp: number // Unix timestamp
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Lifecycle Events
|
|
32
|
+
|
|
33
|
+
| Event | Description |
|
|
34
|
+
|-------|-------------|
|
|
35
|
+
| `client_ready` | SDK initialized and ready to use |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Product Events
|
|
40
|
+
|
|
41
|
+
| Event | Description |
|
|
42
|
+
|-------|-------------|
|
|
43
|
+
| `product_loaded` | Product data fetched and displayed |
|
|
44
|
+
| `product_add_to_cart` | Customer added product to cart |
|
|
45
|
+
| `product_quantity_increase` | Quantity increased on product |
|
|
46
|
+
| `product_quantity_decrease` | Quantity decreased on product |
|
|
47
|
+
| `product_size_changed` | Size/variant selection changed |
|
|
48
|
+
| `product_fulfillment_type_changed` | Shipping/on-demand type changed |
|
|
49
|
+
| `product_fulfillment_changed` | Specific retailer/fulfillment changed |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Address Events
|
|
54
|
+
|
|
55
|
+
| Event | Description |
|
|
56
|
+
|-------|-------------|
|
|
57
|
+
| `address_updated` | Delivery location set or changed |
|
|
58
|
+
| `address_cleared` | Delivery location removed |
|
|
59
|
+
| `address_failed` | Address operation failed |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Cart Events
|
|
64
|
+
|
|
65
|
+
| Event | Description |
|
|
66
|
+
|-------|-------------|
|
|
67
|
+
| `cart_loaded` | Cart data fetched and ready |
|
|
68
|
+
| `cart_opened` | Cart drawer opened |
|
|
69
|
+
| `cart_closed` | Cart drawer closed |
|
|
70
|
+
| `cart_updated` | Cart items or totals changed |
|
|
71
|
+
| `cart_reset` | Cart cleared completely |
|
|
72
|
+
| `cart_failed` | Cart operation failed |
|
|
73
|
+
| `cart_item_added` | Item added to cart |
|
|
74
|
+
| `cart_item_removed` | Item removed from cart |
|
|
75
|
+
| `cart_item_quantity_increase` | Item quantity increased |
|
|
76
|
+
| `cart_item_quantity_decrease` | Item quantity decreased |
|
|
77
|
+
| `cart_item_engraving_updated` | Personalization added/changed/removed |
|
|
78
|
+
| `cart_product_add_success` | Programmatic add succeeded |
|
|
79
|
+
| `cart_product_add_failed` | Programmatic add failed |
|
|
80
|
+
| `cart_promo_code_applied` | Discount code applied |
|
|
81
|
+
| `cart_promo_code_removed` | Discount code removed |
|
|
82
|
+
| `cart_promo_code_failed` | Discount code rejected |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Checkout Events
|
|
87
|
+
|
|
88
|
+
### Lifecycle
|
|
89
|
+
|
|
90
|
+
| Event | Description |
|
|
91
|
+
|-------|-------------|
|
|
92
|
+
| `checkout_loaded` | Checkout ready |
|
|
93
|
+
| `checkout_opened` | Checkout drawer opened |
|
|
94
|
+
| `checkout_closed` | Checkout drawer closed |
|
|
95
|
+
| `checkout_failed` | Checkout operation failed |
|
|
96
|
+
|
|
97
|
+
### Submit
|
|
98
|
+
|
|
99
|
+
| Event | Description |
|
|
100
|
+
|-------|-------------|
|
|
101
|
+
| `checkout_submit_started` | Payment processing started |
|
|
102
|
+
| `checkout_submit_completed` | Order successfully placed |
|
|
103
|
+
| `checkout_submit_failed` | Order submission failed |
|
|
104
|
+
|
|
105
|
+
### Form Updates
|
|
106
|
+
|
|
107
|
+
| Event | Description |
|
|
108
|
+
|-------|-------------|
|
|
109
|
+
| `checkout_customer_information_updated` | Customer form completed |
|
|
110
|
+
| `checkout_billing_information_updated` | Billing form completed |
|
|
111
|
+
| `checkout_gift_information_updated` | Gift form completed |
|
|
112
|
+
| `checkout_is_gift_toggled` | Gift option toggled |
|
|
113
|
+
| `checkout_billing_same_as_shipping_toggled` | Billing address option toggled |
|
|
114
|
+
| `checkout_marketing_preferences_toggled` | Email/SMS opt-in toggled |
|
|
115
|
+
|
|
116
|
+
### Item Changes
|
|
117
|
+
|
|
118
|
+
| Event | Description |
|
|
119
|
+
|-------|-------------|
|
|
120
|
+
| `checkout_item_removed` | Item removed from checkout |
|
|
121
|
+
| `checkout_item_quantity_increase` | Item quantity increased |
|
|
122
|
+
| `checkout_item_quantity_decrease` | Item quantity decreased |
|
|
123
|
+
| `checkout_item_engraving_updated` | Personalization changed |
|
|
124
|
+
| `checkout_tip_updated` | Delivery tip changed |
|
|
125
|
+
|
|
126
|
+
### Discounts
|
|
127
|
+
|
|
128
|
+
| Event | Description |
|
|
129
|
+
|-------|-------------|
|
|
130
|
+
| `checkout_product_add_success` | Programmatic add succeeded |
|
|
131
|
+
| `checkout_product_add_failed` | Programmatic add failed |
|
|
132
|
+
| `checkout_promo_code_applied` | Discount applied |
|
|
133
|
+
| `checkout_promo_code_removed` | Discount removed |
|
|
134
|
+
| `checkout_promo_code_failed` | Discount rejected |
|
|
135
|
+
| `checkout_gift_card_applied` | Gift card applied |
|
|
136
|
+
| `checkout_gift_card_removed` | Gift card removed |
|
|
137
|
+
| `checkout_gift_card_failed` | Gift card rejected |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Listening to All Events
|
|
142
|
+
|
|
143
|
+
Catch all action events with a namespace listener:
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
// All action events
|
|
147
|
+
window.addEventListener('lce:actions', (event) => {
|
|
148
|
+
const eventName = event.detail.metadata.event;
|
|
149
|
+
console.log('Event fired:', eventName);
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Security Notes
|
|
156
|
+
|
|
157
|
+
Events are designed with security in mind:
|
|
158
|
+
|
|
159
|
+
**Included in events:**
|
|
160
|
+
- Success/failure status
|
|
161
|
+
- Discount amounts (visible in UI)
|
|
162
|
+
- Total amounts (visible in UI)
|
|
163
|
+
- Item counts and identifiers
|
|
164
|
+
|
|
165
|
+
**Never included:**
|
|
166
|
+
- Promo codes or gift card codes
|
|
167
|
+
- Gift card balances
|
|
168
|
+
- Customer names, emails, addresses
|
|
169
|
+
- Payment information
|
|
170
|
+
|
|
171
|
+
Form update events (like `checkout_customer_information_updated`) only indicate completion, not actual customer data.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## See Also
|
|
176
|
+
|
|
177
|
+
- [Actions Reference](./actions.md) - Programmatic control
|
|
178
|
+
- [Product](./product.md) - Product component
|
|
179
|
+
- [Cart](./cart.md) - Cart component
|
|
180
|
+
- [Checkout](./checkout.md) - Checkout component
|
|
181
|
+
- [Address](./address.md) - Address component
|
|
@@ -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
|