Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into benelan/8057-input-me…
Browse files Browse the repository at this point in the history
…ssage

* origin/main:
  chore: release next
  feat(list): support multiple selection using the shift key (#8301)
  docs(shell-panel): remove incorrect information from heightScale prop (#8302)
  • Loading branch information
benelan committed Nov 30, 2023
2 parents 100aa27 + aacca51 commit 5413643
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 17 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.12.0-next.4](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-angular@1.12.0-next.3...@esri/calcite-components-angular@1.12.0-next.4) (2023-11-30)

**Note:** Version bump only for package @esri/calcite-components-angular

## [1.12.0-next.3](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-angular@1.12.0-next.2...@esri/calcite-components-angular@1.12.0-next.3) (2023-11-30)

**Note:** Version bump only for package @esri/calcite-components-angular
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@esri/calcite-components-angular",
"version": "1.12.0-next.3",
"version": "1.12.0-next.4",
"sideEffects": false,
"homepage": "https://developers.arcgis.com/calcite-design-system/",
"description": "A set of Angular components that wrap Esri's Calcite Components.",
Expand All @@ -20,7 +20,7 @@
"@angular/core": ">=16.0.0"
},
"dependencies": {
"@esri/calcite-components": "^1.12.0-next.3",
"@esri/calcite-components": "^1.12.0-next.4",
"tslib": "2.3.0"
},
"lerna": {
Expand Down
4 changes: 4 additions & 0 deletions packages/calcite-components-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.12.0-next.4](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@1.12.0-next.3...@esri/calcite-components-react@1.12.0-next.4) (2023-11-30)

**Note:** Version bump only for package @esri/calcite-components-react

## [1.12.0-next.3](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components-react@1.12.0-next.2...@esri/calcite-components-react@1.12.0-next.3) (2023-11-30)

**Note:** Version bump only for package @esri/calcite-components-react
Expand Down
4 changes: 2 additions & 2 deletions packages/calcite-components-react/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@esri/calcite-components-react",
"sideEffects": false,
"version": "1.12.0-next.3",
"version": "1.12.0-next.4",
"homepage": "https://developers.arcgis.com/calcite-design-system/",
"description": "A set of React components that wrap calcite components",
"license": "SEE LICENSE.md",
Expand All @@ -20,7 +20,7 @@
"dist/"
],
"dependencies": {
"@esri/calcite-components": "^1.12.0-next.3"
"@esri/calcite-components": "^1.12.0-next.4"
},
"peerDependencies": {
"react": ">=16.7",
Expand Down
6 changes: 6 additions & 0 deletions packages/calcite-components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.12.0-next.4](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@1.12.0-next.3...@esri/calcite-components@1.12.0-next.4) (2023-11-30)

### Features

- **list:** support multiple selection using the shift key ([#8301](https://github.com/Esri/calcite-design-system/issues/8301)) ([79538be](https://github.com/Esri/calcite-design-system/commit/79538be47f87bf3e35d602a492bcb35bd8462df3)), closes [#7966](https://github.com/Esri/calcite-design-system/issues/7966)

## [1.12.0-next.3](https://github.com/Esri/calcite-design-system/compare/@esri/calcite-components@1.12.0-next.2...@esri/calcite-components@1.12.0-next.3) (2023-11-30)

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/calcite-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@esri/calcite-components",
"version": "1.12.0-next.3",
"version": "1.12.0-next.4",
"homepage": "https://developers.arcgis.com/calcite-design-system/",
"description": "Web Components for Esri's Calcite Design System.",
"main": "dist/index.cjs.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
var(--calcite-list-item-spacing-indent) * var(--calcite-list-item-spacing-indent-multiplier)
);
}

.container:hover {
@apply bg-foreground-2 cursor-pointer;
}
Expand All @@ -44,6 +45,7 @@

