From 6db1e8d91ea998ee25bee860b4ced9ece69b534b Mon Sep 17 00:00:00 2001 From: JC Franco Date: Fri, 5 Aug 2022 00:26:00 -0700 Subject: [PATCH 1/3] feat(tree): add none selection mode --- src/components/tree-item/resources.ts | 3 +- src/components/tree-item/tree-item.tsx | 7 +- src/components/tree/interfaces.ts | 1 + src/components/tree/tree.e2e.ts | 38 +++++++++++ src/components/tree/tree.tsx | 19 +++--- src/demos/tree.html | 89 ++++++++++++++++++++++++++ 6 files changed, 146 insertions(+), 11 deletions(-) diff --git a/src/components/tree-item/resources.ts b/src/components/tree-item/resources.ts index a029cb405cb..b4bd245223e 100644 --- a/src/components/tree-item/resources.ts +++ b/src/components/tree-item/resources.ts @@ -15,5 +15,6 @@ export const SLOTS = { export const ICONS = { bulletPoint: "bullet-point", checkmark: "check", - chevronRight: "chevron-right" + chevronRight: "chevron-right", + blank: "blank" }; diff --git a/src/components/tree-item/tree-item.tsx b/src/components/tree-item/tree-item.tsx index a29f4a3495a..64058f6b6a3 100644 --- a/src/components/tree-item/tree-item.tsx +++ b/src/components/tree-item/tree-item.tsx @@ -181,6 +181,7 @@ export class TreeItem implements ConditionalSlotComponent { const showCheckmark = this.selectionMode === TreeSelectionMode.Multi || this.selectionMode === TreeSelectionMode.MultiChildren; + const showBlank = this.selectionMode === TreeSelectionMode.None; const chevron = this.hasChildren ? ( (this.defaultSlotWrapper = el as HTMLElement)} > {chevron} - {bulletOrCheckIcon} + {itemIndicator} {checkbox ? checkbox : defaultSlotNode}
{ expect(checkbox).not.toBeNull(); }); }); + + describe(`when tree-item selection-mode is ${TreeSelectionMode.None}`, () => { + it("allows selecting items without a selection", async () => { + const page = await newE2EPage(); + await page.setContent(html` + + 1 + 2 + + `); + + type TestWindow = GlobalTestProps<{ + selectedIds: string[]; + }>; + + await page.evaluateHandle(() => + document.addEventListener("calciteTreeSelect", ({ detail }: CustomEvent) => { + (window as TestWindow).selectedIds = detail.selected.map((item) => item.id); + }) + ); + + const getSelectedIds = async (): Promise => page.evaluate(() => (window as TestWindow).selectedIds); + + const tree = await page.find(`calcite-tree`); + const selectEventSpy = await tree.spyOnEvent("calciteTreeSelect"); + const [item1, item2] = await page.findAll(`calcite-tree-item`); + + await item1.click(); + expect(selectEventSpy).toHaveReceivedEventTimes(1); + expect(await getSelectedIds()).toEqual(["1"]); + expect(await page.findAll("calcite-tree-item[selected]")).toHaveLength(0); + + await item2.click(); + expect(selectEventSpy).toHaveReceivedEventTimes(2); + expect(await getSelectedIds()).toEqual(["2"]); + expect(await page.findAll("calcite-tree-item[selected]")).toHaveLength(0); + }); + }); }); describe("keyboard support", () => { diff --git a/src/components/tree/tree.tsx b/src/components/tree/tree.tsx index 93a61bd7217..9f8d64cc137 100644 --- a/src/components/tree/tree.tsx +++ b/src/components/tree/tree.tsx @@ -152,6 +152,8 @@ export class Tree { return; } + const isNoneSelectionMode = this.selectionMode === TreeSelectionMode.None; + const shouldSelect = this.selectionMode !== null && (!target.hasChildren || @@ -160,6 +162,7 @@ export class Tree { this.selectionMode === TreeSelectionMode.MultiChildren))); const shouldModifyToCurrentSelection = + !isNoneSelectionMode && event.detail.modifyCurrentSelection && (this.selectionMode === TreeSelectionMode.Multi || this.selectionMode === TreeSelectionMode.MultiChildren); @@ -220,20 +223,20 @@ export class Tree { targetItems.forEach((treeItem) => { treeItem.selected = false; }); - } else { + } else if (!isNoneSelectionMode) { targetItems.forEach((treeItem) => { treeItem.selected = true; }); } } - this.calciteTreeSelect.emit({ - selected: ( - nodeListToArray( - this.el.querySelectorAll("calcite-tree-item") - ) as HTMLCalciteTreeItemElement[] - ).filter((i) => i.selected) - }); + const selected = isNoneSelectionMode + ? [target] + : (nodeListToArray(this.el.querySelectorAll("calcite-tree-item")).filter( + (i) => i.selected + ) as HTMLCalciteTreeItemElement[]); + + this.calciteTreeSelect.emit({ selected }); event.stopPropagation(); } diff --git a/src/demos/tree.html b/src/demos/tree.html index 059be5b70ae..20cdf392084 100644 --- a/src/demos/tree.html +++ b/src/demos/tree.html @@ -353,6 +353,95 @@

