@faststore/components 2.0.66-alpha.0 → 2.0.70-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.
Files changed (76) hide show
  1. package/dist/assets/ArrowElbowDownRight.d.ts +3 -2
  2. package/dist/assets/ArrowElbowDownRight.js +3 -3
  3. package/dist/assets/ArrowElbowDownRight.js.map +1 -1
  4. package/dist/assets/DotsThree.d.ts +4 -0
  5. package/dist/assets/DotsThree.js +9 -0
  6. package/dist/assets/DotsThree.js.map +1 -0
  7. package/dist/assets/House.d.ts +3 -2
  8. package/dist/assets/House.js +1 -1
  9. package/dist/assets/House.js.map +1 -1
  10. package/dist/assets/IconProps.d.ts +3 -0
  11. package/dist/assets/IconProps.js +2 -0
  12. package/dist/assets/IconProps.js.map +1 -0
  13. package/dist/assets/index.d.ts +1 -0
  14. package/dist/assets/index.js +1 -0
  15. package/dist/assets/index.js.map +1 -1
  16. package/dist/atoms/Price/Price.d.ts +4 -0
  17. package/dist/atoms/Price/Price.js +5 -2
  18. package/dist/atoms/Price/Price.js.map +1 -1
  19. package/dist/index.d.ts +4 -0
  20. package/dist/index.js +2 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/molecules/Breadcrumb/Breadcrumb.d.ts +5 -0
  23. package/dist/molecules/Breadcrumb/Breadcrumb.js +7 -0
  24. package/dist/molecules/Breadcrumb/Breadcrumb.js.map +1 -0
  25. package/dist/molecules/Breadcrumb/BreadcrumbBase.d.ts +77 -0
  26. package/dist/molecules/Breadcrumb/BreadcrumbBase.js +51 -0
  27. package/dist/molecules/Breadcrumb/BreadcrumbBase.js.map +1 -0
  28. package/dist/molecules/Breadcrumb/BreadcrumbPure.d.ts +23 -0
  29. package/dist/molecules/Breadcrumb/BreadcrumbPure.js +12 -0
  30. package/dist/molecules/Breadcrumb/BreadcrumbPure.js.map +1 -0
  31. package/dist/molecules/Breadcrumb/Divider.d.ts +4 -0
  32. package/dist/molecules/Breadcrumb/Divider.js +14 -0
  33. package/dist/molecules/Breadcrumb/Divider.js.map +1 -0
  34. package/dist/molecules/Breadcrumb/HomeLink.d.ts +3 -0
  35. package/dist/molecules/Breadcrumb/HomeLink.js +6 -0
  36. package/dist/molecules/Breadcrumb/HomeLink.js.map +1 -0
  37. package/dist/molecules/Breadcrumb/ListItem.d.ts +10 -0
  38. package/dist/molecules/Breadcrumb/ListItem.js +20 -0
  39. package/dist/molecules/Breadcrumb/ListItem.js.map +1 -0
  40. package/dist/molecules/Breadcrumb/index.d.ts +4 -0
  41. package/dist/molecules/Breadcrumb/index.js +3 -0
  42. package/dist/molecules/Breadcrumb/index.js.map +1 -0
  43. package/dist/molecules/ProductCard/ProductCardContent.js +2 -2
  44. package/dist/molecules/ProductCard/ProductCardContent.js.map +1 -1
  45. package/dist/molecules/SearchProductCard/SearchProductCard.d.ts +20 -0
  46. package/dist/molecules/SearchProductCard/SearchProductCard.js +8 -0
  47. package/dist/molecules/SearchProductCard/SearchProductCard.js.map +1 -0
  48. package/dist/molecules/SearchProductCard/SearchProductCardContent.d.ts +20 -0
  49. package/dist/molecules/SearchProductCard/SearchProductCardContent.js +11 -0
  50. package/dist/molecules/SearchProductCard/SearchProductCardContent.js.map +1 -0
  51. package/dist/molecules/SearchProductCard/SearchProductCardImage.d.ts +10 -0
  52. package/dist/molecules/SearchProductCard/SearchProductCardImage.js +6 -0
  53. package/dist/molecules/SearchProductCard/SearchProductCardImage.js.map +1 -0
  54. package/dist/molecules/SearchProductCard/index.d.ts +6 -0
  55. package/dist/molecules/SearchProductCard/index.js +4 -0
  56. package/dist/molecules/SearchProductCard/index.js.map +1 -0
  57. package/package.json +2 -2
  58. package/src/assets/ArrowElbowDownRight.tsx +5 -11
  59. package/src/assets/DotsThree.tsx +21 -0
  60. package/src/assets/House.tsx +4 -4
  61. package/src/assets/IconProps.ts +3 -0
  62. package/src/assets/index.ts +1 -0
  63. package/src/atoms/Price/Price.tsx +8 -0
  64. package/src/index.ts +18 -0
  65. package/src/molecules/Breadcrumb/Breadcrumb.tsx +17 -0
  66. package/src/molecules/Breadcrumb/BreadcrumbBase.tsx +165 -0
  67. package/src/molecules/Breadcrumb/BreadcrumbPure.tsx +59 -0
  68. package/src/molecules/Breadcrumb/Divider.tsx +18 -0
  69. package/src/molecules/Breadcrumb/HomeLink.tsx +15 -0
  70. package/src/molecules/Breadcrumb/ListItem.tsx +38 -0
  71. package/src/molecules/Breadcrumb/index.ts +4 -0
  72. package/src/molecules/ProductCard/ProductCardContent.tsx +2 -0
  73. package/src/molecules/SearchProductCard/SearchProductCard.tsx +54 -0
  74. package/src/molecules/SearchProductCard/SearchProductCardContent.tsx +51 -0
  75. package/src/molecules/SearchProductCard/SearchProductCardImage.tsx +31 -0
  76. package/src/molecules/SearchProductCard/index.ts +8 -0
