@sonic-equipment/ui 0.0.20 → 0.0.21
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/algolia/algolia-active-filters.d.ts +6 -0
- package/dist/algolia/algolia-categories.d.ts +1 -0
- package/dist/algolia/algolia-filter-panel.d.ts +4 -1
- package/dist/algolia/algolia-provider.d.ts +13 -0
- package/dist/algolia/algolia-sort-by.d.ts +1 -1
- package/dist/algolia/algolia.stories.d.ts +2 -2
- package/dist/buttons/add-to-cart-button/add-to-cart-button.stories.d.ts +1 -0
- package/dist/buttons/add-to-cart-button/connected-add-to-cart-button.d.ts +5 -0
- package/dist/buttons/icon-button/icon-button.d.ts +2 -1
- package/dist/cards/product-card/connected-product-cart.d.ts +6 -0
- package/dist/cards/product-card/product-card.stories.d.ts +1 -0
- package/dist/collapsables/accordion/accordion-item.d.ts +2 -1
- package/dist/collapsables/accordion/accordion.d.ts +2 -1
- package/dist/collapsables/accordion/accordion.stories.d.ts +1 -0
- package/dist/filters/active-filters/active-filters.d.ts +9 -8
- package/dist/filters/active-filters/active-filters.stories.d.ts +2 -2
- package/dist/filters/pagination/pagination.d.ts +6 -0
- package/dist/filters/pagination/pagination.stories.d.ts +18 -0
- package/dist/icons/chevrons/chevron-left-filled-icon.d.ts +2 -0
- package/dist/icons/chevrons/chevron-right-filled-icon.d.ts +2 -0
- package/dist/index.d.ts +7 -9
- package/dist/index.js +342 -80
- package/dist/intl/translation-id.d.ts +1 -1
- package/dist/product-listing/product-listing.d.ts +1 -7
- package/dist/product-listing/product-listing.stories.d.ts +6 -1
- package/dist/shared/hooks/{use-device.d.ts → use-breakpoint.d.ts} +1 -1
- package/dist/shared/hooks/use-debounce-callback.d.ts +1 -0
- package/dist/shared/providers/cart-provider.d.ts +33 -0
- package/dist/shared/providers/global-state-provider.d.ts +23 -0
- package/dist/shared/types/cart.d.ts +8 -0
- package/dist/shared/utils/event-emitter.d.ts +9 -0
- package/dist/styles.css +221 -9
- package/dist/typography/heading/heading.d.ts +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { forwardRef, useState, useEffect, createContext, useContext, Children, cloneElement, useRef, useCallback } from 'react';
|
|
3
|
-
import { Button as Button$1, FieldError as FieldError$1, useContextProps, InputContext, Input as Input$1, Label as Label$1, NumberField as NumberField$1, Link, Checkbox as Checkbox$1, Select as Select$1, SelectValue, Popover, ListBox, ListBoxItem, TextAreaContext, TextArea as TextArea$1, TextField as TextField$1 } from 'react-aria-components';
|
|
2
|
+
import { forwardRef, useState, useEffect, createContext, useContext, Children, cloneElement, useRef, useCallback, createElement } from 'react';
|
|
3
|
+
import { Button as Button$1, FieldError as FieldError$1, useContextProps, InputContext, Input as Input$1, Label as Label$1, NumberField as NumberField$1, Link, Checkbox as Checkbox$1, Select as Select$1, SelectValue, Popover, ListBox, Section, Header, ListBoxItem, TextAreaContext, TextArea as TextArea$1, TextField as TextField$1 } from 'react-aria-components';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
+
import { useCurrentRefinements, useClearRefinements, useRefinementList, useHits, useDynamicWidgets, usePagination, useSortBy } from 'react-instantsearch';
|
|
5
6
|
|
|
6
7
|
function RightArrowFilledIcon(props) {
|
|
7
8
|
return (jsx("svg", { height: "11", viewBox: "0 0 6 11", width: "6", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M.267 11a.263.263 0 0 1-.226-.402l3.463-5.467a1.2 1.2 0 0 0-.103-1.43L.602.432A.262.262 0 0 1 .805 0h2.181c.078 0 .153.034.203.093l2.081 2.43a3 3 0 0 1 .259 3.575L2.5 10.877a.267.267 0 0 1-.225.123H.266z", fill: "currentColor", fillRule: "evenodd" }) }));
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
var styles$
|
|
11
|
+
var styles$r = {"button":"button-module-V4meK","icon":"button-module-XaNWz","sm":"button-module-Pbwz7","md":"button-module-GVTEW","condensed":"button-module-GKHQc","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"};
|
|
11
12
|
|
|
12
13
|
function Button({ _pseudo = 'none', children, className, color = 'primary', condensed, icon, iconPosition = 'left', isDisabled, onPress, size = 'lg', type = 'button', variant = 'solid', withArrow = false, }) {
|
|
13
14
|
if (children && icon)
|
|
14
15
|
console.warn('Button should not have both children and icon. Icon has precedence.');
|
|
15
|
-
return (jsxs(Button$1, { className: clsx(className, styles$
|
|
16
|
+
return (jsxs(Button$1, { className: clsx(className, styles$r.button, styles$r[variant], styles$r[size], styles$r[color], { [styles$r.condensed]: condensed }, { [styles$r.icon]: icon }, styles$r[_pseudo]), isDisabled: isDisabled, onPress: onPress, type: type, children: [icon && iconPosition === 'left' && (jsx("span", { className: styles$r.icon, children: icon })), children, withArrow && (jsx(RightArrowFilledIcon, { className: styles$r['right-arrow-icon'] })), icon && iconPosition === 'right' && (jsx("span", { className: styles$r.icon, children: icon }))] }));
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
var styles$
|
|
19
|
+
var styles$q = {"field-error":"field-error-module-FXnIg"};
|
|
19
20
|
|
|
20
21
|
function FieldError({ children }) {
|
|
21
|
-
return (jsx(FieldError$1, { className: styles$
|
|
22
|
+
return (jsx(FieldError$1, { className: styles$q['field-error'], children: children }));
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
var styles$
|
|
25
|
+
var styles$p = {"input-container":"input-module-2woJR","shadow-input":"input-module-pNKEt","lg":"input-module-Dx2qC","md":"input-module-sH6e7","focus":"input-module-hEEuy","growing-input":"input-module-6HwY4"};
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* This component is used to create an input that grows as the user types.
|
|
@@ -36,33 +37,33 @@ const Input = forwardRef(({ _pseudo = 'none', autoGrow, size = 'lg', ...inputPro
|
|
|
36
37
|
const handleChange = (event) => isControlled
|
|
37
38
|
? onChange?.(event)
|
|
38
39
|
: setUncontrolledValue(event.target.value);
|
|
39
|
-
return (jsx("div", { className: clsx(styles$
|
|
40
|
+
return (jsx("div", { className: clsx(styles$p['input-container'], styles$p[size], styles$p[_pseudo]), children: jsxs("div", { className: clsx({ [styles$p['growing-input']]: autoGrow }), children: [jsx(Input$1, { size: autoGrow ? 1 : undefined, ...props, ref: ref, onChange: handleChange }), autoGrow && jsx("span", { className: styles$p['shadow-input'], children: value })] }) }));
|
|
40
41
|
});
|
|
41
42
|
Input.displayName = 'Input';
|
|
42
43
|
|
|
43
|
-
var styles$
|
|
44
|
+
var styles$o = {"label":"label-module-LGfJt","required":"label-module-oTWaS"};
|
|
44
45
|
|
|
45
46
|
function Label({ children, isRequired }) {
|
|
46
47
|
if (!children)
|
|
47
48
|
return null;
|
|
48
|
-
return (jsxs(Label$1, { className: styles$
|
|
49
|
+
return (jsxs(Label$1, { className: styles$o.label, children: [children, isRequired && jsx("span", { className: styles$o.required, children: "*" })] }));
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
var styles$
|
|
52
|
+
var styles$n = {"field":"number-field-module-gmnog","button-input-container":"number-field-module-8Lvgh"};
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
55
|
* This component is used to create a number field.
|
|
55
56
|
* This field can also grow when a user types in text.
|
|
56
57
|
*/
|
|
57
|
-
function NumberField({ autoFocus, autoGrow, defaultValue, formatOptions = { style: 'decimal', useGrouping: false }, isDisabled, isInvalid, isReadOnly, isRequired, label, maxLength, maxValue, minValue, name, onChange, onInput, onKeyUp, placeholder, showLabel =
|
|
58
|
-
return (jsxs(NumberField$1, { "aria-label": label, autoFocus: autoFocus, className: clsx(styles$
|
|
58
|
+
function NumberField({ autoFocus, autoGrow, defaultValue, formatOptions = { style: 'decimal', useGrouping: false }, isDisabled, isInvalid, isReadOnly, isRequired, label, maxLength, maxValue, minValue, name, onChange, onInput, onKeyUp, placeholder, showLabel = false, size = 'lg', value, withButtons, }) {
|
|
59
|
+
return (jsxs(NumberField$1, { "aria-label": label, autoFocus: autoFocus, className: clsx(styles$n.field, styles$n[size]), defaultValue: defaultValue, formatOptions: formatOptions, isDisabled: isDisabled, isInvalid: isInvalid, isReadOnly: isReadOnly, isRequired: isRequired, maxValue: maxValue, minValue: minValue, name: name, onChange: onChange, onInput: onInput, onKeyUp: e => onKeyUp?.(e), value: value, children: [showLabel && jsx(Label, { isRequired: isRequired, children: label }), jsxs("div", { className: styles$n['button-input-container'], children: [withButtons && jsx(Button$1, { slot: "decrement", children: "-" }), jsx(Input, { autoGrow: autoGrow, maxLength: maxLength, placeholder: placeholder, size: size }), withButtons && jsx(Button$1, { slot: "increment", children: "+" })] }), jsx(FieldError, {})] }));
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
function CartFilledIcon(props) {
|
|
62
63
|
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" }) }));
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
var styles$
|
|
66
|
+
var styles$m = {"manual-input-container":"add-to-cart-button-module-AWFvQ","left-button-spacer":"add-to-cart-button-module-SS7WM"};
|
|
66
67
|
|
|
67
68
|
function AddToCartButton({ initialState = 'initial', onChange, quantity, }) {
|
|
68
69
|
const [currentState, setState] = useState(initialState);
|
|
@@ -124,17 +125,17 @@ function ManualInputState({ onCancel, onConfirm, quantity, }) {
|
|
|
124
125
|
e.key === 'Enter' && onConfirm(updatedQuantity);
|
|
125
126
|
e.key === 'Escape' && onCancel();
|
|
126
127
|
};
|
|
127
|
-
return (jsxs("div", { className: styles$
|
|
128
|
+
return (jsxs("div", { className: styles$m['manual-input-container'], children: [jsx("div", { className: styles$m['left-button-spacer'] }), jsx(NumberField, { autoFocus: true, autoGrow: true, defaultValue: quantity, formatOptions: {
|
|
128
129
|
maximumFractionDigits: 0,
|
|
129
130
|
style: 'decimal',
|
|
130
131
|
useGrouping: false,
|
|
131
132
|
}, label: "Quantity", maxLength: 4, maxValue: 9999, minValue: 0, name: "quantity", onChange: setQuantity, onKeyUp: onKeyUp, showLabel: false, size: "md" }), jsx(Button, { condensed: true, onPress: () => onConfirm(updatedQuantity), size: "md", children: "OK" })] }));
|
|
132
133
|
}
|
|
133
134
|
|
|
134
|
-
var styles$
|
|
135
|
+
var styles$l = {"icon-button":"icon-button-module-4PDK-","md":"icon-button-module-k3s9J","lg":"icon-button-module-agk6Y","primary":"icon-button-module-fTeP4","secondary":"icon-button-module-dM0eo"};
|
|
135
136
|
|
|
136
|
-
function IconButton({ children, className, color = 'primary', onPress, size = 'md', }) {
|
|
137
|
-
return (jsx(Button$1, { className: clsx(styles$
|
|
137
|
+
function IconButton({ children, className, color = 'primary', isDisabled, onPress, size = 'md', }) {
|
|
138
|
+
return (jsx(Button$1, { className: clsx(styles$l['icon-button'], styles$l[size], styles$l[color], className), isDisabled: isDisabled, onPress: onPress, children: children }));
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
function FavoriteFilledIcon(props) {
|
|
@@ -145,29 +146,29 @@ function FavoriteOutlinedIcon(props) {
|
|
|
145
146
|
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" }) }));
|
|
146
147
|
}
|
|
147
148
|
|
|
148
|
-
var styles$
|
|
149
|
+
var styles$k = {"favorite-button":"favorite-button-module-tXSS3","is-favorite":"favorite-button-module-l557q"};
|
|
149
150
|
|
|
150
151
|
function FavoriteButton({ isFavorite, onPress }) {
|
|
151
|
-
return (jsx(IconButton, { className: clsx(styles$
|
|
152
|
-
[styles$
|
|
152
|
+
return (jsx(IconButton, { className: clsx(styles$k['favorite-button'], {
|
|
153
|
+
[styles$k['is-favorite']]: isFavorite,
|
|
153
154
|
}), color: "secondary", onPress: onPress, children: isFavorite ? jsx(FavoriteFilledIcon, {}) : jsx(FavoriteOutlinedIcon, {}) }));
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
var styles$
|
|
157
|
+
var styles$j = {"link-button":"link-button-module-6i75g"};
|
|
157
158
|
|
|
158
159
|
function LinkButton({ children, className, href, isDisabled, onPress, target, }) {
|
|
159
160
|
if (href) {
|
|
160
|
-
return (jsx(Link, { className: clsx(styles$
|
|
161
|
+
return (jsx(Link, { className: clsx(styles$j['link-button'], className), href: href, isDisabled: isDisabled, onPress: onPress, target: target, children: children }));
|
|
161
162
|
}
|
|
162
|
-
return (jsx(Button$1, { className: clsx(styles$
|
|
163
|
+
return (jsx(Button$1, { className: clsx(styles$j['link-button'], className), isDisabled: isDisabled, onPress: onPress, type: "button", children: children }));
|
|
163
164
|
}
|
|
164
165
|
|
|
165
|
-
var styles$
|
|
166
|
+
var styles$i = {"tag":"tag-module-B7r15","body":"tag-module-4cfCf","shape":"tag-module-c7CRb"};
|
|
166
167
|
|
|
167
168
|
function Tag({ children }) {
|
|
168
169
|
if (!children)
|
|
169
170
|
return null;
|
|
170
|
-
return (jsxs("div", { className: styles$
|
|
171
|
+
return (jsxs("div", { className: styles$i.tag, children: [jsx("div", { className: styles$i.body, children: children }), jsx("svg", { className: styles$i.shape, height: "16", viewBox: "0 0 8 16", width: "8", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M.925 0H0v16h5.412l2.463-8.429c.362-1.238-.08-2.576-1.094-3.315L.925 0z", fill: "currentColor", fillRule: "nonzero" }) })] }));
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
const IntlContext = createContext({
|
|
@@ -193,7 +194,7 @@ const useFormattedMessage = () => {
|
|
|
193
194
|
|
|
194
195
|
const FormattedMessage = ({ id, replacementValues, }) => useFormattedMessage()(id, replacementValues);
|
|
195
196
|
|
|
196
|
-
var styles$
|
|
197
|
+
var styles$h = {"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"};
|
|
197
198
|
|
|
198
199
|
const formatPrice = (price) => new Intl.NumberFormat('en-US', {
|
|
199
200
|
maximumFractionDigits: 2,
|
|
@@ -205,16 +206,16 @@ function ProductPrice({ className, current, includeVat, original, }) {
|
|
|
205
206
|
const originalPriceCurrency = original ? formatPrice(original) : null;
|
|
206
207
|
const currentPriceCurrency = formatPrice(current);
|
|
207
208
|
const [wholes, decimals] = currentPriceCurrency.split('.');
|
|
208
|
-
return (jsxs("div", { className: clsx(className, styles$
|
|
209
|
+
return (jsxs("div", { className: clsx(className, styles$h['product-price']), children: [!!original && (jsx("span", { className: styles$h['original-price'], children: originalPriceCurrency })), jsxs("div", { className: styles$h['current-price-wrapper'], children: [jsxs("div", { className: styles$h['current-price'], children: [jsx("span", { className: styles$h.wholes, children: wholes }), jsx("span", { className: styles$h.dot, children: "." }), jsx("span", { className: styles$h.decimals, children: decimals })] }), jsx("span", { className: styles$h.vat, children: includeVat ? (jsx(FormattedMessage, { id: "Incl. VAT" })) : (jsx(FormattedMessage, { id: "Excl. VAT" })) })] })] }));
|
|
209
210
|
}
|
|
210
211
|
|
|
211
|
-
var styles$
|
|
212
|
+
var styles$g = {"product-sku":"product-sku-module-ITb8x"};
|
|
212
213
|
|
|
213
214
|
function ProductSku({ sku }) {
|
|
214
|
-
return jsx("p", { className: styles$
|
|
215
|
+
return jsx("p", { className: styles$g['product-sku'], children: sku });
|
|
215
216
|
}
|
|
216
217
|
|
|
217
|
-
var styles$
|
|
218
|
+
var styles$f = {"image":"image-module-lg7Kj","contain":"image-module-KFEgG","cover":"image-module-tVKFe"};
|
|
218
219
|
|
|
219
220
|
const breakpointToWidth = {
|
|
220
221
|
lg: 1440,
|
|
@@ -239,19 +240,19 @@ function Image({ alt, className, fallbackSrc = '/images/fallback.svg', fit = 'co
|
|
|
239
240
|
const handleError = () => {
|
|
240
241
|
setCurrentSrc(fallbackSrc);
|
|
241
242
|
};
|
|
242
|
-
return (jsx("img", { alt: alt, className: clsx(styles$
|
|
243
|
+
return (jsx("img", { alt: alt, className: clsx(styles$f.image, styles$f[fit], className), height: height, loading: loading, onError: handleError, sizes: sizes, src: currentSrc, srcSet: srcSet, title: title, width: width }));
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
var styles$
|
|
246
|
+
var styles$e = {"product-card":"product-card-module-pLaiB","favorite-button":"product-card-module-tvEdz","content":"product-card-module-e0kMu","top":"product-card-module-Q0VvF","tag":"product-card-module-HkWBE","title":"product-card-module-CStNi","bottom":"product-card-module-kD2tU","image":"product-card-module-p-zoi","price":"product-card-module-irW0D","add-to-cart-button":"product-card-module-SnCvX"};
|
|
246
247
|
|
|
247
248
|
function ProductCard({ addToCartButton: AddToCartButton, favoriteButton: FavoriteButton, image: { alt, fit, src, title: imageTitle }, onClick, price, sku, tag, title, }) {
|
|
248
|
-
return (jsxs("div", { className: styles$
|
|
249
|
+
return (jsxs("div", { className: styles$e['product-card'], onClick: onClick, children: [jsx("div", { className: styles$e.image, children: jsx(Image, { alt: alt, fit: fit, src: src, title: imageTitle }) }), jsx("div", { className: styles$e['favorite-button'], children: FavoriteButton && FavoriteButton }), jsxs("div", { className: styles$e.content, children: [jsxs("div", { className: styles$e.top, children: [jsx("div", { className: styles$e.tag, children: tag && jsx(Tag, { children: tag }) }), jsx("h2", { className: styles$e.title, children: title }), jsx(ProductSku, { sku: sku })] }), jsxs("div", { className: styles$e.bottom, children: [jsx("div", { className: styles$e.price, children: jsx(ProductPrice, { current: price.current, includeVat: price.includeVat, original: price.original }) }), jsx("div", { className: styles$e['add-to-cart-button'], children: AddToCartButton })] })] })] }));
|
|
249
250
|
}
|
|
250
251
|
|
|
251
|
-
var styles$
|
|
252
|
+
var styles$d = {"accordion":"accordion-module-9WvAH","white":"accordion-module-CaVdG","accordion-item":"accordion-module-lf9d-","lg":"accordion-module-0qnae","with-seperators":"accordion-module-yOLrW","indented":"accordion-module-6CcEH","button":"accordion-module--Rwpb","icon":"accordion-module-Y50uq","focus":"accordion-module-M4BZs","panel":"accordion-module-KZjMo","content":"accordion-module-ejMH3","is-open":"accordion-module-W0F1z"};
|
|
252
253
|
|
|
253
|
-
function Accordion({ children, color = 'black', hasLineSeparator = true, size = 'md', }) {
|
|
254
|
-
return (jsx("div", { className: clsx(styles$
|
|
254
|
+
function Accordion({ children, color = 'black', hasLineSeparator = true, indented, size = 'md', }) {
|
|
255
|
+
return (jsx("div", { className: clsx({ [styles$d.indented]: indented }, styles$d.accordion, styles$d[color], styles$d[size], hasLineSeparator && styles$d['with-seperators']), children: children &&
|
|
255
256
|
Children.map(children, child => {
|
|
256
257
|
return cloneElement(child, { size });
|
|
257
258
|
}) }));
|
|
@@ -261,7 +262,7 @@ function ChevronDownSlim(props) {
|
|
|
261
262
|
return (jsx("svg", { viewBox: "0 0 16 17", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "m8 12.648-6.667-6.7a3.11 3.11 0 0 1 .466-.75c.202-.245.444-.477.726-.698l5.459 5.546L13.328 4.5c.288.226.543.459.764.699.222.24.413.489.575.75L8 12.648z", fill: "currentColor", fillRule: "evenodd" }) }));
|
|
262
263
|
}
|
|
263
264
|
|
|
264
|
-
var styles$
|
|
265
|
+
var styles$c = {"show-all":"show-all-module-BDp21","panel":"show-all-module-bEdda","content":"show-all-module-RF--F","has-transparency":"show-all-module-30y7l","button":"show-all-module-58e7Q","icon":"show-all-module-fqncI","is-open":"show-all-module-hQeGI"};
|
|
265
266
|
|
|
266
267
|
const ShowAll = ({ children, hasTransparency = true, initialHeight = 0, isOpen, onToggle, }) => {
|
|
267
268
|
const showAllRef = useRef(null);
|
|
@@ -270,38 +271,38 @@ const ShowAll = ({ children, hasTransparency = true, initialHeight = 0, isOpen,
|
|
|
270
271
|
return;
|
|
271
272
|
showAllRef.current.style.setProperty('--initital-height', `${initialHeight}px`);
|
|
272
273
|
}, [initialHeight]);
|
|
273
|
-
return (jsxs("div", { ref: showAllRef, className: clsx(styles$
|
|
274
|
-
[styles$
|
|
275
|
-
}), children: [jsx("div", { className: styles$
|
|
276
|
-
[styles$
|
|
277
|
-
}), children: children }) }), jsxs(LinkButton, { className: styles$
|
|
274
|
+
return (jsxs("div", { ref: showAllRef, className: clsx(styles$c['show-all'], {
|
|
275
|
+
[styles$c['is-open']]: isOpen,
|
|
276
|
+
}), children: [jsx("div", { className: styles$c.panel, children: jsx("div", { className: clsx(styles$c.content, {
|
|
277
|
+
[styles$c['has-transparency']]: hasTransparency,
|
|
278
|
+
}), children: children }) }), jsxs(LinkButton, { className: styles$c.button, onPress: () => onToggle(!isOpen), children: [jsx(ChevronDownSlim, { className: styles$c.icon }), isOpen ? (jsx(FormattedMessage, { id: "Show less" })) : (jsx(FormattedMessage, { id: "Show all" }))] })] }));
|
|
278
279
|
};
|
|
279
280
|
|
|
280
|
-
var styles$
|
|
281
|
+
var styles$b = {"multi-select":"multi-select-module-DC7Ix","filter-items":"multi-select-module-cwVFb","hidden":"multi-select-module-o7yHU","filter-item":"multi-select-module-OW-NK"};
|
|
281
282
|
|
|
282
283
|
function MultiSelect({ amountShown = 3, isOpen = false, onChange, onToggleOpen, options, render, }) {
|
|
283
284
|
const shownOptions = options.slice(0, amountShown);
|
|
284
285
|
const hiddenOptions = options.slice(amountShown);
|
|
285
|
-
return (jsxs("div", { className: styles$
|
|
286
|
+
return (jsxs("div", { className: styles$b['multi-select'], children: [jsx("div", { className: styles$b['filter-items'], children: shownOptions.map(option => (jsxs("div", { className: styles$b['filter-item'], children: [render({ onChange: () => onChange(option), option }), jsxs("span", { children: ["(", option.amount, ")"] })] }, option.value))) }), hiddenOptions?.length > 0 && (jsx(ShowAll, { hasTransparency: false, isOpen: isOpen, onToggle: onToggleOpen, children: jsx("div", { className: clsx(styles$b['filter-items'], styles$b['hidden']), children: hiddenOptions.map(option => (jsxs("div", { className: styles$b['filter-item'], children: [render({ onChange: () => onChange(option), option }), jsxs("span", { children: ["(", option.amount, ")"] })] }, option.value))) }) }))] }));
|
|
286
287
|
}
|
|
287
288
|
|
|
288
|
-
var styles$
|
|
289
|
+
var styles$a = {"checkbox":"checkbox-module-YNVdd","box":"checkbox-module-UKoyf","checkmark":"checkbox-module-pHIwh","focus":"checkbox-module-v23jy","active":"checkbox-module-7UG-b","color-checkbox":"checkbox-module-nEhvW"};
|
|
289
290
|
|
|
290
291
|
function Checkbox({ _pseudo = 'none', children, className, isDisabled, isSelected, onChange, value, }) {
|
|
291
|
-
return (jsxs(Checkbox$1, { className: clsx(className, styles$
|
|
292
|
+
return (jsxs(Checkbox$1, { className: clsx(className, styles$a.checkbox, styles$a[_pseudo]), isDisabled: isDisabled, isSelected: isSelected, onChange: onChange, value: value, children: [jsx("div", { className: styles$a.box, children: jsx("svg", { "aria-hidden": "true", className: styles$a.checkmark, viewBox: "0 0 18 18", children: jsx("polyline", { points: "1 9 7 14 15 4" }) }) }), children] }));
|
|
292
293
|
}
|
|
293
294
|
|
|
294
295
|
function ColorCheckbox({ _pseudo = 'none', children, className, color, isDisabled, isSelected, onChange, value, }) {
|
|
295
|
-
return (jsxs(Checkbox$1, { className: clsx(className, styles$
|
|
296
|
+
return (jsxs(Checkbox$1, { className: clsx(className, styles$a.checkbox, styles$a['color-checkbox'], styles$a[_pseudo]), isDisabled: isDisabled, isSelected: isSelected, onChange: onChange, style: {
|
|
296
297
|
'--selected-color': color,
|
|
297
|
-
}, value: value, children: [jsx("div", { className: styles$
|
|
298
|
+
}, value: value, children: [jsx("div", { className: styles$a.box }), children] }));
|
|
298
299
|
}
|
|
299
300
|
|
|
300
301
|
function CheckmarkFilledIcon(props) {
|
|
301
302
|
return (jsx("svg", { viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M10.864 17c-.2 0-.378-.045-.534-.135a1.588 1.588 0 0 1-.446-.407L6.278 12.22c-.185-.233-.278-.474-.278-.722 0-.264.087-.488.262-.672a.86.86 0 0 1 .651-.276c.156 0 .299.033.429.101s.258.188.384.361l3.094 3.71 5.42-8.19c.216-.354.483-.531.802-.531.245 0 .466.08.663.243A.785.785 0 0 1 18 6.88c0 .12-.028.243-.084.367a2.53 2.53 0 0 1-.194.356l-5.934 8.844c-.23.369-.538.553-.924.553z", fill: "currentColor", fillRule: "evenodd" }) }));
|
|
302
303
|
}
|
|
303
304
|
|
|
304
|
-
var styles$
|
|
305
|
+
var styles$9 = {"select":"select-module-ui-Wc","button":"select-module-aMQIQ","chevron":"select-module-00uRU","focus":"select-module-XMc0P","popover":"select-module-z8cWq","listbox":"select-module-S21ba","header":"select-module-4Bm2j","item":"select-module-LgEJO","check":"select-module-lQFw3"};
|
|
305
306
|
|
|
306
307
|
function Select({ disabled = false, label, onChange, options, selectedOption, showLabel = true, }) {
|
|
307
308
|
const selectRef = useRef(null);
|
|
@@ -316,10 +317,10 @@ function Select({ disabled = false, label, onChange, options, selectedOption, sh
|
|
|
316
317
|
window.addEventListener('resize', updateWidth);
|
|
317
318
|
return () => window.removeEventListener('resize', updateWidth);
|
|
318
319
|
}, []);
|
|
319
|
-
return (jsxs(Select$1, { ref: selectRef, "aria-label": label, className: styles$
|
|
320
|
+
return (jsxs(Select$1, { ref: selectRef, "aria-label": label, className: styles$9.select, isDisabled: disabled, onSelectionChange: selected => onChange(selected), placeholder: label, selectedKey: String(selectedOption), children: [showLabel && jsx(Label, { children: label }), jsxs(Button$1, { className: styles$9.button, children: [jsx(SelectValue, {}), jsx(ChevronDownSlim, { "aria-hidden": "true", className: styles$9.chevron })] }), jsx(Popover, { className: styles$9.popover, placement: "bottom left", triggerRef: selectRef, children: jsx(ListBox, { className: styles$9.listbox, children: jsxs(Section, { children: [jsx(Header, { className: styles$9.header, children: label }), Object.entries(options).map(([key, value]) => (jsxs(ListBoxItem, { "aria-label": value, className: styles$9.item, id: key, textValue: value, children: [selectedOption === key && (jsx("span", { slot: "description", children: jsx(CheckmarkFilledIcon, { className: styles$9.check }) })), jsx("span", { slot: "label", children: value })] }, key)))] }) }) })] }));
|
|
320
321
|
}
|
|
321
322
|
|
|
322
|
-
var styles$
|
|
323
|
+
var styles$8 = {"input-container":"textarea-module-C6Xr1","lg":"textarea-module-vksG-","md":"textarea-module-6JrQJ"};
|
|
323
324
|
|
|
324
325
|
/**
|
|
325
326
|
* This component is used to create a textarea that can grow as the user types.
|
|
@@ -354,7 +355,7 @@ const TextArea = forwardRef(({ autoGrow, size, ...textAreaProps }, _ref) => {
|
|
|
354
355
|
}
|
|
355
356
|
updateHeight();
|
|
356
357
|
}, [ref, autoGrow, updateHeight, size]);
|
|
357
|
-
return (jsx("div", { className: styles$
|
|
358
|
+
return (jsx("div", { className: styles$8['input-container'], children: jsx(TextArea$1, { ...textAreaProps, ref: node => {
|
|
358
359
|
ref.current =
|
|
359
360
|
node;
|
|
360
361
|
textAreaRef.current = node;
|
|
@@ -365,15 +366,15 @@ const TextArea = forwardRef(({ autoGrow, size, ...textAreaProps }, _ref) => {
|
|
|
365
366
|
});
|
|
366
367
|
TextArea.displayName = 'TextArea';
|
|
367
368
|
|
|
368
|
-
var styles$
|
|
369
|
+
var styles$7 = {"field":"text-field-module-JeaK0"};
|
|
369
370
|
|
|
370
371
|
/**
|
|
371
372
|
* This component is used to create a text field.
|
|
372
373
|
* It can be used as a single line input or as a textarea.
|
|
373
374
|
* This field can also grow when a user types in text.
|
|
374
375
|
*/
|
|
375
|
-
function TextField({ autoFocus, autoGrow, defaultValue, isDisabled, isInvalid, isMultiline, isReadOnly, isRequired, label, maxLength, onChange, onInput, onKeyUp, placeholder, rows, showLabel =
|
|
376
|
-
return (jsxs(TextField$1, { "aria-label": label, autoFocus: autoFocus, className: clsx(styles$
|
|
376
|
+
function TextField({ autoFocus, autoGrow, defaultValue, isDisabled, isInvalid, isMultiline, isReadOnly, isRequired, label, maxLength, onChange, onInput, onKeyUp, placeholder, rows, showLabel = false, size = 'lg', value, }) {
|
|
377
|
+
return (jsxs(TextField$1, { "aria-label": label, autoFocus: autoFocus, className: clsx(styles$7.field, styles$7[size]), defaultValue: defaultValue, isDisabled: isDisabled, isInvalid: isInvalid, isReadOnly: isReadOnly, isRequired: isRequired, maxLength: maxLength, onChange: value => {
|
|
377
378
|
onChange?.(value);
|
|
378
379
|
}, onInput: onInput, onKeyUp: e => onKeyUp?.(e), value: value, children: [showLabel && jsx(Label, { isRequired: isRequired, children: label }), isMultiline ? (jsx(TextArea, { autoGrow: autoGrow, placeholder: placeholder, rows: rows, size: size })) : (jsx(Input, { autoGrow: autoGrow, placeholder: placeholder, size: size })), jsx(FieldError, {})] }));
|
|
379
380
|
}
|
|
@@ -394,16 +395,267 @@ function IntlProvider({ children, formatMessage }) {
|
|
|
394
395
|
return (jsx(IntlContext.Provider, { value: { formatMessage }, children: children }));
|
|
395
396
|
}
|
|
396
397
|
|
|
397
|
-
var styles$
|
|
398
|
+
var styles$6 = {"product-grid":"product-overview-grid-module-bzys-","grid-item":"product-overview-grid-module-MlUVA"};
|
|
398
399
|
|
|
399
400
|
function ProductOverviewGrid({ children }) {
|
|
400
|
-
return (jsx("div", { className: styles$
|
|
401
|
+
return (jsx("div", { className: styles$6['product-grid'], children: Children.map(children, (child, index) => (jsx("div", { className: styles$6['grid-item'], children: child }, index))) }));
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function ChevronDownBold(props) {
|
|
405
|
+
return (jsx("svg", { viewBox: "0 0 14 15", width: "14", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "M6.986 11.837 1.166 5.98c.206-.376.542-.798 1.008-1.268.205-.206.41-.394.615-.563a2.91 2.91 0 0 1 .476-.338l.168-.112 3.553 3.576 3.581-3.605c.392.226.811.564 1.26 1.014.204.207.39.413.559.62l.251.32c.045.06.083.113.112.158l.084.17-5.847 5.885z", fill: "currentColor", fillRule: "evenodd" }) }));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function AccordionItem({ _pseudo = 'none', children, className, id, isDisabled = false, isOpen: isOpenProp = false, size, title, }) {
|
|
409
|
+
const [isOpen, setIsOpen] = useState(isOpenProp);
|
|
410
|
+
const panelId = `panel-${id}`;
|
|
411
|
+
return (jsxs("div", { className: clsx(className, styles$d['accordion-item'], {
|
|
412
|
+
[styles$d['is-open']]: isOpen,
|
|
413
|
+
}), children: [jsx("h3", { children: jsxs("button", { "aria-controls": panelId, "aria-expanded": isOpen, className: clsx(styles$d.button, styles$d[_pseudo]), disabled: isDisabled, id: id, onClick: () => setIsOpen(!isOpen), type: "button", children: [title, jsx("span", { className: styles$d.icon, children: size === 'lg' ? jsx(ChevronDownBold, {}) : jsx(ChevronDownSlim, {}) })] }) }), jsx("div", { "aria-labelledby": id, className: styles$d.panel, id: panelId, role: "region", children: jsx("div", { className: styles$d.content, children: children }) })] }));
|
|
401
414
|
}
|
|
402
415
|
|
|
403
416
|
function CloseFilledIcon(props) {
|
|
404
417
|
return (jsx("svg", { viewBox: "0 0 32 33", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "m10.667 11.14 10.666 10.58m0-10.58L10.667 21.72", fill: "none", fillRule: "evenodd", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.867" }) }));
|
|
405
418
|
}
|
|
406
419
|
|
|
420
|
+
var styles$5 = {"heading":"heading-module-pMC65","uppercase":"heading-module-6spgX","italic":"heading-module-XXMDM","xxl":"heading-module-Kn3ZN","xl":"heading-module--hZs-","l":"heading-module-WrJRY","m":"heading-module-hTexc","s":"heading-module-7W29m","xs":"heading-module-SgaLB","xxs":"heading-module-33en7"};
|
|
421
|
+
|
|
422
|
+
const sizeToTag = {
|
|
423
|
+
l: 'h3',
|
|
424
|
+
m: 'h4',
|
|
425
|
+
s: 'h5',
|
|
426
|
+
xl: 'h2',
|
|
427
|
+
xs: 'h6',
|
|
428
|
+
xxl: 'h1',
|
|
429
|
+
xxs: 'h7',
|
|
430
|
+
};
|
|
431
|
+
function Heading({ children, className, italic, size = 'xxl', tag, uppercase, }) {
|
|
432
|
+
return createElement(tag || sizeToTag[size], {
|
|
433
|
+
className: clsx(className, styles$5.heading, styles$5[size], {
|
|
434
|
+
[styles$5.uppercase]: uppercase,
|
|
435
|
+
[styles$5.italic]: italic,
|
|
436
|
+
}),
|
|
437
|
+
}, children);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
var styles$4 = {"active-filters":"active-filters-module-1qLjB","header":"active-filters-module-UKKDu","title":"active-filters-module-h29rI","active-filter-item":"active-filters-module-Rrmhy","category":"active-filters-module-u9TTE","active-filter-value":"active-filters-module-CIuPU"};
|
|
441
|
+
|
|
442
|
+
const ActiveFilters = ({ onClearAllFilters, onClearFilter, selectedFilterCategories, }) => {
|
|
443
|
+
if (selectedFilterCategories.length === 0)
|
|
444
|
+
return null;
|
|
445
|
+
return (jsxs("div", { className: styles$4['active-filters'], children: [jsxs("div", { className: styles$4.header, children: [jsx(Heading, { className: styles$4.title, size: "m", children: jsx(FormattedMessage, { id: "Chosen filters" }) }), jsx(LinkButton, { onPress: onClearAllFilters, children: jsx(FormattedMessage, { id: "Clear filters" }) })] }), selectedFilterCategories.map((category, index) => (jsx("section", { className: styles$4.category, children: category.filters.map(filter => (jsxs("div", { className: styles$4['active-filter-item'], children: [jsxs("span", { children: [jsxs("span", { children: [category.label, ": "] }), jsx("span", { className: styles$4['active-filter-value'], children: filter.label })] }), jsx(IconButton, { color: "secondary", onPress: () => onClearFilter(category.label, filter), children: jsx(CloseFilledIcon, {}) })] }, `${category.label}-${filter.value}`))) }, `${category.label}-${index}`)))] }));
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
function AlgoliaActiveFilters() {
|
|
449
|
+
const { items, refine } = useCurrentRefinements();
|
|
450
|
+
const { refine: clearAllFilters } = useClearRefinements();
|
|
451
|
+
const selectedFilterCategories = items
|
|
452
|
+
.sort((a, b) => (a.label.localeCompare(b.label) ? 1 : -1))
|
|
453
|
+
.map((category) => ({
|
|
454
|
+
filters: category.refinements.sort((a, b) =>
|
|
455
|
+
// TODO: Investigate how to sort numerical
|
|
456
|
+
a.value.toString().localeCompare(b.value.toString()) ? 1 : -1),
|
|
457
|
+
label: category.label,
|
|
458
|
+
}));
|
|
459
|
+
function onClearFilter(categoryLabel, filter) {
|
|
460
|
+
selectedFilterCategories
|
|
461
|
+
.filter(category => category.label === categoryLabel)
|
|
462
|
+
.flatMap(category => category.filters)
|
|
463
|
+
.filter(f => f.value === filter.value)
|
|
464
|
+
.forEach(refine);
|
|
465
|
+
}
|
|
466
|
+
return (jsx(ActiveFilters, { onClearAllFilters: clearAllFilters, onClearFilter: onClearFilter, selectedFilterCategories: selectedFilterCategories }));
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
var styles$3 = {"filter-panel":"filter-panel-module-8oxI1","scroll-container":"filter-panel-module-w0hhZ","categories-section":"filter-panel-module-AHlq3","category":"filter-panel-module-TMp3J","count":"filter-panel-module-ykW1a","categories":"filter-panel-module-xvhRz","categories-header":"filter-panel-module-hJVR0","button":"filter-panel-module-hMmIb"};
|
|
470
|
+
|
|
471
|
+
function AlgoliaCategories() {
|
|
472
|
+
const categories = [{ count: 123, href: '#', id: '123', name: 'Hand tools' }];
|
|
473
|
+
return (jsx("div", { children: categories?.length > 0 && (jsxs("section", { className: styles$3['categories-section'], children: [jsx("h4", { className: styles$3['categories-header'], children: "Categories" }), jsx("div", { className: styles$3.categories, children: categories.map(({ count, href, id, name }) => (jsxs("a", { className: styles$3['category'], href: href, children: [jsx("span", { children: name }), ' ', jsxs("span", { className: styles$3.count, children: ["(", count, ")"] })] }, id))) })] })) }));
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const useDisclosure = () => {
|
|
477
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
478
|
+
const open = useCallback(() => {
|
|
479
|
+
setIsOpen(true);
|
|
480
|
+
}, []);
|
|
481
|
+
const close = useCallback(() => {
|
|
482
|
+
setIsOpen(false);
|
|
483
|
+
}, []);
|
|
484
|
+
const toggle = useCallback(() => {
|
|
485
|
+
setIsOpen(prevIsOpen => !prevIsOpen);
|
|
486
|
+
}, []);
|
|
487
|
+
return {
|
|
488
|
+
close,
|
|
489
|
+
isClosed: !isOpen,
|
|
490
|
+
isOpen,
|
|
491
|
+
open,
|
|
492
|
+
toggle,
|
|
493
|
+
};
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
function AlgoliaMultiSelect({ attribute }) {
|
|
497
|
+
const { items, refine } = useRefinementList({
|
|
498
|
+
attribute,
|
|
499
|
+
limit: 100,
|
|
500
|
+
operator: 'or',
|
|
501
|
+
showMoreLimit: 100,
|
|
502
|
+
});
|
|
503
|
+
const { isOpen, toggle } = useDisclosure();
|
|
504
|
+
const options = items.map(item => ({
|
|
505
|
+
amount: item.count,
|
|
506
|
+
isSelected: item.isRefined,
|
|
507
|
+
label: item.label,
|
|
508
|
+
value: item.value,
|
|
509
|
+
}));
|
|
510
|
+
return (jsx(MultiSelect, { amountShown: 3, isOpen: isOpen, onChange: option => refine(option.value), onToggleOpen: toggle, options: options, render: ({ onChange, option }) => (jsx(Checkbox, { isSelected: option.isSelected, onChange: () => onChange(option.value), value: option.value, children: option.label })) }));
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function AlgoliaResultsCount() {
|
|
514
|
+
const { results } = useHits();
|
|
515
|
+
const t = useFormattedMessage();
|
|
516
|
+
if (!results)
|
|
517
|
+
return null;
|
|
518
|
+
const count = results.nbHits;
|
|
519
|
+
return `${count} ${count === 1 ? t('article') : t('articles')}`;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function AlgoliaFilterPanel({ onShowProducts, }) {
|
|
523
|
+
const { attributesToRender } = useDynamicWidgets();
|
|
524
|
+
const t = useFormattedMessage();
|
|
525
|
+
return (jsx("div", { className: styles$3['filter-panel'], children: jsxs("div", { className: styles$3['scroll-container'], children: [jsx(AlgoliaCategories, {}), jsx(AlgoliaActiveFilters, {}), attributesToRender.length > 0 && (jsx("section", { children: attributesToRender.map((attribute, index) => (jsx(Accordion, { children: jsx(AccordionItem, { id: `attribute-${index}`, title: t(attribute), children: jsx(AlgoliaMultiSelect, { attribute: attribute }) }) }, `attribute-${index}`))) })), jsx("div", { className: styles$3.button, children: jsxs(Button, { withArrow: true, onPress: onShowProducts, size: "md", children: [jsx(FormattedMessage, { id: "Show" }), " ", jsx(AlgoliaResultsCount, {})] }) })] }) }));
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function ChevronLeftFilledIcon(props) {
|
|
529
|
+
return (jsx("svg", { height: "13", viewBox: "0 0 13 13", width: "13", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "m3.889 6 5.025-5c.19.082.378.198.562.35.184.15.359.332.524.544L5.84 5.988 10 9.996c-.17.216-.344.407-.524.573-.18.166-.367.31-.562.431L3.889 6z", fill: "currentColor", fillRule: "evenodd" }) }));
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function ChevronRightFilledIcon(props) {
|
|
533
|
+
return (jsx("svg", { height: "13", viewBox: "0 0 13 13", width: "13", xmlns: "http://www.w3.org/2000/svg", ...props, children: jsx("path", { d: "m9.111 6-5.025 5a2.332 2.332 0 0 1-.562-.35A3.459 3.459 0 0 1 3 10.107l4.16-4.094L3 2.004c.17-.216.344-.407.524-.573.18-.166.367-.31.562-.431l5.025 5z", fill: "currentColor", fillRule: "evenodd" }) }));
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
var styles$2 = {"pagination":"pagination-module-k4OgY","page-number-container":"pagination-module-oq89A"};
|
|
537
|
+
|
|
538
|
+
function Pagination({ currentPage, onChange, totalPages }) {
|
|
539
|
+
return (jsxs("div", { className: styles$2.pagination, children: [jsx(IconButton, { isDisabled: currentPage === 1, onPress: () => onChange(currentPage - 1), children: jsx(ChevronLeftFilledIcon, {}) }), jsxs("div", { className: styles$2['page-number-container'], children: [jsx(NumberField, { autoGrow: true, label: "current-page", maxValue: totalPages, minValue: 1, onChange: onChange, value: currentPage }), jsx(FormattedMessage, { id: "of" }), jsx("div", { children: totalPages })] }), jsx(IconButton, { isDisabled: currentPage >= totalPages, onPress: () => onChange(currentPage + 1), children: jsx(ChevronRightFilledIcon, {}) })] }));
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
function AlgoliaPagination() {
|
|
543
|
+
const { currentRefinement, nbPages, refine } = usePagination();
|
|
544
|
+
return (jsx(Pagination, { currentPage: currentRefinement + 1, onChange: pageNumber => refine(pageNumber - 1), totalPages: nbPages }));
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function AlgoliaSortBy() {
|
|
548
|
+
const { options: algoliaOptions, refine } = useSortBy({
|
|
549
|
+
items: [
|
|
550
|
+
{ label: 'Name', value: 'dev_sonic_products_en' },
|
|
551
|
+
{ label: 'Height', value: 'dev_sonic_products_en_height' },
|
|
552
|
+
],
|
|
553
|
+
});
|
|
554
|
+
if (algoliaOptions.length === 0)
|
|
555
|
+
return null;
|
|
556
|
+
const options = algoliaOptions.reduce((acc, option) => {
|
|
557
|
+
acc[option.value] = option.label;
|
|
558
|
+
return acc;
|
|
559
|
+
}, {});
|
|
560
|
+
return (jsx(Select, { label: "Sort", onChange: value => refine(String(value)), options: options, selectedOption: "dev_sonic_products_en", showLabel: false }));
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
564
|
+
function useDebouncedCallback(func, delay) {
|
|
565
|
+
const timeoutId = useRef();
|
|
566
|
+
return function debounced(...args) {
|
|
567
|
+
clearTimeout(timeoutId.current);
|
|
568
|
+
timeoutId.current = setTimeout(() => {
|
|
569
|
+
func(...args);
|
|
570
|
+
}, delay);
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const GlobalStateProviderContext = createContext(undefined);
|
|
575
|
+
function useGlobalState(key, initialState) {
|
|
576
|
+
const state = useContext(GlobalStateProviderContext).get(key, initialState);
|
|
577
|
+
const [rerenderState, setRerenderState] = useState(state.value);
|
|
578
|
+
useEffect(() => {
|
|
579
|
+
state.addEventListener('stateChanged', setRerenderState);
|
|
580
|
+
return () => {
|
|
581
|
+
state.removeEventListener('stateChanged', setRerenderState);
|
|
582
|
+
};
|
|
583
|
+
}, [state]);
|
|
584
|
+
return [rerenderState, (value) => (state.value = value)];
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function useCart() {
|
|
588
|
+
const [state] = useGlobalState('cart');
|
|
589
|
+
if (!state) {
|
|
590
|
+
throw new Error('useCart must be used together with the ReduxCartProvider');
|
|
591
|
+
}
|
|
592
|
+
return state;
|
|
593
|
+
}
|
|
594
|
+
function useProductCartLine(productId) {
|
|
595
|
+
const { addToCart, currentCart, isLoaded, isLoading, loadCurrentCart, removeCartLine, updateCartLine, } = useCart();
|
|
596
|
+
return {
|
|
597
|
+
addToCart,
|
|
598
|
+
cartLine: currentCart?.cartLines?.find(cl => cl.productId === productId),
|
|
599
|
+
currentCart,
|
|
600
|
+
isLoaded,
|
|
601
|
+
isLoading,
|
|
602
|
+
loadCurrentCart,
|
|
603
|
+
removeCartLine,
|
|
604
|
+
updateCartLine,
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
const ConnectedAddToCartButton = ({ productId }) => {
|
|
609
|
+
const [quantity, setQuantity] = useState(0);
|
|
610
|
+
const { addToCart, cartLine: _cartLine, isLoaded, isLoading, loadCurrentCart, removeCartLine, updateCartLine, } = useProductCartLine(productId);
|
|
611
|
+
const [cartLine, setCartLineState] = useState(_cartLine);
|
|
612
|
+
const setCartLineStateDebounced = useDebouncedCallback(setCartLineState, 4000);
|
|
613
|
+
useEffect(() => {
|
|
614
|
+
if (isLoading || isLoaded)
|
|
615
|
+
return;
|
|
616
|
+
loadCurrentCart();
|
|
617
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
618
|
+
}, []);
|
|
619
|
+
useEffect(() => {
|
|
620
|
+
setQuantity(cartLine?.qtyOrdered || 0);
|
|
621
|
+
}, [cartLine]);
|
|
622
|
+
useEffect(() => {
|
|
623
|
+
/* Debounce updating the internal cart line state.
|
|
624
|
+
* This is necessary when a user mutates the cart multiple times in quick succession.
|
|
625
|
+
* A response from the server may take a while to come back, so we need to wait for it.
|
|
626
|
+
* If we don't debounce, the cart line state will be updated multiple times, causing the UI to flicker.
|
|
627
|
+
*/
|
|
628
|
+
if (!cartLine) {
|
|
629
|
+
setCartLineState(_cartLine);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
setCartLineStateDebounced(_cartLine);
|
|
633
|
+
}
|
|
634
|
+
}, [_cartLine, cartLine, setCartLineStateDebounced]);
|
|
635
|
+
const updateCart = useDebouncedCallback((quantity) => {
|
|
636
|
+
if (cartLine) {
|
|
637
|
+
if (quantity === 0) {
|
|
638
|
+
removeCartLine({ cartLineId: cartLine.id });
|
|
639
|
+
}
|
|
640
|
+
else {
|
|
641
|
+
updateCartLine({ ...cartLine, qtyOrdered: quantity });
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
addToCart({ productId, quantity });
|
|
646
|
+
}
|
|
647
|
+
}, 300);
|
|
648
|
+
const handleChange = (quantity) => {
|
|
649
|
+
setQuantity(quantity);
|
|
650
|
+
updateCart(quantity);
|
|
651
|
+
};
|
|
652
|
+
return jsx(AddToCartButton, { onChange: handleChange, quantity: quantity });
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
function ConnectedProductCart({ productId, ...props }) {
|
|
656
|
+
return (jsx(ProductCard, { ...props, addToCartButton: jsx(ConnectedAddToCartButton, { productId: productId }) }));
|
|
657
|
+
}
|
|
658
|
+
|
|
407
659
|
const SidebarContext = createContext({
|
|
408
660
|
isOpen: false,
|
|
409
661
|
toggle: () => { },
|
|
@@ -421,7 +673,7 @@ var styles$1 = {"sidebar":"sidebar-module-fSa9Q","close":"sidebar-module-2puGC",
|
|
|
421
673
|
|
|
422
674
|
function Sidebar({ children }) {
|
|
423
675
|
const { isOpen, toggle } = useSidebar();
|
|
424
|
-
return (jsxs("aside", { className: clsx(styles$1.sidebar, { [styles$1['is-open']]: isOpen }), children: [jsx("div", { className: styles$1.close, children: jsx(IconButton, { color: "secondary", onPress: toggle, children: jsx(CloseFilledIcon, {}) }) }),
|
|
676
|
+
return (jsxs("aside", { className: clsx(styles$1.sidebar, { [styles$1['is-open']]: isOpen }), children: [jsx("div", { className: styles$1.close, children: jsx(IconButton, { color: "secondary", onPress: toggle, children: jsx(CloseFilledIcon, {}) }) }), children] }));
|
|
425
677
|
}
|
|
426
678
|
|
|
427
679
|
function FilterOutlinedIcon(props) {
|
|
@@ -433,28 +685,38 @@ const ToggleSidebarButton = () => {
|
|
|
433
685
|
return (jsx(Button, { color: "secondary", icon: jsx(FilterOutlinedIcon, {}), onPress: toggle, size: "sm", variant: "outline", children: jsx(FormattedMessage, { id: "Show filters" }) }));
|
|
434
686
|
};
|
|
435
687
|
|
|
436
|
-
|
|
437
|
-
return (jsxs("div", { children: [jsx("div", { children: jsx("h3", { children: title }) }), jsx("div", { children: children })] }));
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function ColorFilter({ onChange, options, value }) {
|
|
441
|
-
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
|
|
442
|
-
? [...value, option.value]
|
|
443
|
-
: value.filter(v => v !== option.value)), value: option.value, children: option.label }) }, option.value))) }) }));
|
|
444
|
-
}
|
|
688
|
+
var styles = {"product-listing":"product-listing-module-EmEFw","header":"product-listing-module-JEjsa","action-bar":"product-listing-module-rFNcR","count":"product-listing-module-1seez","product-grid-container":"product-listing-module-hZuKD","product-grid":"product-listing-module-RRbLO","pagination":"product-listing-module-kkOfB"};
|
|
445
689
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
690
|
+
function ProductListing({ isLoading = false }) {
|
|
691
|
+
const { toggle } = useSidebar();
|
|
692
|
+
const { hits: productHits } = useHits();
|
|
693
|
+
return (jsxs("div", { className: styles['product-listing'], children: [jsx("div", { className: styles.header, children: jsx(Heading, { italic: true, uppercase: true, size: "xl", tag: "h1", children: "Pliers" }) }), jsxs("section", { className: styles['action-bar'], children: [jsx(ToggleSidebarButton, {}), jsx("span", { className: styles.count, children: jsx(AlgoliaResultsCount, {}) }), jsx(AlgoliaSortBy, {})] }), jsx("section", { children: isLoading ? (jsx("p", { children: "Loading..." })) : (jsxs("div", { className: styles['product-grid-container'], children: [jsx(Sidebar, { children: jsx(AlgoliaFilterPanel, { onShowProducts: toggle }) }), jsx("div", { className: styles['product-grid'], children: jsx(ProductOverviewGrid, { children: productHits.map(productHit => (jsx(ConnectedProductCart, { image: {
|
|
694
|
+
alt: productHit.name,
|
|
695
|
+
fit: 'contain',
|
|
696
|
+
sizes: { lg: 288, md: 204, sm: 122 },
|
|
697
|
+
src: productHit.images?.find(image => image.quality === 'large')?.url || '',
|
|
698
|
+
srcSet: [
|
|
699
|
+
{
|
|
700
|
+
url: productHit.images?.find(image => image.quality === 'small')?.url || '',
|
|
701
|
+
width: 122,
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
url: productHit.images?.find(image => image.quality === 'medium')?.url || '',
|
|
705
|
+
width: 204,
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
url: productHit.images?.find(image => image.quality === 'large')?.url || '',
|
|
709
|
+
width: 288,
|
|
710
|
+
},
|
|
711
|
+
],
|
|
712
|
+
title: productHit.name,
|
|
713
|
+
},
|
|
714
|
+
// eslint-disable-next-line no-console
|
|
715
|
+
onClick: () => console.log('clicked'), price: {
|
|
716
|
+
current: productHit.discountedPrice,
|
|
717
|
+
includeVat: false,
|
|
718
|
+
original: productHit.price,
|
|
719
|
+
}, productId: productHit.id, sku: productHit.ean, tag: "new", title: productHit.name }, productHit.id))) }) }), jsx("div", { className: styles.pagination, children: jsx(AlgoliaPagination, {}) })] })) })] }));
|
|
458
720
|
}
|
|
459
721
|
|
|
460
722
|
function createProductListingSearchParams(state) {
|