@shopkit/cart 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/CHANGELOG.md +58 -0
- package/README.md +216 -0
- package/dist/index.d.mts +730 -0
- package/dist/index.d.ts +730 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -0
- package/package.json +60 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2024-02-11
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release of `@shopkit/cart` package
|
|
13
|
+
- **Core Store** (`store.ts`)
|
|
14
|
+
- Zustand-based cart state management
|
|
15
|
+
- `configureCart()` for runtime configuration
|
|
16
|
+
- `useCartStore()` hook for direct store access
|
|
17
|
+
- Cart operations: `addItem`, `removeItem`, `updateItemQuantity`, `clearCart`
|
|
18
|
+
- Cart UI controls: `openCart`, `closeCart`, `toggleCart`
|
|
19
|
+
- Automatic cart initialization and persistence
|
|
20
|
+
|
|
21
|
+
- **Selectors** (`selectors.ts`)
|
|
22
|
+
- `useCartCount()` - number of unique items
|
|
23
|
+
- `useCartTotalQuantity()` - sum of all quantities
|
|
24
|
+
- `useCartItems()` - array of cart items
|
|
25
|
+
- `useCartTotal()` - client-calculated total
|
|
26
|
+
- `useCartTotalAmount()` - server-calculated total
|
|
27
|
+
- `useIsInCart()` - check if product is in cart
|
|
28
|
+
- `useCartToggle()` - toggle cart visibility
|
|
29
|
+
- `useCartStatus()` - cart loading/error state
|
|
30
|
+
|
|
31
|
+
- **Hooks** (`hooks/`)
|
|
32
|
+
- `useAddToCart()` - add products with loading state management
|
|
33
|
+
|
|
34
|
+
- **Services** (`services/`)
|
|
35
|
+
- `DefaultCartService` - HTTP-based cart API client
|
|
36
|
+
- `DefaultCartStorage` - localStorage-based persistence
|
|
37
|
+
- `ICartService` interface for custom implementations
|
|
38
|
+
- `ICartStorage` interface for custom storage
|
|
39
|
+
|
|
40
|
+
- **Components** (`components/`)
|
|
41
|
+
- `CartInitializer` - cart initialization component
|
|
42
|
+
|
|
43
|
+
- **Utilities** (`utils/`)
|
|
44
|
+
- `formatPrice()` - currency formatting
|
|
45
|
+
- `calculateCartTotal()` - sum cart item prices
|
|
46
|
+
- `calculateSavings()` - calculate compare-at savings
|
|
47
|
+
- `mapProductToCartItem()` - product to cart item mapping
|
|
48
|
+
|
|
49
|
+
- **Types** (`types.ts`)
|
|
50
|
+
- Full TypeScript type definitions
|
|
51
|
+
- `CartItem`, `CartConfig`, `CartResponse` interfaces
|
|
52
|
+
- `ICartService`, `ICartStorage` interfaces
|
|
53
|
+
|
|
54
|
+
### Notes
|
|
55
|
+
|
|
56
|
+
- Extracted from `wellversed-app` internal implementation
|
|
57
|
+
- Designed for use with Shopify Storefront API but backend-agnostic
|
|
58
|
+
- Supports both Zustand v4 and v5
|
package/README.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# @shopkit/cart
|
|
2
|
+
|
|
3
|
+
Cart state management, hooks, and services for e-commerce storefronts.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @shopkit/cart
|
|
9
|
+
# or
|
|
10
|
+
bun add @shopkit/cart
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Configure the cart at app startup
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// app/providers.tsx or similar
|
|
19
|
+
import {
|
|
20
|
+
configureCart,
|
|
21
|
+
DefaultCartService,
|
|
22
|
+
DefaultCartStorage,
|
|
23
|
+
} from '@shopkit/cart';
|
|
24
|
+
|
|
25
|
+
// Configure once at app initialization
|
|
26
|
+
configureCart({
|
|
27
|
+
merchantName: 'my-store',
|
|
28
|
+
cartService: new DefaultCartService('/api/cart'),
|
|
29
|
+
cartStorage: new DefaultCartStorage('my-store'),
|
|
30
|
+
defaultCurrencyCode: 'USD',
|
|
31
|
+
onCartEvent: (event) => {
|
|
32
|
+
console.log('Cart event:', event);
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Initialize the cart in your layout
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
// app/layout.tsx
|
|
41
|
+
import { CartInitializer } from '@shopkit/cart';
|
|
42
|
+
|
|
43
|
+
export default function RootLayout({ children }) {
|
|
44
|
+
return (
|
|
45
|
+
<html>
|
|
46
|
+
<body>
|
|
47
|
+
<CartInitializer merchantName="my-store" />
|
|
48
|
+
{children}
|
|
49
|
+
</body>
|
|
50
|
+
</html>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. Use cart hooks in components
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { useAddToCart, useCartCount, useCartToggle } from '@shopkit/cart';
|
|
59
|
+
|
|
60
|
+
function ProductCard({ product }) {
|
|
61
|
+
const { addToCart, isLoading } = useAddToCart();
|
|
62
|
+
const cartCount = useCartCount();
|
|
63
|
+
const toggleCart = useCartToggle();
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<div>
|
|
67
|
+
<h3>{product.title}</h3>
|
|
68
|
+
<button
|
|
69
|
+
onClick={() => addToCart(product)}
|
|
70
|
+
disabled={isLoading(product.id)}
|
|
71
|
+
>
|
|
72
|
+
Add to Cart
|
|
73
|
+
</button>
|
|
74
|
+
<button onClick={toggleCart}>
|
|
75
|
+
Cart ({cartCount})
|
|
76
|
+
</button>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## API Reference
|
|
83
|
+
|
|
84
|
+
### Configuration
|
|
85
|
+
|
|
86
|
+
#### `configureCart(config: CartConfig)`
|
|
87
|
+
|
|
88
|
+
Configure the cart module. Must be called before using any cart functionality.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
interface CartConfig {
|
|
92
|
+
merchantName: string;
|
|
93
|
+
cartService: ICartService;
|
|
94
|
+
cartStorage: ICartStorage;
|
|
95
|
+
defaultCurrencyCode?: string;
|
|
96
|
+
onCartEvent?: (event: CartEvent) => void;
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Hooks
|
|
101
|
+
|
|
102
|
+
#### `useCartStore()`
|
|
103
|
+
|
|
104
|
+
Direct access to the Zustand store for advanced use cases.
|
|
105
|
+
|
|
106
|
+
#### `useAddToCart(options?)`
|
|
107
|
+
|
|
108
|
+
Hook for adding products to cart with loading state management.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
const { addToCart, isLoading, loadingStates } = useAddToCart({
|
|
112
|
+
onSuccess: (item) => console.log('Added:', item),
|
|
113
|
+
onError: (error) => console.error(error),
|
|
114
|
+
defaultCurrencyCode: 'USD',
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### `useCartCount()`
|
|
119
|
+
|
|
120
|
+
Returns the number of unique items in the cart.
|
|
121
|
+
|
|
122
|
+
#### `useCartTotalQuantity()`
|
|
123
|
+
|
|
124
|
+
Returns the total quantity of all items.
|
|
125
|
+
|
|
126
|
+
#### `useCartItems()`
|
|
127
|
+
|
|
128
|
+
Returns the array of cart items.
|
|
129
|
+
|
|
130
|
+
#### `useCartTotal()`
|
|
131
|
+
|
|
132
|
+
Returns the calculated cart total (client-side).
|
|
133
|
+
|
|
134
|
+
#### `useCartTotalAmount()`
|
|
135
|
+
|
|
136
|
+
Returns the server-calculated total amount.
|
|
137
|
+
|
|
138
|
+
#### `useIsInCart(productId, variantId?)`
|
|
139
|
+
|
|
140
|
+
Check if a product/variant is in the cart.
|
|
141
|
+
|
|
142
|
+
### Services
|
|
143
|
+
|
|
144
|
+
#### `DefaultCartService`
|
|
145
|
+
|
|
146
|
+
Default HTTP-based cart service implementation.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
const service = new DefaultCartService('/api/cart');
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### `DefaultCartStorage`
|
|
153
|
+
|
|
154
|
+
Default localStorage-based cart storage.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const storage = new DefaultCartStorage('my-store');
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Components
|
|
161
|
+
|
|
162
|
+
#### `<CartInitializer merchantName="..." />`
|
|
163
|
+
|
|
164
|
+
Initialize the cart on mount. Must be rendered after `configureCart()` is called.
|
|
165
|
+
|
|
166
|
+
### Utils
|
|
167
|
+
|
|
168
|
+
#### `formatPrice(amount, currencyCode?, locale?)`
|
|
169
|
+
|
|
170
|
+
Format a price amount for display.
|
|
171
|
+
|
|
172
|
+
#### `calculateCartTotal(items)`
|
|
173
|
+
|
|
174
|
+
Calculate the total price of cart items.
|
|
175
|
+
|
|
176
|
+
#### `calculateSavings(items)`
|
|
177
|
+
|
|
178
|
+
Calculate total savings from compare-at prices.
|
|
179
|
+
|
|
180
|
+
#### `mapProductToCartItem(product, variantId?, quantity?, currencyCode?)`
|
|
181
|
+
|
|
182
|
+
Map a product object to a CartItem.
|
|
183
|
+
|
|
184
|
+
## Custom Services
|
|
185
|
+
|
|
186
|
+
Implement `ICartService` for custom cart backends:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { ICartService, CartResponse, CartItemRequest } from '@shopkit/cart';
|
|
190
|
+
|
|
191
|
+
class MyCartService implements ICartService {
|
|
192
|
+
async createCart(merchantName: string): Promise<CartResponse> {
|
|
193
|
+
// Your implementation
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async getCart(cartId: string): Promise<CartResponse> {
|
|
197
|
+
// Your implementation
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async addToCart(cartId: string, items: CartItemRequest[]): Promise<void> {
|
|
201
|
+
// Your implementation
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async removeFromCart(cartId: string, itemIds: string[]): Promise<void> {
|
|
205
|
+
// Your implementation
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async updateCart(cartId: string, items: CartItemRequest[]): Promise<void> {
|
|
209
|
+
// Your implementation
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT
|