diff --git a/BREAKING.md b/BREAKING.md index fd909652af..cec61730f8 100644 --- a/BREAKING.md +++ b/BREAKING.md @@ -63,7 +63,9 @@ This section details the desktop browser, JavaScript framework, and mobile platf

Accordion Group

-`ionChange` is no longer emitted when the `value` of `ion-accordion-group` is modified externally. `ionChange` is only emitted from user committed changes, such as clicking or tapping the accordion header. +-`ionChange` is no longer emitted when the `value` of `ion-accordion-group` is modified externally. `ionChange` is only emitted from user committed changes, such as clicking or tapping the accordion header. + +- Accordion Group no longer automatically adjusts the `value` property when passed an array and `multiple="false"`. Developers should update their apps to ensure they are using the API correctly.

Checkbox

diff --git a/core/src/components.d.ts b/core/src/components.d.ts index b74a2b2a82..4e6c01e8bb 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -73,7 +73,7 @@ export namespace Components { */ "requestAccordionToggle": (accordionValue: string | undefined, accordionExpand: boolean) => Promise; /** - * The value of the accordion group. + * The value of the accordion group. This controls which accordions are expanded. This should be an array of strings only when `multiple="true"` */ "value"?: string | string[] | null; } @@ -3814,7 +3814,7 @@ declare namespace LocalJSX { */ "readonly"?: boolean; /** - * The value of the accordion group. + * The value of the accordion group. This controls which accordions are expanded. This should be an array of strings only when `multiple="true"` */ "value"?: string | string[] | null; } diff --git a/core/src/components/accordion-group/accordion-group.tsx b/core/src/components/accordion-group/accordion-group.tsx index 94b4b0a5e6..9a5c33028f 100644 --- a/core/src/components/accordion-group/accordion-group.tsx +++ b/core/src/components/accordion-group/accordion-group.tsx @@ -3,6 +3,7 @@ import { Component, Element, Event, Host, Listen, Method, Prop, Watch, h } from import { getIonMode } from '../../global/ionic-global'; import type { AccordionGroupChangeEventDetail } from '../../interface'; +import { printIonWarning } from '../../utils/logging'; /** * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use. @@ -32,7 +33,9 @@ export class AccordionGroup implements ComponentInterface { @Prop() multiple?: boolean; /** - * The value of the accordion group. + * The value of the accordion group. This controls which + * accordions are expanded. + * This should be an array of strings only when `multiple="true"` */ @Prop({ mutable: true }) value?: string | string[] | null; @@ -74,16 +77,22 @@ export class AccordionGroup implements ComponentInterface { valueChanged() { const { value, multiple } = this; - /** - * If accordion group does not - * let multiple accordions be open - * at once, but user passes an array - * just grab the first value. - * This should emit ionChange because - * we are updating the value internally. - */ if (!multiple && Array.isArray(value)) { - this.setValue(value[0]); + /** + * We do some processing on the `value` array so + * that it looks more like an array when logged to + * the console. + * Example given ['a', 'b'] + * Default toString() behavior: a,b + * Custom behavior: ['a', 'b'] + */ + printIonWarning( + `ion-accordion-group was passed an array of values, but multiple="false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false". + + Value Passed: [${value.map((v) => `'${v}'`).join(', ')}] +`, + this.el + ); } /** diff --git a/core/src/components/accordion/test/accordion.spec.ts b/core/src/components/accordion/test/accordion.spec.ts index 85d0625b66..4eefb14423 100644 --- a/core/src/components/accordion/test/accordion.spec.ts +++ b/core/src/components/accordion/test/accordion.spec.ts @@ -40,42 +40,6 @@ it('should open correct accordions', async () => { expect(accordions[2].classList.contains('accordion-collapsed')).toEqual(true); }); -it('should not open more than one accordion when multiple="false"', async () => { - const page = await newSpecPage({ - components: [Item, Accordion, AccordionGroup], - html: ` - - - Label -
Content
-
- - Label -
Content
-
- - Label -
Content
-
-
- `, - }); - - const accordionGroup = page.body.querySelector('ion-accordion-group'); - const accordions = accordionGroup.querySelectorAll('ion-accordion'); - - accordions.forEach((accordion) => { - expect(accordion.classList.contains('accordion-collapsed')).toEqual(true); - }); - - accordionGroup.value = ['first', 'second']; - await page.waitForChanges(); - - expect(accordions[0].classList.contains('accordion-collapsed')).toEqual(false); - expect(accordions[1].classList.contains('accordion-collapsed')).toEqual(true); - expect(accordions[2].classList.contains('accordion-collapsed')).toEqual(true); -}); - it('should open more than one accordion when multiple="true"', async () => { const page = await newSpecPage({ components: [Item, Accordion, AccordionGroup], diff --git a/core/src/components/accordion/test/basic/accordion.e2e.ts b/core/src/components/accordion/test/basic/accordion.e2e.ts index f2685f4e4e..0a2e79136d 100644 --- a/core/src/components/accordion/test/basic/accordion.e2e.ts +++ b/core/src/components/accordion/test/basic/accordion.e2e.ts @@ -74,30 +74,4 @@ test.describe('accordion: ionChange', () => { await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => (el.value = 'second')); await expect(ionChange).not.toHaveReceivedEvent(); }); - - test('should fire ionChange setting array of values on a single selection accordion', async ({ page }) => { - await page.setContent(` - - - -
First Content
-
- - -
Second Content
-
- - -
Third Content
-
-
- - `); - - const ionChange = await page.spyOnEvent('ionChange'); - const accordionGroup = page.locator('ion-accordion-group'); - - await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => (el.value = ['second', 'third'])); - await expect(ionChange).toHaveReceivedEventDetail({ value: 'second' }); - }); });