.content-container {
@apply text-color-2
select-none
flex
flex-auto
font-sans
Expand Down
20 changes: 16 additions & 4 deletions packages/calcite-components/src/components/list-item/list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ export class ListItem
*/
@Event({ cancelable: false }) calciteInternalListItemSelect: EventEmitter<void>;

/**
*
* @internal
*/
@Event({ cancelable: false })
calciteInternalListItemSelectMultiple: EventEmitter<{
selectMultiple: boolean;
}>;

/**
*
* @internal
Expand Down Expand Up @@ -724,16 +733,16 @@ export class ListItem
this.open = !this.open;
};

itemClicked = (event: Event): void => {
itemClicked = (event: PointerEvent): void => {
if (event.defaultPrevented) {
return;
}

this.toggleSelected();
this.toggleSelected(event.shiftKey);
this.calciteInternalListItemActive.emit();
};

toggleSelected = (): void => {
toggleSelected = (shiftKey: boolean): void => {
const { selectionMode, selected } = this;

if (this.disabled) {
Expand All @@ -746,6 +755,9 @@ export class ListItem
this.selected = true;
}

this.calciteInternalListItemSelectMultiple.emit({
selectMultiple: shiftKey && selectionMode === "multiple",
});
this.calciteListItemSelect.emit();
};

Expand All @@ -767,7 +779,7 @@ export class ListItem
!composedPath.includes(actionsEndEl)
) {
event.preventDefault();
this.toggleSelected();
this.toggleSelected(event.shiftKey);
} else if (key === "ArrowRight") {
event.preventDefault();
const nextIndex = currentIndex + 1;
Expand Down
72 changes: 72 additions & 0 deletions packages/calcite-components/src/components/list/list.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,78 @@ describe("calcite-list", () => {
expect(visibleItems.map((item) => item.id)).toEqual(["label-match", "description-match", "value-match"]);
});

it("should support shift click to select multiple items", async () => {
const clickItemContent = (item: HTMLCalciteListItemElement, selector: string) => {
item.shadowRoot.querySelector(selector).dispatchEvent(new MouseEvent("click", { bubbles: true, shiftKey: true }));
};

const page = await newE2EPage();
await page.setContent(html`<calcite-list selection-mode="multiple">
<calcite-list-item id="item-1" label="hello" description="world"></calcite-list-item>
<calcite-list-item id="item-2" label="hello 2" description="world 2"></calcite-list-item>
<calcite-list-item id="item-3" label="hello 3" description="world 3"></calcite-list-item>
<calcite-list-item id="item-4" label="hello 4" description="world 4"></calcite-list-item>
</calcite-list>`);
await page.waitForChanges();
await page.waitForTimeout(listDebounceTimeout);

const list = await page.find("calcite-list");
const items = await page.findAll("calcite-list-item");

expect(await items[0].getProperty("selected")).toBe(false);
expect(await items[1].getProperty("selected")).toBe(false);
expect(await items[2].getProperty("selected")).toBe(false);
expect(await items[3].getProperty("selected")).toBe(false);

const eventSpy = await list.spyOnEvent("calciteListChange");

await items[0].click();

await page.waitForChanges();
await page.waitForTimeout(listDebounceTimeout);
expect(eventSpy).toHaveReceivedEventTimes(1);
expect(await list.getProperty("selectedItems")).toHaveLength(1);

expect(await items[0].getProperty("selected")).toBe(true);
expect(await items[1].getProperty("selected")).toBe(false);
expect(await items[2].getProperty("selected")).toBe(false);
expect(await items[3].getProperty("selected")).toBe(false);

await page.$eval("#item-4", clickItemContent, `.${CSS.contentContainer}`);
await page.waitForChanges();
await page.waitForTimeout(listDebounceTimeout);
expect(eventSpy).toHaveReceivedEventTimes(2);
expect(await list.getProperty("selectedItems")).toHaveLength(4);

expect(await items[0].getProperty("selected")).toBe(true);
expect(await items[1].getProperty("selected")).toBe(true);
expect(await items[2].getProperty("selected")).toBe(true);
expect(await items[3].getProperty("selected")).toBe(true);

await items[3].click();

await page.waitForChanges();
await page.waitForTimeout(listDebounceTimeout);
expect(eventSpy).toHaveReceivedEventTimes(3);
expect(await list.getProperty("selectedItems")).toHaveLength(3);

expect(await items[0].getProperty("selected")).toBe(true);
expect(await items[1].getProperty("selected")).toBe(true);
expect(await items[2].getProperty("selected")).toBe(true);
expect(await items[3].getProperty("selected")).toBe(false);

await page.$eval("#item-1", clickItemContent, `.${CSS.contentContainer}`);
await page.waitForChanges();
await page.waitForTimeout(listDebounceTimeout);
expect(eventSpy).toHaveReceivedEventTimes(4);
expect(await list.getProperty("selectedItems")).toHaveLength(0);

expect(await items[0].getProperty("selected")).toBe(false);
expect(await items[1].getProperty("selected")).toBe(false);
expect(await items[2].getProperty("selected")).toBe(false);
expect(await items[3].getProperty("selected")).toBe(false);
});

it("should update active item on init and click", async () => {
const page = await newE2EPage();
await page.setContent(html`<calcite-list selection-mode="none">
Expand Down
31 changes: 31 additions & 0 deletions packages/calcite-components/src/components/list/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,35 @@ export class List
this.updateSelectedItems();
}

@Listen("calciteInternalListItemSelectMultiple")
handleCalciteInternalListItemSelectMultiple(
event: CustomEvent<{
selectMultiple: boolean;
}>
): void {
if (!!this.parentListEl) {
return;
}

event.stopPropagation();
const { target, detail } = event;
const { enabledListItems, lastSelectedInfo } = this;
const selectedItem = target as HTMLCalciteListItemElement;

if (detail.selectMultiple && !!lastSelectedInfo) {
const currentIndex = enabledListItems.indexOf(selectedItem);
const lastSelectedIndex = enabledListItems.indexOf(lastSelectedInfo.selectedItem);
const startIndex = Math.min(lastSelectedIndex, currentIndex);
const endIndex = Math.max(lastSelectedIndex, currentIndex);

enabledListItems
.slice(startIndex, endIndex + 1)
.forEach((item) => (item.selected = lastSelectedInfo.selected));
} else {
this.lastSelectedInfo = { selectedItem, selected: selectedItem.selected };
}
}

@Listen("calciteInternalListItemChange")
handleCalciteInternalListItemChange(event: CustomEvent): void {
if (!!this.parentListEl) {
Expand Down Expand Up @@ -410,6 +439,8 @@ export class List

private ancestorOfFirstFilteredItem: HTMLCalciteListItemElement;

private lastSelectedInfo: { selectedItem: HTMLCalciteListItemElement; selected: boolean };

// --------------------------------------------------------------------------
//
// Public Methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export class ShellPanel implements ConditionalSlotComponent, LocalizedComponent,
}

/**
* When `layout` is `horizontal`, or `layout` is `vertical` and `displayMode` is `float`, specifies the maximum height of the component.
* When `layout` is `horizontal`, specifies the maximum height of the component.
*/
@Prop({ reflect: true }) heightScale: Scale;

Expand Down

0 comments on commit 5413643

Please sign in to comment.