@@ -0,0 +1,10 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ import React from 'react';
3
+ export interface SearchProductCardImageProps extends HTMLAttributes<HTMLDivElement> {
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 SearchProductCardImage: React.ForwardRefExoticComponent<SearchProductCardImageProps & React.RefAttributes<HTMLDivElement>>;
10
+ export default SearchProductCardImage;
@@ -0,0 +1,6 @@
1
+ import React, { forwardRef } from 'react';
2
+ const SearchProductCardImage = forwardRef(function SearchProductCardImage({ testId = 'fs-search-product-card-image', children, ...otherProps }, ref) {
3
+ return (React.createElement("div", { ref: ref, "data-fs-search-product-card-image": true, "data-testid": testId, ...otherProps }, children));
4
+ });
5
+ export default SearchProductCardImage;
6
+ //# sourceMappingURL=SearchProductCardImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchProductCardImage.js","sourceRoot":"","sources":["../../../src/molecules/SearchProductCard/SearchProductCardImage.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAUzC,MAAM,sBAAsB,GAAG,UAAU,CAGvC,SAAS,sBAAsB,CAC/B,EAAE,MAAM,GAAG,8BAA8B,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,EACpE,GAAG;IAEH,OAAO,CACL,6BACE,GAAG,EAAE,GAAG,4DAEK,MAAM,KACf,UAAU,IAEb,QAAQ,CACL,CACP,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,sBAAsB,CAAA"}
@@ -0,0 +1,6 @@
1
+ export { default } from './SearchProductCard';
2
+ export type { SearchProductCardProps } from './SearchProductCard';
3
+ export { default as SearchProductCardImage } from './SearchProductCardImage';
4
+ export type { SearchProductCardImageProps } from './SearchProductCardImage';
5
+ export { default as SearchProductCardContent } from './SearchProductCardContent';
6
+ export type { SearchProductCardContentProps } from './SearchProductCardContent';
@@ -0,0 +1,4 @@
1
+ export { default } from './SearchProductCard';
2
+ export { default as SearchProductCardImage } from './SearchProductCardImage';
3
+ export { default as SearchProductCardContent } from './SearchProductCardContent';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/molecules/SearchProductCard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAG5E,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,4BAA4B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/components",
3
- "version": "2.0.66-alpha.0",
3
+ "version": "2.0.70-alpha.0",
4
4
  "module": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
6
6
  "author": "Emerson Laurentino @emersonlaurentino",
@@ -30,5 +30,5 @@
30
30
  "node": "16.18.0",
31
31
  "yarn": "1.19.1"
32
32
  },
