@sonic-equipment/ui 0.0.11 → 0.0.12

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 (38) hide show
  1. package/README.md +46 -18
  2. package/dist/badges/tag/tag.d.ts +5 -0
  3. package/dist/badges/tag/tag.stories.d.ts +18 -0
  4. package/dist/base.css +18 -0
  5. package/dist/buttons/button/button.d.ts +13 -8
  6. package/dist/buttons/button/button.stories.d.ts +11 -6
  7. package/dist/buttons/favorite/favorite-button.d.ts +2 -2
  8. package/dist/buttons/favorite/favorite-button.stories.d.ts +6 -6
  9. package/dist/buttons/icon-button/icon-button.d.ts +9 -7
  10. package/dist/buttons/icon-button/icon-button.stories.d.ts +6 -6
  11. package/dist/cards/product-card/product-card.d.ts +9 -9
  12. package/dist/cards/product-card/product-card.stories.d.ts +3 -3
  13. package/dist/display/product-price/product-price.d.ts +11 -0
  14. package/dist/display/product-price/product-price.stories.d.ts +15 -0
  15. package/dist/display/product-sku/product-sku.d.ts +4 -0
  16. package/dist/display/product-sku/product-sku.stories.d.ts +13 -0
  17. package/dist/fonts.css +96 -49
  18. package/dist/icons/arrows/left-arrow-filled-icon.d.ts +2 -0
  19. package/dist/icons/arrows/right-arrow-filled-icon.d.ts +2 -0
  20. package/dist/icons/cart/cart-filled-icon.d.ts +2 -0
  21. package/dist/icons/cart/cart-outlined-icon.d.ts +2 -0
  22. package/dist/index.d.ts +89 -45
  23. package/dist/index.js +72 -31
  24. package/dist/inputs/checkbox/checkbox.d.ts +11 -4
  25. package/dist/inputs/checkbox/checkbox.stories.d.ts +8 -6
  26. package/dist/product-listing/filters/colors/color-filter.d.ts +5 -5
  27. package/dist/product-listing/filters/filter/filter.d.ts +4 -4
  28. package/dist/product-listing/product-listing.d.ts +16 -13
  29. package/dist/product-listing/product-listing.stories.d.ts +7 -7
  30. package/dist/product-listing/search-params.d.ts +3 -3
  31. package/dist/shared/types/product.d.ts +4 -0
  32. package/dist/styles.css +296 -89
  33. package/dist/tokens/tokens.d.ts +2 -0
  34. package/dist/typography/heading/heading.d.ts +17 -0
  35. package/dist/typography/heading/heading.stories.d.ts +37 -0
  36. package/package.json +50 -30
  37. package/dist/reset.css +0 -384
  38. /package/dist/icons/favorite/{favorite-outline-icon.d.ts → favorite-outlined-icon.d.ts} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,53 +1,95 @@
1
1
  /// <reference types="react" />
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
- import { Button as Button$1, Checkbox as Checkbox$1 } from 'react-aria-components';
4
- import { ComponentPropsWithoutRef, ComponentType } from 'react';
3
+ import { ComponentType, ReactNode } from 'react';
5
4
 
