@magento/venia-ui 9.6.0-beta.1 → 9.7.0-alpha.1
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/i18n/en_US.json +1 -0
- package/lib/components/Accordion/__tests__/__snapshots__/accordion.spec.js.snap +2 -0
- package/lib/components/Accordion/section.js +1 -0
- package/lib/components/AddToCartDialog/__tests__/__snapshots__/addToCartDialog.spec.js.snap +11 -0
- package/lib/components/AddToCartDialog/__tests__/addToCartDialog.spec.js +1 -0
- package/lib/components/AddToCartDialog/addToCartDialog.js +4 -1
- package/lib/components/CartPage/PriceAdjustments/__tests__/__snapshots__/priceAdjustments.spec.js.snap +2 -0
- package/lib/components/CartPage/ProductListing/EditModal/__tests__/__snapshots__/productForm.spec.js.snap +22 -0
- package/lib/components/CartPage/ProductListing/EditModal/__tests__/productForm.spec.js +1 -0
- package/lib/components/CartPage/ProductListing/EditModal/productForm.js +2 -0
- package/lib/components/CartPage/ProductListing/__tests__/__snapshots__/product.spec.js.snap +3 -0
- package/lib/components/CategoryTree/categoryBranch.js +3 -3
- package/lib/components/CategoryTree/categoryLeaf.js +3 -3
- package/lib/components/CategoryTree/categoryTree.js +4 -4
- package/lib/components/CheckoutPage/PaymentInformation/paymentMethods.js +2 -0
- package/lib/components/CheckoutPage/PaymentInformation/paymentMethods.module.css +1 -3
- package/lib/components/FilterSidebar/filterSidebar.js +0 -1
- package/lib/components/Gallery/__tests__/__snapshots__/gallery.spec.js.snap +0 -6
- package/lib/components/Gallery/__tests__/__snapshots__/item.spec.js.snap +0 -2
- package/lib/components/Gallery/gallery.js +1 -6
- package/lib/components/Gallery/item.js +3 -9
- package/lib/components/Header/__tests__/__snapshots__/accountTrigger.spec.js.snap +1 -0
- package/lib/components/Header/accountTrigger.js +1 -0
- package/lib/components/LegacyMiniCart/__tests__/__snapshots__/kebab.spec.js.snap +2 -0
- package/lib/components/LegacyMiniCart/kebab.js +2 -1
- package/lib/components/LegacyMiniCart/kebab.module.css +0 -1
- package/lib/components/Logo/logo.js +1 -0
- package/lib/components/MegaMenu/__tests__/__snapshots__/MegaMenu.spec.js.snap +3 -0
- package/lib/components/MegaMenu/__tests__/__snapshots__/MegaMenuItem.spec.js.snap +2 -0
- package/lib/components/MegaMenu/megaMenuItem.js +4 -0
- package/lib/components/Navigation/navigation.js +2 -2
- package/lib/components/Pagination/navButton.module.css +5 -0
- package/lib/components/Pagination/tile.module.css +0 -1
- package/lib/components/ProductFullDetail/__tests__/__snapshots__/productFullDetail.spec.js.snap +576 -298
- package/lib/components/ProductFullDetail/__tests__/productFullDetail.spec.js +16 -0
- package/lib/components/ProductFullDetail/productFullDetail.js +37 -20
- package/lib/components/ProductFullDetail/productFullDetail.module.css +3 -0
- package/lib/components/ProductOptions/__tests__/__snapshots__/swatch.spec.js.snap +51 -0
- package/lib/components/ProductOptions/__tests__/__snapshots__/tile.spec.js.snap +28 -0
- package/lib/components/ProductOptions/__tests__/swatch.spec.js +52 -0
- package/lib/components/ProductOptions/__tests__/tile.spec.js +48 -0
- package/lib/components/ProductOptions/option.js +5 -1
- package/lib/components/ProductOptions/options.js +12 -2
- package/lib/components/ProductOptions/swatch.js +27 -5
- package/lib/components/ProductOptions/swatch.module.css +17 -0
- package/lib/components/ProductOptions/swatchList.js +25 -4
- package/lib/components/ProductOptions/tile.js +24 -5
- package/lib/components/ProductOptions/tile.module.css +20 -0
- package/lib/components/ProductOptions/tileList.js +25 -2
- package/lib/components/ProductSort/__tests__/__snapshots__/productSort.spec.js.snap +0 -1
- package/lib/components/ProductSort/productSort.js +0 -1
- package/lib/components/SearchPage/__tests__/__snapshots__/searchPage.spec.js.snap +28 -9
- package/lib/components/SearchPage/searchPage.js +6 -6
- package/lib/components/SortedByContainer/sortedByContainer.js +1 -1
- package/package.json +2 -2
|
@@ -175,6 +175,8 @@ const talonProps = {
|
|
|
175
175
|
handleAddToCart: mockHandleAddToCart,
|
|
176
176
|
handleSelectionChange: mockHandleSelectionChange,
|
|
177
177
|
isOutOfStock: false,
|
|
178
|
+
isEverythingOutOfStock: false,
|
|
179
|
+
outOfStockVariants: [],
|
|
178
180
|
isAddToCartDisabled: false,
|
|
179
181
|
isSupportedProductType: true,
|
|
180
182
|
mediaGalleryEntries: [],
|
|
@@ -356,3 +358,17 @@ test('it renders message with unsupported product type', () => {
|
|
|
356
358
|
|
|
357
359
|
expect(tree.toJSON()).toMatchSnapshot();
|
|
358
360
|
});
|
|
361
|
+
|
|
362
|
+
test('it renders message with everything out of stock', () => {
|
|
363
|
+
useProductFullDetail.mockReturnValue({
|
|
364
|
+
...talonProps,
|
|
365
|
+
isEverythingOutOfStock: true,
|
|
366
|
+
isAddToCartDisabled: true
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const tree = createTestInstance(
|
|
370
|
+
<ProductFullDetail product={mockConfigurableProduct} />
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
expect(tree.toJSON()).toMatchSnapshot();
|
|
374
|
+
});
|
|
@@ -47,6 +47,8 @@ const ProductFullDetail = props => {
|
|
|
47
47
|
handleAddToCart,
|
|
48
48
|
handleSelectionChange,
|
|
49
49
|
isOutOfStock,
|
|
50
|
+
isEverythingOutOfStock,
|
|
51
|
+
outOfStockVariants,
|
|
50
52
|
isAddToCartDisabled,
|
|
51
53
|
isSupportedProductType,
|
|
52
54
|
mediaGalleryEntries,
|
|
@@ -64,6 +66,8 @@ const ProductFullDetail = props => {
|
|
|
64
66
|
<Options
|
|
65
67
|
onSelectionChange={handleSelectionChange}
|
|
66
68
|
options={product.configurable_options}
|
|
69
|
+
isEverythingOutOfStock={isEverythingOutOfStock}
|
|
70
|
+
outOfStockVariants={outOfStockVariants}
|
|
67
71
|
/>
|
|
68
72
|
</Suspense>
|
|
69
73
|
) : null;
|
|
@@ -167,27 +171,40 @@ const ProductFullDetail = props => {
|
|
|
167
171
|
};
|
|
168
172
|
}, [customAttributes, productDetails.sku, formatMessage]);
|
|
169
173
|
|
|
170
|
-
const cartCallToActionText =
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
174
|
+
const cartCallToActionText =
|
|
175
|
+
!isEverythingOutOfStock || !isOutOfStock ? (
|
|
176
|
+
<FormattedMessage
|
|
177
|
+
id="productFullDetail.addItemToCart"
|
|
178
|
+
defaultMessage="Add to Cart"
|
|
179
|
+
/>
|
|
180
|
+
) : (
|
|
181
|
+
<FormattedMessage
|
|
182
|
+
id="productFullDetail.itemOutOfStock"
|
|
183
|
+
defaultMessage="Out of Stock"
|
|
184
|
+
/>
|
|
185
|
+
);
|
|
186
|
+
// Error message for screen reader
|
|
182
187
|
const cartActionContent = isSupportedProductType ? (
|
|
183
|
-
<
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
188
|
+
<section className={classes.actButton}>
|
|
189
|
+
<Button
|
|
190
|
+
data-cy="ProductFullDetail-addToCartButton"
|
|
191
|
+
disabled={isAddToCartDisabled}
|
|
192
|
+
aria-disabled={isAddToCartDisabled}
|
|
193
|
+
aria-label={
|
|
194
|
+
isEverythingOutOfStock
|
|
195
|
+
? formatMessage({
|
|
196
|
+
id: 'productFullDetail.outOfStockProduct',
|
|
197
|
+
defaultMessage:
|
|
198
|
+
'This item is currently out of stock'
|
|
199
|
+
})
|
|
200
|
+
: ''
|
|
201
|
+
}
|
|
202
|
+
priority="high"
|
|
203
|
+
type="submit"
|
|
204
|
+
>
|
|
205
|
+
{cartCallToActionText}
|
|
206
|
+
</Button>
|
|
207
|
+
</section>
|
|
191
208
|
) : (
|
|
192
209
|
<div className={classes.unavailableContainer}>
|
|
193
210
|
<Info />
|
|
@@ -35,6 +35,57 @@ exports[`appends "_focused" to className if hasFocus is true 1`] = `
|
|
|
35
35
|
</button>
|
|
36
36
|
`;
|
|
37
37
|
|
|
38
|
+
exports[`appends "_outOfStock" to className if isEverythingOutOfStock is true 1`] = `
|
|
39
|
+
<button
|
|
40
|
+
className="root_outOfStock"
|
|
41
|
+
disabled={true}
|
|
42
|
+
onClick={[Function]}
|
|
43
|
+
style={
|
|
44
|
+
Object {
|
|
45
|
+
"--venia-swatch-bg": "#123123",
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
title="red"
|
|
49
|
+
type="button"
|
|
50
|
+
>
|
|
51
|
+
<span
|
|
52
|
+
className="root"
|
|
53
|
+
>
|
|
54
|
+
<svg
|
|
55
|
+
className="icon"
|
|
56
|
+
fill="none"
|
|
57
|
+
height={24}
|
|
58
|
+
stroke="currentColor"
|
|
59
|
+
strokeLinecap="round"
|
|
60
|
+
strokeLinejoin="round"
|
|
61
|
+
strokeWidth="2"
|
|
62
|
+
viewBox="0 0 24 24"
|
|
63
|
+
width={24}
|
|
64
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
65
|
+
>
|
|
66
|
+
<polyline
|
|
67
|
+
points="20 6 9 17 4 12"
|
|
68
|
+
/>
|
|
69
|
+
</svg>
|
|
70
|
+
</span>
|
|
71
|
+
</button>
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
exports[`appends "_outOfStock" to className if isOptionOutOfStock is true 1`] = `
|
|
75
|
+
<button
|
|
76
|
+
className="root_outOfStock"
|
|
77
|
+
disabled={true}
|
|
78
|
+
onClick={[Function]}
|
|
79
|
+
style={
|
|
80
|
+
Object {
|
|
81
|
+
"--venia-swatch-bg": "#123123",
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
title="red"
|
|
85
|
+
type="button"
|
|
86
|
+
/>
|
|
87
|
+
`;
|
|
88
|
+
|
|
38
89
|
exports[`appends "_selected" to className if isSelected is true 1`] = `
|
|
39
90
|
<button
|
|
40
91
|
className="root_selected"
|
|
@@ -13,6 +13,34 @@ exports[`appends "_focused" to className if hasFocus is true 1`] = `
|
|
|
13
13
|
</button>
|
|
14
14
|
`;
|
|
15
15
|
|
|
16
|
+
exports[`appends "_outOfStock" to className if isEverythingOutOfStock is true 1`] = `
|
|
17
|
+
<button
|
|
18
|
+
className="root_outOfStock"
|
|
19
|
+
disabled={true}
|
|
20
|
+
onClick={[Function]}
|
|
21
|
+
title="red"
|
|
22
|
+
type="button"
|
|
23
|
+
>
|
|
24
|
+
<span>
|
|
25
|
+
red
|
|
26
|
+
</span>
|
|
27
|
+
</button>
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
exports[`appends "_outOfStock" to className if isOptionOutOfStock is true 1`] = `
|
|
31
|
+
<button
|
|
32
|
+
className="root_outOfStock"
|
|
33
|
+
disabled={true}
|
|
34
|
+
onClick={[Function]}
|
|
35
|
+
title="red"
|
|
36
|
+
type="button"
|
|
37
|
+
>
|
|
38
|
+
<span>
|
|
39
|
+
red
|
|
40
|
+
</span>
|
|
41
|
+
</button>
|
|
42
|
+
`;
|
|
43
|
+
|
|
16
44
|
exports[`appends "_selected" to className if isSelected is true 1`] = `
|
|
17
45
|
<button
|
|
18
46
|
className="root_selected"
|
|
@@ -27,6 +27,10 @@ test('renders a Swatch correctly', () => {
|
|
|
27
27
|
expect(component.root.findByType('button').props.className).not.toContain(
|
|
28
28
|
'_focused'
|
|
29
29
|
);
|
|
30
|
+
|
|
31
|
+
expect(component.root.findByType('button').props.className).not.toContain(
|
|
32
|
+
'_outOfStock'
|
|
33
|
+
);
|
|
30
34
|
expect(component).toMatchSnapshot();
|
|
31
35
|
});
|
|
32
36
|
|
|
@@ -59,6 +63,34 @@ test('appends "_focused" to className if hasFocus is true', () => {
|
|
|
59
63
|
expect(component).toMatchSnapshot();
|
|
60
64
|
});
|
|
61
65
|
|
|
66
|
+
test('appends "_outOfStock" to className if isEverythingOutOfStock is true', () => {
|
|
67
|
+
const props = {
|
|
68
|
+
...defaultProps,
|
|
69
|
+
isEverythingOutOfStock: true
|
|
70
|
+
};
|
|
71
|
+
const component = testRenderer.create(<Swatch {...props} />);
|
|
72
|
+
|
|
73
|
+
expect(component.root.findByType('button').props.className).toContain(
|
|
74
|
+
'_outOfStock'
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(component).toMatchSnapshot();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('appends "_outOfStock" to className if isOptionOutOfStock is true', () => {
|
|
81
|
+
const props = {
|
|
82
|
+
...defaultProps,
|
|
83
|
+
isOptionOutOfStock: true
|
|
84
|
+
};
|
|
85
|
+
const component = testRenderer.create(<Swatch {...props} />);
|
|
86
|
+
|
|
87
|
+
expect(component.root.findByType('button').props.className).toContain(
|
|
88
|
+
'_outOfStock'
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
expect(component).toMatchSnapshot();
|
|
92
|
+
});
|
|
93
|
+
|
|
62
94
|
test('renders an icon if isSelected is true', () => {
|
|
63
95
|
const props = {
|
|
64
96
|
...defaultProps,
|
|
@@ -70,3 +102,23 @@ test('renders an icon if isSelected is true', () => {
|
|
|
70
102
|
expect(() => component.root.findByType(Icon)).not.toThrow();
|
|
71
103
|
expect(component).toMatchSnapshot();
|
|
72
104
|
});
|
|
105
|
+
|
|
106
|
+
test('button is disabled if isEverythingOutOfStock is true', () => {
|
|
107
|
+
const props = {
|
|
108
|
+
...defaultProps,
|
|
109
|
+
isEverythingOutOfStock: true
|
|
110
|
+
};
|
|
111
|
+
const component = testRenderer.create(<Swatch {...props} />);
|
|
112
|
+
|
|
113
|
+
expect(component.root.findByType('button').props.disabled).toBeTruthy;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('button is disabled if isOptionOutOfStock is true', () => {
|
|
117
|
+
const props = {
|
|
118
|
+
...defaultProps,
|
|
119
|
+
isOptionOutOfStock: true
|
|
120
|
+
};
|
|
121
|
+
const component = testRenderer.create(<Swatch {...props} />);
|
|
122
|
+
|
|
123
|
+
expect(component.root.findByType('button').props.disabled).toBeTruthy;
|
|
124
|
+
});
|
|
@@ -54,3 +54,51 @@ test('appends "_focused" to className if hasFocus is true', () => {
|
|
|
54
54
|
|
|
55
55
|
expect(component).toMatchSnapshot();
|
|
56
56
|
});
|
|
57
|
+
|
|
58
|
+
test('appends "_outOfStock" to className if isEverythingOutOfStock is true', () => {
|
|
59
|
+
const props = {
|
|
60
|
+
...defaultProps,
|
|
61
|
+
isEverythingOutOfStock: true
|
|
62
|
+
};
|
|
63
|
+
const component = testRenderer.create(<Tile {...props} />);
|
|
64
|
+
|
|
65
|
+
expect(component.root.findByType('button').props.className).toContain(
|
|
66
|
+
'_outOfStock'
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
expect(component).toMatchSnapshot();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('appends "_outOfStock" to className if isOptionOutOfStock is true', () => {
|
|
73
|
+
const props = {
|
|
74
|
+
...defaultProps,
|
|
75
|
+
isOptionOutOfStock: true
|
|
76
|
+
};
|
|
77
|
+
const component = testRenderer.create(<Tile {...props} />);
|
|
78
|
+
|
|
79
|
+
expect(component.root.findByType('button').props.className).toContain(
|
|
80
|
+
'_outOfStock'
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
expect(component).toMatchSnapshot();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('button is disabled if isEverythingOutOfStock is true', () => {
|
|
87
|
+
const props = {
|
|
88
|
+
...defaultProps,
|
|
89
|
+
isEverythingOutOfStock: true
|
|
90
|
+
};
|
|
91
|
+
const component = testRenderer.create(<Tile {...props} />);
|
|
92
|
+
|
|
93
|
+
expect(component.root.findByType('button').props.disabled).toBeTruthy;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('button is disabled if isOptionOutOfStock is true', () => {
|
|
97
|
+
const props = {
|
|
98
|
+
...defaultProps,
|
|
99
|
+
isOptionOutOfStock: true
|
|
100
|
+
};
|
|
101
|
+
const component = testRenderer.create(<Tile {...props} />);
|
|
102
|
+
|
|
103
|
+
expect(component.root.findByType('button').props.disabled).toBeTruthy;
|
|
104
|
+
});
|
|
@@ -34,7 +34,9 @@ const Option = props => {
|
|
|
34
34
|
label,
|
|
35
35
|
onSelectionChange,
|
|
36
36
|
selectedValue,
|
|
37
|
-
values
|
|
37
|
+
values,
|
|
38
|
+
isEverythingOutOfStock,
|
|
39
|
+
outOfStockVariants
|
|
38
40
|
} = props;
|
|
39
41
|
|
|
40
42
|
const talonProps = useOption({
|
|
@@ -66,6 +68,8 @@ const Option = props => {
|
|
|
66
68
|
selectedValue={initialSelection}
|
|
67
69
|
items={values}
|
|
68
70
|
onSelectionChange={handleSelectionChange}
|
|
71
|
+
isEverythingOutOfStock={isEverythingOutOfStock}
|
|
72
|
+
outOfStockVariants={outOfStockVariants}
|
|
69
73
|
/>
|
|
70
74
|
<dl className={classes.selection}>
|
|
71
75
|
<dt
|
|
@@ -5,11 +5,19 @@ import Option from './option';
|
|
|
5
5
|
import { useOptions } from '@magento/peregrine/lib/talons/ProductOptions/useOptions';
|
|
6
6
|
|
|
7
7
|
const Options = props => {
|
|
8
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
classes,
|
|
10
|
+
onSelectionChange,
|
|
11
|
+
options,
|
|
12
|
+
selectedValues = [],
|
|
13
|
+
isEverythingOutOfStock,
|
|
14
|
+
outOfStockVariants
|
|
15
|
+
} = props;
|
|
9
16
|
|
|
10
17
|
const talonProps = useOptions({
|
|
11
18
|
onSelectionChange,
|
|
12
|
-
selectedValues
|
|
19
|
+
selectedValues,
|
|
20
|
+
options
|
|
13
21
|
});
|
|
14
22
|
|
|
15
23
|
const { handleSelectionChange, selectedValueMap } = talonProps;
|
|
@@ -22,6 +30,8 @@ const Options = props => {
|
|
|
22
30
|
key={option.attribute_id}
|
|
23
31
|
onSelectionChange={handleSelectionChange}
|
|
24
32
|
selectedValue={selectedValueMap.get(option.label)}
|
|
33
|
+
isEverythingOutOfStock={isEverythingOutOfStock}
|
|
34
|
+
outOfStockVariants={outOfStockVariants}
|
|
25
35
|
/>
|
|
26
36
|
));
|
|
27
37
|
};
|
|
@@ -18,8 +18,16 @@ import defaultClasses from './swatch.module.css';
|
|
|
18
18
|
|
|
19
19
|
import { useSwatch } from '@magento/peregrine/lib/talons/ProductOptions/useSwatch';
|
|
20
20
|
|
|
21
|
-
const getClassName = (
|
|
22
|
-
|
|
21
|
+
const getClassName = (
|
|
22
|
+
name,
|
|
23
|
+
isSelected,
|
|
24
|
+
hasFocus,
|
|
25
|
+
isOptionOutOfStock,
|
|
26
|
+
isEverythingOutOfStock
|
|
27
|
+
) =>
|
|
28
|
+
`${name}${isSelected ? '_selected' : ''}${hasFocus ? '_focused' : ''}${
|
|
29
|
+
isEverythingOutOfStock || isOptionOutOfStock ? '_outOfStock' : ''
|
|
30
|
+
}`;
|
|
23
31
|
|
|
24
32
|
// Swatches _must_ have a 1x1 aspect ratio to match the UI.
|
|
25
33
|
const SWATCH_WIDTH = 48;
|
|
@@ -30,7 +38,9 @@ const Swatch = props => {
|
|
|
30
38
|
isSelected,
|
|
31
39
|
item: { label, value_index, swatch_data },
|
|
32
40
|
onClick,
|
|
33
|
-
style
|
|
41
|
+
style,
|
|
42
|
+
isEverythingOutOfStock,
|
|
43
|
+
isOptionOutOfStock
|
|
34
44
|
} = props;
|
|
35
45
|
|
|
36
46
|
const talonProps = useSwatch({
|
|
@@ -74,7 +84,16 @@ const Swatch = props => {
|
|
|
74
84
|
});
|
|
75
85
|
}
|
|
76
86
|
|
|
77
|
-
const className =
|
|
87
|
+
const className =
|
|
88
|
+
classes[
|
|
89
|
+
getClassName(
|
|
90
|
+
'root',
|
|
91
|
+
isSelected,
|
|
92
|
+
hasFocus,
|
|
93
|
+
isOptionOutOfStock,
|
|
94
|
+
isEverythingOutOfStock
|
|
95
|
+
)
|
|
96
|
+
];
|
|
78
97
|
|
|
79
98
|
return (
|
|
80
99
|
<button
|
|
@@ -84,8 +103,11 @@ const Swatch = props => {
|
|
|
84
103
|
title={label}
|
|
85
104
|
type="button"
|
|
86
105
|
data-cy="Swatch-root"
|
|
106
|
+
disabled={isEverythingOutOfStock || isOptionOutOfStock}
|
|
87
107
|
>
|
|
88
|
-
|
|
108
|
+
{!isOptionOutOfStock && (
|
|
109
|
+
<Icon classes={{ root: checkStyle }} src={CheckIcon} />
|
|
110
|
+
)}
|
|
89
111
|
</button>
|
|
90
112
|
);
|
|
91
113
|
};
|
|
@@ -36,3 +36,20 @@
|
|
|
36
36
|
composes: checked;
|
|
37
37
|
opacity: 0;
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
.root_outOfStock,
|
|
41
|
+
.root_selected_outOfStock {
|
|
42
|
+
composes: root;
|
|
43
|
+
composes: opacity-40 from global;
|
|
44
|
+
composes: border-2 from global;
|
|
45
|
+
composes: border-solid from global;
|
|
46
|
+
composes: border-gray-400 from global;
|
|
47
|
+
}
|
|
48
|
+
.root_outOfStock:after,
|
|
49
|
+
.root_selected_outOfStock:after {
|
|
50
|
+
content: '';
|
|
51
|
+
position: absolute;
|
|
52
|
+
border-top: 2px solid rgb(var(--venia-global-color-gray-400));
|
|
53
|
+
width: 62px;
|
|
54
|
+
transform: rotate(-45deg);
|
|
55
|
+
}
|
|
@@ -6,25 +6,46 @@ import { useStyle } from '../../classify';
|
|
|
6
6
|
import defaultClasses from './swatchList.module.css';
|
|
7
7
|
|
|
8
8
|
const SwatchList = props => {
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
getItemKey,
|
|
11
|
+
selectedValue = {},
|
|
12
|
+
items,
|
|
13
|
+
onSelectionChange,
|
|
14
|
+
isEverythingOutOfStock,
|
|
15
|
+
outOfStockVariants
|
|
16
|
+
} = props;
|
|
10
17
|
|
|
11
18
|
const classes = useStyle(defaultClasses, props.classes);
|
|
12
|
-
|
|
13
19
|
const swatches = useMemo(
|
|
14
20
|
() =>
|
|
15
21
|
items.map(item => {
|
|
16
22
|
const isSelected = item.label === selectedValue.label;
|
|
17
|
-
|
|
23
|
+
let isOptionOutOfStock;
|
|
24
|
+
if (outOfStockVariants && outOfStockVariants.length > 0) {
|
|
25
|
+
const flatOutOfStockArray = outOfStockVariants.flat();
|
|
26
|
+
isOptionOutOfStock = flatOutOfStockArray.includes(
|
|
27
|
+
item.value_index
|
|
28
|
+
);
|
|
29
|
+
}
|
|
18
30
|
return (
|
|
19
31
|
<Swatch
|
|
20
32
|
key={getItemKey(item)}
|
|
21
33
|
isSelected={isSelected}
|
|
22
34
|
item={item}
|
|
23
35
|
onClick={onSelectionChange}
|
|
36
|
+
isEverythingOutOfStock={isEverythingOutOfStock}
|
|
37
|
+
isOptionOutOfStock={isOptionOutOfStock}
|
|
24
38
|
/>
|
|
25
39
|
);
|
|
26
40
|
}),
|
|
27
|
-
[
|
|
41
|
+
[
|
|
42
|
+
getItemKey,
|
|
43
|
+
selectedValue.label,
|
|
44
|
+
items,
|
|
45
|
+
onSelectionChange,
|
|
46
|
+
isEverythingOutOfStock,
|
|
47
|
+
outOfStockVariants
|
|
48
|
+
]
|
|
28
49
|
);
|
|
29
50
|
|
|
30
51
|
return <div className={classes.root}>{swatches}</div>;
|
|
@@ -5,15 +5,25 @@ import { useStyle } from '../../classify';
|
|
|
5
5
|
import defaultClasses from './tile.module.css';
|
|
6
6
|
import { useTile } from '@magento/peregrine/lib/talons/ProductOptions/useTile';
|
|
7
7
|
|
|
8
|
-
const getClassName = (
|
|
9
|
-
|
|
8
|
+
const getClassName = (
|
|
9
|
+
name,
|
|
10
|
+
isSelected,
|
|
11
|
+
hasFocus,
|
|
12
|
+
isOptionOutOfStock,
|
|
13
|
+
isEverythingOutOfStock
|
|
14
|
+
) =>
|
|
15
|
+
`${name}${isSelected ? '_selected' : ''}${hasFocus ? '_focused' : ''}${
|
|
16
|
+
isEverythingOutOfStock || isOptionOutOfStock ? '_outOfStock' : ''
|
|
17
|
+
}`;
|
|
10
18
|
|
|
11
19
|
const Tile = props => {
|
|
12
20
|
const {
|
|
13
21
|
hasFocus,
|
|
14
22
|
isSelected,
|
|
15
23
|
item: { label, value_index },
|
|
16
|
-
onClick
|
|
24
|
+
onClick,
|
|
25
|
+
isEverythingOutOfStock,
|
|
26
|
+
isOptionOutOfStock
|
|
17
27
|
} = props;
|
|
18
28
|
|
|
19
29
|
const talonProps = useTile({
|
|
@@ -22,9 +32,17 @@ const Tile = props => {
|
|
|
22
32
|
});
|
|
23
33
|
|
|
24
34
|
const { handleClick } = talonProps;
|
|
25
|
-
|
|
26
35
|
const classes = useStyle(defaultClasses, props.classes);
|
|
27
|
-
const className =
|
|
36
|
+
const className =
|
|
37
|
+
classes[
|
|
38
|
+
getClassName(
|
|
39
|
+
'root',
|
|
40
|
+
isSelected,
|
|
41
|
+
hasFocus,
|
|
42
|
+
isOptionOutOfStock,
|
|
43
|
+
isEverythingOutOfStock
|
|
44
|
+
)
|
|
45
|
+
];
|
|
28
46
|
|
|
29
47
|
return (
|
|
30
48
|
<button
|
|
@@ -33,6 +51,7 @@ const Tile = props => {
|
|
|
33
51
|
title={label}
|
|
34
52
|
type="button"
|
|
35
53
|
data-cy="Tile-button"
|
|
54
|
+
disabled={isEverythingOutOfStock || isOptionOutOfStock}
|
|
36
55
|
>
|
|
37
56
|
<span>{label}</span>
|
|
38
57
|
</button>
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
composes: px-2xs from global;
|
|
10
10
|
composes: py-0 from global;
|
|
11
11
|
composes: rounded-sm from global;
|
|
12
|
+
position: relative;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
.root_selected {
|
|
@@ -25,3 +26,22 @@
|
|
|
25
26
|
.root_selected_focused {
|
|
26
27
|
composes: root_selected;
|
|
27
28
|
}
|
|
29
|
+
|
|
30
|
+
.root_outOfStock,
|
|
31
|
+
.root_selected_outOfStock {
|
|
32
|
+
composes: root;
|
|
33
|
+
composes: bg-disabledTile from global;
|
|
34
|
+
composes: opacity-50 from global;
|
|
35
|
+
composes: border-2 from global;
|
|
36
|
+
composes: border-solid from global;
|
|
37
|
+
composes: border-gray-400 from global;
|
|
38
|
+
composes: text-gray-600 from global;
|
|
39
|
+
}
|
|
40
|
+
.root_outOfStock:after,
|
|
41
|
+
.root_selected_outOfStock:after {
|
|
42
|
+
content: '';
|
|
43
|
+
position: absolute;
|
|
44
|
+
border-top: 2px solid rgb(var(--venia-global-color-gray-400));
|
|
45
|
+
width: 62px;
|
|
46
|
+
transform: rotate(-45deg);
|
|
47
|
+
}
|
|
@@ -6,7 +6,14 @@ import { useStyle } from '../../classify';
|
|
|
6
6
|
import defaultClasses from './tileList.module.css';
|
|
7
7
|
|
|
8
8
|
const TileList = props => {
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
getItemKey,
|
|
11
|
+
selectedValue = {},
|
|
12
|
+
items,
|
|
13
|
+
onSelectionChange,
|
|
14
|
+
isEverythingOutOfStock,
|
|
15
|
+
outOfStockVariants
|
|
16
|
+
} = props;
|
|
10
17
|
|
|
11
18
|
const classes = useStyle(defaultClasses, props.classes);
|
|
12
19
|
|
|
@@ -14,6 +21,13 @@ const TileList = props => {
|
|
|
14
21
|
() =>
|
|
15
22
|
items.map(item => {
|
|
16
23
|
const isSelected = item.label === selectedValue.label;
|
|
24
|
+
let isOptionOutOfStock;
|
|
25
|
+
if (outOfStockVariants && outOfStockVariants.length > 0) {
|
|
26
|
+
const flatOutOfStockArray = outOfStockVariants.flat();
|
|
27
|
+
isOptionOutOfStock = flatOutOfStockArray.includes(
|
|
28
|
+
item.value_index
|
|
29
|
+
);
|
|
30
|
+
}
|
|
17
31
|
|
|
18
32
|
return (
|
|
19
33
|
<Tile
|
|
@@ -21,10 +35,19 @@ const TileList = props => {
|
|
|
21
35
|
isSelected={isSelected}
|
|
22
36
|
item={item}
|
|
23
37
|
onClick={onSelectionChange}
|
|
38
|
+
isEverythingOutOfStock={isEverythingOutOfStock}
|
|
39
|
+
isOptionOutOfStock={isOptionOutOfStock}
|
|
24
40
|
/>
|
|
25
41
|
);
|
|
26
42
|
}),
|
|
27
|
-
[
|
|
43
|
+
[
|
|
44
|
+
getItemKey,
|
|
45
|
+
selectedValue.label,
|
|
46
|
+
items,
|
|
47
|
+
onSelectionChange,
|
|
48
|
+
isEverythingOutOfStock,
|
|
49
|
+
outOfStockVariants
|
|
50
|
+
]
|
|
28
51
|
);
|
|
29
52
|
|
|
30
53
|
return <div className={classes.root}>{tiles}</div>;
|