@faststore/components 2.0.5-alpha.0 → 2.0.7-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/assets/XCircle.d.ts +3 -0
- package/dist/assets/XCircle.js +9 -0
- package/dist/assets/XCircle.js.map +1 -0
- package/dist/assets/index.d.ts +1 -0
- package/dist/assets/index.js +1 -0
- package/dist/assets/index.js.map +1 -1
- package/dist/atoms/Input/Input.d.ts +10 -0
- package/dist/atoms/Input/Input.js +6 -0
- package/dist/atoms/Input/Input.js.map +1 -0
- package/dist/atoms/Input/index.d.ts +2 -0
- package/dist/atoms/Input/index.js +2 -0
- package/dist/atoms/Input/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/molecules/DiscountBadge/DiscountBadge.d.ts +25 -0
- package/dist/molecules/DiscountBadge/DiscountBadge.js +19 -0
- package/dist/molecules/DiscountBadge/DiscountBadge.js.map +1 -0
- package/dist/molecules/DiscountBadge/index.d.ts +2 -0
- package/dist/molecules/DiscountBadge/index.js +2 -0
- package/dist/molecules/DiscountBadge/index.js.map +1 -0
- package/dist/molecules/DiscountBadge/useDiscountPercent.d.ts +1 -0
- package/dist/molecules/DiscountBadge/useDiscountPercent.js +9 -0
- package/dist/molecules/DiscountBadge/useDiscountPercent.js.map +1 -0
- package/dist/molecules/InputField/InputField.d.ts +55 -0
- package/dist/molecules/InputField/InputField.js +19 -0
- package/dist/molecules/InputField/InputField.js.map +1 -0
- package/dist/molecules/InputField/index.d.ts +2 -0
- package/dist/molecules/InputField/index.js +2 -0
- package/dist/molecules/InputField/index.js.map +1 -0
- package/package.json +2 -2
- package/src/assets/XCircle.tsx +47 -0
- package/src/assets/index.ts +1 -0
- package/src/atoms/Input/Input.tsx +19 -0
- package/src/atoms/Input/index.ts +2 -0
- package/src/index.ts +6 -0
- package/src/molecules/DiscountBadge/DiscountBadge.tsx +60 -0
- package/src/molecules/DiscountBadge/index.ts +2 -0
- package/src/molecules/DiscountBadge/useDiscountPercent.ts +10 -0
- package/src/molecules/InputField/InputField.tsx +125 -0
- package/src/molecules/InputField/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,24 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.7-alpha.0](https://github.com/vtex/faststore/compare/v2.0.6-alpha.0...v2.0.7-alpha.0) (2022-12-09)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Adds `DiscountBadge` component ([#1546](https://github.com/vtex/faststore/issues/1546)) ([9b2e279](https://github.com/vtex/faststore/commit/9b2e27940ffa9b52c9a62541a07e1f593a0bcfb7)), closes [#313](https://github.com/vtex/faststore/issues/313)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## [2.0.6-alpha.0](https://github.com/vtex/faststore/compare/v2.0.5-alpha.0...v2.0.6-alpha.0) (2022-12-08)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* Adds `Input` & `InputField` components ([#1545](https://github.com/vtex/faststore/issues/1545)) ([f89ec49](https://github.com/vtex/faststore/commit/f89ec4930dbcc7179f0fac484e16b0981540b6df))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
6
24
|
## [2.0.5-alpha.0](https://github.com/vtex/faststore/compare/v2.0.4-alpha.0...v2.0.5-alpha.0) (2022-12-07)
|
|
7
25
|
|
|
8
26
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
// Icon from Phosphor Icons
|
|
3
|
+
const XCircle = () => (React.createElement("svg", { id: "XCircle", xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", viewBox: "0 0 256 256", strokeWidth: "16", width: 20, height: 20 },
|
|
4
|
+
React.createElement("rect", { width: "256", height: "256", fill: "none" }),
|
|
5
|
+
React.createElement("circle", { cx: "128", cy: "128", r: "96", fill: "none", stroke: "currentColor", strokeMiterlimit: "10" }),
|
|
6
|
+
React.createElement("line", { x1: "160", y1: "96", x2: "96", y2: "160", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
7
|
+
React.createElement("line", { x1: "160", y1: "160", x2: "96", y2: "96", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round" })));
|
|
8
|
+
export default XCircle;
|
|
9
|
+
//# sourceMappingURL=XCircle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"XCircle.js","sourceRoot":"","sources":["../../src/assets/XCircle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,2BAA2B;AAC3B,MAAM,OAAO,GAAO,GAAG,EAAE,CAAC,CACxB,6BACE,EAAE,EAAC,SAAS,EACZ,KAAK,EAAC,4BAA4B,EAClC,IAAI,EAAC,cAAc,EACnB,OAAO,EAAC,aAAa,EACrB,WAAW,EAAC,IAAI,EAChB,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE;IAEV,8BAAM,KAAK,EAAC,KAAK,EAAC,MAAM,EAAC,KAAK,EAAC,IAAI,EAAC,MAAM,GAAQ;IAClD,gCACE,EAAE,EAAC,KAAK,EACR,EAAE,EAAC,KAAK,EACR,CAAC,EAAC,IAAI,EACN,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,gBAAgB,EAAC,IAAI,GACb;IACV,8BACE,EAAE,EAAC,KAAK,EACR,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,KAAK,EACR,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,GAChB;IACR,8BACE,EAAE,EAAC,KAAK,EACR,EAAE,EAAC,KAAK,EACR,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,GAChB,CACJ,CACP,CAAA;AAED,eAAe,OAAO,CAAA"}
|
package/dist/assets/index.d.ts
CHANGED
package/dist/assets/index.js
CHANGED
package/dist/assets/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,CAAC,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,WAAW,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InputHTMLAttributes } from 'react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
4
|
+
/**
|
|
5
|
+
* ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
|
|
6
|
+
*/
|
|
7
|
+
testId?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
10
|
+
export default Input;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
const Input = forwardRef(function Input({ testId = 'fs-input', ...otherProps }, ref) {
|
|
3
|
+
return React.createElement("input", { ref: ref, "data-fs-input": true, "data-testid": testId, ...otherProps });
|
|
4
|
+
});
|
|
5
|
+
export default Input;
|
|
6
|
+
//# sourceMappingURL=Input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../src/atoms/Input/Input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AASzC,MAAM,KAAK,GAAG,UAAU,CAA+B,SAAS,KAAK,CACnE,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,UAAU,EAAE,EACtC,GAAG;IAEH,OAAO,+BAAO,GAAG,EAAE,GAAG,wCAA6B,MAAM,KAAM,UAAU,GAAI,CAAA;AAC/E,CAAC,CAAC,CAAA;AAEF,eAAe,KAAK,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/atoms/Input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export { default as Checkbox } from './atoms/Checkbox';
|
|
|
6
6
|
export type { CheckboxProps } from './atoms/Checkbox';
|
|
7
7
|
export { default as Icon } from './atoms/Icon';
|
|
8
8
|
export type { IconProps } from './atoms/Icon';
|
|
9
|
+
export { default as Input } from './atoms/Input';
|
|
10
|
+
export type { InputProps } from './atoms/Input';
|
|
9
11
|
export { default as Label } from './atoms/Label';
|
|
10
12
|
export type { LabelProps } from './atoms/Label';
|
|
11
13
|
export { default as Overlay } from './atoms/Overlay';
|
|
@@ -16,6 +18,10 @@ export { default as CheckboxField } from './molecules/CheckboxField';
|
|
|
16
18
|
export type { CheckboxFieldProps } from './molecules/CheckboxField';
|
|
17
19
|
export { default as IconButton } from './molecules/IconButton';
|
|
18
20
|
export type { IconButtonProps } from './molecules/IconButton';
|
|
21
|
+
export { default as DiscountBadge } from './molecules/DiscountBadge';
|
|
22
|
+
export type { DiscountBadgeProps } from './molecules/DiscountBadge';
|
|
23
|
+
export { default as InputField } from './molecules/InputField';
|
|
24
|
+
export type { InputFieldProps } from './molecules/InputField';
|
|
19
25
|
export { default as RadioField } from './molecules/RadioField';
|
|
20
26
|
export type { RadioFieldProps } from './molecules/RadioField';
|
|
21
27
|
export { default as Tag } from './molecules/Tag';
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,15 @@ export { default as Badge } from './atoms/Badge';
|
|
|
3
3
|
export { default as Button } from './atoms/Button';
|
|
4
4
|
export { default as Checkbox } from './atoms/Checkbox';
|
|
5
5
|
export { default as Icon } from './atoms/Icon';
|
|
6
|
+
export { default as Input } from './atoms/Input';
|
|
6
7
|
export { default as Label } from './atoms/Label';
|
|
7
8
|
export { default as Overlay } from './atoms/Overlay';
|
|
8
9
|
export { default as Radio } from './atoms/Radio';
|
|
9
10
|
// Molecules
|
|
10
11
|
export { default as CheckboxField } from './molecules/CheckboxField';
|
|
11
12
|
export { default as IconButton } from './molecules/IconButton';
|
|
13
|
+
export { default as DiscountBadge } from './molecules/DiscountBadge';
|
|
14
|
+
export { default as InputField } from './molecules/InputField';
|
|
12
15
|
export { default as RadioField } from './molecules/RadioField';
|
|
13
16
|
export { default as Tag } from './molecules/Tag';
|
|
14
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEpD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAA;AAGhD,YAAY;AACZ,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEpE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEpD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,eAAe,CAAA;AAGhD,YAAY;AACZ,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEpE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEpE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAE9D,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare type DiscountBadgeProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Specifies price without discount applied.
|
|
5
|
+
*/
|
|
6
|
+
listPrice: number;
|
|
7
|
+
/**
|
|
8
|
+
* Specifies current price with discount applied.
|
|
9
|
+
*/
|
|
10
|
+
spotPrice: number;
|
|
11
|
+
/**
|
|
12
|
+
* Sets the component's size.
|
|
13
|
+
*/
|
|
14
|
+
size?: 'small' | 'big';
|
|
15
|
+
/**
|
|
16
|
+
* Sets the limit percentage value to consider a low discount.
|
|
17
|
+
*/
|
|
18
|
+
thresholdLow?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Sets the limit percentage value to consider a high discount.
|
|
21
|
+
*/
|
|
22
|
+
thresholdHigh?: number;
|
|
23
|
+
};
|
|
24
|
+
declare const DiscountBadge: ({ listPrice, spotPrice, size, thresholdLow, thresholdHigh, }: DiscountBadgeProps) => JSX.Element;
|
|
25
|
+
export default DiscountBadge;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Badge } from '../..';
|
|
3
|
+
import { useDiscountPercent } from '../DiscountBadge/useDiscountPercent';
|
|
4
|
+
const DiscountBadge = ({ listPrice, spotPrice, size = 'small', thresholdLow = 15, thresholdHigh = 40, }) => {
|
|
5
|
+
const discountPercent = useDiscountPercent(listPrice, spotPrice);
|
|
6
|
+
if (discountPercent === 0) {
|
|
7
|
+
return React.createElement(React.Fragment, null);
|
|
8
|
+
}
|
|
9
|
+
const discountVariant = discountPercent <= thresholdLow
|
|
10
|
+
? 'low'
|
|
11
|
+
: discountPercent <= thresholdHigh
|
|
12
|
+
? 'medium'
|
|
13
|
+
: 'high';
|
|
14
|
+
return (React.createElement(Badge, { size: size, "data-fs-discount-badge": true, "data-fs-discount-badge-variant": discountVariant },
|
|
15
|
+
discountPercent,
|
|
16
|
+
"% off"));
|
|
17
|
+
};
|
|
18
|
+
export default DiscountBadge;
|
|
19
|
+
//# sourceMappingURL=DiscountBadge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiscountBadge.js","sourceRoot":"","sources":["../../../src/molecules/DiscountBadge/DiscountBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAA;AAyBxE,MAAM,aAAa,GAAG,CAAC,EACrB,SAAS,EACT,SAAS,EACT,IAAI,GAAG,OAAO,EACd,YAAY,GAAG,EAAE,EACjB,aAAa,GAAG,EAAE,GACC,EAAE,EAAE;IACvB,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAEhE,IAAI,eAAe,KAAK,CAAC,EAAE;QACzB,OAAO,yCAAK,CAAA;KACb;IAED,MAAM,eAAe,GACnB,eAAe,IAAI,YAAY;QAC7B,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,eAAe,IAAI,aAAa;YAClC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,MAAM,CAAA;IAEZ,OAAO,CACL,oBAAC,KAAK,IACJ,IAAI,EAAE,IAAI,oEAEsB,eAAe;QAE9C,eAAe;gBACV,CACT,CAAA;AACH,CAAC,CAAA;AAED,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/molecules/DiscountBadge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useDiscountPercent: (listPrice: number, spotPrice: number) => number;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
export const useDiscountPercent = (listPrice, spotPrice) => {
|
|
3
|
+
return useMemo(() => {
|
|
4
|
+
const diff = listPrice - spotPrice;
|
|
5
|
+
const discount = (diff * 100) / listPrice;
|
|
6
|
+
return Math.round(discount);
|
|
7
|
+
}, [spotPrice, listPrice]);
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=useDiscountPercent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDiscountPercent.js","sourceRoot":"","sources":["../../../src/molecules/DiscountBadge/useDiscountPercent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,SAAiB,EAAE,SAAiB,EAAE,EAAE;IACzE,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,IAAI,GAAG,SAAS,GAAG,SAAS,CAAA;QAClC,MAAM,QAAQ,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,SAAS,CAAA;QAEzC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAA;AAC5B,CAAC,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { MutableRefObject } from 'react';
|
|
2
|
+
import type { InputProps } from '../../index';
|
|
3
|
+
declare type DefaultProps = {
|
|
4
|
+
/**
|
|
5
|
+
* ID to identify input and corresponding label.
|
|
6
|
+
*/
|
|
7
|
+
id: string;
|
|
8
|
+
/**
|
|
9
|
+
* The text displayed to identify input text.
|
|
10
|
+
*/
|
|
11
|
+
label: string;
|
|
12
|
+
/**
|
|
13
|
+
* The error message is displayed when an error occurs.
|
|
14
|
+
*/
|
|
15
|
+
error?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Component's ref.
|
|
18
|
+
*/
|
|
19
|
+
inputRef?: MutableRefObject<HTMLInputElement | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Specifies that the whole input component should be disabled.
|
|
22
|
+
*/
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
};
|
|
25
|
+
declare type ActionableInputField = {
|
|
26
|
+
actionable?: never;
|
|
27
|
+
onSubmit?: never;
|
|
28
|
+
onClear?: never;
|
|
29
|
+
buttonActionText?: string;
|
|
30
|
+
displayClearButton?: never;
|
|
31
|
+
} | {
|
|
32
|
+
/**
|
|
33
|
+
* Adds a Button to the component.
|
|
34
|
+
*/
|
|
35
|
+
actionable: true;
|
|
36
|
+
/**
|
|
37
|
+
* Callback function when button is clicked. Required for actionable input.
|
|
38
|
+
*/
|
|
39
|
+
onSubmit: () => void;
|
|
40
|
+
/**
|
|
41
|
+
* Callback function when clear button is clicked. Required for actionable input.
|
|
42
|
+
*/
|
|
43
|
+
onClear: () => void;
|
|
44
|
+
/**
|
|
45
|
+
* The text displayed on the Button. Suggestion: maximum 9 characters.
|
|
46
|
+
*/
|
|
47
|
+
buttonActionText?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Boolean that controls the clear button.
|
|
50
|
+
*/
|
|
51
|
+
displayClearButton?: boolean;
|
|
52
|
+
};
|
|
53
|
+
export declare type InputFieldProps = DefaultProps & Omit<InputProps, 'disabled' | 'onSubmit'> & ActionableInputField;
|
|
54
|
+
declare const InputField: ({ id, label, type, error, displayClearButton, actionable, buttonActionText, onSubmit, onClear, placeholder, inputRef, disabled, value, ...otherProps }: InputFieldProps) => JSX.Element;
|
|
55
|
+
export default InputField;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Input, Label, IconButton, Button } from '../../index';
|
|
3
|
+
import { XCircle } from '../../assets';
|
|
4
|
+
const InputField = ({ id, label, type = 'text', error, displayClearButton, actionable, buttonActionText = 'Apply', onSubmit, onClear, placeholder = ' ', // initializes with an empty space to style float label using `placeholder-shown`
|
|
5
|
+
inputRef, disabled, value, ...otherProps }) => {
|
|
6
|
+
const shouldDisplayError = !disabled && error && error !== '';
|
|
7
|
+
const shouldDisplayButton = actionable && !disabled && value !== '';
|
|
8
|
+
return (React.createElement("div", { "data-fs-input-field": true, "data-fs-input-field-actionable": actionable, "data-fs-input-field-error": error && error !== '' },
|
|
9
|
+
React.createElement(Input, { id: id, type: type, value: value, ref: inputRef, disabled: disabled, placeholder: placeholder, ...otherProps }),
|
|
10
|
+
React.createElement(Label, { htmlFor: id }, label),
|
|
11
|
+
shouldDisplayButton &&
|
|
12
|
+
(displayClearButton || error ? (React.createElement(IconButton, { "data-fs-button-size": "small", "aria-label": "Clear Field", icon: React.createElement(XCircle, null), onClick: () => {
|
|
13
|
+
onClear?.();
|
|
14
|
+
inputRef?.current?.focus();
|
|
15
|
+
} })) : (React.createElement(Button, { variant: "tertiary", size: "small", onClick: onSubmit }, buttonActionText))),
|
|
16
|
+
shouldDisplayError && (React.createElement("span", { "data-fs-input-field-error-message": true }, error))));
|
|
17
|
+
};
|
|
18
|
+
export default InputField;
|
|
19
|
+
//# sourceMappingURL=InputField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputField.js","sourceRoot":"","sources":["../../../src/molecules/InputField/InputField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AA4DtC,MAAM,UAAU,GAAG,CAAC,EAClB,EAAE,EACF,KAAK,EACL,IAAI,GAAG,MAAM,EACb,KAAK,EACL,kBAAkB,EAClB,UAAU,EACV,gBAAgB,GAAG,OAAO,EAC1B,QAAQ,EACR,OAAO,EACP,WAAW,GAAG,GAAG,EAAE,iFAAiF;AACpG,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,GAAG,UAAU,EACG,EAAE,EAAE;IACpB,MAAM,kBAAkB,GAAG,CAAC,QAAQ,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE,CAAA;IAC7D,MAAM,mBAAmB,GAAG,UAAU,IAAI,CAAC,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAA;IAEnE,OAAO,CACL,4FAEkC,UAAU,+BACf,KAAK,IAAI,KAAK,KAAK,EAAE;QAEhD,oBAAC,KAAK,IACJ,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,KACpB,UAAU,GACd;QACF,oBAAC,KAAK,IAAC,OAAO,EAAE,EAAE,IAAG,KAAK,CAAS;QAElC,mBAAmB;YAClB,CAAC,kBAAkB,IAAI,KAAK,CAAC,CAAC,CAAC,CAC7B,oBAAC,UAAU,2BACW,OAAO,gBAChB,aAAa,EACxB,IAAI,EAAE,oBAAC,OAAO,OAAG,EACjB,OAAO,EAAE,GAAG,EAAE;oBACZ,OAAO,EAAE,EAAE,CAAA;oBACX,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;gBAC5B,CAAC,GACD,CACH,CAAC,CAAC,CAAC,CACF,oBAAC,MAAM,IAAC,OAAO,EAAC,UAAU,EAAC,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,QAAQ,IACtD,gBAAgB,CACV,CACV,CAAC;QACH,kBAAkB,IAAI,CACrB,2EAAyC,KAAK,CAAQ,CACvD,CACG,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/molecules/InputField/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/components",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7-alpha.0",
|
|
4
4
|
"module": "dist/index.js",
|
|
5
5
|
"typings": "dist/index.d.ts",
|
|
6
6
|
"author": "Emerson Laurentino @emersonlaurentino",
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"node": "16.18.0",
|
|
29
29
|
"yarn": "1.19.1"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "f740d9f405309548f33c81d061131de9905c95bf"
|
|
32
32
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { FC } from 'react'
|
|
3
|
+
|
|
4
|
+
// Icon from Phosphor Icons
|
|
5
|
+
const XCircle: FC = () => (
|
|
6
|
+
<svg
|
|
7
|
+
id="XCircle"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
fill="currentColor"
|
|
10
|
+
viewBox="0 0 256 256"
|
|
11
|
+
strokeWidth="16"
|
|
12
|
+
width={20}
|
|
13
|
+
height={20}
|
|
14
|
+
>
|
|
15
|
+
<rect width="256" height="256" fill="none"></rect>
|
|
16
|
+
<circle
|
|
17
|
+
cx="128"
|
|
18
|
+
cy="128"
|
|
19
|
+
r="96"
|
|
20
|
+
fill="none"
|
|
21
|
+
stroke="currentColor"
|
|
22
|
+
strokeMiterlimit="10"
|
|
23
|
+
></circle>
|
|
24
|
+
<line
|
|
25
|
+
x1="160"
|
|
26
|
+
y1="96"
|
|
27
|
+
x2="96"
|
|
28
|
+
y2="160"
|
|
29
|
+
fill="none"
|
|
30
|
+
stroke="currentColor"
|
|
31
|
+
strokeLinecap="round"
|
|
32
|
+
strokeLinejoin="round"
|
|
33
|
+
></line>
|
|
34
|
+
<line
|
|
35
|
+
x1="160"
|
|
36
|
+
y1="160"
|
|
37
|
+
x2="96"
|
|
38
|
+
y2="96"
|
|
39
|
+
fill="none"
|
|
40
|
+
stroke="currentColor"
|
|
41
|
+
strokeLinecap="round"
|
|
42
|
+
strokeLinejoin="round"
|
|
43
|
+
></line>
|
|
44
|
+
</svg>
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
export default XCircle
|
package/src/assets/index.ts
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
2
|
+
import type { InputHTMLAttributes } from 'react'
|
|
3
|
+
import React, { forwardRef } from 'react'
|
|
4
|
+
|
|
5
|
+
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
6
|
+
/**
|
|
7
|
+
* ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
|
|
8
|
+
*/
|
|
9
|
+
testId?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
|
13
|
+
{ testId = 'fs-input', ...otherProps },
|
|
14
|
+
ref
|
|
15
|
+
) {
|
|
16
|
+
return <input ref={ref} data-fs-input data-testid={testId} {...otherProps} />
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export default Input
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,8 @@ export { default as Checkbox } from './atoms/Checkbox'
|
|
|
7
7
|
export type { CheckboxProps } from './atoms/Checkbox'
|
|
8
8
|
export { default as Icon } from './atoms/Icon'
|
|
9
9
|
export type { IconProps } from './atoms/Icon'
|
|
10
|
+
export { default as Input } from './atoms/Input'
|
|
11
|
+
export type { InputProps } from './atoms/Input'
|
|
10
12
|
export { default as Label } from './atoms/Label'
|
|
11
13
|
export type { LabelProps } from './atoms/Label'
|
|
12
14
|
export { default as Overlay } from './atoms/Overlay'
|
|
@@ -19,6 +21,10 @@ export { default as CheckboxField } from './molecules/CheckboxField'
|
|
|
19
21
|
export type { CheckboxFieldProps } from './molecules/CheckboxField'
|
|
20
22
|
export { default as IconButton } from './molecules/IconButton'
|
|
21
23
|
export type { IconButtonProps } from './molecules/IconButton'
|
|
24
|
+
export { default as DiscountBadge } from './molecules/DiscountBadge'
|
|
25
|
+
export type { DiscountBadgeProps } from './molecules/DiscountBadge'
|
|
26
|
+
export { default as InputField } from './molecules/InputField'
|
|
27
|
+
export type { InputFieldProps } from './molecules/InputField'
|
|
22
28
|
export { default as RadioField } from './molecules/RadioField'
|
|
23
29
|
export type { RadioFieldProps } from './molecules/RadioField'
|
|
24
30
|
export { default as Tag } from './molecules/Tag'
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Badge } from '../..'
|
|
3
|
+
|
|
4
|
+
import { useDiscountPercent } from '../DiscountBadge/useDiscountPercent'
|
|
5
|
+
|
|
6
|
+
export type DiscountBadgeProps = {
|
|
7
|
+
/**
|
|
8
|
+
* Specifies price without discount applied.
|
|
9
|
+
*/
|
|
10
|
+
listPrice: number
|
|
11
|
+
/**
|
|
12
|
+
* Specifies current price with discount applied.
|
|
13
|
+
*/
|
|
14
|
+
spotPrice: number
|
|
15
|
+
/**
|
|
16
|
+
* Sets the component's size.
|
|
17
|
+
*/
|
|
18
|
+
size?: 'small' | 'big'
|
|
19
|
+
/**
|
|
20
|
+
* Sets the limit percentage value to consider a low discount.
|
|
21
|
+
*/
|
|
22
|
+
thresholdLow?: number
|
|
23
|
+
/**
|
|
24
|
+
* Sets the limit percentage value to consider a high discount.
|
|
25
|
+
*/
|
|
26
|
+
thresholdHigh?: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const DiscountBadge = ({
|
|
30
|
+
listPrice,
|
|
31
|
+
spotPrice,
|
|
32
|
+
size = 'small',
|
|
33
|
+
thresholdLow = 15,
|
|
34
|
+
thresholdHigh = 40,
|
|
35
|
+
}: DiscountBadgeProps) => {
|
|
36
|
+
const discountPercent = useDiscountPercent(listPrice, spotPrice)
|
|
37
|
+
|
|
38
|
+
if (discountPercent === 0) {
|
|
39
|
+
return <></>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const discountVariant =
|
|
43
|
+
discountPercent <= thresholdLow
|
|
44
|
+
? 'low'
|
|
45
|
+
: discountPercent <= thresholdHigh
|
|
46
|
+
? 'medium'
|
|
47
|
+
: 'high'
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Badge
|
|
51
|
+
size={size}
|
|
52
|
+
data-fs-discount-badge
|
|
53
|
+
data-fs-discount-badge-variant={discountVariant}
|
|
54
|
+
>
|
|
55
|
+
{discountPercent}% off
|
|
56
|
+
</Badge>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default DiscountBadge
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
|
|
3
|
+
export const useDiscountPercent = (listPrice: number, spotPrice: number) => {
|
|
4
|
+
return useMemo(() => {
|
|
5
|
+
const diff = listPrice - spotPrice
|
|
6
|
+
const discount = (diff * 100) / listPrice
|
|
7
|
+
|
|
8
|
+
return Math.round(discount)
|
|
9
|
+
}, [spotPrice, listPrice])
|
|
10
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { MutableRefObject } from 'react'
|
|
3
|
+
|
|
4
|
+
import { Input, Label, IconButton, Button } from '../../index'
|
|
5
|
+
import type { InputProps } from '../../index'
|
|
6
|
+
import { XCircle } from '../../assets'
|
|
7
|
+
|
|
8
|
+
type DefaultProps = {
|
|
9
|
+
/**
|
|
10
|
+
* ID to identify input and corresponding label.
|
|
11
|
+
*/
|
|
12
|
+
id: string
|
|
13
|
+
/**
|
|
14
|
+
* The text displayed to identify input text.
|
|
15
|
+
*/
|
|
16
|
+
label: string
|
|
17
|
+
/**
|
|
18
|
+
* The error message is displayed when an error occurs.
|
|
19
|
+
*/
|
|
20
|
+
error?: string
|
|
21
|
+
/**
|
|
22
|
+
* Component's ref.
|
|
23
|
+
*/
|
|
24
|
+
inputRef?: MutableRefObject<HTMLInputElement | null>
|
|
25
|
+
/**
|
|
26
|
+
* Specifies that the whole input component should be disabled.
|
|
27
|
+
*/
|
|
28
|
+
disabled?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type ActionableInputField =
|
|
32
|
+
| {
|
|
33
|
+
actionable?: never
|
|
34
|
+
onSubmit?: never
|
|
35
|
+
onClear?: never
|
|
36
|
+
buttonActionText?: string
|
|
37
|
+
displayClearButton?: never
|
|
38
|
+
}
|
|
39
|
+
| {
|
|
40
|
+
/**
|
|
41
|
+
* Adds a Button to the component.
|
|
42
|
+
*/
|
|
43
|
+
actionable: true
|
|
44
|
+
/**
|
|
45
|
+
* Callback function when button is clicked. Required for actionable input.
|
|
46
|
+
*/
|
|
47
|
+
onSubmit: () => void
|
|
48
|
+
/**
|
|
49
|
+
* Callback function when clear button is clicked. Required for actionable input.
|
|
50
|
+
*/
|
|
51
|
+
onClear: () => void
|
|
52
|
+
/**
|
|
53
|
+
* The text displayed on the Button. Suggestion: maximum 9 characters.
|
|
54
|
+
*/
|
|
55
|
+
buttonActionText?: string
|
|
56
|
+
/**
|
|
57
|
+
* Boolean that controls the clear button.
|
|
58
|
+
*/
|
|
59
|
+
displayClearButton?: boolean
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type InputFieldProps = DefaultProps &
|
|
63
|
+
Omit<InputProps, 'disabled' | 'onSubmit'> &
|
|
64
|
+
ActionableInputField
|
|
65
|
+
|
|
66
|
+
const InputField = ({
|
|
67
|
+
id,
|
|
68
|
+
label,
|
|
69
|
+
type = 'text',
|
|
70
|
+
error,
|
|
71
|
+
displayClearButton,
|
|
72
|
+
actionable,
|
|
73
|
+
buttonActionText = 'Apply',
|
|
74
|
+
onSubmit,
|
|
75
|
+
onClear,
|
|
76
|
+
placeholder = ' ', // initializes with an empty space to style float label using `placeholder-shown`
|
|
77
|
+
inputRef,
|
|
78
|
+
disabled,
|
|
79
|
+
value,
|
|
80
|
+
...otherProps
|
|
81
|
+
}: InputFieldProps) => {
|
|
82
|
+
const shouldDisplayError = !disabled && error && error !== ''
|
|
83
|
+
const shouldDisplayButton = actionable && !disabled && value !== ''
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div
|
|
87
|
+
data-fs-input-field
|
|
88
|
+
data-fs-input-field-actionable={actionable}
|
|
89
|
+
data-fs-input-field-error={error && error !== ''}
|
|
90
|
+
>
|
|
91
|
+
<Input
|
|
92
|
+
id={id}
|
|
93
|
+
type={type}
|
|
94
|
+
value={value}
|
|
95
|
+
ref={inputRef}
|
|
96
|
+
disabled={disabled}
|
|
97
|
+
placeholder={placeholder}
|
|
98
|
+
{...otherProps}
|
|
99
|
+
/>
|
|
100
|
+
<Label htmlFor={id}>{label}</Label>
|
|
101
|
+
|
|
102
|
+
{shouldDisplayButton &&
|
|
103
|
+
(displayClearButton || error ? (
|
|
104
|
+
<IconButton
|
|
105
|
+
data-fs-button-size="small"
|
|
106
|
+
aria-label="Clear Field"
|
|
107
|
+
icon={<XCircle />}
|
|
108
|
+
onClick={() => {
|
|
109
|
+
onClear?.()
|
|
110
|
+
inputRef?.current?.focus()
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
) : (
|
|
114
|
+
<Button variant="tertiary" size="small" onClick={onSubmit}>
|
|
115
|
+
{buttonActionText}
|
|
116
|
+
</Button>
|
|
117
|
+
))}
|
|
118
|
+
{shouldDisplayError && (
|
|
119
|
+
<span data-fs-input-field-error-message>{error}</span>
|
|
120
|
+
)}
|
|
121
|
+
</div>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default InputField
|