@tapcart/mobile-components 0.9.1 → 0.9.2
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-scroll-direction-safe.d.ts +8 -0
- package/dist/components/hooks/use-scroll-direction-safe.d.ts.map +1 -0
- package/dist/components/hooks/use-scroll-direction-safe.js +75 -0
- package/dist/components/hooks/use-transition-compat.d.ts +12 -0
- package/dist/components/hooks/use-transition-compat.d.ts.map +1 -0
- package/dist/components/hooks/use-transition-compat.js +42 -0
- package/dist/components/hooks/use-transition-compat.test.d.ts +2 -0
- package/dist/components/hooks/use-transition-compat.test.d.ts.map +1 -0
- package/dist/components/hooks/use-transition-compat.test.js +179 -0
- package/dist/components/hooks/use-transition-shim.d.ts +7 -0
- package/dist/components/hooks/use-transition-shim.d.ts.map +1 -0
- package/dist/components/hooks/use-transition-shim.js +25 -0
- package/dist/components/ui/quantity-picker copy.d.ts +25 -0
- package/dist/components/ui/quantity-picker copy.d.ts.map +1 -0
- package/dist/components/ui/quantity-picker copy.js +125 -0
- package/dist/components/ui/quantity-pickerDEP.d.ts +23 -0
- package/dist/components/ui/quantity-pickerDEP.d.ts.map +1 -0
- package/dist/components/ui/quantity-pickerDEP.js +88 -0
- package/dist/components/ui/quantity-pickerDEPRECATED.d.ts +23 -0
- package/dist/components/ui/quantity-pickerDEPRECATED.d.ts.map +1 -0
- package/dist/components/ui/quantity-pickerDEPRECATED.js +88 -0
- package/dist/components/ui/wishlist-select.d.ts +54 -0
- package/dist/components/ui/wishlist-select.d.ts.map +1 -1
- package/dist/components/ui/wishlist-select.js +88 -12
- package/dist/components/ui/wishlist.d.ts +29 -1
- package/dist/components/ui/wishlist.d.ts.map +1 -1
- package/dist/components/ui/wishlist.js +57 -20
- package/dist/lib/state.d.ts +3 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +9 -0
- package/dist/styles.css +0 -11
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type ScrollDirection = "up" | "down" | null;
|
|
2
|
+
interface ScrollData {
|
|
3
|
+
direction: ScrollDirection;
|
|
4
|
+
scrollY: number;
|
|
5
|
+
}
|
|
6
|
+
declare function useScrollDirectionSafe(threshold?: number): ScrollData;
|
|
7
|
+
export { useScrollDirectionSafe };
|
|
8
|
+
//# sourceMappingURL=use-scroll-direction-safe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-scroll-direction-safe.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-scroll-direction-safe.ts"],"names":[],"mappings":"AAWA,KAAK,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;AAE3C,UAAU,UAAU;IAClB,SAAS,EAAE,eAAe,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,iBAAS,sBAAsB,CAAC,SAAS,GAAE,MAAY,GAAG,UAAU,CA2EnE;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAA"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useEffect, useRef } from "react";
|
|
3
|
+
// Safe import of useTransition - will be undefined in older React versions
|
|
4
|
+
let useTransition;
|
|
5
|
+
try {
|
|
6
|
+
useTransition = require("react").useTransition;
|
|
7
|
+
}
|
|
8
|
+
catch (_a) {
|
|
9
|
+
// useTransition not available
|
|
10
|
+
}
|
|
11
|
+
function useScrollDirectionSafe(threshold = 100) {
|
|
12
|
+
const [scrollData, setScrollData] = useState({
|
|
13
|
+
direction: null,
|
|
14
|
+
scrollY: 0,
|
|
15
|
+
});
|
|
16
|
+
// Conditionally use useTransition if available
|
|
17
|
+
const transitionResult = useTransition === null || useTransition === void 0 ? void 0 : useTransition();
|
|
18
|
+
const [isPending, startTransition] = transitionResult || [
|
|
19
|
+
false,
|
|
20
|
+
(callback) => callback(),
|
|
21
|
+
];
|
|
22
|
+
const scrollElement = useRef(null);
|
|
23
|
+
const hasScrollListener = useRef(false);
|
|
24
|
+
const lastScrollY = useRef(0);
|
|
25
|
+
const isBouncing = useRef(false);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
var _a;
|
|
28
|
+
if (typeof window === "undefined") {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const updateScrollDirection = () => {
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
if (document.body.hasAttribute("data-scroll-locked")) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const scrollY = ((_a = scrollElement.current) === null || _a === void 0 ? void 0 : _a.scrollTop) || 0;
|
|
37
|
+
const scrollHeight = ((_b = scrollElement.current) === null || _b === void 0 ? void 0 : _b.scrollHeight) || 0;
|
|
38
|
+
const clientHeight = ((_c = scrollElement.current) === null || _c === void 0 ? void 0 : _c.clientHeight) || 0;
|
|
39
|
+
// Detect if the user is at the top or bottom of the page
|
|
40
|
+
if (scrollY <= 0 || scrollY + clientHeight >= scrollHeight) {
|
|
41
|
+
isBouncing.current = true;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
isBouncing.current = false;
|
|
45
|
+
}
|
|
46
|
+
// Prevent updating scroll direction if the page is bouncing
|
|
47
|
+
if (!isBouncing.current &&
|
|
48
|
+
Math.abs(scrollY - lastScrollY.current) > threshold) {
|
|
49
|
+
startTransition(() => {
|
|
50
|
+
setScrollData({
|
|
51
|
+
direction: scrollY > lastScrollY.current ? "down" : "up",
|
|
52
|
+
scrollY,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
lastScrollY.current = scrollY > 0 ? scrollY : 0;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
if (!scrollElement.current) {
|
|
59
|
+
scrollElement.current = document.getElementById("tc-vgsl");
|
|
60
|
+
}
|
|
61
|
+
if (!hasScrollListener.current) {
|
|
62
|
+
(_a = scrollElement.current) === null || _a === void 0 ? void 0 : _a.addEventListener("scroll", updateScrollDirection, {
|
|
63
|
+
passive: true,
|
|
64
|
+
});
|
|
65
|
+
hasScrollListener.current = true;
|
|
66
|
+
}
|
|
67
|
+
return () => {
|
|
68
|
+
var _a;
|
|
69
|
+
(_a = scrollElement.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("scroll", updateScrollDirection);
|
|
70
|
+
hasScrollListener.current = false;
|
|
71
|
+
};
|
|
72
|
+
}, [threshold, startTransition]);
|
|
73
|
+
return scrollData;
|
|
74
|
+
}
|
|
75
|
+
export { useScrollDirectionSafe };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React version-aware useTransition compatibility hook
|
|
3
|
+
* Automatically detects React version and provides appropriate behavior
|
|
4
|
+
*
|
|
5
|
+
* Warning: This hook may cause your app to spontaneously time travel.
|
|
6
|
+
* Side effects include: temporal paradoxes and meeting your past self.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useTransitionCompat(): [
|
|
9
|
+
boolean,
|
|
10
|
+
(callback: () => void) => void
|
|
11
|
+
];
|
|
12
|
+
//# sourceMappingURL=use-transition-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-transition-compat.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-transition-compat.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI;IACrC,OAAO;IACP,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI;CAC/B,CAuCA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* React version-aware useTransition compatibility hook
|
|
5
|
+
* Automatically detects React version and provides appropriate behavior
|
|
6
|
+
*
|
|
7
|
+
* Warning: This hook may cause your app to spontaneously time travel.
|
|
8
|
+
* Side effects include: temporal paradoxes and meeting your past self.
|
|
9
|
+
*/
|
|
10
|
+
export function useTransitionCompat() {
|
|
11
|
+
const [fallbackIsPending, setFallbackIsPending] = React.useState(false);
|
|
12
|
+
const reactVersion = React.version;
|
|
13
|
+
const majorVersion = parseInt((reactVersion === null || reactVersion === void 0 ? void 0 : reactVersion.split(".")[0]) || "0", 10);
|
|
14
|
+
// Use native useTransition if available in React 18+
|
|
15
|
+
const hasNativeUseTransition = majorVersion >= 18 && "useTransition" in React;
|
|
16
|
+
const nativeUseTransition = hasNativeUseTransition
|
|
17
|
+
? React.useTransition()
|
|
18
|
+
: null;
|
|
19
|
+
const startTransition = React.useCallback((callback) => {
|
|
20
|
+
if (nativeUseTransition) {
|
|
21
|
+
// Use native startTransition
|
|
22
|
+
nativeUseTransition[1](callback);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
setFallbackIsPending(true);
|
|
26
|
+
if (majorVersion >= 17) {
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
callback();
|
|
29
|
+
setFallbackIsPending(false);
|
|
30
|
+
}, 0);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
callback();
|
|
34
|
+
setFallbackIsPending(false);
|
|
35
|
+
}
|
|
36
|
+
}, [majorVersion, nativeUseTransition]);
|
|
37
|
+
// Return native pending state if available, otherwise fallback state
|
|
38
|
+
const isPending = nativeUseTransition
|
|
39
|
+
? nativeUseTransition[0]
|
|
40
|
+
: fallbackIsPending;
|
|
41
|
+
return [isPending, startTransition];
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-transition-compat.test.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-transition-compat.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
/* eslint-disable no-undef */
|
|
11
|
+
import { renderHook, act } from "@testing-library/react";
|
|
12
|
+
import React from "react";
|
|
13
|
+
import { useTransitionCompat } from "./use-transition-compat";
|
|
14
|
+
// Mock React to control version and useTransition availability
|
|
15
|
+
const mockReact = React;
|
|
16
|
+
describe("useTransitionCompat", () => {
|
|
17
|
+
// Store original values to restore after tests
|
|
18
|
+
const originalVersion = React.version;
|
|
19
|
+
const originalUseTransition = React.useTransition;
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
// Restore original React properties
|
|
22
|
+
mockReact.version = originalVersion;
|
|
23
|
+
if (originalUseTransition) {
|
|
24
|
+
mockReact.useTransition = originalUseTransition;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
delete mockReact.useTransition;
|
|
28
|
+
}
|
|
29
|
+
jest.clearAllTimers();
|
|
30
|
+
jest.useRealTimers();
|
|
31
|
+
});
|
|
32
|
+
describe("React 18+ with native useTransition", () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
mockReact.version = "18.2.0";
|
|
35
|
+
mockReact.useTransition = jest.fn(() => [false, jest.fn()]);
|
|
36
|
+
});
|
|
37
|
+
it("should use native useTransition when available in React 18+", () => {
|
|
38
|
+
const mockStartTransition = jest.fn();
|
|
39
|
+
mockReact.useTransition = jest.fn(() => [false, mockStartTransition]);
|
|
40
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
41
|
+
const [isPending, startTransition] = result.current;
|
|
42
|
+
// Should initially not be pending
|
|
43
|
+
expect(isPending).toBe(false);
|
|
44
|
+
// Should call native useTransition
|
|
45
|
+
expect(mockReact.useTransition).toHaveBeenCalled();
|
|
46
|
+
// Test startTransition calls native function
|
|
47
|
+
const callback = jest.fn();
|
|
48
|
+
act(() => {
|
|
49
|
+
startTransition(callback);
|
|
50
|
+
});
|
|
51
|
+
expect(mockStartTransition).toHaveBeenCalledWith(callback);
|
|
52
|
+
});
|
|
53
|
+
it("should handle pending state from native useTransition", () => {
|
|
54
|
+
const mockStartTransition = jest.fn();
|
|
55
|
+
mockReact.useTransition = jest.fn(() => [true, mockStartTransition]);
|
|
56
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
57
|
+
const [isPending] = result.current;
|
|
58
|
+
expect(isPending).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("React 17 fallback behavior", () => {
|
|
62
|
+
beforeEach(() => {
|
|
63
|
+
mockReact.version = "17.0.2";
|
|
64
|
+
delete mockReact.useTransition;
|
|
65
|
+
jest.useFakeTimers();
|
|
66
|
+
});
|
|
67
|
+
it("should use setTimeout fallback for React 17", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
69
|
+
const [initialPending, startTransition] = result.current;
|
|
70
|
+
// Initially should not be pending
|
|
71
|
+
expect(initialPending).toBe(false);
|
|
72
|
+
const callback = jest.fn();
|
|
73
|
+
// Start transition
|
|
74
|
+
act(() => {
|
|
75
|
+
startTransition(callback);
|
|
76
|
+
});
|
|
77
|
+
// Should be pending immediately after calling startTransition
|
|
78
|
+
expect(result.current[0]).toBe(true);
|
|
79
|
+
// Callback should not be called yet
|
|
80
|
+
expect(callback).not.toHaveBeenCalled();
|
|
81
|
+
// Fast-forward timers
|
|
82
|
+
act(() => {
|
|
83
|
+
jest.runAllTimers();
|
|
84
|
+
});
|
|
85
|
+
// Callback should now be called and pending should be false
|
|
86
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
87
|
+
expect(result.current[0]).toBe(false);
|
|
88
|
+
}));
|
|
89
|
+
});
|
|
90
|
+
describe("React < 17 immediate execution", () => {
|
|
91
|
+
beforeEach(() => {
|
|
92
|
+
mockReact.version = "16.14.0";
|
|
93
|
+
delete mockReact.useTransition;
|
|
94
|
+
});
|
|
95
|
+
it("should execute callback immediately for React < 17", () => {
|
|
96
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
97
|
+
const [initialPending, startTransition] = result.current;
|
|
98
|
+
// Initially should not be pending
|
|
99
|
+
expect(initialPending).toBe(false);
|
|
100
|
+
const callback = jest.fn();
|
|
101
|
+
// Start transition
|
|
102
|
+
act(() => {
|
|
103
|
+
startTransition(callback);
|
|
104
|
+
});
|
|
105
|
+
// Callback should be called immediately and not be pending
|
|
106
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(result.current[0]).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
describe("Edge cases", () => {
|
|
111
|
+
it("should handle missing React version gracefully", () => {
|
|
112
|
+
mockReact.version = undefined;
|
|
113
|
+
delete mockReact.useTransition;
|
|
114
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
115
|
+
const [isPending, startTransition] = result.current;
|
|
116
|
+
expect(isPending).toBe(false);
|
|
117
|
+
const callback = jest.fn();
|
|
118
|
+
act(() => {
|
|
119
|
+
startTransition(callback);
|
|
120
|
+
});
|
|
121
|
+
// Should execute immediately when version is unknown
|
|
122
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
123
|
+
expect(result.current[0]).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
it("should handle malformed version strings", () => {
|
|
126
|
+
mockReact.version = "not-a-version";
|
|
127
|
+
delete mockReact.useTransition;
|
|
128
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
129
|
+
const [isPending, startTransition] = result.current;
|
|
130
|
+
expect(isPending).toBe(false);
|
|
131
|
+
const callback = jest.fn();
|
|
132
|
+
act(() => {
|
|
133
|
+
startTransition(callback);
|
|
134
|
+
});
|
|
135
|
+
// Should execute immediately when version parsing fails
|
|
136
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
137
|
+
expect(result.current[0]).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
it("should handle React 18+ without useTransition (edge case)", () => {
|
|
140
|
+
mockReact.version = "18.0.0";
|
|
141
|
+
delete mockReact.useTransition;
|
|
142
|
+
jest.useFakeTimers();
|
|
143
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
144
|
+
const [initialPending, startTransition] = result.current;
|
|
145
|
+
expect(initialPending).toBe(false);
|
|
146
|
+
const callback = jest.fn();
|
|
147
|
+
act(() => {
|
|
148
|
+
startTransition(callback);
|
|
149
|
+
});
|
|
150
|
+
// Should fall back to setTimeout behavior even in React 18 if useTransition is missing
|
|
151
|
+
expect(result.current[0]).toBe(true);
|
|
152
|
+
act(() => {
|
|
153
|
+
jest.runAllTimers();
|
|
154
|
+
});
|
|
155
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
156
|
+
expect(result.current[0]).toBe(false);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe("Return value consistency", () => {
|
|
160
|
+
it("should always return tuple with boolean and function", () => {
|
|
161
|
+
mockReact.version = "18.2.0";
|
|
162
|
+
mockReact.useTransition = jest.fn(() => [false, jest.fn()]);
|
|
163
|
+
const { result } = renderHook(() => useTransitionCompat());
|
|
164
|
+
const [isPending, startTransition] = result.current;
|
|
165
|
+
expect(typeof isPending).toBe("boolean");
|
|
166
|
+
expect(typeof startTransition).toBe("function");
|
|
167
|
+
});
|
|
168
|
+
it("should maintain referential stability of startTransition function", () => {
|
|
169
|
+
mockReact.version = "17.0.0";
|
|
170
|
+
delete mockReact.useTransition;
|
|
171
|
+
const { result, rerender } = renderHook(() => useTransitionCompat());
|
|
172
|
+
const firstStartTransition = result.current[1];
|
|
173
|
+
rerender();
|
|
174
|
+
const secondStartTransition = result.current[1];
|
|
175
|
+
// Function reference should be stable due to useCallback
|
|
176
|
+
expect(firstStartTransition).toBe(secondStartTransition);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shim for useTransition that falls back gracefully on older React versions
|
|
3
|
+
* In older versions, we just execute the callback immediately without transition
|
|
4
|
+
* @returns [isPending, startTransition] - same signature as React's useTransition
|
|
5
|
+
*/
|
|
6
|
+
export declare function useTransitionShim(): [boolean, (callback: () => void) => void];
|
|
7
|
+
//# sourceMappingURL=use-transition-shim.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-transition-shim.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-transition-shim.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,CAoB7E"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useTransition as useReactTransition } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Shim for useTransition that falls back gracefully on older React versions
|
|
5
|
+
* In older versions, we just execute the callback immediately without transition
|
|
6
|
+
* @returns [isPending, startTransition] - same signature as React's useTransition
|
|
7
|
+
*/
|
|
8
|
+
export function useTransitionShim() {
|
|
9
|
+
// Check if useTransition exists (React 18+)
|
|
10
|
+
if (typeof useReactTransition === "function") {
|
|
11
|
+
try {
|
|
12
|
+
return useReactTransition();
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
// Fallback if useTransition fails for any reason
|
|
16
|
+
console.warn("useTransition not available, falling back to immediate execution");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Fallback for React < 18: execute immediately, never pending
|
|
20
|
+
const startTransition = (callback) => {
|
|
21
|
+
// Execute callback immediately in older React versions
|
|
22
|
+
callback();
|
|
23
|
+
};
|
|
24
|
+
return [false, startTransition];
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface QuantityPickerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
decreaseIconUrl: string;
|
|
4
|
+
increaseIconUrl: string;
|
|
5
|
+
deleteIconUrl: string;
|
|
6
|
+
isDeleteOnly: boolean;
|
|
7
|
+
iconColor: string;
|
|
8
|
+
onDecreaseClick: React.ReactEventHandler;
|
|
9
|
+
onIncreaseClick: React.ReactEventHandler;
|
|
10
|
+
isDecreaseDisabled?: boolean;
|
|
11
|
+
isIncreaseDisabled?: boolean;
|
|
12
|
+
loading?: boolean;
|
|
13
|
+
value: number;
|
|
14
|
+
onValueSet: (_: number) => void;
|
|
15
|
+
onAdjustQuantity: (_: number) => void;
|
|
16
|
+
className?: string;
|
|
17
|
+
inputStyle?: React.CSSProperties;
|
|
18
|
+
buttonStyle?: React.CSSProperties;
|
|
19
|
+
buttonCornerRadius?: number;
|
|
20
|
+
debounceTime?: number;
|
|
21
|
+
max?: number;
|
|
22
|
+
}
|
|
23
|
+
declare const QuantityPicker: React.ForwardRefExoticComponent<QuantityPickerProps & React.RefAttributes<HTMLDivElement>>;
|
|
24
|
+
export { QuantityPicker };
|
|
25
|
+
//# sourceMappingURL=quantity-picker%20copy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantity-picker copy.d.ts","sourceRoot":"","sources":["../../../components/ui/quantity-picker copy.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,MAAM,WAAW,mBACf,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;AA0ED,QAAA,MAAM,cAAc,4FAiLnB,CAAA;AAID,OAAO,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
import { cn } from "../../lib/utils";
|
|
16
|
+
import { Icon } from "./icon";
|
|
17
|
+
import { useTap } from "./tap";
|
|
18
|
+
import { LoadingDots } from "./loading-dots";
|
|
19
|
+
import debounce from "lodash/debounce";
|
|
20
|
+
const IconButton = ({ iconUrl, iconColor, handler, className, style, disabled }) => {
|
|
21
|
+
const { onTap, isPressed, ref: tapRef } = useTap();
|
|
22
|
+
const [isButtonPressed, setIsButtonPressed] = React.useState(false);
|
|
23
|
+
// Handle press state manually for the invisible button
|
|
24
|
+
const handleMouseDown = React.useCallback(() => {
|
|
25
|
+
if (!disabled)
|
|
26
|
+
setIsButtonPressed(true);
|
|
27
|
+
}, [disabled]);
|
|
28
|
+
const handleMouseUp = React.useCallback(() => {
|
|
29
|
+
setIsButtonPressed(false);
|
|
30
|
+
}, []);
|
|
31
|
+
// Calculate the visual styles for the button
|
|
32
|
+
const visualButtonStyle = Object.assign({}, style);
|
|
33
|
+
return (_jsxs("div", Object.assign({ className: "relative h-7 w-7", style: { touchAction: "manipulation" } }, { children: [_jsx("div", Object.assign({ className: cn("absolute inset-0 flex items-center justify-center bg-stateColors-skeleton border border-coreColors-dividingLines", className, disabled ? "opacity-50" : ""), style: visualButtonStyle, "aria-hidden": "true" }, { children: _jsx(Icon, { url: iconUrl, size: "sm", strokeColor: iconColor, strokeWidth: 4, style: {
|
|
34
|
+
opacity: isPressed || isButtonPressed ? 0.7 : 1,
|
|
35
|
+
} }) })), _jsx("button", { onClick: onTap(handler), onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onTouchStart: handleMouseDown, onTouchEnd: handleMouseUp, onTouchCancel: handleMouseUp, ref: tapRef, className: "absolute cursor-pointer", style: {
|
|
36
|
+
top: "-8px",
|
|
37
|
+
right: "-8px",
|
|
38
|
+
bottom: "-8px",
|
|
39
|
+
left: "-8px",
|
|
40
|
+
opacity: 0,
|
|
41
|
+
zIndex: 10,
|
|
42
|
+
}, disabled: disabled, "aria-label": "Quantity button" })] })));
|
|
43
|
+
};
|
|
44
|
+
const QuantityPicker = React.forwardRef((_a, ref) => {
|
|
45
|
+
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"]);
|
|
46
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
47
|
+
const pendingQuantityAdjustment = React.useRef(0);
|
|
48
|
+
const [localInputValue, setLocalInputValue] = React.useState(value);
|
|
49
|
+
// Update local state when external value changes
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
if (pendingQuantityAdjustment.current === 0) {
|
|
52
|
+
setLocalInputValue(value);
|
|
53
|
+
}
|
|
54
|
+
}, [value]);
|
|
55
|
+
// Create debounced function for applying changes
|
|
56
|
+
const debouncedApplyChanges = React.useMemo(() => debounce(() => {
|
|
57
|
+
if (pendingQuantityAdjustment.current !== 0) {
|
|
58
|
+
onAdjustQuantity(pendingQuantityAdjustment.current);
|
|
59
|
+
pendingQuantityAdjustment.current = 0;
|
|
60
|
+
}
|
|
61
|
+
}, debounceTime), [debounceTime, onAdjustQuantity]);
|
|
62
|
+
const leftButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderTopLeftRadius: buttonCornerRadius
|
|
63
|
+
? `${buttonCornerRadius}px`
|
|
64
|
+
: undefined, borderBottomLeftRadius: buttonCornerRadius
|
|
65
|
+
? `${buttonCornerRadius}px`
|
|
66
|
+
: undefined });
|
|
67
|
+
const rightButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderTopRightRadius: buttonCornerRadius
|
|
68
|
+
? `${buttonCornerRadius}px`
|
|
69
|
+
: undefined, borderBottomRightRadius: buttonCornerRadius
|
|
70
|
+
? `${buttonCornerRadius}px`
|
|
71
|
+
: undefined });
|
|
72
|
+
const singleButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderRadius: buttonCornerRadius ? `${buttonCornerRadius}px` : undefined });
|
|
73
|
+
const adjustQuantity = (amount) => {
|
|
74
|
+
const newAmount = localInputValue + amount;
|
|
75
|
+
const clampedNewAmount = Math.min(Math.max(newAmount, 0), max);
|
|
76
|
+
// Update local value immediately
|
|
77
|
+
setLocalInputValue(clampedNewAmount);
|
|
78
|
+
// Track pending change for batched update
|
|
79
|
+
pendingQuantityAdjustment.current += amount;
|
|
80
|
+
// Trigger debounced API update
|
|
81
|
+
debouncedApplyChanges();
|
|
82
|
+
};
|
|
83
|
+
const handleDecreaseClick = (e) => {
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
adjustQuantity(-1);
|
|
87
|
+
onDecreaseClick(e);
|
|
88
|
+
};
|
|
89
|
+
const handleIncreaseClick = (e) => {
|
|
90
|
+
e.preventDefault();
|
|
91
|
+
e.stopPropagation();
|
|
92
|
+
adjustQuantity(1);
|
|
93
|
+
onIncreaseClick(e);
|
|
94
|
+
};
|
|
95
|
+
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) => {
|
|
96
|
+
setIsFocused(false);
|
|
97
|
+
const parsedValue = parseInt(e.target.value) || 0;
|
|
98
|
+
const clampedValue = Math.min(parsedValue, max);
|
|
99
|
+
// Cancel any pending debounced operations
|
|
100
|
+
debouncedApplyChanges.cancel();
|
|
101
|
+
// Update and apply changes
|
|
102
|
+
const delta = clampedValue - value;
|
|
103
|
+
pendingQuantityAdjustment.current = delta;
|
|
104
|
+
setLocalInputValue(clampedValue);
|
|
105
|
+
onValueSet(clampedValue);
|
|
106
|
+
}, onFocus: () => {
|
|
107
|
+
setIsFocused(true);
|
|
108
|
+
}, onChange: (e) => {
|
|
109
|
+
const inputValue = e.target.value;
|
|
110
|
+
if (inputValue === "") {
|
|
111
|
+
setLocalInputValue(0);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
const parsedValue = parseInt(inputValue);
|
|
115
|
+
if (!isNaN(parsedValue)) {
|
|
116
|
+
const clampedValue = Math.min(parsedValue, max);
|
|
117
|
+
setLocalInputValue(clampedValue);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}, 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)
|
|
121
|
+
? `${inputStyle.borderRadius}px`
|
|
122
|
+
: 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 })] })));
|
|
123
|
+
});
|
|
124
|
+
QuantityPicker.displayName = "QuantityPicker";
|
|
125
|
+
export { QuantityPicker };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface QuantityPickerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
decreaseIconUrl: string;
|
|
4
|
+
increaseIconUrl: string;
|
|
5
|
+
deleteIconUrl: string;
|
|
6
|
+
isDeleteOnly: boolean;
|
|
7
|
+
iconColor: string;
|
|
8
|
+
onDecreaseClick: React.ReactEventHandler;
|
|
9
|
+
onIncreaseClick: React.ReactEventHandler;
|
|
10
|
+
isDecreaseDisabled?: boolean;
|
|
11
|
+
isIncreaseDisabled?: boolean;
|
|
12
|
+
loading?: boolean;
|
|
13
|
+
value: number;
|
|
14
|
+
setValue: (_: number) => void;
|
|
15
|
+
className?: string;
|
|
16
|
+
inputStyle?: React.CSSProperties;
|
|
17
|
+
buttonStyle?: React.CSSProperties;
|
|
18
|
+
buttonCornerRadius?: number;
|
|
19
|
+
max?: number;
|
|
20
|
+
}
|
|
21
|
+
declare const QuantityPicker: React.ForwardRefExoticComponent<QuantityPickerProps & React.RefAttributes<HTMLDivElement>>;
|
|
22
|
+
export { QuantityPicker };
|
|
23
|
+
//# sourceMappingURL=quantity-pickerDEP.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantity-pickerDEP.d.ts","sourceRoot":"","sources":["../../../components/ui/quantity-pickerDEP.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,WAAW,mBACf,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,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,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,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AA0ED,QAAA,MAAM,cAAc,4FA8HnB,CAAA;AAID,OAAO,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
import { cn } from "../../lib/utils";
|
|
16
|
+
import { Icon } from "./icon";
|
|
17
|
+
import { useTap } from "./tap";
|
|
18
|
+
import { LoadingDots } from "./loading-dots";
|
|
19
|
+
const IconButton = ({ iconUrl, iconColor, handler, className, style, disabled }) => {
|
|
20
|
+
const { onTap, isPressed, ref: tapRef } = useTap();
|
|
21
|
+
const [isButtonPressed, setIsButtonPressed] = React.useState(false);
|
|
22
|
+
// Handle press state manually for the invisible button
|
|
23
|
+
const handleMouseDown = React.useCallback(() => {
|
|
24
|
+
if (!disabled)
|
|
25
|
+
setIsButtonPressed(true);
|
|
26
|
+
}, [disabled]);
|
|
27
|
+
const handleMouseUp = React.useCallback(() => {
|
|
28
|
+
setIsButtonPressed(false);
|
|
29
|
+
}, []);
|
|
30
|
+
// Calculate the visual styles for the button
|
|
31
|
+
const visualButtonStyle = Object.assign({}, style);
|
|
32
|
+
return (_jsxs("div", Object.assign({ className: "relative h-7 w-7", style: { touchAction: "manipulation" } }, { children: [_jsx("div", Object.assign({ className: cn("absolute inset-0 flex items-center justify-center bg-stateColors-skeleton border border-coreColors-dividingLines", className, disabled ? "opacity-50" : ""), style: visualButtonStyle, "aria-hidden": "true" }, { children: _jsx(Icon, { url: iconUrl, size: "sm", strokeColor: iconColor, strokeWidth: 4, style: {
|
|
33
|
+
opacity: isPressed || isButtonPressed ? 0.7 : 1,
|
|
34
|
+
} }) })), _jsx("button", { onClick: onTap(handler), onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onTouchStart: handleMouseDown, onTouchEnd: handleMouseUp, onTouchCancel: handleMouseUp, ref: tapRef, className: "absolute cursor-pointer", style: {
|
|
35
|
+
top: "-8px",
|
|
36
|
+
right: "-8px",
|
|
37
|
+
bottom: "-8px",
|
|
38
|
+
left: "-8px",
|
|
39
|
+
opacity: 0,
|
|
40
|
+
zIndex: 10,
|
|
41
|
+
}, disabled: disabled, "aria-label": "Quantity button" })] })));
|
|
42
|
+
};
|
|
43
|
+
const QuantityPicker = React.forwardRef((_a, ref) => {
|
|
44
|
+
var { className, decreaseIconUrl, increaseIconUrl, deleteIconUrl, isDeleteOnly = false, iconColor, onDecreaseClick, onIncreaseClick, isDecreaseDisabled, isIncreaseDisabled, value, setValue, inputStyle, buttonStyle, buttonCornerRadius = 4, max = 99, loading = false } = _a, props = __rest(_a, ["className", "decreaseIconUrl", "increaseIconUrl", "deleteIconUrl", "isDeleteOnly", "iconColor", "onDecreaseClick", "onIncreaseClick", "isDecreaseDisabled", "isIncreaseDisabled", "value", "setValue", "inputStyle", "buttonStyle", "buttonCornerRadius", "max", "loading"]);
|
|
45
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
46
|
+
const [localValue, setLocalValue] = React.useState(value.toString());
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
if (!isFocused) {
|
|
49
|
+
setLocalValue(value.toString());
|
|
50
|
+
}
|
|
51
|
+
}, [value, isFocused]);
|
|
52
|
+
const leftButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderTopLeftRadius: buttonCornerRadius
|
|
53
|
+
? `${buttonCornerRadius}px`
|
|
54
|
+
: undefined, borderBottomLeftRadius: buttonCornerRadius
|
|
55
|
+
? `${buttonCornerRadius}px`
|
|
56
|
+
: undefined });
|
|
57
|
+
const rightButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderTopRightRadius: buttonCornerRadius
|
|
58
|
+
? `${buttonCornerRadius}px`
|
|
59
|
+
: undefined, borderBottomRightRadius: buttonCornerRadius
|
|
60
|
+
? `${buttonCornerRadius}px`
|
|
61
|
+
: undefined });
|
|
62
|
+
const singleButtonStyle = Object.assign(Object.assign({}, buttonStyle), { borderRadius: buttonCornerRadius ? `${buttonCornerRadius}px` : undefined });
|
|
63
|
+
return (_jsxs("div", Object.assign({ className: cn("flex relative", className), ref: ref }, props, { children: [isDeleteOnly ? (_jsx(IconButton, { handler: onDecreaseClick, iconUrl: deleteIconUrl, iconColor: iconColor, style: singleButtonStyle })) : (_jsxs(_Fragment, { children: [_jsx(IconButton, { handler: onDecreaseClick, iconUrl: value === 1 ? deleteIconUrl : decreaseIconUrl, iconColor: iconColor, style: leftButtonStyle, disabled: isDecreaseDisabled || loading }), _jsx("input", { type: "number", pattern: "[0-9]*", disabled: loading, max: max, value: localValue, onBlur: (e) => {
|
|
64
|
+
setIsFocused(false);
|
|
65
|
+
const parsedValue = parseInt(e.target.value) || 0;
|
|
66
|
+
const clampedValue = Math.min(parsedValue, max);
|
|
67
|
+
setValue(clampedValue);
|
|
68
|
+
setLocalValue(clampedValue.toString());
|
|
69
|
+
}, onFocus: () => {
|
|
70
|
+
setIsFocused(true);
|
|
71
|
+
}, onChange: (e) => {
|
|
72
|
+
const inputValue = e.target.value;
|
|
73
|
+
if (inputValue === "") {
|
|
74
|
+
setLocalValue("");
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const parsedValue = parseInt(inputValue);
|
|
78
|
+
if (!isNaN(parsedValue)) {
|
|
79
|
+
const clampedValue = Math.min(parsedValue, max);
|
|
80
|
+
setLocalValue(clampedValue.toString());
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, className: "w-8 h-7 focus-visible:outline-none 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)
|
|
84
|
+
? `${inputStyle.borderRadius}px`
|
|
85
|
+
: 0 }), inputMode: "numeric" }), _jsx(IconButton, { handler: onIncreaseClick, iconUrl: increaseIconUrl, iconColor: iconColor, style: rightButtonStyle, disabled: isIncreaseDisabled || loading })] })), _jsx(LoadingDots, { show: loading, size: 1, iconColor: iconColor })] })));
|
|
86
|
+
});
|
|
87
|
+
QuantityPicker.displayName = "QuantityPicker";
|
|
88
|
+
export { QuantityPicker };
|