6
- type ButtonProps = ComponentPropsWithoutRef<typeof Button$1> & {
7
- variant?: "solid" | "outline" | "ghost";
8
- size?: "md" | "lg";
9
- color?: "primary" | "secondary" | "tertiary" | "quaternary";
5
+ interface ButtonProps {
6
+ _pseudo?: 'none' | 'focus' | 'hover' | 'active';
7
+ children: string;
8
+ className?: string;
9
+ color?: 'primary' | 'secondary';
10
+ icon?: React.ReactNode;
11
+ isDisabled?: boolean;
12
+ onPress?: VoidFunction;
13
+ size?: 'md' | 'lg';
14
+ variant?: 'solid' | 'outline' | 'ghost';
10
15
  withArrow?: boolean;
11
- };
12
- declare function Button({ children, variant, size, color, className, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
13
-
14
- declare function FavoriteFilledIcon(props: React.SVGProps<SVGSVGElement>): react_jsx_runtime.JSX.Element;
16
+ }
17
+ declare function Button({ _pseudo, children, className, color, icon, isDisabled, onPress, size, variant, withArrow, }: ButtonProps): react_jsx_runtime.JSX.Element;
15
18
 
16
- declare function FavoriteOutlinedIcon(props: React.SVGProps<SVGSVGElement>): react_jsx_runtime.JSX.Element;
17
-
18
- type FavoriteButtonProps = {
19
+ interface FavoriteButtonProps {
19
20
  isFavorite: boolean;
20
21
  onPress: () => void;
21
- };
22
+ }
22
23
  declare function FavoriteButton({ isFavorite, onPress }: FavoriteButtonProps): react_jsx_runtime.JSX.Element;
23
24
 
24
- type IconButtonProps = ComponentPropsWithoutRef<typeof Button$1> & {
25
- size?: "md" | "lg";
26
- color?: "primary" | "secondary";
27
- };
28
- declare function IconButton({ size, color, className, ...props }: IconButtonProps): react_jsx_runtime.JSX.Element;
25
+ interface IconButtonProps {
26
+ children: React.ReactNode;
27
+ className?: string;
28
+ color?: 'primary' | 'secondary';
29
+ onPress?: VoidFunction;
30
+ size?: 'md' | 'lg';
31
+ }
32
+ declare function IconButton({ children, className, color, onPress, size, }: IconButtonProps): react_jsx_runtime.JSX.Element;
29
33
 
30
- type ProductCardProps = {
31
- product: {
32
- id: string;
33
- title: string;
34
- };
35
- favoriteButton: ComponentType<any>;
36
- };
37
- declare function ProductCard({ product, favoriteButton: FavoriteButton, }: ProductCardProps): react_jsx_runtime.JSX.Element;
34
+ interface Product {
35
+ id: string
36
+ title: string
37
+ }
38
38
 
39
- type CheckboxProps = ComponentPropsWithoutRef<typeof Checkbox$1>;
40
- declare function Checkbox({ children, ...props }: CheckboxProps): react_jsx_runtime.JSX.Element;
39
+ interface ProductCardProps {
40
+ favoriteButton: ComponentType<{
41
+ productId: string;
42
+ }>;
43
+ product: Product;
44
+ }
45
+ declare function ProductCard({ favoriteButton: FavoriteButton, product, }: ProductCardProps): react_jsx_runtime.JSX.Element;
41
46
 
42
- type Filters = {
47
+ interface Price {
48
+ exclVat: number;
49
+ inclVat: number;
50
+ }
51
+ interface ProductPriceProps {
52
+ current: Price;
53
+ includeVat?: boolean;
54
+ original?: Price;
55
+ }
56
+ declare function ProductPrice({ current, includeVat, original, }: ProductPriceProps): react_jsx_runtime.JSX.Element | undefined;
57
+
58
+ interface ProductSkuProps {
59
+ sku: string;
60
+ }
61
+ declare function ProductSku({ sku }: ProductSkuProps): react_jsx_runtime.JSX.Element;
62
+
63
+ declare function RightArrowFilledIcon(props: React.SVGProps<SVGSVGElement>): react_jsx_runtime.JSX.Element;
64
+
65
+ declare function CartFilledIcon(props: React.SVGProps<SVGSVGElement>): react_jsx_runtime.JSX.Element;
66
+
67
+ declare function CartOutlinedIcon(props: React.SVGProps<SVGSVGElement>): react_jsx_runtime.JSX.Element;
68
+
69
+ declare function FavoriteFilledIcon(props: React.SVGProps<SVGSVGElement>): react_jsx_runtime.JSX.Element;
70
+
71
+ declare function FavoriteOutlinedIcon(props: React.SVGProps<SVGSVGElement>): react_jsx_runtime.JSX.Element;
72
+
73
+ interface CheckboxProps {
74
+ _pseudo?: 'none' | 'focus' | 'hover' | 'active';
75
+ children: ReactNode;
76
+ className?: string;
77
+ isDisabled?: boolean;
78
+ isSelected?: boolean;
79
+ onChange?: (isSelected: boolean) => void;
80
+ value?: string;
81
+ }
82
+ declare function Checkbox({ _pseudo, children, className, isDisabled, isSelected, onChange, value, }: CheckboxProps): react_jsx_runtime.JSX.Element;
83
+
84
+ interface Filters {
43
85
  color: {
44
86
  options: {
45
- value: string;
46
- label: string;
47
87
  count: number;
88
+ label: string;
89
+ value: string;
48
90
  }[];
49
91
  };
50
- };
92
+ }
51
93
  type ActiveFilters = {
52
94
  colors: string[];
53
95
  };
@@ -56,32 +98,34 @@ type Sort = {
56
98
  direction: string;
57
99
  };
58
100
  type ProductListingProps = {
59
- productCard: ComponentType<any>;
101
+ activeFilters: ActiveFilters;
102
+ filters: Filters;
103
+ isLoading?: boolean;
104
+ onFilterChange: (filters: ActiveFilters) => void;
105
+ onSortChange: (sort: Sort) => void;
106
+ productCard: ComponentType<{
107
+ product: Product;
108
+ }>;
60
109
  products: {
61
110
  id: string;
62
111
  title: string;
63
112
  }[];
64
- total: number;
65
- filters: Filters;
66
- activeFilters: ActiveFilters;
67
113
  sort: {
68
114
  by: string;
69
115
  direction: string;
70
116
  };
71
- isLoading?: boolean;
72
- onFilterChange: (filters: ActiveFilters) => void;
73
- onSortChange: (sort: Sort) => void;
117
+ total: number;
74
118
  };
75
- declare function ProductListing({ productCard: ProductCard, products, filters, isLoading, activeFilters, onFilterChange, onSortChange, }: ProductListingProps): react_jsx_runtime.JSX.Element;
119
+ declare function ProductListing({ activeFilters, filters, isLoading, onFilterChange, onSortChange, productCard: ProductCard, products, }: ProductListingProps): react_jsx_runtime.JSX.Element;
76
120
 
77
121
  declare function createProductListingSearchParams(state: {
122
+ filters: {
123
+ colors: string[];
124
+ };
78
125
  sort: {
79
126
  by: string;
80
127
  direction: string;
81
128
  };
82
- filters: {
83
- colors: string[];
84
- };
85
129
  }): URLSearchParams;
86
130
  declare function parseProductListingSearchParams(params: URLSearchParams): {
87
131
  filters: {
@@ -93,4 +137,4 @@ declare function parseProductListingSearchParams(params: URLSearchParams): {
93
137
  };
94
138
  };
95
139
 
96
- export { type ActiveFilters, Button, type ButtonProps, Checkbox, type CheckboxProps, FavoriteButton, type FavoriteButtonProps, FavoriteFilledIcon, FavoriteOutlinedIcon, type Filters, IconButton, type IconButtonProps, ProductCard, type ProductCardProps, ProductListing, type ProductListingProps, type Sort, createProductListingSearchParams, parseProductListingSearchParams };
140
+ export { type ActiveFilters, Button, type ButtonProps, CartFilledIcon, CartOutlinedIcon, Checkbox, type CheckboxProps, FavoriteButton, type FavoriteButtonProps, FavoriteFilledIcon, FavoriteOutlinedIcon, type Filters, IconButton, type IconButtonProps, ProductCard, type ProductCardProps, ProductListing, type ProductListingProps, ProductPrice, type ProductPriceProps, ProductSku, type ProductSkuProps, RightArrowFilledIcon, type Sort, createProductListingSearchParams, parseProductListingSearchParams };
package/dist/index.js CHANGED
@@ -1,74 +1,115 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import clsx from 'clsx';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
2
  import { Button as Button$1, Checkbox as Checkbox$1 } from 'react-aria-components';
3
+ import clsx from 'clsx';
4
4
 
5
- var styles$3 = {"button":"button-module-V4meK","md":"button-module-GVTEW","lg":"button-module-nyNY8","solid":"button-module-AjvlY","primary":"button-module-tmyk8","outline":"button-module-vq9GI"};
5
+ function RightArrowFilledIcon(props) {
6
+ return (jsx("svg", { height: "13", viewBox: "0 0 12 13", width: "12", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M3.24 11.4a.239.239 0 0 1-.203-.365l3.105-4.97c.256-.41.219-.932-.093-1.3L3.54 1.792a.239.239 0 0 1 .183-.393h1.956c.07 0 .137.031.182.085l1.866 2.21c.778.92.871 2.226.232 3.249l-2.715 4.344a.239.239 0 0 1-.202.112H3.239z", fill: "currentColor", fillRule: "evenodd" }) }));
7
+ }
6
8
 
7
- function Button({ children, variant = "solid", size = "md", color = "primary", className, ...props }) {
8
- return (jsx(Button$1, { ...props, className: clsx(styles$3.button, styles$3[variant], styles$3[size], styles$3[color], className), children: children }));
9
+ var styles$5 = {"button":"button-module-V4meK","md":"button-module-GVTEW","lg":"button-module-nyNY8","primary":"button-module-tmyk8","outline":"button-module-vq9GI","solid":"button-module-AjvlY","hover":"button-module-YzPAr","focus":"button-module--xzsY","active":"button-module-XMFzj","ghost":"button-module-f4UVe","right-arrow-icon":"button-module-ydQAo","secondary":"button-module--1bCH"};
10
+
11
+ function Button({ _pseudo = 'none', children, className, color = 'primary', icon, isDisabled, onPress, size = 'md', variant = 'solid', withArrow = false, }) {
12
+ if (children && icon)
13
+ console.warn('Button should not have both children and icon. Icon has precedence.');
14
+ return (jsx(Button$1, { className: clsx(className, styles$5.button, styles$5[variant], styles$5[size], styles$5[color], { [styles$5.icon]: icon }, styles$5[_pseudo]), isDisabled: isDisabled, onPress: onPress, children: icon ? (icon) : (jsxs(Fragment, { children: [children, withArrow && (jsx(RightArrowFilledIcon, { className: styles$5['right-arrow-icon'] }))] })) }));
15
+ }
16
+
17
+ var styles$4 = {"iconButton":"icon-button-module-HJm0i","md":"icon-button-module-k3s9J","lg":"icon-button-module-agk6Y","primary":"icon-button-module-fTeP4","secondary":"icon-button-module-dM0eo"};
18
+
19
+ function IconButton({ children, className, color = 'primary', onPress, size = 'md', }) {
20
+ return (jsx(Button$1, { className: clsx(styles$4.iconButton, styles$4[size], styles$4[color], className), onPress: onPress, children: children }));
9
21
  }
10
22
 
11
23
  function FavoriteFilledIcon(props) {
12
- return (jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M12 22a.667.667 0 0 1-.534-.267L3.227 10.72C2.411 9.599 2 8.46 2 7.327A5.336 5.336 0 0 1 7.333 2c1.892 0 3.669.982 4.667 2.468C12.998 2.982 14.775 2 16.667 2 19.607 2 22 4.39 22 7.327c0 1.133-.411 2.272-1.222 3.387l-8.244 11.019A.667.667 0 0 1 12 22", fill: "currentColor", fillRule: "evenodd" }) }));
24
+ return (jsx("svg", { height: "24", viewBox: "0 0 24 24", width: "24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M12 22a.667.667 0 0 1-.534-.267L3.227 10.72C2.411 9.599 2 8.46 2 7.327A5.336 5.336 0 0 1 7.333 2c1.892 0 3.669.982 4.667 2.468C12.998 2.982 14.775 2 16.667 2 19.607 2 22 4.39 22 7.327c0 1.133-.411 2.272-1.222 3.387l-8.244 11.019A.667.667 0 0 1 12 22", fill: "currentColor", fillRule: "evenodd" }) }));
13
25
  }
14
26
 
15
27
  function FavoriteOutlinedIcon(props) {
16
- return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", ...props, children: jsx("path", { d: "M7.333 3.33c-2.206 0-4 1.793-4 3.997 0 .857.316 1.71.967 2.604L12 20.223l7.705-10.299c.646-.888.962-1.74.962-2.597a4.003 4.003 0 0 0-4-3.996c-1.813 0-3.545 1.232-4.028 2.865a.666.666 0 0 1-1.278 0C10.878 4.563 9.146 3.33 7.333 3.33M12 22c-.21 0-.408-.1-.534-.267L3.227 10.72C2.411 9.599 2 8.46 2 7.327A5.336 5.336 0 0 1 7.333 2c1.892 0 3.669.982 4.667 2.468C12.998 2.982 14.775 2 16.667 2 19.607 2 22 4.39 22 7.327c0 1.133-.411 2.272-1.222 3.387l-8.245 11.019A.667.667 0 0 1 12 22", fill: "currentColor", fillRule: "evenodd" }) }));
28
+ return (jsx("svg", { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M7.333 3.33c-2.206 0-4 1.793-4 3.997 0 .857.316 1.71.967 2.604L12 20.223l7.705-10.299c.646-.888.962-1.74.962-2.597a4.003 4.003 0 0 0-4-3.996c-1.813 0-3.545 1.232-4.028 2.865a.666.666 0 0 1-1.278 0C10.878 4.563 9.146 3.33 7.333 3.33M12 22c-.21 0-.408-.1-.534-.267L3.227 10.72C2.411 9.599 2 8.46 2 7.327A5.336 5.336 0 0 1 7.333 2c1.892 0 3.669.982 4.667 2.468C12.998 2.982 14.775 2 16.667 2 19.607 2 22 4.39 22 7.327c0 1.133-.411 2.272-1.222 3.387l-8.245 11.019A.667.667 0 0 1 12 22", fill: "currentColor", fillRule: "evenodd" }) }));
17
29
  }
18
30
 
19
- var styles$2 = {"iconButton":"icon-button-module-HJm0i","md":"icon-button-module-k3s9J","lg":"icon-button-module-agk6Y","primary":"icon-button-module-fTeP4","secondary":"icon-button-module-dM0eo"};
31
+ var styles$3 = {"favorite-button":"favorite-button-module-tXSS3","isFavorite":"favorite-button-module-6FS3Q"};
20
32
 
21
- function IconButton({ size = "md", color = "primary", className, ...props }) {
22
- return (jsx(Button$1, { ...props, className: clsx(styles$2.iconButton, styles$2[size], styles$2[color], className) }));
33
+ function FavoriteButton({ isFavorite, onPress }) {
34
+ return (jsx(IconButton, { className: clsx(styles$3['favorite-button'], {
35
+ [styles$3.isFavorite]: isFavorite,
36
+ }), color: "secondary", onPress: onPress, children: isFavorite ? jsx(FavoriteFilledIcon, {}) : jsx(FavoriteOutlinedIcon, {}) }));
23
37
  }
24
38
 
25
- var styles$1 = {"isFavorite":"favorite-button-module-6FS3Q"};
39
+ function ProductCard({ favoriteButton: FavoriteButton, product, }) {
40
+ return (jsxs("div", { children: [jsx("div", { children: jsx(FavoriteButton, { productId: product.id }) }), jsx("h2", { children: product.title })] }));
41
+ }
26
42
 
27
- function FavoriteButton({ isFavorite, onPress }) {
28
- return (jsx(IconButton, { color: "secondary", onPress: () => onPress(), className: clsx({ [styles$1.isFavorite]: isFavorite }), children: isFavorite ? jsx(FavoriteFilledIcon, {}) : jsx(FavoriteOutlinedIcon, {}) }));
43
+ var styles$2 = {"product-price":"product-price-module-oIU1K","original-price":"product-price-module-til0s","current-price-wrapper":"product-price-module-FfVhl","current-price":"product-price-module-pvy2w","wholes":"product-price-module-GCw07","dot":"product-price-module-N56iV","decimals":"product-price-module-eWOOF","vat":"product-price-module-96DoG"};
44
+
45
+ const formatPrice = (price) => new Intl.NumberFormat('en-US', {
46
+ maximumFractionDigits: 2,
47
+ minimumFractionDigits: 2,
48
+ }).format(price);
49
+ function ProductPrice({ current, includeVat = true, original, }) {
50
+ if (!current.inclVat && !current.exclVat)
51
+ return;
52
+ const originalPrice = includeVat ? original?.inclVat : original?.exclVat;
53
+ const currentPrice = includeVat ? current.inclVat : current.exclVat;
54
+ const originalPriceCurrency = originalPrice
55
+ ? formatPrice(originalPrice)
56
+ : null;
57
+ const currentPriceCurrency = formatPrice(currentPrice);
58
+ const [wholes, decimals] = currentPriceCurrency.split('.');
59
+ return (jsxs("div", { className: styles$2['product-price'], children: [!!originalPrice && (jsx("span", { className: styles$2['original-price'], children: originalPriceCurrency })), jsxs("div", { className: styles$2['current-price-wrapper'], children: [jsxs("div", { className: styles$2['current-price'], children: [jsx("span", { className: styles$2.wholes, children: wholes }), jsx("span", { className: styles$2.dot, children: "." }), jsx("span", { className: styles$2.decimals, children: decimals })] }), jsx("span", { className: styles$2.vat, children: includeVat ? 'incl. tax' : 'excl. tax' })] })] }));
29
60
  }
30
61
 
31
- function ProductCard({ product, favoriteButton: FavoriteButton, }) {
32
- return (jsxs("div", { children: [jsx("div", { children: jsx(FavoriteButton, { productId: product.id }) }), jsx("h2", { children: product.title })] }));
62
+ var styles$1 = {"product-sku":"product-sku-module-ITb8x"};
63
+
64
+ function ProductSku({ sku }) {
65
+ return jsx("p", { className: styles$1['product-sku'], children: sku });
66
+ }
67
+
68
+ function CartFilledIcon(props) {
69
+ return (jsx("svg", { height: "24", viewBox: "0 0 24 24", width: "24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M7.896 16.666a2.603 2.603 0 1 1 0 5.207 2.603 2.603 0 0 1 0-5.207zm8.925 0a2.603 2.603 0 1 1 0 5.207 2.603 2.603 0 0 1 0-5.207zM7.896 18.1c-.645 0-1.17.524-1.17 1.169s.525 1.17 1.17 1.17a1.171 1.171 0 0 0 0-2.34zm8.925 0c-.645 0-1.17.524-1.17 1.169s.525 1.17 1.17 1.17a1.171 1.171 0 0 0 0-2.34zM4.589 3c.016 0 .032.004.048.005a.714.714 0 0 1 .146.025l.05.016a.7.7 0 0 1 .083.037l.04.021a.712.712 0 0 1 .076.053l.035.03a.699.699 0 0 1 .168.223.703.703 0 0 1 .061.209c.002.014.007.027.008.042l.207 2.646h15.776c.027.001.05.006.073.008.026.003.052.004.077.01.022.004.036.011.05.016.03.008.058.016.085.028.02.009.037.02.056.03.022.012.044.024.065.038.019.013.035.029.053.044.017.015.036.029.052.046.015.016.028.034.042.051.015.019.03.037.044.057.011.018.02.038.03.057.012.021.024.042.033.065.009.022.014.044.021.067.006.022.014.043.018.066.006.027.007.054.009.081.001.018.005.035.005.053-.001.031-.005.054-.008.077-.003.026-.004.052-.01.077l-1.39 6.054-.004.017a.698.698 0 0 1-.033.1l-.008.024a.716.716 0 0 1-.06.11l-.024.03a.707.707 0 0 1-.057.07l-.035.033a.695.695 0 0 1-.175.117l-.048.022a.723.723 0 0 1-.083.026c-.014.003-.027.008-.041.01a.707.707 0 0 1-.134.014H6.096l.112 1.427H19.41a.717.717 0 0 1 0 1.434H5.544a.714.714 0 0 1-.14-.015c-.015-.003-.03-.008-.044-.012-.03-.008-.06-.016-.087-.027-.018-.008-.034-.017-.05-.026-.024-.012-.048-.023-.07-.037-.016-.011-.03-.024-.046-.036-.02-.016-.04-.03-.058-.048-.015-.014-.027-.03-.04-.044-.017-.02-.033-.038-.048-.058-.012-.017-.021-.034-.032-.052a.678.678 0 0 1-.035-.065c-.009-.02-.016-.04-.023-.06a.715.715 0 0 1-.033-.136l-.008-.045-.904-11.571H2.717a.717.717 0 1 1 0-1.434z", fill: "currentColor", fillRule: "evenodd" }) }));
70
+ }
71
+
72
+ function CartOutlinedIcon(props) {
73
+ return (jsx("svg", { height: "24", viewBox: "0 0 24 24", width: "24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M7.896 16.666a2.603 2.603 0 1 1 0 5.207 2.603 2.603 0 0 1 0-5.207zm8.925 0a2.603 2.603 0 1 1 0 5.207 2.603 2.603 0 0 1 0-5.207zM7.896 18.1c-.645 0-1.17.524-1.17 1.169s.525 1.17 1.17 1.17a1.171 1.171 0 0 0 0-2.34zm8.925 0c-.645 0-1.17.524-1.17 1.169s.525 1.17 1.17 1.17a1.171 1.171 0 0 0 0-2.34zM4.589 3c.016 0 .032.004.048.005a.714.714 0 0 1 .146.025l.05.016a.7.7 0 0 1 .083.037l.04.021a.712.712 0 0 1 .076.053l.035.03a.699.699 0 0 1 .168.223.703.703 0 0 1 .061.209c.002.014.007.027.008.042l.207 2.646h15.776c.027.001.05.006.073.008.026.003.052.004.077.01.022.004.036.011.05.016.03.008.058.016.085.028.02.009.037.02.056.03.022.012.044.024.065.038.019.013.035.029.053.044.017.015.036.029.052.046.015.016.028.034.042.051.015.019.03.037.044.057.011.018.02.038.03.057.012.021.024.042.033.065.009.022.014.044.021.067.006.022.014.043.018.066.006.027.007.054.009.081.001.018.005.035.005.053-.001.031-.005.054-.008.077-.003.026-.004.052-.01.077l-1.39 6.054-.004.017a.698.698 0 0 1-.033.1l-.008.024a.716.716 0 0 1-.06.11l-.024.03a.707.707 0 0 1-.057.07l-.035.033a.695.695 0 0 1-.175.117l-.048.022a.723.723 0 0 1-.083.026c-.014.003-.027.008-.041.01a.707.707 0 0 1-.134.014H6.096l.112 1.427H19.41a.717.717 0 0 1 0 1.434H5.544a.714.714 0 0 1-.14-.015c-.015-.003-.03-.008-.044-.012-.03-.008-.06-.016-.087-.027-.018-.008-.034-.017-.05-.026-.024-.012-.048-.023-.07-.037-.016-.011-.03-.024-.046-.036-.02-.016-.04-.03-.058-.048-.015-.014-.027-.03-.04-.044-.017-.02-.033-.038-.048-.058-.012-.017-.021-.034-.032-.052a.678.678 0 0 1-.035-.065c-.009-.02-.016-.04-.023-.06a.715.715 0 0 1-.033-.136l-.008-.045-.904-11.571H2.717a.717.717 0 1 1 0-1.434zm15.794 4.741H5.623l.361 4.63h13.334l1.065-4.63z", fill: "currentColor", fillRule: "evenodd" }) }));
33
74
  }
34
75
 
35
- var styles = {"checkbox":"checkbox-module-y3eBg","box":"checkbox-module-TqLux","checkmark":"checkbox-module-Yhrdp"};
76
+ var styles = {"checkbox":"checkbox-module-y3eBg","box":"checkbox-module-TqLux","checkmark":"checkbox-module-Yhrdp","focus":"checkbox-module-zoTSP","active":"checkbox-module-sHmzp"};
36
77
 
37
- function Checkbox({ children, ...props }) {
38
- return (jsxs(Checkbox$1, { ...props, className: styles.checkbox, children: [jsx("div", { className: styles.box, children: jsx("svg", { className: styles.checkmark, viewBox: "0 0 18 18", "aria-hidden": "true", children: jsx("polyline", { points: "1 9 7 14 15 4" }) }) }), children] }));
78
+ function Checkbox({ _pseudo = 'none', children, className, isDisabled, isSelected, onChange, value, }) {
79
+ return (jsxs(Checkbox$1, { className: clsx(className, styles.checkbox, styles[_pseudo]), isDisabled: isDisabled, isSelected: isSelected, onChange: onChange, value: value, children: [jsx("div", { className: styles.box, children: jsx("svg", { "aria-hidden": "true", className: styles.checkmark, viewBox: "0 0 18 18", children: jsx("polyline", { points: "1 9 7 14 15 4" }) }) }), children] }));
39
80
  }
40
81
 
41
- function Filter({ title, children }) {
82
+ function Filter({ children, title }) {
42
83
  return (jsxs("div", { children: [jsx("div", { children: jsx("h3", { children: title }) }), jsx("div", { children: children })] }));
43
84
  }
44
85
 
45
- function ColorFilter({ options, value, onChange }) {
46
- return (jsx(Filter, { title: "Color", children: jsx("ul", { children: options.map((option) => (jsx("li", { children: jsx(Checkbox, { onChange: (isSelected) => onChange(isSelected
86
+ function ColorFilter({ onChange, options, value }) {
87
+ return (jsx(Filter, { title: "Color", children: jsx("ul", { children: options.map(option => (jsx("li", { children: jsx(Checkbox, { isSelected: value.includes(option.value), onChange: isSelected => onChange(isSelected
47
88
  ? [...value, option.value]
48
- : value.filter((v) => v !== option.value)), value: option.value, isSelected: value.includes(option.value), children: option.label }) }, option.value))) }) }));
89
+ : value.filter(v => v !== option.value)), value: option.value, children: option.label }) }, option.value))) }) }));
49
90
  }
50
91
 
51
- function ProductListing({ productCard: ProductCard, products, filters, isLoading = false, activeFilters, onFilterChange, onSortChange, }) {
52
- return (jsxs("div", { children: [jsx("h1", { children: "Product listing" }), jsxs("aside", { children: [jsx("h2", { children: "Filter" }), jsx("div", { children: jsx(ColorFilter, { options: filters.color.options, value: activeFilters.colors, onChange: (colors) => onFilterChange({ colors }) }) })] }), jsx("main", { children: jsxs("select", { onChange: (e) => onSortChange({ by: e.target.value, direction: "asc" }), children: [jsx("option", { value: "", children: "Sort By" }), jsx("option", { value: "price", children: "Price" }), jsx("option", { value: "title", children: "Title" })] }) }), isLoading ? (jsx("p", { children: "Loading..." })) : (jsx("ul", { children: products.map((product) => (jsx("li", { children: jsx(ProductCard, { product: product }) }, product.id))) }))] }));
92
+ function ProductListing({ activeFilters, filters, isLoading = false, onFilterChange, onSortChange, productCard: ProductCard, products, }) {
93
+ return (jsxs("div", { children: [jsx("h1", { children: "Product listing" }), jsxs("aside", { children: [jsx("h2", { children: "Filter" }), jsx("div", { children: jsx(ColorFilter, { onChange: colors => onFilterChange({ colors }), options: filters.color.options, value: activeFilters.colors }) })] }), jsx("main", { children: jsxs("select", { onChange: e => onSortChange({ by: e.target.value, direction: 'asc' }), children: [jsx("option", { value: "", children: "Sort By" }), jsx("option", { value: "price", children: "Price" }), jsx("option", { value: "title", children: "Title" })] }) }), isLoading ? (jsx("p", { children: "Loading..." })) : (jsx("ul", { children: products.map(product => (jsx("li", { children: jsx(ProductCard, { product: product }) }, product.id))) }))] }));
53
94
  }
54
95
 
55
96
  function createProductListingSearchParams(state) {
56
97
  const params = new URLSearchParams();
57
98
  if (state.filters.colors.length > 0) {
58
- params.set("colors", state.filters.colors.join(","));
99
+ params.set('colors', state.filters.colors.join(','));
59
100
  }
60
- params.set("sortBy", state.sort.by);
61
- params.set("sortDirection", state.sort.direction);
101
+ params.set('sortBy', state.sort.by);
102
+ params.set('sortDirection', state.sort.direction);
62
103
  return params;
63
104
  }
64
105
  function parseProductListingSearchParams(params) {
65
106
  return {
66
- filters: { colors: params.get("colors")?.split(",") ?? [] },
107
+ filters: { colors: params.get('colors')?.split(',') ?? [] },
67
108
  sort: {
68
- by: params.get("sortBy") ?? "relevance",
69
- direction: params.get("sortDirection") ?? "asc",
109
+ by: params.get('sortBy') ?? 'relevance',
110
+ direction: params.get('sortDirection') ?? 'asc',
70
111
  },
71
112
  };
72
113
  }
73
114
 
74
- export { Button, Checkbox, FavoriteButton, FavoriteFilledIcon, FavoriteOutlinedIcon, IconButton, ProductCard, ProductListing, createProductListingSearchParams, parseProductListingSearchParams };
115
+ export { Button, CartFilledIcon, CartOutlinedIcon, Checkbox, FavoriteButton, FavoriteFilledIcon, FavoriteOutlinedIcon, IconButton, ProductCard, ProductListing, ProductPrice, ProductSku, RightArrowFilledIcon, createProductListingSearchParams, parseProductListingSearchParams };
@@ -1,4 +1,11 @@
1
- import { Checkbox as AriaCheckbox } from "react-aria-components";
2
- import { ComponentPropsWithoutRef } from "react";
3
- export type CheckboxProps = ComponentPropsWithoutRef<typeof AriaCheckbox>;
4
- export declare function Checkbox({ children, ...props }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
1
+ import { ReactNode } from 'react';
2
+ export interface CheckboxProps {
3
+ _pseudo?: 'none' | 'focus' | 'hover' | 'active';
4
+ children: ReactNode;
5
+ className?: string;
6
+ isDisabled?: boolean;
7
+ isSelected?: boolean;
8
+ onChange?: (isSelected: boolean) => void;
9
+ value?: string;
10
+ }
11
+ export declare function Checkbox({ _pseudo, children, className, isDisabled, isSelected, onChange, value, }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
@@ -1,17 +1,19 @@
1
- import type { StoryObj } from "@storybook/react";
2
- import { Checkbox } from "./checkbox";
1
+ import type { StoryObj } from '@storybook/react';
2
+ import { Checkbox } from './checkbox';
3
3
  declare const meta: {
4
- title: string;
4
+ args: {
5
+ onChange: import("@vitest/spy").Mock<[isSelected: boolean], void>;
6
+ };
5
7
  component: typeof Checkbox;
6
8
  parameters: {
7
9
  layout: string;
8
10
  };
9
11
  tags: string[];
10
- args: {
11
- onChange: import("@storybook/test").Mock<[isSelected: boolean], void>;
12
- };
12
+ title: string;
13
13
  };
14
14
  export default meta;
15
15
  type Story = StoryObj<typeof Checkbox>;
16
16
  export declare const Unchecked: Story;
17
17
  export declare const Checked: Story;
18
+ export declare const CheckedDisabled: Story;
19
+ export declare const CheckedFocus: Story;
@@ -1,11 +1,11 @@
1
- import { FilterProps } from "../filter/filter";
1
+ import { FilterProps } from 'product-listing/filters/filter/filter';
2
2
  export type ColorFilterProps = FilterProps & {
3
+ onChange: (value: string[]) => void;
3
4
  options: {
4
- value: string;
5
- label: string;
6
5
  count: number;
6
+ label: string;
7
+ value: string;
7
8
  }[];
8
9
  value: string[];
9
- onChange: (value: string[]) => void;
10
10
  };
11
- export declare function ColorFilter({ options, value, onChange }: ColorFilterProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function ColorFilter({ onChange, options, value }: ColorFilterProps): import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
- import { PropsWithChildren } from "react";
1
+ import { PropsWithChildren } from 'react';
2
2
  export type FilterProps = PropsWithChildren<{
3
- title?: string;
4
- isCollapseable?: boolean;
5
3
  initialIsCollapsed?: boolean;
4
+ isCollapseable?: boolean;
5
+ title?: string;
6
6
  }>;
7
- export declare function Filter({ title, children }: FilterProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function Filter({ children, title }: FilterProps): import("react/jsx-runtime").JSX.Element;
@@ -1,13 +1,14 @@
1
- import { ComponentType } from "react";
2
- export type Filters = {
1
+ import { ComponentType } from 'react';
2
+ import type { Product } from 'shared/types/product';
3
+ export interface Filters {
3
4
  color: {
4
5
  options: {
5
- value: string;
6
- label: string;
7
6
  count: number;
7
+ label: string;
8
+ value: string;
8
9
  }[];
9
10
  };
10
- };
11
+ }
11
12
  export type ActiveFilters = {
12
13
  colors: string[];
13
14
  };
@@ -16,20 +17,22 @@ export type Sort = {
16
17
  direction: string;
17
18
  };
18
19
  export type ProductListingProps = {
19
- productCard: ComponentType<any>;
20
+ activeFilters: ActiveFilters;
21
+ filters: Filters;
22
+ isLoading?: boolean;
23
+ onFilterChange: (filters: ActiveFilters) => void;
24
+ onSortChange: (sort: Sort) => void;
25
+ productCard: ComponentType<{
26
+ product: Product;
27
+ }>;
20
28
  products: {
21
29
  id: string;
22
30
  title: string;
23
31
  }[];
24
- total: number;
25
- filters: Filters;
26
- activeFilters: ActiveFilters;
27
32
  sort: {
28
33
  by: string;
29
34
  direction: string;
30
35
  };
31
- isLoading?: boolean;
32
- onFilterChange: (filters: ActiveFilters) => void;
33
- onSortChange: (sort: Sort) => void;
36
+ total: number;
34
37
  };
35
- export declare function ProductListing({ productCard: ProductCard, products, filters, isLoading, activeFilters, onFilterChange, onSortChange, }: ProductListingProps): import("react/jsx-runtime").JSX.Element;
38
+ export declare function ProductListing({ activeFilters, filters, isLoading, onFilterChange, onSortChange, productCard: ProductCard, products, }: ProductListingProps): import("react/jsx-runtime").JSX.Element;
@@ -1,13 +1,13 @@
1
- import { StoryObj } from "@storybook/react";
2
- import { ProductListing } from "./product-listing";
1
+ import { StoryObj } from '@storybook/react';
2
+ import { ProductListing } from './product-listing';
3
3
  declare const meta: {
4
- title: string;
5
- component: typeof ProductListing;
6
- tags: string[];
7
4
  args: {
8
- onFilterChange: import("@storybook/test").Mock<[filters: import("./product-listing").ActiveFilters], void>;
9
- onSortChange: import("@storybook/test").Mock<[sort: import("./product-listing").Sort], void>;
5
+ onFilterChange: import("@vitest/spy").Mock<[filters: import("./product-listing").ActiveFilters], void>;
6
+ onSortChange: import("@vitest/spy").Mock<[sort: import("./product-listing").Sort], void>;
10
7
  };
8
+ component: typeof ProductListing;
9
+ tags: string[];
10
+ title: string;
11
11
  };
12
12
  export default meta;
13
13
  type Story = StoryObj<typeof ProductListing>;
@@ -1,11 +1,11 @@
1
1
  export declare function createProductListingSearchParams(state: {
2
+ filters: {
3
+ colors: string[];
4
+ };
2
5
  sort: {
3
6
  by: string;
4
7
  direction: string;
5
8
  };
6
- filters: {
7
- colors: string[];
8
- };
9
9
  }): URLSearchParams;
10
10
  export declare function parseProductListingSearchParams(params: URLSearchParams): {
11
11
  filters: {
@@ -0,0 +1,4 @@
1
+ export interface Product {
2
+ id: string;
3
+ title: string;
4
+ }