From 9f313a7a480ae7057c2455176901a4f6edee6393 Mon Sep 17 00:00:00 2001 From: eliza Date: Fri, 6 Dec 2024 11:27:23 -0800 Subject: [PATCH 1/2] feat(list-item): deprecate open/close props in favor of expanded/collapsed --- .../src/components/list-item/list-item.e2e.ts | 33 ++++- .../src/components/list-item/list-item.tsx | 125 +++++++++++------- .../src/components/list-item/resources.ts | 10 +- 3 files changed, 115 insertions(+), 53 deletions(-) diff --git a/packages/calcite-components/src/components/list-item/list-item.e2e.ts b/packages/calcite-components/src/components/list-item/list-item.e2e.ts index db7985c019e..f9141bffcc4 100755 --- a/packages/calcite-components/src/components/list-item/list-item.e2e.ts +++ b/packages/calcite-components/src/components/list-item/list-item.e2e.ts @@ -45,6 +45,10 @@ describe("calcite-list-item", () => { propertyName: "open", defaultValue: false, }, + { + propertyName: "expanded", + defaultValue: false, + }, { propertyName: "dragHandle", defaultValue: false, @@ -362,7 +366,7 @@ describe("calcite-list-item", () => { expect(await listItem.getProperty("open")).toBe(false); - const openButton = await page.find(`calcite-list-item >>> .${CSS.openContainer}`); + const openButton = await page.find(`calcite-list-item >>> .${CSS.expandedContainer}`); await openButton.click(); expect(await listItem.getProperty("open")).toBe(true); @@ -373,6 +377,29 @@ describe("calcite-list-item", () => { expect(calciteListItemToggle).toHaveReceivedEventTimes(2); }); + it("should fire calciteListItemToggle event when expanded and collapsed", async () => { + const page = await newE2EPage({ + html: html``, + }); + + const listItem = await page.find("calcite-list-item"); + const calciteListItemToggle = await page.spyOnEvent("calciteListItemToggle", "window"); + + expect(await listItem.getProperty("expanded")).toBe(false); + + const openButton = await page.find(`calcite-list-item >>> .${CSS.expandedContainer}`); + + await openButton.click(); + expect(await listItem.getProperty("expanded")).toBe(true); + expect(calciteListItemToggle).toHaveReceivedEventTimes(1); + + await openButton.click(); + expect(await listItem.getProperty("expanded")).toBe(false); + expect(calciteListItemToggle).toHaveReceivedEventTimes(2); + }); + it("should not fire calciteListItemToggle event without nested items", async () => { const page = await newE2EPage({ html: html``, @@ -383,7 +410,7 @@ describe("calcite-list-item", () => { expect(await listItem.getProperty("open")).toBe(false); - const openButton = await page.find(`calcite-list-item >>> .${CSS.openContainer}`); + const openButton = await page.find(`calcite-list-item >>> .${CSS.expandedContainer}`); expect(openButton.getAttribute("title")).toBe(null); @@ -403,7 +430,7 @@ describe("calcite-list-item", () => { >`, }); - const openButton = await page.find(`calcite-list-item >>> .${CSS.openContainer}`); + const openButton = await page.find(`calcite-list-item >>> .${CSS.expandedContainer}`); expect(openButton).toBe(null); }); diff --git a/packages/calcite-components/src/components/list-item/list-item.tsx b/packages/calcite-components/src/components/list-item/list-item.tsx index 052abfa12f6..d60576ef8fe 100644 --- a/packages/calcite-components/src/components/list-item/list-item.tsx +++ b/packages/calcite-components/src/components/list-item/list-item.tsx @@ -89,7 +89,7 @@ export class ListItem @state() level: number = null; - @state() openable = false; + @state() expandable = false; @state() parentListEl: List["el"]; @@ -111,12 +111,26 @@ export class ListItem */ @property() bordered = false; - /** When `true`, a close button is added to the component. */ + /** + * When `true`, a close button is added to the component. + * + * @deprecated Use `collapsible` prop instead. + */ @property({ reflect: true }) closable = false; - /** When `true`, hides the component. */ + /** When `true`, a close button is added to the component. */ + @property({ reflect: true }) collapsible = false; + + /** + * When `true`, hides the component. + * + * @deprecated Use `collapsed` prop instead. + */ @property({ reflect: true }) closed = false; + /** When `true`, hides the component. */ + @property({ reflect: true }) collapsed = false; + /** A description for the component. Displays below the label text. */ @property() description: string; @@ -177,9 +191,16 @@ export class ListItem */ @property() moveToItems: MoveTo[] = []; - /** When `true`, the item is open to show child components. */ + /** + * When `true`, the item is open to show child components. + * + * @deprecated Use `expanded` prop instead. + */ @property({ reflect: true }) open = false; + /** When `true`, the item is expanded to show child components. */ + @property({ reflect: true }) expanded = false; + /** * Specifies the size of the component. * @@ -300,7 +321,7 @@ export class ListItem calciteInternalListItemToggle = createEvent({ cancelable: false }); /** Fires when the close button is clicked. */ - calciteListItemClose = createEvent({ cancelable: false }); + calciteListItemCollapse = createEvent({ cancelable: false }); /** Fires when the component is selected. */ calciteListItemSelect = createEvent({ cancelable: false }); @@ -361,16 +382,23 @@ export class ListItem this.activeHandler(this.active); } - if (changes.has("closed") && (this.hasUpdated || this.closed !== false)) { - this.handleClosedChange(); + if ( + (changes.has("closed") || changes.has("collapsed")) && + (this.hasUpdated || this.closed !== false || this.collapsed !== false) + ) { + this.handleCollapsedChange(); } if (changes.has("disabled") && (this.hasUpdated || this.disabled !== false)) { this.handleDisabledChange(); } - if (changes.has("open") && (this.hasUpdated || this.open !== false)) { - this.handleOpenChange(); + if ( + changes.has("open") || + (changes.has("expanded") && + (this.hasUpdated || this.open !== false || this.expanded !== false)) + ) { + this.handleExpandedChange(); } if (changes.has("selected") && (this.hasUpdated || this.selected !== false)) { @@ -382,7 +410,7 @@ export class ListItem } if (changes.has("displayMode") && this.hasUpdated) { - this.handleOpenableChange(this.defaultSlotEl.value); + this.handleExpandableChange(this.defaultSlotEl.value); } } @@ -404,7 +432,7 @@ export class ListItem } } - private handleClosedChange(): void { + private handleCollapsedChange(): void { this.emitCalciteInternalListItemChange(); } @@ -412,7 +440,7 @@ export class ListItem this.emitCalciteInternalListItemChange(); } - private handleOpenChange(): void { + private handleExpandedChange(): void { this.emitCalciteInternalListItemToggle(); } @@ -431,7 +459,7 @@ export class ListItem private handleCalciteInternalListDefaultSlotChanges(event: CustomEvent): void { event.stopPropagation(); - this.handleOpenableChange(this.defaultSlotEl.value); + this.handleExpandableChange(this.defaultSlotEl.value); } private setSortHandleEl(el: SortHandle["el"]): void { @@ -489,9 +517,9 @@ export class ListItem this.calciteInternalListItemChange.emit(); } - private handleCloseClick(): void { - this.closed = true; - this.calciteListItemClose.emit(); + private handleCollapseClick(): void { + this.closed = this.collapsed = true; + this.calciteListItemCollapse.emit(); } private handleContentSlotChange(event: Event): void { @@ -534,24 +562,24 @@ export class ListItem } } - private handleOpenableChange(slotEl: HTMLSlotElement): void { + private handleExpandableChange(slotEl: HTMLSlotElement): void { if (!slotEl) { return; } - this.openable = this.displayMode === "nested" && hasListItemChildren(slotEl); + this.expandable = this.displayMode === "nested" && hasListItemChildren(slotEl); } private handleDefaultSlotChange(event: Event): void { - this.handleOpenableChange(event.target as HTMLSlotElement); + this.handleExpandableChange(event.target as HTMLSlotElement); } private handleToggleClick(): void { this.toggle(); } - private toggle(value = !this.open): void { - this.open = value; + private toggle(value = !this.open || !this.expanded): void { + this.open = this.expanded = value; this.calciteListItemToggle.emit(); } @@ -603,7 +631,8 @@ export class ListItem actionsStartEl: { value: actionsStartEl }, actionsEndEl: { value: actionsEndEl }, open, - openable, + expanded, + expandable, } = this; const cells = this.getGridCells(); @@ -620,7 +649,7 @@ export class ListItem event.preventDefault(); const nextIndex = currentIndex + 1; if (currentIndex === -1) { - if (!open && openable) { + if ((!open || !expanded) && expandable) { this.toggle(true); this.focusCell(null); } else if (cells[0]) { @@ -634,7 +663,7 @@ export class ListItem const prevIndex = currentIndex - 1; if (currentIndex === -1) { this.focusCell(null); - if (open && openable) { + if ((open || expanded) && expandable) { this.toggle(false); } else { this.calciteInternalFocusPreviousItem.emit(); @@ -759,8 +788,8 @@ export class ListItem ) : null; } - private renderOpen(): JsxNode { - const { el, open, openable, messages, displayMode, scale } = this; + private renderExpanded(): JsxNode { + const { el, open, expanded, expandable, messages, displayMode, scale } = this; if (displayMode !== "nested") { return null; @@ -768,25 +797,29 @@ export class ListItem const dir = getElementDir(el); - const icon = openable - ? open + const icon = expandable + ? open || expanded ? ICONS.open : dir === "rtl" - ? ICONS.closedRTL - : ICONS.closedLTR + ? ICONS.collapsedRTL + : ICONS.collapsedLTR : ICONS.blank; const iconScale = getIconScale(scale); - const tooltip = openable ? (open ? messages.collapse : messages.expand) : undefined; + const tooltip = expandable + ? open || expanded + ? messages.collapse + : messages.expand + : undefined; - const openClickHandler = openable ? this.handleToggleClick : undefined; + const expandedClickHandler = expandable ? this.handleToggleClick : undefined; return (
@@ -812,26 +845,26 @@ export class ListItem } private renderActionsEnd(): JsxNode { - const { label, hasActionsEnd, closable, messages } = this; + const { label, hasActionsEnd, closable, collapsible, messages } = this; return (