Skip to content

Commit 907435b

Browse files
authored
Merge pull request #1031 from rebecastilho/fix/sortVariations
sort variations options sku selector
2 parents 72e0808 + c911636 commit 907435b

File tree

7 files changed

+621
-10
lines changed

7 files changed

+621
-10
lines changed

docs/SKUSelector.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ The `sku-selector` block is mainly used in Product Details Pages (PDPs) to displ
4949
| `disableUnavailableSelectOptions` | `boolean` | Whether a product variation that leads to an impossible product combination should be displayed with the disabled attribute when `displayMode` is set to `select`. By default, all select options are without the disabled attribute set based on the type of variation | `false` |
5050
| `displayMode` | `enum` | Defines how the product variation names will be displayed (it doesn't apply to product variation images). Possible values are: `default` (displays all variation names), `select` (only displays the selected variation name) or `slider` (displays all variation names in a slider when the number of available options in greater than the value defined in the `sliderDisplayThreshold` prop). Notice that this prop is _responsive_, so you can declare an object as its value specifying a value for each breakpoint (`desktop` and `mobile`). | `default` |
5151
| `hideImpossibleCombinations` | `boolean` | Defines if a product variation should be clickable (`true`) or not (`false`). If `true`, the variation won't be displayed. If `false`, the variation is displayed with less opacity. For example, there are two colors for a pair of sneakers: pink and white, and if the pink sneaker is available for only one size, the other sizes won't be displayed (`true`).| `true` |
52+
| `sortVariationsByLabel` | `boolean` | Defines if the variations are to be sorted in alphabetical order.| `false` |
5253
| `imageHeight` | `number` | `object` | Height (in `px`) of the product thumbnail image. You can declare an object as its value in case you want to define a height for each device (`desktop` and `mobile`). | `undefined` |
5354
| `imageWidth` | `number` | `object` | Width (in `px`) of the product thumbnail image. You can declare an object as its value in case you want to define a width for each device (`desktop` and `mobile`). | `undefined` |
5455
| `initialSelection` | `enum` | Controls the user initial selection for available variations when product page is fully loaded. Possible values are: `complete` (selects the first available SKU's variation values), `image` (selects the first available image variation) or `empty` (no variations will be selected when the page is loaded). | `complete` |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@
3939
"resolutions": {
4040
"glob-parent": "^6.0.1"
4141
}
42-
}
42+
}

react/__tests__/components/SKUSelector.test.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,4 +1408,54 @@ describe('<SKUSelector />', () => {
14081408

14091409
expect(queryByText('Yellow')).toBeFalsy()
14101410
})
1411+
1412+
it('must order sku specification to be sorted in alphabetical order', async () => {
1413+
const skuItems = [
1414+
{
1415+
itemId: '1',
1416+
name: 'Gray Shoe',
1417+
variations: [
1418+
{ name: 'Size', values: ['43'] },
1419+
{ name: 'Color', values: ['Gray'] },
1420+
],
1421+
images: [],
1422+
},
1423+
{
1424+
itemId: '4',
1425+
name: 'Gray Shoe',
1426+
variations: [
1427+
{
1428+
name: 'Size',
1429+
values: ['42'],
1430+
},
1431+
{ name: 'Color', values: ['Gray'] },
1432+
],
1433+
images: [],
1434+
},
1435+
{
1436+
itemId: '4',
1437+
name: 'Gray Shoe',
1438+
variations: [
1439+
{
1440+
name: 'Size',
1441+
values: ['41'],
1442+
},
1443+
{ name: 'Color', values: ['Gray'] },
1444+
],
1445+
images: [],
1446+
},
1447+
]
1448+
1449+
const { container } = renderComponent({
1450+
sortVariationsByLabel: true,
1451+
skuSelected: skuItems[0],
1452+
skuItems,
1453+
})
1454+
1455+
const options = container.querySelectorAll('.skuSelectorItemTextValue')
1456+
1457+
expect(options[0]).toHaveTextContent('41')
1458+
expect(options[1]).toHaveTextContent('42')
1459+
expect(options[2]).toHaveTextContent('43')
1460+
})
14111461
})

react/components/SKUSelector/Wrapper.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ interface Props {
169169
sliderDisplayThreshold?: number
170170
sliderArrowSize?: number
171171
sliderItemsPerPage?: ResponsiveValuesTypes.ResponsiveValue<number>
172+
sortVariationsByLabel?: boolean
172173
/** Used to override default CSS handles */
173174
classes?: CssHandlesTypes.CustomClasses<typeof SKU_SELECTOR_CSS_HANDLES>
174175
}
@@ -260,6 +261,7 @@ function SKUSelectorWrapper(props: Props) {
260261
sliderItemsPerPage={props.sliderItemsPerPage}
261262
sliderArrowSize={props.sliderArrowSize}
262263
sliderDisplayThreshold={props.sliderDisplayThreshold}
264+
sortVariationsByLabel={props.sortVariationsByLabel}
263265
/>
264266
</SKUSelectorCssHandlesProvider>
265267
)

