From ceb41f31f382ff1bcf81de2b11680699d33d5077 Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Wed, 26 Jun 2024 11:35:44 -0400 Subject: [PATCH] fix(angular): popover arrow navigation with disabled items (#29662) Issue number: resolves #29640 --------- ## What is the current behavior? (Angular) If a list inside of a popover contains a disabled item and is included in the following way: ```html Option 1 Option 2 Option 3 ``` when you try to navigate using the arrow down keys, it will stop at the disabled item instead of continuing over it. Note that changing the item to the following will work: ```html Option 2 ``` ## What is the new behavior? Reflect the `disabled` property in the item so that when items are queried in the popover, the arrow down key skips over the disabled item. ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information This can be tested in the Angular test app by following the documentation here: https://github.com/ionic-team/ionic-framework/blob/main/docs/angular/testing.md Removing my fix in `core`, then running `npm run build` and re-syncing the test app should reproduce the problem. --- core/api.txt | 2 +- core/src/components/item/item.tsx | 2 +- .../angular/test/base/e2e/src/lazy/popover.spec.ts | 10 ++++++++++ .../src/app/lazy/home-page/home-page.component.html | 5 +++++ .../lazy/popover-inline/popover-inline.component.html | 4 ++-- .../lazy/popover-inline/popover-inline.component.ts | 4 ++-- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/core/api.txt b/core/api.txt index ea7d4ab3c6..aa94edeaf2 100644 --- a/core/api.txt +++ b/core/api.txt @@ -783,7 +783,7 @@ ion-item,prop,button,boolean,false,false,false ion-item,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record | undefined,undefined,false,true ion-item,prop,detail,boolean | undefined,undefined,false,false ion-item,prop,detailIcon,string,chevronForward,false,false -ion-item,prop,disabled,boolean,false,false,false +ion-item,prop,disabled,boolean,false,false,true ion-item,prop,download,string | undefined,undefined,false,false ion-item,prop,href,string | undefined,undefined,false,false ion-item,prop,lines,"full" | "inset" | "none" | undefined,undefined,false,false diff --git a/core/src/components/item/item.tsx b/core/src/components/item/item.tsx index 6356c7ddca..b3c179c17e 100644 --- a/core/src/components/item/item.tsx +++ b/core/src/components/item/item.tsx @@ -64,7 +64,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac /** * If `true`, the user cannot interact with the item. */ - @Prop() disabled = false; + @Prop({ reflect: true }) disabled = false; /** * This attribute instructs browsers to download a URL instead of navigating to diff --git a/packages/angular/test/base/e2e/src/lazy/popover.spec.ts b/packages/angular/test/base/e2e/src/lazy/popover.spec.ts index 20500bb5c3..20bd3a1436 100644 --- a/packages/angular/test/base/e2e/src/lazy/popover.spec.ts +++ b/packages/angular/test/base/e2e/src/lazy/popover.spec.ts @@ -22,4 +22,14 @@ describe('Popovers: Inline', () => { cy.get('ion-list ion-item:nth-child(3)').should('have.text', 'C'); cy.get('ion-list ion-item:nth-child(4)').should('have.text', 'D'); }); + + it('should have an item with a disabled attribute', () => { + cy.get('ion-button').click(); + + cy.get('ion-popover').should('be.visible'); + + cy.wait(1500); + + cy.get('ion-list ion-item:nth-child(3)').should('have.attr', 'disabled'); + }); }); diff --git a/packages/angular/test/base/src/app/lazy/home-page/home-page.component.html b/packages/angular/test/base/src/app/lazy/home-page/home-page.component.html index 314f6e6ae6..3c78cea695 100644 --- a/packages/angular/test/base/src/app/lazy/home-page/home-page.component.html +++ b/packages/angular/test/base/src/app/lazy/home-page/home-page.component.html @@ -57,5 +57,10 @@ Accordions Test + + + Popovers + + diff --git a/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.html b/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.html index f4f311646c..d71c5b16e1 100644 --- a/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.html +++ b/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.html @@ -4,8 +4,8 @@ - - {{ item }} + + {{ item.text }} diff --git a/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.ts b/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.ts index 8ebf37f2d0..e05515f949 100644 --- a/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.ts +++ b/packages/angular/test/base/src/app/lazy/popover-inline/popover-inline.component.ts @@ -13,13 +13,13 @@ import { IonPopover } from "@ionic/angular"; }) export class PopoverInlineComponent { - items: string[] = []; + items: {text: string, disabled?: boolean}[] = []; openPopover(popover: IonPopover) { popover.present(); setTimeout(() => { - this.items = ['A', 'B', 'C', 'D']; + this.items = [{text: 'A'}, {text: 'B'}, {text: 'C', disabled: true}, {text: 'D'}]; }, 1000); }