@tapcart/mobile-components 0.8.62 → 0.8.64

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.
@@ -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
- initialData: PageData;
14
- queryVariables: Record<string, any>;
15
- direction: "vertical" | "horizontal";
16
- productLimit: number;
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;AAE1C,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;IAC9B,WAAW,EAAE,QAAQ,CAAA;IACrB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,SAAS,EAAE,UAAU,GAAG,YAAY,CAAA;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,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,oIASpB,sBAAsB,KAAG,uBA0H3B,CAAA;AAED,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,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 = ({ initialData, queryVariables: queryVariableProps, direction = "vertical", productLimit = Infinity, threshold = 0.01, interval = 33, // ~2 frames
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
- let getKey = (pageIndex, previousPageData, queryVariables) => {
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
- if (customGetKey) {
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
- if (customFetcher) {
80
- fetcher = customFetcher;
81
- }
82
- const { data, error, size, setSize, isLoading, isValidating, } = useSWRInfinite((pageIndex, previousPageData) => getKey(pageIndex, previousPageData, queryVariables), fetcher, {
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
- const hasMore = (_e = (_d = data === null || data === void 0 ? void 0 : data[data.length - 1]) === null || _d === void 0 ? void 0 : _d.pageData) === null || _e === void 0 ? void 0 : _e.cursorBlob;
91
- const isEndPointer = data ? !hasMore : true;
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
- return {
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: data
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 };
@@ -359,7 +359,7 @@ const transformCart = ({ products, cartOrigin = cartMock, }) => {
359
359
  totalDutyAmount: null,
360
360
  } });
361
361
  };
362
- export const useMockCart = ({ apiUrl, appId, enabled = true, limit = 3, }) => {
362
+ export const useMockCart = ({ apiUrl, appId, enabled = true, limit = 4, }) => {
363
363
  const [isLoading, setIsLoading] = useState(true);
364
364
  const [initialLoadHappened, setInitialLoadHappened] = useState(false);
365
365
  const { products, error: productsError, isRefreshing: productsLoading, } = useProducts({
@@ -1 +1 @@
1
- {"version":3,"file":"use-products.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-products.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAM1C,KAAK,GAAG,GAAG,MAAM,CAAA;AACjB,KAAK,cAAc,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AACxD,KAAK,gBAAgB,GAAG;IACtB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IACjC,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,OAAO,EAAE,GAAG,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACpC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAC1E,UAAU,CAAC,EAAE,cAAc,EAAE,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC,CAAA;AACD,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,KAAK,EAAE,GAAG,CAAA;IACV,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;IACrB,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAC3B;QACE,EAAE,EAAE,MAAM,CAAA;QACV,MAAM,EAAE,MAAM,CAAA;KACf,GACD,SAAS,CAAA;CACd,CAAA;AAgCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAAG,iBAAiB,CA4I7E"}
1
+ {"version":3,"file":"use-products.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-products.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAK1C,KAAK,GAAG,GAAG,MAAM,CAAA;AACjB,KAAK,cAAc,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AACxD,KAAK,gBAAgB,GAAG;IACtB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IACjC,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,OAAO,EAAE,GAAG,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACpC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAC1E,UAAU,CAAC,EAAE,cAAc,EAAE,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC,CAAA;AACD,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,KAAK,EAAE,GAAG,CAAA;IACV,SAAS,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,OAAO,CAAA;IACrB,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAC3B;QACE,EAAE,EAAE,MAAM,CAAA;QACV,MAAM,EAAE,MAAM,CAAA;KACf,GACD,SAAS,CAAA;CACd,CAAA;AAgCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAAG,iBAAiB,CA8I7E"}
@@ -10,7 +10,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  import useSWR from "swr";
12
12
  import { getProductGidsFromIds, getVariantGidsFromIds } from "../../lib/utils";
13
- import { useCollection } from "./use-collection";
14
13
  import React from "react";
15
14
  import ProductsLocalStorage from "../libs/cache/ProductsLocalStorage";
16
15
  const isUseProductsProps = (props) => {
@@ -31,28 +30,21 @@ const formatProductData = ({ data, onlyAvailableProducts = false, }) => {
31
30
  };
32
31
  const productsLocalStorage = new ProductsLocalStorage();
33
32
  export function useProducts(props) {
34
- var _a, _b, _c, _d;
33
+ var _a;
35
34
  let url = null;
36
35
  let body = null;
37
36
  const shouldMockProducts = Boolean(props === null || props === void 0 ? void 0 : props.mock);
38
- const { collections } = useCollection({
39
- apiUrl: (props === null || props === void 0 ? void 0 : props.baseURL) || "",
40
- appId: ((_a = props === null || props === void 0 ? void 0 : props.queryVariables) === null || _a === void 0 ? void 0 : _a.appId) || "",
41
- language: ((_b = props === null || props === void 0 ? void 0 : props.queryVariables) === null || _b === void 0 ? void 0 : _b.language) || "en",
42
- collectionId: undefined,
43
- getCollections: shouldMockProducts,
44
- limit: 1,
45
- });
46
- const [cachedProducts, setCachedProducts] = React.useState(productsLocalStorage.getCacheItems({
37
+ // No collection logic needed for mock mode - we use direct product fetching
38
+ const [productResponse, setProductResponse] = React.useState(() => productsLocalStorage.getCacheItems({
47
39
  productIds: props === null || props === void 0 ? void 0 : props.productIds,
48
40
  productHandles: props === null || props === void 0 ? void 0 : props.productHandles,
49
41
  }));
50
42
  if (isUseProductsProps(props)) {
51
43
  let { baseURL, productIds, variantIds, productHandles, metafields, collection, queryVariables, } = props;
52
44
  if (shouldMockProducts) {
53
- const collectionToFetchID = (_c = collections[0]) === null || _c === void 0 ? void 0 : _c.id;
54
- queryVariables = Object.assign(Object.assign({}, queryVariables), { collectionId: collectionToFetchID });
55
- collection = collectionToFetchID;
45
+ // In mock mode, always use direct product fetching without collections
46
+ queryVariables = Object.assign({}, queryVariables);
47
+ // Don't set collection to enable direct product fetching
56
48
  }
57
49
  let queryParams = new URLSearchParams();
58
50
  if ((productIds === null || productIds === void 0 ? void 0 : productIds.length) > 0) {
@@ -79,9 +71,18 @@ export function useProducts(props) {
79
71
  if (queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.language) {
80
72
  queryParams.set("language", queryVariables.language);
81
73
  }
82
- queryParams.set("mediaLimit", (_d = queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.mediaLimit) !== null && _d !== void 0 ? _d : 10);
74
+ queryParams.set("mediaLimit", (_a = queryVariables === null || queryVariables === void 0 ? void 0 : queryVariables.mediaLimit) !== null && _a !== void 0 ? _a : 10);
83
75
  url = `${baseURL}/products/by-ids?${queryParams.toString()}`;
84
76
  }
77
+ // Handle collection-free product fetching when in mock mode
78
+ if (shouldMockProducts &&
79
+ !collection &&
80
+ !(productIds === null || productIds === void 0 ? void 0 : productIds.length) &&
81
+ !(productHandles === null || productHandles === void 0 ? void 0 : productHandles.length) &&
82
+ !(variantIds === null || variantIds === void 0 ? void 0 : variantIds.length)) {
83
+ url = `${baseURL}/products/by-page?${queryParams.toString()}`;
84
+ body = queryVariables || {};
85
+ }
85
86
  }
86
87
  const defaultFetcher = (url, body) => fetch(url, {
87
88
  method: body ? "POST" : "GET",
@@ -110,23 +111,21 @@ export function useProducts(props) {
110
111
  };
111
112
  // set local state when when SWR data is updated
112
113
  React.useEffect(() => {
113
- if (!data) {
114
- setCachedProducts([]);
114
+ if (!data)
115
115
  return;
116
- }
117
116
  // Determine the products array from data
118
117
  const productsArray = Array.isArray(data) ? data : data.products || [];
119
118
  if (!productsArray.length)
120
119
  return;
121
- setCachedProducts(productsArray);
120
+ setProductResponse(productsArray);
122
121
  }, [data]);
123
122
  return {
124
123
  products: formatProductData({
125
- data: cachedProducts,
124
+ data: productResponse,
126
125
  onlyAvailableProducts: (props === null || props === void 0 ? void 0 : props.mock) && (props === null || props === void 0 ? void 0 : props.onlyAvailableProducts),
127
126
  }),
128
127
  error,
129
- isLoading: !cachedProducts.length && isLoading,
128
+ isLoading: !productResponse.length && isLoading,
130
129
  isRefreshing: isLoading,
131
130
  cacheProduct,
132
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;AAE7C,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;CAChD;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,iDAIhB,kBAAkB,KAAG,mBAgDvB,CAAA;AAED,OAAO,EAAE,aAAa,EAAE,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 || !sortFilterData.dynamicFiltersEnabled)
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;AAE7C,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;IAajB,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;IASrB,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"}
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"}
@@ -1,4 +1,5 @@
1
1
  import AppStudioCache from "./AppStudioCache";
2
+ import { getProductGidsFromIds } from "../../../lib/utils";
2
3
  export default class ProductsLocalStorage extends AppStudioCache {
3
4
  getIdCacheKey(id) {
4
5
  return `${this.cachePrefix}-data-${id}`;
@@ -31,8 +32,11 @@ export default class ProductsLocalStorage extends AppStudioCache {
31
32
  getCacheItem({ id, handle, }) {
32
33
  if (!(id === null || id === void 0 ? void 0 : id.length) && !(handle === null || handle === void 0 ? void 0 : handle.length))
33
34
  return null;
34
- let objectId = id;
35
- if (handle === null || handle === void 0 ? void 0 : handle.length) {
35
+ let objectId = null;
36
+ if (id === null || id === void 0 ? void 0 : id.length) {
37
+ objectId = getProductGidsFromIds([id])[0];
38
+ }
39
+ else if (handle === null || handle === void 0 ? void 0 : handle.length) {
36
40
  objectId = localStorage.getItem(this.getHandleCacheKey(handle));
37
41
  }
38
42
  if (!(objectId === null || objectId === void 0 ? void 0 : objectId.length))
@@ -45,11 +49,11 @@ export default class ProductsLocalStorage extends AppStudioCache {
45
49
  getCacheItems(products) {
46
50
  var _a, _b;
47
51
  const returnProducts = ((_a = products === null || products === void 0 ? void 0 : products.productIds) === null || _a === void 0 ? void 0 : _a.length)
48
- ? products.productIds.map((id) => this.getCacheItem({ id }))
52
+ ? products.productIds.map((id) => this.getCacheItem({ id: getProductGidsFromIds([id])[0] }))
49
53
  : ((_b = products === null || products === void 0 ? void 0 : products.productHandles) === null || _b === void 0 ? void 0 : _b.length)
50
54
  ? products.productHandles.map((handle) => this.getCacheItem({ handle }))
51
55
  : [];
52
- return returnProducts;
56
+ return returnProducts.filter((product) => product !== null);
53
57
  }
54
58
  setCacheItem(product, cache, shouldExpire = true) {
55
59
  var _a, _b;
@@ -83,7 +83,7 @@ const labelVariants = cva("truncate", {
83
83
  });
84
84
  const Button = (_a) => {
85
85
  var { className, labelClassName, labelStyle, variant, size, asChild = false, loading, icon, iconColor, iconStrokeColor, iconPosition, iconSize, iconUrl, iconClassName, onClick, type, disableHaptic = false } = _a, props = __rest(_a, ["className", "labelClassName", "labelStyle", "variant", "size", "asChild", "loading", "icon", "iconColor", "iconStrokeColor", "iconPosition", "iconSize", "iconUrl", "iconClassName", "onClick", "type", "disableHaptic"]);
86
- const { action } = useActions();
86
+ const webbridgeActions = useActions();
87
87
  const Comp = asChild
88
88
  ? Slot
89
89
  : (onClick || type ? "button" : "div");
@@ -96,11 +96,12 @@ const Button = (_a) => {
96
96
  const LoadingButton = () => (_jsx("div", Object.assign({ className: cn("flex items-center justify-center", size === "icon" ? "h-5" : "h-6") }, { children: _jsx(Icon, { className: cn(iconVariants({ variant }), "h-5 w-5 animate-spin"), name: "loader", style: { color: iconColor } }) })));
97
97
  const handleClick = Comp === "button" && onClick
98
98
  ? (e) => {
99
+ var _a;
99
100
  try {
100
- onClick(e);
101
101
  if (!disableHaptic) {
102
- action("trigger/haptic");
102
+ (_a = webbridgeActions.action) === null || _a === void 0 ? void 0 : _a.call(webbridgeActions, "trigger/haptic");
103
103
  }
104
+ onClick(e);
104
105
  }
105
106
  catch (error) {
106
107
  console.error(error);
@@ -19,6 +19,7 @@ export interface QuantityPickerNEWProps extends React.HTMLAttributes<HTMLDivElem
19
19
  buttonCornerRadius?: number;
20
20
  debounceTime?: number;
21
21
  max?: number;
22
+ parentRef?: React.RefObject<HTMLDivElement>;
22
23
  }
23
24
  declare const QuantityPickerNEW: React.ForwardRefExoticComponent<QuantityPickerNEWProps & React.RefAttributes<HTMLDivElement>>;
24
25
  export { QuantityPickerNEW };
@@ -1 +1 @@
1
- {"version":3,"file":"quantity-pickerNEW.d.ts","sourceRoot":"","sources":["../../../components/ui/quantity-pickerNEW.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,WAAW,sBACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5C,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,KAAK,CAAC,iBAAiB,CAAA;IACxC,eAAe,EAAE,KAAK,CAAC,iBAAiB,CAAA;IACxC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAChC,WAAW,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAwED,QAAA,MAAM,iBAAiB,+FAoLtB,CAAA;AAID,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
1
+ {"version":3,"file":"quantity-pickerNEW.d.ts","sourceRoot":"","sources":["../../../components/ui/quantity-pickerNEW.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,WAAW,sBACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5C,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,KAAK,CAAC,iBAAiB,CAAA;IACxC,eAAe,EAAE,KAAK,CAAC,iBAAiB,CAAA;IACxC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAChC,WAAW,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;CAC5C;AAwED,QAAA,MAAM,iBAAiB,+FA0KtB,CAAA;AAID,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
@@ -15,7 +15,6 @@ import * as React from "react";
15
15
  import { cn } from "../../lib/utils";
16
16
  import { Icon } from "./icon";
17
17
  import { LoadingDots } from "./loading-dots";
18
- import debounce from "lodash/debounce";
19
18
  const IconButton = ({ iconUrl, iconColor, handler, className, style, disabled }) => {
20
19
  const [isButtonPressed, setIsButtonPressed] = React.useState(false);
21
20
  // Handle press state manually for the invisible button
@@ -40,23 +39,14 @@ const IconButton = ({ iconUrl, iconColor, handler, className, style, disabled })
40
39
  }, disabled: disabled, "aria-label": "Quantity button" })] })));
41
40
  };
42
41
  const QuantityPickerNEW = React.forwardRef((_a, ref) => {
43
- var { className, decreaseIconUrl, increaseIconUrl, deleteIconUrl, isDeleteOnly = false, iconColor, onDecreaseClick, onIncreaseClick, isDecreaseDisabled, isIncreaseDisabled, value, onValueSet, onAdjustQuantity, inputStyle, buttonStyle, buttonCornerRadius = 4, max = 99, loading = false, debounceTime = 300 } = _a, props = __rest(_a, ["className", "decreaseIconUrl", "increaseIconUrl", "deleteIconUrl", "isDeleteOnly", "iconColor", "onDecreaseClick", "onIncreaseClick", "isDecreaseDisabled", "isIncreaseDisabled", "value", "onValueSet", "onAdjustQuantity", "inputStyle", "buttonStyle", "buttonCornerRadius", "max", "loading", "debounceTime"]);
42
+ var { className, decreaseIconUrl, increaseIconUrl, deleteIconUrl, isDeleteOnly = false, iconColor, onDecreaseClick, onIncreaseClick, isDecreaseDisabled, isIncreaseDisabled, value, onValueSet, onAdjustQuantity, inputStyle, buttonStyle, buttonCornerRadius = 4, max = 99, loading = false, debounceTime = 300, parentRef } = _a, props = __rest(_a, ["className", "decreaseIconUrl", "increaseIconUrl", "deleteIconUrl", "isDeleteOnly", "iconColor", "onDecreaseClick", "onIncreaseClick", "isDecreaseDisabled", "isIncreaseDisabled", "value", "onValueSet", "onAdjustQuantity", "inputStyle", "buttonStyle", "buttonCornerRadius", "max", "loading", "debounceTime", "parentRef"]);
43
+ const inputRef = React.useRef(null);
44
44
  const [isFocused, setIsFocused] = React.useState(false);
45
- const pendingQuantityAdjustment = React.useRef(0);
46
45
  const [localInputValue, setLocalInputValue] = React.useState(value);
47
46
  // Update local state when external value changes
48
47
  React.useEffect(() => {
49
- if (pendingQuantityAdjustment.current === 0) {
50
- setLocalInputValue(value);
51
- }
48
+ setLocalInputValue(value);
52
49
  }, [value]);
53
- // Create debounced function for applying changes
54
- const debouncedApplyChanges = React.useMemo(() => debounce(() => {
55
- if (pendingQuantityAdjustment.current !== 0) {
56
- onAdjustQuantity(pendingQuantityAdjustment.current);
57
- pendingQuantityAdjustment.current = 0;
58
- }
59
- }, debounceTime), [debounceTime, onAdjustQuantity]);
60
50
  const leftButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderTopLeftRadius: buttonCornerRadius
61
51
  ? `${buttonCornerRadius}px`
62
52
  : undefined, borderBottomLeftRadius: buttonCornerRadius
@@ -68,56 +58,60 @@ const QuantityPickerNEW = React.forwardRef((_a, ref) => {
68
58
  ? `${buttonCornerRadius}px`
69
59
  : undefined });
70
60
  const singleButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderRadius: buttonCornerRadius ? `${buttonCornerRadius}px` : undefined });
71
- const adjustQuantity = (amount) => {
72
- const newAmount = localInputValue + amount;
73
- const clampedNewAmount = Math.min(Math.max(newAmount, 0), max);
74
- // Update local value immediately
75
- setLocalInputValue(clampedNewAmount);
76
- // Track pending change for batched update
77
- pendingQuantityAdjustment.current += amount;
78
- // Trigger debounced API update
79
- debouncedApplyChanges();
80
- };
81
61
  const handleDecreaseClick = (e) => {
82
62
  e.preventDefault();
83
63
  e.stopPropagation();
84
- adjustQuantity(-1);
64
+ onAdjustQuantity(-1);
85
65
  onDecreaseClick(e);
86
66
  };
87
67
  const handleIncreaseClick = (e) => {
88
68
  e.preventDefault();
89
69
  e.stopPropagation();
90
- adjustQuantity(1);
70
+ onAdjustQuantity(1);
91
71
  onIncreaseClick(e);
92
72
  };
93
- return (_jsxs("div", Object.assign({ className: cn("flex relative", className), ref: ref }, props, { children: [isDeleteOnly ? (_jsx(IconButton, { handler: handleDecreaseClick, iconUrl: deleteIconUrl, iconColor: iconColor, style: singleButtonStyle })) : (_jsxs(_Fragment, { children: [_jsx(IconButton, { handler: handleDecreaseClick, iconUrl: localInputValue === 1 ? deleteIconUrl : decreaseIconUrl, iconColor: iconColor, style: leftButtonStyle, disabled: isDecreaseDisabled || loading }), _jsx("input", { type: "number", pattern: "[0-9]*", disabled: loading, max: max, value: localInputValue, onBlur: (e) => {
73
+ return (_jsxs("div", Object.assign({ className: cn("flex relative", className), ref: ref }, props, { children: [isDeleteOnly ? (_jsx(IconButton, { handler: handleDecreaseClick, iconUrl: deleteIconUrl, iconColor: iconColor, style: singleButtonStyle })) : (_jsxs(_Fragment, { children: [_jsx(IconButton, { handler: handleDecreaseClick, iconUrl: value <= 1 ? deleteIconUrl : decreaseIconUrl, iconColor: iconColor, style: leftButtonStyle, disabled: isDecreaseDisabled || loading }), _jsx("input", { type: "number", step: 1, enterKeyHint: "done", ref: inputRef, disabled: loading, max: max, value: localInputValue, onBlur: (e) => {
94
74
  setIsFocused(false);
75
+ if (e.target.value === "") {
76
+ setLocalInputValue(value);
77
+ return;
78
+ }
95
79
  const parsedValue = parseInt(e.target.value) || 0;
96
80
  const clampedValue = Math.min(parsedValue, max);
97
- // Cancel any pending debounced operations
98
- debouncedApplyChanges.cancel();
99
- // Update and apply changes
100
- const delta = clampedValue - value;
101
- pendingQuantityAdjustment.current = delta;
102
- setLocalInputValue(clampedValue);
103
81
  onValueSet(clampedValue);
104
- }, onFocus: () => {
82
+ }, onFocus: (e) => {
83
+ setLocalInputValue("");
105
84
  setIsFocused(true);
85
+ setTimeout(() => {
86
+ var _a;
87
+ (_a = parentRef === null || parentRef === void 0 ? void 0 : parentRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
88
+ block: "start",
89
+ inline: "nearest",
90
+ behavior: "smooth",
91
+ });
92
+ }, 250);
106
93
  }, onChange: (e) => {
107
94
  const inputValue = e.target.value;
108
95
  if (inputValue === "") {
109
- setLocalInputValue(0);
96
+ setLocalInputValue("");
110
97
  }
111
98
  else {
112
- const parsedValue = parseInt(inputValue);
99
+ const parsedValue = parseInt(inputValue, 10);
113
100
  if (!isNaN(parsedValue)) {
114
101
  const clampedValue = Math.min(parsedValue, max);
115
102
  setLocalInputValue(clampedValue);
116
103
  }
117
104
  }
105
+ }, onKeyDown: (e) => {
106
+ var _a;
107
+ if (e.key === "Enter") {
108
+ e.preventDefault();
109
+ e.stopPropagation();
110
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
111
+ }
118
112
  }, className: "w-8 h-7 focus-visible:outline-no ne text-center bg-coreColors-inputBackground text-textColors-primaryColor border-t border-b border-coreColors-dividingLines", style: Object.assign(Object.assign({}, inputStyle), { borderRadius: (inputStyle === null || inputStyle === void 0 ? void 0 : inputStyle.borderRadius)
119
113
  ? `${inputStyle.borderRadius}px`
120
- : 0 }), inputMode: "numeric" }), _jsx(IconButton, { handler: handleIncreaseClick, iconUrl: increaseIconUrl, iconColor: iconColor, style: rightButtonStyle, disabled: isIncreaseDisabled || loading || localInputValue >= max })] })), _jsx(LoadingDots, { show: loading, size: 1, iconColor: iconColor })] })));
114
+ : 0 }), inputMode: "numeric" }), _jsx(IconButton, { handler: handleIncreaseClick, iconUrl: increaseIconUrl, iconColor: iconColor, style: rightButtonStyle, disabled: isIncreaseDisabled || loading || value >= max })] })), _jsx(LoadingDots, { show: loading, size: 1, iconColor: iconColor })] })));
121
115
  });
122
116
  QuantityPickerNEW.displayName = "QuantityPickerNEW";
123
117
  export { QuantityPickerNEW };
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
  }
@@ -2016,6 +2023,10 @@ video {
2016
2023
  .text-\[23px\] {
2017
2024
  font-size: 23px;
2018
2025
  }
2026
+ .text-base {
2027
+ font-size: 1rem;
2028
+ line-height: 1.5rem;
2029
+ }
2019
2030
  .text-lg {
2020
2031
  font-size: 1.125rem;
2021
2032
  line-height: 1.75rem;
@@ -2619,6 +2630,10 @@ body::-webkit-scrollbar {
2619
2630
  background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
2620
2631
  }
2621
2632
 
2633
+ .hover\:no-underline:hover {
2634
+ text-decoration-line: none;
2635
+ }
2636
+
2622
2637
  .hover\:opacity-90:hover {
2623
2638
  opacity: 0.9;
2624
2639
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapcart/mobile-components",
3
- "version": "0.8.62",
3
+ "version": "0.8.64",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "style": "dist/styles.css",