react/components/SKUSelector/components/SKUSelector.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ interface Props {
6767
sliderDisplayThreshold: number
6868
sliderArrowSize: number
6969
sliderItemsPerPage: ResponsiveValuesTypes.ResponsiveValue<number>
70+
sortVariationsByLabel?: boolean
7071
}
7172

7273
function isSkuAvailable(item?: SelectorProductItem) {
@@ -117,6 +118,7 @@ interface AvailableVariationParams {
117118
skuItems: SelectorProductItem[]
118119
hideImpossibleCombinations: boolean
119120
disableUnavailableSelectOptions: boolean
121+
sortVariationsByLabel: boolean
120122
}
121123

122124
const parseOptionNameToDisplayOption =
@@ -212,6 +214,7 @@ const variationNameToDisplayVariation =
212214
variationCount,
213215
hideImpossibleCombinations,
214216
disableUnavailableSelectOptions,
217+
sortVariationsByLabel,
215218
}: {
216219
variations: Variations
217220
selectedVariations: SelectedVariations
@@ -221,6 +224,7 @@ const variationNameToDisplayVariation =
221224
variationCount: number
222225
hideImpossibleCombinations: boolean
223226
disableUnavailableSelectOptions: boolean
227+
sortVariationsByLabel: boolean
224228
}) =>
225229
(variationName: string): DisplayVariation => {
226230
const name = variationName
@@ -240,6 +244,12 @@ const variationNameToDisplayVariation =
240244
)
241245
.filter(Boolean) as DisplayOption[]
242246

247+
if (sortVariationsByLabel) {
248+
options.sort((a, b) => {
249+
return a.label < b.label ? -1 : a.label > b.label ? 1 : 0
250+
})
251+
}
252+
243253
return { name, originalName, options }
244254
}
245255

@@ -252,6 +262,7 @@ const getAvailableVariations = ({
252262
skuItems,
253263
hideImpossibleCombinations,
254264
disableUnavailableSelectOptions,
265+
sortVariationsByLabel,
255266
}: AvailableVariationParams): DisplayVariation[] => {
256267
const variationCount = Object.keys(variations).length
257268

@@ -265,6 +276,7 @@ const getAvailableVariations = ({
265276
variationCount,
266277
hideImpossibleCombinations,
267278
disableUnavailableSelectOptions,
279+
sortVariationsByLabel,
268280
})
269281
)
270282
}
@@ -303,6 +315,7 @@ function SKUSelector({
303315
sliderDisplayThreshold,
304316
sliderArrowSize,
305317
sliderItemsPerPage,
318+
sortVariationsByLabel = false,
306319
}: Props) {
307320
const { handles } = useSKUSelectorCssHandles()
308321
const variationsSpacing = getValidMarginBottom(marginBottomProp)
@@ -334,6 +347,7 @@ function SKUSelector({
334347
skuItems,
335348
hideImpossibleCombinations,
336349
disableUnavailableSelectOptions,
350+
sortVariationsByLabel,
337351
}),
338352
[
339353
variations,
@@ -343,6 +357,7 @@ function SKUSelector({
343357
skuItems,
344358
hideImpossibleCombinations,
345359
disableUnavailableSelectOptions,
360+
sortVariationsByLabel,
346361
]
347362
)
348363

react/components/SKUSelector/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ interface Props {
186186
sliderDisplayThreshold?: number
187187
sliderArrowSize?: number
188188
sliderItemsPerPage?: ResponsiveValuesTypes.ResponsiveValue<number>
189+
sortVariationsByLabel?: boolean
189190
}
190191

191192
const getNewSelectedVariations = (
@@ -247,6 +248,7 @@ const SKUSelectorContainer: FC<Props> = ({
247248
initialSelection = 'complete',
248249
sliderDisplayThreshold = 3,
249250
sliderArrowSize = 12,
251+
sortVariationsByLabel = false,
250252
sliderItemsPerPage = {
251253
desktop: 3,
252254
tablet: 2,
@@ -422,6 +424,7 @@ const SKUSelectorContainer: FC<Props> = ({
422424
sliderDisplayThreshold={sliderDisplayThreshold}
423425
sliderArrowSize={sliderArrowSize}
424426
sliderItemsPerPage={sliderItemsPerPage}
427+
sortVariationsByLabel={sortVariationsByLabel}
425428
/>
426429
)
427430
}

0 commit comments

Comments
 (0)