@tapcart/mobile-components 0.8.63 → 0.8.65
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/dist/components/hooks/use-infinite-scroll.d.ts +7 -6
- package/dist/components/hooks/use-infinite-scroll.d.ts.map +1 -1
- package/dist/components/hooks/use-infinite-scroll.js +80 -18
- package/dist/components/hooks/use-order-details.d.ts.map +1 -1
- package/dist/components/hooks/use-order-details.js +27 -17
- package/dist/components/hooks/use-products.js +2 -2
- package/dist/components/hooks/use-sort-filter.d.ts +3 -2
- package/dist/components/hooks/use-sort-filter.d.ts.map +1 -1
- package/dist/components/hooks/use-sort-filter.js +36 -6
- package/dist/components/libs/cache/ProductsLocalStorage.d.ts.map +1 -1
- package/dist/components/libs/cache/ProductsLocalStorage.js +1 -1
- package/dist/components/ui/icon.d.ts.map +1 -1
- package/dist/components/ui/icon.js +1 -18
- package/dist/components/ui/star-rating.d.ts +1 -0
- package/dist/components/ui/star-rating.d.ts.map +1 -1
- package/dist/components/ui/star-rating.js +12 -6
- package/dist/styles.css +7 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReadonlyURLSearchParams } from "next/navigation";
|
|
2
|
-
import { Product } from "app-studio-types";
|
|
2
|
+
import { Product, BaseSearchClient } from "app-studio-types";
|
|
3
3
|
interface PageData {
|
|
4
4
|
products: Product[];
|
|
5
5
|
cursorBlob?: string;
|
|
@@ -10,10 +10,11 @@ interface PageData {
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
interface UseInfiniteScrollProps {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
searchClient?: BaseSearchClient<Product>;
|
|
14
|
+
initialData?: PageData;
|
|
15
|
+
queryVariables?: Record<string, any>;
|
|
16
|
+
direction?: "vertical" | "horizontal";
|
|
17
|
+
productLimit?: number;
|
|
17
18
|
threshold?: number;
|
|
18
19
|
interval?: number;
|
|
19
20
|
customFetcher?: (...args: any[]) => Promise<any>;
|
|
@@ -33,6 +34,6 @@ interface UseInfiniteScrollReturn {
|
|
|
33
34
|
}
|
|
34
35
|
export declare const formatSearchParamsAsNextQueryVariables: (searchParams: ReadonlyURLSearchParams) => {};
|
|
35
36
|
declare const constructURL: (apiURL: string) => string;
|
|
36
|
-
declare const useInfiniteScroll: ({ initialData, queryVariables: queryVariableProps, direction, productLimit, threshold, interval, customFetcher, customGetKey, }: UseInfiniteScrollProps) => UseInfiniteScrollReturn;
|
|
37
|
+
declare const useInfiniteScroll: ({ searchClient, initialData, queryVariables: queryVariableProps, direction, productLimit, threshold, interval, customFetcher, customGetKey, }: UseInfiniteScrollProps) => UseInfiniteScrollReturn;
|
|
37
38
|
export { useInfiniteScroll, constructURL };
|
|
38
39
|
//# sourceMappingURL=use-infinite-scroll.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-infinite-scroll.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-infinite-scroll.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAmB,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"use-infinite-scroll.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-infinite-scroll.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uBAAuB,EAAmB,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE5D,UAAU,QAAQ;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,GAAG,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;CACxC;AAED,UAAU,sBAAsB;IAE9B,YAAY,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAGxC,WAAW,CAAC,EAAE,QAAQ,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAGpC,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,CAAA;IACrC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAChD,YAAY,CAAC,EAAE,CACb,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,GAAG,GAAG,IAAI,EAC5B,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,GAAG,CAAA;CACT;AAED,UAAU,uBAAuB;IAC/B,IAAI,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAA;IAC5B,KAAK,EAAE,GAAG,CAAA;IACV,oBAAoB,EAAE,OAAO,CAAA;IAC7B,aAAa,EAAE,OAAO,GAAG,SAAS,CAAA;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,KAAK,IAAI,CAAA;IAChD,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;CACtB;AAED,eAAO,MAAM,sCAAsC,iBACnC,uBAAuB,OAsBtC,CAAA;AAED,QAAA,MAAM,YAAY,WAAY,MAAM,WAGnC,CAAA;AAED,QAAA,MAAM,iBAAiB,kJAepB,sBAAsB,KAAG,uBA+L3B,CAAA;AAED,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAA"}
|
|
@@ -41,7 +41,13 @@ const constructURL = (apiURL) => {
|
|
|
41
41
|
const url = new URL(apiURL);
|
|
42
42
|
return url.toString();
|
|
43
43
|
};
|
|
44
|
-
const useInfiniteScroll = ({
|
|
44
|
+
const useInfiniteScroll = ({
|
|
45
|
+
// Search client props
|
|
46
|
+
searchClient,
|
|
47
|
+
// API props (backwards compatibility)
|
|
48
|
+
initialData, queryVariables: queryVariableProps,
|
|
49
|
+
// Common props
|
|
50
|
+
direction = "vertical", productLimit = Infinity, threshold = 0.01, interval = 33, // ~2 frames
|
|
45
51
|
customFetcher, customGetKey, }) => {
|
|
46
52
|
var _a, _b, _c, _d, _e;
|
|
47
53
|
const searchParams = useSearchParams();
|
|
@@ -50,11 +56,19 @@ customFetcher, customGetKey, }) => {
|
|
|
50
56
|
rootMargin: direction === "vertical" ? "600px" : "0px 420px 0px 0px",
|
|
51
57
|
threshold: threshold,
|
|
52
58
|
});
|
|
59
|
+
// When searchClient is provided, use search client approach
|
|
60
|
+
const usingSearchClient = Boolean(searchClient);
|
|
61
|
+
// Search client approach - getKey and fetcher
|
|
62
|
+
const searchClientGetKey = useMemo(() => customGetKey || (searchClient === null || searchClient === void 0 ? void 0 : searchClient.getKey), [customGetKey, searchClient === null || searchClient === void 0 ? void 0 : searchClient.getKey]);
|
|
63
|
+
const searchClientFetcher = useMemo(() => customFetcher || (searchClient === null || searchClient === void 0 ? void 0 : searchClient.fetcher), [customFetcher, searchClient === null || searchClient === void 0 ? void 0 : searchClient.fetcher]);
|
|
64
|
+
// API approach - query variables and fetcher
|
|
53
65
|
const queryVariables = useMemo(() => {
|
|
66
|
+
if (usingSearchClient)
|
|
67
|
+
return null;
|
|
54
68
|
const formattedParams = formatSearchParamsAsNextQueryVariables(searchParams);
|
|
55
69
|
return Object.assign(Object.assign({}, queryVariableProps), { searchParams: formattedParams });
|
|
56
|
-
}, [queryVariableProps, searchParams]);
|
|
57
|
-
|
|
70
|
+
}, [queryVariableProps, searchParams, usingSearchClient]);
|
|
71
|
+
const apiGetKey = (pageIndex, previousPageData, queryVariables) => {
|
|
58
72
|
var _a;
|
|
59
73
|
if (pageIndex === 0) {
|
|
60
74
|
return Object.assign({}, queryVariables);
|
|
@@ -63,11 +77,11 @@ customFetcher, customGetKey, }) => {
|
|
|
63
77
|
return null;
|
|
64
78
|
return Object.assign(Object.assign({}, queryVariables), { cursorBlob: previousPageData.pageData.cursorBlob });
|
|
65
79
|
};
|
|
66
|
-
|
|
67
|
-
getKey = customGetKey;
|
|
68
|
-
}
|
|
69
|
-
let fetcher = (body) => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
|
+
const apiFetcher = (body) => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
81
|
var _f, _g;
|
|
82
|
+
if (!(initialData === null || initialData === void 0 ? void 0 : initialData.apiURL)) {
|
|
83
|
+
throw new Error("initialData.apiURL is required for API mode");
|
|
84
|
+
}
|
|
71
85
|
const res = yield fetch(constructURL(initialData.apiURL), {
|
|
72
86
|
method: "POST",
|
|
73
87
|
body: JSON.stringify(body),
|
|
@@ -76,10 +90,25 @@ customFetcher, customGetKey, }) => {
|
|
|
76
90
|
productCount.current += (_g = (_f = data === null || data === void 0 ? void 0 : data.products) === null || _f === void 0 ? void 0 : _f.length) !== null && _g !== void 0 ? _g : 0;
|
|
77
91
|
return data;
|
|
78
92
|
});
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
// Determine which approach to use
|
|
94
|
+
const getKey = usingSearchClient
|
|
95
|
+
? (pageIndex, previousPageData) => {
|
|
96
|
+
if (!searchClientGetKey)
|
|
97
|
+
return null;
|
|
98
|
+
return searchClientGetKey(pageIndex, previousPageData);
|
|
99
|
+
}
|
|
100
|
+
: (pageIndex, previousPageData) => (customGetKey || apiGetKey)(pageIndex, previousPageData, queryVariables !== null && queryVariables !== void 0 ? queryVariables : {});
|
|
101
|
+
const fetcher = usingSearchClient
|
|
102
|
+
? (...args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
var _h, _j;
|
|
104
|
+
if (!searchClientFetcher)
|
|
105
|
+
return null;
|
|
106
|
+
const result = yield searchClientFetcher(...args);
|
|
107
|
+
productCount.current += (_j = (_h = result === null || result === void 0 ? void 0 : result.products) === null || _h === void 0 ? void 0 : _h.length) !== null && _j !== void 0 ? _j : 0;
|
|
108
|
+
return result;
|
|
109
|
+
})
|
|
110
|
+
: customFetcher || apiFetcher;
|
|
111
|
+
const { data, error, size, setSize, isLoading, isValidating, mutate, } = useSWRInfinite(getKey, fetcher, {
|
|
83
112
|
revalidateFirstPage: false,
|
|
84
113
|
initialSize: 1,
|
|
85
114
|
});
|
|
@@ -87,8 +116,16 @@ customFetcher, customGetKey, }) => {
|
|
|
87
116
|
const isLoadingMore = isLoadingInitialData ||
|
|
88
117
|
(size > 0 && data && typeof data[size - 1] === "undefined");
|
|
89
118
|
const isEmpty = ((_c = (_b = (_a = data === null || data === void 0 ? void 0 : data[0]) === null || _a === void 0 ? void 0 : _a.products) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) === 0;
|
|
90
|
-
|
|
91
|
-
|
|
119
|
+
let isEndPointer;
|
|
120
|
+
if (!data) {
|
|
121
|
+
isEndPointer = true;
|
|
122
|
+
}
|
|
123
|
+
else if (usingSearchClient) {
|
|
124
|
+
isEndPointer = !(searchClient === null || searchClient === void 0 ? void 0 : searchClient.getHasMore());
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
isEndPointer = !((_e = (_d = data[data.length - 1]) === null || _d === void 0 ? void 0 : _d.pageData) === null || _e === void 0 ? void 0 : _e.cursorBlob);
|
|
128
|
+
}
|
|
92
129
|
const isReachingEnd = isEmpty || isEndPointer;
|
|
93
130
|
const isRefreshing = isValidating && data && data.length === size;
|
|
94
131
|
const loadMore = useCallback(() => {
|
|
@@ -104,6 +141,7 @@ customFetcher, customGetKey, }) => {
|
|
|
104
141
|
isRefreshing,
|
|
105
142
|
productLimit,
|
|
106
143
|
setSize,
|
|
144
|
+
size,
|
|
107
145
|
]);
|
|
108
146
|
const throttleLoadMore = useMemo(() => throttle(loadMore, interval), [loadMore, interval]);
|
|
109
147
|
useEffect(() => {
|
|
@@ -111,7 +149,22 @@ customFetcher, customGetKey, }) => {
|
|
|
111
149
|
throttleLoadMore();
|
|
112
150
|
}
|
|
113
151
|
}, [inView, throttleLoadMore]);
|
|
114
|
-
|
|
152
|
+
// Search client state change listener (only for search client approach)
|
|
153
|
+
useEffect(() => {
|
|
154
|
+
if (!usingSearchClient || !searchClient)
|
|
155
|
+
return;
|
|
156
|
+
const unsubscribeAllChanges = searchClient.onSearchStateChange(() => {
|
|
157
|
+
productCount.current = 0;
|
|
158
|
+
mutate(undefined, { revalidate: true });
|
|
159
|
+
});
|
|
160
|
+
return unsubscribeAllChanges;
|
|
161
|
+
}, [searchClient, mutate, usingSearchClient]);
|
|
162
|
+
const products = useMemo(() => {
|
|
163
|
+
return data
|
|
164
|
+
? data === null || data === void 0 ? void 0 : data.flatMap((page) => page === null || page === void 0 ? void 0 : page.products).slice(0, productLimit)
|
|
165
|
+
: [];
|
|
166
|
+
}, [data, productLimit]);
|
|
167
|
+
return useMemo(() => ({
|
|
115
168
|
data,
|
|
116
169
|
error,
|
|
117
170
|
isLoadingInitialData,
|
|
@@ -119,11 +172,20 @@ customFetcher, customGetKey, }) => {
|
|
|
119
172
|
isEmpty,
|
|
120
173
|
isReachingEnd,
|
|
121
174
|
ref,
|
|
122
|
-
products
|
|
123
|
-
? data === null || data === void 0 ? void 0 : data.flatMap((page) => page === null || page === void 0 ? void 0 : page.products).slice(0, productLimit)
|
|
124
|
-
: [],
|
|
175
|
+
products,
|
|
125
176
|
isLoading,
|
|
126
177
|
isValidating,
|
|
127
|
-
}
|
|
178
|
+
}), [
|
|
179
|
+
data,
|
|
180
|
+
error,
|
|
181
|
+
isLoadingInitialData,
|
|
182
|
+
isLoadingMore,
|
|
183
|
+
isEmpty,
|
|
184
|
+
isReachingEnd,
|
|
185
|
+
ref,
|
|
186
|
+
products,
|
|
187
|
+
isLoading,
|
|
188
|
+
isValidating,
|
|
189
|
+
]);
|
|
128
190
|
};
|
|
129
191
|
export { useInfiniteScroll, constructURL };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-order-details.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-order-details.ts"],"names":[],"mappings":"AAKA,KAAK,oBAAoB,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAClC,CAAA;
|
|
1
|
+
{"version":3,"file":"use-order-details.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-order-details.ts"],"names":[],"mappings":"AAKA,KAAK,oBAAoB,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAClC,CAAA;AA0LD,eAAO,MAAM,qBAAqB,UACzB,OAAO,MAAM,EAAE,GAAG,CAAC;kBACT,OAAO,MAAM,EAAE,GAAG,CAAC;kBAAgB,OAAO,MAAM,EAAE,GAAG,CAAC;CA+NxE,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,MAAM,EACN,KAAK,EACL,QAAQ,EACR,OAAO,EACP,IAAY,GACb,EAAE,oBAAoB,GAAG,iBAAiB,CA4D1C"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { useProducts } from "./use-products";
|
|
4
|
-
const getProductIds = (lines) => lines
|
|
4
|
+
const getProductIds = (lines) => (lines !== null && lines !== void 0 ? lines : [])
|
|
5
|
+
.map((line) => line.productId)
|
|
6
|
+
.filter((id) => id && id !== "undefined");
|
|
5
7
|
const calculateCompareAtPrice = (variant) => {
|
|
6
8
|
var _a, _b, _c, _d;
|
|
7
9
|
return ({
|
|
@@ -72,8 +74,9 @@ const calculateCartPrice = (lines) => {
|
|
|
72
74
|
};
|
|
73
75
|
};
|
|
74
76
|
const updateOrderDetails = (orderDetails, products) => {
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
+
var _a;
|
|
78
|
+
const product = products === null || products === void 0 ? void 0 : products[0];
|
|
79
|
+
const variant = (_a = product === null || product === void 0 ? void 0 : product.variants) === null || _a === void 0 ? void 0 : _a[0];
|
|
77
80
|
const compareAtPrice = calculateCompareAtPrice(variant);
|
|
78
81
|
orderDetails.paymentMethods = createPaymentMethods();
|
|
79
82
|
orderDetails.cart = {
|
|
@@ -235,12 +238,16 @@ export const transformOrderDetails = (order) => {
|
|
|
235
238
|
currencyCode: currencyCode || order.currency || order.currencyCode || "USD",
|
|
236
239
|
});
|
|
237
240
|
// Transform checkout data (minimal for price/line updates)
|
|
238
|
-
const subtotal = order.
|
|
241
|
+
const subtotal = order.subtotal ||
|
|
242
|
+
order.subtotalAmount ||
|
|
243
|
+
order.subtotalPrice ||
|
|
244
|
+
order.currentSubtotalPrice;
|
|
239
245
|
const total = order.totalAmount || order.totalPrice || order.currentTotalPrice;
|
|
240
246
|
const taxes = order.taxAmount || order.totalTax || order.currentTotalTax;
|
|
241
247
|
const shipping = order.shippingAmount ||
|
|
242
248
|
order.totalShippingPrice ||
|
|
243
|
-
order.currentTotalShippingPrice
|
|
249
|
+
order.currentTotalShippingPrice ||
|
|
250
|
+
order.totalShipping;
|
|
244
251
|
const currencyCode = order.currency || order.currencyCode || "USD";
|
|
245
252
|
const checkoutData = {
|
|
246
253
|
shippingLine: {
|
|
@@ -256,20 +263,23 @@ export const transformOrderDetails = (order) => {
|
|
|
256
263
|
})),
|
|
257
264
|
subtotalPrice: wrapMoney(subtotal, currencyCode),
|
|
258
265
|
lineItems: (order.lineItems || []).map((lineItem) => {
|
|
259
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
266
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
260
267
|
const variant = lineItem.variant || {};
|
|
261
268
|
const product = variant.product || {};
|
|
262
269
|
const currencyCode = ((_a = lineItem.discountedTotalPrice) === null || _a === void 0 ? void 0 : _a.currencyCode) ||
|
|
263
270
|
((_b = lineItem.originalTotalPrice) === null || _b === void 0 ? void 0 : _b.currencyCode) ||
|
|
271
|
+
((_d = (_c = lineItem.price) === null || _c === void 0 ? void 0 : _c.amount) === null || _d === void 0 ? void 0 : _d.currencyCode) ||
|
|
264
272
|
order.currency ||
|
|
265
273
|
order.currencyCode ||
|
|
266
274
|
"USD";
|
|
267
275
|
// Calculate finalLinePrice with full-discount logic
|
|
268
|
-
let finalLinePriceAmount = parseAmount((
|
|
276
|
+
let finalLinePriceAmount = parseAmount(((_e = lineItem.discountedTotalPrice) === null || _e === void 0 ? void 0 : _e.amount) ||
|
|
277
|
+
((_f = lineItem.finalLinePrice) === null || _f === void 0 ? void 0 : _f.amount) ||
|
|
278
|
+
((_g = lineItem.price) === null || _g === void 0 ? void 0 : _g.amount));
|
|
269
279
|
if (Array.isArray(lineItem.discountAllocations) &&
|
|
270
280
|
lineItem.discountAllocations.length > 0) {
|
|
271
281
|
const totalDiscount = lineItem.discountAllocations.reduce((sum, discount) => { var _a; return sum + parseAmount((_a = discount.allocatedAmount) === null || _a === void 0 ? void 0 : _a.amount); }, 0);
|
|
272
|
-
const original = parseAmount((
|
|
282
|
+
const original = parseAmount((_h = lineItem.originalTotalPrice) === null || _h === void 0 ? void 0 : _h.amount);
|
|
273
283
|
if (totalDiscount >= original && original > 0) {
|
|
274
284
|
finalLinePriceAmount = 0;
|
|
275
285
|
}
|
|
@@ -283,17 +293,17 @@ export const transformOrderDetails = (order) => {
|
|
|
283
293
|
product: {
|
|
284
294
|
type: product.type || "",
|
|
285
295
|
vendor: product.vendor || lineItem.vendor || "Unknown",
|
|
286
|
-
id: ((
|
|
287
|
-
((
|
|
296
|
+
id: ((_j = product.id) === null || _j === void 0 ? void 0 : _j.split("/").pop()) ||
|
|
297
|
+
((_k = lineItem.productId) === null || _k === void 0 ? void 0 : _k.split("/").pop()),
|
|
288
298
|
untranslatedTitle: lineItem.title || product.title,
|
|
289
299
|
title: lineItem.title || product.title,
|
|
290
300
|
url: `/products/${product.handle || ""}`,
|
|
291
301
|
},
|
|
292
|
-
id: ((
|
|
293
|
-
((
|
|
294
|
-
price: wrapMoney(((
|
|
302
|
+
id: ((_l = variant.id) === null || _l === void 0 ? void 0 : _l.split("/").pop()) ||
|
|
303
|
+
((_m = lineItem.variantId) === null || _m === void 0 ? void 0 : _m.split("/").pop()),
|
|
304
|
+
price: wrapMoney(((_o = variant.price) === null || _o === void 0 ? void 0 : _o.amount) || ((_p = lineItem.price) === null || _p === void 0 ? void 0 : _p.amount), currencyCode),
|
|
295
305
|
image: {
|
|
296
|
-
src: ((
|
|
306
|
+
src: ((_q = variant.image) === null || _q === void 0 ? void 0 : _q.url) || ((_r = lineItem.image) === null || _r === void 0 ? void 0 : _r.url),
|
|
297
307
|
},
|
|
298
308
|
},
|
|
299
309
|
discountAllocations: (lineItem.discountAllocations || []).map((allocation) => {
|
|
@@ -305,7 +315,7 @@ export const transformOrderDetails = (order) => {
|
|
|
305
315
|
}),
|
|
306
316
|
quantity: lineItem.quantity || 1,
|
|
307
317
|
title: lineItem.title || product.title,
|
|
308
|
-
id: ((
|
|
318
|
+
id: ((_s = variant.id) === null || _s === void 0 ? void 0 : _s.split("/").pop()) || ((_t = lineItem.variantId) === null || _t === void 0 ? void 0 : _t.split("/").pop()),
|
|
309
319
|
};
|
|
310
320
|
}),
|
|
311
321
|
totalPrice: wrapMoney(total, currencyCode),
|
|
@@ -329,9 +339,9 @@ export function useOrderDetails({ variables, apiUrl, appId, language, country, m
|
|
|
329
339
|
});
|
|
330
340
|
useEffect(() => {
|
|
331
341
|
var _a, _b;
|
|
332
|
-
if (
|
|
342
|
+
if ((orderVariables === null || orderVariables === void 0 ? void 0 : orderVariables.orderDetails) && (orderVariables === null || orderVariables === void 0 ? void 0 : orderVariables.checkoutData)) {
|
|
333
343
|
const updatedOrderDetails = Object.assign({}, orderVariables === null || orderVariables === void 0 ? void 0 : orderVariables.orderDetails);
|
|
334
|
-
if (mock) {
|
|
344
|
+
if (mock && products.length > 0) {
|
|
335
345
|
updateOrderDetails(updatedOrderDetails, products);
|
|
336
346
|
}
|
|
337
347
|
else {
|
|
@@ -115,7 +115,7 @@ export function useProducts(props) {
|
|
|
115
115
|
return;
|
|
116
116
|
// Determine the products array from data
|
|
117
117
|
const productsArray = Array.isArray(data) ? data : data.products || [];
|
|
118
|
-
if (!productsArray.length)
|
|
118
|
+
if (!(productsArray === null || productsArray === void 0 ? void 0 : productsArray.length))
|
|
119
119
|
return;
|
|
120
120
|
setProductResponse(productsArray);
|
|
121
121
|
}, [data]);
|
|
@@ -125,7 +125,7 @@ export function useProducts(props) {
|
|
|
125
125
|
onlyAvailableProducts: (props === null || props === void 0 ? void 0 : props.mock) && (props === null || props === void 0 ? void 0 : props.onlyAvailableProducts),
|
|
126
126
|
}),
|
|
127
127
|
error,
|
|
128
|
-
isLoading: !productResponse.length && isLoading,
|
|
128
|
+
isLoading: !(productResponse === null || productResponse === void 0 ? void 0 : productResponse.length) && isLoading,
|
|
129
129
|
isRefreshing: isLoading,
|
|
130
130
|
cacheProduct,
|
|
131
131
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { Collection } from "app-studio-types";
|
|
1
|
+
import { Collection, Product, BaseSearchClient } from "app-studio-types";
|
|
2
2
|
import { FilterCategory, FiltersAndRelatedCategories, Integration, IntegrationSortItem } from "../libs/sort-filter/search-integration";
|
|
3
3
|
interface UseSortFilterProps {
|
|
4
4
|
initialData: PageData;
|
|
5
5
|
queryVariables: Record<string, any>;
|
|
6
6
|
dynamicKey?: (queryVariables: any) => () => any;
|
|
7
|
+
searchClient?: BaseSearchClient<Product>;
|
|
7
8
|
}
|
|
8
9
|
interface PageData {
|
|
9
10
|
filtersURL: string;
|
|
@@ -27,6 +28,6 @@ interface SortFilterData {
|
|
|
27
28
|
dynamicFiltersEnabled: boolean;
|
|
28
29
|
integrations: Integration[];
|
|
29
30
|
}
|
|
30
|
-
declare const useSortFilter: ({ initialData, queryVariables, dynamicKey, }: UseSortFilterProps) => UseSortFilterReturn;
|
|
31
|
+
declare const useSortFilter: ({ initialData, queryVariables, dynamicKey, searchClient, }: UseSortFilterProps) => UseSortFilterReturn;
|
|
31
32
|
export { useSortFilter };
|
|
32
33
|
//# sourceMappingURL=use-sort-filter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-sort-filter.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-sort-filter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"use-sort-filter.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-sort-filter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExE,OAAO,EACL,cAAc,EACd,2BAA2B,EAC3B,WAAW,EACX,mBAAmB,EACpB,MAAM,wCAAwC,CAAA;AAI/C,UAAU,kBAAkB;IAC1B,WAAW,EAAE,QAAQ,CAAA;IACrB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,KAAK,MAAM,GAAG,CAAA;IAC/C,YAAY,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAA;CACzC;AAED,UAAU,QAAQ;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,cAAc,EAAE,CAAA;IAC/B,cAAc,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAA;CACxC;AAED,UAAU,mBAAmB;IAC3B,cAAc,EAAE,cAAc,CAAA;IAC9B,IAAI,EAAE,GAAG,EAAE,CAAA;IACX,MAAM,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,OAAO,CAAA;CACzB;AAED,UAAU,cAAc;IACtB,UAAU,EAAE,UAAU,CAAA;IACtB,2BAA2B,EAAE,2BAA2B,CAAA;IACxD,WAAW,EAAE,mBAAmB,EAAE,CAAA;IAClC,qBAAqB,EAAE,OAAO,CAAA;IAC9B,YAAY,EAAE,WAAW,EAAE,CAAA;CAC5B;AAeD,QAAA,MAAM,aAAa,+DAKhB,kBAAkB,KAAG,mBA2EvB,CAAA;AAED,OAAO,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
import useSWRInfinite from "swr/infinite";
|
|
3
12
|
import useSWR from "swr";
|
|
4
13
|
import { useCallback, useMemo } from "react";
|
|
@@ -12,26 +21,28 @@ const fetcher = ({ apiURL, body }) => fetch(constructURL(apiURL), {
|
|
|
12
21
|
})
|
|
13
22
|
.then((res) => res.json())
|
|
14
23
|
.catch((error) => console.error(error));
|
|
15
|
-
const useSortFilter = ({ initialData, queryVariables, dynamicKey, }) => {
|
|
16
|
-
const shouldFetch = queryVariables && Object.keys(queryVariables).length > 0;
|
|
24
|
+
const useSortFilter = ({ initialData, queryVariables, dynamicKey, searchClient, }) => {
|
|
25
|
+
const shouldFetch = queryVariables && Object.keys(queryVariables).length > 0 && !searchClient;
|
|
17
26
|
const { data: sortFilterData, isLoading } = useSWR(shouldFetch
|
|
18
27
|
? { apiUrl: initialData.sortFilterURL, body: Object.assign({}, queryVariables) }
|
|
19
28
|
: null, ({ apiUrl, body }) => fetcher({ apiURL: apiUrl, body }), { revalidateOnFocus: false });
|
|
20
29
|
const getKey = () => {
|
|
21
|
-
if (!sortFilterData ||
|
|
30
|
+
if (!sortFilterData ||
|
|
31
|
+
!sortFilterData.dynamicFiltersEnabled ||
|
|
32
|
+
searchClient)
|
|
22
33
|
return null;
|
|
23
34
|
return Object.assign(Object.assign({}, sortFilterData.queryVariables), (initialData.uiFilterState && {
|
|
24
35
|
filterCategories: initialData.uiFilterState,
|
|
25
36
|
}));
|
|
26
37
|
};
|
|
27
38
|
const memoizedDynamicKey = useCallback(() => {
|
|
28
|
-
if (dynamicKey) {
|
|
29
|
-
return dynamicKey(sortFilterData.queryVariables);
|
|
39
|
+
if (dynamicKey && !searchClient) {
|
|
40
|
+
return dynamicKey(sortFilterData === null || sortFilterData === void 0 ? void 0 : sortFilterData.queryVariables);
|
|
30
41
|
}
|
|
31
42
|
else {
|
|
32
43
|
return null;
|
|
33
44
|
}
|
|
34
|
-
}, [dynamicKey, sortFilterData === null || sortFilterData === void 0 ? void 0 : sortFilterData.queryVariables]);
|
|
45
|
+
}, [dynamicKey, sortFilterData === null || sortFilterData === void 0 ? void 0 : sortFilterData.queryVariables, searchClient]);
|
|
35
46
|
const memoizedFetch = useMemo(() => {
|
|
36
47
|
return (body) => fetcher({ apiURL: initialData.filtersURL, body });
|
|
37
48
|
}, [initialData.filtersURL]);
|
|
@@ -40,6 +51,25 @@ const useSortFilter = ({ initialData, queryVariables, dynamicKey, }) => {
|
|
|
40
51
|
revalidateOnFocus: false,
|
|
41
52
|
initialSize: 1,
|
|
42
53
|
});
|
|
54
|
+
// If searchClient is provided, return default values
|
|
55
|
+
if (searchClient) {
|
|
56
|
+
return {
|
|
57
|
+
sortFilterData: {
|
|
58
|
+
collection: {},
|
|
59
|
+
filtersAndRelatedCategories: {
|
|
60
|
+
filterCategories: [],
|
|
61
|
+
relatedCategories: [],
|
|
62
|
+
},
|
|
63
|
+
sortOptions: [],
|
|
64
|
+
dynamicFiltersEnabled: false,
|
|
65
|
+
integrations: [],
|
|
66
|
+
},
|
|
67
|
+
data: [],
|
|
68
|
+
mutate: () => __awaiter(void 0, void 0, void 0, function* () { return ({}); }),
|
|
69
|
+
isLoading: false,
|
|
70
|
+
isFilterLoading: false,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
43
73
|
return {
|
|
44
74
|
sortFilterData,
|
|
45
75
|
data: data !== null && data !== void 0 ? data : [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsLocalStorage.d.ts","sourceRoot":"","sources":["../../../../components/libs/cache/ProductsLocalStorage.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAG7C,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,cAAc;IAC9D,OAAO,EAAE,MAAM,CAA2B;IAC1C,WAAW,EAAE,MAAM,CAAe;IAElC,aAAa,CAAC,EAAE,EAAE,MAAM;IAIxB,iBAAiB,CAAC,MAAM,EAAE,MAAM;;IAShC,QAAQ,IAAI,aAAa,EAAE;IAiB3B,YAAY,CAAC,EACX,EAAE,EACF,MAAM,GACP,EAAE;QACD,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,GAAG,MAAM,GAAG,IAAI;IAgBjB,aAAa,CAAC,QAAQ,EAAE;QACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;QACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAC1B,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"ProductsLocalStorage.d.ts","sourceRoot":"","sources":["../../../../components/libs/cache/ProductsLocalStorage.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAG7C,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,cAAc;IAC9D,OAAO,EAAE,MAAM,CAA2B;IAC1C,WAAW,EAAE,MAAM,CAAe;IAElC,aAAa,CAAC,EAAE,EAAE,MAAM;IAIxB,iBAAiB,CAAC,MAAM,EAAE,MAAM;;IAShC,QAAQ,IAAI,aAAa,EAAE;IAiB3B,YAAY,CAAC,EACX,EAAE,EACF,MAAM,GACP,EAAE;QACD,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,GAAG,MAAM,GAAG,IAAI;IAgBjB,aAAa,CAAC,QAAQ,EAAE;QACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;QACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAC1B,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;IAYrB,YAAY,CACV,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EACvC,KAAK,CAAC,EAAE,aAAa,EAAE,EACvB,YAAY,GAAE,OAAc;gBAFT,MAAM;YAAM,MAAM;;IAiEvC,aAAa,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE;;;;IASrD,eAAe,CAAC,WAAW,GAAE,MAAU;IAWvC,UAAU;IAQV,eAAe,CAAC,CAAC,EAAE,GAAG;CASvB"}
|
|
@@ -53,7 +53,7 @@ export default class ProductsLocalStorage extends AppStudioCache {
|
|
|
53
53
|
: ((_b = products === null || products === void 0 ? void 0 : products.productHandles) === null || _b === void 0 ? void 0 : _b.length)
|
|
54
54
|
? products.productHandles.map((handle) => this.getCacheItem({ handle }))
|
|
55
55
|
: [];
|
|
56
|
-
return returnProducts;
|
|
56
|
+
return returnProducts.filter((product) => product !== null);
|
|
57
57
|
}
|
|
58
58
|
setCacheItem(product, cache, shouldExpire = true) {
|
|
59
59
|
var _a, _b;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../components/ui/icon.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAEL,eAAe,EAyChB,MAAM,qBAAqB,CAAA;AAI5B,QAAA,MAAM,YAAY;;;mFAiBjB,CAAA;AA+DD,MAAM,WAAW,SACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,EACzD,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;
|
|
1
|
+
{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../components/ui/icon.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAEL,eAAe,EAyChB,MAAM,qBAAqB,CAAA;AAI5B,QAAA,MAAM,YAAY;;;mFAiBjB,CAAA;AA+DD,MAAM,WAAW,SACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,EACzD,YAAY,CAAC,OAAO,YAAY,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAuID,iBAAS,IAAI,CAAC,EACZ,SAAS,EACT,IAAI,EACJ,IAAW,EACX,KAAK,EACL,GAAG,EACH,SAAS,EACT,kBAAkB,EAClB,WAAW,EACX,WAAW,EACX,cAAc,EACd,GAAG,KAAK,EACT,EAAE,SAAS,2CA+BX;AAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -116,6 +116,7 @@ const CustomIcon = ({ url, size, color, strokeColor, strokeWidth, fillColor, fil
|
|
|
116
116
|
if (path.hasAttribute("stroke")) {
|
|
117
117
|
path.setAttribute("stroke-width", strokeWidthMapping[size].toString());
|
|
118
118
|
}
|
|
119
|
+
// Override stroke width if one is provided
|
|
119
120
|
if (strokeWidth != null && path.hasAttribute("stroke")) {
|
|
120
121
|
path.setAttribute("stroke-width", strokeWidth.toString());
|
|
121
122
|
}
|
|
@@ -124,7 +125,6 @@ const CustomIcon = ({ url, size, color, strokeColor, strokeWidth, fillColor, fil
|
|
|
124
125
|
const percentage = Math.min(Math.max(fillPercentage, 0), 1);
|
|
125
126
|
const uniqueId = crypto.randomUUID();
|
|
126
127
|
const fillGradientId = `fill-gradient-${uniqueId}`;
|
|
127
|
-
const strokeGradientId = `stroke-gradient-${uniqueId}`;
|
|
128
128
|
let defs = svg.querySelector("defs");
|
|
129
129
|
if (!defs) {
|
|
130
130
|
defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
@@ -145,24 +145,7 @@ const CustomIcon = ({ url, size, color, strokeColor, strokeWidth, fillColor, fil
|
|
|
145
145
|
fillStop2.setAttribute("stop-color", secondaryFillColor || "transparent");
|
|
146
146
|
fillGradient.appendChild(fillStop2);
|
|
147
147
|
defs.appendChild(fillGradient);
|
|
148
|
-
const strokeGradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
|
|
149
|
-
strokeGradient.setAttribute("id", strokeGradientId);
|
|
150
|
-
strokeGradient.setAttribute("x1", "0%");
|
|
151
|
-
strokeGradient.setAttribute("y1", "0%");
|
|
152
|
-
strokeGradient.setAttribute("x2", "100%");
|
|
153
|
-
strokeGradient.setAttribute("y2", "0%");
|
|
154
|
-
const strokeStop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
|
155
|
-
strokeStop1.setAttribute("offset", `${percentage * 100}%`);
|
|
156
|
-
strokeStop1.setAttribute("stop-color", color || strokeColor || fillColor || "currentColor");
|
|
157
|
-
strokeGradient.appendChild(strokeStop1);
|
|
158
|
-
const strokeStop2 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
|
|
159
|
-
strokeStop2.setAttribute("offset", `${percentage * 100}%`);
|
|
160
|
-
strokeStop2.setAttribute("stop-color", secondaryFillColor || "currentColor");
|
|
161
|
-
strokeGradient.appendChild(strokeStop2);
|
|
162
|
-
defs.appendChild(strokeGradient);
|
|
163
148
|
path.setAttribute("fill", `url(#${fillGradientId})`);
|
|
164
|
-
path.setAttribute("stroke", `url(#${strokeGradientId})`);
|
|
165
|
-
path.setAttribute("stroke-width", strokeWidthMapping[size].toString());
|
|
166
149
|
}
|
|
167
150
|
});
|
|
168
151
|
} }));
|
|
@@ -6,6 +6,7 @@ export interface StarRatingProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
6
6
|
filledColor?: string;
|
|
7
7
|
emptyColor?: string;
|
|
8
8
|
designOptions?: "condensed" | "expanded";
|
|
9
|
+
strokeOnEmpty?: boolean;
|
|
9
10
|
}
|
|
10
11
|
declare const StarRating: React.ForwardRefExoticComponent<StarRatingProps & React.RefAttributes<HTMLDivElement>>;
|
|
11
12
|
export { StarRating };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"star-rating.d.ts","sourceRoot":"","sources":["../../../components/ui/star-rating.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,WAAW,GAAG,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"star-rating.d.ts","sourceRoot":"","sources":["../../../components/ui/star-rating.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,WAAW,GAAG,UAAU,CAAA;IACxC,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,QAAA,MAAM,UAAU,wFAuHf,CAAA;AAID,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
|
@@ -16,37 +16,43 @@ import { Icon } from "./icon";
|
|
|
16
16
|
const StarRating = React.forwardRef((_a, ref) => {
|
|
17
17
|
var { className, score, iconSize = "sm", iconUrl, filledColor = "#facc15", // default to yellow-400
|
|
18
18
|
emptyColor = "#e5e7eb", // default to gray-200
|
|
19
|
-
designOptions } = _a, props = __rest(_a, ["className", "score", "iconSize", "iconUrl", "filledColor", "emptyColor", "designOptions"]);
|
|
19
|
+
designOptions, strokeOnEmpty = false } = _a, props = __rest(_a, ["className", "score", "iconSize", "iconUrl", "filledColor", "emptyColor", "designOptions", "strokeOnEmpty"]);
|
|
20
20
|
const getIconProps = (isFilled) => {
|
|
21
21
|
if (iconUrl) {
|
|
22
22
|
return { url: iconUrl };
|
|
23
23
|
}
|
|
24
24
|
return { name: isFilled ? "star-filled" : "star" };
|
|
25
25
|
};
|
|
26
|
+
const strokeStyle = strokeOnEmpty
|
|
27
|
+
? {
|
|
28
|
+
strokeColor: filledColor,
|
|
29
|
+
strokeWidth: 2,
|
|
30
|
+
}
|
|
31
|
+
: {};
|
|
26
32
|
if (designOptions === "condensed") {
|
|
27
|
-
return (_jsx(Icon, Object.assign({ size: iconSize }, getIconProps(score > 0), {
|
|
33
|
+
return (_jsx(Icon, Object.assign({ size: iconSize }, getIconProps(score > 0), { fillColor: score > 0 ? filledColor : emptyColor }, strokeStyle)));
|
|
28
34
|
}
|
|
29
35
|
return (_jsx("div", Object.assign({ className: cn("flex flex-row gap-1", className), ref: ref }, props, { children: Array.from({ length: 5 }).map((_, index) => {
|
|
30
36
|
const starNumber = index + 1;
|
|
31
37
|
if (score >= starNumber) {
|
|
32
38
|
// Fully filled star
|
|
33
|
-
return (_jsx(Icon, Object.assign({ size: iconSize }, getIconProps(true), {
|
|
39
|
+
return (_jsx(Icon, Object.assign({ size: iconSize }, getIconProps(true), { fillColor: filledColor }, strokeStyle), index));
|
|
34
40
|
}
|
|
35
41
|
else if (score > index && score < starNumber) {
|
|
36
42
|
// Partial star - create overlay effect
|
|
37
43
|
const fillPercentage = score - index;
|
|
38
44
|
if (iconUrl) {
|
|
39
45
|
// Use fillPercentage for custom icons
|
|
40
|
-
return (_jsx(Icon, { size: iconSize, url: iconUrl, fillColor: filledColor, secondaryFillColor: emptyColor, fillPercentage: fillPercentage }, index));
|
|
46
|
+
return (_jsx(Icon, Object.assign({ size: iconSize, url: iconUrl, fillColor: filledColor, secondaryFillColor: emptyColor, fillPercentage: fillPercentage }, strokeStyle), index));
|
|
41
47
|
}
|
|
42
48
|
else {
|
|
43
49
|
// For Tabler icons, create overlay effect
|
|
44
|
-
return (_jsxs("div", Object.assign({ className: "relative" }, { children: [_jsx(Icon, { size: iconSize, name: "star",
|
|
50
|
+
return (_jsxs("div", Object.assign({ className: "relative" }, { children: [_jsx(Icon, Object.assign({ size: iconSize, name: "star", fillColor: emptyColor }, strokeStyle)), _jsx("div", Object.assign({ className: "absolute inset-0 overflow-hidden", style: { width: `${fillPercentage * 100}%` } }, { children: _jsx(Icon, Object.assign({ size: iconSize, name: "star-filled", fillColor: filledColor }, strokeStyle)) }))] }), index));
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
else {
|
|
48
54
|
// Empty star
|
|
49
|
-
return (_jsx(Icon, Object.assign({ size: iconSize }, getIconProps(false), {
|
|
55
|
+
return (_jsx(Icon, Object.assign({ size: iconSize }, getIconProps(false), { fillColor: emptyColor }, strokeStyle), index));
|
|
50
56
|
}
|
|
51
57
|
}) })));
|
|
52
58
|
});
|
package/dist/styles.css
CHANGED
|
@@ -823,6 +823,10 @@ video {
|
|
|
823
823
|
.m-auto {
|
|
824
824
|
margin: auto;
|
|
825
825
|
}
|
|
826
|
+
.-mx-4 {
|
|
827
|
+
margin-left: -1rem;
|
|
828
|
+
margin-right: -1rem;
|
|
829
|
+
}
|
|
826
830
|
.mx-1 {
|
|
827
831
|
margin-left: 0.25rem;
|
|
828
832
|
margin-right: 0.25rem;
|
|
@@ -1072,6 +1076,9 @@ video {
|
|
|
1072
1076
|
.h-full {
|
|
1073
1077
|
height: 100%;
|
|
1074
1078
|
}
|
|
1079
|
+
.h-px {
|
|
1080
|
+
height: 1px;
|
|
1081
|
+
}
|
|
1075
1082
|
.h-screen {
|
|
1076
1083
|
height: 100vh;
|
|
1077
1084
|
}
|