Skip to content

Commit

Permalink
feat(Combo): Add support for groupingDirection: none.
Browse files Browse the repository at this point in the history
Remove the sorting of the items when combo has
grouping.
  • Loading branch information
mddragnev committed Jan 15, 2024
1 parent 9b26cc2 commit 7e541ad
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 16 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [4.8.0]
### Added
- Combo component can now set `groupSorting` to `none` which shows the groups in the order of the provided data.

### Changed
- Grouping in Combo component no longer sorts the data. `groupSorting` property now affects the sorting direction only of the groups.
**Behavioral change**
In previous release the sorting directions of the groups sorted the items as well. If you want to achieve this behavior you can pass already sorted data to the Combo component.

## [4.7.0] - 2024-01-05
### Added
- Tree - Added **`toggleNodeOnClick`** property that determines whether clicking over a node will change its expanded state or not. Defaults to `false`. [#1003](https://github.com/IgniteUI/igniteui-webcomponents/pull/1003).
Expand Down
113 changes: 102 additions & 11 deletions src/components/combo/combo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { elementUpdated, expect, fixture } from '@open-wc/testing';
import { html } from 'lit';
import { spy } from 'sinon';

import IgcComboHeaderComponent from './combo-header.js';
import IgcComboItemComponent from './combo-item.js';
import IgcComboListComponent from './combo-list.js';
import IgcComboComponent from './combo.js';
Expand Down Expand Up @@ -59,6 +60,63 @@ describe('Combo', () => {
},
];

const citiesWithDiacritics = [
{
id: 'US01',
name: 'New York',
country: 'Méxícó',
zip: '10001',
},
{
id: 'JP01',
name: 'Tokyo',
country: 'Ángel',
zip: '163-8001',
},
{
id: 'US02',
name: 'Boston',
country: 'Méxícó',
zip: '02108',
},
{
id: 'US03',
name: 'San Francisco',
country: 'Méxícó',
zip: '94103',
},
{
id: 'JP02',
name: 'Yokohama',
country: 'Ángel',
zip: '781-0240',
},
{
id: 'JP03',
name: 'Osaka',
country: 'Ángel',
zip: '552-0021',
},
{
id: 'BG01',
name: 'diakritikós',
country: 'México',
zip: '1000',
},
{
id: 'BG02',
name: 'coöperate',
country: 'México',
zip: '4000',
},
{
id: 'BG03',
name: 'Muğams',
country: 'México',
zip: '9000',
},
];

const primitive = [
0,
'Sofia',
Expand Down Expand Up @@ -88,6 +146,12 @@ describe('Combo', () => {
await Promise.all([elementUpdated(combo), list.layoutComplete]);
};

const headerItems = <T extends object>(combo: IgcComboComponent<T>) =>
[
...combo
.shadowRoot!.querySelector('igc-combo-list')!
.querySelectorAll('[part~="group-header"]'),
] as IgcComboHeaderComponent[];
before(() => {
defineComponents(IgcComboComponent);
});
Expand Down Expand Up @@ -419,8 +483,8 @@ describe('Combo', () => {
const args = {
cancelable: true,
detail: {
newValue: ['BG02'],
items: [cities[1]],
newValue: ['BG01'],
items: [cities[0]],
type: 'selection',
},
};
Expand All @@ -430,7 +494,7 @@ describe('Combo', () => {
await list.layoutComplete;

items(combo)[0].click();
expect(combo.value).to.deep.equal(['BG02']);
expect(combo.value).to.deep.equal(['BG01']);
expect(eventSpy).calledWithExactly('igcChange', args);
});

Expand All @@ -439,8 +503,8 @@ describe('Combo', () => {
const args = {
cancelable: true,
detail: {
newValue: ['BG01', 'BG03'],
items: [cities[1]],
newValue: ['BG02', 'BG03'],
items: [cities[0]],
type: 'deselection',
},
};
Expand All @@ -454,7 +518,7 @@ describe('Combo', () => {

items(combo)[0].click();
await elementUpdated(combo);
expect(combo.value).to.deep.equal(['BG01', 'BG03']);
expect(combo.value).to.deep.equal(['BG02', 'BG03']);

expect(eventSpy).calledWithExactly('igcChange', args);
});
Expand Down Expand Up @@ -783,16 +847,16 @@ describe('Combo', () => {
await elementUpdated(combo);
await list.layoutComplete;

expect(items(combo)[0].selected).to.be.true;
expect(items(combo)[1].selected).to.be.true;

pressKey(options, 'ArrowDown');
pressKey(options, 'ArrowDown', 2);
pressKey(options, ' ');

await elementUpdated(combo);
await list.layoutComplete;

expect(items(combo)[0].selected).to.be.false;
expect(items(combo)[1].selected).to.be.true;
expect(items(combo)[1].selected).to.be.false;
expect(items(combo)[2].selected).to.be.true;
});

it('should clear selection upon changing the search term via input', async () => {
Expand All @@ -814,7 +878,7 @@ describe('Combo', () => {
await elementUpdated(combo);
await list.layoutComplete;

expect(items(combo)[0].selected).to.be.true;
expect(items(combo)[1].selected).to.be.true;
expect(combo.value).to.deep.equal(['BG02']);

await filterCombo('sof');
Expand Down Expand Up @@ -1117,6 +1181,33 @@ describe('Combo', () => {
expect(combo.selection[0]).to.equal(cities[3]);
expect(combo.selection[1]).to.equal(cities[4]);
});

it('should sort groups with diacritics and none as groupSorting direction', async () => {
combo.data = citiesWithDiacritics;
combo.groupSorting = 'asc';
combo.open = true;
await elementUpdated(combo);
await list.layoutComplete;

let comboHeadersLabel = headerItems(combo).map(
(header) => header.innerText
);
expect(comboHeadersLabel).to.eql(['Ángel', 'México', 'Méxícó']);

combo.groupSorting = 'desc';
await elementUpdated(combo);
await list.layoutComplete;

comboHeadersLabel = headerItems(combo).map((header) => header.innerText);
expect(comboHeadersLabel).to.eql(['Méxícó', 'México', 'Ángel']);

combo.groupSorting = 'none';
await elementUpdated(combo);
await list.layoutComplete;

comboHeadersLabel = headerItems(combo).map((header) => header.innerText);
expect(comboHeadersLabel).to.eql(['Méxícó', 'Ángel', 'México']);
});
});

describe('Form integration', () => {
Expand Down
10 changes: 6 additions & 4 deletions src/components/combo/operations/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ export default class GroupDataOperation<T extends object> {
groupBy(data, (item) => item.value[groupKey] ?? 'Other')
);

return groups.flatMap(([group, items]) => {
items.sort((a, b) =>
this.compareObjects(a.value, b.value, displayKey!, direction)
);
if (direction !== 'none') {
groups.sort((a, b) => {
return this.orderBy.get(direction)! * a[0].localeCompare(b[0]);
});
}

return groups.flatMap(([group, items]) => {
items.unshift({
dataIndex: -1,
header: true,
Expand Down
2 changes: 1 addition & 1 deletion src/components/combo/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type ComboRecord<T extends object> = {
export type ComboHost<T extends object> = ReactiveControllerHost &
IgcComboComponent<T>;

export type GroupingDirection = 'asc' | 'desc';
export type GroupingDirection = 'asc' | 'desc' | 'none';
export type ComboChangeType = 'selection' | 'deselection' | 'addition';
export type ComboRenderFunction<T extends object> = RenderItemFunction<
ComboRecord<T>
Expand Down

0 comments on commit 7e541ad

Please sign in to comment.