@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 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