Tree

+ +
+
none selection mode
+ +
+ + + Child 1 + + + + Child 2 + + + + Grandchild 1 + + + Great Grandchild 1 + + + Great Grandchild 2 + + + Great Grandchild 3 + + + + + Grandchild 2 + + + Grandchild 3 + + + + + + Child 3 + + + Child 4 + + +
+ +
+ + + Child 1 + + + + Child 2 + + + + Grandchild 1 + + + Great Grandchild 1 + + + Great Grandchild 2 + + + Great Grandchild 3 + + + + + Grandchild 2 + + + Grandchild 3 + + + + + + Child 3 + + + Child 4 + + +
+
+
events
From 4b17d9ffe184cde7ba19388022251d636cc8c6dc Mon Sep 17 00:00:00 2001 From: JC Franco Date: Mon, 15 Aug 2022 11:17:16 -0700 Subject: [PATCH 2/3] tidy up --- src/components/tree-item/tree-item.scss | 8 +++++++- src/components/tree-item/tree-item.tsx | 5 +---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/tree-item/tree-item.scss b/src/components/tree-item/tree-item.scss index 3cce0ade0c9..9471768d2b2 100644 --- a/src/components/tree-item/tree-item.scss +++ b/src/components/tree-item/tree-item.scss @@ -5,6 +5,12 @@ cursor-pointer; } +:host([selection-mode="none"]:not([has-children])) { + .node-container { + margin-inline: theme("margin.3"); + } +} + @include calciteHydratedHidden(); :host([scale="s"]) { @@ -177,7 +183,7 @@ } // dropdown expanded and not selected -:host([has-children][expanded]:not([selected])) > .node-container { +:host([has-children][expanded]:not([selected]):not([selection-mode="none"])) > .node-container { ::slotted(*) { @apply text-color-1 font-medium; } diff --git a/src/components/tree-item/tree-item.tsx b/src/components/tree-item/tree-item.tsx index 64058f6b6a3..7b661ed5446 100644 --- a/src/components/tree-item/tree-item.tsx +++ b/src/components/tree-item/tree-item.tsx @@ -107,7 +107,7 @@ export class TreeItem implements ConditionalSlotComponent { /** * @internal */ - @Prop({ mutable: true }) selectionMode: TreeSelectionMode; + @Prop({ mutable: true, reflect: true }) selectionMode: TreeSelectionMode; @Watch("selectionMode") getselectionMode(): void { @@ -181,7 +181,6 @@ export class TreeItem implements ConditionalSlotComponent { const showCheckmark = this.selectionMode === TreeSelectionMode.Multi || this.selectionMode === TreeSelectionMode.MultiChildren; - const showBlank = this.selectionMode === TreeSelectionMode.None; const chevron = this.hasChildren ? ( Date: Mon, 15 Aug 2022 11:33:13 -0700 Subject: [PATCH 3/3] update stories --- src/components/tree/tree.stories.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/components/tree/tree.stories.ts b/src/components/tree/tree.stories.ts index 4a27c14ef35..1df9d37b949 100644 --- a/src/components/tree/tree.stories.ts +++ b/src/components/tree/tree.stories.ts @@ -49,14 +49,12 @@ export default { } }; +const selectionModes = ["single", "multi", "children", "multi-children", "ancestors", "none"]; + export const Simple = (): string => html` ${treeItems} @@ -67,11 +65,7 @@ export const RTL = (): string => html` ${treeItems} @@ -82,11 +76,7 @@ export const DarkMode = (): string => html` ${treeItems}