33
- "gitHead": "67c201f56dcedf4ee63b4a852264e8b147b8dff0"
33
+ "gitHead": "5718a199c16ee52a9446cd4090a4f564863c4243"
34
34
  }
@@ -1,32 +1,26 @@
1
1
  import React from 'react'
2
- import type { FC } from 'react'
2
+ import { IconProps } from './IconProps'
3
3
 
4
4
  // Icon from Phosphor Icons
5
- const ArrowElbowDownRight: FC = () => (
5
+ const ArrowElbowDownRight = ({ size = 24 }: IconProps) => (
6
6
  <svg
7
7
  xmlns="http://www.w3.org/2000/svg"
8
8
  viewBox="0 0 256 256"
9
9
  fill="currentColor"
10
10
  strokeWidth="16"
11
- width={24}
12
- height={24}
11
+ width={size}
12
+ height={size}
13
13
  >
14
14
  <rect width="256" height="256" fill="none"></rect>
15
15
  <polyline
16
16
  points="160 128 208 176 160 224"
17
17
  fill="none"
18
- stroke="currentColor"
19
- stroke-linecap="round"
20
- stroke-linejoin="round"
21
- stroke-width="16"
18
+ stroke="currentColor"
22
19
  ></polyline>
23
20
  <polyline
24
21
  points="64 32 64 176 208 176"
25
22
  fill="none"
26
23
  stroke="currentColor"
27
- stroke-linecap="round"
28
- stroke-linejoin="round"
29
- stroke-width="16"
30
24
  ></polyline>
31
25
  </svg>
32
26
  )
@@ -0,0 +1,21 @@
1
+ import React from 'react'
2
+ import { IconProps } from './IconProps'
3
+
4
+ // Icon from Phosphor Icons
5
+ const DotsThree = ({ size = 24 }: IconProps) => (
6
+ <svg
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="currentColor"
9
+ viewBox="0 0 256 256"
10
+ strokeWidth="16"
11
+ width={size}
12
+ height={size}
13
+ >
14
+ <rect width="256" height="256" fill="none"></rect>
15
+ <circle cx="128" cy="128" r="12"></circle>
16
+ <circle cx="192" cy="128" r="12"></circle>
17
+ <circle cx="64" cy="128" r="12"></circle>
18
+ </svg>
19
+ )
20
+
21
+ export default DotsThree
@@ -1,15 +1,15 @@
1
1
  import React from 'react'
2
- import type { FC } from 'react'
2
+ import { IconProps } from './IconProps'
3
3
 
4
4
  // Icon from Phosphor Icons
5
- const House: FC = () => (
5
+ const House = ({ size = 24 }: IconProps) => (
6
6
  <svg
7
7
  xmlns="http://www.w3.org/2000/svg"
8
8
  fill="currentColor"
9
9
  viewBox="0 0 256 256"
10
10
  strokeWidth="16"
11
- width={24}
12
- height={24}
11
+ width={size}
12
+ height={size}
13
13
  >
14
14
  <rect width="256" height="256" fill="none"></rect>
15
15
  <path
@@ -0,0 +1,3 @@
1
+ export type IconProps = {
2
+ size?: number
3
+ }
@@ -5,6 +5,7 @@ export { default as ArrowElbowDownRight } from './ArrowElbowDownRight'
5
5
  export { default as ArrowRight } from './ArrowRight'
6
6
  export { default as CaretDown } from './CaretDown'
7
7
  export { default as Checked } from './Checked'
8
+ export { default as DotsThree } from './DotsThree'
8
9
  export { default as Heart } from './Heart'
9
10
  export { default as House } from './House'
10
11
  export { default as Minus } from './Minus'
@@ -1,6 +1,8 @@
1
1
  import type { HTMLAttributes, ElementType, ReactNode } from 'react'
2
2
  import React, { forwardRef } from 'react'
3
3
 
4
+ import { SROnly } from '../../'
5
+
4
6
  export type PriceVariant =
5
7
  | 'selling'
6
8
  | 'listing'
@@ -32,6 +34,10 @@ export interface PriceProps
32
34
  * The current use case variant for prices.
33
35
  */
34
36
  variant?: PriceVariant
37
+ /**
38
+ * Text for the screen readers only
39
+ */
40
+ SRText?: string
35
41
  }
36
42
 
37
43
  const Price = forwardRef<Omit<HTMLSpanElement, 'children'>, PriceProps>(
@@ -42,6 +48,7 @@ const Price = forwardRef<Omit<HTMLSpanElement, 'children'>, PriceProps>(
42
48
  variant = 'selling',
43
49
  testId = 'fs-price',
44
50
  formatter = (price) => price,
51
+ SRText,
45
52
  ...otherProps
46
53
  },
47
54
  ref
@@ -56,6 +63,7 @@ const Price = forwardRef<Omit<HTMLSpanElement, 'children'>, PriceProps>(
56
63
  data-testid={testId}
57
64
  {...otherProps}
58
65
  >
66
+ {SRText && <SROnly text={SRText} />}
59
67
  {formattedPrice}
60
68
  </Component>
61
69
  )
package/src/index.ts CHANGED
@@ -52,6 +52,14 @@ export type {
52
52
  } from './molecules/Accordion'
53
53
  export { default as Alert } from './molecules/Alert'
54
54
  export type { AlertProps } from './molecules/Alert'
55
+ export {
56
+ BreadcrumbPure,
57
+ Breadcrumb,
58
+ } from './molecules/Breadcrumb'
59
+ export type {
60
+ BreadcrumbPureProps,
61
+ BreadcrumbProps,
62
+ } from './molecules/Breadcrumb'
55
63
  export { default as BuyButton } from './molecules/BuyButton'
56
64
  export {
57
65
  default as CartItem,
@@ -111,6 +119,16 @@ export { default as RadioGroup, RadioOption } from './molecules/RadioGroup'
111
119
  export type { RadioGroupProps, RadioOptionProps } from './molecules/RadioGroup'
112
120
  export { default as Rating } from './molecules/Rating'
113
121
  export type { RatingProps } from './molecules/Rating'
122
+ export {
123
+ default as SearchProductCard,
124
+ SearchProductCardImage,
125
+ SearchProductCardContent,
126
+ } from './molecules/SearchProductCard'
127
+ export type {
128
+ SearchProductCardProps,
129
+ SearchProductCardImageProps,
130
+ SearchProductCardContentProps,
131
+ } from './molecules/SearchProductCard'
114
132
  export { default as SelectField } from './molecules/SelectField'
115
133
  export type { SelectFieldProps } from './molecules/SelectField'
116
134
  export {
@@ -0,0 +1,17 @@
1
+ import React from 'react'
2
+ import BreadcrumbBase, { BreadcrumbBaseProps } from './BreadcrumbBase'
3
+
4
+ export type BreadcrumbProps = Omit<BreadcrumbBaseProps, "isDesktop">
5
+
6
+
7
+ const Breadcrumb = ({
8
+ breadcrumbList,
9
+ ...otherProps
10
+ }: BreadcrumbProps) => (
11
+ <>
12
+ <BreadcrumbBase breadcrumbList={breadcrumbList} {...otherProps} />
13
+ <BreadcrumbBase breadcrumbList={breadcrumbList} isDesktop {...otherProps} />
14
+ </>
15
+ )
16
+
17
+ export default Breadcrumb
@@ -0,0 +1,165 @@
1
+ import React, { cloneElement, forwardRef, ReactElement, ReactNode, useCallback } from 'react'
2
+ import { ArrowElbowDownRight, DotsThree } from '../../assets'
3
+ import Icon from '../../atoms/Icon'
4
+ import Link from '../../atoms/Link'
5
+ import Dropdown, {
6
+ DropdownButton,
7
+ DropdownMenu,
8
+ DropdownItem,
9
+ } from '../Dropdown'
10
+ import BreadcrumbPure, { BreadcrumbPureProps } from './BreadcrumbPure'
11
+ import HomeLink from './HomeLink'
12
+
13
+ type ItemElement = {
14
+ item: string
15
+ name: string
16
+ position: number
17
+ }
18
+
19
+ type RenderLinkProps = {
20
+ /**
21
+ * Item prop for specific item.
22
+ */
23
+ itemProps: ItemElement
24
+ /**
25
+ * Represents if the item is collapsed or not.
26
+ */
27
+ collapsed: boolean
28
+ }
29
+
30
+ export type BreadcrumbBaseProps = {
31
+ /**
32
+ * Array of ItemElement that represents each breadcrumb item.
33
+ */
34
+ breadcrumbList: ItemElement[]
35
+ /**
36
+ * Represents if is Desktop os mobile.
37
+ */
38
+ isDesktop?: boolean
39
+ /**
40
+ * Link go to home.
41
+ */
42
+ homeLink?: ReactElement
43
+ /**
44
+ * Icon for dropdown button.
45
+ */
46
+ dropdownButtonIcon?: ReactNode
47
+ /**
48
+ * Icon for collapsed items.
49
+ */
50
+ collapsedItemsIcon?: ReactNode
51
+ /**
52
+ * Function to render a item as breadcrumb link.
53
+ * @param renderLinkProps Properties for each item to be rendered.
54
+ * @returns Link to be rendered.
55
+ */
56
+ renderLink?: (renderLinkProps: RenderLinkProps) => ReactElement
57
+ } & BreadcrumbPureProps
58
+
59
+ const BreadcrumbBase = forwardRef<HTMLDivElement, BreadcrumbBaseProps>(
60
+ function BreadcrumbBase(
61
+ {
62
+ children,
63
+ divider: rawDivider = '',
64
+ testId = 'fs-breadcrumb',
65
+ breadcrumbList,
66
+ isDesktop = false,
67
+ renderLink,
68
+ homeLink = <HomeLink />,
69
+ dropdownButtonIcon = <Icon component={<DotsThree />} />,
70
+ collapsedItemsIcon = <Icon component={<ArrowElbowDownRight />} />,
71
+ ...otherProps
72
+ },
73
+ ref
74
+ ) {
75
+ const homeLinkProps = {
76
+ 'data-fs-breadcrumb-link': true,
77
+ 'data-fs-breadcrumb-link-home': true,
78
+ 'aria-label': 'Go to homepage',
79
+ href: '/',
80
+ }
81
+
82
+ const homeLinkWithProps = cloneElement(homeLink, homeLinkProps)
83
+
84
+ const firstItem = isDesktop ? breadcrumbList[0] : null
85
+ const mediumItems = isDesktop
86
+ ? breadcrumbList.slice(1, -2)
87
+ : breadcrumbList.slice(0, -2)
88
+
89
+ const lastItems = breadcrumbList.slice(-2)
90
+
91
+ const collapseBreadcrumb = breadcrumbList.length > 4
92
+
93
+ const breadcrumbLink = useCallback((renderLinkProps: RenderLinkProps) => {
94
+ const breadcrumbItem = renderLink?.(renderLinkProps)
95
+ const itemProps = renderLinkProps.collapsed
96
+ ? {
97
+ 'data-fs-breadcrumb-dropdown-link': true,
98
+ }
99
+ : {
100
+ 'data-fs-breadcrumb-link': true,
101
+ }
102
+ return breadcrumbItem ? (
103
+ cloneElement(breadcrumbItem, {...itemProps, key: renderLinkProps.itemProps.position })
104
+ ) : (
105
+ <Link {...itemProps} href={renderLinkProps.itemProps.item} key={renderLinkProps.itemProps.position}>
106
+ {renderLinkProps.itemProps.name}
107
+ </Link>
108
+ )
109
+ }, [renderLink])
110
+
111
+ return (
112
+ <BreadcrumbPure
113
+ ref={ref}
114
+ data-fs-breadcrumb-is-desktop={isDesktop}
115
+ {...otherProps}
116
+ >
117
+ {homeLinkWithProps}
118
+
119
+ {!collapseBreadcrumb &&
120
+ breadcrumbList.map((item, index) => {
121
+ return breadcrumbList.length === index + 1 ? (
122
+ <span key={String(item.position)}>{item.name}</span>
123
+ ) : (
124
+ breadcrumbLink({ itemProps: item, collapsed: false })
125
+ )
126
+ })}
127
+
128
+ {collapseBreadcrumb &&
129
+ firstItem &&
130
+ breadcrumbLink({ itemProps: firstItem, collapsed: false })}
131
+
132
+ {collapseBreadcrumb && (
133
+ <Dropdown>
134
+ <DropdownButton
135
+ data-fs-breadcrumb-dropdown-button
136
+ size="small"
137
+ >{dropdownButtonIcon}</DropdownButton>
138
+ <DropdownMenu data-fs-breadcrumb-dropdown-menu>
139
+ {mediumItems.map((item) => (
140
+ <DropdownItem
141
+ data-fs-breadcrumb-dropdown-item
142
+ key={String(item.position)}
143
+ icon={collapsedItemsIcon}
144
+ >
145
+ {breadcrumbLink({ itemProps: item, collapsed: true })}
146
+ </DropdownItem>
147
+ ))}
148
+ </DropdownMenu>
149
+ </Dropdown>
150
+ )}
151
+
152
+ {collapseBreadcrumb &&
153
+ lastItems.map((item, index) => {
154
+ return lastItems.length === index + 1 ? (
155
+ <span key={String(item.position)}>{item.name}</span>
156
+ ) : (
157
+ breadcrumbLink({ itemProps: item, collapsed: false })
158
+ )
159
+ })}
160
+ </BreadcrumbPure>
161
+ )
162
+ }
163
+ )
164
+
165
+ export default BreadcrumbBase
@@ -0,0 +1,59 @@
1
+ import React, { forwardRef } from "react"
2
+ import List from "../../atoms/List"
3
+ import type { HTMLAttributes, ReactNode } from 'react'
4
+ import ListItem from "./ListItem"
5
+
6
+ export type BreadcrumbPureProps = {
7
+ /**
8
+ * A ReactNode that will be rendered as the Divider icon.
9
+ */
10
+ divider?: ReactNode
11
+ /**
12
+ * ID to find this component in testing tools (e.g.: cypress, testing library, and jest).
13
+ */
14
+ testId?: string
15
+ } & HTMLAttributes<HTMLDivElement>
16
+
17
+ const BreadcrumbPure = forwardRef<HTMLDivElement, BreadcrumbPureProps>(
18
+ function BreadcrumbPure(
19
+ {
20
+ children,
21
+ divider: rawDivider = '',
22
+ testId = 'fs-breadcrumb',
23
+ ...otherProps
24
+ },
25
+ ref
26
+ ) {
27
+ return (
28
+ <nav
29
+ aria-label="Breadcrumb"
30
+ role="navigation"
31
+ ref={ref}
32
+ data-fs-breadcrumb
33
+ data-testid={testId}
34
+ {...otherProps}
35
+ >
36
+ <List as="ol" data-fs-breadcrumb-list>
37
+ {React.Children.toArray(children).map(
38
+ (child, index, childrenArray) => {
39
+ const isLastItem = index === childrenArray.length - 1
40
+
41
+ return (
42
+ <ListItem
43
+ isLastItem={isLastItem}
44
+ divider={rawDivider}
45
+ key={`breadcrumb-${index}`}
46
+ testId={testId}
47
+ >
48
+ {child}
49
+ </ListItem>
50
+ )
51
+ }
52
+ )}
53
+ </List>
54
+ </nav>
55
+ )
56
+ }
57
+ )
58
+
59
+ export default BreadcrumbPure
@@ -0,0 +1,18 @@
1
+ import React from "react"
2
+ import { BreadcrumbBaseProps } from "./BreadcrumbBase"
3
+
4
+ const Divider = ({ divider, testId }: Omit<BreadcrumbBaseProps, "breadcrumbList">) => {
5
+ const props = {
6
+ 'data-fs-breadcrumb-divider': true,
7
+ 'aria-hidden': true,
8
+ 'data-testid': `${testId}-divider`,
9
+ }
10
+
11
+ if (React.isValidElement(divider)) {
12
+ return React.cloneElement(divider, props)
13
+ }
14
+
15
+ return <span {...props}>{divider ?? '/'}</span>
16
+ }
17
+
18
+ export default Divider
@@ -0,0 +1,15 @@
1
+ import { House, Icon, Link } from "../..";
2
+ import React from "react";
3
+
4
+ const HomeLink = () => (
5
+ <Link
6
+ data-fs-breadcrumb-link
7
+ data-fs-breadcrumb-link-home
8
+ aria-label="Go to homepage"
9
+ href="/"
10
+ >
11
+ <Icon component={<House size={18} />} />
12
+ </Link>
13
+ )
14
+
15
+ export default HomeLink
@@ -0,0 +1,38 @@
1
+ import React, { ReactNode } from 'react'
2
+ import { BreadcrumbBaseProps } from './BreadcrumbBase'
3
+ import Divider from './Divider'
4
+
5
+ type ListItemProps = {
6
+ children: ReactNode
7
+ isLastItem: boolean
8
+ divider: BreadcrumbBaseProps['divider']
9
+ testId: string
10
+ }
11
+
12
+ const ListItem = ({ children, isLastItem, divider, testId }: ListItemProps) => {
13
+ const props = {
14
+ 'data-testid': `${testId}-item`,
15
+ 'data-fs-breadcrumb-item': isLastItem ? 'current' : true,
16
+ 'aria-current': isLastItem ? ('page' as const) : undefined,
17
+ }
18
+
19
+ if (!React.isValidElement(children)) {
20
+ return (
21
+ <li data-fs-breadcrumb-list-item>
22
+ <span {...props}>
23
+ {children}
24
+ {isLastItem ? null : <Divider divider={divider} testId={testId} />}
25
+ </span>
26
+ </li>
27
+ )
28
+ }
29
+
30
+ return (
31
+ <li data-fs-breadcrumb-list-item>
32
+ {React.cloneElement(children, props)}
33
+ {isLastItem ? null : <Divider divider={divider} testId={testId} />}
34
+ </li>
35
+ )
36
+ }
37
+
38
+ export default ListItem
@@ -0,0 +1,4 @@
1
+ export { default as BreadcrumbPure } from './BreadcrumbPure'
2
+ export type { BreadcrumbPureProps } from './BreadcrumbPure'
3
+ export { default as Breadcrumb } from './Breadcrumb'
4
+ export type { BreadcrumbProps } from './Breadcrumb'
@@ -103,6 +103,7 @@ const ProductCardContent = forwardRef<HTMLElement, ProductCardContentProps>(
103
103
  testId="list-price"
104
104
  data-value={price?.listPrice}
105
105
  variant="listing"
106
+ SRText="Original price:"
106
107
  />
107
108
  <Price
108
109
  value={price?.value ? price.value : 0}
@@ -110,6 +111,7 @@ const ProductCardContent = forwardRef<HTMLElement, ProductCardContentProps>(
110
111
  testId="price"
111
112
  data-value={price?.value}
112
113
  variant="spot"
114
+ SRText="Sale Price:"
113
115
  />
114
116
  </div>
115
117
  {ratingValue && <Rating value={ratingValue} icon={<Star />} />}
@@ -0,0 +1,54 @@
1
+ import React, { forwardRef } from 'react'
2
+ import type { HTMLAttributes } from 'react'
3
+
4
+ import { Link, LinkProps, LinkElementType } from '../../'
5
+
6
+ export interface SearchProductCardProps extends HTMLAttributes<HTMLDivElement> {
7
+ /**
8
+ * ID to find this component in testing tools (e.g.: cypress,
9
+ * testing-library, and jest).
10
+ */
11
+ testId?: string
12
+ /**
13
+ * Props for the link from SearchProduct component.
14
+ */
15
+ linkProps?: Partial<LinkProps<LinkElementType>>
16
+ /**
17
+ * Callback function when SearchProduct link is clicked.
18
+ */
19
+ onLinkClick?: () => void
20
+ }
21
+
22
+ const SearchProductCard = forwardRef<HTMLDivElement, SearchProductCardProps>(
23
+ function ProductCard(
24
+ {
25
+ testId = 'fs-search-product-card',
26
+ linkProps,
27
+ onLinkClick,
28
+ children,
29
+ ...otherProps
30
+ },
31
+ ref
32
+ ) {
33
+ return (
34
+ <article
35
+ ref={ref}
36
+ data-fs-search-product-card
37
+ data-testid={testId}
38
+ {...otherProps}
39
+ >
40
+ <Link
41
+ {...linkProps}
42
+ data-fs-search-product-card-link
43
+ title={name}
44
+ variant="display"
45
+ onClick={onLinkClick}
46
+ >
47
+ {children}
48
+ </Link>
49
+ </article>
50
+ )
51
+ }
52
+ )
53
+
54
+ export default SearchProductCard
@@ -0,0 +1,51 @@
1
+ import React, { forwardRef } from 'react'
2
+ import { Price } from '../../'
3
+ import type { PriceFormatter } from '../../atoms/Price/Price'
4
+
5
+ interface Price {
6
+ value: number
7
+ listPrice: number
8
+ formatter: PriceFormatter
9
+ }
10
+
11
+ export type SearchProductCardContentProps = {
12
+ /**
13
+ * Specifies the product's title.
14
+ */
15
+ title: string
16
+ /**
17
+ * Specifies product's prices.
18
+ */
19
+ price: Price
20
+ }
21
+
22
+ const SearchProductCardContent = forwardRef<
23
+ HTMLElement,
24
+ SearchProductCardContentProps
25
+ >(function SearchProductCardContent({ price, title, ...otherProps }, ref) {
26
+ return (
27
+ <section ref={ref} data-fs-search-product-card-content {...otherProps}>
28
+ <p data-fs-search-product-card-title>{title}</p>
29
+ <span data-fs-search-product-card-prices>
30
+ <Price
31
+ value={price?.listPrice ? price.listPrice : 0}
32
+ formatter={price?.formatter}
33
+ testId="list-price"
34
+ data-value={price?.listPrice}
35
+ variant="listing"
36
+ SRText="Original price:"
37
+ />
38
+ <Price
39
+ value={price?.value ? price.value : 0}
40
+ formatter={price?.formatter}
41
+ testId="price"
42
+ data-value={price?.value}
43
+ variant="spot"
44
+ SRText="Price:"
45
+ />
46
+ </span>
47
+ </section>
48
+ )
49
+ })
50
+
51
+ export default SearchProductCardContent