@faststore/components 3.0.44 → 3.0.47
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/cjs/molecules/CartItem/CartItem.d.ts +10 -2
- package/dist/cjs/molecules/CartItem/CartItem.js +2 -2
- package/dist/cjs/molecules/CartItem/CartItem.js.map +1 -1
- package/dist/cjs/molecules/QuantitySelector/QuantitySelector.d.ts +9 -1
- package/dist/cjs/molecules/QuantitySelector/QuantitySelector.js +20 -3
- package/dist/cjs/molecules/QuantitySelector/QuantitySelector.js.map +1 -1
- package/dist/esm/molecules/CartItem/CartItem.d.ts +10 -2
- package/dist/esm/molecules/CartItem/CartItem.js +2 -2
- package/dist/esm/molecules/CartItem/CartItem.js.map +1 -1
- package/dist/esm/molecules/QuantitySelector/QuantitySelector.d.ts +9 -1
- package/dist/esm/molecules/QuantitySelector/QuantitySelector.js +20 -3
- package/dist/esm/molecules/QuantitySelector/QuantitySelector.js.map +1 -1
- package/package.json +4 -4
- package/src/molecules/CartItem/CartItem.tsx +12 -0
- package/src/molecules/QuantitySelector/QuantitySelector.tsx +37 -5
|
@@ -16,8 +16,16 @@ export interface CartItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
16
16
|
*/
|
|
17
17
|
quantity?: number;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
|
|
19
|
+
* Controls by how many units the value advances
|
|
20
|
+
**/
|
|
21
|
+
unitMultiplier?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Controls wheter you use or not the unitMultiplier
|
|
24
|
+
*/
|
|
25
|
+
useUnitMultiplier?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Specifies that this product is unavailable.
|
|
28
|
+
*/
|
|
21
29
|
unavailable?: boolean;
|
|
22
30
|
/**
|
|
23
31
|
* Props for the Remove from cart IconButton component.
|
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
5
5
|
const __1 = require("../../");
|
|
6
|
-
const CartItem = (0, react_1.forwardRef)(function CartItem({ testId = 'fs-cart-item', price, quantity, unavailable, onQuantityChange, children, removeBtnProps, ...otherProps }, ref) {
|
|
6
|
+
const CartItem = (0, react_1.forwardRef)(function CartItem({ testId = 'fs-cart-item', price, quantity, unavailable, onQuantityChange, unitMultiplier, useUnitMultiplier, children, removeBtnProps, ...otherProps }, ref) {
|
|
7
7
|
return (react_1.default.createElement("article", { ref: ref, "data-fs-cart-item": unavailable ? 'unavailable' : 'true', "data-testid": testId, ...otherProps },
|
|
8
8
|
react_1.default.createElement("div", { "data-fs-cart-item-content": true }, children),
|
|
9
9
|
react_1.default.createElement(__1.IconButton, { "data-fs-cart-item-remove-button": true, icon: react_1.default.createElement(__1.Icon, { name: "XCircle" }), "aria-label": "Remove", ...removeBtnProps }),
|
|
10
10
|
react_1.default.createElement("div", { "data-fs-cart-item-actions": true },
|
|
11
|
-
react_1.default.createElement(__1.QuantitySelector, { min: 1, initial: quantity, onChange: onQuantityChange }),
|
|
11
|
+
react_1.default.createElement(__1.QuantitySelector, { min: 1, initial: quantity, unitMultiplier: unitMultiplier, useUnitMultiplier: useUnitMultiplier, onChange: onQuantityChange }),
|
|
12
12
|
react_1.default.createElement(__1.ProductPrice, { "data-fs-cart-item-prices": true, listPrice: price?.listPrice ? price.listPrice : 0, value: price?.value ? price.value : 0, formatter: price?.formatter }))));
|
|
13
13
|
});
|
|
14
14
|
exports.default = CartItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartItem.js","sourceRoot":"","sources":["../../../../src/molecules/CartItem/CartItem.tsx"],"names":[],"mappings":";;;AACA,uDAAyC;AAEzC,8BAMe;
|
|
1
|
+
{"version":3,"file":"CartItem.js","sourceRoot":"","sources":["../../../../src/molecules/CartItem/CartItem.tsx"],"names":[],"mappings":";;;AACA,uDAAyC;AAEzC,8BAMe;AAuCf,MAAM,QAAQ,GAAG,IAAA,kBAAU,EAAgC,SAAS,QAAQ,CAC1E,EACE,MAAM,GAAG,cAAc,EACvB,KAAK,EACL,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,GAAG,UAAU,EACd,EACD,GAAG;IAEH,OAAO,CACL,2CACE,GAAG,EAAE,GAAG,uBACW,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,iBAC1C,MAAM,KACf,UAAU;QAEd,4EAAgC,QAAQ,CAAO;QAC/C,8BAAC,cAAU,6CAET,IAAI,EAAE,8BAAC,QAAI,IAAC,IAAI,EAAC,SAAS,GAAG,gBAClB,QAAQ,KACf,cAAc,GAClB;QACF;YACE,8BAAC,oBAAgB,IACf,GAAG,EAAE,CAAC,EACN,OAAO,EAAE,QAAQ,EACjB,cAAc,EAAE,cAAc,EAC9B,iBAAiB,EAAE,iBAAiB,EACpC,QAAQ,EAAE,gBAAgB,GAC1B;YACF,8BAAC,gBAAY,sCAEX,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EACjD,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACrC,SAAS,EAAE,KAAK,EAAE,SAAS,GAC3B,CACE,CACE,CACX,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,kBAAe,QAAQ,CAAA"}
|
|
@@ -18,6 +18,14 @@ export interface QuantitySelectorProps {
|
|
|
18
18
|
* The initial value for quantity selector
|
|
19
19
|
*/
|
|
20
20
|
initial?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Controls by how many units the value advances
|
|
23
|
+
*/
|
|
24
|
+
unitMultiplier?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Controls wheter you use or not the unitMultiplier
|
|
27
|
+
*/
|
|
28
|
+
useUnitMultiplier?: boolean;
|
|
21
29
|
/**
|
|
22
30
|
* Specifies that the whole quantity selector component should be disabled.
|
|
23
31
|
*/
|
|
@@ -27,5 +35,5 @@ export interface QuantitySelectorProps {
|
|
|
27
35
|
*/
|
|
28
36
|
onChange?: (value: number) => void;
|
|
29
37
|
}
|
|
30
|
-
declare const QuantitySelector: ({ max, min, initial, disabled, onChange, testId, ...otherProps }: QuantitySelectorProps) => React.JSX.Element;
|
|
38
|
+
declare const QuantitySelector: ({ max, min, unitMultiplier, useUnitMultiplier, initial, disabled, onChange, testId, ...otherProps }: QuantitySelectorProps) => React.JSX.Element;
|
|
31
39
|
export default QuantitySelector;
|
|
@@ -3,26 +3,43 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const react_1 = tslib_1.__importStar(require("react"));
|
|
5
5
|
const __1 = require("../../");
|
|
6
|
-
const QuantitySelector = ({ max, min = 1, initial, disabled = false, onChange, testId = 'fs-quantity-selector', ...otherProps }) => {
|
|
6
|
+
const QuantitySelector = ({ max, min = 1, unitMultiplier = 1, useUnitMultiplier, initial, disabled = false, onChange, testId = 'fs-quantity-selector', ...otherProps }) => {
|
|
7
7
|
const [quantity, setQuantity] = (0, react_1.useState)(initial ?? min);
|
|
8
|
+
const [multipliedUnit, setMultipliedUnit] = (0, react_1.useState)(quantity * unitMultiplier);
|
|
9
|
+
const roundUpQuantityIfNeeded = (quantity) => {
|
|
10
|
+
if (!useUnitMultiplier) {
|
|
11
|
+
return quantity;
|
|
12
|
+
}
|
|
13
|
+
return Math.ceil(quantity / unitMultiplier) * unitMultiplier;
|
|
14
|
+
};
|
|
8
15
|
const isLeftDisabled = quantity === min;
|
|
9
16
|
const isRightDisabled = quantity === max;
|
|
10
17
|
const changeQuantity = (increaseValue) => {
|
|
11
18
|
const quantityValue = validateQuantityBounds(quantity + increaseValue);
|
|
12
19
|
onChange?.(quantityValue);
|
|
13
20
|
setQuantity(quantityValue);
|
|
21
|
+
setMultipliedUnit(quantityValue * unitMultiplier);
|
|
14
22
|
};
|
|
15
23
|
const increase = () => changeQuantity(1);
|
|
16
24
|
const decrease = () => changeQuantity(-1);
|
|
17
25
|
function validateQuantityBounds(n) {
|
|
18
26
|
const maxValue = min ? Math.max(n, min) : n;
|
|
19
|
-
return max ? Math.min(maxValue, max) : maxValue;
|
|
27
|
+
return max ? Math.min(maxValue, useUnitMultiplier ? max * unitMultiplier : max) : maxValue;
|
|
28
|
+
}
|
|
29
|
+
function validateBlur() {
|
|
30
|
+
const roundedQuantity = roundUpQuantityIfNeeded(quantity);
|
|
31
|
+
setQuantity(() => {
|
|
32
|
+
setMultipliedUnit(roundedQuantity);
|
|
33
|
+
onChange?.(roundedQuantity / unitMultiplier);
|
|
34
|
+
return roundedQuantity / unitMultiplier;
|
|
35
|
+
});
|
|
20
36
|
}
|
|
21
37
|
function validateInput(e) {
|
|
22
38
|
const val = e.currentTarget.value;
|
|
23
39
|
if (!Number.isNaN(Number(val))) {
|
|
24
40
|
setQuantity(() => {
|
|
25
41
|
const quantityValue = validateQuantityBounds(Number(val));
|
|
42
|
+
setMultipliedUnit(quantityValue);
|
|
26
43
|
onChange?.(quantityValue);
|
|
27
44
|
return quantityValue;
|
|
28
45
|
});
|
|
@@ -33,7 +50,7 @@ const QuantitySelector = ({ max, min = 1, initial, disabled = false, onChange, t
|
|
|
33
50
|
}, [initial]);
|
|
34
51
|
return (react_1.default.createElement("div", { "data-fs-quantity-selector": disabled ? 'disabled' : 'true', "data-testid": testId, ...otherProps },
|
|
35
52
|
react_1.default.createElement(__1.IconButton, { "data-quantity-selector-button": "left", icon: react_1.default.createElement(__1.Icon, { name: "Minus", width: 16, height: 16, weight: "bold" }), "aria-label": "Decrement Quantity", "aria-controls": "quantity-selector-input", disabled: isLeftDisabled || disabled, onClick: decrease, testId: `${testId}-left-button`, size: "small" }),
|
|
36
|
-
react_1.default.createElement(__1.Input, { "data-quantity-selector-input": true, id: "quantity-selector-input", "aria-label": "Quantity", value: quantity, onChange: validateInput, disabled: disabled }),
|
|
53
|
+
react_1.default.createElement(__1.Input, { "data-quantity-selector-input": true, id: "quantity-selector-input", "aria-label": "Quantity", value: useUnitMultiplier ? multipliedUnit : quantity, onChange: validateInput, onBlur: validateBlur, disabled: disabled }),
|
|
37
54
|
react_1.default.createElement(__1.IconButton, { "data-quantity-selector-button": "right", "aria-controls": "quantity-selector-input", "aria-label": "Increment Quantity", disabled: isRightDisabled || disabled, icon: react_1.default.createElement(__1.Icon, { name: "Plus", width: 16, height: 16, weight: "bold" }), onClick: increase, testId: `${testId}-right-button`, size: "small" })));
|
|
38
55
|
};
|
|
39
56
|
exports.default = QuantitySelector;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuantitySelector.js","sourceRoot":"","sources":["../../../../src/molecules/QuantitySelector/QuantitySelector.tsx"],"names":[],"mappings":";;;AAAA,uDAAkD;AAElD,8BAAgD;
|
|
1
|
+
{"version":3,"file":"QuantitySelector.js","sourceRoot":"","sources":["../../../../src/molecules/QuantitySelector/QuantitySelector.tsx"],"names":[],"mappings":";;;AAAA,uDAAkD;AAElD,8BAAgD;AAuChD,MAAM,gBAAgB,GAAG,CAAC,EACxB,GAAG,EACH,GAAG,GAAG,CAAC,EACP,cAAc,GAAG,CAAC,EAClB,iBAAiB,EACjB,OAAO,EACP,QAAQ,GAAG,KAAK,EAChB,QAAQ,EACR,MAAM,GAAG,sBAAsB,EAC/B,GAAG,UAAU,EACS,EAAE,EAAE;IAC1B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,EAAS,OAAO,IAAI,GAAG,CAAC,CAAA;IAChE,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,gBAAQ,EAAS,QAAQ,GAAG,cAAc,CAAC,CAAA;IAEvF,MAAM,uBAAuB,GAAG,CAAC,QAAgB,EAAE,EAAE;QACnD,IAAG,CAAC,iBAAiB,EAAC;YACpB,OAAO,QAAQ,CAAA;SAChB;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,cAAc,CAAC,GAAG,cAAc,CAAC;IAC/D,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,QAAQ,KAAK,GAAG,CAAA;IACvC,MAAM,eAAe,GAAG,QAAQ,KAAK,GAAG,CAAA;IAExC,MAAM,cAAc,GAAG,CAAC,aAAqB,EAAE,EAAE;QAC/C,MAAM,aAAa,GAAG,sBAAsB,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAA;QAEtE,QAAQ,EAAE,CAAC,aAAa,CAAC,CAAA;QACzB,WAAW,CAAC,aAAa,CAAC,CAAA;QAC1B,iBAAiB,CAAC,aAAa,GAAG,cAAc,CAAC,CAAA;IACnD,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;IAExC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;IAEzC,SAAS,sBAAsB,CAAC,CAAS;QACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAE3C,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC5F,CAAC;IAED,SAAS,YAAY;QACjB,MAAM,eAAe,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAA;QAEzD,WAAW,CAAC,GAAG,EAAE;YACf,iBAAiB,CAAC,eAAe,CAAC,CAAA;YAClC,QAAQ,EAAE,CAAC,eAAe,GAAG,cAAc,CAAC,CAAA;YAE5C,OAAO,eAAe,GAAG,cAAc,CAAA;QACzC,CAAC,CAAC,CAAA;IACN,CAAC;IAED,SAAS,aAAa,CAAC,CAAoC;QACzD,MAAM,GAAG,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAA;QAEjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;YAC9B,WAAW,CAAC,GAAG,EAAE;gBACf,MAAM,aAAa,GAAG,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;gBACzD,iBAAiB,CAAC,aAAa,CAAC,CAAA;gBAChC,QAAQ,EAAE,CAAC,aAAa,CAAC,CAAA;gBAEzB,OAAO,aAAa,CAAA;YACtB,CAAC,CAAC,CAAA;SACH;IACH,CAAC;IAGD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;IACjC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,OAAO,CACL,oEAC6B,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,iBAC5C,MAAM,KACf,UAAU;QAEd,8BAAC,cAAU,qCACqB,MAAM,EACpC,IAAI,EAAE,8BAAC,QAAI,IAAC,IAAI,EAAC,OAAO,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,GAAG,gBACrD,oBAAoB,mBACjB,yBAAyB,EACvC,QAAQ,EAAE,cAAc,IAAI,QAAQ,EACpC,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,GAAG,MAAM,cAAc,EAC/B,IAAI,EAAC,OAAO,GACZ;QACF,8BAAC,SAAK,0CAEJ,EAAE,EAAC,yBAAyB,gBACjB,UAAU,EACrB,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,EACpD,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,GAClB;QACF,8BAAC,cAAU,qCACqB,OAAO,mBACvB,yBAAyB,gBAC5B,oBAAoB,EAC/B,QAAQ,EAAE,eAAe,IAAI,QAAQ,EACrC,IAAI,EAAE,8BAAC,QAAI,IAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,GAAG,EAC/D,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,GAAG,MAAM,eAAe,EAChC,IAAI,EAAC,OAAO,GACZ,CACE,CACP,CAAA;AACH,CAAC,CAAA;AAED,kBAAe,gBAAgB,CAAA"}
|
|
@@ -16,8 +16,16 @@ export interface CartItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
16
16
|
*/
|
|
17
17
|
quantity?: number;
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
|
|
19
|
+
* Controls by how many units the value advances
|
|
20
|
+
**/
|
|
21
|
+
unitMultiplier?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Controls wheter you use or not the unitMultiplier
|
|
24
|
+
*/
|
|
25
|
+
useUnitMultiplier?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Specifies that this product is unavailable.
|
|
28
|
+
*/
|
|
21
29
|
unavailable?: boolean;
|
|
22
30
|
/**
|
|
23
31
|
* Props for the Remove from cart IconButton component.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
2
|
import { Icon, IconButton, ProductPrice, QuantitySelector, } from '../../';
|
|
3
|
-
const CartItem = forwardRef(function CartItem({ testId = 'fs-cart-item', price, quantity, unavailable, onQuantityChange, children, removeBtnProps, ...otherProps }, ref) {
|
|
3
|
+
const CartItem = forwardRef(function CartItem({ testId = 'fs-cart-item', price, quantity, unavailable, onQuantityChange, unitMultiplier, useUnitMultiplier, children, removeBtnProps, ...otherProps }, ref) {
|
|
4
4
|
return (React.createElement("article", { ref: ref, "data-fs-cart-item": unavailable ? 'unavailable' : 'true', "data-testid": testId, ...otherProps },
|
|
5
5
|
React.createElement("div", { "data-fs-cart-item-content": true }, children),
|
|
6
6
|
React.createElement(IconButton, { "data-fs-cart-item-remove-button": true, icon: React.createElement(Icon, { name: "XCircle" }), "aria-label": "Remove", ...removeBtnProps }),
|
|
7
7
|
React.createElement("div", { "data-fs-cart-item-actions": true },
|
|
8
|
-
React.createElement(QuantitySelector, { min: 1, initial: quantity, onChange: onQuantityChange }),
|
|
8
|
+
React.createElement(QuantitySelector, { min: 1, initial: quantity, unitMultiplier: unitMultiplier, useUnitMultiplier: useUnitMultiplier, onChange: onQuantityChange }),
|
|
9
9
|
React.createElement(ProductPrice, { "data-fs-cart-item-prices": true, listPrice: price?.listPrice ? price.listPrice : 0, value: price?.value ? price.value : 0, formatter: price?.formatter }))));
|
|
10
10
|
});
|
|
11
11
|
export default CartItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartItem.js","sourceRoot":"","sources":["../../../../src/molecules/CartItem/CartItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAEzC,OAAO,EACL,IAAI,EACJ,UAAU,EAEV,YAAY,EACZ,gBAAgB,GACjB,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"CartItem.js","sourceRoot":"","sources":["../../../../src/molecules/CartItem/CartItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAEzC,OAAO,EACL,IAAI,EACJ,UAAU,EAEV,YAAY,EACZ,gBAAgB,GACjB,MAAM,QAAQ,CAAA;AAuCf,MAAM,QAAQ,GAAG,UAAU,CAAgC,SAAS,QAAQ,CAC1E,EACE,MAAM,GAAG,cAAc,EACvB,KAAK,EACL,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,cAAc,EACd,GAAG,UAAU,EACd,EACD,GAAG;IAEH,OAAO,CACL,iCACE,GAAG,EAAE,GAAG,uBACW,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,iBAC1C,MAAM,KACf,UAAU;QAEd,kEAAgC,QAAQ,CAAO;QAC/C,oBAAC,UAAU,6CAET,IAAI,EAAE,oBAAC,IAAI,IAAC,IAAI,EAAC,SAAS,GAAG,gBAClB,QAAQ,KACf,cAAc,GAClB;QACF;YACE,oBAAC,gBAAgB,IACf,GAAG,EAAE,CAAC,EACN,OAAO,EAAE,QAAQ,EACjB,cAAc,EAAE,cAAc,EAC9B,iBAAiB,EAAE,iBAAiB,EACpC,QAAQ,EAAE,gBAAgB,GAC1B;YACF,oBAAC,YAAY,sCAEX,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EACjD,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACrC,SAAS,EAAE,KAAK,EAAE,SAAS,GAC3B,CACE,CACE,CACX,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,QAAQ,CAAA"}
|
|
@@ -18,6 +18,14 @@ export interface QuantitySelectorProps {
|
|
|
18
18
|
* The initial value for quantity selector
|
|
19
19
|
*/
|
|
20
20
|
initial?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Controls by how many units the value advances
|
|
23
|
+
*/
|
|
24
|
+
unitMultiplier?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Controls wheter you use or not the unitMultiplier
|
|
27
|
+
*/
|
|
28
|
+
useUnitMultiplier?: boolean;
|
|
21
29
|
/**
|
|
22
30
|
* Specifies that the whole quantity selector component should be disabled.
|
|
23
31
|
*/
|
|
@@ -27,5 +35,5 @@ export interface QuantitySelectorProps {
|
|
|
27
35
|
*/
|
|
28
36
|
onChange?: (value: number) => void;
|
|
29
37
|
}
|
|
30
|
-
declare const QuantitySelector: ({ max, min, initial, disabled, onChange, testId, ...otherProps }: QuantitySelectorProps) => React.JSX.Element;
|
|
38
|
+
declare const QuantitySelector: ({ max, min, unitMultiplier, useUnitMultiplier, initial, disabled, onChange, testId, ...otherProps }: QuantitySelectorProps) => React.JSX.Element;
|
|
31
39
|
export default QuantitySelector;
|
|
@@ -1,25 +1,42 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { Icon, IconButton, Input } from '../../';
|
|
3
|
-
const QuantitySelector = ({ max, min = 1, initial, disabled = false, onChange, testId = 'fs-quantity-selector', ...otherProps }) => {
|
|
3
|
+
const QuantitySelector = ({ max, min = 1, unitMultiplier = 1, useUnitMultiplier, initial, disabled = false, onChange, testId = 'fs-quantity-selector', ...otherProps }) => {
|
|
4
4
|
const [quantity, setQuantity] = useState(initial ?? min);
|
|
5
|
+
const [multipliedUnit, setMultipliedUnit] = useState(quantity * unitMultiplier);
|
|
6
|
+
const roundUpQuantityIfNeeded = (quantity) => {
|
|
7
|
+
if (!useUnitMultiplier) {
|
|
8
|
+
return quantity;
|
|
9
|
+
}
|
|
10
|
+
return Math.ceil(quantity / unitMultiplier) * unitMultiplier;
|
|
11
|
+
};
|
|
5
12
|
const isLeftDisabled = quantity === min;
|
|
6
13
|
const isRightDisabled = quantity === max;
|
|
7
14
|
const changeQuantity = (increaseValue) => {
|
|
8
15
|
const quantityValue = validateQuantityBounds(quantity + increaseValue);
|
|
9
16
|
onChange?.(quantityValue);
|
|
10
17
|
setQuantity(quantityValue);
|
|
18
|
+
setMultipliedUnit(quantityValue * unitMultiplier);
|
|
11
19
|
};
|
|
12
20
|
const increase = () => changeQuantity(1);
|
|
13
21
|
const decrease = () => changeQuantity(-1);
|
|
14
22
|
function validateQuantityBounds(n) {
|
|
15
23
|
const maxValue = min ? Math.max(n, min) : n;
|
|
16
|
-
return max ? Math.min(maxValue, max) : maxValue;
|
|
24
|
+
return max ? Math.min(maxValue, useUnitMultiplier ? max * unitMultiplier : max) : maxValue;
|
|
25
|
+
}
|
|
26
|
+
function validateBlur() {
|
|
27
|
+
const roundedQuantity = roundUpQuantityIfNeeded(quantity);
|
|
28
|
+
setQuantity(() => {
|
|
29
|
+
setMultipliedUnit(roundedQuantity);
|
|
30
|
+
onChange?.(roundedQuantity / unitMultiplier);
|
|
31
|
+
return roundedQuantity / unitMultiplier;
|
|
32
|
+
});
|
|
17
33
|
}
|
|
18
34
|
function validateInput(e) {
|
|
19
35
|
const val = e.currentTarget.value;
|
|
20
36
|
if (!Number.isNaN(Number(val))) {
|
|
21
37
|
setQuantity(() => {
|
|
22
38
|
const quantityValue = validateQuantityBounds(Number(val));
|
|
39
|
+
setMultipliedUnit(quantityValue);
|
|
23
40
|
onChange?.(quantityValue);
|
|
24
41
|
return quantityValue;
|
|
25
42
|
});
|
|
@@ -30,7 +47,7 @@ const QuantitySelector = ({ max, min = 1, initial, disabled = false, onChange, t
|
|
|
30
47
|
}, [initial]);
|
|
31
48
|
return (React.createElement("div", { "data-fs-quantity-selector": disabled ? 'disabled' : 'true', "data-testid": testId, ...otherProps },
|
|
32
49
|
React.createElement(IconButton, { "data-quantity-selector-button": "left", icon: React.createElement(Icon, { name: "Minus", width: 16, height: 16, weight: "bold" }), "aria-label": "Decrement Quantity", "aria-controls": "quantity-selector-input", disabled: isLeftDisabled || disabled, onClick: decrease, testId: `${testId}-left-button`, size: "small" }),
|
|
33
|
-
React.createElement(Input, { "data-quantity-selector-input": true, id: "quantity-selector-input", "aria-label": "Quantity", value: quantity, onChange: validateInput, disabled: disabled }),
|
|
50
|
+
React.createElement(Input, { "data-quantity-selector-input": true, id: "quantity-selector-input", "aria-label": "Quantity", value: useUnitMultiplier ? multipliedUnit : quantity, onChange: validateInput, onBlur: validateBlur, disabled: disabled }),
|
|
34
51
|
React.createElement(IconButton, { "data-quantity-selector-button": "right", "aria-controls": "quantity-selector-input", "aria-label": "Increment Quantity", disabled: isRightDisabled || disabled, icon: React.createElement(Icon, { name: "Plus", width: 16, height: 16, weight: "bold" }), onClick: increase, testId: `${testId}-right-button`, size: "small" })));
|
|
35
52
|
};
|
|
36
53
|
export default QuantitySelector;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuantitySelector.js","sourceRoot":"","sources":["../../../../src/molecules/QuantitySelector/QuantitySelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAElD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"QuantitySelector.js","sourceRoot":"","sources":["../../../../src/molecules/QuantitySelector/QuantitySelector.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/components",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.47",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"typings": "dist/esm/index.d.ts",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"react-dom": "^18.2.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@faststore/eslint-config": "^3.0.
|
|
39
|
-
"@faststore/shared": "^3.0.
|
|
38
|
+
"@faststore/eslint-config": "^3.0.47",
|
|
39
|
+
"@faststore/shared": "^3.0.47",
|
|
40
40
|
"@testing-library/react": "^14.3.0",
|
|
41
41
|
"@types/react": "^18.2.42",
|
|
42
42
|
"@types/react-dom": "^18.2.17",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"volta": {
|
|
50
50
|
"extends": "../../package.json"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "bdb7b6cc92d39717ab8f583586859f5d34b85f16"
|
|
53
53
|
}
|
|
@@ -25,6 +25,14 @@ export interface CartItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
25
25
|
*/
|
|
26
26
|
quantity?: number
|
|
27
27
|
/**
|
|
28
|
+
* Controls by how many units the value advances
|
|
29
|
+
**/
|
|
30
|
+
unitMultiplier?: number
|
|
31
|
+
/**
|
|
32
|
+
* Controls wheter you use or not the unitMultiplier
|
|
33
|
+
*/
|
|
34
|
+
useUnitMultiplier?: boolean
|
|
35
|
+
/**
|
|
28
36
|
* Specifies that this product is unavailable.
|
|
29
37
|
*/
|
|
30
38
|
unavailable?: boolean
|
|
@@ -45,6 +53,8 @@ const CartItem = forwardRef<HTMLDivElement, CartItemProps>(function CartItem(
|
|
|
45
53
|
quantity,
|
|
46
54
|
unavailable,
|
|
47
55
|
onQuantityChange,
|
|
56
|
+
unitMultiplier,
|
|
57
|
+
useUnitMultiplier,
|
|
48
58
|
children,
|
|
49
59
|
removeBtnProps,
|
|
50
60
|
...otherProps
|
|
@@ -69,6 +79,8 @@ const CartItem = forwardRef<HTMLDivElement, CartItemProps>(function CartItem(
|
|
|
69
79
|
<QuantitySelector
|
|
70
80
|
min={1}
|
|
71
81
|
initial={quantity}
|
|
82
|
+
unitMultiplier={unitMultiplier}
|
|
83
|
+
useUnitMultiplier={useUnitMultiplier}
|
|
72
84
|
onChange={onQuantityChange}
|
|
73
85
|
/>
|
|
74
86
|
<ProductPrice
|
|
@@ -21,6 +21,14 @@ export interface QuantitySelectorProps {
|
|
|
21
21
|
* The initial value for quantity selector
|
|
22
22
|
*/
|
|
23
23
|
initial?: number
|
|
24
|
+
/**
|
|
25
|
+
* Controls by how many units the value advances
|
|
26
|
+
*/
|
|
27
|
+
unitMultiplier?: number
|
|
28
|
+
/**
|
|
29
|
+
* Controls wheter you use or not the unitMultiplier
|
|
30
|
+
*/
|
|
31
|
+
useUnitMultiplier?: boolean
|
|
24
32
|
/**
|
|
25
33
|
* Specifies that the whole quantity selector component should be disabled.
|
|
26
34
|
*/
|
|
@@ -34,6 +42,8 @@ export interface QuantitySelectorProps {
|
|
|
34
42
|
const QuantitySelector = ({
|
|
35
43
|
max,
|
|
36
44
|
min = 1,
|
|
45
|
+
unitMultiplier = 1,
|
|
46
|
+
useUnitMultiplier,
|
|
37
47
|
initial,
|
|
38
48
|
disabled = false,
|
|
39
49
|
onChange,
|
|
@@ -41,17 +51,26 @@ const QuantitySelector = ({
|
|
|
41
51
|
...otherProps
|
|
42
52
|
}: QuantitySelectorProps) => {
|
|
43
53
|
const [quantity, setQuantity] = useState<number>(initial ?? min)
|
|
54
|
+
const [multipliedUnit, setMultipliedUnit] = useState<number>(quantity * unitMultiplier)
|
|
55
|
+
|
|
56
|
+
const roundUpQuantityIfNeeded = (quantity: number) => {
|
|
57
|
+
if(!useUnitMultiplier){
|
|
58
|
+
return quantity
|
|
59
|
+
}
|
|
60
|
+
return Math.ceil(quantity / unitMultiplier) * unitMultiplier;
|
|
61
|
+
}
|
|
44
62
|
|
|
45
63
|
const isLeftDisabled = quantity === min
|
|
46
|
-
const isRightDisabled = quantity === max
|
|
64
|
+
const isRightDisabled = quantity === max
|
|
47
65
|
|
|
48
66
|
const changeQuantity = (increaseValue: number) => {
|
|
49
67
|
const quantityValue = validateQuantityBounds(quantity + increaseValue)
|
|
50
68
|
|
|
51
69
|
onChange?.(quantityValue)
|
|
52
70
|
setQuantity(quantityValue)
|
|
71
|
+
setMultipliedUnit(quantityValue * unitMultiplier)
|
|
53
72
|
}
|
|
54
|
-
|
|
73
|
+
|
|
55
74
|
const increase = () => changeQuantity(1)
|
|
56
75
|
|
|
57
76
|
const decrease = () => changeQuantity(-1)
|
|
@@ -59,7 +78,18 @@ const QuantitySelector = ({
|
|
|
59
78
|
function validateQuantityBounds(n: number): number {
|
|
60
79
|
const maxValue = min ? Math.max(n, min) : n
|
|
61
80
|
|
|
62
|
-
return max ? Math.min(maxValue, max) : maxValue
|
|
81
|
+
return max ? Math.min(maxValue, useUnitMultiplier ? max * unitMultiplier : max) : maxValue
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function validateBlur() {
|
|
85
|
+
const roundedQuantity = roundUpQuantityIfNeeded(quantity)
|
|
86
|
+
|
|
87
|
+
setQuantity(() => {
|
|
88
|
+
setMultipliedUnit(roundedQuantity)
|
|
89
|
+
onChange?.(roundedQuantity / unitMultiplier)
|
|
90
|
+
|
|
91
|
+
return roundedQuantity / unitMultiplier
|
|
92
|
+
})
|
|
63
93
|
}
|
|
64
94
|
|
|
65
95
|
function validateInput(e: React.FormEvent<HTMLInputElement>) {
|
|
@@ -68,7 +98,7 @@ const QuantitySelector = ({
|
|
|
68
98
|
if (!Number.isNaN(Number(val))) {
|
|
69
99
|
setQuantity(() => {
|
|
70
100
|
const quantityValue = validateQuantityBounds(Number(val))
|
|
71
|
-
|
|
101
|
+
setMultipliedUnit(quantityValue)
|
|
72
102
|
onChange?.(quantityValue)
|
|
73
103
|
|
|
74
104
|
return quantityValue
|
|
@@ -76,6 +106,7 @@ const QuantitySelector = ({
|
|
|
76
106
|
}
|
|
77
107
|
}
|
|
78
108
|
|
|
109
|
+
|
|
79
110
|
useEffect(() => {
|
|
80
111
|
initial && setQuantity(initial)
|
|
81
112
|
}, [initial])
|
|
@@ -100,8 +131,9 @@ const QuantitySelector = ({
|
|
|
100
131
|
data-quantity-selector-input
|
|
101
132
|
id="quantity-selector-input"
|
|
102
133
|
aria-label="Quantity"
|
|
103
|
-
value={quantity}
|
|
134
|
+
value={useUnitMultiplier ? multipliedUnit : quantity}
|
|
104
135
|
onChange={validateInput}
|
|
136
|
+
onBlur={validateBlur}
|
|
105
137
|
disabled={disabled}
|
|
106
138
|
/>
|
|
107
139
|
<IconButton
|